1 /* 2 * qemu user cpu loop 3 * 4 * Copyright (c) 2003-2008 Fabrice Bellard 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #include "qemu/osdep.h" 21 #include "qemu-common.h" 22 #include "qemu.h" 23 #include "cpu_loop-common.h" 24 25 static inline uint64_t cpu_ppc_get_tb(CPUPPCState *env) 26 { 27 return cpu_get_host_ticks(); 28 } 29 30 uint64_t cpu_ppc_load_tbl(CPUPPCState *env) 31 { 32 return cpu_ppc_get_tb(env); 33 } 34 35 uint32_t cpu_ppc_load_tbu(CPUPPCState *env) 36 { 37 return cpu_ppc_get_tb(env) >> 32; 38 } 39 40 uint64_t cpu_ppc_load_atbl(CPUPPCState *env) 41 { 42 return cpu_ppc_get_tb(env); 43 } 44 45 uint32_t cpu_ppc_load_atbu(CPUPPCState *env) 46 { 47 return cpu_ppc_get_tb(env) >> 32; 48 } 49 50 uint32_t cpu_ppc601_load_rtcu(CPUPPCState *env) 51 __attribute__ (( alias ("cpu_ppc_load_tbu") )); 52 53 uint32_t cpu_ppc601_load_rtcl(CPUPPCState *env) 54 { 55 return cpu_ppc_load_tbl(env) & 0x3FFFFF80; 56 } 57 58 /* XXX: to be fixed */ 59 int ppc_dcr_read (ppc_dcr_t *dcr_env, int dcrn, uint32_t *valp) 60 { 61 return -1; 62 } 63 64 int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, uint32_t val) 65 { 66 return -1; 67 } 68 69 void cpu_loop(CPUPPCState *env) 70 { 71 CPUState *cs = env_cpu(env); 72 target_siginfo_t info; 73 int trapnr; 74 target_ulong ret; 75 76 for(;;) { 77 bool arch_interrupt; 78 79 cpu_exec_start(cs); 80 trapnr = cpu_exec(cs); 81 cpu_exec_end(cs); 82 process_queued_cpu_work(cs); 83 84 arch_interrupt = true; 85 switch (trapnr) { 86 case POWERPC_EXCP_NONE: 87 /* Just go on */ 88 break; 89 case POWERPC_EXCP_CRITICAL: /* Critical input */ 90 cpu_abort(cs, "Critical interrupt while in user mode. " 91 "Aborting\n"); 92 break; 93 case POWERPC_EXCP_MCHECK: /* Machine check exception */ 94 cpu_abort(cs, "Machine check exception while in user mode. " 95 "Aborting\n"); 96 break; 97 case POWERPC_EXCP_DSI: /* Data storage exception */ 98 /* XXX: check this. Seems bugged */ 99 switch (env->error_code & 0xFF000000) { 100 case 0x40000000: 101 case 0x42000000: 102 info.si_signo = TARGET_SIGSEGV; 103 info.si_errno = 0; 104 info.si_code = TARGET_SEGV_MAPERR; 105 break; 106 case 0x04000000: 107 info.si_signo = TARGET_SIGILL; 108 info.si_errno = 0; 109 info.si_code = TARGET_ILL_ILLADR; 110 break; 111 case 0x08000000: 112 info.si_signo = TARGET_SIGSEGV; 113 info.si_errno = 0; 114 info.si_code = TARGET_SEGV_ACCERR; 115 break; 116 default: 117 /* Let's send a regular segfault... */ 118 EXCP_DUMP(env, "Invalid segfault errno (%02x)\n", 119 env->error_code); 120 info.si_signo = TARGET_SIGSEGV; 121 info.si_errno = 0; 122 info.si_code = TARGET_SEGV_MAPERR; 123 break; 124 } 125 info._sifields._sigfault._addr = env->spr[SPR_DAR]; 126 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); 127 break; 128 case POWERPC_EXCP_ISI: /* Instruction storage exception */ 129 /* XXX: check this */ 130 switch (env->error_code & 0xFF000000) { 131 case 0x40000000: 132 info.si_signo = TARGET_SIGSEGV; 133 info.si_errno = 0; 134 info.si_code = TARGET_SEGV_MAPERR; 135 break; 136 case 0x10000000: 137 case 0x08000000: 138 info.si_signo = TARGET_SIGSEGV; 139 info.si_errno = 0; 140 info.si_code = TARGET_SEGV_ACCERR; 141 break; 142 default: 143 /* Let's send a regular segfault... */ 144 EXCP_DUMP(env, "Invalid segfault errno (%02x)\n", 145 env->error_code); 146 info.si_signo = TARGET_SIGSEGV; 147 info.si_errno = 0; 148 info.si_code = TARGET_SEGV_MAPERR; 149 break; 150 } 151 info._sifields._sigfault._addr = env->nip - 4; 152 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); 153 break; 154 case POWERPC_EXCP_EXTERNAL: /* External input */ 155 cpu_abort(cs, "External interrupt while in user mode. " 156 "Aborting\n"); 157 break; 158 case POWERPC_EXCP_ALIGN: /* Alignment exception */ 159 /* XXX: check this */ 160 info.si_signo = TARGET_SIGBUS; 161 info.si_errno = 0; 162 info.si_code = TARGET_BUS_ADRALN; 163 info._sifields._sigfault._addr = env->nip; 164 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); 165 break; 166 case POWERPC_EXCP_PROGRAM: /* Program exception */ 167 case POWERPC_EXCP_HV_EMU: /* HV emulation */ 168 /* XXX: check this */ 169 switch (env->error_code & ~0xF) { 170 case POWERPC_EXCP_FP: 171 info.si_signo = TARGET_SIGFPE; 172 info.si_errno = 0; 173 switch (env->error_code & 0xF) { 174 case POWERPC_EXCP_FP_OX: 175 info.si_code = TARGET_FPE_FLTOVF; 176 break; 177 case POWERPC_EXCP_FP_UX: 178 info.si_code = TARGET_FPE_FLTUND; 179 break; 180 case POWERPC_EXCP_FP_ZX: 181 case POWERPC_EXCP_FP_VXZDZ: 182 info.si_code = TARGET_FPE_FLTDIV; 183 break; 184 case POWERPC_EXCP_FP_XX: 185 info.si_code = TARGET_FPE_FLTRES; 186 break; 187 case POWERPC_EXCP_FP_VXSOFT: 188 info.si_code = TARGET_FPE_FLTINV; 189 break; 190 case POWERPC_EXCP_FP_VXSNAN: 191 case POWERPC_EXCP_FP_VXISI: 192 case POWERPC_EXCP_FP_VXIDI: 193 case POWERPC_EXCP_FP_VXIMZ: 194 case POWERPC_EXCP_FP_VXVC: 195 case POWERPC_EXCP_FP_VXSQRT: 196 case POWERPC_EXCP_FP_VXCVI: 197 info.si_code = TARGET_FPE_FLTSUB; 198 break; 199 default: 200 EXCP_DUMP(env, "Unknown floating point exception (%02x)\n", 201 env->error_code); 202 break; 203 } 204 break; 205 case POWERPC_EXCP_INVAL: 206 info.si_signo = TARGET_SIGILL; 207 info.si_errno = 0; 208 switch (env->error_code & 0xF) { 209 case POWERPC_EXCP_INVAL_INVAL: 210 info.si_code = TARGET_ILL_ILLOPC; 211 break; 212 case POWERPC_EXCP_INVAL_LSWX: 213 info.si_code = TARGET_ILL_ILLOPN; 214 break; 215 case POWERPC_EXCP_INVAL_SPR: 216 info.si_code = TARGET_ILL_PRVREG; 217 break; 218 case POWERPC_EXCP_INVAL_FP: 219 info.si_code = TARGET_ILL_COPROC; 220 break; 221 default: 222 EXCP_DUMP(env, "Unknown invalid operation (%02x)\n", 223 env->error_code & 0xF); 224 info.si_code = TARGET_ILL_ILLADR; 225 break; 226 } 227 break; 228 case POWERPC_EXCP_PRIV: 229 info.si_signo = TARGET_SIGILL; 230 info.si_errno = 0; 231 switch (env->error_code & 0xF) { 232 case POWERPC_EXCP_PRIV_OPC: 233 info.si_code = TARGET_ILL_PRVOPC; 234 break; 235 case POWERPC_EXCP_PRIV_REG: 236 info.si_code = TARGET_ILL_PRVREG; 237 break; 238 default: 239 EXCP_DUMP(env, "Unknown privilege violation (%02x)\n", 240 env->error_code & 0xF); 241 info.si_code = TARGET_ILL_PRVOPC; 242 break; 243 } 244 break; 245 case POWERPC_EXCP_TRAP: 246 cpu_abort(cs, "Tried to call a TRAP\n"); 247 break; 248 default: 249 /* Should not happen ! */ 250 cpu_abort(cs, "Unknown program exception (%02x)\n", 251 env->error_code); 252 break; 253 } 254 info._sifields._sigfault._addr = env->nip; 255 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); 256 break; 257 case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */ 258 info.si_signo = TARGET_SIGILL; 259 info.si_errno = 0; 260 info.si_code = TARGET_ILL_COPROC; 261 info._sifields._sigfault._addr = env->nip; 262 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); 263 break; 264 case POWERPC_EXCP_SYSCALL: /* System call exception */ 265 cpu_abort(cs, "Syscall exception while in user mode. " 266 "Aborting\n"); 267 break; 268 case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */ 269 info.si_signo = TARGET_SIGILL; 270 info.si_errno = 0; 271 info.si_code = TARGET_ILL_COPROC; 272 info._sifields._sigfault._addr = env->nip; 273 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); 274 break; 275 case POWERPC_EXCP_DECR: /* Decrementer exception */ 276 cpu_abort(cs, "Decrementer interrupt while in user mode. " 277 "Aborting\n"); 278 break; 279 case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt */ 280 cpu_abort(cs, "Fix interval timer interrupt while in user mode. " 281 "Aborting\n"); 282 break; 283 case POWERPC_EXCP_WDT: /* Watchdog timer interrupt */ 284 cpu_abort(cs, "Watchdog timer interrupt while in user mode. " 285 "Aborting\n"); 286 break; 287 case POWERPC_EXCP_DTLB: /* Data TLB error */ 288 cpu_abort(cs, "Data TLB exception while in user mode. " 289 "Aborting\n"); 290 break; 291 case POWERPC_EXCP_ITLB: /* Instruction TLB error */ 292 cpu_abort(cs, "Instruction TLB exception while in user mode. " 293 "Aborting\n"); 294 break; 295 case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavail. */ 296 info.si_signo = TARGET_SIGILL; 297 info.si_errno = 0; 298 info.si_code = TARGET_ILL_COPROC; 299 info._sifields._sigfault._addr = env->nip; 300 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); 301 break; 302 case POWERPC_EXCP_EFPDI: /* Embedded floating-point data IRQ */ 303 cpu_abort(cs, "Embedded floating-point data IRQ not handled\n"); 304 break; 305 case POWERPC_EXCP_EFPRI: /* Embedded floating-point round IRQ */ 306 cpu_abort(cs, "Embedded floating-point round IRQ not handled\n"); 307 break; 308 case POWERPC_EXCP_EPERFM: /* Embedded performance monitor IRQ */ 309 cpu_abort(cs, "Performance monitor exception not handled\n"); 310 break; 311 case POWERPC_EXCP_DOORI: /* Embedded doorbell interrupt */ 312 cpu_abort(cs, "Doorbell interrupt while in user mode. " 313 "Aborting\n"); 314 break; 315 case POWERPC_EXCP_DOORCI: /* Embedded doorbell critical interrupt */ 316 cpu_abort(cs, "Doorbell critical interrupt while in user mode. " 317 "Aborting\n"); 318 break; 319 case POWERPC_EXCP_RESET: /* System reset exception */ 320 cpu_abort(cs, "Reset interrupt while in user mode. " 321 "Aborting\n"); 322 break; 323 case POWERPC_EXCP_DSEG: /* Data segment exception */ 324 cpu_abort(cs, "Data segment exception while in user mode. " 325 "Aborting\n"); 326 break; 327 case POWERPC_EXCP_ISEG: /* Instruction segment exception */ 328 cpu_abort(cs, "Instruction segment exception " 329 "while in user mode. Aborting\n"); 330 break; 331 /* PowerPC 64 with hypervisor mode support */ 332 case POWERPC_EXCP_HDECR: /* Hypervisor decrementer exception */ 333 cpu_abort(cs, "Hypervisor decrementer interrupt " 334 "while in user mode. Aborting\n"); 335 break; 336 case POWERPC_EXCP_TRACE: /* Trace exception */ 337 /* Nothing to do: 338 * we use this exception to emulate step-by-step execution mode. 339 */ 340 break; 341 /* PowerPC 64 with hypervisor mode support */ 342 case POWERPC_EXCP_HDSI: /* Hypervisor data storage exception */ 343 cpu_abort(cs, "Hypervisor data storage exception " 344 "while in user mode. Aborting\n"); 345 break; 346 case POWERPC_EXCP_HISI: /* Hypervisor instruction storage excp */ 347 cpu_abort(cs, "Hypervisor instruction storage exception " 348 "while in user mode. Aborting\n"); 349 break; 350 case POWERPC_EXCP_HDSEG: /* Hypervisor data segment exception */ 351 cpu_abort(cs, "Hypervisor data segment exception " 352 "while in user mode. Aborting\n"); 353 break; 354 case POWERPC_EXCP_HISEG: /* Hypervisor instruction segment excp */ 355 cpu_abort(cs, "Hypervisor instruction segment exception " 356 "while in user mode. Aborting\n"); 357 break; 358 case POWERPC_EXCP_VPU: /* Vector unavailable exception */ 359 info.si_signo = TARGET_SIGILL; 360 info.si_errno = 0; 361 info.si_code = TARGET_ILL_COPROC; 362 info._sifields._sigfault._addr = env->nip; 363 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); 364 break; 365 case POWERPC_EXCP_PIT: /* Programmable interval timer IRQ */ 366 cpu_abort(cs, "Programmable interval timer interrupt " 367 "while in user mode. Aborting\n"); 368 break; 369 case POWERPC_EXCP_IO: /* IO error exception */ 370 cpu_abort(cs, "IO error exception while in user mode. " 371 "Aborting\n"); 372 break; 373 case POWERPC_EXCP_RUNM: /* Run mode exception */ 374 cpu_abort(cs, "Run mode exception while in user mode. " 375 "Aborting\n"); 376 break; 377 case POWERPC_EXCP_EMUL: /* Emulation trap exception */ 378 cpu_abort(cs, "Emulation trap exception not handled\n"); 379 break; 380 case POWERPC_EXCP_IFTLB: /* Instruction fetch TLB error */ 381 cpu_abort(cs, "Instruction fetch TLB exception " 382 "while in user-mode. Aborting"); 383 break; 384 case POWERPC_EXCP_DLTLB: /* Data load TLB miss */ 385 cpu_abort(cs, "Data load TLB exception while in user-mode. " 386 "Aborting"); 387 break; 388 case POWERPC_EXCP_DSTLB: /* Data store TLB miss */ 389 cpu_abort(cs, "Data store TLB exception while in user-mode. " 390 "Aborting"); 391 break; 392 case POWERPC_EXCP_FPA: /* Floating-point assist exception */ 393 cpu_abort(cs, "Floating-point assist exception not handled\n"); 394 break; 395 case POWERPC_EXCP_IABR: /* Instruction address breakpoint */ 396 cpu_abort(cs, "Instruction address breakpoint exception " 397 "not handled\n"); 398 break; 399 case POWERPC_EXCP_SMI: /* System management interrupt */ 400 cpu_abort(cs, "System management interrupt while in user mode. " 401 "Aborting\n"); 402 break; 403 case POWERPC_EXCP_THERM: /* Thermal interrupt */ 404 cpu_abort(cs, "Thermal interrupt interrupt while in user mode. " 405 "Aborting\n"); 406 break; 407 case POWERPC_EXCP_PERFM: /* Embedded performance monitor IRQ */ 408 cpu_abort(cs, "Performance monitor exception not handled\n"); 409 break; 410 case POWERPC_EXCP_VPUA: /* Vector assist exception */ 411 cpu_abort(cs, "Vector assist exception not handled\n"); 412 break; 413 case POWERPC_EXCP_SOFTP: /* Soft patch exception */ 414 cpu_abort(cs, "Soft patch exception not handled\n"); 415 break; 416 case POWERPC_EXCP_MAINT: /* Maintenance exception */ 417 cpu_abort(cs, "Maintenance exception while in user mode. " 418 "Aborting\n"); 419 break; 420 case POWERPC_EXCP_STOP: /* stop translation */ 421 /* We did invalidate the instruction cache. Go on */ 422 break; 423 case POWERPC_EXCP_BRANCH: /* branch instruction: */ 424 /* We just stopped because of a branch. Go on */ 425 break; 426 case POWERPC_EXCP_SYSCALL_USER: 427 /* system call in user-mode emulation */ 428 /* WARNING: 429 * PPC ABI uses overflow flag in cr0 to signal an error 430 * in syscalls. 431 */ 432 env->crf[0] &= ~0x1; 433 env->nip += 4; 434 ret = do_syscall(env, env->gpr[0], env->gpr[3], env->gpr[4], 435 env->gpr[5], env->gpr[6], env->gpr[7], 436 env->gpr[8], 0, 0); 437 if (ret == -TARGET_ERESTARTSYS) { 438 env->nip -= 4; 439 break; 440 } 441 if (ret == (target_ulong)(-TARGET_QEMU_ESIGRETURN)) { 442 /* Returning from a successful sigreturn syscall. 443 Avoid corrupting register state. */ 444 break; 445 } 446 if (ret > (target_ulong)(-515)) { 447 env->crf[0] |= 0x1; 448 ret = -ret; 449 } 450 env->gpr[3] = ret; 451 break; 452 case EXCP_DEBUG: 453 info.si_signo = TARGET_SIGTRAP; 454 info.si_errno = 0; 455 info.si_code = TARGET_TRAP_BRKPT; 456 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); 457 break; 458 case EXCP_INTERRUPT: 459 /* just indicate that signals should be handled asap */ 460 break; 461 case EXCP_ATOMIC: 462 cpu_exec_step_atomic(cs); 463 arch_interrupt = false; 464 break; 465 default: 466 cpu_abort(cs, "Unknown exception 0x%x. Aborting\n", trapnr); 467 break; 468 } 469 process_pending_signals(env); 470 471 /* Most of the traps imply a transition through kernel mode, 472 * which implies an REI instruction has been executed. Which 473 * means that RX and LOCK_ADDR should be cleared. But there 474 * are a few exceptions for traps internal to QEMU. 475 */ 476 if (arch_interrupt) { 477 env->reserve_addr = -1; 478 } 479 } 480 } 481 482 void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs) 483 { 484 int i; 485 486 #if defined(TARGET_PPC64) 487 int flag = (env->insns_flags2 & PPC2_BOOKE206) ? MSR_CM : MSR_SF; 488 #if defined(TARGET_ABI32) 489 env->msr &= ~((target_ulong)1 << flag); 490 #else 491 env->msr |= (target_ulong)1 << flag; 492 #endif 493 #endif 494 env->nip = regs->nip; 495 for(i = 0; i < 32; i++) { 496 env->gpr[i] = regs->gpr[i]; 497 } 498 } 499