123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner/* 223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner * QEMU System Emulator 323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner * 423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner * Copyright (c) 2003-2008 Fabrice Bellard 523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner * 623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner * Permission is hereby granted, free of charge, to any person obtaining a copy 723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner * of this software and associated documentation files (the "Software"), to deal 823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner * in the Software without restriction, including without limitation the rights 923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 1023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner * copies of the Software, and to permit persons to whom the Software is 1123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner * furnished to do so, subject to the following conditions: 1223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner * 1323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner * The above copyright notice and this permission notice shall be included in 1423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner * all copies or substantial portions of the Software. 1523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner * 1623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 2023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 2123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 2223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner * THE SOFTWARE. 2323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner */ 2423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner#include "config-host.h" 2523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 2623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner#include "monitor.h" 2723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner#include "sysemu.h" 2823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner#include "gdbstub.h" 2923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner#include "dma.h" 3023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner#include "kvm.h" 31a381ef07088ce479610129e37bfef42538f397daJun Nakajima#include "hax.h" 3223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 3323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner#include "cpus.h" 3423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 3523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnerstatic CPUState *cur_cpu; 3623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnerstatic CPUState *next_cpu; 3723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 3823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner/***********************************************************/ 3923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnervoid hw_error(const char *fmt, ...) 4023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner{ 4123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner va_list ap; 4223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner CPUState *env; 4323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 4423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner va_start(ap, fmt); 4523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner fprintf(stderr, "qemu: hardware error: "); 4623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner vfprintf(stderr, fmt, ap); 4723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner fprintf(stderr, "\n"); 4823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner for(env = first_cpu; env != NULL; env = env->next_cpu) { 4923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner fprintf(stderr, "CPU #%d:\n", env->cpu_index); 5023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner#ifdef TARGET_I386 5123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner cpu_dump_state(env, stderr, fprintf, X86_DUMP_FPU); 5223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner#else 5323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner cpu_dump_state(env, stderr, fprintf, 0); 5423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner#endif 5523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner } 5623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner va_end(ap); 5723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner abort(); 5823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner} 5923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 6023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnerstatic void do_vm_stop(int reason) 6123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner{ 6223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner if (vm_running) { 6323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner cpu_disable_ticks(); 6423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner vm_running = 0; 6523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner pause_all_vcpus(); 6623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner vm_state_notify(0, reason); 6723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner } 6823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner} 6923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 7023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnerstatic int cpu_can_run(CPUState *env) 7123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner{ 7223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner if (env->stop) 7323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner return 0; 7423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner if (env->stopped) 7523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner return 0; 7623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner return 1; 7723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner} 7823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 7923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnerstatic int cpu_has_work(CPUState *env) 8023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner{ 8123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner if (env->stop) 8223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner return 1; 8323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner if (env->stopped) 8423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner return 0; 8523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner if (!env->halted) 8623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner return 1; 8723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner if (qemu_cpu_has_work(env)) 8823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner return 1; 8923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner return 0; 9023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner} 9123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 9223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnerint tcg_has_work(void) 9323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner{ 9423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner CPUState *env; 9523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 9623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner for (env = first_cpu; env != NULL; env = env->next_cpu) 9723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner if (cpu_has_work(env)) 9823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner return 1; 9923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner return 0; 10023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner} 10123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 10223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner#ifndef _WIN32 10323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnerstatic int io_thread_fd = -1; 10423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 10523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner#if 0 10623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnerstatic void qemu_event_increment(void) 10723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner{ 10823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner static const char byte = 0; 10923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 11023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner if (io_thread_fd == -1) 11123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner return; 11223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 11323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner write(io_thread_fd, &byte, sizeof(byte)); 11423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner} 11523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner#endif 11623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 11723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnerstatic void qemu_event_read(void *opaque) 11823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner{ 11923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner int fd = (unsigned long)opaque; 12023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner ssize_t len; 12123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 12223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner /* Drain the notify pipe */ 12323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner do { 12423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner char buffer[512]; 12523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner len = read(fd, buffer, sizeof(buffer)); 12623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner } while ((len == -1 && errno == EINTR) || len > 0); 12723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner} 12823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 12923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnerstatic int qemu_event_init(void) 13023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner{ 13123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner int err; 13223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner int fds[2]; 13323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 13423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner err = pipe(fds); 13523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner if (err == -1) 13623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner return -errno; 13723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 13823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner err = fcntl_setfl(fds[0], O_NONBLOCK); 13923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner if (err < 0) 14023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner goto fail; 14123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 14223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner err = fcntl_setfl(fds[1], O_NONBLOCK); 14323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner if (err < 0) 14423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner goto fail; 14523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 14623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_set_fd_handler2(fds[0], NULL, qemu_event_read, NULL, 14723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner (void *)(unsigned long)fds[0]); 14823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 14923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner io_thread_fd = fds[1]; 15023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner return 0; 15123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 15223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnerfail: 15323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner close(fds[0]); 15423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner close(fds[1]); 15523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner return err; 15623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner} 15723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner#else 15823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' TurnerHANDLE qemu_event_handle; 15923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 16023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnerstatic void dummy_event_handler(void *opaque) 16123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner{ 16223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner} 16323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 16423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnerstatic int qemu_event_init(void) 16523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner{ 16623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_event_handle = CreateEvent(NULL, FALSE, FALSE, NULL); 16723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner if (!qemu_event_handle) { 16823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner perror("Failed CreateEvent"); 16923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner return -1; 17023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner } 17123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_add_wait_object(qemu_event_handle, dummy_event_handler, NULL); 17223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner return 0; 17323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner} 17423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 17523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner#if 0 17623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnerstatic void qemu_event_increment(void) 17723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner{ 17823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner SetEvent(qemu_event_handle); 17923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner} 18023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner#endif 18123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner#endif 18223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 18323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner#ifndef CONFIG_IOTHREAD 18423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnerint qemu_init_main_loop(void) 18523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner{ 18623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner return qemu_event_init(); 18723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner} 18823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 18923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnervoid qemu_init_vcpu(void *_env) 19023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner{ 19123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner CPUState *env = _env; 19223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 19323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner if (kvm_enabled()) 19423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner kvm_init_vcpu(env); 195a381ef07088ce479610129e37bfef42538f397daJun Nakajima#ifdef CONFIG_HAX 196a381ef07088ce479610129e37bfef42538f397daJun Nakajima if (hax_enabled()) 197a381ef07088ce479610129e37bfef42538f397daJun Nakajima hax_init_vcpu(env); 198a381ef07088ce479610129e37bfef42538f397daJun Nakajima#endif 19923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner return; 20023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner} 20123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 20223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnerint qemu_cpu_self(void *env) 20323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner{ 20423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner return 1; 20523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner} 20623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 20723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnervoid resume_all_vcpus(void) 20823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner{ 20923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner} 21023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 21123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnervoid pause_all_vcpus(void) 21223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner{ 21323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner} 21423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 21523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnervoid qemu_cpu_kick(void *env) 21623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner{ 21723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner return; 21823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner} 21923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 22023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnervoid qemu_notify_event(void) 22123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner{ 22223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner CPUState *env = cpu_single_env; 22323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 22423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner if (env) { 22523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner cpu_exit(env); 22623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner#ifdef USE_KQEMU 22723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner if (env->kqemu_enabled) 22823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner kqemu_cpu_interrupt(env); 22923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner#endif 230a381ef07088ce479610129e37bfef42538f397daJun Nakajima /* 231a381ef07088ce479610129e37bfef42538f397daJun Nakajima * This is mainly for the Windows host, where the timer may be in 232a381ef07088ce479610129e37bfef42538f397daJun Nakajima * a different thread with vcpu. Thus the timer function needs to 233a381ef07088ce479610129e37bfef42538f397daJun Nakajima * notify the vcpu thread of more than simply cpu_exit. If env is 234a381ef07088ce479610129e37bfef42538f397daJun Nakajima * not NULL, it means that the vcpu is in execute state, we need 235a381ef07088ce479610129e37bfef42538f397daJun Nakajima * only to set the flags. If the guest is in execute state, the 236a381ef07088ce479610129e37bfef42538f397daJun Nakajima * HAX kernel module will exit to qemu. If env is NULL, vcpu is 237a381ef07088ce479610129e37bfef42538f397daJun Nakajima * in main_loop_wait, and we need a event to notify it. 238a381ef07088ce479610129e37bfef42538f397daJun Nakajima */ 239a381ef07088ce479610129e37bfef42538f397daJun Nakajima#ifdef CONFIG_HAX 240a381ef07088ce479610129e37bfef42538f397daJun Nakajima if (hax_enabled()) 241a381ef07088ce479610129e37bfef42538f397daJun Nakajima hax_raise_event(env); 242a381ef07088ce479610129e37bfef42538f397daJun Nakajima } else { 243a381ef07088ce479610129e37bfef42538f397daJun Nakajima#ifdef _WIN32 244a381ef07088ce479610129e37bfef42538f397daJun Nakajima if(hax_enabled()) 245a381ef07088ce479610129e37bfef42538f397daJun Nakajima SetEvent(qemu_event_handle); 246a381ef07088ce479610129e37bfef42538f397daJun Nakajima#endif 24723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner } 248a381ef07088ce479610129e37bfef42538f397daJun Nakajima#else 249a381ef07088ce479610129e37bfef42538f397daJun Nakajima } 250a381ef07088ce479610129e37bfef42538f397daJun Nakajima#endif 25123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner} 25223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 25323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnervoid qemu_mutex_lock_iothread(void) 25423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner{ 25523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner} 25623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 25723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnervoid qemu_mutex_unlock_iothread(void) 25823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner{ 25923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner} 26023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 26123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnervoid vm_stop(int reason) 26223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner{ 26323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner do_vm_stop(reason); 26423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner} 26523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 26623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner#else /* CONFIG_IOTHREAD */ 26723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 26823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner#include "qemu-thread.h" 26923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 27023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' TurnerQemuMutex qemu_global_mutex; 27123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnerstatic QemuMutex qemu_fair_mutex; 27223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 27323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnerstatic QemuThread io_thread; 27423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 27523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnerstatic QemuThread *tcg_cpu_thread; 27623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnerstatic QemuCond *tcg_halt_cond; 27723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 27823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnerstatic int qemu_system_ready; 27923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner/* cpu creation */ 28023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnerstatic QemuCond qemu_cpu_cond; 28123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner/* system init */ 28223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnerstatic QemuCond qemu_system_cond; 28323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnerstatic QemuCond qemu_pause_cond; 28423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 28523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnerstatic void block_io_signals(void); 28623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnerstatic void unblock_io_signals(void); 28723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnerstatic int tcg_has_work(void); 28823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 28923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnerint qemu_init_main_loop(void) 29023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner{ 29123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner int ret; 29223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 29323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner ret = qemu_event_init(); 29423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner if (ret) 29523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner return ret; 29623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 29723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_cond_init(&qemu_pause_cond); 29823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_mutex_init(&qemu_fair_mutex); 29923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_mutex_init(&qemu_global_mutex); 30023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_mutex_lock(&qemu_global_mutex); 30123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 30223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner unblock_io_signals(); 30323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_thread_self(&io_thread); 30423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 30523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner return 0; 30623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner} 30723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 30823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnerstatic void qemu_wait_io_event(CPUState *env) 30923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner{ 31023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner while (!tcg_has_work()) 31123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_cond_timedwait(env->halt_cond, &qemu_global_mutex, 1000); 31223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 31323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_mutex_unlock(&qemu_global_mutex); 31423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 31523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner /* 31623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner * Users of qemu_global_mutex can be starved, having no chance 31723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner * to acquire it since this path will get to it first. 31823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner * So use another lock to provide fairness. 31923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner */ 32023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_mutex_lock(&qemu_fair_mutex); 32123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_mutex_unlock(&qemu_fair_mutex); 32223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 32323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_mutex_lock(&qemu_global_mutex); 32423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner if (env->stop) { 32523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner env->stop = 0; 32623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner env->stopped = 1; 32723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_cond_signal(&qemu_pause_cond); 32823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner } 32923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner} 33023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 33123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnerstatic int qemu_cpu_exec(CPUState *env); 33223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 33323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnerstatic void *kvm_cpu_thread_fn(void *arg) 33423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner{ 33523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner CPUState *env = arg; 33623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 33723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner block_io_signals(); 33823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_thread_self(env->thread); 33923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 34023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner /* signal CPU creation */ 34123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_mutex_lock(&qemu_global_mutex); 34223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner env->created = 1; 34323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_cond_signal(&qemu_cpu_cond); 34423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 34523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner /* and wait for machine initialization */ 34623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner while (!qemu_system_ready) 34723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_cond_timedwait(&qemu_system_cond, &qemu_global_mutex, 100); 34823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 34923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner while (1) { 35023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner if (cpu_can_run(env)) 35123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_cpu_exec(env); 35223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_wait_io_event(env); 35323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner } 35423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 35523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner return NULL; 35623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner} 35723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 35823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnerstatic void tcg_cpu_exec(void); 35923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 36023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnerstatic void *tcg_cpu_thread_fn(void *arg) 36123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner{ 36223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner CPUState *env = arg; 36323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 36423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner block_io_signals(); 36523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_thread_self(env->thread); 36623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 36723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner /* signal CPU creation */ 36823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_mutex_lock(&qemu_global_mutex); 36923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner for (env = first_cpu; env != NULL; env = env->next_cpu) 37023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner env->created = 1; 37123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_cond_signal(&qemu_cpu_cond); 37223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 37323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner /* and wait for machine initialization */ 37423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner while (!qemu_system_ready) 37523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_cond_timedwait(&qemu_system_cond, &qemu_global_mutex, 100); 37623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 37723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner while (1) { 37823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner tcg_cpu_exec(); 37923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_wait_io_event(cur_cpu); 38023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner } 38123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 38223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner return NULL; 38323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner} 38423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 38523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnervoid qemu_cpu_kick(void *_env) 38623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner{ 38723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner CPUState *env = _env; 38823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_cond_broadcast(env->halt_cond); 389a381ef07088ce479610129e37bfef42538f397daJun Nakajima if (kvm_enabled() || hax_enabled()) 39023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_thread_signal(env->thread, SIGUSR1); 39123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner} 39223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 39323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnerint qemu_cpu_self(void *env) 39423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner{ 39523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner return (cpu_single_env != NULL); 39623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner} 39723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 39823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnerstatic void cpu_signal(int sig) 39923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner{ 40023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner if (cpu_single_env) 40123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner cpu_exit(cpu_single_env); 40223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner} 40323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 40423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnerstatic void block_io_signals(void) 40523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner{ 40623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner sigset_t set; 40723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner struct sigaction sigact; 40823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 40923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner sigemptyset(&set); 41023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner sigaddset(&set, SIGUSR2); 41123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner sigaddset(&set, SIGIO); 41223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner sigaddset(&set, SIGALRM); 41323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner pthread_sigmask(SIG_BLOCK, &set, NULL); 41423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 41523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner sigemptyset(&set); 41623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner sigaddset(&set, SIGUSR1); 41723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner pthread_sigmask(SIG_UNBLOCK, &set, NULL); 41823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 41923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner memset(&sigact, 0, sizeof(sigact)); 42023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner sigact.sa_handler = cpu_signal; 42123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner sigaction(SIGUSR1, &sigact, NULL); 42223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner} 42323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 42423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnerstatic void unblock_io_signals(void) 42523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner{ 42623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner sigset_t set; 42723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 42823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner sigemptyset(&set); 42923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner sigaddset(&set, SIGUSR2); 43023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner sigaddset(&set, SIGIO); 43123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner sigaddset(&set, SIGALRM); 43223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner pthread_sigmask(SIG_UNBLOCK, &set, NULL); 43323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 43423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner sigemptyset(&set); 43523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner sigaddset(&set, SIGUSR1); 43623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner pthread_sigmask(SIG_BLOCK, &set, NULL); 43723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner} 43823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 43923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnerstatic void qemu_signal_lock(unsigned int msecs) 44023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner{ 44123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_mutex_lock(&qemu_fair_mutex); 44223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 44323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner while (qemu_mutex_trylock(&qemu_global_mutex)) { 44423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_thread_signal(tcg_cpu_thread, SIGUSR1); 44523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner if (!qemu_mutex_timedlock(&qemu_global_mutex, msecs)) 44623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner break; 44723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner } 44823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_mutex_unlock(&qemu_fair_mutex); 44923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner} 45023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 45123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnervoid qemu_mutex_lock_iothread(void) 45223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner{ 453a381ef07088ce479610129e37bfef42538f397daJun Nakajima if (kvm_enabled() || hax_enabled()) { 45423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_mutex_lock(&qemu_fair_mutex); 45523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_mutex_lock(&qemu_global_mutex); 45623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_mutex_unlock(&qemu_fair_mutex); 45723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner } else 45823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_signal_lock(100); 45923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner} 46023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 46123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnervoid qemu_mutex_unlock_iothread(void) 46223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner{ 46323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_mutex_unlock(&qemu_global_mutex); 46423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner} 46523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 46623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnerstatic int all_vcpus_paused(void) 46723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner{ 46823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner CPUState *penv = first_cpu; 46923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 47023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner while (penv) { 47123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner if (!penv->stopped) 47223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner return 0; 47323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner penv = (CPUState *)penv->next_cpu; 47423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner } 47523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 47623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner return 1; 47723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner} 47823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 47923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnervoid pause_all_vcpus(void) 48023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner{ 48123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner CPUState *penv = first_cpu; 48223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 48323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner while (penv) { 48423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner penv->stop = 1; 48523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_thread_signal(penv->thread, SIGUSR1); 48623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_cpu_kick(penv); 48723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner penv = (CPUState *)penv->next_cpu; 48823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner } 48923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 49023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner while (!all_vcpus_paused()) { 49123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_cond_timedwait(&qemu_pause_cond, &qemu_global_mutex, 100); 49223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner penv = first_cpu; 49323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner while (penv) { 49423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_thread_signal(penv->thread, SIGUSR1); 49523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner penv = (CPUState *)penv->next_cpu; 49623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner } 49723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner } 49823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner} 49923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 50023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnervoid resume_all_vcpus(void) 50123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner{ 50223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner CPUState *penv = first_cpu; 50323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 50423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner while (penv) { 50523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner penv->stop = 0; 50623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner penv->stopped = 0; 50723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_thread_signal(penv->thread, SIGUSR1); 50823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_cpu_kick(penv); 50923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner penv = (CPUState *)penv->next_cpu; 51023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner } 51123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner} 51223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 51323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnerstatic void tcg_init_vcpu(void *_env) 51423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner{ 51523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner CPUState *env = _env; 51623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner /* share a single thread for all cpus with TCG */ 51723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner if (!tcg_cpu_thread) { 51823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner env->thread = qemu_mallocz(sizeof(QemuThread)); 51923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner env->halt_cond = qemu_mallocz(sizeof(QemuCond)); 52023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_cond_init(env->halt_cond); 52123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_thread_create(env->thread, tcg_cpu_thread_fn, env); 52223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner while (env->created == 0) 52323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_cond_timedwait(&qemu_cpu_cond, &qemu_global_mutex, 100); 52423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner tcg_cpu_thread = env->thread; 52523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner tcg_halt_cond = env->halt_cond; 52623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner } else { 52723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner env->thread = tcg_cpu_thread; 52823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner env->halt_cond = tcg_halt_cond; 52923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner } 53023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner} 53123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 53223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnerstatic void kvm_start_vcpu(CPUState *env) 53323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner{ 53423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner#if 0 53523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner kvm_init_vcpu(env); 53623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner env->thread = qemu_mallocz(sizeof(QemuThread)); 53723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner env->halt_cond = qemu_mallocz(sizeof(QemuCond)); 53823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_cond_init(env->halt_cond); 53923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_thread_create(env->thread, kvm_cpu_thread_fn, env); 54023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner while (env->created == 0) 54123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_cond_timedwait(&qemu_cpu_cond, &qemu_global_mutex, 100); 54223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner#endif 54323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner} 54423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 54523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnervoid qemu_init_vcpu(void *_env) 54623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner{ 54723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner CPUState *env = _env; 54823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 54923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner if (kvm_enabled()) 55023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner kvm_start_vcpu(env); 55123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner else 55223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner tcg_init_vcpu(env); 55323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner} 55423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 55523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnervoid qemu_notify_event(void) 55623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner{ 55723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_event_increment(); 55823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner} 55923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 56023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnervoid vm_stop(int reason) 56123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner{ 56223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner QemuThread me; 56323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_thread_self(&me); 56423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 56523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner if (!qemu_thread_equal(&me, &io_thread)) { 56623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_system_vmstop_request(reason); 56723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner /* 56823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner * FIXME: should not return to device code in case 56923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner * vm_stop() has been requested. 57023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner */ 57123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner if (cpu_single_env) { 57223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner cpu_exit(cpu_single_env); 57323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner cpu_single_env->stop = 1; 57423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner } 57523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner return; 57623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner } 57723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner do_vm_stop(reason); 57823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner} 57923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 58023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner#endif 58123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 58223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnerstatic int qemu_cpu_exec(CPUState *env) 58323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner{ 58423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner int ret; 58523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner#ifdef CONFIG_PROFILER 58623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner int64_t ti; 58723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner#endif 58823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 58923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner#ifdef CONFIG_PROFILER 59023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner ti = profile_getclock(); 59123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner#endif 59223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner if (use_icount) { 59323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner int64_t count; 59423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner int decr; 59523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_icount -= (env->icount_decr.u16.low + env->icount_extra); 59623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner env->icount_decr.u16.low = 0; 59723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner env->icount_extra = 0; 59823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner count = qemu_next_icount_deadline(); 59923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner count = (count + (1 << icount_time_shift) - 1) 60023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner >> icount_time_shift; 60123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_icount += count; 60223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner decr = (count > 0xffff) ? 0xffff : count; 60323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner count -= decr; 60423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner env->icount_decr.u16.low = decr; 60523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner env->icount_extra = count; 60623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner } 60723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner#ifdef CONFIG_TRACE 60823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner if (tbflush_requested) { 60923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner tbflush_requested = 0; 61023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner tb_flush(env); 61123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner return EXCP_INTERRUPT; 61223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner } 61323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner#endif 61423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 61523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 61623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner ret = cpu_exec(env); 61723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner#ifdef CONFIG_PROFILER 61823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_time += profile_getclock() - ti; 61923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner#endif 62023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner if (use_icount) { 62123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner /* Fold pending instructions back into the 62223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner instruction counter, and clear the interrupt flag. */ 62323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner qemu_icount -= (env->icount_decr.u16.low 62423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner + env->icount_extra); 62523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner env->icount_decr.u32 = 0; 62623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner env->icount_extra = 0; 62723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner } 62823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner return ret; 62923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner} 63023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 63123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnervoid tcg_cpu_exec(void) 63223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner{ 63323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner int ret = 0; 63423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 63523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner if (next_cpu == NULL) 63623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner next_cpu = first_cpu; 63723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner for (; next_cpu != NULL; next_cpu = next_cpu->next_cpu) { 63823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner CPUState *env = cur_cpu = next_cpu; 63923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 64023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner if (!vm_running) 64123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner break; 64223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner if (qemu_timer_alarm_pending()) { 64323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner break; 64423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner } 64523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner if (cpu_can_run(env)) 64623ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner ret = qemu_cpu_exec(env); 64723ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner if (ret == EXCP_DEBUG) { 64823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner gdb_set_stop_cpu(env); 64923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner debug_requested = 1; 65023ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner break; 65123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner } 65223ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner } 65323ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner} 65423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner 655