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