Home | History | Annotate | Download | only in qemu
      1 /*
      2  * QEMU System Emulator
      3  *
      4  * Copyright (c) 2003-2008 Fabrice Bellard
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a copy
      7  * of this software and associated documentation files (the "Software"), to deal
      8  * in the Software without restriction, including without limitation the rights
      9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     10  * copies of the Software, and to permit persons to whom the Software is
     11  * furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice shall be included in
     14  * all copies or substantial portions of the Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
     19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     22  * THE SOFTWARE.
     23  */
     24 #include "config-host.h"
     25 
     26 #include "cpu.h"
     27 #include "monitor/monitor.h"
     28 #include "sysemu/sysemu.h"
     29 #include "cpu.h"
     30 #include "exec/exec-all.h"
     31 #include "exec/gdbstub.h"
     32 #include "sysemu/dma.h"
     33 #include "sysemu/kvm.h"
     34 #include "exec/exec-all.h"
     35 #include "exec/hax.h"
     36 
     37 #include "sysemu/cpus.h"
     38 
     39 static CPUState *cur_cpu;
     40 static CPUState *next_cpu;
     41 
     42 /***********************************************************/
     43 void hw_error(const char *fmt, ...)
     44 {
     45     va_list ap;
     46     CPUState *cpu;
     47 
     48     va_start(ap, fmt);
     49     fprintf(stderr, "qemu: hardware error: ");
     50     vfprintf(stderr, fmt, ap);
     51     fprintf(stderr, "\n");
     52     CPU_FOREACH(cpu) {
     53         fprintf(stderr, "CPU #%d:\n", cpu->cpu_index);
     54 #ifdef TARGET_I386
     55         cpu_dump_state(cpu->env_ptr, stderr, fprintf, X86_DUMP_FPU);
     56 #else
     57         cpu_dump_state(cpu->env_ptr, stderr, fprintf, 0);
     58 #endif
     59     }
     60     va_end(ap);
     61     abort();
     62 }
     63 
     64 static void do_vm_stop(int reason)
     65 {
     66     if (vm_running) {
     67         cpu_disable_ticks();
     68         vm_running = 0;
     69         pause_all_vcpus();
     70         vm_state_notify(0, reason);
     71     }
     72 }
     73 
     74 static int cpu_can_run(CPUArchState *env)
     75 {
     76     CPUState *cpu = ENV_GET_CPU(env);
     77     if (cpu->stop)
     78         return 0;
     79     if (cpu->stopped)
     80         return 0;
     81     return 1;
     82 }
     83 
     84 int tcg_has_work(void)
     85 {
     86     CPUState *cpu;
     87 
     88     CPU_FOREACH(cpu) {
     89         if (cpu->stop)
     90             return 1;
     91         if (cpu->stopped)
     92             return 0;
     93         if (!cpu->halted)
     94             return 1;
     95         if (cpu_has_work(cpu))
     96             return 1;
     97         return 0;
     98     }
     99     return 0;
    100 }
    101 
    102 void qemu_init_vcpu(CPUState *cpu)
    103 {
    104     if (kvm_enabled())
    105         kvm_init_vcpu(cpu);
    106 #ifdef CONFIG_HAX
    107     if (hax_enabled())
    108         hax_init_vcpu(cpu);
    109 #endif
    110     return;
    111 }
    112 
    113 bool qemu_cpu_is_self(CPUState *cpu)
    114 {
    115     return true;
    116 }
    117 
    118 void resume_all_vcpus(void)
    119 {
    120 }
    121 
    122 void pause_all_vcpus(void)
    123 {
    124 }
    125 
    126 void qemu_cpu_kick(CPUState *cpu)
    127 {
    128     return;
    129 }
    130 
    131 // In main-loop.c
    132 #ifdef _WIN32
    133 extern HANDLE qemu_event_handle;
    134 #endif
    135 
    136 void qemu_notify_event(void)
    137 {
    138     CPUState *cpu = current_cpu;
    139 
    140     if (cpu) {
    141         cpu_exit(cpu);
    142     /*
    143      * This is mainly for the Windows host, where the timer may be in
    144      * a different thread with vcpu. Thus the timer function needs to
    145      * notify the vcpu thread of more than simply cpu_exit.  If env is
    146      * not NULL, it means that the vcpu is in execute state, we need
    147      * only to set the flags.  If the guest is in execute state, the
    148      * HAX kernel module will exit to qemu.  If env is NULL, vcpu is
    149      * in main_loop_wait, and we need a event to notify it.
    150      */
    151 #ifdef CONFIG_HAX
    152         if (hax_enabled())
    153             hax_raise_event(cpu);
    154      } else {
    155 #ifdef _WIN32
    156          if(hax_enabled())
    157              SetEvent(qemu_event_handle);
    158 #endif
    159      }
    160 #else
    161      }
    162 #endif
    163 }
    164 
    165 void qemu_mutex_lock_iothread(void)
    166 {
    167 }
    168 
    169 void qemu_mutex_unlock_iothread(void)
    170 {
    171 }
    172 
    173 void vm_stop(int reason)
    174 {
    175     do_vm_stop(reason);
    176 }
    177 
    178 static int qemu_cpu_exec(CPUOldState *env)
    179 {
    180     int ret;
    181 
    182 #ifdef CONFIG_PROFILER
    183     int64_t ti = profile_getclock();
    184 #endif
    185 #ifndef CONFIG_ANDROID
    186     if (use_icount) {
    187         int64_t count;
    188         int decr;
    189         qemu_icount -= (env->icount_decr.u16.low + env->icount_extra);
    190         env->icount_decr.u16.low = 0;
    191         env->icount_extra = 0;
    192         count = qemu_next_icount_deadline();
    193         count = (count + (1 << icount_time_shift) - 1)
    194                 >> icount_time_shift;
    195         qemu_icount += count;
    196         decr = (count > 0xffff) ? 0xffff : count;
    197         count -= decr;
    198         env->icount_decr.u16.low = decr;
    199         env->icount_extra = count;
    200     }
    201 #endif
    202     ret = cpu_exec(env);
    203 #ifdef CONFIG_PROFILER
    204     qemu_time += profile_getclock() - ti;
    205 #endif
    206 #ifndef CONFIG_ANDROID
    207     if (use_icount) {
    208         /* Fold pending instructions back into the
    209            instruction counter, and clear the interrupt flag.  */
    210         qemu_icount -= (env->icount_decr.u16.low
    211                         + env->icount_extra);
    212         env->icount_decr.u32 = 0;
    213         env->icount_extra = 0;
    214     }
    215 #endif
    216     return ret;
    217 }
    218 
    219 void tcg_cpu_exec(void)
    220 {
    221     int ret = 0;
    222 
    223     if (next_cpu == NULL)
    224         next_cpu = QTAILQ_FIRST(&cpus);
    225     for (; next_cpu != NULL; next_cpu = QTAILQ_NEXT(next_cpu, node)) {\
    226         cur_cpu = next_cpu;
    227         CPUOldState *env = cur_cpu->env_ptr;
    228 
    229         if (!vm_running)
    230             break;
    231         if (qemu_timer_alarm_pending()) {
    232             break;
    233         }
    234         if (cpu_can_run(env))
    235             ret = qemu_cpu_exec(env);
    236         if (ret == EXCP_DEBUG) {
    237             gdb_set_stop_cpu(cur_cpu);
    238             debug_requested = 1;
    239             break;
    240         }
    241     }
    242 }
    243 
    244 /***********************************************************/
    245 /* guest cycle counter */
    246 
    247 typedef struct TimersState {
    248     int64_t cpu_ticks_prev;
    249     int64_t cpu_ticks_offset;
    250     int64_t cpu_clock_offset;
    251     int32_t cpu_ticks_enabled;
    252     int64_t dummy;
    253 } TimersState;
    254 
    255 static void timer_save(QEMUFile *f, void *opaque)
    256 {
    257     TimersState *s = opaque;
    258 
    259     if (s->cpu_ticks_enabled) {
    260         hw_error("cannot save state if virtual timers are running");
    261     }
    262     qemu_put_be64(f, s->cpu_ticks_prev);
    263     qemu_put_be64(f, s->cpu_ticks_offset);
    264     qemu_put_be64(f, s->cpu_clock_offset);
    265  }
    266 
    267 static int timer_load(QEMUFile *f, void *opaque, int version_id)
    268 {
    269     TimersState *s = opaque;
    270 
    271     if (version_id != 1 && version_id != 2)
    272         return -EINVAL;
    273     if (s->cpu_ticks_enabled) {
    274         return -EINVAL;
    275     }
    276     s->cpu_ticks_prev   = qemu_get_sbe64(f);
    277     s->cpu_ticks_offset = qemu_get_sbe64(f);
    278     if (version_id == 2) {
    279         s->cpu_clock_offset = qemu_get_sbe64(f);
    280     }
    281     return 0;
    282 }
    283 
    284 
    285 TimersState timers_state;
    286 
    287 void qemu_timer_register_savevm(void) {
    288     register_savevm(NULL,
    289                     "timer",
    290                     0,
    291                     2,
    292                     timer_save,
    293                     timer_load,
    294                     &timers_state);
    295 }
    296 
    297 /* Return the virtual CPU time, based on the instruction counter.  */
    298 int64_t cpu_get_icount(void)
    299 {
    300     int64_t icount;
    301     CPUOldState *env = cpu_single_env;;
    302 
    303     icount = qemu_icount;
    304     if (env) {
    305         if (!can_do_io(env)) {
    306             fprintf(stderr, "Bad clock read\n");
    307         }
    308         icount -= (env->icount_decr.u16.low + env->icount_extra);
    309     }
    310     return qemu_icount_bias + (icount << icount_time_shift);
    311 }
    312 
    313 /* return the host CPU cycle counter and handle stop/restart */
    314 int64_t cpu_get_ticks(void)
    315 {
    316     if (use_icount) {
    317         return cpu_get_icount();
    318     }
    319     if (!timers_state.cpu_ticks_enabled) {
    320         return timers_state.cpu_ticks_offset;
    321     } else {
    322         int64_t ticks;
    323         ticks = cpu_get_real_ticks();
    324         if (timers_state.cpu_ticks_prev > ticks) {
    325             /* Note: non increasing ticks may happen if the host uses
    326                software suspend */
    327             timers_state.cpu_ticks_offset += timers_state.cpu_ticks_prev - ticks;
    328         }
    329         timers_state.cpu_ticks_prev = ticks;
    330         return ticks + timers_state.cpu_ticks_offset;
    331     }
    332 }
    333 
    334 /* return the host CPU monotonic timer and handle stop/restart */
    335 int64_t cpu_get_clock(void)
    336 {
    337     int64_t ti;
    338     if (!timers_state.cpu_ticks_enabled) {
    339         return timers_state.cpu_clock_offset;
    340     } else {
    341         ti = get_clock();
    342         return ti + timers_state.cpu_clock_offset;
    343     }
    344 }
    345 
    346 /* enable cpu_get_ticks() */
    347 void cpu_enable_ticks(void)
    348 {
    349     if (!timers_state.cpu_ticks_enabled) {
    350         timers_state.cpu_ticks_offset -= cpu_get_real_ticks();
    351         timers_state.cpu_clock_offset -= get_clock();
    352         timers_state.cpu_ticks_enabled = 1;
    353     }
    354 }
    355 
    356 /* disable cpu_get_ticks() : the clock is stopped. You must not call
    357    cpu_get_ticks() after that.  */
    358 void cpu_disable_ticks(void)
    359 {
    360     if (timers_state.cpu_ticks_enabled) {
    361         timers_state.cpu_ticks_offset = cpu_get_ticks();
    362         timers_state.cpu_clock_offset = cpu_get_clock();
    363         timers_state.cpu_ticks_enabled = 0;
    364     }
    365 }
    366 
    367 void qemu_clock_warp(QEMUClockType clock) {
    368 }
    369