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/exec-all.h" 23 #include "internal.h" 24 #include "helper_regs.h" 25 26 #include "trace.h" 27 28 #ifdef CONFIG_TCG 29 #include "exec/helper-proto.h" 30 #include "exec/cpu_ldst.h" 31 #endif 32 33 /*****************************************************************************/ 34 /* Exception processing */ 35 #if !defined(CONFIG_USER_ONLY) 36 37 static const char *powerpc_excp_name(int excp) 38 { 39 switch (excp) { 40 case POWERPC_EXCP_CRITICAL: return "CRITICAL"; 41 case POWERPC_EXCP_MCHECK: return "MCHECK"; 42 case POWERPC_EXCP_DSI: return "DSI"; 43 case POWERPC_EXCP_ISI: return "ISI"; 44 case POWERPC_EXCP_EXTERNAL: return "EXTERNAL"; 45 case POWERPC_EXCP_ALIGN: return "ALIGN"; 46 case POWERPC_EXCP_PROGRAM: return "PROGRAM"; 47 case POWERPC_EXCP_FPU: return "FPU"; 48 case POWERPC_EXCP_SYSCALL: return "SYSCALL"; 49 case POWERPC_EXCP_APU: return "APU"; 50 case POWERPC_EXCP_DECR: return "DECR"; 51 case POWERPC_EXCP_FIT: return "FIT"; 52 case POWERPC_EXCP_WDT: return "WDT"; 53 case POWERPC_EXCP_DTLB: return "DTLB"; 54 case POWERPC_EXCP_ITLB: return "ITLB"; 55 case POWERPC_EXCP_DEBUG: return "DEBUG"; 56 case POWERPC_EXCP_SPEU: return "SPEU"; 57 case POWERPC_EXCP_EFPDI: return "EFPDI"; 58 case POWERPC_EXCP_EFPRI: return "EFPRI"; 59 case POWERPC_EXCP_EPERFM: return "EPERFM"; 60 case POWERPC_EXCP_DOORI: return "DOORI"; 61 case POWERPC_EXCP_DOORCI: return "DOORCI"; 62 case POWERPC_EXCP_GDOORI: return "GDOORI"; 63 case POWERPC_EXCP_GDOORCI: return "GDOORCI"; 64 case POWERPC_EXCP_HYPPRIV: return "HYPPRIV"; 65 case POWERPC_EXCP_RESET: return "RESET"; 66 case POWERPC_EXCP_DSEG: return "DSEG"; 67 case POWERPC_EXCP_ISEG: return "ISEG"; 68 case POWERPC_EXCP_HDECR: return "HDECR"; 69 case POWERPC_EXCP_TRACE: return "TRACE"; 70 case POWERPC_EXCP_HDSI: return "HDSI"; 71 case POWERPC_EXCP_HISI: return "HISI"; 72 case POWERPC_EXCP_HDSEG: return "HDSEG"; 73 case POWERPC_EXCP_HISEG: return "HISEG"; 74 case POWERPC_EXCP_VPU: return "VPU"; 75 case POWERPC_EXCP_PIT: return "PIT"; 76 case POWERPC_EXCP_EMUL: return "EMUL"; 77 case POWERPC_EXCP_IFTLB: return "IFTLB"; 78 case POWERPC_EXCP_DLTLB: return "DLTLB"; 79 case POWERPC_EXCP_DSTLB: return "DSTLB"; 80 case POWERPC_EXCP_FPA: return "FPA"; 81 case POWERPC_EXCP_DABR: return "DABR"; 82 case POWERPC_EXCP_IABR: return "IABR"; 83 case POWERPC_EXCP_SMI: return "SMI"; 84 case POWERPC_EXCP_PERFM: return "PERFM"; 85 case POWERPC_EXCP_THERM: return "THERM"; 86 case POWERPC_EXCP_VPUA: return "VPUA"; 87 case POWERPC_EXCP_SOFTP: return "SOFTP"; 88 case POWERPC_EXCP_MAINT: return "MAINT"; 89 case POWERPC_EXCP_MEXTBR: return "MEXTBR"; 90 case POWERPC_EXCP_NMEXTBR: return "NMEXTBR"; 91 case POWERPC_EXCP_ITLBE: return "ITLBE"; 92 case POWERPC_EXCP_DTLBE: return "DTLBE"; 93 case POWERPC_EXCP_VSXU: return "VSXU"; 94 case POWERPC_EXCP_FU: return "FU"; 95 case POWERPC_EXCP_HV_EMU: return "HV_EMU"; 96 case POWERPC_EXCP_HV_MAINT: return "HV_MAINT"; 97 case POWERPC_EXCP_HV_FU: return "HV_FU"; 98 case POWERPC_EXCP_SDOOR: return "SDOOR"; 99 case POWERPC_EXCP_SDOOR_HV: return "SDOOR_HV"; 100 case POWERPC_EXCP_HVIRT: return "HVIRT"; 101 case POWERPC_EXCP_SYSCALL_VECTORED: return "SYSCALL_VECTORED"; 102 default: 103 g_assert_not_reached(); 104 } 105 } 106 107 static void dump_syscall(CPUPPCState *env) 108 { 109 qemu_log_mask(CPU_LOG_INT, "syscall r0=%016" PRIx64 110 " r3=%016" PRIx64 " r4=%016" PRIx64 " r5=%016" PRIx64 111 " r6=%016" PRIx64 " r7=%016" PRIx64 " r8=%016" PRIx64 112 " nip=" TARGET_FMT_lx "\n", 113 ppc_dump_gpr(env, 0), ppc_dump_gpr(env, 3), 114 ppc_dump_gpr(env, 4), ppc_dump_gpr(env, 5), 115 ppc_dump_gpr(env, 6), ppc_dump_gpr(env, 7), 116 ppc_dump_gpr(env, 8), env->nip); 117 } 118 119 static void dump_hcall(CPUPPCState *env) 120 { 121 qemu_log_mask(CPU_LOG_INT, "hypercall r3=%016" PRIx64 122 " r4=%016" PRIx64 " r5=%016" PRIx64 " r6=%016" PRIx64 123 " r7=%016" PRIx64 " r8=%016" PRIx64 " r9=%016" PRIx64 124 " r10=%016" PRIx64 " r11=%016" PRIx64 " r12=%016" PRIx64 125 " nip=" TARGET_FMT_lx "\n", 126 ppc_dump_gpr(env, 3), ppc_dump_gpr(env, 4), 127 ppc_dump_gpr(env, 5), ppc_dump_gpr(env, 6), 128 ppc_dump_gpr(env, 7), ppc_dump_gpr(env, 8), 129 ppc_dump_gpr(env, 9), ppc_dump_gpr(env, 10), 130 ppc_dump_gpr(env, 11), ppc_dump_gpr(env, 12), 131 env->nip); 132 } 133 134 static void ppc_excp_debug_sw_tlb(CPUPPCState *env, int excp) 135 { 136 const char *es; 137 target_ulong *miss, *cmp; 138 int en; 139 140 if (!qemu_loglevel_mask(CPU_LOG_MMU)) { 141 return; 142 } 143 144 if (excp == POWERPC_EXCP_IFTLB) { 145 es = "I"; 146 en = 'I'; 147 miss = &env->spr[SPR_IMISS]; 148 cmp = &env->spr[SPR_ICMP]; 149 } else { 150 if (excp == POWERPC_EXCP_DLTLB) { 151 es = "DL"; 152 } else { 153 es = "DS"; 154 } 155 en = 'D'; 156 miss = &env->spr[SPR_DMISS]; 157 cmp = &env->spr[SPR_DCMP]; 158 } 159 qemu_log("6xx %sTLB miss: %cM " TARGET_FMT_lx " %cC " 160 TARGET_FMT_lx " H1 " TARGET_FMT_lx " H2 " 161 TARGET_FMT_lx " %08x\n", es, en, *miss, en, *cmp, 162 env->spr[SPR_HASH1], env->spr[SPR_HASH2], 163 env->error_code); 164 } 165 166 167 static int powerpc_reset_wakeup(CPUState *cs, CPUPPCState *env, int excp, 168 target_ulong *msr) 169 { 170 /* We no longer are in a PM state */ 171 env->resume_as_sreset = false; 172 173 /* Pretend to be returning from doze always as we don't lose state */ 174 *msr |= SRR1_WS_NOLOSS; 175 176 /* Machine checks are sent normally */ 177 if (excp == POWERPC_EXCP_MCHECK) { 178 return excp; 179 } 180 switch (excp) { 181 case POWERPC_EXCP_RESET: 182 *msr |= SRR1_WAKERESET; 183 break; 184 case POWERPC_EXCP_EXTERNAL: 185 *msr |= SRR1_WAKEEE; 186 break; 187 case POWERPC_EXCP_DECR: 188 *msr |= SRR1_WAKEDEC; 189 break; 190 case POWERPC_EXCP_SDOOR: 191 *msr |= SRR1_WAKEDBELL; 192 break; 193 case POWERPC_EXCP_SDOOR_HV: 194 *msr |= SRR1_WAKEHDBELL; 195 break; 196 case POWERPC_EXCP_HV_MAINT: 197 *msr |= SRR1_WAKEHMI; 198 break; 199 case POWERPC_EXCP_HVIRT: 200 *msr |= SRR1_WAKEHVI; 201 break; 202 default: 203 cpu_abort(cs, "Unsupported exception %d in Power Save mode\n", 204 excp); 205 } 206 return POWERPC_EXCP_RESET; 207 } 208 209 /* 210 * AIL - Alternate Interrupt Location, a mode that allows interrupts to be 211 * taken with the MMU on, and which uses an alternate location (e.g., so the 212 * kernel/hv can map the vectors there with an effective address). 213 * 214 * An interrupt is considered to be taken "with AIL" or "AIL applies" if they 215 * are delivered in this way. AIL requires the LPCR to be set to enable this 216 * mode, and then a number of conditions have to be true for AIL to apply. 217 * 218 * First of all, SRESET, MCE, and HMI are always delivered without AIL, because 219 * they specifically want to be in real mode (e.g., the MCE might be signaling 220 * a SLB multi-hit which requires SLB flush before the MMU can be enabled). 221 * 222 * After that, behaviour depends on the current MSR[IR], MSR[DR], MSR[HV], 223 * whether or not the interrupt changes MSR[HV] from 0 to 1, and the current 224 * radix mode (LPCR[HR]). 225 * 226 * POWER8, POWER9 with LPCR[HR]=0 227 * | LPCR[AIL] | MSR[IR||DR] | MSR[HV] | new MSR[HV] | AIL | 228 * +-----------+-------------+---------+-------------+-----+ 229 * | a | 00/01/10 | x | x | 0 | 230 * | a | 11 | 0 | 1 | 0 | 231 * | a | 11 | 1 | 1 | a | 232 * | a | 11 | 0 | 0 | a | 233 * +-------------------------------------------------------+ 234 * 235 * POWER9 with LPCR[HR]=1 236 * | LPCR[AIL] | MSR[IR||DR] | MSR[HV] | new MSR[HV] | AIL | 237 * +-----------+-------------+---------+-------------+-----+ 238 * | a | 00/01/10 | x | x | 0 | 239 * | a | 11 | x | x | a | 240 * +-------------------------------------------------------+ 241 * 242 * The difference with POWER9 being that MSR[HV] 0->1 interrupts can be sent to 243 * the hypervisor in AIL mode if the guest is radix. This is good for 244 * performance but allows the guest to influence the AIL of hypervisor 245 * interrupts using its MSR, and also the hypervisor must disallow guest 246 * interrupts (MSR[HV] 0->0) from using AIL if the hypervisor does not want to 247 * use AIL for its MSR[HV] 0->1 interrupts. 248 * 249 * POWER10 addresses those issues with a new LPCR[HAIL] bit that is applied to 250 * interrupts that begin execution with MSR[HV]=1 (so both MSR[HV] 0->1 and 251 * MSR[HV] 1->1). 252 * 253 * HAIL=1 is equivalent to AIL=3, for interrupts delivered with MSR[HV]=1. 254 * 255 * POWER10 behaviour is 256 * | LPCR[AIL] | LPCR[HAIL] | MSR[IR||DR] | MSR[HV] | new MSR[HV] | AIL | 257 * +-----------+------------+-------------+---------+-------------+-----+ 258 * | a | h | 00/01/10 | 0 | 0 | 0 | 259 * | a | h | 11 | 0 | 0 | a | 260 * | a | h | x | 0 | 1 | h | 261 * | a | h | 00/01/10 | 1 | 1 | 0 | 262 * | a | h | 11 | 1 | 1 | h | 263 * +--------------------------------------------------------------------+ 264 */ 265 static void ppc_excp_apply_ail(PowerPCCPU *cpu, int excp_model, int excp, 266 target_ulong msr, 267 target_ulong *new_msr, 268 target_ulong *vector) 269 { 270 #if defined(TARGET_PPC64) 271 CPUPPCState *env = &cpu->env; 272 bool mmu_all_on = ((msr >> MSR_IR) & 1) && ((msr >> MSR_DR) & 1); 273 bool hv_escalation = !(msr & MSR_HVB) && (*new_msr & MSR_HVB); 274 int ail = 0; 275 276 if (excp == POWERPC_EXCP_MCHECK || 277 excp == POWERPC_EXCP_RESET || 278 excp == POWERPC_EXCP_HV_MAINT) { 279 /* SRESET, MCE, HMI never apply AIL */ 280 return; 281 } 282 283 if (excp_model == POWERPC_EXCP_POWER8 || 284 excp_model == POWERPC_EXCP_POWER9) { 285 if (!mmu_all_on) { 286 /* AIL only works if MSR[IR] and MSR[DR] are both enabled. */ 287 return; 288 } 289 if (hv_escalation && !(env->spr[SPR_LPCR] & LPCR_HR)) { 290 /* 291 * AIL does not work if there is a MSR[HV] 0->1 transition and the 292 * partition is in HPT mode. For radix guests, such interrupts are 293 * allowed to be delivered to the hypervisor in ail mode. 294 */ 295 return; 296 } 297 298 ail = (env->spr[SPR_LPCR] & LPCR_AIL) >> LPCR_AIL_SHIFT; 299 if (ail == 0) { 300 return; 301 } 302 if (ail == 1) { 303 /* AIL=1 is reserved, treat it like AIL=0 */ 304 return; 305 } 306 307 } else if (excp_model == POWERPC_EXCP_POWER10) { 308 if (!mmu_all_on && !hv_escalation) { 309 /* 310 * AIL works for HV interrupts even with guest MSR[IR/DR] disabled. 311 * Guest->guest and HV->HV interrupts do require MMU on. 312 */ 313 return; 314 } 315 316 if (*new_msr & MSR_HVB) { 317 if (!(env->spr[SPR_LPCR] & LPCR_HAIL)) { 318 /* HV interrupts depend on LPCR[HAIL] */ 319 return; 320 } 321 ail = 3; /* HAIL=1 gives AIL=3 behaviour for HV interrupts */ 322 } else { 323 ail = (env->spr[SPR_LPCR] & LPCR_AIL) >> LPCR_AIL_SHIFT; 324 } 325 if (ail == 0) { 326 return; 327 } 328 if (ail == 1 || ail == 2) { 329 /* AIL=1 and AIL=2 are reserved, treat them like AIL=0 */ 330 return; 331 } 332 } else { 333 /* Other processors do not support AIL */ 334 return; 335 } 336 337 /* 338 * AIL applies, so the new MSR gets IR and DR set, and an offset applied 339 * to the new IP. 340 */ 341 *new_msr |= (1 << MSR_IR) | (1 << MSR_DR); 342 343 if (excp != POWERPC_EXCP_SYSCALL_VECTORED) { 344 if (ail == 2) { 345 *vector |= 0x0000000000018000ull; 346 } else if (ail == 3) { 347 *vector |= 0xc000000000004000ull; 348 } 349 } else { 350 /* 351 * scv AIL is a little different. AIL=2 does not change the address, 352 * only the MSR. AIL=3 replaces the 0x17000 base with 0xc...3000. 353 */ 354 if (ail == 3) { 355 *vector &= ~0x0000000000017000ull; /* Un-apply the base offset */ 356 *vector |= 0xc000000000003000ull; /* Apply scv's AIL=3 offset */ 357 } 358 } 359 #endif 360 } 361 362 static void powerpc_set_excp_state(PowerPCCPU *cpu, 363 target_ulong vector, target_ulong msr) 364 { 365 CPUState *cs = CPU(cpu); 366 CPUPPCState *env = &cpu->env; 367 368 /* 369 * We don't use hreg_store_msr here as already have treated any 370 * special case that could occur. Just store MSR and update hflags 371 * 372 * Note: We *MUST* not use hreg_store_msr() as-is anyway because it 373 * will prevent setting of the HV bit which some exceptions might need 374 * to do. 375 */ 376 env->msr = msr & env->msr_mask; 377 hreg_compute_hflags(env); 378 env->nip = vector; 379 /* Reset exception state */ 380 cs->exception_index = POWERPC_EXCP_NONE; 381 env->error_code = 0; 382 383 /* Reset the reservation */ 384 env->reserve_addr = -1; 385 386 /* 387 * Any interrupt is context synchronizing, check if TCG TLB needs 388 * a delayed flush on ppc64 389 */ 390 check_tlb_flush(env, false); 391 } 392 393 static void powerpc_excp_40x(PowerPCCPU *cpu, int excp) 394 { 395 CPUState *cs = CPU(cpu); 396 CPUPPCState *env = &cpu->env; 397 target_ulong msr, new_msr, vector; 398 int srr0, srr1; 399 400 if (excp <= POWERPC_EXCP_NONE || excp >= POWERPC_EXCP_NB) { 401 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); 402 } 403 404 qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx 405 " => %s (%d) error=%02x\n", env->nip, powerpc_excp_name(excp), 406 excp, env->error_code); 407 408 /* new srr1 value excluding must-be-zero bits */ 409 msr = env->msr & ~0x783f0000ULL; 410 411 /* 412 * new interrupt handler msr preserves existing ME unless 413 * explicitly overriden. 414 */ 415 new_msr = env->msr & (((target_ulong)1 << MSR_ME)); 416 417 /* target registers */ 418 srr0 = SPR_SRR0; 419 srr1 = SPR_SRR1; 420 421 /* 422 * Hypervisor emulation assistance interrupt only exists on server 423 * arch 2.05 server or later. 424 */ 425 if (excp == POWERPC_EXCP_HV_EMU) { 426 excp = POWERPC_EXCP_PROGRAM; 427 } 428 429 vector = env->excp_vectors[excp]; 430 if (vector == (target_ulong)-1ULL) { 431 cpu_abort(cs, "Raised an exception without defined vector %d\n", 432 excp); 433 } 434 435 vector |= env->excp_prefix; 436 437 switch (excp) { 438 case POWERPC_EXCP_CRITICAL: /* Critical input */ 439 srr0 = SPR_40x_SRR2; 440 srr1 = SPR_40x_SRR3; 441 break; 442 case POWERPC_EXCP_MCHECK: /* Machine check exception */ 443 if (msr_me == 0) { 444 /* 445 * Machine check exception is not enabled. Enter 446 * checkstop state. 447 */ 448 fprintf(stderr, "Machine check while not allowed. " 449 "Entering checkstop state\n"); 450 if (qemu_log_separate()) { 451 qemu_log("Machine check while not allowed. " 452 "Entering checkstop state\n"); 453 } 454 cs->halted = 1; 455 cpu_interrupt_exittb(cs); 456 } 457 458 /* machine check exceptions don't have ME set */ 459 new_msr &= ~((target_ulong)1 << MSR_ME); 460 461 srr0 = SPR_40x_SRR2; 462 srr1 = SPR_40x_SRR3; 463 break; 464 case POWERPC_EXCP_DSI: /* Data storage exception */ 465 trace_ppc_excp_dsi(env->spr[SPR_40x_ESR], env->spr[SPR_40x_DEAR]); 466 break; 467 case POWERPC_EXCP_ISI: /* Instruction storage exception */ 468 trace_ppc_excp_isi(msr, env->nip); 469 break; 470 case POWERPC_EXCP_EXTERNAL: /* External input */ 471 break; 472 case POWERPC_EXCP_ALIGN: /* Alignment exception */ 473 break; 474 case POWERPC_EXCP_PROGRAM: /* Program exception */ 475 switch (env->error_code & ~0xF) { 476 case POWERPC_EXCP_FP: 477 if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) { 478 trace_ppc_excp_fp_ignore(); 479 cs->exception_index = POWERPC_EXCP_NONE; 480 env->error_code = 0; 481 return; 482 } 483 env->spr[SPR_40x_ESR] = ESR_FP; 484 break; 485 case POWERPC_EXCP_INVAL: 486 trace_ppc_excp_inval(env->nip); 487 env->spr[SPR_40x_ESR] = ESR_PIL; 488 break; 489 case POWERPC_EXCP_PRIV: 490 env->spr[SPR_40x_ESR] = ESR_PPR; 491 break; 492 case POWERPC_EXCP_TRAP: 493 env->spr[SPR_40x_ESR] = ESR_PTR; 494 break; 495 default: 496 cpu_abort(cs, "Invalid program exception %d. Aborting\n", 497 env->error_code); 498 break; 499 } 500 break; 501 case POWERPC_EXCP_SYSCALL: /* System call exception */ 502 dump_syscall(env); 503 504 /* 505 * We need to correct the NIP which in this case is supposed 506 * to point to the next instruction 507 */ 508 env->nip += 4; 509 break; 510 case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt */ 511 trace_ppc_excp_print("FIT"); 512 break; 513 case POWERPC_EXCP_WDT: /* Watchdog timer interrupt */ 514 trace_ppc_excp_print("WDT"); 515 break; 516 case POWERPC_EXCP_DTLB: /* Data TLB error */ 517 case POWERPC_EXCP_ITLB: /* Instruction TLB error */ 518 break; 519 case POWERPC_EXCP_PIT: /* Programmable interval timer interrupt */ 520 trace_ppc_excp_print("PIT"); 521 break; 522 case POWERPC_EXCP_DEBUG: /* Debug interrupt */ 523 cpu_abort(cs, "%s exception not implemented\n", 524 powerpc_excp_name(excp)); 525 break; 526 default: 527 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); 528 break; 529 } 530 531 /* Sanity check */ 532 if (!(env->msr_mask & MSR_HVB)) { 533 if (new_msr & MSR_HVB) { 534 cpu_abort(cs, "Trying to deliver HV exception (MSR) %d with " 535 "no HV support\n", excp); 536 } 537 if (srr0 == SPR_HSRR0) { 538 cpu_abort(cs, "Trying to deliver HV exception (HSRR) %d with " 539 "no HV support\n", excp); 540 } 541 } 542 543 /* Save PC */ 544 env->spr[srr0] = env->nip; 545 546 /* Save MSR */ 547 env->spr[srr1] = msr; 548 549 powerpc_set_excp_state(cpu, vector, new_msr); 550 } 551 552 static void powerpc_excp_6xx(PowerPCCPU *cpu, int excp) 553 { 554 CPUState *cs = CPU(cpu); 555 CPUPPCState *env = &cpu->env; 556 target_ulong msr, new_msr, vector; 557 558 if (excp <= POWERPC_EXCP_NONE || excp >= POWERPC_EXCP_NB) { 559 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); 560 } 561 562 qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx 563 " => %s (%d) error=%02x\n", env->nip, powerpc_excp_name(excp), 564 excp, env->error_code); 565 566 /* new srr1 value excluding must-be-zero bits */ 567 msr = env->msr & ~0x783f0000ULL; 568 569 /* 570 * new interrupt handler msr preserves existing ME unless 571 * explicitly overriden 572 */ 573 new_msr = env->msr & ((target_ulong)1 << MSR_ME); 574 575 /* 576 * Hypervisor emulation assistance interrupt only exists on server 577 * arch 2.05 server or later. 578 */ 579 if (excp == POWERPC_EXCP_HV_EMU) { 580 excp = POWERPC_EXCP_PROGRAM; 581 } 582 583 vector = env->excp_vectors[excp]; 584 if (vector == (target_ulong)-1ULL) { 585 cpu_abort(cs, "Raised an exception without defined vector %d\n", 586 excp); 587 } 588 589 vector |= env->excp_prefix; 590 591 switch (excp) { 592 case POWERPC_EXCP_CRITICAL: /* Critical input */ 593 break; 594 case POWERPC_EXCP_MCHECK: /* Machine check exception */ 595 if (msr_me == 0) { 596 /* 597 * Machine check exception is not enabled. Enter 598 * checkstop state. 599 */ 600 fprintf(stderr, "Machine check while not allowed. " 601 "Entering checkstop state\n"); 602 if (qemu_log_separate()) { 603 qemu_log("Machine check while not allowed. " 604 "Entering checkstop state\n"); 605 } 606 cs->halted = 1; 607 cpu_interrupt_exittb(cs); 608 } 609 610 /* machine check exceptions don't have ME set */ 611 new_msr &= ~((target_ulong)1 << MSR_ME); 612 613 break; 614 case POWERPC_EXCP_DSI: /* Data storage exception */ 615 trace_ppc_excp_dsi(env->spr[SPR_DSISR], env->spr[SPR_DAR]); 616 break; 617 case POWERPC_EXCP_ISI: /* Instruction storage exception */ 618 trace_ppc_excp_isi(msr, env->nip); 619 msr |= env->error_code; 620 break; 621 case POWERPC_EXCP_EXTERNAL: /* External input */ 622 break; 623 case POWERPC_EXCP_ALIGN: /* Alignment exception */ 624 /* Get rS/rD and rA from faulting opcode */ 625 /* 626 * Note: the opcode fields will not be set properly for a 627 * direct store load/store, but nobody cares as nobody 628 * actually uses direct store segments. 629 */ 630 env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16; 631 break; 632 case POWERPC_EXCP_PROGRAM: /* Program exception */ 633 switch (env->error_code & ~0xF) { 634 case POWERPC_EXCP_FP: 635 if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) { 636 trace_ppc_excp_fp_ignore(); 637 cs->exception_index = POWERPC_EXCP_NONE; 638 env->error_code = 0; 639 return; 640 } 641 642 /* 643 * FP exceptions always have NIP pointing to the faulting 644 * instruction, so always use store_next and claim we are 645 * precise in the MSR. 646 */ 647 msr |= 0x00100000; 648 break; 649 case POWERPC_EXCP_INVAL: 650 trace_ppc_excp_inval(env->nip); 651 msr |= 0x00080000; 652 break; 653 case POWERPC_EXCP_PRIV: 654 msr |= 0x00040000; 655 break; 656 case POWERPC_EXCP_TRAP: 657 msr |= 0x00020000; 658 break; 659 default: 660 /* Should never occur */ 661 cpu_abort(cs, "Invalid program exception %d. Aborting\n", 662 env->error_code); 663 break; 664 } 665 break; 666 case POWERPC_EXCP_SYSCALL: /* System call exception */ 667 dump_syscall(env); 668 669 /* 670 * We need to correct the NIP which in this case is supposed 671 * to point to the next instruction 672 */ 673 env->nip += 4; 674 break; 675 case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */ 676 case POWERPC_EXCP_DECR: /* Decrementer exception */ 677 break; 678 case POWERPC_EXCP_DTLB: /* Data TLB error */ 679 case POWERPC_EXCP_ITLB: /* Instruction TLB error */ 680 break; 681 case POWERPC_EXCP_RESET: /* System reset exception */ 682 if (msr_pow) { 683 cpu_abort(cs, "Trying to deliver power-saving system reset " 684 "exception %d with no HV support\n", excp); 685 } 686 break; 687 case POWERPC_EXCP_TRACE: /* Trace exception */ 688 break; 689 case POWERPC_EXCP_IFTLB: /* Instruction fetch TLB error */ 690 case POWERPC_EXCP_DLTLB: /* Data load TLB miss */ 691 case POWERPC_EXCP_DSTLB: /* Data store TLB miss */ 692 /* Swap temporary saved registers with GPRs */ 693 if (!(new_msr & ((target_ulong)1 << MSR_TGPR))) { 694 new_msr |= (target_ulong)1 << MSR_TGPR; 695 hreg_swap_gpr_tgpr(env); 696 } 697 698 ppc_excp_debug_sw_tlb(env, excp); 699 700 msr |= env->crf[0] << 28; 701 msr |= env->error_code; /* key, D/I, S/L bits */ 702 /* Set way using a LRU mechanism */ 703 msr |= ((env->last_way + 1) & (env->nb_ways - 1)) << 17; 704 break; 705 case POWERPC_EXCP_FPA: /* Floating-point assist exception */ 706 case POWERPC_EXCP_DABR: /* Data address breakpoint */ 707 case POWERPC_EXCP_IABR: /* Instruction address breakpoint */ 708 case POWERPC_EXCP_SMI: /* System management interrupt */ 709 case POWERPC_EXCP_MEXTBR: /* Maskable external breakpoint */ 710 case POWERPC_EXCP_NMEXTBR: /* Non maskable external breakpoint */ 711 cpu_abort(cs, "%s exception not implemented\n", 712 powerpc_excp_name(excp)); 713 break; 714 default: 715 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); 716 break; 717 } 718 719 /* Sanity check */ 720 if (!(env->msr_mask & MSR_HVB)) { 721 if (new_msr & MSR_HVB) { 722 cpu_abort(cs, "Trying to deliver HV exception (MSR) %d with " 723 "no HV support\n", excp); 724 } 725 } 726 727 /* 728 * Sort out endianness of interrupt, this differs depending on the 729 * CPU, the HV mode, etc... 730 */ 731 if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) { 732 new_msr |= (target_ulong)1 << MSR_LE; 733 } 734 735 /* Save PC */ 736 env->spr[SPR_SRR0] = env->nip; 737 738 /* Save MSR */ 739 env->spr[SPR_SRR1] = msr; 740 741 powerpc_set_excp_state(cpu, vector, new_msr); 742 } 743 744 static void powerpc_excp_7xx(PowerPCCPU *cpu, int excp) 745 { 746 CPUState *cs = CPU(cpu); 747 CPUPPCState *env = &cpu->env; 748 int excp_model = env->excp_model; 749 target_ulong msr, new_msr, vector; 750 int srr0, srr1, lev = -1; 751 752 if (excp <= POWERPC_EXCP_NONE || excp >= POWERPC_EXCP_NB) { 753 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); 754 } 755 756 qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx 757 " => %s (%d) error=%02x\n", env->nip, powerpc_excp_name(excp), 758 excp, env->error_code); 759 760 /* new srr1 value excluding must-be-zero bits */ 761 msr = env->msr & ~0x783f0000ULL; 762 763 /* 764 * new interrupt handler msr preserves existing ME unless 765 * explicitly overriden 766 */ 767 new_msr = env->msr & ((target_ulong)1 << MSR_ME); 768 769 /* target registers */ 770 srr0 = SPR_SRR0; 771 srr1 = SPR_SRR1; 772 773 /* 774 * Hypervisor emulation assistance interrupt only exists on server 775 * arch 2.05 server or later. 776 */ 777 if (excp == POWERPC_EXCP_HV_EMU) { 778 excp = POWERPC_EXCP_PROGRAM; 779 } 780 781 vector = env->excp_vectors[excp]; 782 if (vector == (target_ulong)-1ULL) { 783 cpu_abort(cs, "Raised an exception without defined vector %d\n", 784 excp); 785 } 786 787 vector |= env->excp_prefix; 788 789 switch (excp) { 790 case POWERPC_EXCP_MCHECK: /* Machine check exception */ 791 if (msr_me == 0) { 792 /* 793 * Machine check exception is not enabled. Enter 794 * checkstop state. 795 */ 796 fprintf(stderr, "Machine check while not allowed. " 797 "Entering checkstop state\n"); 798 if (qemu_log_separate()) { 799 qemu_log("Machine check while not allowed. " 800 "Entering checkstop state\n"); 801 } 802 cs->halted = 1; 803 cpu_interrupt_exittb(cs); 804 } 805 806 /* machine check exceptions don't have ME set */ 807 new_msr &= ~((target_ulong)1 << MSR_ME); 808 809 break; 810 case POWERPC_EXCP_DSI: /* Data storage exception */ 811 trace_ppc_excp_dsi(env->spr[SPR_DSISR], env->spr[SPR_DAR]); 812 break; 813 case POWERPC_EXCP_ISI: /* Instruction storage exception */ 814 trace_ppc_excp_isi(msr, env->nip); 815 msr |= env->error_code; 816 break; 817 case POWERPC_EXCP_EXTERNAL: /* External input */ 818 break; 819 case POWERPC_EXCP_ALIGN: /* Alignment exception */ 820 /* Get rS/rD and rA from faulting opcode */ 821 /* 822 * Note: the opcode fields will not be set properly for a 823 * direct store load/store, but nobody cares as nobody 824 * actually uses direct store segments. 825 */ 826 env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16; 827 break; 828 case POWERPC_EXCP_PROGRAM: /* Program exception */ 829 switch (env->error_code & ~0xF) { 830 case POWERPC_EXCP_FP: 831 if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) { 832 trace_ppc_excp_fp_ignore(); 833 cs->exception_index = POWERPC_EXCP_NONE; 834 env->error_code = 0; 835 return; 836 } 837 838 /* 839 * FP exceptions always have NIP pointing to the faulting 840 * instruction, so always use store_next and claim we are 841 * precise in the MSR. 842 */ 843 msr |= 0x00100000; 844 env->spr[SPR_BOOKE_ESR] = ESR_FP; 845 break; 846 case POWERPC_EXCP_INVAL: 847 trace_ppc_excp_inval(env->nip); 848 msr |= 0x00080000; 849 env->spr[SPR_BOOKE_ESR] = ESR_PIL; 850 break; 851 case POWERPC_EXCP_PRIV: 852 msr |= 0x00040000; 853 env->spr[SPR_BOOKE_ESR] = ESR_PPR; 854 break; 855 case POWERPC_EXCP_TRAP: 856 msr |= 0x00020000; 857 env->spr[SPR_BOOKE_ESR] = ESR_PTR; 858 break; 859 default: 860 /* Should never occur */ 861 cpu_abort(cs, "Invalid program exception %d. Aborting\n", 862 env->error_code); 863 break; 864 } 865 break; 866 case POWERPC_EXCP_SYSCALL: /* System call exception */ 867 lev = env->error_code; 868 869 if ((lev == 1) && cpu->vhyp) { 870 dump_hcall(env); 871 } else { 872 dump_syscall(env); 873 } 874 875 /* 876 * We need to correct the NIP which in this case is supposed 877 * to point to the next instruction 878 */ 879 env->nip += 4; 880 881 /* "PAPR mode" built-in hypercall emulation */ 882 if ((lev == 1) && cpu->vhyp) { 883 PPCVirtualHypervisorClass *vhc = 884 PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp); 885 vhc->hypercall(cpu->vhyp, cpu); 886 return; 887 } 888 if (lev == 1) { 889 new_msr |= (target_ulong)MSR_HVB; 890 } 891 break; 892 case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */ 893 case POWERPC_EXCP_DECR: /* Decrementer exception */ 894 break; 895 case POWERPC_EXCP_RESET: /* System reset exception */ 896 /* A power-saving exception sets ME, otherwise it is unchanged */ 897 if (msr_pow) { 898 /* indicate that we resumed from power save mode */ 899 msr |= 0x10000; 900 new_msr |= ((target_ulong)1 << MSR_ME); 901 } 902 if (env->msr_mask & MSR_HVB) { 903 /* 904 * ISA specifies HV, but can be delivered to guest with HV 905 * clear (e.g., see FWNMI in PAPR, NMI injection in QEMU). 906 */ 907 new_msr |= (target_ulong)MSR_HVB; 908 } else { 909 if (msr_pow) { 910 cpu_abort(cs, "Trying to deliver power-saving system reset " 911 "exception %d with no HV support\n", excp); 912 } 913 } 914 break; 915 case POWERPC_EXCP_TRACE: /* Trace exception */ 916 break; 917 case POWERPC_EXCP_IFTLB: /* Instruction fetch TLB error */ 918 case POWERPC_EXCP_DLTLB: /* Data load TLB miss */ 919 case POWERPC_EXCP_DSTLB: /* Data store TLB miss */ 920 switch (excp_model) { 921 case POWERPC_EXCP_6xx: 922 /* Swap temporary saved registers with GPRs */ 923 if (!(new_msr & ((target_ulong)1 << MSR_TGPR))) { 924 new_msr |= (target_ulong)1 << MSR_TGPR; 925 hreg_swap_gpr_tgpr(env); 926 } 927 /* fall through */ 928 case POWERPC_EXCP_7xx: 929 ppc_excp_debug_sw_tlb(env, excp); 930 931 msr |= env->crf[0] << 28; 932 msr |= env->error_code; /* key, D/I, S/L bits */ 933 /* Set way using a LRU mechanism */ 934 msr |= ((env->last_way + 1) & (env->nb_ways - 1)) << 17; 935 break; 936 default: 937 cpu_abort(cs, "Invalid TLB miss exception\n"); 938 break; 939 } 940 break; 941 case POWERPC_EXCP_IABR: /* Instruction address breakpoint */ 942 case POWERPC_EXCP_SMI: /* System management interrupt */ 943 case POWERPC_EXCP_THERM: /* Thermal interrupt */ 944 case POWERPC_EXCP_PERFM: /* Embedded performance monitor interrupt */ 945 cpu_abort(cs, "%s exception not implemented\n", 946 powerpc_excp_name(excp)); 947 break; 948 default: 949 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); 950 break; 951 } 952 953 /* Sanity check */ 954 if (!(env->msr_mask & MSR_HVB)) { 955 if (new_msr & MSR_HVB) { 956 cpu_abort(cs, "Trying to deliver HV exception (MSR) %d with " 957 "no HV support\n", excp); 958 } 959 if (srr0 == SPR_HSRR0) { 960 cpu_abort(cs, "Trying to deliver HV exception (HSRR) %d with " 961 "no HV support\n", excp); 962 } 963 } 964 965 /* 966 * Sort out endianness of interrupt, this differs depending on the 967 * CPU, the HV mode, etc... 968 */ 969 if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) { 970 new_msr |= (target_ulong)1 << MSR_LE; 971 } 972 973 /* Save PC */ 974 env->spr[srr0] = env->nip; 975 976 /* Save MSR */ 977 env->spr[srr1] = msr; 978 979 powerpc_set_excp_state(cpu, vector, new_msr); 980 } 981 982 static void powerpc_excp_74xx(PowerPCCPU *cpu, int excp) 983 { 984 CPUState *cs = CPU(cpu); 985 CPUPPCState *env = &cpu->env; 986 target_ulong msr, new_msr, vector; 987 988 if (excp <= POWERPC_EXCP_NONE || excp >= POWERPC_EXCP_NB) { 989 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); 990 } 991 992 qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx 993 " => %s (%d) error=%02x\n", env->nip, powerpc_excp_name(excp), 994 excp, env->error_code); 995 996 /* new srr1 value excluding must-be-zero bits */ 997 msr = env->msr & ~0x783f0000ULL; 998 999 /* 1000 * new interrupt handler msr preserves existing ME unless 1001 * explicitly overriden 1002 */ 1003 new_msr = env->msr & ((target_ulong)1 << MSR_ME); 1004 1005 /* 1006 * Hypervisor emulation assistance interrupt only exists on server 1007 * arch 2.05 server or later. 1008 */ 1009 if (excp == POWERPC_EXCP_HV_EMU) { 1010 excp = POWERPC_EXCP_PROGRAM; 1011 } 1012 1013 vector = env->excp_vectors[excp]; 1014 if (vector == (target_ulong)-1ULL) { 1015 cpu_abort(cs, "Raised an exception without defined vector %d\n", 1016 excp); 1017 } 1018 1019 vector |= env->excp_prefix; 1020 1021 switch (excp) { 1022 case POWERPC_EXCP_MCHECK: /* Machine check exception */ 1023 if (msr_me == 0) { 1024 /* 1025 * Machine check exception is not enabled. Enter 1026 * checkstop state. 1027 */ 1028 fprintf(stderr, "Machine check while not allowed. " 1029 "Entering checkstop state\n"); 1030 if (qemu_log_separate()) { 1031 qemu_log("Machine check while not allowed. " 1032 "Entering checkstop state\n"); 1033 } 1034 cs->halted = 1; 1035 cpu_interrupt_exittb(cs); 1036 } 1037 1038 /* machine check exceptions don't have ME set */ 1039 new_msr &= ~((target_ulong)1 << MSR_ME); 1040 1041 break; 1042 case POWERPC_EXCP_DSI: /* Data storage exception */ 1043 trace_ppc_excp_dsi(env->spr[SPR_DSISR], env->spr[SPR_DAR]); 1044 break; 1045 case POWERPC_EXCP_ISI: /* Instruction storage exception */ 1046 trace_ppc_excp_isi(msr, env->nip); 1047 msr |= env->error_code; 1048 break; 1049 case POWERPC_EXCP_EXTERNAL: /* External input */ 1050 break; 1051 case POWERPC_EXCP_ALIGN: /* Alignment exception */ 1052 /* Get rS/rD and rA from faulting opcode */ 1053 /* 1054 * Note: the opcode fields will not be set properly for a 1055 * direct store load/store, but nobody cares as nobody 1056 * actually uses direct store segments. 1057 */ 1058 env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16; 1059 break; 1060 case POWERPC_EXCP_PROGRAM: /* Program exception */ 1061 switch (env->error_code & ~0xF) { 1062 case POWERPC_EXCP_FP: 1063 if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) { 1064 trace_ppc_excp_fp_ignore(); 1065 cs->exception_index = POWERPC_EXCP_NONE; 1066 env->error_code = 0; 1067 return; 1068 } 1069 1070 /* 1071 * FP exceptions always have NIP pointing to the faulting 1072 * instruction, so always use store_next and claim we are 1073 * precise in the MSR. 1074 */ 1075 msr |= 0x00100000; 1076 break; 1077 case POWERPC_EXCP_INVAL: 1078 trace_ppc_excp_inval(env->nip); 1079 msr |= 0x00080000; 1080 break; 1081 case POWERPC_EXCP_PRIV: 1082 msr |= 0x00040000; 1083 break; 1084 case POWERPC_EXCP_TRAP: 1085 msr |= 0x00020000; 1086 break; 1087 default: 1088 /* Should never occur */ 1089 cpu_abort(cs, "Invalid program exception %d. Aborting\n", 1090 env->error_code); 1091 break; 1092 } 1093 break; 1094 case POWERPC_EXCP_SYSCALL: /* System call exception */ 1095 { 1096 int lev = env->error_code; 1097 1098 if ((lev == 1) && cpu->vhyp) { 1099 dump_hcall(env); 1100 } else { 1101 dump_syscall(env); 1102 } 1103 1104 /* 1105 * We need to correct the NIP which in this case is supposed 1106 * to point to the next instruction 1107 */ 1108 env->nip += 4; 1109 1110 /* 1111 * The Virtual Open Firmware (VOF) relies on the 'sc 1' 1112 * instruction to communicate with QEMU. The pegasos2 machine 1113 * uses VOF and the 74xx CPUs, so although the 74xx don't have 1114 * HV mode, we need to keep hypercall support. 1115 */ 1116 if ((lev == 1) && cpu->vhyp) { 1117 PPCVirtualHypervisorClass *vhc = 1118 PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp); 1119 vhc->hypercall(cpu->vhyp, cpu); 1120 return; 1121 } 1122 1123 break; 1124 } 1125 case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */ 1126 case POWERPC_EXCP_DECR: /* Decrementer exception */ 1127 break; 1128 case POWERPC_EXCP_RESET: /* System reset exception */ 1129 if (msr_pow) { 1130 cpu_abort(cs, "Trying to deliver power-saving system reset " 1131 "exception %d with no HV support\n", excp); 1132 } 1133 break; 1134 case POWERPC_EXCP_TRACE: /* Trace exception */ 1135 break; 1136 case POWERPC_EXCP_VPU: /* Vector unavailable exception */ 1137 break; 1138 case POWERPC_EXCP_IABR: /* Instruction address breakpoint */ 1139 case POWERPC_EXCP_SMI: /* System management interrupt */ 1140 case POWERPC_EXCP_THERM: /* Thermal interrupt */ 1141 case POWERPC_EXCP_PERFM: /* Embedded performance monitor interrupt */ 1142 case POWERPC_EXCP_VPUA: /* Vector assist exception */ 1143 cpu_abort(cs, "%s exception not implemented\n", 1144 powerpc_excp_name(excp)); 1145 break; 1146 default: 1147 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); 1148 break; 1149 } 1150 1151 /* Sanity check */ 1152 if (!(env->msr_mask & MSR_HVB)) { 1153 if (new_msr & MSR_HVB) { 1154 cpu_abort(cs, "Trying to deliver HV exception (MSR) %d with " 1155 "no HV support\n", excp); 1156 } 1157 } 1158 1159 /* 1160 * Sort out endianness of interrupt, this differs depending on the 1161 * CPU, the HV mode, etc... 1162 */ 1163 if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) { 1164 new_msr |= (target_ulong)1 << MSR_LE; 1165 } 1166 1167 /* Save PC */ 1168 env->spr[SPR_SRR0] = env->nip; 1169 1170 /* Save MSR */ 1171 env->spr[SPR_SRR1] = msr; 1172 1173 powerpc_set_excp_state(cpu, vector, new_msr); 1174 } 1175 1176 static void powerpc_excp_booke(PowerPCCPU *cpu, int excp) 1177 { 1178 CPUState *cs = CPU(cpu); 1179 CPUPPCState *env = &cpu->env; 1180 target_ulong msr, new_msr, vector; 1181 int srr0, srr1; 1182 1183 if (excp <= POWERPC_EXCP_NONE || excp >= POWERPC_EXCP_NB) { 1184 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); 1185 } 1186 1187 qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx 1188 " => %s (%d) error=%02x\n", env->nip, powerpc_excp_name(excp), 1189 excp, env->error_code); 1190 1191 msr = env->msr; 1192 1193 /* 1194 * new interrupt handler msr preserves existing ME unless 1195 * explicitly overriden 1196 */ 1197 new_msr = env->msr & ((target_ulong)1 << MSR_ME); 1198 1199 /* target registers */ 1200 srr0 = SPR_SRR0; 1201 srr1 = SPR_SRR1; 1202 1203 /* 1204 * Hypervisor emulation assistance interrupt only exists on server 1205 * arch 2.05 server or later. 1206 */ 1207 if (excp == POWERPC_EXCP_HV_EMU) { 1208 excp = POWERPC_EXCP_PROGRAM; 1209 } 1210 1211 #ifdef TARGET_PPC64 1212 /* 1213 * SPEU and VPU share the same IVOR but they exist in different 1214 * processors. SPEU is e500v1/2 only and VPU is e6500 only. 1215 */ 1216 if (excp == POWERPC_EXCP_VPU) { 1217 excp = POWERPC_EXCP_SPEU; 1218 } 1219 #endif 1220 1221 vector = env->excp_vectors[excp]; 1222 if (vector == (target_ulong)-1ULL) { 1223 cpu_abort(cs, "Raised an exception without defined vector %d\n", 1224 excp); 1225 } 1226 1227 vector |= env->excp_prefix; 1228 1229 switch (excp) { 1230 case POWERPC_EXCP_CRITICAL: /* Critical input */ 1231 srr0 = SPR_BOOKE_CSRR0; 1232 srr1 = SPR_BOOKE_CSRR1; 1233 break; 1234 case POWERPC_EXCP_MCHECK: /* Machine check exception */ 1235 if (msr_me == 0) { 1236 /* 1237 * Machine check exception is not enabled. Enter 1238 * checkstop state. 1239 */ 1240 fprintf(stderr, "Machine check while not allowed. " 1241 "Entering checkstop state\n"); 1242 if (qemu_log_separate()) { 1243 qemu_log("Machine check while not allowed. " 1244 "Entering checkstop state\n"); 1245 } 1246 cs->halted = 1; 1247 cpu_interrupt_exittb(cs); 1248 } 1249 1250 /* machine check exceptions don't have ME set */ 1251 new_msr &= ~((target_ulong)1 << MSR_ME); 1252 1253 /* FIXME: choose one or the other based on CPU type */ 1254 srr0 = SPR_BOOKE_MCSRR0; 1255 srr1 = SPR_BOOKE_MCSRR1; 1256 1257 env->spr[SPR_BOOKE_CSRR0] = env->nip; 1258 env->spr[SPR_BOOKE_CSRR1] = msr; 1259 1260 break; 1261 case POWERPC_EXCP_DSI: /* Data storage exception */ 1262 trace_ppc_excp_dsi(env->spr[SPR_BOOKE_ESR], env->spr[SPR_BOOKE_DEAR]); 1263 break; 1264 case POWERPC_EXCP_ISI: /* Instruction storage exception */ 1265 trace_ppc_excp_isi(msr, env->nip); 1266 break; 1267 case POWERPC_EXCP_EXTERNAL: /* External input */ 1268 if (env->mpic_proxy) { 1269 /* IACK the IRQ on delivery */ 1270 env->spr[SPR_BOOKE_EPR] = ldl_phys(cs->as, env->mpic_iack); 1271 } 1272 break; 1273 case POWERPC_EXCP_ALIGN: /* Alignment exception */ 1274 break; 1275 case POWERPC_EXCP_PROGRAM: /* Program exception */ 1276 switch (env->error_code & ~0xF) { 1277 case POWERPC_EXCP_FP: 1278 if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) { 1279 trace_ppc_excp_fp_ignore(); 1280 cs->exception_index = POWERPC_EXCP_NONE; 1281 env->error_code = 0; 1282 return; 1283 } 1284 1285 /* 1286 * FP exceptions always have NIP pointing to the faulting 1287 * instruction, so always use store_next and claim we are 1288 * precise in the MSR. 1289 */ 1290 msr |= 0x00100000; 1291 env->spr[SPR_BOOKE_ESR] = ESR_FP; 1292 break; 1293 case POWERPC_EXCP_INVAL: 1294 trace_ppc_excp_inval(env->nip); 1295 msr |= 0x00080000; 1296 env->spr[SPR_BOOKE_ESR] = ESR_PIL; 1297 break; 1298 case POWERPC_EXCP_PRIV: 1299 msr |= 0x00040000; 1300 env->spr[SPR_BOOKE_ESR] = ESR_PPR; 1301 break; 1302 case POWERPC_EXCP_TRAP: 1303 msr |= 0x00020000; 1304 env->spr[SPR_BOOKE_ESR] = ESR_PTR; 1305 break; 1306 default: 1307 /* Should never occur */ 1308 cpu_abort(cs, "Invalid program exception %d. Aborting\n", 1309 env->error_code); 1310 break; 1311 } 1312 break; 1313 case POWERPC_EXCP_SYSCALL: /* System call exception */ 1314 dump_syscall(env); 1315 1316 /* 1317 * We need to correct the NIP which in this case is supposed 1318 * to point to the next instruction 1319 */ 1320 env->nip += 4; 1321 break; 1322 case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */ 1323 case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */ 1324 case POWERPC_EXCP_DECR: /* Decrementer exception */ 1325 break; 1326 case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt */ 1327 /* FIT on 4xx */ 1328 trace_ppc_excp_print("FIT"); 1329 break; 1330 case POWERPC_EXCP_WDT: /* Watchdog timer interrupt */ 1331 trace_ppc_excp_print("WDT"); 1332 srr0 = SPR_BOOKE_CSRR0; 1333 srr1 = SPR_BOOKE_CSRR1; 1334 break; 1335 case POWERPC_EXCP_DTLB: /* Data TLB error */ 1336 case POWERPC_EXCP_ITLB: /* Instruction TLB error */ 1337 break; 1338 case POWERPC_EXCP_DEBUG: /* Debug interrupt */ 1339 if (env->flags & POWERPC_FLAG_DE) { 1340 /* FIXME: choose one or the other based on CPU type */ 1341 srr0 = SPR_BOOKE_DSRR0; 1342 srr1 = SPR_BOOKE_DSRR1; 1343 1344 env->spr[SPR_BOOKE_CSRR0] = env->nip; 1345 env->spr[SPR_BOOKE_CSRR1] = msr; 1346 1347 /* DBSR already modified by caller */ 1348 } else { 1349 cpu_abort(cs, "Debug exception triggered on unsupported model\n"); 1350 } 1351 break; 1352 case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavailable/VPU */ 1353 env->spr[SPR_BOOKE_ESR] = ESR_SPV; 1354 break; 1355 case POWERPC_EXCP_RESET: /* System reset exception */ 1356 if (msr_pow) { 1357 cpu_abort(cs, "Trying to deliver power-saving system reset " 1358 "exception %d with no HV support\n", excp); 1359 } 1360 break; 1361 case POWERPC_EXCP_EFPDI: /* Embedded floating-point data interrupt */ 1362 case POWERPC_EXCP_EFPRI: /* Embedded floating-point round interrupt */ 1363 cpu_abort(cs, "%s exception not implemented\n", 1364 powerpc_excp_name(excp)); 1365 break; 1366 default: 1367 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); 1368 break; 1369 } 1370 1371 /* Sanity check */ 1372 if (!(env->msr_mask & MSR_HVB)) { 1373 if (new_msr & MSR_HVB) { 1374 cpu_abort(cs, "Trying to deliver HV exception (MSR) %d with " 1375 "no HV support\n", excp); 1376 } 1377 if (srr0 == SPR_HSRR0) { 1378 cpu_abort(cs, "Trying to deliver HV exception (HSRR) %d with " 1379 "no HV support\n", excp); 1380 } 1381 } 1382 1383 #if defined(TARGET_PPC64) 1384 if (env->spr[SPR_BOOKE_EPCR] & EPCR_ICM) { 1385 /* Cat.64-bit: EPCR.ICM is copied to MSR.CM */ 1386 new_msr |= (target_ulong)1 << MSR_CM; 1387 } else { 1388 vector = (uint32_t)vector; 1389 } 1390 #endif 1391 1392 /* Save PC */ 1393 env->spr[srr0] = env->nip; 1394 1395 /* Save MSR */ 1396 env->spr[srr1] = msr; 1397 1398 powerpc_set_excp_state(cpu, vector, new_msr); 1399 } 1400 1401 #ifdef TARGET_PPC64 1402 static void powerpc_excp_books(PowerPCCPU *cpu, int excp) 1403 { 1404 CPUState *cs = CPU(cpu); 1405 CPUPPCState *env = &cpu->env; 1406 int excp_model = env->excp_model; 1407 target_ulong msr, new_msr, vector; 1408 int srr0, srr1, lev = -1; 1409 1410 if (excp <= POWERPC_EXCP_NONE || excp >= POWERPC_EXCP_NB) { 1411 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); 1412 } 1413 1414 qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx 1415 " => %s (%d) error=%02x\n", env->nip, powerpc_excp_name(excp), 1416 excp, env->error_code); 1417 1418 /* new srr1 value excluding must-be-zero bits */ 1419 msr = env->msr & ~0x783f0000ULL; 1420 1421 /* 1422 * new interrupt handler msr preserves existing HV and ME unless 1423 * explicitly overriden 1424 */ 1425 new_msr = env->msr & (((target_ulong)1 << MSR_ME) | MSR_HVB); 1426 1427 /* target registers */ 1428 srr0 = SPR_SRR0; 1429 srr1 = SPR_SRR1; 1430 1431 /* 1432 * check for special resume at 0x100 from doze/nap/sleep/winkle on 1433 * P7/P8/P9 1434 */ 1435 if (env->resume_as_sreset) { 1436 excp = powerpc_reset_wakeup(cs, env, excp, &msr); 1437 } 1438 1439 /* 1440 * We don't want to generate a Hypervisor Emulation Assistance 1441 * Interrupt if we don't have HVB in msr_mask (PAPR mode). 1442 */ 1443 if (excp == POWERPC_EXCP_HV_EMU && !(env->msr_mask & MSR_HVB)) { 1444 excp = POWERPC_EXCP_PROGRAM; 1445 } 1446 1447 vector = env->excp_vectors[excp]; 1448 if (vector == (target_ulong)-1ULL) { 1449 cpu_abort(cs, "Raised an exception without defined vector %d\n", 1450 excp); 1451 } 1452 1453 vector |= env->excp_prefix; 1454 1455 switch (excp) { 1456 case POWERPC_EXCP_MCHECK: /* Machine check exception */ 1457 if (msr_me == 0) { 1458 /* 1459 * Machine check exception is not enabled. Enter 1460 * checkstop state. 1461 */ 1462 fprintf(stderr, "Machine check while not allowed. " 1463 "Entering checkstop state\n"); 1464 if (qemu_log_separate()) { 1465 qemu_log("Machine check while not allowed. " 1466 "Entering checkstop state\n"); 1467 } 1468 cs->halted = 1; 1469 cpu_interrupt_exittb(cs); 1470 } 1471 if (env->msr_mask & MSR_HVB) { 1472 /* 1473 * ISA specifies HV, but can be delivered to guest with HV 1474 * clear (e.g., see FWNMI in PAPR). 1475 */ 1476 new_msr |= (target_ulong)MSR_HVB; 1477 } 1478 1479 /* machine check exceptions don't have ME set */ 1480 new_msr &= ~((target_ulong)1 << MSR_ME); 1481 1482 break; 1483 case POWERPC_EXCP_DSI: /* Data storage exception */ 1484 trace_ppc_excp_dsi(env->spr[SPR_DSISR], env->spr[SPR_DAR]); 1485 break; 1486 case POWERPC_EXCP_ISI: /* Instruction storage exception */ 1487 trace_ppc_excp_isi(msr, env->nip); 1488 msr |= env->error_code; 1489 break; 1490 case POWERPC_EXCP_EXTERNAL: /* External input */ 1491 { 1492 bool lpes0; 1493 1494 /* 1495 * LPES0 is only taken into consideration if we support HV 1496 * mode for this CPU. 1497 */ 1498 if (!env->has_hv_mode) { 1499 break; 1500 } 1501 1502 lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0); 1503 1504 if (!lpes0) { 1505 new_msr |= (target_ulong)MSR_HVB; 1506 new_msr |= env->msr & ((target_ulong)1 << MSR_RI); 1507 srr0 = SPR_HSRR0; 1508 srr1 = SPR_HSRR1; 1509 } 1510 1511 break; 1512 } 1513 case POWERPC_EXCP_ALIGN: /* Alignment exception */ 1514 /* Get rS/rD and rA from faulting opcode */ 1515 /* 1516 * Note: the opcode fields will not be set properly for a 1517 * direct store load/store, but nobody cares as nobody 1518 * actually uses direct store segments. 1519 */ 1520 env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16; 1521 break; 1522 case POWERPC_EXCP_PROGRAM: /* Program exception */ 1523 switch (env->error_code & ~0xF) { 1524 case POWERPC_EXCP_FP: 1525 if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) { 1526 trace_ppc_excp_fp_ignore(); 1527 cs->exception_index = POWERPC_EXCP_NONE; 1528 env->error_code = 0; 1529 return; 1530 } 1531 1532 /* 1533 * FP exceptions always have NIP pointing to the faulting 1534 * instruction, so always use store_next and claim we are 1535 * precise in the MSR. 1536 */ 1537 msr |= 0x00100000; 1538 break; 1539 case POWERPC_EXCP_INVAL: 1540 trace_ppc_excp_inval(env->nip); 1541 msr |= 0x00080000; 1542 break; 1543 case POWERPC_EXCP_PRIV: 1544 msr |= 0x00040000; 1545 break; 1546 case POWERPC_EXCP_TRAP: 1547 msr |= 0x00020000; 1548 break; 1549 default: 1550 /* Should never occur */ 1551 cpu_abort(cs, "Invalid program exception %d. Aborting\n", 1552 env->error_code); 1553 break; 1554 } 1555 break; 1556 case POWERPC_EXCP_SYSCALL: /* System call exception */ 1557 lev = env->error_code; 1558 1559 if ((lev == 1) && cpu->vhyp) { 1560 dump_hcall(env); 1561 } else { 1562 dump_syscall(env); 1563 } 1564 1565 /* 1566 * We need to correct the NIP which in this case is supposed 1567 * to point to the next instruction 1568 */ 1569 env->nip += 4; 1570 1571 /* "PAPR mode" built-in hypercall emulation */ 1572 if ((lev == 1) && cpu->vhyp) { 1573 PPCVirtualHypervisorClass *vhc = 1574 PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp); 1575 vhc->hypercall(cpu->vhyp, cpu); 1576 return; 1577 } 1578 if (lev == 1) { 1579 new_msr |= (target_ulong)MSR_HVB; 1580 } 1581 break; 1582 case POWERPC_EXCP_SYSCALL_VECTORED: /* scv exception */ 1583 lev = env->error_code; 1584 dump_syscall(env); 1585 env->nip += 4; 1586 new_msr |= env->msr & ((target_ulong)1 << MSR_EE); 1587 new_msr |= env->msr & ((target_ulong)1 << MSR_RI); 1588 1589 vector += lev * 0x20; 1590 1591 env->lr = env->nip; 1592 env->ctr = msr; 1593 break; 1594 case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */ 1595 case POWERPC_EXCP_DECR: /* Decrementer exception */ 1596 break; 1597 case POWERPC_EXCP_RESET: /* System reset exception */ 1598 /* A power-saving exception sets ME, otherwise it is unchanged */ 1599 if (msr_pow) { 1600 /* indicate that we resumed from power save mode */ 1601 msr |= 0x10000; 1602 new_msr |= ((target_ulong)1 << MSR_ME); 1603 } 1604 if (env->msr_mask & MSR_HVB) { 1605 /* 1606 * ISA specifies HV, but can be delivered to guest with HV 1607 * clear (e.g., see FWNMI in PAPR, NMI injection in QEMU). 1608 */ 1609 new_msr |= (target_ulong)MSR_HVB; 1610 } else { 1611 if (msr_pow) { 1612 cpu_abort(cs, "Trying to deliver power-saving system reset " 1613 "exception %d with no HV support\n", excp); 1614 } 1615 } 1616 break; 1617 case POWERPC_EXCP_DSEG: /* Data segment exception */ 1618 case POWERPC_EXCP_ISEG: /* Instruction segment exception */ 1619 case POWERPC_EXCP_TRACE: /* Trace exception */ 1620 break; 1621 case POWERPC_EXCP_HISI: /* Hypervisor instruction storage exception */ 1622 msr |= env->error_code; 1623 /* fall through */ 1624 case POWERPC_EXCP_HDECR: /* Hypervisor decrementer exception */ 1625 case POWERPC_EXCP_HDSI: /* Hypervisor data storage exception */ 1626 case POWERPC_EXCP_SDOOR_HV: /* Hypervisor Doorbell interrupt */ 1627 case POWERPC_EXCP_HV_EMU: 1628 case POWERPC_EXCP_HVIRT: /* Hypervisor virtualization */ 1629 srr0 = SPR_HSRR0; 1630 srr1 = SPR_HSRR1; 1631 new_msr |= (target_ulong)MSR_HVB; 1632 new_msr |= env->msr & ((target_ulong)1 << MSR_RI); 1633 break; 1634 case POWERPC_EXCP_VPU: /* Vector unavailable exception */ 1635 case POWERPC_EXCP_VSXU: /* VSX unavailable exception */ 1636 case POWERPC_EXCP_FU: /* Facility unavailable exception */ 1637 env->spr[SPR_FSCR] |= ((target_ulong)env->error_code << 56); 1638 break; 1639 case POWERPC_EXCP_HV_FU: /* Hypervisor Facility Unavailable Exception */ 1640 env->spr[SPR_HFSCR] |= ((target_ulong)env->error_code << FSCR_IC_POS); 1641 srr0 = SPR_HSRR0; 1642 srr1 = SPR_HSRR1; 1643 new_msr |= (target_ulong)MSR_HVB; 1644 new_msr |= env->msr & ((target_ulong)1 << MSR_RI); 1645 break; 1646 case POWERPC_EXCP_THERM: /* Thermal interrupt */ 1647 case POWERPC_EXCP_PERFM: /* Embedded performance monitor interrupt */ 1648 case POWERPC_EXCP_VPUA: /* Vector assist exception */ 1649 case POWERPC_EXCP_MAINT: /* Maintenance exception */ 1650 case POWERPC_EXCP_SDOOR: /* Doorbell interrupt */ 1651 case POWERPC_EXCP_HV_MAINT: /* Hypervisor Maintenance exception */ 1652 cpu_abort(cs, "%s exception not implemented\n", 1653 powerpc_excp_name(excp)); 1654 break; 1655 default: 1656 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); 1657 break; 1658 } 1659 1660 /* Sanity check */ 1661 if (!(env->msr_mask & MSR_HVB)) { 1662 if (new_msr & MSR_HVB) { 1663 cpu_abort(cs, "Trying to deliver HV exception (MSR) %d with " 1664 "no HV support\n", excp); 1665 } 1666 if (srr0 == SPR_HSRR0) { 1667 cpu_abort(cs, "Trying to deliver HV exception (HSRR) %d with " 1668 "no HV support\n", excp); 1669 } 1670 } 1671 1672 /* 1673 * Sort out endianness of interrupt, this differs depending on the 1674 * CPU, the HV mode, etc... 1675 */ 1676 if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) { 1677 new_msr |= (target_ulong)1 << MSR_LE; 1678 } 1679 1680 new_msr |= (target_ulong)1 << MSR_SF; 1681 1682 if (excp != POWERPC_EXCP_SYSCALL_VECTORED) { 1683 /* Save PC */ 1684 env->spr[srr0] = env->nip; 1685 1686 /* Save MSR */ 1687 env->spr[srr1] = msr; 1688 } 1689 1690 /* This can update new_msr and vector if AIL applies */ 1691 ppc_excp_apply_ail(cpu, excp_model, excp, msr, &new_msr, &vector); 1692 1693 powerpc_set_excp_state(cpu, vector, new_msr); 1694 } 1695 #else 1696 static inline void powerpc_excp_books(PowerPCCPU *cpu, int excp) 1697 { 1698 g_assert_not_reached(); 1699 } 1700 #endif 1701 1702 /* 1703 * Note that this function should be greatly optimized when called 1704 * with a constant excp, from ppc_hw_interrupt 1705 */ 1706 static inline void powerpc_excp_legacy(PowerPCCPU *cpu, int excp) 1707 { 1708 CPUState *cs = CPU(cpu); 1709 CPUPPCState *env = &cpu->env; 1710 int excp_model = env->excp_model; 1711 target_ulong msr, new_msr, vector; 1712 int srr0, srr1, lev = -1; 1713 1714 if (excp <= POWERPC_EXCP_NONE || excp >= POWERPC_EXCP_NB) { 1715 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); 1716 } 1717 1718 qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx 1719 " => %s (%d) error=%02x\n", env->nip, powerpc_excp_name(excp), 1720 excp, env->error_code); 1721 1722 /* new srr1 value excluding must-be-zero bits */ 1723 if (excp_model == POWERPC_EXCP_BOOKE) { 1724 msr = env->msr; 1725 } else { 1726 msr = env->msr & ~0x783f0000ULL; 1727 } 1728 1729 /* 1730 * new interrupt handler msr preserves existing HV and ME unless 1731 * explicitly overriden 1732 */ 1733 new_msr = env->msr & (((target_ulong)1 << MSR_ME) | MSR_HVB); 1734 1735 /* target registers */ 1736 srr0 = SPR_SRR0; 1737 srr1 = SPR_SRR1; 1738 1739 /* 1740 * check for special resume at 0x100 from doze/nap/sleep/winkle on 1741 * P7/P8/P9 1742 */ 1743 if (env->resume_as_sreset) { 1744 excp = powerpc_reset_wakeup(cs, env, excp, &msr); 1745 } 1746 1747 /* 1748 * Hypervisor emulation assistance interrupt only exists on server 1749 * arch 2.05 server or later. We also don't want to generate it if 1750 * we don't have HVB in msr_mask (PAPR mode). 1751 */ 1752 if (excp == POWERPC_EXCP_HV_EMU 1753 #if defined(TARGET_PPC64) 1754 && !(mmu_is_64bit(env->mmu_model) && (env->msr_mask & MSR_HVB)) 1755 #endif /* defined(TARGET_PPC64) */ 1756 1757 ) { 1758 excp = POWERPC_EXCP_PROGRAM; 1759 } 1760 1761 #ifdef TARGET_PPC64 1762 /* 1763 * SPEU and VPU share the same IVOR but they exist in different 1764 * processors. SPEU is e500v1/2 only and VPU is e6500 only. 1765 */ 1766 if (excp_model == POWERPC_EXCP_BOOKE && excp == POWERPC_EXCP_VPU) { 1767 excp = POWERPC_EXCP_SPEU; 1768 } 1769 #endif 1770 1771 vector = env->excp_vectors[excp]; 1772 if (vector == (target_ulong)-1ULL) { 1773 cpu_abort(cs, "Raised an exception without defined vector %d\n", 1774 excp); 1775 } 1776 1777 vector |= env->excp_prefix; 1778 1779 switch (excp) { 1780 case POWERPC_EXCP_CRITICAL: /* Critical input */ 1781 switch (excp_model) { 1782 case POWERPC_EXCP_40x: 1783 srr0 = SPR_40x_SRR2; 1784 srr1 = SPR_40x_SRR3; 1785 break; 1786 case POWERPC_EXCP_BOOKE: 1787 srr0 = SPR_BOOKE_CSRR0; 1788 srr1 = SPR_BOOKE_CSRR1; 1789 break; 1790 case POWERPC_EXCP_6xx: 1791 break; 1792 default: 1793 goto excp_invalid; 1794 } 1795 break; 1796 case POWERPC_EXCP_MCHECK: /* Machine check exception */ 1797 if (msr_me == 0) { 1798 /* 1799 * Machine check exception is not enabled. Enter 1800 * checkstop state. 1801 */ 1802 fprintf(stderr, "Machine check while not allowed. " 1803 "Entering checkstop state\n"); 1804 if (qemu_log_separate()) { 1805 qemu_log("Machine check while not allowed. " 1806 "Entering checkstop state\n"); 1807 } 1808 cs->halted = 1; 1809 cpu_interrupt_exittb(cs); 1810 } 1811 if (env->msr_mask & MSR_HVB) { 1812 /* 1813 * ISA specifies HV, but can be delivered to guest with HV 1814 * clear (e.g., see FWNMI in PAPR). 1815 */ 1816 new_msr |= (target_ulong)MSR_HVB; 1817 } 1818 1819 /* machine check exceptions don't have ME set */ 1820 new_msr &= ~((target_ulong)1 << MSR_ME); 1821 1822 /* XXX: should also have something loaded in DAR / DSISR */ 1823 switch (excp_model) { 1824 case POWERPC_EXCP_40x: 1825 srr0 = SPR_40x_SRR2; 1826 srr1 = SPR_40x_SRR3; 1827 break; 1828 case POWERPC_EXCP_BOOKE: 1829 /* FIXME: choose one or the other based on CPU type */ 1830 srr0 = SPR_BOOKE_MCSRR0; 1831 srr1 = SPR_BOOKE_MCSRR1; 1832 1833 env->spr[SPR_BOOKE_CSRR0] = env->nip; 1834 env->spr[SPR_BOOKE_CSRR1] = msr; 1835 break; 1836 default: 1837 break; 1838 } 1839 break; 1840 case POWERPC_EXCP_DSI: /* Data storage exception */ 1841 trace_ppc_excp_dsi(env->spr[SPR_DSISR], env->spr[SPR_DAR]); 1842 break; 1843 case POWERPC_EXCP_ISI: /* Instruction storage exception */ 1844 trace_ppc_excp_isi(msr, env->nip); 1845 msr |= env->error_code; 1846 break; 1847 case POWERPC_EXCP_EXTERNAL: /* External input */ 1848 { 1849 bool lpes0; 1850 1851 cs = CPU(cpu); 1852 1853 /* 1854 * Exception targeting modifiers 1855 * 1856 * LPES0 is supported on POWER7/8/9 1857 * LPES1 is not supported (old iSeries mode) 1858 * 1859 * On anything else, we behave as if LPES0 is 1 1860 * (externals don't alter MSR:HV) 1861 */ 1862 #if defined(TARGET_PPC64) 1863 if (excp_model == POWERPC_EXCP_POWER7 || 1864 excp_model == POWERPC_EXCP_POWER8 || 1865 excp_model == POWERPC_EXCP_POWER9 || 1866 excp_model == POWERPC_EXCP_POWER10) { 1867 lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0); 1868 } else 1869 #endif /* defined(TARGET_PPC64) */ 1870 { 1871 lpes0 = true; 1872 } 1873 1874 if (!lpes0) { 1875 new_msr |= (target_ulong)MSR_HVB; 1876 new_msr |= env->msr & ((target_ulong)1 << MSR_RI); 1877 srr0 = SPR_HSRR0; 1878 srr1 = SPR_HSRR1; 1879 } 1880 if (env->mpic_proxy) { 1881 /* IACK the IRQ on delivery */ 1882 env->spr[SPR_BOOKE_EPR] = ldl_phys(cs->as, env->mpic_iack); 1883 } 1884 break; 1885 } 1886 case POWERPC_EXCP_ALIGN: /* Alignment exception */ 1887 /* Get rS/rD and rA from faulting opcode */ 1888 /* 1889 * Note: the opcode fields will not be set properly for a 1890 * direct store load/store, but nobody cares as nobody 1891 * actually uses direct store segments. 1892 */ 1893 env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16; 1894 break; 1895 case POWERPC_EXCP_PROGRAM: /* Program exception */ 1896 switch (env->error_code & ~0xF) { 1897 case POWERPC_EXCP_FP: 1898 if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) { 1899 trace_ppc_excp_fp_ignore(); 1900 cs->exception_index = POWERPC_EXCP_NONE; 1901 env->error_code = 0; 1902 return; 1903 } 1904 1905 /* 1906 * FP exceptions always have NIP pointing to the faulting 1907 * instruction, so always use store_next and claim we are 1908 * precise in the MSR. 1909 */ 1910 msr |= 0x00100000; 1911 env->spr[SPR_BOOKE_ESR] = ESR_FP; 1912 break; 1913 case POWERPC_EXCP_INVAL: 1914 trace_ppc_excp_inval(env->nip); 1915 msr |= 0x00080000; 1916 env->spr[SPR_BOOKE_ESR] = ESR_PIL; 1917 break; 1918 case POWERPC_EXCP_PRIV: 1919 msr |= 0x00040000; 1920 env->spr[SPR_BOOKE_ESR] = ESR_PPR; 1921 break; 1922 case POWERPC_EXCP_TRAP: 1923 msr |= 0x00020000; 1924 env->spr[SPR_BOOKE_ESR] = ESR_PTR; 1925 break; 1926 default: 1927 /* Should never occur */ 1928 cpu_abort(cs, "Invalid program exception %d. Aborting\n", 1929 env->error_code); 1930 break; 1931 } 1932 break; 1933 case POWERPC_EXCP_SYSCALL: /* System call exception */ 1934 lev = env->error_code; 1935 1936 if ((lev == 1) && cpu->vhyp) { 1937 dump_hcall(env); 1938 } else { 1939 dump_syscall(env); 1940 } 1941 1942 /* 1943 * We need to correct the NIP which in this case is supposed 1944 * to point to the next instruction 1945 */ 1946 env->nip += 4; 1947 1948 /* "PAPR mode" built-in hypercall emulation */ 1949 if ((lev == 1) && cpu->vhyp) { 1950 PPCVirtualHypervisorClass *vhc = 1951 PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp); 1952 vhc->hypercall(cpu->vhyp, cpu); 1953 return; 1954 } 1955 if (lev == 1) { 1956 new_msr |= (target_ulong)MSR_HVB; 1957 } 1958 break; 1959 case POWERPC_EXCP_SYSCALL_VECTORED: /* scv exception */ 1960 lev = env->error_code; 1961 dump_syscall(env); 1962 env->nip += 4; 1963 new_msr |= env->msr & ((target_ulong)1 << MSR_EE); 1964 new_msr |= env->msr & ((target_ulong)1 << MSR_RI); 1965 1966 vector += lev * 0x20; 1967 1968 env->lr = env->nip; 1969 env->ctr = msr; 1970 break; 1971 case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */ 1972 case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */ 1973 case POWERPC_EXCP_DECR: /* Decrementer exception */ 1974 break; 1975 case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt */ 1976 /* FIT on 4xx */ 1977 trace_ppc_excp_print("FIT"); 1978 break; 1979 case POWERPC_EXCP_WDT: /* Watchdog timer interrupt */ 1980 trace_ppc_excp_print("WDT"); 1981 switch (excp_model) { 1982 case POWERPC_EXCP_BOOKE: 1983 srr0 = SPR_BOOKE_CSRR0; 1984 srr1 = SPR_BOOKE_CSRR1; 1985 break; 1986 default: 1987 break; 1988 } 1989 break; 1990 case POWERPC_EXCP_DTLB: /* Data TLB error */ 1991 case POWERPC_EXCP_ITLB: /* Instruction TLB error */ 1992 break; 1993 case POWERPC_EXCP_DEBUG: /* Debug interrupt */ 1994 if (env->flags & POWERPC_FLAG_DE) { 1995 /* FIXME: choose one or the other based on CPU type */ 1996 srr0 = SPR_BOOKE_DSRR0; 1997 srr1 = SPR_BOOKE_DSRR1; 1998 1999 env->spr[SPR_BOOKE_CSRR0] = env->nip; 2000 env->spr[SPR_BOOKE_CSRR1] = msr; 2001 2002 /* DBSR already modified by caller */ 2003 } else { 2004 cpu_abort(cs, "Debug exception triggered on unsupported model\n"); 2005 } 2006 break; 2007 case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavailable/VPU */ 2008 env->spr[SPR_BOOKE_ESR] = ESR_SPV; 2009 break; 2010 case POWERPC_EXCP_DOORI: /* Embedded doorbell interrupt */ 2011 break; 2012 case POWERPC_EXCP_DOORCI: /* Embedded doorbell critical interrupt */ 2013 srr0 = SPR_BOOKE_CSRR0; 2014 srr1 = SPR_BOOKE_CSRR1; 2015 break; 2016 case POWERPC_EXCP_RESET: /* System reset exception */ 2017 /* A power-saving exception sets ME, otherwise it is unchanged */ 2018 if (msr_pow) { 2019 /* indicate that we resumed from power save mode */ 2020 msr |= 0x10000; 2021 new_msr |= ((target_ulong)1 << MSR_ME); 2022 } 2023 if (env->msr_mask & MSR_HVB) { 2024 /* 2025 * ISA specifies HV, but can be delivered to guest with HV 2026 * clear (e.g., see FWNMI in PAPR, NMI injection in QEMU). 2027 */ 2028 new_msr |= (target_ulong)MSR_HVB; 2029 } else { 2030 if (msr_pow) { 2031 cpu_abort(cs, "Trying to deliver power-saving system reset " 2032 "exception %d with no HV support\n", excp); 2033 } 2034 } 2035 break; 2036 case POWERPC_EXCP_DSEG: /* Data segment exception */ 2037 case POWERPC_EXCP_ISEG: /* Instruction segment exception */ 2038 case POWERPC_EXCP_TRACE: /* Trace exception */ 2039 break; 2040 case POWERPC_EXCP_HISI: /* Hypervisor instruction storage exception */ 2041 msr |= env->error_code; 2042 /* fall through */ 2043 case POWERPC_EXCP_HDECR: /* Hypervisor decrementer exception */ 2044 case POWERPC_EXCP_HDSI: /* Hypervisor data storage exception */ 2045 case POWERPC_EXCP_HDSEG: /* Hypervisor data segment exception */ 2046 case POWERPC_EXCP_HISEG: /* Hypervisor instruction segment exception */ 2047 case POWERPC_EXCP_SDOOR_HV: /* Hypervisor Doorbell interrupt */ 2048 case POWERPC_EXCP_HV_EMU: 2049 case POWERPC_EXCP_HVIRT: /* Hypervisor virtualization */ 2050 srr0 = SPR_HSRR0; 2051 srr1 = SPR_HSRR1; 2052 new_msr |= (target_ulong)MSR_HVB; 2053 new_msr |= env->msr & ((target_ulong)1 << MSR_RI); 2054 break; 2055 case POWERPC_EXCP_VPU: /* Vector unavailable exception */ 2056 case POWERPC_EXCP_VSXU: /* VSX unavailable exception */ 2057 case POWERPC_EXCP_FU: /* Facility unavailable exception */ 2058 #ifdef TARGET_PPC64 2059 env->spr[SPR_FSCR] |= ((target_ulong)env->error_code << 56); 2060 #endif 2061 break; 2062 case POWERPC_EXCP_HV_FU: /* Hypervisor Facility Unavailable Exception */ 2063 #ifdef TARGET_PPC64 2064 env->spr[SPR_HFSCR] |= ((target_ulong)env->error_code << FSCR_IC_POS); 2065 srr0 = SPR_HSRR0; 2066 srr1 = SPR_HSRR1; 2067 new_msr |= (target_ulong)MSR_HVB; 2068 new_msr |= env->msr & ((target_ulong)1 << MSR_RI); 2069 #endif 2070 break; 2071 case POWERPC_EXCP_PIT: /* Programmable interval timer interrupt */ 2072 trace_ppc_excp_print("PIT"); 2073 break; 2074 case POWERPC_EXCP_IFTLB: /* Instruction fetch TLB error */ 2075 case POWERPC_EXCP_DLTLB: /* Data load TLB miss */ 2076 case POWERPC_EXCP_DSTLB: /* Data store TLB miss */ 2077 switch (excp_model) { 2078 case POWERPC_EXCP_6xx: 2079 /* Swap temporary saved registers with GPRs */ 2080 if (!(new_msr & ((target_ulong)1 << MSR_TGPR))) { 2081 new_msr |= (target_ulong)1 << MSR_TGPR; 2082 hreg_swap_gpr_tgpr(env); 2083 } 2084 /* fall through */ 2085 case POWERPC_EXCP_7xx: 2086 ppc_excp_debug_sw_tlb(env, excp); 2087 2088 msr |= env->crf[0] << 28; 2089 msr |= env->error_code; /* key, D/I, S/L bits */ 2090 /* Set way using a LRU mechanism */ 2091 msr |= ((env->last_way + 1) & (env->nb_ways - 1)) << 17; 2092 break; 2093 default: 2094 cpu_abort(cs, "Invalid TLB miss exception\n"); 2095 break; 2096 } 2097 break; 2098 case POWERPC_EXCP_EFPDI: /* Embedded floating-point data interrupt */ 2099 case POWERPC_EXCP_EFPRI: /* Embedded floating-point round interrupt */ 2100 case POWERPC_EXCP_EPERFM: /* Embedded performance monitor interrupt */ 2101 case POWERPC_EXCP_FPA: /* Floating-point assist exception */ 2102 case POWERPC_EXCP_DABR: /* Data address breakpoint */ 2103 case POWERPC_EXCP_IABR: /* Instruction address breakpoint */ 2104 case POWERPC_EXCP_SMI: /* System management interrupt */ 2105 case POWERPC_EXCP_THERM: /* Thermal interrupt */ 2106 case POWERPC_EXCP_PERFM: /* Embedded performance monitor interrupt */ 2107 case POWERPC_EXCP_VPUA: /* Vector assist exception */ 2108 case POWERPC_EXCP_SOFTP: /* Soft patch exception */ 2109 case POWERPC_EXCP_MAINT: /* Maintenance exception */ 2110 case POWERPC_EXCP_MEXTBR: /* Maskable external breakpoint */ 2111 case POWERPC_EXCP_NMEXTBR: /* Non maskable external breakpoint */ 2112 cpu_abort(cs, "%s exception not implemented\n", 2113 powerpc_excp_name(excp)); 2114 break; 2115 default: 2116 excp_invalid: 2117 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); 2118 break; 2119 } 2120 2121 /* Sanity check */ 2122 if (!(env->msr_mask & MSR_HVB)) { 2123 if (new_msr & MSR_HVB) { 2124 cpu_abort(cs, "Trying to deliver HV exception (MSR) %d with " 2125 "no HV support\n", excp); 2126 } 2127 if (srr0 == SPR_HSRR0) { 2128 cpu_abort(cs, "Trying to deliver HV exception (HSRR) %d with " 2129 "no HV support\n", excp); 2130 } 2131 } 2132 2133 /* 2134 * Sort out endianness of interrupt, this differs depending on the 2135 * CPU, the HV mode, etc... 2136 */ 2137 if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) { 2138 new_msr |= (target_ulong)1 << MSR_LE; 2139 } 2140 2141 #if defined(TARGET_PPC64) 2142 if (excp_model == POWERPC_EXCP_BOOKE) { 2143 if (env->spr[SPR_BOOKE_EPCR] & EPCR_ICM) { 2144 /* Cat.64-bit: EPCR.ICM is copied to MSR.CM */ 2145 new_msr |= (target_ulong)1 << MSR_CM; 2146 } else { 2147 vector = (uint32_t)vector; 2148 } 2149 } else { 2150 if (!msr_isf && !mmu_is_64bit(env->mmu_model)) { 2151 vector = (uint32_t)vector; 2152 } else { 2153 new_msr |= (target_ulong)1 << MSR_SF; 2154 } 2155 } 2156 #endif 2157 2158 if (excp != POWERPC_EXCP_SYSCALL_VECTORED) { 2159 /* Save PC */ 2160 env->spr[srr0] = env->nip; 2161 2162 /* Save MSR */ 2163 env->spr[srr1] = msr; 2164 } 2165 2166 /* This can update new_msr and vector if AIL applies */ 2167 ppc_excp_apply_ail(cpu, excp_model, excp, msr, &new_msr, &vector); 2168 2169 powerpc_set_excp_state(cpu, vector, new_msr); 2170 } 2171 2172 static void powerpc_excp(PowerPCCPU *cpu, int excp) 2173 { 2174 CPUPPCState *env = &cpu->env; 2175 2176 switch (env->excp_model) { 2177 case POWERPC_EXCP_40x: 2178 powerpc_excp_40x(cpu, excp); 2179 break; 2180 case POWERPC_EXCP_6xx: 2181 powerpc_excp_6xx(cpu, excp); 2182 break; 2183 case POWERPC_EXCP_7xx: 2184 powerpc_excp_7xx(cpu, excp); 2185 break; 2186 case POWERPC_EXCP_74xx: 2187 powerpc_excp_74xx(cpu, excp); 2188 break; 2189 case POWERPC_EXCP_BOOKE: 2190 powerpc_excp_booke(cpu, excp); 2191 break; 2192 case POWERPC_EXCP_970: 2193 case POWERPC_EXCP_POWER7: 2194 case POWERPC_EXCP_POWER8: 2195 case POWERPC_EXCP_POWER9: 2196 case POWERPC_EXCP_POWER10: 2197 powerpc_excp_books(cpu, excp); 2198 break; 2199 default: 2200 powerpc_excp_legacy(cpu, excp); 2201 } 2202 } 2203 2204 void ppc_cpu_do_interrupt(CPUState *cs) 2205 { 2206 PowerPCCPU *cpu = POWERPC_CPU(cs); 2207 2208 powerpc_excp(cpu, cs->exception_index); 2209 } 2210 2211 static void ppc_hw_interrupt(CPUPPCState *env) 2212 { 2213 PowerPCCPU *cpu = env_archcpu(env); 2214 bool async_deliver; 2215 2216 /* External reset */ 2217 if (env->pending_interrupts & (1 << PPC_INTERRUPT_RESET)) { 2218 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_RESET); 2219 powerpc_excp(cpu, POWERPC_EXCP_RESET); 2220 return; 2221 } 2222 /* Machine check exception */ 2223 if (env->pending_interrupts & (1 << PPC_INTERRUPT_MCK)) { 2224 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_MCK); 2225 powerpc_excp(cpu, POWERPC_EXCP_MCHECK); 2226 return; 2227 } 2228 #if 0 /* TODO */ 2229 /* External debug exception */ 2230 if (env->pending_interrupts & (1 << PPC_INTERRUPT_DEBUG)) { 2231 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DEBUG); 2232 powerpc_excp(cpu, POWERPC_EXCP_DEBUG); 2233 return; 2234 } 2235 #endif 2236 2237 /* 2238 * For interrupts that gate on MSR:EE, we need to do something a 2239 * bit more subtle, as we need to let them through even when EE is 2240 * clear when coming out of some power management states (in order 2241 * for them to become a 0x100). 2242 */ 2243 async_deliver = (msr_ee != 0) || env->resume_as_sreset; 2244 2245 /* Hypervisor decrementer exception */ 2246 if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDECR)) { 2247 /* LPCR will be clear when not supported so this will work */ 2248 bool hdice = !!(env->spr[SPR_LPCR] & LPCR_HDICE); 2249 if ((async_deliver || msr_hv == 0) && hdice) { 2250 /* HDEC clears on delivery */ 2251 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDECR); 2252 powerpc_excp(cpu, POWERPC_EXCP_HDECR); 2253 return; 2254 } 2255 } 2256 2257 /* Hypervisor virtualization interrupt */ 2258 if (env->pending_interrupts & (1 << PPC_INTERRUPT_HVIRT)) { 2259 /* LPCR will be clear when not supported so this will work */ 2260 bool hvice = !!(env->spr[SPR_LPCR] & LPCR_HVICE); 2261 if ((async_deliver || msr_hv == 0) && hvice) { 2262 powerpc_excp(cpu, POWERPC_EXCP_HVIRT); 2263 return; 2264 } 2265 } 2266 2267 /* External interrupt can ignore MSR:EE under some circumstances */ 2268 if (env->pending_interrupts & (1 << PPC_INTERRUPT_EXT)) { 2269 bool lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0); 2270 bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC); 2271 /* HEIC blocks delivery to the hypervisor */ 2272 if ((async_deliver && !(heic && msr_hv && !msr_pr)) || 2273 (env->has_hv_mode && msr_hv == 0 && !lpes0)) { 2274 powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL); 2275 return; 2276 } 2277 } 2278 if (msr_ce != 0) { 2279 /* External critical interrupt */ 2280 if (env->pending_interrupts & (1 << PPC_INTERRUPT_CEXT)) { 2281 powerpc_excp(cpu, POWERPC_EXCP_CRITICAL); 2282 return; 2283 } 2284 } 2285 if (async_deliver != 0) { 2286 /* Watchdog timer on embedded PowerPC */ 2287 if (env->pending_interrupts & (1 << PPC_INTERRUPT_WDT)) { 2288 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_WDT); 2289 powerpc_excp(cpu, POWERPC_EXCP_WDT); 2290 return; 2291 } 2292 if (env->pending_interrupts & (1 << PPC_INTERRUPT_CDOORBELL)) { 2293 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_CDOORBELL); 2294 powerpc_excp(cpu, POWERPC_EXCP_DOORCI); 2295 return; 2296 } 2297 /* Fixed interval timer on embedded PowerPC */ 2298 if (env->pending_interrupts & (1 << PPC_INTERRUPT_FIT)) { 2299 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_FIT); 2300 powerpc_excp(cpu, POWERPC_EXCP_FIT); 2301 return; 2302 } 2303 /* Programmable interval timer on embedded PowerPC */ 2304 if (env->pending_interrupts & (1 << PPC_INTERRUPT_PIT)) { 2305 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PIT); 2306 powerpc_excp(cpu, POWERPC_EXCP_PIT); 2307 return; 2308 } 2309 /* Decrementer exception */ 2310 if (env->pending_interrupts & (1 << PPC_INTERRUPT_DECR)) { 2311 if (ppc_decr_clear_on_delivery(env)) { 2312 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DECR); 2313 } 2314 powerpc_excp(cpu, POWERPC_EXCP_DECR); 2315 return; 2316 } 2317 if (env->pending_interrupts & (1 << PPC_INTERRUPT_DOORBELL)) { 2318 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL); 2319 if (is_book3s_arch2x(env)) { 2320 powerpc_excp(cpu, POWERPC_EXCP_SDOOR); 2321 } else { 2322 powerpc_excp(cpu, POWERPC_EXCP_DOORI); 2323 } 2324 return; 2325 } 2326 if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDOORBELL)) { 2327 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDOORBELL); 2328 powerpc_excp(cpu, POWERPC_EXCP_SDOOR_HV); 2329 return; 2330 } 2331 if (env->pending_interrupts & (1 << PPC_INTERRUPT_PERFM)) { 2332 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PERFM); 2333 powerpc_excp(cpu, POWERPC_EXCP_PERFM); 2334 return; 2335 } 2336 /* Thermal interrupt */ 2337 if (env->pending_interrupts & (1 << PPC_INTERRUPT_THERM)) { 2338 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_THERM); 2339 powerpc_excp(cpu, POWERPC_EXCP_THERM); 2340 return; 2341 } 2342 } 2343 2344 if (env->resume_as_sreset) { 2345 /* 2346 * This is a bug ! It means that has_work took us out of halt without 2347 * anything to deliver while in a PM state that requires getting 2348 * out via a 0x100 2349 * 2350 * This means we will incorrectly execute past the power management 2351 * instruction instead of triggering a reset. 2352 * 2353 * It generally means a discrepancy between the wakeup conditions in the 2354 * processor has_work implementation and the logic in this function. 2355 */ 2356 cpu_abort(env_cpu(env), 2357 "Wakeup from PM state but interrupt Undelivered"); 2358 } 2359 } 2360 2361 void ppc_cpu_do_system_reset(CPUState *cs) 2362 { 2363 PowerPCCPU *cpu = POWERPC_CPU(cs); 2364 2365 powerpc_excp(cpu, POWERPC_EXCP_RESET); 2366 } 2367 2368 void ppc_cpu_do_fwnmi_machine_check(CPUState *cs, target_ulong vector) 2369 { 2370 PowerPCCPU *cpu = POWERPC_CPU(cs); 2371 CPUPPCState *env = &cpu->env; 2372 target_ulong msr = 0; 2373 2374 /* 2375 * Set MSR and NIP for the handler, SRR0/1, DAR and DSISR have already 2376 * been set by KVM. 2377 */ 2378 msr = (1ULL << MSR_ME); 2379 msr |= env->msr & (1ULL << MSR_SF); 2380 if (ppc_interrupts_little_endian(cpu, false)) { 2381 msr |= (1ULL << MSR_LE); 2382 } 2383 2384 powerpc_set_excp_state(cpu, vector, msr); 2385 } 2386 2387 bool ppc_cpu_exec_interrupt(CPUState *cs, int interrupt_request) 2388 { 2389 PowerPCCPU *cpu = POWERPC_CPU(cs); 2390 CPUPPCState *env = &cpu->env; 2391 2392 if (interrupt_request & CPU_INTERRUPT_HARD) { 2393 ppc_hw_interrupt(env); 2394 if (env->pending_interrupts == 0) { 2395 cs->interrupt_request &= ~CPU_INTERRUPT_HARD; 2396 } 2397 return true; 2398 } 2399 return false; 2400 } 2401 2402 #endif /* !CONFIG_USER_ONLY */ 2403 2404 /*****************************************************************************/ 2405 /* Exceptions processing helpers */ 2406 2407 void raise_exception_err_ra(CPUPPCState *env, uint32_t exception, 2408 uint32_t error_code, uintptr_t raddr) 2409 { 2410 CPUState *cs = env_cpu(env); 2411 2412 cs->exception_index = exception; 2413 env->error_code = error_code; 2414 cpu_loop_exit_restore(cs, raddr); 2415 } 2416 2417 void raise_exception_err(CPUPPCState *env, uint32_t exception, 2418 uint32_t error_code) 2419 { 2420 raise_exception_err_ra(env, exception, error_code, 0); 2421 } 2422 2423 void raise_exception(CPUPPCState *env, uint32_t exception) 2424 { 2425 raise_exception_err_ra(env, exception, 0, 0); 2426 } 2427 2428 void raise_exception_ra(CPUPPCState *env, uint32_t exception, 2429 uintptr_t raddr) 2430 { 2431 raise_exception_err_ra(env, exception, 0, raddr); 2432 } 2433 2434 #ifdef CONFIG_TCG 2435 void helper_raise_exception_err(CPUPPCState *env, uint32_t exception, 2436 uint32_t error_code) 2437 { 2438 raise_exception_err_ra(env, exception, error_code, 0); 2439 } 2440 2441 void helper_raise_exception(CPUPPCState *env, uint32_t exception) 2442 { 2443 raise_exception_err_ra(env, exception, 0, 0); 2444 } 2445 #endif 2446 2447 #if !defined(CONFIG_USER_ONLY) 2448 #ifdef CONFIG_TCG 2449 void helper_store_msr(CPUPPCState *env, target_ulong val) 2450 { 2451 uint32_t excp = hreg_store_msr(env, val, 0); 2452 2453 if (excp != 0) { 2454 CPUState *cs = env_cpu(env); 2455 cpu_interrupt_exittb(cs); 2456 raise_exception(env, excp); 2457 } 2458 } 2459 2460 #if defined(TARGET_PPC64) 2461 void helper_scv(CPUPPCState *env, uint32_t lev) 2462 { 2463 if (env->spr[SPR_FSCR] & (1ull << FSCR_SCV)) { 2464 raise_exception_err(env, POWERPC_EXCP_SYSCALL_VECTORED, lev); 2465 } else { 2466 raise_exception_err(env, POWERPC_EXCP_FU, FSCR_IC_SCV); 2467 } 2468 } 2469 2470 void helper_pminsn(CPUPPCState *env, powerpc_pm_insn_t insn) 2471 { 2472 CPUState *cs; 2473 2474 cs = env_cpu(env); 2475 cs->halted = 1; 2476 2477 /* Condition for waking up at 0x100 */ 2478 env->resume_as_sreset = (insn != PPC_PM_STOP) || 2479 (env->spr[SPR_PSSCR] & PSSCR_EC); 2480 } 2481 #endif /* defined(TARGET_PPC64) */ 2482 2483 static void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr) 2484 { 2485 CPUState *cs = env_cpu(env); 2486 2487 /* MSR:POW cannot be set by any form of rfi */ 2488 msr &= ~(1ULL << MSR_POW); 2489 2490 /* MSR:TGPR cannot be set by any form of rfi */ 2491 if (env->flags & POWERPC_FLAG_TGPR) 2492 msr &= ~(1ULL << MSR_TGPR); 2493 2494 #if defined(TARGET_PPC64) 2495 /* Switching to 32-bit ? Crop the nip */ 2496 if (!msr_is_64bit(env, msr)) { 2497 nip = (uint32_t)nip; 2498 } 2499 #else 2500 nip = (uint32_t)nip; 2501 #endif 2502 /* XXX: beware: this is false if VLE is supported */ 2503 env->nip = nip & ~((target_ulong)0x00000003); 2504 hreg_store_msr(env, msr, 1); 2505 trace_ppc_excp_rfi(env->nip, env->msr); 2506 /* 2507 * No need to raise an exception here, as rfi is always the last 2508 * insn of a TB 2509 */ 2510 cpu_interrupt_exittb(cs); 2511 /* Reset the reservation */ 2512 env->reserve_addr = -1; 2513 2514 /* Context synchronizing: check if TCG TLB needs flush */ 2515 check_tlb_flush(env, false); 2516 } 2517 2518 void helper_rfi(CPUPPCState *env) 2519 { 2520 do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1] & 0xfffffffful); 2521 } 2522 2523 #define MSR_BOOK3S_MASK 2524 #if defined(TARGET_PPC64) 2525 void helper_rfid(CPUPPCState *env) 2526 { 2527 /* 2528 * The architecture defines a number of rules for which bits can 2529 * change but in practice, we handle this in hreg_store_msr() 2530 * which will be called by do_rfi(), so there is no need to filter 2531 * here 2532 */ 2533 do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1]); 2534 } 2535 2536 void helper_rfscv(CPUPPCState *env) 2537 { 2538 do_rfi(env, env->lr, env->ctr); 2539 } 2540 2541 void helper_hrfid(CPUPPCState *env) 2542 { 2543 do_rfi(env, env->spr[SPR_HSRR0], env->spr[SPR_HSRR1]); 2544 } 2545 #endif 2546 2547 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) 2548 void helper_rfebb(CPUPPCState *env, target_ulong s) 2549 { 2550 target_ulong msr = env->msr; 2551 2552 /* 2553 * Handling of BESCR bits 32:33 according to PowerISA v3.1: 2554 * 2555 * "If BESCR 32:33 != 0b00 the instruction is treated as if 2556 * the instruction form were invalid." 2557 */ 2558 if (env->spr[SPR_BESCR] & BESCR_INVALID) { 2559 raise_exception_err(env, POWERPC_EXCP_PROGRAM, 2560 POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL); 2561 } 2562 2563 env->nip = env->spr[SPR_EBBRR]; 2564 2565 /* Switching to 32-bit ? Crop the nip */ 2566 if (!msr_is_64bit(env, msr)) { 2567 env->nip = (uint32_t)env->spr[SPR_EBBRR]; 2568 } 2569 2570 if (s) { 2571 env->spr[SPR_BESCR] |= BESCR_GE; 2572 } else { 2573 env->spr[SPR_BESCR] &= ~BESCR_GE; 2574 } 2575 } 2576 #endif 2577 2578 /*****************************************************************************/ 2579 /* Embedded PowerPC specific helpers */ 2580 void helper_40x_rfci(CPUPPCState *env) 2581 { 2582 do_rfi(env, env->spr[SPR_40x_SRR2], env->spr[SPR_40x_SRR3]); 2583 } 2584 2585 void helper_rfci(CPUPPCState *env) 2586 { 2587 do_rfi(env, env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1]); 2588 } 2589 2590 void helper_rfdi(CPUPPCState *env) 2591 { 2592 /* FIXME: choose CSRR1 or DSRR1 based on cpu type */ 2593 do_rfi(env, env->spr[SPR_BOOKE_DSRR0], env->spr[SPR_BOOKE_DSRR1]); 2594 } 2595 2596 void helper_rfmci(CPUPPCState *env) 2597 { 2598 /* FIXME: choose CSRR1 or MCSRR1 based on cpu type */ 2599 do_rfi(env, env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1]); 2600 } 2601 #endif /* CONFIG_TCG */ 2602 #endif /* !defined(CONFIG_USER_ONLY) */ 2603 2604 #ifdef CONFIG_TCG 2605 void helper_tw(CPUPPCState *env, target_ulong arg1, target_ulong arg2, 2606 uint32_t flags) 2607 { 2608 if (!likely(!(((int32_t)arg1 < (int32_t)arg2 && (flags & 0x10)) || 2609 ((int32_t)arg1 > (int32_t)arg2 && (flags & 0x08)) || 2610 ((int32_t)arg1 == (int32_t)arg2 && (flags & 0x04)) || 2611 ((uint32_t)arg1 < (uint32_t)arg2 && (flags & 0x02)) || 2612 ((uint32_t)arg1 > (uint32_t)arg2 && (flags & 0x01))))) { 2613 raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, 2614 POWERPC_EXCP_TRAP, GETPC()); 2615 } 2616 } 2617 2618 #if defined(TARGET_PPC64) 2619 void helper_td(CPUPPCState *env, target_ulong arg1, target_ulong arg2, 2620 uint32_t flags) 2621 { 2622 if (!likely(!(((int64_t)arg1 < (int64_t)arg2 && (flags & 0x10)) || 2623 ((int64_t)arg1 > (int64_t)arg2 && (flags & 0x08)) || 2624 ((int64_t)arg1 == (int64_t)arg2 && (flags & 0x04)) || 2625 ((uint64_t)arg1 < (uint64_t)arg2 && (flags & 0x02)) || 2626 ((uint64_t)arg1 > (uint64_t)arg2 && (flags & 0x01))))) { 2627 raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, 2628 POWERPC_EXCP_TRAP, GETPC()); 2629 } 2630 } 2631 #endif 2632 #endif 2633 2634 #if !defined(CONFIG_USER_ONLY) 2635 2636 #ifdef CONFIG_TCG 2637 2638 /* Embedded.Processor Control */ 2639 static int dbell2irq(target_ulong rb) 2640 { 2641 int msg = rb & DBELL_TYPE_MASK; 2642 int irq = -1; 2643 2644 switch (msg) { 2645 case DBELL_TYPE_DBELL: 2646 irq = PPC_INTERRUPT_DOORBELL; 2647 break; 2648 case DBELL_TYPE_DBELL_CRIT: 2649 irq = PPC_INTERRUPT_CDOORBELL; 2650 break; 2651 case DBELL_TYPE_G_DBELL: 2652 case DBELL_TYPE_G_DBELL_CRIT: 2653 case DBELL_TYPE_G_DBELL_MC: 2654 /* XXX implement */ 2655 default: 2656 break; 2657 } 2658 2659 return irq; 2660 } 2661 2662 void helper_msgclr(CPUPPCState *env, target_ulong rb) 2663 { 2664 int irq = dbell2irq(rb); 2665 2666 if (irq < 0) { 2667 return; 2668 } 2669 2670 env->pending_interrupts &= ~(1 << irq); 2671 } 2672 2673 void helper_msgsnd(target_ulong rb) 2674 { 2675 int irq = dbell2irq(rb); 2676 int pir = rb & DBELL_PIRTAG_MASK; 2677 CPUState *cs; 2678 2679 if (irq < 0) { 2680 return; 2681 } 2682 2683 qemu_mutex_lock_iothread(); 2684 CPU_FOREACH(cs) { 2685 PowerPCCPU *cpu = POWERPC_CPU(cs); 2686 CPUPPCState *cenv = &cpu->env; 2687 2688 if ((rb & DBELL_BRDCAST) || (cenv->spr[SPR_BOOKE_PIR] == pir)) { 2689 cenv->pending_interrupts |= 1 << irq; 2690 cpu_interrupt(cs, CPU_INTERRUPT_HARD); 2691 } 2692 } 2693 qemu_mutex_unlock_iothread(); 2694 } 2695 2696 /* Server Processor Control */ 2697 2698 static bool dbell_type_server(target_ulong rb) 2699 { 2700 /* 2701 * A Directed Hypervisor Doorbell message is sent only if the 2702 * message type is 5. All other types are reserved and the 2703 * instruction is a no-op 2704 */ 2705 return (rb & DBELL_TYPE_MASK) == DBELL_TYPE_DBELL_SERVER; 2706 } 2707 2708 void helper_book3s_msgclr(CPUPPCState *env, target_ulong rb) 2709 { 2710 if (!dbell_type_server(rb)) { 2711 return; 2712 } 2713 2714 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDOORBELL); 2715 } 2716 2717 static void book3s_msgsnd_common(int pir, int irq) 2718 { 2719 CPUState *cs; 2720 2721 qemu_mutex_lock_iothread(); 2722 CPU_FOREACH(cs) { 2723 PowerPCCPU *cpu = POWERPC_CPU(cs); 2724 CPUPPCState *cenv = &cpu->env; 2725 2726 /* TODO: broadcast message to all threads of the same processor */ 2727 if (cenv->spr_cb[SPR_PIR].default_value == pir) { 2728 cenv->pending_interrupts |= 1 << irq; 2729 cpu_interrupt(cs, CPU_INTERRUPT_HARD); 2730 } 2731 } 2732 qemu_mutex_unlock_iothread(); 2733 } 2734 2735 void helper_book3s_msgsnd(target_ulong rb) 2736 { 2737 int pir = rb & DBELL_PROCIDTAG_MASK; 2738 2739 if (!dbell_type_server(rb)) { 2740 return; 2741 } 2742 2743 book3s_msgsnd_common(pir, PPC_INTERRUPT_HDOORBELL); 2744 } 2745 2746 #if defined(TARGET_PPC64) 2747 void helper_book3s_msgclrp(CPUPPCState *env, target_ulong rb) 2748 { 2749 helper_hfscr_facility_check(env, HFSCR_MSGP, "msgclrp", HFSCR_IC_MSGP); 2750 2751 if (!dbell_type_server(rb)) { 2752 return; 2753 } 2754 2755 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL); 2756 } 2757 2758 /* 2759 * sends a message to other threads that are on the same 2760 * multi-threaded processor 2761 */ 2762 void helper_book3s_msgsndp(CPUPPCState *env, target_ulong rb) 2763 { 2764 int pir = env->spr_cb[SPR_PIR].default_value; 2765 2766 helper_hfscr_facility_check(env, HFSCR_MSGP, "msgsndp", HFSCR_IC_MSGP); 2767 2768 if (!dbell_type_server(rb)) { 2769 return; 2770 } 2771 2772 /* TODO: TCG supports only one thread */ 2773 2774 book3s_msgsnd_common(pir, PPC_INTERRUPT_DOORBELL); 2775 } 2776 #endif /* TARGET_PPC64 */ 2777 2778 void ppc_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr, 2779 MMUAccessType access_type, 2780 int mmu_idx, uintptr_t retaddr) 2781 { 2782 CPUPPCState *env = cs->env_ptr; 2783 uint32_t insn; 2784 2785 /* Restore state and reload the insn we executed, for filling in DSISR. */ 2786 cpu_restore_state(cs, retaddr, true); 2787 insn = cpu_ldl_code(env, env->nip); 2788 2789 switch (env->mmu_model) { 2790 case POWERPC_MMU_SOFT_4xx: 2791 env->spr[SPR_40x_DEAR] = vaddr; 2792 break; 2793 case POWERPC_MMU_BOOKE: 2794 case POWERPC_MMU_BOOKE206: 2795 env->spr[SPR_BOOKE_DEAR] = vaddr; 2796 break; 2797 default: 2798 env->spr[SPR_DAR] = vaddr; 2799 break; 2800 } 2801 2802 cs->exception_index = POWERPC_EXCP_ALIGN; 2803 env->error_code = insn & 0x03FF0000; 2804 cpu_loop_exit(cs); 2805 } 2806 #endif /* CONFIG_TCG */ 2807 #endif /* !CONFIG_USER_ONLY */ 2808