1a77dabc3SClaudio Fontana /* 245e077d7SClaudio Fontana * QEMU TCG vCPU common functionality 345e077d7SClaudio Fontana * 445e077d7SClaudio Fontana * Functionality common to all TCG vCPU variants: mttcg, rr and icount. 5a77dabc3SClaudio Fontana * 6a77dabc3SClaudio Fontana * Copyright (c) 2003-2008 Fabrice Bellard 7a77dabc3SClaudio Fontana * Copyright (c) 2014 Red Hat Inc. 8a77dabc3SClaudio Fontana * 9a77dabc3SClaudio Fontana * Permission is hereby granted, free of charge, to any person obtaining a copy 10a77dabc3SClaudio Fontana * of this software and associated documentation files (the "Software"), to deal 11a77dabc3SClaudio Fontana * in the Software without restriction, including without limitation the rights 12a77dabc3SClaudio Fontana * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13a77dabc3SClaudio Fontana * copies of the Software, and to permit persons to whom the Software is 14a77dabc3SClaudio Fontana * furnished to do so, subject to the following conditions: 15a77dabc3SClaudio Fontana * 16a77dabc3SClaudio Fontana * The above copyright notice and this permission notice shall be included in 17a77dabc3SClaudio Fontana * all copies or substantial portions of the Software. 18a77dabc3SClaudio Fontana * 19a77dabc3SClaudio Fontana * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20a77dabc3SClaudio Fontana * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21a77dabc3SClaudio Fontana * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 22a77dabc3SClaudio Fontana * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23a77dabc3SClaudio Fontana * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24a77dabc3SClaudio Fontana * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25a77dabc3SClaudio Fontana * THE SOFTWARE. 26a77dabc3SClaudio Fontana */ 27a77dabc3SClaudio Fontana 28a77dabc3SClaudio Fontana #include "qemu/osdep.h" 29a77dabc3SClaudio Fontana #include "qemu-common.h" 30a77dabc3SClaudio Fontana #include "sysemu/tcg.h" 31a77dabc3SClaudio Fontana #include "sysemu/replay.h" 32a77dabc3SClaudio Fontana #include "qemu/main-loop.h" 33a77dabc3SClaudio Fontana #include "qemu/guest-random.h" 34a77dabc3SClaudio Fontana #include "exec/exec-all.h" 35a77dabc3SClaudio Fontana #include "hw/boards.h" 36a77dabc3SClaudio Fontana 37*b86f59c7SClaudio Fontana #include "tcg-accel-ops.h" 38*b86f59c7SClaudio Fontana #include "tcg-accel-ops-mttcg.h" 39*b86f59c7SClaudio Fontana #include "tcg-accel-ops-rr.h" 40*b86f59c7SClaudio Fontana #include "tcg-accel-ops-icount.h" 41a77dabc3SClaudio Fontana 4245e077d7SClaudio Fontana /* common functionality among all TCG variants */ 43a77dabc3SClaudio Fontana 449e2658d6SClaudio Fontana void tcg_cpus_destroy(CPUState *cpu) 45a77dabc3SClaudio Fontana { 4645e077d7SClaudio Fontana cpu_thread_signal_destroyed(cpu); 47a77dabc3SClaudio Fontana } 48a77dabc3SClaudio Fontana 499e2658d6SClaudio Fontana int tcg_cpus_exec(CPUState *cpu) 50a77dabc3SClaudio Fontana { 5145e077d7SClaudio Fontana int ret; 5245e077d7SClaudio Fontana #ifdef CONFIG_PROFILER 5345e077d7SClaudio Fontana int64_t ti; 5445e077d7SClaudio Fontana #endif 5545e077d7SClaudio Fontana assert(tcg_enabled()); 5645e077d7SClaudio Fontana #ifdef CONFIG_PROFILER 5745e077d7SClaudio Fontana ti = profile_getclock(); 5845e077d7SClaudio Fontana #endif 5945e077d7SClaudio Fontana cpu_exec_start(cpu); 6045e077d7SClaudio Fontana ret = cpu_exec(cpu); 6145e077d7SClaudio Fontana cpu_exec_end(cpu); 6245e077d7SClaudio Fontana #ifdef CONFIG_PROFILER 6345e077d7SClaudio Fontana qatomic_set(&tcg_ctx->prof.cpu_exec_time, 6445e077d7SClaudio Fontana tcg_ctx->prof.cpu_exec_time + profile_getclock() - ti); 6545e077d7SClaudio Fontana #endif 6645e077d7SClaudio Fontana return ret; 67a77dabc3SClaudio Fontana } 68a77dabc3SClaudio Fontana 69bb4776beSClaudio Fontana /* mask must never be zero, except for A20 change call */ 70*b86f59c7SClaudio Fontana void tcg_handle_interrupt(CPUState *cpu, int mask) 71bb4776beSClaudio Fontana { 72bb4776beSClaudio Fontana g_assert(qemu_mutex_iothread_locked()); 73bb4776beSClaudio Fontana 74bb4776beSClaudio Fontana cpu->interrupt_request |= mask; 75bb4776beSClaudio Fontana 76bb4776beSClaudio Fontana /* 77bb4776beSClaudio Fontana * If called from iothread context, wake the target cpu in 78bb4776beSClaudio Fontana * case its halted. 79bb4776beSClaudio Fontana */ 80bb4776beSClaudio Fontana if (!qemu_cpu_is_self(cpu)) { 81bb4776beSClaudio Fontana qemu_cpu_kick(cpu); 82bb4776beSClaudio Fontana } else { 83bb4776beSClaudio Fontana qatomic_set(&cpu_neg(cpu)->icount_decr.u16.high, -1); 84bb4776beSClaudio Fontana } 85bb4776beSClaudio Fontana } 86*b86f59c7SClaudio Fontana 87*b86f59c7SClaudio Fontana static void tcg_accel_ops_init(AccelOpsClass *ops) 88*b86f59c7SClaudio Fontana { 89*b86f59c7SClaudio Fontana if (qemu_tcg_mttcg_enabled()) { 90*b86f59c7SClaudio Fontana ops->create_vcpu_thread = mttcg_start_vcpu_thread; 91*b86f59c7SClaudio Fontana ops->kick_vcpu_thread = mttcg_kick_vcpu_thread; 92*b86f59c7SClaudio Fontana ops->handle_interrupt = tcg_handle_interrupt; 93*b86f59c7SClaudio Fontana } else if (icount_enabled()) { 94*b86f59c7SClaudio Fontana ops->create_vcpu_thread = rr_start_vcpu_thread; 95*b86f59c7SClaudio Fontana ops->kick_vcpu_thread = rr_kick_vcpu_thread; 96*b86f59c7SClaudio Fontana ops->handle_interrupt = icount_handle_interrupt; 97*b86f59c7SClaudio Fontana ops->get_virtual_clock = icount_get; 98*b86f59c7SClaudio Fontana ops->get_elapsed_ticks = icount_get; 99*b86f59c7SClaudio Fontana } else { 100*b86f59c7SClaudio Fontana ops->create_vcpu_thread = rr_start_vcpu_thread; 101*b86f59c7SClaudio Fontana ops->kick_vcpu_thread = rr_kick_vcpu_thread; 102*b86f59c7SClaudio Fontana ops->handle_interrupt = tcg_handle_interrupt; 103*b86f59c7SClaudio Fontana } 104*b86f59c7SClaudio Fontana } 105*b86f59c7SClaudio Fontana 106*b86f59c7SClaudio Fontana static void tcg_accel_ops_class_init(ObjectClass *oc, void *data) 107*b86f59c7SClaudio Fontana { 108*b86f59c7SClaudio Fontana AccelOpsClass *ops = ACCEL_OPS_CLASS(oc); 109*b86f59c7SClaudio Fontana 110*b86f59c7SClaudio Fontana ops->ops_init = tcg_accel_ops_init; 111*b86f59c7SClaudio Fontana } 112*b86f59c7SClaudio Fontana 113*b86f59c7SClaudio Fontana static const TypeInfo tcg_accel_ops_type = { 114*b86f59c7SClaudio Fontana .name = ACCEL_OPS_NAME("tcg"), 115*b86f59c7SClaudio Fontana 116*b86f59c7SClaudio Fontana .parent = TYPE_ACCEL_OPS, 117*b86f59c7SClaudio Fontana .class_init = tcg_accel_ops_class_init, 118*b86f59c7SClaudio Fontana .abstract = true, 119*b86f59c7SClaudio Fontana }; 120*b86f59c7SClaudio Fontana 121*b86f59c7SClaudio Fontana static void tcg_accel_ops_register_types(void) 122*b86f59c7SClaudio Fontana { 123*b86f59c7SClaudio Fontana type_register_static(&tcg_accel_ops_type); 124*b86f59c7SClaudio Fontana } 125*b86f59c7SClaudio Fontana type_init(tcg_accel_ops_register_types); 126