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