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