1 /* 2 * PowerPC exception emulation helpers for QEMU. 3 * 4 * Copyright (c) 2003-2007 Jocelyn Mayer 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library 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 GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 18 */ 19 #include "qemu/osdep.h" 20 #include "qemu/main-loop.h" 21 #include "cpu.h" 22 #include "exec/helper-proto.h" 23 #include "exec/exec-all.h" 24 #include "exec/cpu_ldst.h" 25 #include "internal.h" 26 #include "helper_regs.h" 27 28 /* #define DEBUG_OP */ 29 /* #define DEBUG_SOFTWARE_TLB */ 30 /* #define DEBUG_EXCEPTIONS */ 31 32 #ifdef DEBUG_EXCEPTIONS 33 # define LOG_EXCP(...) qemu_log(__VA_ARGS__) 34 #else 35 # define LOG_EXCP(...) do { } while (0) 36 #endif 37 38 /*****************************************************************************/ 39 /* Exception processing */ 40 #if defined(CONFIG_USER_ONLY) 41 void ppc_cpu_do_interrupt(CPUState *cs) 42 { 43 PowerPCCPU *cpu = POWERPC_CPU(cs); 44 CPUPPCState *env = &cpu->env; 45 46 cs->exception_index = POWERPC_EXCP_NONE; 47 env->error_code = 0; 48 } 49 50 static void ppc_hw_interrupt(CPUPPCState *env) 51 { 52 CPUState *cs = env_cpu(env); 53 54 cs->exception_index = POWERPC_EXCP_NONE; 55 env->error_code = 0; 56 } 57 #else /* defined(CONFIG_USER_ONLY) */ 58 static inline void dump_syscall(CPUPPCState *env) 59 { 60 qemu_log_mask(CPU_LOG_INT, "syscall r0=%016" PRIx64 61 " r3=%016" PRIx64 " r4=%016" PRIx64 " r5=%016" PRIx64 62 " r6=%016" PRIx64 " r7=%016" PRIx64 " r8=%016" PRIx64 63 " nip=" TARGET_FMT_lx "\n", 64 ppc_dump_gpr(env, 0), ppc_dump_gpr(env, 3), 65 ppc_dump_gpr(env, 4), ppc_dump_gpr(env, 5), 66 ppc_dump_gpr(env, 6), ppc_dump_gpr(env, 7), 67 ppc_dump_gpr(env, 8), env->nip); 68 } 69 70 static inline void dump_syscall_vectored(CPUPPCState *env) 71 { 72 qemu_log_mask(CPU_LOG_INT, "syscall r0=%016" PRIx64 73 " r3=%016" PRIx64 " r4=%016" PRIx64 " r5=%016" PRIx64 74 " r6=%016" PRIx64 " r7=%016" PRIx64 " r8=%016" PRIx64 75 " nip=" TARGET_FMT_lx "\n", 76 ppc_dump_gpr(env, 0), ppc_dump_gpr(env, 3), 77 ppc_dump_gpr(env, 4), ppc_dump_gpr(env, 5), 78 ppc_dump_gpr(env, 6), ppc_dump_gpr(env, 7), 79 ppc_dump_gpr(env, 8), env->nip); 80 } 81 82 static inline void dump_hcall(CPUPPCState *env) 83 { 84 qemu_log_mask(CPU_LOG_INT, "hypercall r3=%016" PRIx64 85 " r4=%016" PRIx64 " r5=%016" PRIx64 " r6=%016" PRIx64 86 " r7=%016" PRIx64 " r8=%016" PRIx64 " r9=%016" PRIx64 87 " r10=%016" PRIx64 " r11=%016" PRIx64 " r12=%016" PRIx64 88 " nip=" TARGET_FMT_lx "\n", 89 ppc_dump_gpr(env, 3), ppc_dump_gpr(env, 4), 90 ppc_dump_gpr(env, 5), ppc_dump_gpr(env, 6), 91 ppc_dump_gpr(env, 7), ppc_dump_gpr(env, 8), 92 ppc_dump_gpr(env, 9), ppc_dump_gpr(env, 10), 93 ppc_dump_gpr(env, 11), ppc_dump_gpr(env, 12), 94 env->nip); 95 } 96 97 static int powerpc_reset_wakeup(CPUState *cs, CPUPPCState *env, int excp, 98 target_ulong *msr) 99 { 100 /* We no longer are in a PM state */ 101 env->resume_as_sreset = false; 102 103 /* Pretend to be returning from doze always as we don't lose state */ 104 *msr |= SRR1_WS_NOLOSS; 105 106 /* Machine checks are sent normally */ 107 if (excp == POWERPC_EXCP_MCHECK) { 108 return excp; 109 } 110 switch (excp) { 111 case POWERPC_EXCP_RESET: 112 *msr |= SRR1_WAKERESET; 113 break; 114 case POWERPC_EXCP_EXTERNAL: 115 *msr |= SRR1_WAKEEE; 116 break; 117 case POWERPC_EXCP_DECR: 118 *msr |= SRR1_WAKEDEC; 119 break; 120 case POWERPC_EXCP_SDOOR: 121 *msr |= SRR1_WAKEDBELL; 122 break; 123 case POWERPC_EXCP_SDOOR_HV: 124 *msr |= SRR1_WAKEHDBELL; 125 break; 126 case POWERPC_EXCP_HV_MAINT: 127 *msr |= SRR1_WAKEHMI; 128 break; 129 case POWERPC_EXCP_HVIRT: 130 *msr |= SRR1_WAKEHVI; 131 break; 132 default: 133 cpu_abort(cs, "Unsupported exception %d in Power Save mode\n", 134 excp); 135 } 136 return POWERPC_EXCP_RESET; 137 } 138 139 static uint64_t ppc_excp_vector_offset(CPUState *cs, int ail) 140 { 141 uint64_t offset = 0; 142 143 switch (ail) { 144 case AIL_NONE: 145 break; 146 case AIL_0001_8000: 147 offset = 0x18000; 148 break; 149 case AIL_C000_0000_0000_4000: 150 offset = 0xc000000000004000ull; 151 break; 152 default: 153 cpu_abort(cs, "Invalid AIL combination %d\n", ail); 154 break; 155 } 156 157 return offset; 158 } 159 160 static inline void powerpc_set_excp_state(PowerPCCPU *cpu, 161 target_ulong vector, target_ulong msr) 162 { 163 CPUState *cs = CPU(cpu); 164 CPUPPCState *env = &cpu->env; 165 166 /* 167 * We don't use hreg_store_msr here as already have treated any 168 * special case that could occur. Just store MSR and update hflags 169 * 170 * Note: We *MUST* not use hreg_store_msr() as-is anyway because it 171 * will prevent setting of the HV bit which some exceptions might need 172 * to do. 173 */ 174 env->msr = msr & env->msr_mask; 175 hreg_compute_hflags(env); 176 env->nip = vector; 177 /* Reset exception state */ 178 cs->exception_index = POWERPC_EXCP_NONE; 179 env->error_code = 0; 180 181 /* Reset the reservation */ 182 env->reserve_addr = -1; 183 184 /* 185 * Any interrupt is context synchronizing, check if TCG TLB needs 186 * a delayed flush on ppc64 187 */ 188 check_tlb_flush(env, false); 189 } 190 191 /* 192 * Note that this function should be greatly optimized when called 193 * with a constant excp, from ppc_hw_interrupt 194 */ 195 static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) 196 { 197 CPUState *cs = CPU(cpu); 198 CPUPPCState *env = &cpu->env; 199 target_ulong msr, new_msr, vector; 200 int srr0, srr1, asrr0, asrr1, lev = -1, ail; 201 bool lpes0; 202 203 qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx 204 " => %08x (%02x)\n", env->nip, excp, env->error_code); 205 206 /* new srr1 value excluding must-be-zero bits */ 207 if (excp_model == POWERPC_EXCP_BOOKE) { 208 msr = env->msr; 209 } else { 210 msr = env->msr & ~0x783f0000ULL; 211 } 212 213 /* 214 * new interrupt handler msr preserves existing HV and ME unless 215 * explicitly overriden 216 */ 217 new_msr = env->msr & (((target_ulong)1 << MSR_ME) | MSR_HVB); 218 219 /* target registers */ 220 srr0 = SPR_SRR0; 221 srr1 = SPR_SRR1; 222 asrr0 = -1; 223 asrr1 = -1; 224 225 /* 226 * check for special resume at 0x100 from doze/nap/sleep/winkle on 227 * P7/P8/P9 228 */ 229 if (env->resume_as_sreset) { 230 excp = powerpc_reset_wakeup(cs, env, excp, &msr); 231 } 232 233 /* 234 * Exception targeting modifiers 235 * 236 * LPES0 is supported on POWER7/8/9 237 * LPES1 is not supported (old iSeries mode) 238 * 239 * On anything else, we behave as if LPES0 is 1 240 * (externals don't alter MSR:HV) 241 * 242 * AIL is initialized here but can be cleared by 243 * selected exceptions 244 */ 245 #if defined(TARGET_PPC64) 246 if (excp_model == POWERPC_EXCP_POWER7 || 247 excp_model == POWERPC_EXCP_POWER8 || 248 excp_model == POWERPC_EXCP_POWER9) { 249 lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0); 250 if (excp_model != POWERPC_EXCP_POWER7) { 251 ail = (env->spr[SPR_LPCR] & LPCR_AIL) >> LPCR_AIL_SHIFT; 252 } else { 253 ail = 0; 254 } 255 } else 256 #endif /* defined(TARGET_PPC64) */ 257 { 258 lpes0 = true; 259 ail = 0; 260 } 261 262 /* 263 * Hypervisor emulation assistance interrupt only exists on server 264 * arch 2.05 server or later. We also don't want to generate it if 265 * we don't have HVB in msr_mask (PAPR mode). 266 */ 267 if (excp == POWERPC_EXCP_HV_EMU 268 #if defined(TARGET_PPC64) 269 && !(mmu_is_64bit(env->mmu_model) && (env->msr_mask & MSR_HVB)) 270 #endif /* defined(TARGET_PPC64) */ 271 272 ) { 273 excp = POWERPC_EXCP_PROGRAM; 274 } 275 276 switch (excp) { 277 case POWERPC_EXCP_NONE: 278 /* Should never happen */ 279 return; 280 case POWERPC_EXCP_CRITICAL: /* Critical input */ 281 switch (excp_model) { 282 case POWERPC_EXCP_40x: 283 srr0 = SPR_40x_SRR2; 284 srr1 = SPR_40x_SRR3; 285 break; 286 case POWERPC_EXCP_BOOKE: 287 srr0 = SPR_BOOKE_CSRR0; 288 srr1 = SPR_BOOKE_CSRR1; 289 break; 290 case POWERPC_EXCP_G2: 291 break; 292 default: 293 goto excp_invalid; 294 } 295 break; 296 case POWERPC_EXCP_MCHECK: /* Machine check exception */ 297 if (msr_me == 0) { 298 /* 299 * Machine check exception is not enabled. Enter 300 * checkstop state. 301 */ 302 fprintf(stderr, "Machine check while not allowed. " 303 "Entering checkstop state\n"); 304 if (qemu_log_separate()) { 305 qemu_log("Machine check while not allowed. " 306 "Entering checkstop state\n"); 307 } 308 cs->halted = 1; 309 cpu_interrupt_exittb(cs); 310 } 311 if (env->msr_mask & MSR_HVB) { 312 /* 313 * ISA specifies HV, but can be delivered to guest with HV 314 * clear (e.g., see FWNMI in PAPR). 315 */ 316 new_msr |= (target_ulong)MSR_HVB; 317 } 318 ail = 0; 319 320 /* machine check exceptions don't have ME set */ 321 new_msr &= ~((target_ulong)1 << MSR_ME); 322 323 /* XXX: should also have something loaded in DAR / DSISR */ 324 switch (excp_model) { 325 case POWERPC_EXCP_40x: 326 srr0 = SPR_40x_SRR2; 327 srr1 = SPR_40x_SRR3; 328 break; 329 case POWERPC_EXCP_BOOKE: 330 /* FIXME: choose one or the other based on CPU type */ 331 srr0 = SPR_BOOKE_MCSRR0; 332 srr1 = SPR_BOOKE_MCSRR1; 333 asrr0 = SPR_BOOKE_CSRR0; 334 asrr1 = SPR_BOOKE_CSRR1; 335 break; 336 default: 337 break; 338 } 339 break; 340 case POWERPC_EXCP_DSI: /* Data storage exception */ 341 LOG_EXCP("DSI exception: DSISR=" TARGET_FMT_lx" DAR=" TARGET_FMT_lx 342 "\n", env->spr[SPR_DSISR], env->spr[SPR_DAR]); 343 break; 344 case POWERPC_EXCP_ISI: /* Instruction storage exception */ 345 LOG_EXCP("ISI exception: msr=" TARGET_FMT_lx ", nip=" TARGET_FMT_lx 346 "\n", msr, env->nip); 347 msr |= env->error_code; 348 break; 349 case POWERPC_EXCP_EXTERNAL: /* External input */ 350 cs = CPU(cpu); 351 352 if (!lpes0) { 353 new_msr |= (target_ulong)MSR_HVB; 354 new_msr |= env->msr & ((target_ulong)1 << MSR_RI); 355 srr0 = SPR_HSRR0; 356 srr1 = SPR_HSRR1; 357 } 358 if (env->mpic_proxy) { 359 /* IACK the IRQ on delivery */ 360 env->spr[SPR_BOOKE_EPR] = ldl_phys(cs->as, env->mpic_iack); 361 } 362 break; 363 case POWERPC_EXCP_ALIGN: /* Alignment exception */ 364 /* Get rS/rD and rA from faulting opcode */ 365 /* 366 * Note: the opcode fields will not be set properly for a 367 * direct store load/store, but nobody cares as nobody 368 * actually uses direct store segments. 369 */ 370 env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16; 371 break; 372 case POWERPC_EXCP_PROGRAM: /* Program exception */ 373 switch (env->error_code & ~0xF) { 374 case POWERPC_EXCP_FP: 375 if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) { 376 LOG_EXCP("Ignore floating point exception\n"); 377 cs->exception_index = POWERPC_EXCP_NONE; 378 env->error_code = 0; 379 return; 380 } 381 382 /* 383 * FP exceptions always have NIP pointing to the faulting 384 * instruction, so always use store_next and claim we are 385 * precise in the MSR. 386 */ 387 msr |= 0x00100000; 388 env->spr[SPR_BOOKE_ESR] = ESR_FP; 389 break; 390 case POWERPC_EXCP_INVAL: 391 LOG_EXCP("Invalid instruction at " TARGET_FMT_lx "\n", env->nip); 392 msr |= 0x00080000; 393 env->spr[SPR_BOOKE_ESR] = ESR_PIL; 394 break; 395 case POWERPC_EXCP_PRIV: 396 msr |= 0x00040000; 397 env->spr[SPR_BOOKE_ESR] = ESR_PPR; 398 break; 399 case POWERPC_EXCP_TRAP: 400 msr |= 0x00020000; 401 env->spr[SPR_BOOKE_ESR] = ESR_PTR; 402 break; 403 default: 404 /* Should never occur */ 405 cpu_abort(cs, "Invalid program exception %d. Aborting\n", 406 env->error_code); 407 break; 408 } 409 break; 410 case POWERPC_EXCP_SYSCALL: /* System call exception */ 411 lev = env->error_code; 412 413 if ((lev == 1) && cpu->vhyp) { 414 dump_hcall(env); 415 } else { 416 dump_syscall(env); 417 } 418 419 /* 420 * We need to correct the NIP which in this case is supposed 421 * to point to the next instruction 422 */ 423 env->nip += 4; 424 425 /* "PAPR mode" built-in hypercall emulation */ 426 if ((lev == 1) && cpu->vhyp) { 427 PPCVirtualHypervisorClass *vhc = 428 PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp); 429 vhc->hypercall(cpu->vhyp, cpu); 430 return; 431 } 432 if (lev == 1) { 433 new_msr |= (target_ulong)MSR_HVB; 434 } 435 break; 436 case POWERPC_EXCP_SYSCALL_VECTORED: /* scv exception */ 437 lev = env->error_code; 438 dump_syscall_vectored(env); 439 env->nip += 4; 440 new_msr |= env->msr & ((target_ulong)1 << MSR_EE); 441 new_msr |= env->msr & ((target_ulong)1 << MSR_RI); 442 break; 443 case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */ 444 case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */ 445 case POWERPC_EXCP_DECR: /* Decrementer exception */ 446 break; 447 case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt */ 448 /* FIT on 4xx */ 449 LOG_EXCP("FIT exception\n"); 450 break; 451 case POWERPC_EXCP_WDT: /* Watchdog timer interrupt */ 452 LOG_EXCP("WDT exception\n"); 453 switch (excp_model) { 454 case POWERPC_EXCP_BOOKE: 455 srr0 = SPR_BOOKE_CSRR0; 456 srr1 = SPR_BOOKE_CSRR1; 457 break; 458 default: 459 break; 460 } 461 break; 462 case POWERPC_EXCP_DTLB: /* Data TLB error */ 463 case POWERPC_EXCP_ITLB: /* Instruction TLB error */ 464 break; 465 case POWERPC_EXCP_DEBUG: /* Debug interrupt */ 466 if (env->flags & POWERPC_FLAG_DE) { 467 /* FIXME: choose one or the other based on CPU type */ 468 srr0 = SPR_BOOKE_DSRR0; 469 srr1 = SPR_BOOKE_DSRR1; 470 asrr0 = SPR_BOOKE_CSRR0; 471 asrr1 = SPR_BOOKE_CSRR1; 472 /* DBSR already modified by caller */ 473 } else { 474 cpu_abort(cs, "Debug exception triggered on unsupported model\n"); 475 } 476 break; 477 case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavailable */ 478 env->spr[SPR_BOOKE_ESR] = ESR_SPV; 479 break; 480 case POWERPC_EXCP_EFPDI: /* Embedded floating-point data interrupt */ 481 /* XXX: TODO */ 482 cpu_abort(cs, "Embedded floating point data exception " 483 "is not implemented yet !\n"); 484 env->spr[SPR_BOOKE_ESR] = ESR_SPV; 485 break; 486 case POWERPC_EXCP_EFPRI: /* Embedded floating-point round interrupt */ 487 /* XXX: TODO */ 488 cpu_abort(cs, "Embedded floating point round exception " 489 "is not implemented yet !\n"); 490 env->spr[SPR_BOOKE_ESR] = ESR_SPV; 491 break; 492 case POWERPC_EXCP_EPERFM: /* Embedded performance monitor interrupt */ 493 /* XXX: TODO */ 494 cpu_abort(cs, 495 "Performance counter exception is not implemented yet !\n"); 496 break; 497 case POWERPC_EXCP_DOORI: /* Embedded doorbell interrupt */ 498 break; 499 case POWERPC_EXCP_DOORCI: /* Embedded doorbell critical interrupt */ 500 srr0 = SPR_BOOKE_CSRR0; 501 srr1 = SPR_BOOKE_CSRR1; 502 break; 503 case POWERPC_EXCP_RESET: /* System reset exception */ 504 /* A power-saving exception sets ME, otherwise it is unchanged */ 505 if (msr_pow) { 506 /* indicate that we resumed from power save mode */ 507 msr |= 0x10000; 508 new_msr |= ((target_ulong)1 << MSR_ME); 509 } 510 if (env->msr_mask & MSR_HVB) { 511 /* 512 * ISA specifies HV, but can be delivered to guest with HV 513 * clear (e.g., see FWNMI in PAPR, NMI injection in QEMU). 514 */ 515 new_msr |= (target_ulong)MSR_HVB; 516 } else { 517 if (msr_pow) { 518 cpu_abort(cs, "Trying to deliver power-saving system reset " 519 "exception %d with no HV support\n", excp); 520 } 521 } 522 ail = 0; 523 break; 524 case POWERPC_EXCP_DSEG: /* Data segment exception */ 525 case POWERPC_EXCP_ISEG: /* Instruction segment exception */ 526 case POWERPC_EXCP_TRACE: /* Trace exception */ 527 break; 528 case POWERPC_EXCP_HISI: /* Hypervisor instruction storage exception */ 529 msr |= env->error_code; 530 /* fall through */ 531 case POWERPC_EXCP_HDECR: /* Hypervisor decrementer exception */ 532 case POWERPC_EXCP_HDSI: /* Hypervisor data storage exception */ 533 case POWERPC_EXCP_HDSEG: /* Hypervisor data segment exception */ 534 case POWERPC_EXCP_HISEG: /* Hypervisor instruction segment exception */ 535 case POWERPC_EXCP_SDOOR_HV: /* Hypervisor Doorbell interrupt */ 536 case POWERPC_EXCP_HV_EMU: 537 case POWERPC_EXCP_HVIRT: /* Hypervisor virtualization */ 538 srr0 = SPR_HSRR0; 539 srr1 = SPR_HSRR1; 540 new_msr |= (target_ulong)MSR_HVB; 541 new_msr |= env->msr & ((target_ulong)1 << MSR_RI); 542 break; 543 case POWERPC_EXCP_VPU: /* Vector unavailable exception */ 544 case POWERPC_EXCP_VSXU: /* VSX unavailable exception */ 545 case POWERPC_EXCP_FU: /* Facility unavailable exception */ 546 #ifdef TARGET_PPC64 547 env->spr[SPR_FSCR] |= ((target_ulong)env->error_code << 56); 548 #endif 549 break; 550 case POWERPC_EXCP_HV_FU: /* Hypervisor Facility Unavailable Exception */ 551 #ifdef TARGET_PPC64 552 env->spr[SPR_HFSCR] |= ((target_ulong)env->error_code << FSCR_IC_POS); 553 srr0 = SPR_HSRR0; 554 srr1 = SPR_HSRR1; 555 new_msr |= (target_ulong)MSR_HVB; 556 new_msr |= env->msr & ((target_ulong)1 << MSR_RI); 557 #endif 558 break; 559 case POWERPC_EXCP_PIT: /* Programmable interval timer interrupt */ 560 LOG_EXCP("PIT exception\n"); 561 break; 562 case POWERPC_EXCP_IO: /* IO error exception */ 563 /* XXX: TODO */ 564 cpu_abort(cs, "601 IO error exception is not implemented yet !\n"); 565 break; 566 case POWERPC_EXCP_RUNM: /* Run mode exception */ 567 /* XXX: TODO */ 568 cpu_abort(cs, "601 run mode exception is not implemented yet !\n"); 569 break; 570 case POWERPC_EXCP_EMUL: /* Emulation trap exception */ 571 /* XXX: TODO */ 572 cpu_abort(cs, "602 emulation trap exception " 573 "is not implemented yet !\n"); 574 break; 575 case POWERPC_EXCP_IFTLB: /* Instruction fetch TLB error */ 576 switch (excp_model) { 577 case POWERPC_EXCP_602: 578 case POWERPC_EXCP_603: 579 case POWERPC_EXCP_603E: 580 case POWERPC_EXCP_G2: 581 goto tlb_miss_tgpr; 582 case POWERPC_EXCP_7x5: 583 goto tlb_miss; 584 case POWERPC_EXCP_74xx: 585 goto tlb_miss_74xx; 586 default: 587 cpu_abort(cs, "Invalid instruction TLB miss exception\n"); 588 break; 589 } 590 break; 591 case POWERPC_EXCP_DLTLB: /* Data load TLB miss */ 592 switch (excp_model) { 593 case POWERPC_EXCP_602: 594 case POWERPC_EXCP_603: 595 case POWERPC_EXCP_603E: 596 case POWERPC_EXCP_G2: 597 goto tlb_miss_tgpr; 598 case POWERPC_EXCP_7x5: 599 goto tlb_miss; 600 case POWERPC_EXCP_74xx: 601 goto tlb_miss_74xx; 602 default: 603 cpu_abort(cs, "Invalid data load TLB miss exception\n"); 604 break; 605 } 606 break; 607 case POWERPC_EXCP_DSTLB: /* Data store TLB miss */ 608 switch (excp_model) { 609 case POWERPC_EXCP_602: 610 case POWERPC_EXCP_603: 611 case POWERPC_EXCP_603E: 612 case POWERPC_EXCP_G2: 613 tlb_miss_tgpr: 614 /* Swap temporary saved registers with GPRs */ 615 if (!(new_msr & ((target_ulong)1 << MSR_TGPR))) { 616 new_msr |= (target_ulong)1 << MSR_TGPR; 617 hreg_swap_gpr_tgpr(env); 618 } 619 goto tlb_miss; 620 case POWERPC_EXCP_7x5: 621 tlb_miss: 622 #if defined(DEBUG_SOFTWARE_TLB) 623 if (qemu_log_enabled()) { 624 const char *es; 625 target_ulong *miss, *cmp; 626 int en; 627 628 if (excp == POWERPC_EXCP_IFTLB) { 629 es = "I"; 630 en = 'I'; 631 miss = &env->spr[SPR_IMISS]; 632 cmp = &env->spr[SPR_ICMP]; 633 } else { 634 if (excp == POWERPC_EXCP_DLTLB) { 635 es = "DL"; 636 } else { 637 es = "DS"; 638 } 639 en = 'D'; 640 miss = &env->spr[SPR_DMISS]; 641 cmp = &env->spr[SPR_DCMP]; 642 } 643 qemu_log("6xx %sTLB miss: %cM " TARGET_FMT_lx " %cC " 644 TARGET_FMT_lx " H1 " TARGET_FMT_lx " H2 " 645 TARGET_FMT_lx " %08x\n", es, en, *miss, en, *cmp, 646 env->spr[SPR_HASH1], env->spr[SPR_HASH2], 647 env->error_code); 648 } 649 #endif 650 msr |= env->crf[0] << 28; 651 msr |= env->error_code; /* key, D/I, S/L bits */ 652 /* Set way using a LRU mechanism */ 653 msr |= ((env->last_way + 1) & (env->nb_ways - 1)) << 17; 654 break; 655 case POWERPC_EXCP_74xx: 656 tlb_miss_74xx: 657 #if defined(DEBUG_SOFTWARE_TLB) 658 if (qemu_log_enabled()) { 659 const char *es; 660 target_ulong *miss, *cmp; 661 int en; 662 663 if (excp == POWERPC_EXCP_IFTLB) { 664 es = "I"; 665 en = 'I'; 666 miss = &env->spr[SPR_TLBMISS]; 667 cmp = &env->spr[SPR_PTEHI]; 668 } else { 669 if (excp == POWERPC_EXCP_DLTLB) { 670 es = "DL"; 671 } else { 672 es = "DS"; 673 } 674 en = 'D'; 675 miss = &env->spr[SPR_TLBMISS]; 676 cmp = &env->spr[SPR_PTEHI]; 677 } 678 qemu_log("74xx %sTLB miss: %cM " TARGET_FMT_lx " %cC " 679 TARGET_FMT_lx " %08x\n", es, en, *miss, en, *cmp, 680 env->error_code); 681 } 682 #endif 683 msr |= env->error_code; /* key bit */ 684 break; 685 default: 686 cpu_abort(cs, "Invalid data store TLB miss exception\n"); 687 break; 688 } 689 break; 690 case POWERPC_EXCP_FPA: /* Floating-point assist exception */ 691 /* XXX: TODO */ 692 cpu_abort(cs, "Floating point assist exception " 693 "is not implemented yet !\n"); 694 break; 695 case POWERPC_EXCP_DABR: /* Data address breakpoint */ 696 /* XXX: TODO */ 697 cpu_abort(cs, "DABR exception is not implemented yet !\n"); 698 break; 699 case POWERPC_EXCP_IABR: /* Instruction address breakpoint */ 700 /* XXX: TODO */ 701 cpu_abort(cs, "IABR exception is not implemented yet !\n"); 702 break; 703 case POWERPC_EXCP_SMI: /* System management interrupt */ 704 /* XXX: TODO */ 705 cpu_abort(cs, "SMI exception is not implemented yet !\n"); 706 break; 707 case POWERPC_EXCP_THERM: /* Thermal interrupt */ 708 /* XXX: TODO */ 709 cpu_abort(cs, "Thermal management exception " 710 "is not implemented yet !\n"); 711 break; 712 case POWERPC_EXCP_PERFM: /* Embedded performance monitor interrupt */ 713 /* XXX: TODO */ 714 cpu_abort(cs, 715 "Performance counter exception is not implemented yet !\n"); 716 break; 717 case POWERPC_EXCP_VPUA: /* Vector assist exception */ 718 /* XXX: TODO */ 719 cpu_abort(cs, "VPU assist exception is not implemented yet !\n"); 720 break; 721 case POWERPC_EXCP_SOFTP: /* Soft patch exception */ 722 /* XXX: TODO */ 723 cpu_abort(cs, 724 "970 soft-patch exception is not implemented yet !\n"); 725 break; 726 case POWERPC_EXCP_MAINT: /* Maintenance exception */ 727 /* XXX: TODO */ 728 cpu_abort(cs, 729 "970 maintenance exception is not implemented yet !\n"); 730 break; 731 case POWERPC_EXCP_MEXTBR: /* Maskable external breakpoint */ 732 /* XXX: TODO */ 733 cpu_abort(cs, "Maskable external exception " 734 "is not implemented yet !\n"); 735 break; 736 case POWERPC_EXCP_NMEXTBR: /* Non maskable external breakpoint */ 737 /* XXX: TODO */ 738 cpu_abort(cs, "Non maskable external exception " 739 "is not implemented yet !\n"); 740 break; 741 default: 742 excp_invalid: 743 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); 744 break; 745 } 746 747 /* Sanity check */ 748 if (!(env->msr_mask & MSR_HVB)) { 749 if (new_msr & MSR_HVB) { 750 cpu_abort(cs, "Trying to deliver HV exception (MSR) %d with " 751 "no HV support\n", excp); 752 } 753 if (srr0 == SPR_HSRR0) { 754 cpu_abort(cs, "Trying to deliver HV exception (HSRR) %d with " 755 "no HV support\n", excp); 756 } 757 } 758 759 /* 760 * Sort out endianness of interrupt, this differs depending on the 761 * CPU, the HV mode, etc... 762 */ 763 #ifdef TARGET_PPC64 764 if (excp_model == POWERPC_EXCP_POWER7) { 765 if (!(new_msr & MSR_HVB) && (env->spr[SPR_LPCR] & LPCR_ILE)) { 766 new_msr |= (target_ulong)1 << MSR_LE; 767 } 768 } else if (excp_model == POWERPC_EXCP_POWER8) { 769 if (new_msr & MSR_HVB) { 770 if (env->spr[SPR_HID0] & HID0_HILE) { 771 new_msr |= (target_ulong)1 << MSR_LE; 772 } 773 } else if (env->spr[SPR_LPCR] & LPCR_ILE) { 774 new_msr |= (target_ulong)1 << MSR_LE; 775 } 776 } else if (excp_model == POWERPC_EXCP_POWER9) { 777 if (new_msr & MSR_HVB) { 778 if (env->spr[SPR_HID0] & HID0_POWER9_HILE) { 779 new_msr |= (target_ulong)1 << MSR_LE; 780 } 781 } else if (env->spr[SPR_LPCR] & LPCR_ILE) { 782 new_msr |= (target_ulong)1 << MSR_LE; 783 } 784 } else if (msr_ile) { 785 new_msr |= (target_ulong)1 << MSR_LE; 786 } 787 #else 788 if (msr_ile) { 789 new_msr |= (target_ulong)1 << MSR_LE; 790 } 791 #endif 792 793 /* 794 * AIL only works if MSR[IR] and MSR[DR] are both enabled. 795 */ 796 if (!((msr >> MSR_IR) & 1) || !((msr >> MSR_DR) & 1)) { 797 ail = 0; 798 } 799 800 /* 801 * AIL does not work if there is a MSR[HV] 0->1 transition and the 802 * partition is in HPT mode. For radix guests, such interrupts are 803 * allowed to be delivered to the hypervisor in ail mode. 804 */ 805 if ((new_msr & MSR_HVB) && !(msr & MSR_HVB)) { 806 if (!(env->spr[SPR_LPCR] & LPCR_HR)) { 807 ail = 0; 808 } 809 } 810 811 vector = env->excp_vectors[excp]; 812 if (vector == (target_ulong)-1ULL) { 813 cpu_abort(cs, "Raised an exception without defined vector %d\n", 814 excp); 815 } 816 817 vector |= env->excp_prefix; 818 819 /* If any alternate SRR register are defined, duplicate saved values */ 820 if (asrr0 != -1) { 821 env->spr[asrr0] = env->nip; 822 } 823 if (asrr1 != -1) { 824 env->spr[asrr1] = msr; 825 } 826 827 #if defined(TARGET_PPC64) 828 if (excp_model == POWERPC_EXCP_BOOKE) { 829 if (env->spr[SPR_BOOKE_EPCR] & EPCR_ICM) { 830 /* Cat.64-bit: EPCR.ICM is copied to MSR.CM */ 831 new_msr |= (target_ulong)1 << MSR_CM; 832 } else { 833 vector = (uint32_t)vector; 834 } 835 } else { 836 if (!msr_isf && !mmu_is_64bit(env->mmu_model)) { 837 vector = (uint32_t)vector; 838 } else { 839 new_msr |= (target_ulong)1 << MSR_SF; 840 } 841 } 842 #endif 843 844 if (excp != POWERPC_EXCP_SYSCALL_VECTORED) { 845 /* Save PC */ 846 env->spr[srr0] = env->nip; 847 848 /* Save MSR */ 849 env->spr[srr1] = msr; 850 851 /* Handle AIL */ 852 if (ail) { 853 new_msr |= (1 << MSR_IR) | (1 << MSR_DR); 854 vector |= ppc_excp_vector_offset(cs, ail); 855 } 856 857 #if defined(TARGET_PPC64) 858 } else { 859 /* scv AIL is a little different */ 860 if (ail) { 861 new_msr |= (1 << MSR_IR) | (1 << MSR_DR); 862 } 863 if (ail == AIL_C000_0000_0000_4000) { 864 vector |= 0xc000000000003000ull; 865 } else { 866 vector |= 0x0000000000017000ull; 867 } 868 vector += lev * 0x20; 869 870 env->lr = env->nip; 871 env->ctr = msr; 872 #endif 873 } 874 875 powerpc_set_excp_state(cpu, vector, new_msr); 876 } 877 878 void ppc_cpu_do_interrupt(CPUState *cs) 879 { 880 PowerPCCPU *cpu = POWERPC_CPU(cs); 881 CPUPPCState *env = &cpu->env; 882 883 powerpc_excp(cpu, env->excp_model, cs->exception_index); 884 } 885 886 static void ppc_hw_interrupt(CPUPPCState *env) 887 { 888 PowerPCCPU *cpu = env_archcpu(env); 889 bool async_deliver; 890 891 /* External reset */ 892 if (env->pending_interrupts & (1 << PPC_INTERRUPT_RESET)) { 893 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_RESET); 894 powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_RESET); 895 return; 896 } 897 /* Machine check exception */ 898 if (env->pending_interrupts & (1 << PPC_INTERRUPT_MCK)) { 899 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_MCK); 900 powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_MCHECK); 901 return; 902 } 903 #if 0 /* TODO */ 904 /* External debug exception */ 905 if (env->pending_interrupts & (1 << PPC_INTERRUPT_DEBUG)) { 906 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DEBUG); 907 powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DEBUG); 908 return; 909 } 910 #endif 911 912 /* 913 * For interrupts that gate on MSR:EE, we need to do something a 914 * bit more subtle, as we need to let them through even when EE is 915 * clear when coming out of some power management states (in order 916 * for them to become a 0x100). 917 */ 918 async_deliver = (msr_ee != 0) || env->resume_as_sreset; 919 920 /* Hypervisor decrementer exception */ 921 if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDECR)) { 922 /* LPCR will be clear when not supported so this will work */ 923 bool hdice = !!(env->spr[SPR_LPCR] & LPCR_HDICE); 924 if ((async_deliver || msr_hv == 0) && hdice) { 925 /* HDEC clears on delivery */ 926 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDECR); 927 powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_HDECR); 928 return; 929 } 930 } 931 932 /* Hypervisor virtualization interrupt */ 933 if (env->pending_interrupts & (1 << PPC_INTERRUPT_HVIRT)) { 934 /* LPCR will be clear when not supported so this will work */ 935 bool hvice = !!(env->spr[SPR_LPCR] & LPCR_HVICE); 936 if ((async_deliver || msr_hv == 0) && hvice) { 937 powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_HVIRT); 938 return; 939 } 940 } 941 942 /* External interrupt can ignore MSR:EE under some circumstances */ 943 if (env->pending_interrupts & (1 << PPC_INTERRUPT_EXT)) { 944 bool lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0); 945 bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC); 946 /* HEIC blocks delivery to the hypervisor */ 947 if ((async_deliver && !(heic && msr_hv && !msr_pr)) || 948 (env->has_hv_mode && msr_hv == 0 && !lpes0)) { 949 powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_EXTERNAL); 950 return; 951 } 952 } 953 if (msr_ce != 0) { 954 /* External critical interrupt */ 955 if (env->pending_interrupts & (1 << PPC_INTERRUPT_CEXT)) { 956 powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_CRITICAL); 957 return; 958 } 959 } 960 if (async_deliver != 0) { 961 /* Watchdog timer on embedded PowerPC */ 962 if (env->pending_interrupts & (1 << PPC_INTERRUPT_WDT)) { 963 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_WDT); 964 powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_WDT); 965 return; 966 } 967 if (env->pending_interrupts & (1 << PPC_INTERRUPT_CDOORBELL)) { 968 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_CDOORBELL); 969 powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DOORCI); 970 return; 971 } 972 /* Fixed interval timer on embedded PowerPC */ 973 if (env->pending_interrupts & (1 << PPC_INTERRUPT_FIT)) { 974 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_FIT); 975 powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_FIT); 976 return; 977 } 978 /* Programmable interval timer on embedded PowerPC */ 979 if (env->pending_interrupts & (1 << PPC_INTERRUPT_PIT)) { 980 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PIT); 981 powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_PIT); 982 return; 983 } 984 /* Decrementer exception */ 985 if (env->pending_interrupts & (1 << PPC_INTERRUPT_DECR)) { 986 if (ppc_decr_clear_on_delivery(env)) { 987 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DECR); 988 } 989 powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DECR); 990 return; 991 } 992 if (env->pending_interrupts & (1 << PPC_INTERRUPT_DOORBELL)) { 993 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL); 994 if (is_book3s_arch2x(env)) { 995 powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_SDOOR); 996 } else { 997 powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DOORI); 998 } 999 return; 1000 } 1001 if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDOORBELL)) { 1002 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDOORBELL); 1003 powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_SDOOR_HV); 1004 return; 1005 } 1006 if (env->pending_interrupts & (1 << PPC_INTERRUPT_PERFM)) { 1007 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PERFM); 1008 powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_PERFM); 1009 return; 1010 } 1011 /* Thermal interrupt */ 1012 if (env->pending_interrupts & (1 << PPC_INTERRUPT_THERM)) { 1013 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_THERM); 1014 powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_THERM); 1015 return; 1016 } 1017 } 1018 1019 if (env->resume_as_sreset) { 1020 /* 1021 * This is a bug ! It means that has_work took us out of halt without 1022 * anything to deliver while in a PM state that requires getting 1023 * out via a 0x100 1024 * 1025 * This means we will incorrectly execute past the power management 1026 * instruction instead of triggering a reset. 1027 * 1028 * It generally means a discrepancy between the wakeup conditions in the 1029 * processor has_work implementation and the logic in this function. 1030 */ 1031 cpu_abort(env_cpu(env), 1032 "Wakeup from PM state but interrupt Undelivered"); 1033 } 1034 } 1035 1036 void ppc_cpu_do_system_reset(CPUState *cs) 1037 { 1038 PowerPCCPU *cpu = POWERPC_CPU(cs); 1039 CPUPPCState *env = &cpu->env; 1040 1041 powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_RESET); 1042 } 1043 1044 void ppc_cpu_do_fwnmi_machine_check(CPUState *cs, target_ulong vector) 1045 { 1046 PowerPCCPU *cpu = POWERPC_CPU(cs); 1047 CPUPPCState *env = &cpu->env; 1048 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); 1049 target_ulong msr = 0; 1050 1051 /* 1052 * Set MSR and NIP for the handler, SRR0/1, DAR and DSISR have already 1053 * been set by KVM. 1054 */ 1055 msr = (1ULL << MSR_ME); 1056 msr |= env->msr & (1ULL << MSR_SF); 1057 if (!(*pcc->interrupts_big_endian)(cpu)) { 1058 msr |= (1ULL << MSR_LE); 1059 } 1060 1061 powerpc_set_excp_state(cpu, vector, msr); 1062 } 1063 #endif /* !CONFIG_USER_ONLY */ 1064 1065 bool ppc_cpu_exec_interrupt(CPUState *cs, int interrupt_request) 1066 { 1067 PowerPCCPU *cpu = POWERPC_CPU(cs); 1068 CPUPPCState *env = &cpu->env; 1069 1070 if (interrupt_request & CPU_INTERRUPT_HARD) { 1071 ppc_hw_interrupt(env); 1072 if (env->pending_interrupts == 0) { 1073 cs->interrupt_request &= ~CPU_INTERRUPT_HARD; 1074 } 1075 return true; 1076 } 1077 return false; 1078 } 1079 1080 #if defined(DEBUG_OP) 1081 static void cpu_dump_rfi(target_ulong RA, target_ulong msr) 1082 { 1083 qemu_log("Return from exception at " TARGET_FMT_lx " with flags " 1084 TARGET_FMT_lx "\n", RA, msr); 1085 } 1086 #endif 1087 1088 /*****************************************************************************/ 1089 /* Exceptions processing helpers */ 1090 1091 void raise_exception_err_ra(CPUPPCState *env, uint32_t exception, 1092 uint32_t error_code, uintptr_t raddr) 1093 { 1094 CPUState *cs = env_cpu(env); 1095 1096 cs->exception_index = exception; 1097 env->error_code = error_code; 1098 cpu_loop_exit_restore(cs, raddr); 1099 } 1100 1101 void raise_exception_err(CPUPPCState *env, uint32_t exception, 1102 uint32_t error_code) 1103 { 1104 raise_exception_err_ra(env, exception, error_code, 0); 1105 } 1106 1107 void raise_exception(CPUPPCState *env, uint32_t exception) 1108 { 1109 raise_exception_err_ra(env, exception, 0, 0); 1110 } 1111 1112 void raise_exception_ra(CPUPPCState *env, uint32_t exception, 1113 uintptr_t raddr) 1114 { 1115 raise_exception_err_ra(env, exception, 0, raddr); 1116 } 1117 1118 void helper_raise_exception_err(CPUPPCState *env, uint32_t exception, 1119 uint32_t error_code) 1120 { 1121 raise_exception_err_ra(env, exception, error_code, 0); 1122 } 1123 1124 void helper_raise_exception(CPUPPCState *env, uint32_t exception) 1125 { 1126 raise_exception_err_ra(env, exception, 0, 0); 1127 } 1128 1129 #if !defined(CONFIG_USER_ONLY) 1130 void helper_store_msr(CPUPPCState *env, target_ulong val) 1131 { 1132 uint32_t excp = hreg_store_msr(env, val, 0); 1133 1134 if (excp != 0) { 1135 CPUState *cs = env_cpu(env); 1136 cpu_interrupt_exittb(cs); 1137 raise_exception(env, excp); 1138 } 1139 } 1140 1141 #if defined(TARGET_PPC64) 1142 void helper_scv(CPUPPCState *env, uint32_t lev) 1143 { 1144 if (env->spr[SPR_FSCR] & (1ull << FSCR_SCV)) { 1145 raise_exception_err(env, POWERPC_EXCP_SYSCALL_VECTORED, lev); 1146 } else { 1147 raise_exception_err(env, POWERPC_EXCP_FU, FSCR_IC_SCV); 1148 } 1149 } 1150 1151 void helper_pminsn(CPUPPCState *env, powerpc_pm_insn_t insn) 1152 { 1153 CPUState *cs; 1154 1155 cs = env_cpu(env); 1156 cs->halted = 1; 1157 1158 /* 1159 * The architecture specifies that HDEC interrupts are discarded 1160 * in PM states 1161 */ 1162 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDECR); 1163 1164 /* Condition for waking up at 0x100 */ 1165 env->resume_as_sreset = (insn != PPC_PM_STOP) || 1166 (env->spr[SPR_PSSCR] & PSSCR_EC); 1167 } 1168 #endif /* defined(TARGET_PPC64) */ 1169 1170 static inline void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr) 1171 { 1172 CPUState *cs = env_cpu(env); 1173 1174 /* MSR:POW cannot be set by any form of rfi */ 1175 msr &= ~(1ULL << MSR_POW); 1176 1177 #if defined(TARGET_PPC64) 1178 /* Switching to 32-bit ? Crop the nip */ 1179 if (!msr_is_64bit(env, msr)) { 1180 nip = (uint32_t)nip; 1181 } 1182 #else 1183 nip = (uint32_t)nip; 1184 #endif 1185 /* XXX: beware: this is false if VLE is supported */ 1186 env->nip = nip & ~((target_ulong)0x00000003); 1187 hreg_store_msr(env, msr, 1); 1188 #if defined(DEBUG_OP) 1189 cpu_dump_rfi(env->nip, env->msr); 1190 #endif 1191 /* 1192 * No need to raise an exception here, as rfi is always the last 1193 * insn of a TB 1194 */ 1195 cpu_interrupt_exittb(cs); 1196 /* Reset the reservation */ 1197 env->reserve_addr = -1; 1198 1199 /* Context synchronizing: check if TCG TLB needs flush */ 1200 check_tlb_flush(env, false); 1201 } 1202 1203 void helper_rfi(CPUPPCState *env) 1204 { 1205 do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1] & 0xfffffffful); 1206 } 1207 1208 #define MSR_BOOK3S_MASK 1209 #if defined(TARGET_PPC64) 1210 void helper_rfid(CPUPPCState *env) 1211 { 1212 /* 1213 * The architecture defines a number of rules for which bits can 1214 * change but in practice, we handle this in hreg_store_msr() 1215 * which will be called by do_rfi(), so there is no need to filter 1216 * here 1217 */ 1218 do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1]); 1219 } 1220 1221 void helper_rfscv(CPUPPCState *env) 1222 { 1223 do_rfi(env, env->lr, env->ctr); 1224 } 1225 1226 void helper_hrfid(CPUPPCState *env) 1227 { 1228 do_rfi(env, env->spr[SPR_HSRR0], env->spr[SPR_HSRR1]); 1229 } 1230 #endif 1231 1232 /*****************************************************************************/ 1233 /* Embedded PowerPC specific helpers */ 1234 void helper_40x_rfci(CPUPPCState *env) 1235 { 1236 do_rfi(env, env->spr[SPR_40x_SRR2], env->spr[SPR_40x_SRR3]); 1237 } 1238 1239 void helper_rfci(CPUPPCState *env) 1240 { 1241 do_rfi(env, env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1]); 1242 } 1243 1244 void helper_rfdi(CPUPPCState *env) 1245 { 1246 /* FIXME: choose CSRR1 or DSRR1 based on cpu type */ 1247 do_rfi(env, env->spr[SPR_BOOKE_DSRR0], env->spr[SPR_BOOKE_DSRR1]); 1248 } 1249 1250 void helper_rfmci(CPUPPCState *env) 1251 { 1252 /* FIXME: choose CSRR1 or MCSRR1 based on cpu type */ 1253 do_rfi(env, env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1]); 1254 } 1255 #endif 1256 1257 void helper_tw(CPUPPCState *env, target_ulong arg1, target_ulong arg2, 1258 uint32_t flags) 1259 { 1260 if (!likely(!(((int32_t)arg1 < (int32_t)arg2 && (flags & 0x10)) || 1261 ((int32_t)arg1 > (int32_t)arg2 && (flags & 0x08)) || 1262 ((int32_t)arg1 == (int32_t)arg2 && (flags & 0x04)) || 1263 ((uint32_t)arg1 < (uint32_t)arg2 && (flags & 0x02)) || 1264 ((uint32_t)arg1 > (uint32_t)arg2 && (flags & 0x01))))) { 1265 raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, 1266 POWERPC_EXCP_TRAP, GETPC()); 1267 } 1268 } 1269 1270 #if defined(TARGET_PPC64) 1271 void helper_td(CPUPPCState *env, target_ulong arg1, target_ulong arg2, 1272 uint32_t flags) 1273 { 1274 if (!likely(!(((int64_t)arg1 < (int64_t)arg2 && (flags & 0x10)) || 1275 ((int64_t)arg1 > (int64_t)arg2 && (flags & 0x08)) || 1276 ((int64_t)arg1 == (int64_t)arg2 && (flags & 0x04)) || 1277 ((uint64_t)arg1 < (uint64_t)arg2 && (flags & 0x02)) || 1278 ((uint64_t)arg1 > (uint64_t)arg2 && (flags & 0x01))))) { 1279 raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, 1280 POWERPC_EXCP_TRAP, GETPC()); 1281 } 1282 } 1283 #endif 1284 1285 #if !defined(CONFIG_USER_ONLY) 1286 /*****************************************************************************/ 1287 /* PowerPC 601 specific instructions (POWER bridge) */ 1288 1289 void helper_rfsvc(CPUPPCState *env) 1290 { 1291 do_rfi(env, env->lr, env->ctr & 0x0000FFFF); 1292 } 1293 1294 /* Embedded.Processor Control */ 1295 static int dbell2irq(target_ulong rb) 1296 { 1297 int msg = rb & DBELL_TYPE_MASK; 1298 int irq = -1; 1299 1300 switch (msg) { 1301 case DBELL_TYPE_DBELL: 1302 irq = PPC_INTERRUPT_DOORBELL; 1303 break; 1304 case DBELL_TYPE_DBELL_CRIT: 1305 irq = PPC_INTERRUPT_CDOORBELL; 1306 break; 1307 case DBELL_TYPE_G_DBELL: 1308 case DBELL_TYPE_G_DBELL_CRIT: 1309 case DBELL_TYPE_G_DBELL_MC: 1310 /* XXX implement */ 1311 default: 1312 break; 1313 } 1314 1315 return irq; 1316 } 1317 1318 void helper_msgclr(CPUPPCState *env, target_ulong rb) 1319 { 1320 int irq = dbell2irq(rb); 1321 1322 if (irq < 0) { 1323 return; 1324 } 1325 1326 env->pending_interrupts &= ~(1 << irq); 1327 } 1328 1329 void helper_msgsnd(target_ulong rb) 1330 { 1331 int irq = dbell2irq(rb); 1332 int pir = rb & DBELL_PIRTAG_MASK; 1333 CPUState *cs; 1334 1335 if (irq < 0) { 1336 return; 1337 } 1338 1339 qemu_mutex_lock_iothread(); 1340 CPU_FOREACH(cs) { 1341 PowerPCCPU *cpu = POWERPC_CPU(cs); 1342 CPUPPCState *cenv = &cpu->env; 1343 1344 if ((rb & DBELL_BRDCAST) || (cenv->spr[SPR_BOOKE_PIR] == pir)) { 1345 cenv->pending_interrupts |= 1 << irq; 1346 cpu_interrupt(cs, CPU_INTERRUPT_HARD); 1347 } 1348 } 1349 qemu_mutex_unlock_iothread(); 1350 } 1351 1352 /* Server Processor Control */ 1353 1354 static bool dbell_type_server(target_ulong rb) 1355 { 1356 /* 1357 * A Directed Hypervisor Doorbell message is sent only if the 1358 * message type is 5. All other types are reserved and the 1359 * instruction is a no-op 1360 */ 1361 return (rb & DBELL_TYPE_MASK) == DBELL_TYPE_DBELL_SERVER; 1362 } 1363 1364 void helper_book3s_msgclr(CPUPPCState *env, target_ulong rb) 1365 { 1366 if (!dbell_type_server(rb)) { 1367 return; 1368 } 1369 1370 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDOORBELL); 1371 } 1372 1373 static void book3s_msgsnd_common(int pir, int irq) 1374 { 1375 CPUState *cs; 1376 1377 qemu_mutex_lock_iothread(); 1378 CPU_FOREACH(cs) { 1379 PowerPCCPU *cpu = POWERPC_CPU(cs); 1380 CPUPPCState *cenv = &cpu->env; 1381 1382 /* TODO: broadcast message to all threads of the same processor */ 1383 if (cenv->spr_cb[SPR_PIR].default_value == pir) { 1384 cenv->pending_interrupts |= 1 << irq; 1385 cpu_interrupt(cs, CPU_INTERRUPT_HARD); 1386 } 1387 } 1388 qemu_mutex_unlock_iothread(); 1389 } 1390 1391 void helper_book3s_msgsnd(target_ulong rb) 1392 { 1393 int pir = rb & DBELL_PROCIDTAG_MASK; 1394 1395 if (!dbell_type_server(rb)) { 1396 return; 1397 } 1398 1399 book3s_msgsnd_common(pir, PPC_INTERRUPT_HDOORBELL); 1400 } 1401 1402 #if defined(TARGET_PPC64) 1403 void helper_book3s_msgclrp(CPUPPCState *env, target_ulong rb) 1404 { 1405 helper_hfscr_facility_check(env, HFSCR_MSGP, "msgclrp", HFSCR_IC_MSGP); 1406 1407 if (!dbell_type_server(rb)) { 1408 return; 1409 } 1410 1411 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL); 1412 } 1413 1414 /* 1415 * sends a message to other threads that are on the same 1416 * multi-threaded processor 1417 */ 1418 void helper_book3s_msgsndp(CPUPPCState *env, target_ulong rb) 1419 { 1420 int pir = env->spr_cb[SPR_PIR].default_value; 1421 1422 helper_hfscr_facility_check(env, HFSCR_MSGP, "msgsndp", HFSCR_IC_MSGP); 1423 1424 if (!dbell_type_server(rb)) { 1425 return; 1426 } 1427 1428 /* TODO: TCG supports only one thread */ 1429 1430 book3s_msgsnd_common(pir, PPC_INTERRUPT_DOORBELL); 1431 } 1432 #endif 1433 #endif 1434 1435 void ppc_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr, 1436 MMUAccessType access_type, 1437 int mmu_idx, uintptr_t retaddr) 1438 { 1439 CPUPPCState *env = cs->env_ptr; 1440 uint32_t insn; 1441 1442 /* Restore state and reload the insn we executed, for filling in DSISR. */ 1443 cpu_restore_state(cs, retaddr, true); 1444 insn = cpu_ldl_code(env, env->nip); 1445 1446 cs->exception_index = POWERPC_EXCP_ALIGN; 1447 env->error_code = insn & 0x03FF0000; 1448 cpu_loop_exit(cs); 1449 } 1450