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 36b86f59c7SClaudio Fontana #include "tcg-accel-ops.h" 37b86f59c7SClaudio Fontana #include "tcg-accel-ops-mttcg.h" 38b86f59c7SClaudio Fontana #include "tcg-accel-ops-rr.h" 39b86f59c7SClaudio Fontana #include "tcg-accel-ops-icount.h" 40a77dabc3SClaudio Fontana 4145e077d7SClaudio Fontana /* common functionality among all TCG variants */ 42a77dabc3SClaudio Fontana 436cc9d67cSRichard Henderson void tcg_cpu_init_cflags(CPUState *cpu, bool parallel) 446cc9d67cSRichard Henderson { 456cc9d67cSRichard Henderson uint32_t cflags = cpu->cluster_index << CF_CLUSTER_SHIFT; 466cc9d67cSRichard Henderson cflags |= parallel ? CF_PARALLEL : 0; 476cc9d67cSRichard Henderson cflags |= icount_enabled() ? CF_USE_ICOUNT : 0; 486cc9d67cSRichard Henderson cpu->tcg_cflags = cflags; 496cc9d67cSRichard Henderson } 506cc9d67cSRichard Henderson 519e2658d6SClaudio Fontana void tcg_cpus_destroy(CPUState *cpu) 52a77dabc3SClaudio Fontana { 5345e077d7SClaudio Fontana cpu_thread_signal_destroyed(cpu); 54a77dabc3SClaudio Fontana } 55a77dabc3SClaudio Fontana 569e2658d6SClaudio Fontana int tcg_cpus_exec(CPUState *cpu) 57a77dabc3SClaudio Fontana { 5845e077d7SClaudio Fontana int ret; 5945e077d7SClaudio Fontana #ifdef CONFIG_PROFILER 6045e077d7SClaudio Fontana int64_t ti; 6145e077d7SClaudio Fontana #endif 6245e077d7SClaudio Fontana assert(tcg_enabled()); 6345e077d7SClaudio Fontana #ifdef CONFIG_PROFILER 6445e077d7SClaudio Fontana ti = profile_getclock(); 6545e077d7SClaudio Fontana #endif 6645e077d7SClaudio Fontana cpu_exec_start(cpu); 6745e077d7SClaudio Fontana ret = cpu_exec(cpu); 6845e077d7SClaudio Fontana cpu_exec_end(cpu); 6945e077d7SClaudio Fontana #ifdef CONFIG_PROFILER 7045e077d7SClaudio Fontana qatomic_set(&tcg_ctx->prof.cpu_exec_time, 7145e077d7SClaudio Fontana tcg_ctx->prof.cpu_exec_time + profile_getclock() - ti); 7245e077d7SClaudio Fontana #endif 7345e077d7SClaudio Fontana return ret; 74a77dabc3SClaudio Fontana } 75a77dabc3SClaudio Fontana 76bb4776beSClaudio Fontana /* mask must never be zero, except for A20 change call */ 77b86f59c7SClaudio Fontana void tcg_handle_interrupt(CPUState *cpu, int mask) 78bb4776beSClaudio Fontana { 79bb4776beSClaudio Fontana g_assert(qemu_mutex_iothread_locked()); 80bb4776beSClaudio Fontana 81bb4776beSClaudio Fontana cpu->interrupt_request |= mask; 82bb4776beSClaudio Fontana 83bb4776beSClaudio Fontana /* 84bb4776beSClaudio Fontana * If called from iothread context, wake the target cpu in 85bb4776beSClaudio Fontana * case its halted. 86bb4776beSClaudio Fontana */ 87bb4776beSClaudio Fontana if (!qemu_cpu_is_self(cpu)) { 88bb4776beSClaudio Fontana qemu_cpu_kick(cpu); 89bb4776beSClaudio Fontana } else { 90bb4776beSClaudio Fontana qatomic_set(&cpu_neg(cpu)->icount_decr.u16.high, -1); 91bb4776beSClaudio Fontana } 92bb4776beSClaudio Fontana } 93b86f59c7SClaudio Fontana 94b86f59c7SClaudio Fontana static void tcg_accel_ops_init(AccelOpsClass *ops) 95b86f59c7SClaudio Fontana { 96b86f59c7SClaudio Fontana if (qemu_tcg_mttcg_enabled()) { 97b86f59c7SClaudio Fontana ops->create_vcpu_thread = mttcg_start_vcpu_thread; 98b86f59c7SClaudio Fontana ops->kick_vcpu_thread = mttcg_kick_vcpu_thread; 99b86f59c7SClaudio Fontana ops->handle_interrupt = tcg_handle_interrupt; 100b86f59c7SClaudio Fontana } else if (icount_enabled()) { 101b86f59c7SClaudio Fontana ops->create_vcpu_thread = rr_start_vcpu_thread; 102b86f59c7SClaudio Fontana ops->kick_vcpu_thread = rr_kick_vcpu_thread; 103b86f59c7SClaudio Fontana ops->handle_interrupt = icount_handle_interrupt; 104b86f59c7SClaudio Fontana ops->get_virtual_clock = icount_get; 105b86f59c7SClaudio Fontana ops->get_elapsed_ticks = icount_get; 106b86f59c7SClaudio Fontana } else { 107b86f59c7SClaudio Fontana ops->create_vcpu_thread = rr_start_vcpu_thread; 108b86f59c7SClaudio Fontana ops->kick_vcpu_thread = rr_kick_vcpu_thread; 109b86f59c7SClaudio Fontana ops->handle_interrupt = tcg_handle_interrupt; 110b86f59c7SClaudio Fontana } 111b86f59c7SClaudio Fontana } 112b86f59c7SClaudio Fontana 113b86f59c7SClaudio Fontana static void tcg_accel_ops_class_init(ObjectClass *oc, void *data) 114b86f59c7SClaudio Fontana { 115b86f59c7SClaudio Fontana AccelOpsClass *ops = ACCEL_OPS_CLASS(oc); 116b86f59c7SClaudio Fontana 117b86f59c7SClaudio Fontana ops->ops_init = tcg_accel_ops_init; 118b86f59c7SClaudio Fontana } 119b86f59c7SClaudio Fontana 120b86f59c7SClaudio Fontana static const TypeInfo tcg_accel_ops_type = { 121b86f59c7SClaudio Fontana .name = ACCEL_OPS_NAME("tcg"), 122b86f59c7SClaudio Fontana 123b86f59c7SClaudio Fontana .parent = TYPE_ACCEL_OPS, 124b86f59c7SClaudio Fontana .class_init = tcg_accel_ops_class_init, 125b86f59c7SClaudio Fontana .abstract = true, 126b86f59c7SClaudio Fontana }; 127*9e5d3b69SGerd Hoffmann module_obj(ACCEL_OPS_NAME("tcg")); 128b86f59c7SClaudio Fontana 129b86f59c7SClaudio Fontana static void tcg_accel_ops_register_types(void) 130b86f59c7SClaudio Fontana { 131b86f59c7SClaudio Fontana type_register_static(&tcg_accel_ops_type); 132b86f59c7SClaudio Fontana } 133b86f59c7SClaudio Fontana type_init(tcg_accel_ops_register_types); 134