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 { 819 bool lpes0; 820 821 cs = CPU(cpu); 822 823 /* 824 * Exception targeting modifiers 825 * 826 * LPES0 is supported on POWER7/8/9 827 * LPES1 is not supported (old iSeries mode) 828 * 829 * On anything else, we behave as if LPES0 is 1 830 * (externals don't alter MSR:HV) 831 */ 832 #if defined(TARGET_PPC64) 833 if (excp_model == POWERPC_EXCP_POWER7 || 834 excp_model == POWERPC_EXCP_POWER8 || 835 excp_model == POWERPC_EXCP_POWER9 || 836 excp_model == POWERPC_EXCP_POWER10) { 837 lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0); 838 } else 839 #endif /* defined(TARGET_PPC64) */ 840 { 841 lpes0 = true; 842 } 843 844 if (!lpes0) { 845 new_msr |= (target_ulong)MSR_HVB; 846 new_msr |= env->msr & ((target_ulong)1 << MSR_RI); 847 srr0 = SPR_HSRR0; 848 srr1 = SPR_HSRR1; 849 } 850 if (env->mpic_proxy) { 851 /* IACK the IRQ on delivery */ 852 env->spr[SPR_BOOKE_EPR] = ldl_phys(cs->as, env->mpic_iack); 853 } 854 break; 855 } 856 case POWERPC_EXCP_ALIGN: /* Alignment exception */ 857 /* Get rS/rD and rA from faulting opcode */ 858 /* 859 * Note: the opcode fields will not be set properly for a 860 * direct store load/store, but nobody cares as nobody 861 * actually uses direct store segments. 862 */ 863 env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16; 864 break; 865 case POWERPC_EXCP_PROGRAM: /* Program exception */ 866 switch (env->error_code & ~0xF) { 867 case POWERPC_EXCP_FP: 868 if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) { 869 trace_ppc_excp_fp_ignore(); 870 cs->exception_index = POWERPC_EXCP_NONE; 871 env->error_code = 0; 872 return; 873 } 874 875 /* 876 * FP exceptions always have NIP pointing to the faulting 877 * instruction, so always use store_next and claim we are 878 * precise in the MSR. 879 */ 880 msr |= 0x00100000; 881 env->spr[SPR_BOOKE_ESR] = ESR_FP; 882 break; 883 case POWERPC_EXCP_INVAL: 884 trace_ppc_excp_inval(env->nip); 885 msr |= 0x00080000; 886 env->spr[SPR_BOOKE_ESR] = ESR_PIL; 887 break; 888 case POWERPC_EXCP_PRIV: 889 msr |= 0x00040000; 890 env->spr[SPR_BOOKE_ESR] = ESR_PPR; 891 break; 892 case POWERPC_EXCP_TRAP: 893 msr |= 0x00020000; 894 env->spr[SPR_BOOKE_ESR] = ESR_PTR; 895 break; 896 default: 897 /* Should never occur */ 898 cpu_abort(cs, "Invalid program exception %d. Aborting\n", 899 env->error_code); 900 break; 901 } 902 break; 903 case POWERPC_EXCP_SYSCALL: /* System call exception */ 904 lev = env->error_code; 905 906 if ((lev == 1) && cpu->vhyp) { 907 dump_hcall(env); 908 } else { 909 dump_syscall(env); 910 } 911 912 /* 913 * We need to correct the NIP which in this case is supposed 914 * to point to the next instruction 915 */ 916 env->nip += 4; 917 918 /* "PAPR mode" built-in hypercall emulation */ 919 if ((lev == 1) && cpu->vhyp) { 920 PPCVirtualHypervisorClass *vhc = 921 PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp); 922 vhc->hypercall(cpu->vhyp, cpu); 923 return; 924 } 925 if (lev == 1) { 926 new_msr |= (target_ulong)MSR_HVB; 927 } 928 break; 929 case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */ 930 case POWERPC_EXCP_DECR: /* Decrementer exception */ 931 break; 932 case POWERPC_EXCP_RESET: /* System reset exception */ 933 /* A power-saving exception sets ME, otherwise it is unchanged */ 934 if (msr_pow) { 935 /* indicate that we resumed from power save mode */ 936 msr |= 0x10000; 937 new_msr |= ((target_ulong)1 << MSR_ME); 938 } 939 if (env->msr_mask & MSR_HVB) { 940 /* 941 * ISA specifies HV, but can be delivered to guest with HV 942 * clear (e.g., see FWNMI in PAPR, NMI injection in QEMU). 943 */ 944 new_msr |= (target_ulong)MSR_HVB; 945 } else { 946 if (msr_pow) { 947 cpu_abort(cs, "Trying to deliver power-saving system reset " 948 "exception %d with no HV support\n", excp); 949 } 950 } 951 break; 952 case POWERPC_EXCP_TRACE: /* Trace exception */ 953 break; 954 case POWERPC_EXCP_IFTLB: /* Instruction fetch TLB error */ 955 case POWERPC_EXCP_DLTLB: /* Data load TLB miss */ 956 case POWERPC_EXCP_DSTLB: /* Data store TLB miss */ 957 switch (excp_model) { 958 case POWERPC_EXCP_6xx: 959 /* Swap temporary saved registers with GPRs */ 960 if (!(new_msr & ((target_ulong)1 << MSR_TGPR))) { 961 new_msr |= (target_ulong)1 << MSR_TGPR; 962 hreg_swap_gpr_tgpr(env); 963 } 964 /* fall through */ 965 case POWERPC_EXCP_7xx: 966 ppc_excp_debug_sw_tlb(env, excp); 967 968 msr |= env->crf[0] << 28; 969 msr |= env->error_code; /* key, D/I, S/L bits */ 970 /* Set way using a LRU mechanism */ 971 msr |= ((env->last_way + 1) & (env->nb_ways - 1)) << 17; 972 break; 973 default: 974 cpu_abort(cs, "Invalid TLB miss exception\n"); 975 break; 976 } 977 break; 978 case POWERPC_EXCP_IABR: /* Instruction address breakpoint */ 979 case POWERPC_EXCP_SMI: /* System management interrupt */ 980 case POWERPC_EXCP_THERM: /* Thermal interrupt */ 981 case POWERPC_EXCP_PERFM: /* Embedded performance monitor interrupt */ 982 cpu_abort(cs, "%s exception not implemented\n", 983 powerpc_excp_name(excp)); 984 break; 985 default: 986 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); 987 break; 988 } 989 990 /* Sanity check */ 991 if (!(env->msr_mask & MSR_HVB)) { 992 if (new_msr & MSR_HVB) { 993 cpu_abort(cs, "Trying to deliver HV exception (MSR) %d with " 994 "no HV support\n", excp); 995 } 996 if (srr0 == SPR_HSRR0) { 997 cpu_abort(cs, "Trying to deliver HV exception (HSRR) %d with " 998 "no HV support\n", excp); 999 } 1000 } 1001 1002 /* 1003 * Sort out endianness of interrupt, this differs depending on the 1004 * CPU, the HV mode, etc... 1005 */ 1006 if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) { 1007 new_msr |= (target_ulong)1 << MSR_LE; 1008 } 1009 1010 /* Save PC */ 1011 env->spr[srr0] = env->nip; 1012 1013 /* Save MSR */ 1014 env->spr[srr1] = msr; 1015 1016 powerpc_set_excp_state(cpu, vector, new_msr); 1017 } 1018 1019 static void powerpc_excp_74xx(PowerPCCPU *cpu, int excp) 1020 { 1021 CPUState *cs = CPU(cpu); 1022 CPUPPCState *env = &cpu->env; 1023 target_ulong msr, new_msr, vector; 1024 1025 if (excp <= POWERPC_EXCP_NONE || excp >= POWERPC_EXCP_NB) { 1026 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); 1027 } 1028 1029 qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx 1030 " => %s (%d) error=%02x\n", env->nip, powerpc_excp_name(excp), 1031 excp, env->error_code); 1032 1033 /* new srr1 value excluding must-be-zero bits */ 1034 msr = env->msr & ~0x783f0000ULL; 1035 1036 /* 1037 * new interrupt handler msr preserves existing ME unless 1038 * explicitly overriden 1039 */ 1040 new_msr = env->msr & ((target_ulong)1 << MSR_ME); 1041 1042 /* 1043 * Hypervisor emulation assistance interrupt only exists on server 1044 * arch 2.05 server or later. 1045 */ 1046 if (excp == POWERPC_EXCP_HV_EMU) { 1047 excp = POWERPC_EXCP_PROGRAM; 1048 } 1049 1050 vector = env->excp_vectors[excp]; 1051 if (vector == (target_ulong)-1ULL) { 1052 cpu_abort(cs, "Raised an exception without defined vector %d\n", 1053 excp); 1054 } 1055 1056 vector |= env->excp_prefix; 1057 1058 switch (excp) { 1059 case POWERPC_EXCP_MCHECK: /* Machine check exception */ 1060 if (msr_me == 0) { 1061 /* 1062 * Machine check exception is not enabled. Enter 1063 * checkstop state. 1064 */ 1065 fprintf(stderr, "Machine check while not allowed. " 1066 "Entering checkstop state\n"); 1067 if (qemu_log_separate()) { 1068 qemu_log("Machine check while not allowed. " 1069 "Entering checkstop state\n"); 1070 } 1071 cs->halted = 1; 1072 cpu_interrupt_exittb(cs); 1073 } 1074 1075 /* machine check exceptions don't have ME set */ 1076 new_msr &= ~((target_ulong)1 << MSR_ME); 1077 1078 break; 1079 case POWERPC_EXCP_DSI: /* Data storage exception */ 1080 trace_ppc_excp_dsi(env->spr[SPR_DSISR], env->spr[SPR_DAR]); 1081 break; 1082 case POWERPC_EXCP_ISI: /* Instruction storage exception */ 1083 trace_ppc_excp_isi(msr, env->nip); 1084 msr |= env->error_code; 1085 break; 1086 case POWERPC_EXCP_EXTERNAL: /* External input */ 1087 break; 1088 case POWERPC_EXCP_ALIGN: /* Alignment exception */ 1089 /* Get rS/rD and rA from faulting opcode */ 1090 /* 1091 * Note: the opcode fields will not be set properly for a 1092 * direct store load/store, but nobody cares as nobody 1093 * actually uses direct store segments. 1094 */ 1095 env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16; 1096 break; 1097 case POWERPC_EXCP_PROGRAM: /* Program exception */ 1098 switch (env->error_code & ~0xF) { 1099 case POWERPC_EXCP_FP: 1100 if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) { 1101 trace_ppc_excp_fp_ignore(); 1102 cs->exception_index = POWERPC_EXCP_NONE; 1103 env->error_code = 0; 1104 return; 1105 } 1106 1107 /* 1108 * FP exceptions always have NIP pointing to the faulting 1109 * instruction, so always use store_next and claim we are 1110 * precise in the MSR. 1111 */ 1112 msr |= 0x00100000; 1113 break; 1114 case POWERPC_EXCP_INVAL: 1115 trace_ppc_excp_inval(env->nip); 1116 msr |= 0x00080000; 1117 break; 1118 case POWERPC_EXCP_PRIV: 1119 msr |= 0x00040000; 1120 break; 1121 case POWERPC_EXCP_TRAP: 1122 msr |= 0x00020000; 1123 break; 1124 default: 1125 /* Should never occur */ 1126 cpu_abort(cs, "Invalid program exception %d. Aborting\n", 1127 env->error_code); 1128 break; 1129 } 1130 break; 1131 case POWERPC_EXCP_SYSCALL: /* System call exception */ 1132 { 1133 int lev = env->error_code; 1134 1135 if ((lev == 1) && cpu->vhyp) { 1136 dump_hcall(env); 1137 } else { 1138 dump_syscall(env); 1139 } 1140 1141 /* 1142 * We need to correct the NIP which in this case is supposed 1143 * to point to the next instruction 1144 */ 1145 env->nip += 4; 1146 1147 /* 1148 * The Virtual Open Firmware (VOF) relies on the 'sc 1' 1149 * instruction to communicate with QEMU. The pegasos2 machine 1150 * uses VOF and the 74xx CPUs, so although the 74xx don't have 1151 * HV mode, we need to keep hypercall support. 1152 */ 1153 if ((lev == 1) && cpu->vhyp) { 1154 PPCVirtualHypervisorClass *vhc = 1155 PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp); 1156 vhc->hypercall(cpu->vhyp, cpu); 1157 return; 1158 } 1159 1160 break; 1161 } 1162 case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */ 1163 case POWERPC_EXCP_DECR: /* Decrementer exception */ 1164 break; 1165 case POWERPC_EXCP_RESET: /* System reset exception */ 1166 if (msr_pow) { 1167 cpu_abort(cs, "Trying to deliver power-saving system reset " 1168 "exception %d with no HV support\n", excp); 1169 } 1170 break; 1171 case POWERPC_EXCP_TRACE: /* Trace exception */ 1172 break; 1173 case POWERPC_EXCP_VPU: /* Vector unavailable exception */ 1174 break; 1175 case POWERPC_EXCP_IABR: /* Instruction address breakpoint */ 1176 case POWERPC_EXCP_SMI: /* System management interrupt */ 1177 case POWERPC_EXCP_THERM: /* Thermal interrupt */ 1178 case POWERPC_EXCP_PERFM: /* Embedded performance monitor interrupt */ 1179 case POWERPC_EXCP_VPUA: /* Vector assist exception */ 1180 cpu_abort(cs, "%s exception not implemented\n", 1181 powerpc_excp_name(excp)); 1182 break; 1183 default: 1184 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); 1185 break; 1186 } 1187 1188 /* Sanity check */ 1189 if (!(env->msr_mask & MSR_HVB)) { 1190 if (new_msr & MSR_HVB) { 1191 cpu_abort(cs, "Trying to deliver HV exception (MSR) %d with " 1192 "no HV support\n", excp); 1193 } 1194 } 1195 1196 /* 1197 * Sort out endianness of interrupt, this differs depending on the 1198 * CPU, the HV mode, etc... 1199 */ 1200 if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) { 1201 new_msr |= (target_ulong)1 << MSR_LE; 1202 } 1203 1204 /* Save PC */ 1205 env->spr[SPR_SRR0] = env->nip; 1206 1207 /* Save MSR */ 1208 env->spr[SPR_SRR1] = msr; 1209 1210 powerpc_set_excp_state(cpu, vector, new_msr); 1211 } 1212 1213 static void powerpc_excp_booke(PowerPCCPU *cpu, int excp) 1214 { 1215 CPUState *cs = CPU(cpu); 1216 CPUPPCState *env = &cpu->env; 1217 target_ulong msr, new_msr, vector; 1218 int srr0, srr1; 1219 1220 if (excp <= POWERPC_EXCP_NONE || excp >= POWERPC_EXCP_NB) { 1221 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); 1222 } 1223 1224 qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx 1225 " => %s (%d) error=%02x\n", env->nip, powerpc_excp_name(excp), 1226 excp, env->error_code); 1227 1228 msr = env->msr; 1229 1230 /* 1231 * new interrupt handler msr preserves existing ME unless 1232 * explicitly overriden 1233 */ 1234 new_msr = env->msr & ((target_ulong)1 << MSR_ME); 1235 1236 /* target registers */ 1237 srr0 = SPR_SRR0; 1238 srr1 = SPR_SRR1; 1239 1240 /* 1241 * Hypervisor emulation assistance interrupt only exists on server 1242 * arch 2.05 server or later. 1243 */ 1244 if (excp == POWERPC_EXCP_HV_EMU) { 1245 excp = POWERPC_EXCP_PROGRAM; 1246 } 1247 1248 #ifdef TARGET_PPC64 1249 /* 1250 * SPEU and VPU share the same IVOR but they exist in different 1251 * processors. SPEU is e500v1/2 only and VPU is e6500 only. 1252 */ 1253 if (excp == POWERPC_EXCP_VPU) { 1254 excp = POWERPC_EXCP_SPEU; 1255 } 1256 #endif 1257 1258 vector = env->excp_vectors[excp]; 1259 if (vector == (target_ulong)-1ULL) { 1260 cpu_abort(cs, "Raised an exception without defined vector %d\n", 1261 excp); 1262 } 1263 1264 vector |= env->excp_prefix; 1265 1266 switch (excp) { 1267 case POWERPC_EXCP_CRITICAL: /* Critical input */ 1268 srr0 = SPR_BOOKE_CSRR0; 1269 srr1 = SPR_BOOKE_CSRR1; 1270 break; 1271 case POWERPC_EXCP_MCHECK: /* Machine check exception */ 1272 if (msr_me == 0) { 1273 /* 1274 * Machine check exception is not enabled. Enter 1275 * checkstop state. 1276 */ 1277 fprintf(stderr, "Machine check while not allowed. " 1278 "Entering checkstop state\n"); 1279 if (qemu_log_separate()) { 1280 qemu_log("Machine check while not allowed. " 1281 "Entering checkstop state\n"); 1282 } 1283 cs->halted = 1; 1284 cpu_interrupt_exittb(cs); 1285 } 1286 1287 /* machine check exceptions don't have ME set */ 1288 new_msr &= ~((target_ulong)1 << MSR_ME); 1289 1290 /* FIXME: choose one or the other based on CPU type */ 1291 srr0 = SPR_BOOKE_MCSRR0; 1292 srr1 = SPR_BOOKE_MCSRR1; 1293 1294 env->spr[SPR_BOOKE_CSRR0] = env->nip; 1295 env->spr[SPR_BOOKE_CSRR1] = msr; 1296 1297 break; 1298 case POWERPC_EXCP_DSI: /* Data storage exception */ 1299 trace_ppc_excp_dsi(env->spr[SPR_BOOKE_ESR], env->spr[SPR_BOOKE_DEAR]); 1300 break; 1301 case POWERPC_EXCP_ISI: /* Instruction storage exception */ 1302 trace_ppc_excp_isi(msr, env->nip); 1303 break; 1304 case POWERPC_EXCP_EXTERNAL: /* External input */ 1305 if (env->mpic_proxy) { 1306 /* IACK the IRQ on delivery */ 1307 env->spr[SPR_BOOKE_EPR] = ldl_phys(cs->as, env->mpic_iack); 1308 } 1309 break; 1310 case POWERPC_EXCP_ALIGN: /* Alignment exception */ 1311 break; 1312 case POWERPC_EXCP_PROGRAM: /* Program exception */ 1313 switch (env->error_code & ~0xF) { 1314 case POWERPC_EXCP_FP: 1315 if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) { 1316 trace_ppc_excp_fp_ignore(); 1317 cs->exception_index = POWERPC_EXCP_NONE; 1318 env->error_code = 0; 1319 return; 1320 } 1321 1322 /* 1323 * FP exceptions always have NIP pointing to the faulting 1324 * instruction, so always use store_next and claim we are 1325 * precise in the MSR. 1326 */ 1327 msr |= 0x00100000; 1328 env->spr[SPR_BOOKE_ESR] = ESR_FP; 1329 break; 1330 case POWERPC_EXCP_INVAL: 1331 trace_ppc_excp_inval(env->nip); 1332 msr |= 0x00080000; 1333 env->spr[SPR_BOOKE_ESR] = ESR_PIL; 1334 break; 1335 case POWERPC_EXCP_PRIV: 1336 msr |= 0x00040000; 1337 env->spr[SPR_BOOKE_ESR] = ESR_PPR; 1338 break; 1339 case POWERPC_EXCP_TRAP: 1340 msr |= 0x00020000; 1341 env->spr[SPR_BOOKE_ESR] = ESR_PTR; 1342 break; 1343 default: 1344 /* Should never occur */ 1345 cpu_abort(cs, "Invalid program exception %d. Aborting\n", 1346 env->error_code); 1347 break; 1348 } 1349 break; 1350 case POWERPC_EXCP_SYSCALL: /* System call exception */ 1351 dump_syscall(env); 1352 1353 /* 1354 * We need to correct the NIP which in this case is supposed 1355 * to point to the next instruction 1356 */ 1357 env->nip += 4; 1358 break; 1359 case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */ 1360 case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */ 1361 case POWERPC_EXCP_DECR: /* Decrementer exception */ 1362 break; 1363 case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt */ 1364 /* FIT on 4xx */ 1365 trace_ppc_excp_print("FIT"); 1366 break; 1367 case POWERPC_EXCP_WDT: /* Watchdog timer interrupt */ 1368 trace_ppc_excp_print("WDT"); 1369 srr0 = SPR_BOOKE_CSRR0; 1370 srr1 = SPR_BOOKE_CSRR1; 1371 break; 1372 case POWERPC_EXCP_DTLB: /* Data TLB error */ 1373 case POWERPC_EXCP_ITLB: /* Instruction TLB error */ 1374 break; 1375 case POWERPC_EXCP_DEBUG: /* Debug interrupt */ 1376 if (env->flags & POWERPC_FLAG_DE) { 1377 /* FIXME: choose one or the other based on CPU type */ 1378 srr0 = SPR_BOOKE_DSRR0; 1379 srr1 = SPR_BOOKE_DSRR1; 1380 1381 env->spr[SPR_BOOKE_CSRR0] = env->nip; 1382 env->spr[SPR_BOOKE_CSRR1] = msr; 1383 1384 /* DBSR already modified by caller */ 1385 } else { 1386 cpu_abort(cs, "Debug exception triggered on unsupported model\n"); 1387 } 1388 break; 1389 case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavailable/VPU */ 1390 env->spr[SPR_BOOKE_ESR] = ESR_SPV; 1391 break; 1392 case POWERPC_EXCP_RESET: /* System reset exception */ 1393 if (msr_pow) { 1394 cpu_abort(cs, "Trying to deliver power-saving system reset " 1395 "exception %d with no HV support\n", excp); 1396 } 1397 break; 1398 case POWERPC_EXCP_EFPDI: /* Embedded floating-point data interrupt */ 1399 case POWERPC_EXCP_EFPRI: /* Embedded floating-point round interrupt */ 1400 cpu_abort(cs, "%s exception not implemented\n", 1401 powerpc_excp_name(excp)); 1402 break; 1403 default: 1404 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); 1405 break; 1406 } 1407 1408 /* Sanity check */ 1409 if (!(env->msr_mask & MSR_HVB)) { 1410 if (new_msr & MSR_HVB) { 1411 cpu_abort(cs, "Trying to deliver HV exception (MSR) %d with " 1412 "no HV support\n", excp); 1413 } 1414 if (srr0 == SPR_HSRR0) { 1415 cpu_abort(cs, "Trying to deliver HV exception (HSRR) %d with " 1416 "no HV support\n", excp); 1417 } 1418 } 1419 1420 #if defined(TARGET_PPC64) 1421 if (env->spr[SPR_BOOKE_EPCR] & EPCR_ICM) { 1422 /* Cat.64-bit: EPCR.ICM is copied to MSR.CM */ 1423 new_msr |= (target_ulong)1 << MSR_CM; 1424 } else { 1425 vector = (uint32_t)vector; 1426 } 1427 #endif 1428 1429 /* Save PC */ 1430 env->spr[srr0] = env->nip; 1431 1432 /* Save MSR */ 1433 env->spr[srr1] = msr; 1434 1435 powerpc_set_excp_state(cpu, vector, new_msr); 1436 } 1437 1438 #ifdef TARGET_PPC64 1439 static void powerpc_excp_books(PowerPCCPU *cpu, int excp) 1440 { 1441 CPUState *cs = CPU(cpu); 1442 CPUPPCState *env = &cpu->env; 1443 int excp_model = env->excp_model; 1444 target_ulong msr, new_msr, vector; 1445 int srr0, srr1, lev = -1; 1446 1447 if (excp <= POWERPC_EXCP_NONE || excp >= POWERPC_EXCP_NB) { 1448 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); 1449 } 1450 1451 qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx 1452 " => %s (%d) error=%02x\n", env->nip, powerpc_excp_name(excp), 1453 excp, env->error_code); 1454 1455 /* new srr1 value excluding must-be-zero bits */ 1456 msr = env->msr & ~0x783f0000ULL; 1457 1458 /* 1459 * new interrupt handler msr preserves existing HV and ME unless 1460 * explicitly overriden 1461 */ 1462 new_msr = env->msr & (((target_ulong)1 << MSR_ME) | MSR_HVB); 1463 1464 /* target registers */ 1465 srr0 = SPR_SRR0; 1466 srr1 = SPR_SRR1; 1467 1468 /* 1469 * check for special resume at 0x100 from doze/nap/sleep/winkle on 1470 * P7/P8/P9 1471 */ 1472 if (env->resume_as_sreset) { 1473 excp = powerpc_reset_wakeup(cs, env, excp, &msr); 1474 } 1475 1476 /* 1477 * We don't want to generate a Hypervisor Emulation Assistance 1478 * Interrupt if we don't have HVB in msr_mask (PAPR mode). 1479 */ 1480 if (excp == POWERPC_EXCP_HV_EMU && !(env->msr_mask & MSR_HVB)) { 1481 excp = POWERPC_EXCP_PROGRAM; 1482 } 1483 1484 vector = env->excp_vectors[excp]; 1485 if (vector == (target_ulong)-1ULL) { 1486 cpu_abort(cs, "Raised an exception without defined vector %d\n", 1487 excp); 1488 } 1489 1490 vector |= env->excp_prefix; 1491 1492 switch (excp) { 1493 case POWERPC_EXCP_MCHECK: /* Machine check exception */ 1494 if (msr_me == 0) { 1495 /* 1496 * Machine check exception is not enabled. Enter 1497 * checkstop state. 1498 */ 1499 fprintf(stderr, "Machine check while not allowed. " 1500 "Entering checkstop state\n"); 1501 if (qemu_log_separate()) { 1502 qemu_log("Machine check while not allowed. " 1503 "Entering checkstop state\n"); 1504 } 1505 cs->halted = 1; 1506 cpu_interrupt_exittb(cs); 1507 } 1508 if (env->msr_mask & MSR_HVB) { 1509 /* 1510 * ISA specifies HV, but can be delivered to guest with HV 1511 * clear (e.g., see FWNMI in PAPR). 1512 */ 1513 new_msr |= (target_ulong)MSR_HVB; 1514 } 1515 1516 /* machine check exceptions don't have ME set */ 1517 new_msr &= ~((target_ulong)1 << MSR_ME); 1518 1519 break; 1520 case POWERPC_EXCP_DSI: /* Data storage exception */ 1521 trace_ppc_excp_dsi(env->spr[SPR_DSISR], env->spr[SPR_DAR]); 1522 break; 1523 case POWERPC_EXCP_ISI: /* Instruction storage exception */ 1524 trace_ppc_excp_isi(msr, env->nip); 1525 msr |= env->error_code; 1526 break; 1527 case POWERPC_EXCP_EXTERNAL: /* External input */ 1528 { 1529 bool lpes0; 1530 1531 /* 1532 * LPES0 is only taken into consideration if we support HV 1533 * mode for this CPU. 1534 */ 1535 if (!env->has_hv_mode) { 1536 break; 1537 } 1538 1539 lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0); 1540 1541 if (!lpes0) { 1542 new_msr |= (target_ulong)MSR_HVB; 1543 new_msr |= env->msr & ((target_ulong)1 << MSR_RI); 1544 srr0 = SPR_HSRR0; 1545 srr1 = SPR_HSRR1; 1546 } 1547 1548 break; 1549 } 1550 case POWERPC_EXCP_ALIGN: /* Alignment exception */ 1551 /* Get rS/rD and rA from faulting opcode */ 1552 /* 1553 * Note: the opcode fields will not be set properly for a 1554 * direct store load/store, but nobody cares as nobody 1555 * actually uses direct store segments. 1556 */ 1557 env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16; 1558 break; 1559 case POWERPC_EXCP_PROGRAM: /* Program exception */ 1560 switch (env->error_code & ~0xF) { 1561 case POWERPC_EXCP_FP: 1562 if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) { 1563 trace_ppc_excp_fp_ignore(); 1564 cs->exception_index = POWERPC_EXCP_NONE; 1565 env->error_code = 0; 1566 return; 1567 } 1568 1569 /* 1570 * FP exceptions always have NIP pointing to the faulting 1571 * instruction, so always use store_next and claim we are 1572 * precise in the MSR. 1573 */ 1574 msr |= 0x00100000; 1575 break; 1576 case POWERPC_EXCP_INVAL: 1577 trace_ppc_excp_inval(env->nip); 1578 msr |= 0x00080000; 1579 break; 1580 case POWERPC_EXCP_PRIV: 1581 msr |= 0x00040000; 1582 break; 1583 case POWERPC_EXCP_TRAP: 1584 msr |= 0x00020000; 1585 break; 1586 default: 1587 /* Should never occur */ 1588 cpu_abort(cs, "Invalid program exception %d. Aborting\n", 1589 env->error_code); 1590 break; 1591 } 1592 break; 1593 case POWERPC_EXCP_SYSCALL: /* System call exception */ 1594 lev = env->error_code; 1595 1596 if ((lev == 1) && cpu->vhyp) { 1597 dump_hcall(env); 1598 } else { 1599 dump_syscall(env); 1600 } 1601 1602 /* 1603 * We need to correct the NIP which in this case is supposed 1604 * to point to the next instruction 1605 */ 1606 env->nip += 4; 1607 1608 /* "PAPR mode" built-in hypercall emulation */ 1609 if ((lev == 1) && cpu->vhyp) { 1610 PPCVirtualHypervisorClass *vhc = 1611 PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp); 1612 vhc->hypercall(cpu->vhyp, cpu); 1613 return; 1614 } 1615 if (lev == 1) { 1616 new_msr |= (target_ulong)MSR_HVB; 1617 } 1618 break; 1619 case POWERPC_EXCP_SYSCALL_VECTORED: /* scv exception */ 1620 lev = env->error_code; 1621 dump_syscall(env); 1622 env->nip += 4; 1623 new_msr |= env->msr & ((target_ulong)1 << MSR_EE); 1624 new_msr |= env->msr & ((target_ulong)1 << MSR_RI); 1625 1626 vector += lev * 0x20; 1627 1628 env->lr = env->nip; 1629 env->ctr = msr; 1630 break; 1631 case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */ 1632 case POWERPC_EXCP_DECR: /* Decrementer exception */ 1633 break; 1634 case POWERPC_EXCP_RESET: /* System reset exception */ 1635 /* A power-saving exception sets ME, otherwise it is unchanged */ 1636 if (msr_pow) { 1637 /* indicate that we resumed from power save mode */ 1638 msr |= 0x10000; 1639 new_msr |= ((target_ulong)1 << MSR_ME); 1640 } 1641 if (env->msr_mask & MSR_HVB) { 1642 /* 1643 * ISA specifies HV, but can be delivered to guest with HV 1644 * clear (e.g., see FWNMI in PAPR, NMI injection in QEMU). 1645 */ 1646 new_msr |= (target_ulong)MSR_HVB; 1647 } else { 1648 if (msr_pow) { 1649 cpu_abort(cs, "Trying to deliver power-saving system reset " 1650 "exception %d with no HV support\n", excp); 1651 } 1652 } 1653 break; 1654 case POWERPC_EXCP_DSEG: /* Data segment exception */ 1655 case POWERPC_EXCP_ISEG: /* Instruction segment exception */ 1656 case POWERPC_EXCP_TRACE: /* Trace exception */ 1657 break; 1658 case POWERPC_EXCP_HISI: /* Hypervisor instruction storage exception */ 1659 msr |= env->error_code; 1660 /* fall through */ 1661 case POWERPC_EXCP_HDECR: /* Hypervisor decrementer exception */ 1662 case POWERPC_EXCP_HDSI: /* Hypervisor data storage exception */ 1663 case POWERPC_EXCP_SDOOR_HV: /* Hypervisor Doorbell interrupt */ 1664 case POWERPC_EXCP_HV_EMU: 1665 case POWERPC_EXCP_HVIRT: /* Hypervisor virtualization */ 1666 srr0 = SPR_HSRR0; 1667 srr1 = SPR_HSRR1; 1668 new_msr |= (target_ulong)MSR_HVB; 1669 new_msr |= env->msr & ((target_ulong)1 << MSR_RI); 1670 break; 1671 case POWERPC_EXCP_VPU: /* Vector unavailable exception */ 1672 case POWERPC_EXCP_VSXU: /* VSX unavailable exception */ 1673 case POWERPC_EXCP_FU: /* Facility unavailable exception */ 1674 env->spr[SPR_FSCR] |= ((target_ulong)env->error_code << 56); 1675 break; 1676 case POWERPC_EXCP_HV_FU: /* Hypervisor Facility Unavailable Exception */ 1677 env->spr[SPR_HFSCR] |= ((target_ulong)env->error_code << FSCR_IC_POS); 1678 srr0 = SPR_HSRR0; 1679 srr1 = SPR_HSRR1; 1680 new_msr |= (target_ulong)MSR_HVB; 1681 new_msr |= env->msr & ((target_ulong)1 << MSR_RI); 1682 break; 1683 case POWERPC_EXCP_THERM: /* Thermal interrupt */ 1684 case POWERPC_EXCP_PERFM: /* Embedded performance monitor interrupt */ 1685 case POWERPC_EXCP_VPUA: /* Vector assist exception */ 1686 case POWERPC_EXCP_MAINT: /* Maintenance exception */ 1687 case POWERPC_EXCP_SDOOR: /* Doorbell interrupt */ 1688 case POWERPC_EXCP_HV_MAINT: /* Hypervisor Maintenance exception */ 1689 cpu_abort(cs, "%s exception not implemented\n", 1690 powerpc_excp_name(excp)); 1691 break; 1692 default: 1693 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); 1694 break; 1695 } 1696 1697 /* Sanity check */ 1698 if (!(env->msr_mask & MSR_HVB)) { 1699 if (new_msr & MSR_HVB) { 1700 cpu_abort(cs, "Trying to deliver HV exception (MSR) %d with " 1701 "no HV support\n", excp); 1702 } 1703 if (srr0 == SPR_HSRR0) { 1704 cpu_abort(cs, "Trying to deliver HV exception (HSRR) %d with " 1705 "no HV support\n", excp); 1706 } 1707 } 1708 1709 /* 1710 * Sort out endianness of interrupt, this differs depending on the 1711 * CPU, the HV mode, etc... 1712 */ 1713 if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) { 1714 new_msr |= (target_ulong)1 << MSR_LE; 1715 } 1716 1717 new_msr |= (target_ulong)1 << MSR_SF; 1718 1719 if (excp != POWERPC_EXCP_SYSCALL_VECTORED) { 1720 /* Save PC */ 1721 env->spr[srr0] = env->nip; 1722 1723 /* Save MSR */ 1724 env->spr[srr1] = msr; 1725 } 1726 1727 /* This can update new_msr and vector if AIL applies */ 1728 ppc_excp_apply_ail(cpu, excp_model, excp, msr, &new_msr, &vector); 1729 1730 powerpc_set_excp_state(cpu, vector, new_msr); 1731 } 1732 #else 1733 static inline void powerpc_excp_books(PowerPCCPU *cpu, int excp) 1734 { 1735 g_assert_not_reached(); 1736 } 1737 #endif 1738 1739 /* 1740 * Note that this function should be greatly optimized when called 1741 * with a constant excp, from ppc_hw_interrupt 1742 */ 1743 static inline void powerpc_excp_legacy(PowerPCCPU *cpu, int excp) 1744 { 1745 CPUState *cs = CPU(cpu); 1746 CPUPPCState *env = &cpu->env; 1747 int excp_model = env->excp_model; 1748 target_ulong msr, new_msr, vector; 1749 int srr0, srr1, lev = -1; 1750 1751 if (excp <= POWERPC_EXCP_NONE || excp >= POWERPC_EXCP_NB) { 1752 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); 1753 } 1754 1755 qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx 1756 " => %s (%d) error=%02x\n", env->nip, powerpc_excp_name(excp), 1757 excp, env->error_code); 1758 1759 /* new srr1 value excluding must-be-zero bits */ 1760 if (excp_model == POWERPC_EXCP_BOOKE) { 1761 msr = env->msr; 1762 } else { 1763 msr = env->msr & ~0x783f0000ULL; 1764 } 1765 1766 /* 1767 * new interrupt handler msr preserves existing HV and ME unless 1768 * explicitly overriden 1769 */ 1770 new_msr = env->msr & (((target_ulong)1 << MSR_ME) | MSR_HVB); 1771 1772 /* target registers */ 1773 srr0 = SPR_SRR0; 1774 srr1 = SPR_SRR1; 1775 1776 /* 1777 * check for special resume at 0x100 from doze/nap/sleep/winkle on 1778 * P7/P8/P9 1779 */ 1780 if (env->resume_as_sreset) { 1781 excp = powerpc_reset_wakeup(cs, env, excp, &msr); 1782 } 1783 1784 /* 1785 * Hypervisor emulation assistance interrupt only exists on server 1786 * arch 2.05 server or later. We also don't want to generate it if 1787 * we don't have HVB in msr_mask (PAPR mode). 1788 */ 1789 if (excp == POWERPC_EXCP_HV_EMU 1790 #if defined(TARGET_PPC64) 1791 && !(mmu_is_64bit(env->mmu_model) && (env->msr_mask & MSR_HVB)) 1792 #endif /* defined(TARGET_PPC64) */ 1793 1794 ) { 1795 excp = POWERPC_EXCP_PROGRAM; 1796 } 1797 1798 #ifdef TARGET_PPC64 1799 /* 1800 * SPEU and VPU share the same IVOR but they exist in different 1801 * processors. SPEU is e500v1/2 only and VPU is e6500 only. 1802 */ 1803 if (excp_model == POWERPC_EXCP_BOOKE && excp == POWERPC_EXCP_VPU) { 1804 excp = POWERPC_EXCP_SPEU; 1805 } 1806 #endif 1807 1808 vector = env->excp_vectors[excp]; 1809 if (vector == (target_ulong)-1ULL) { 1810 cpu_abort(cs, "Raised an exception without defined vector %d\n", 1811 excp); 1812 } 1813 1814 vector |= env->excp_prefix; 1815 1816 switch (excp) { 1817 case POWERPC_EXCP_CRITICAL: /* Critical input */ 1818 switch (excp_model) { 1819 case POWERPC_EXCP_40x: 1820 srr0 = SPR_40x_SRR2; 1821 srr1 = SPR_40x_SRR3; 1822 break; 1823 case POWERPC_EXCP_BOOKE: 1824 srr0 = SPR_BOOKE_CSRR0; 1825 srr1 = SPR_BOOKE_CSRR1; 1826 break; 1827 case POWERPC_EXCP_6xx: 1828 break; 1829 default: 1830 goto excp_invalid; 1831 } 1832 break; 1833 case POWERPC_EXCP_MCHECK: /* Machine check exception */ 1834 if (msr_me == 0) { 1835 /* 1836 * Machine check exception is not enabled. Enter 1837 * checkstop state. 1838 */ 1839 fprintf(stderr, "Machine check while not allowed. " 1840 "Entering checkstop state\n"); 1841 if (qemu_log_separate()) { 1842 qemu_log("Machine check while not allowed. " 1843 "Entering checkstop state\n"); 1844 } 1845 cs->halted = 1; 1846 cpu_interrupt_exittb(cs); 1847 } 1848 if (env->msr_mask & MSR_HVB) { 1849 /* 1850 * ISA specifies HV, but can be delivered to guest with HV 1851 * clear (e.g., see FWNMI in PAPR). 1852 */ 1853 new_msr |= (target_ulong)MSR_HVB; 1854 } 1855 1856 /* machine check exceptions don't have ME set */ 1857 new_msr &= ~((target_ulong)1 << MSR_ME); 1858 1859 /* XXX: should also have something loaded in DAR / DSISR */ 1860 switch (excp_model) { 1861 case POWERPC_EXCP_40x: 1862 srr0 = SPR_40x_SRR2; 1863 srr1 = SPR_40x_SRR3; 1864 break; 1865 case POWERPC_EXCP_BOOKE: 1866 /* FIXME: choose one or the other based on CPU type */ 1867 srr0 = SPR_BOOKE_MCSRR0; 1868 srr1 = SPR_BOOKE_MCSRR1; 1869 1870 env->spr[SPR_BOOKE_CSRR0] = env->nip; 1871 env->spr[SPR_BOOKE_CSRR1] = msr; 1872 break; 1873 default: 1874 break; 1875 } 1876 break; 1877 case POWERPC_EXCP_DSI: /* Data storage exception */ 1878 trace_ppc_excp_dsi(env->spr[SPR_DSISR], env->spr[SPR_DAR]); 1879 break; 1880 case POWERPC_EXCP_ISI: /* Instruction storage exception */ 1881 trace_ppc_excp_isi(msr, env->nip); 1882 msr |= env->error_code; 1883 break; 1884 case POWERPC_EXCP_EXTERNAL: /* External input */ 1885 { 1886 bool lpes0; 1887 1888 cs = CPU(cpu); 1889 1890 /* 1891 * Exception targeting modifiers 1892 * 1893 * LPES0 is supported on POWER7/8/9 1894 * LPES1 is not supported (old iSeries mode) 1895 * 1896 * On anything else, we behave as if LPES0 is 1 1897 * (externals don't alter MSR:HV) 1898 */ 1899 #if defined(TARGET_PPC64) 1900 if (excp_model == POWERPC_EXCP_POWER7 || 1901 excp_model == POWERPC_EXCP_POWER8 || 1902 excp_model == POWERPC_EXCP_POWER9 || 1903 excp_model == POWERPC_EXCP_POWER10) { 1904 lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0); 1905 } else 1906 #endif /* defined(TARGET_PPC64) */ 1907 { 1908 lpes0 = true; 1909 } 1910 1911 if (!lpes0) { 1912 new_msr |= (target_ulong)MSR_HVB; 1913 new_msr |= env->msr & ((target_ulong)1 << MSR_RI); 1914 srr0 = SPR_HSRR0; 1915 srr1 = SPR_HSRR1; 1916 } 1917 if (env->mpic_proxy) { 1918 /* IACK the IRQ on delivery */ 1919 env->spr[SPR_BOOKE_EPR] = ldl_phys(cs->as, env->mpic_iack); 1920 } 1921 break; 1922 } 1923 case POWERPC_EXCP_ALIGN: /* Alignment exception */ 1924 /* Get rS/rD and rA from faulting opcode */ 1925 /* 1926 * Note: the opcode fields will not be set properly for a 1927 * direct store load/store, but nobody cares as nobody 1928 * actually uses direct store segments. 1929 */ 1930 env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16; 1931 break; 1932 case POWERPC_EXCP_PROGRAM: /* Program exception */ 1933 switch (env->error_code & ~0xF) { 1934 case POWERPC_EXCP_FP: 1935 if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) { 1936 trace_ppc_excp_fp_ignore(); 1937 cs->exception_index = POWERPC_EXCP_NONE; 1938 env->error_code = 0; 1939 return; 1940 } 1941 1942 /* 1943 * FP exceptions always have NIP pointing to the faulting 1944 * instruction, so always use store_next and claim we are 1945 * precise in the MSR. 1946 */ 1947 msr |= 0x00100000; 1948 env->spr[SPR_BOOKE_ESR] = ESR_FP; 1949 break; 1950 case POWERPC_EXCP_INVAL: 1951 trace_ppc_excp_inval(env->nip); 1952 msr |= 0x00080000; 1953 env->spr[SPR_BOOKE_ESR] = ESR_PIL; 1954 break; 1955 case POWERPC_EXCP_PRIV: 1956 msr |= 0x00040000; 1957 env->spr[SPR_BOOKE_ESR] = ESR_PPR; 1958 break; 1959 case POWERPC_EXCP_TRAP: 1960 msr |= 0x00020000; 1961 env->spr[SPR_BOOKE_ESR] = ESR_PTR; 1962 break; 1963 default: 1964 /* Should never occur */ 1965 cpu_abort(cs, "Invalid program exception %d. Aborting\n", 1966 env->error_code); 1967 break; 1968 } 1969 break; 1970 case POWERPC_EXCP_SYSCALL: /* System call exception */ 1971 lev = env->error_code; 1972 1973 if ((lev == 1) && cpu->vhyp) { 1974 dump_hcall(env); 1975 } else { 1976 dump_syscall(env); 1977 } 1978 1979 /* 1980 * We need to correct the NIP which in this case is supposed 1981 * to point to the next instruction 1982 */ 1983 env->nip += 4; 1984 1985 /* "PAPR mode" built-in hypercall emulation */ 1986 if ((lev == 1) && cpu->vhyp) { 1987 PPCVirtualHypervisorClass *vhc = 1988 PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp); 1989 vhc->hypercall(cpu->vhyp, cpu); 1990 return; 1991 } 1992 if (lev == 1) { 1993 new_msr |= (target_ulong)MSR_HVB; 1994 } 1995 break; 1996 case POWERPC_EXCP_SYSCALL_VECTORED: /* scv exception */ 1997 lev = env->error_code; 1998 dump_syscall(env); 1999 env->nip += 4; 2000 new_msr |= env->msr & ((target_ulong)1 << MSR_EE); 2001 new_msr |= env->msr & ((target_ulong)1 << MSR_RI); 2002 2003 vector += lev * 0x20; 2004 2005 env->lr = env->nip; 2006 env->ctr = msr; 2007 break; 2008 case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */ 2009 case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */ 2010 case POWERPC_EXCP_DECR: /* Decrementer exception */ 2011 break; 2012 case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt */ 2013 /* FIT on 4xx */ 2014 trace_ppc_excp_print("FIT"); 2015 break; 2016 case POWERPC_EXCP_WDT: /* Watchdog timer interrupt */ 2017 trace_ppc_excp_print("WDT"); 2018 switch (excp_model) { 2019 case POWERPC_EXCP_BOOKE: 2020 srr0 = SPR_BOOKE_CSRR0; 2021 srr1 = SPR_BOOKE_CSRR1; 2022 break; 2023 default: 2024 break; 2025 } 2026 break; 2027 case POWERPC_EXCP_DTLB: /* Data TLB error */ 2028 case POWERPC_EXCP_ITLB: /* Instruction TLB error */ 2029 break; 2030 case POWERPC_EXCP_DEBUG: /* Debug interrupt */ 2031 if (env->flags & POWERPC_FLAG_DE) { 2032 /* FIXME: choose one or the other based on CPU type */ 2033 srr0 = SPR_BOOKE_DSRR0; 2034 srr1 = SPR_BOOKE_DSRR1; 2035 2036 env->spr[SPR_BOOKE_CSRR0] = env->nip; 2037 env->spr[SPR_BOOKE_CSRR1] = msr; 2038 2039 /* DBSR already modified by caller */ 2040 } else { 2041 cpu_abort(cs, "Debug exception triggered on unsupported model\n"); 2042 } 2043 break; 2044 case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavailable/VPU */ 2045 env->spr[SPR_BOOKE_ESR] = ESR_SPV; 2046 break; 2047 case POWERPC_EXCP_DOORI: /* Embedded doorbell interrupt */ 2048 break; 2049 case POWERPC_EXCP_DOORCI: /* Embedded doorbell critical interrupt */ 2050 srr0 = SPR_BOOKE_CSRR0; 2051 srr1 = SPR_BOOKE_CSRR1; 2052 break; 2053 case POWERPC_EXCP_RESET: /* System reset exception */ 2054 /* A power-saving exception sets ME, otherwise it is unchanged */ 2055 if (msr_pow) { 2056 /* indicate that we resumed from power save mode */ 2057 msr |= 0x10000; 2058 new_msr |= ((target_ulong)1 << MSR_ME); 2059 } 2060 if (env->msr_mask & MSR_HVB) { 2061 /* 2062 * ISA specifies HV, but can be delivered to guest with HV 2063 * clear (e.g., see FWNMI in PAPR, NMI injection in QEMU). 2064 */ 2065 new_msr |= (target_ulong)MSR_HVB; 2066 } else { 2067 if (msr_pow) { 2068 cpu_abort(cs, "Trying to deliver power-saving system reset " 2069 "exception %d with no HV support\n", excp); 2070 } 2071 } 2072 break; 2073 case POWERPC_EXCP_DSEG: /* Data segment exception */ 2074 case POWERPC_EXCP_ISEG: /* Instruction segment exception */ 2075 case POWERPC_EXCP_TRACE: /* Trace exception */ 2076 break; 2077 case POWERPC_EXCP_HISI: /* Hypervisor instruction storage exception */ 2078 msr |= env->error_code; 2079 /* fall through */ 2080 case POWERPC_EXCP_HDECR: /* Hypervisor decrementer exception */ 2081 case POWERPC_EXCP_HDSI: /* Hypervisor data storage exception */ 2082 case POWERPC_EXCP_HDSEG: /* Hypervisor data segment exception */ 2083 case POWERPC_EXCP_HISEG: /* Hypervisor instruction segment exception */ 2084 case POWERPC_EXCP_SDOOR_HV: /* Hypervisor Doorbell interrupt */ 2085 case POWERPC_EXCP_HV_EMU: 2086 case POWERPC_EXCP_HVIRT: /* Hypervisor virtualization */ 2087 srr0 = SPR_HSRR0; 2088 srr1 = SPR_HSRR1; 2089 new_msr |= (target_ulong)MSR_HVB; 2090 new_msr |= env->msr & ((target_ulong)1 << MSR_RI); 2091 break; 2092 case POWERPC_EXCP_VPU: /* Vector unavailable exception */ 2093 case POWERPC_EXCP_VSXU: /* VSX unavailable exception */ 2094 case POWERPC_EXCP_FU: /* Facility unavailable exception */ 2095 #ifdef TARGET_PPC64 2096 env->spr[SPR_FSCR] |= ((target_ulong)env->error_code << 56); 2097 #endif 2098 break; 2099 case POWERPC_EXCP_HV_FU: /* Hypervisor Facility Unavailable Exception */ 2100 #ifdef TARGET_PPC64 2101 env->spr[SPR_HFSCR] |= ((target_ulong)env->error_code << FSCR_IC_POS); 2102 srr0 = SPR_HSRR0; 2103 srr1 = SPR_HSRR1; 2104 new_msr |= (target_ulong)MSR_HVB; 2105 new_msr |= env->msr & ((target_ulong)1 << MSR_RI); 2106 #endif 2107 break; 2108 case POWERPC_EXCP_PIT: /* Programmable interval timer interrupt */ 2109 trace_ppc_excp_print("PIT"); 2110 break; 2111 case POWERPC_EXCP_IFTLB: /* Instruction fetch TLB error */ 2112 case POWERPC_EXCP_DLTLB: /* Data load TLB miss */ 2113 case POWERPC_EXCP_DSTLB: /* Data store TLB miss */ 2114 switch (excp_model) { 2115 case POWERPC_EXCP_6xx: 2116 /* Swap temporary saved registers with GPRs */ 2117 if (!(new_msr & ((target_ulong)1 << MSR_TGPR))) { 2118 new_msr |= (target_ulong)1 << MSR_TGPR; 2119 hreg_swap_gpr_tgpr(env); 2120 } 2121 /* fall through */ 2122 case POWERPC_EXCP_7xx: 2123 ppc_excp_debug_sw_tlb(env, excp); 2124 2125 msr |= env->crf[0] << 28; 2126 msr |= env->error_code; /* key, D/I, S/L bits */ 2127 /* Set way using a LRU mechanism */ 2128 msr |= ((env->last_way + 1) & (env->nb_ways - 1)) << 17; 2129 break; 2130 default: 2131 cpu_abort(cs, "Invalid TLB miss exception\n"); 2132 break; 2133 } 2134 break; 2135 case POWERPC_EXCP_EFPDI: /* Embedded floating-point data interrupt */ 2136 case POWERPC_EXCP_EFPRI: /* Embedded floating-point round interrupt */ 2137 case POWERPC_EXCP_EPERFM: /* Embedded performance monitor interrupt */ 2138 case POWERPC_EXCP_FPA: /* Floating-point assist exception */ 2139 case POWERPC_EXCP_DABR: /* Data address breakpoint */ 2140 case POWERPC_EXCP_IABR: /* Instruction address breakpoint */ 2141 case POWERPC_EXCP_SMI: /* System management interrupt */ 2142 case POWERPC_EXCP_THERM: /* Thermal interrupt */ 2143 case POWERPC_EXCP_PERFM: /* Embedded performance monitor interrupt */ 2144 case POWERPC_EXCP_VPUA: /* Vector assist exception */ 2145 case POWERPC_EXCP_SOFTP: /* Soft patch exception */ 2146 case POWERPC_EXCP_MAINT: /* Maintenance exception */ 2147 case POWERPC_EXCP_MEXTBR: /* Maskable external breakpoint */ 2148 case POWERPC_EXCP_NMEXTBR: /* Non maskable external breakpoint */ 2149 cpu_abort(cs, "%s exception not implemented\n", 2150 powerpc_excp_name(excp)); 2151 break; 2152 default: 2153 excp_invalid: 2154 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); 2155 break; 2156 } 2157 2158 /* Sanity check */ 2159 if (!(env->msr_mask & MSR_HVB)) { 2160 if (new_msr & MSR_HVB) { 2161 cpu_abort(cs, "Trying to deliver HV exception (MSR) %d with " 2162 "no HV support\n", excp); 2163 } 2164 if (srr0 == SPR_HSRR0) { 2165 cpu_abort(cs, "Trying to deliver HV exception (HSRR) %d with " 2166 "no HV support\n", excp); 2167 } 2168 } 2169 2170 /* 2171 * Sort out endianness of interrupt, this differs depending on the 2172 * CPU, the HV mode, etc... 2173 */ 2174 if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) { 2175 new_msr |= (target_ulong)1 << MSR_LE; 2176 } 2177 2178 #if defined(TARGET_PPC64) 2179 if (excp_model == POWERPC_EXCP_BOOKE) { 2180 if (env->spr[SPR_BOOKE_EPCR] & EPCR_ICM) { 2181 /* Cat.64-bit: EPCR.ICM is copied to MSR.CM */ 2182 new_msr |= (target_ulong)1 << MSR_CM; 2183 } else { 2184 vector = (uint32_t)vector; 2185 } 2186 } else { 2187 if (!msr_isf && !mmu_is_64bit(env->mmu_model)) { 2188 vector = (uint32_t)vector; 2189 } else { 2190 new_msr |= (target_ulong)1 << MSR_SF; 2191 } 2192 } 2193 #endif 2194 2195 if (excp != POWERPC_EXCP_SYSCALL_VECTORED) { 2196 /* Save PC */ 2197 env->spr[srr0] = env->nip; 2198 2199 /* Save MSR */ 2200 env->spr[srr1] = msr; 2201 } 2202 2203 /* This can update new_msr and vector if AIL applies */ 2204 ppc_excp_apply_ail(cpu, excp_model, excp, msr, &new_msr, &vector); 2205 2206 powerpc_set_excp_state(cpu, vector, new_msr); 2207 } 2208 2209 static void powerpc_excp(PowerPCCPU *cpu, int excp) 2210 { 2211 CPUPPCState *env = &cpu->env; 2212 2213 switch (env->excp_model) { 2214 case POWERPC_EXCP_40x: 2215 powerpc_excp_40x(cpu, excp); 2216 break; 2217 case POWERPC_EXCP_6xx: 2218 powerpc_excp_6xx(cpu, excp); 2219 break; 2220 case POWERPC_EXCP_7xx: 2221 powerpc_excp_7xx(cpu, excp); 2222 break; 2223 case POWERPC_EXCP_74xx: 2224 powerpc_excp_74xx(cpu, excp); 2225 break; 2226 case POWERPC_EXCP_BOOKE: 2227 powerpc_excp_booke(cpu, excp); 2228 break; 2229 case POWERPC_EXCP_970: 2230 case POWERPC_EXCP_POWER7: 2231 case POWERPC_EXCP_POWER8: 2232 case POWERPC_EXCP_POWER9: 2233 case POWERPC_EXCP_POWER10: 2234 powerpc_excp_books(cpu, excp); 2235 break; 2236 default: 2237 powerpc_excp_legacy(cpu, excp); 2238 } 2239 } 2240 2241 void ppc_cpu_do_interrupt(CPUState *cs) 2242 { 2243 PowerPCCPU *cpu = POWERPC_CPU(cs); 2244 2245 powerpc_excp(cpu, cs->exception_index); 2246 } 2247 2248 static void ppc_hw_interrupt(CPUPPCState *env) 2249 { 2250 PowerPCCPU *cpu = env_archcpu(env); 2251 bool async_deliver; 2252 2253 /* External reset */ 2254 if (env->pending_interrupts & (1 << PPC_INTERRUPT_RESET)) { 2255 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_RESET); 2256 powerpc_excp(cpu, POWERPC_EXCP_RESET); 2257 return; 2258 } 2259 /* Machine check exception */ 2260 if (env->pending_interrupts & (1 << PPC_INTERRUPT_MCK)) { 2261 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_MCK); 2262 powerpc_excp(cpu, POWERPC_EXCP_MCHECK); 2263 return; 2264 } 2265 #if 0 /* TODO */ 2266 /* External debug exception */ 2267 if (env->pending_interrupts & (1 << PPC_INTERRUPT_DEBUG)) { 2268 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DEBUG); 2269 powerpc_excp(cpu, POWERPC_EXCP_DEBUG); 2270 return; 2271 } 2272 #endif 2273 2274 /* 2275 * For interrupts that gate on MSR:EE, we need to do something a 2276 * bit more subtle, as we need to let them through even when EE is 2277 * clear when coming out of some power management states (in order 2278 * for them to become a 0x100). 2279 */ 2280 async_deliver = (msr_ee != 0) || env->resume_as_sreset; 2281 2282 /* Hypervisor decrementer exception */ 2283 if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDECR)) { 2284 /* LPCR will be clear when not supported so this will work */ 2285 bool hdice = !!(env->spr[SPR_LPCR] & LPCR_HDICE); 2286 if ((async_deliver || msr_hv == 0) && hdice) { 2287 /* HDEC clears on delivery */ 2288 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDECR); 2289 powerpc_excp(cpu, POWERPC_EXCP_HDECR); 2290 return; 2291 } 2292 } 2293 2294 /* Hypervisor virtualization interrupt */ 2295 if (env->pending_interrupts & (1 << PPC_INTERRUPT_HVIRT)) { 2296 /* LPCR will be clear when not supported so this will work */ 2297 bool hvice = !!(env->spr[SPR_LPCR] & LPCR_HVICE); 2298 if ((async_deliver || msr_hv == 0) && hvice) { 2299 powerpc_excp(cpu, POWERPC_EXCP_HVIRT); 2300 return; 2301 } 2302 } 2303 2304 /* External interrupt can ignore MSR:EE under some circumstances */ 2305 if (env->pending_interrupts & (1 << PPC_INTERRUPT_EXT)) { 2306 bool lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0); 2307 bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC); 2308 /* HEIC blocks delivery to the hypervisor */ 2309 if ((async_deliver && !(heic && msr_hv && !msr_pr)) || 2310 (env->has_hv_mode && msr_hv == 0 && !lpes0)) { 2311 powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL); 2312 return; 2313 } 2314 } 2315 if (msr_ce != 0) { 2316 /* External critical interrupt */ 2317 if (env->pending_interrupts & (1 << PPC_INTERRUPT_CEXT)) { 2318 powerpc_excp(cpu, POWERPC_EXCP_CRITICAL); 2319 return; 2320 } 2321 } 2322 if (async_deliver != 0) { 2323 /* Watchdog timer on embedded PowerPC */ 2324 if (env->pending_interrupts & (1 << PPC_INTERRUPT_WDT)) { 2325 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_WDT); 2326 powerpc_excp(cpu, POWERPC_EXCP_WDT); 2327 return; 2328 } 2329 if (env->pending_interrupts & (1 << PPC_INTERRUPT_CDOORBELL)) { 2330 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_CDOORBELL); 2331 powerpc_excp(cpu, POWERPC_EXCP_DOORCI); 2332 return; 2333 } 2334 /* Fixed interval timer on embedded PowerPC */ 2335 if (env->pending_interrupts & (1 << PPC_INTERRUPT_FIT)) { 2336 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_FIT); 2337 powerpc_excp(cpu, POWERPC_EXCP_FIT); 2338 return; 2339 } 2340 /* Programmable interval timer on embedded PowerPC */ 2341 if (env->pending_interrupts & (1 << PPC_INTERRUPT_PIT)) { 2342 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PIT); 2343 powerpc_excp(cpu, POWERPC_EXCP_PIT); 2344 return; 2345 } 2346 /* Decrementer exception */ 2347 if (env->pending_interrupts & (1 << PPC_INTERRUPT_DECR)) { 2348 if (ppc_decr_clear_on_delivery(env)) { 2349 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DECR); 2350 } 2351 powerpc_excp(cpu, POWERPC_EXCP_DECR); 2352 return; 2353 } 2354 if (env->pending_interrupts & (1 << PPC_INTERRUPT_DOORBELL)) { 2355 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL); 2356 if (is_book3s_arch2x(env)) { 2357 powerpc_excp(cpu, POWERPC_EXCP_SDOOR); 2358 } else { 2359 powerpc_excp(cpu, POWERPC_EXCP_DOORI); 2360 } 2361 return; 2362 } 2363 if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDOORBELL)) { 2364 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDOORBELL); 2365 powerpc_excp(cpu, POWERPC_EXCP_SDOOR_HV); 2366 return; 2367 } 2368 if (env->pending_interrupts & (1 << PPC_INTERRUPT_PERFM)) { 2369 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PERFM); 2370 powerpc_excp(cpu, POWERPC_EXCP_PERFM); 2371 return; 2372 } 2373 /* Thermal interrupt */ 2374 if (env->pending_interrupts & (1 << PPC_INTERRUPT_THERM)) { 2375 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_THERM); 2376 powerpc_excp(cpu, POWERPC_EXCP_THERM); 2377 return; 2378 } 2379 } 2380 2381 if (env->resume_as_sreset) { 2382 /* 2383 * This is a bug ! It means that has_work took us out of halt without 2384 * anything to deliver while in a PM state that requires getting 2385 * out via a 0x100 2386 * 2387 * This means we will incorrectly execute past the power management 2388 * instruction instead of triggering a reset. 2389 * 2390 * It generally means a discrepancy between the wakeup conditions in the 2391 * processor has_work implementation and the logic in this function. 2392 */ 2393 cpu_abort(env_cpu(env), 2394 "Wakeup from PM state but interrupt Undelivered"); 2395 } 2396 } 2397 2398 void ppc_cpu_do_system_reset(CPUState *cs) 2399 { 2400 PowerPCCPU *cpu = POWERPC_CPU(cs); 2401 2402 powerpc_excp(cpu, POWERPC_EXCP_RESET); 2403 } 2404 2405 void ppc_cpu_do_fwnmi_machine_check(CPUState *cs, target_ulong vector) 2406 { 2407 PowerPCCPU *cpu = POWERPC_CPU(cs); 2408 CPUPPCState *env = &cpu->env; 2409 target_ulong msr = 0; 2410 2411 /* 2412 * Set MSR and NIP for the handler, SRR0/1, DAR and DSISR have already 2413 * been set by KVM. 2414 */ 2415 msr = (1ULL << MSR_ME); 2416 msr |= env->msr & (1ULL << MSR_SF); 2417 if (ppc_interrupts_little_endian(cpu, false)) { 2418 msr |= (1ULL << MSR_LE); 2419 } 2420 2421 powerpc_set_excp_state(cpu, vector, msr); 2422 } 2423 2424 bool ppc_cpu_exec_interrupt(CPUState *cs, int interrupt_request) 2425 { 2426 PowerPCCPU *cpu = POWERPC_CPU(cs); 2427 CPUPPCState *env = &cpu->env; 2428 2429 if (interrupt_request & CPU_INTERRUPT_HARD) { 2430 ppc_hw_interrupt(env); 2431 if (env->pending_interrupts == 0) { 2432 cs->interrupt_request &= ~CPU_INTERRUPT_HARD; 2433 } 2434 return true; 2435 } 2436 return false; 2437 } 2438 2439 #endif /* !CONFIG_USER_ONLY */ 2440 2441 /*****************************************************************************/ 2442 /* Exceptions processing helpers */ 2443 2444 void raise_exception_err_ra(CPUPPCState *env, uint32_t exception, 2445 uint32_t error_code, uintptr_t raddr) 2446 { 2447 CPUState *cs = env_cpu(env); 2448 2449 cs->exception_index = exception; 2450 env->error_code = error_code; 2451 cpu_loop_exit_restore(cs, raddr); 2452 } 2453 2454 void raise_exception_err(CPUPPCState *env, uint32_t exception, 2455 uint32_t error_code) 2456 { 2457 raise_exception_err_ra(env, exception, error_code, 0); 2458 } 2459 2460 void raise_exception(CPUPPCState *env, uint32_t exception) 2461 { 2462 raise_exception_err_ra(env, exception, 0, 0); 2463 } 2464 2465 void raise_exception_ra(CPUPPCState *env, uint32_t exception, 2466 uintptr_t raddr) 2467 { 2468 raise_exception_err_ra(env, exception, 0, raddr); 2469 } 2470 2471 #ifdef CONFIG_TCG 2472 void helper_raise_exception_err(CPUPPCState *env, uint32_t exception, 2473 uint32_t error_code) 2474 { 2475 raise_exception_err_ra(env, exception, error_code, 0); 2476 } 2477 2478 void helper_raise_exception(CPUPPCState *env, uint32_t exception) 2479 { 2480 raise_exception_err_ra(env, exception, 0, 0); 2481 } 2482 #endif 2483 2484 #if !defined(CONFIG_USER_ONLY) 2485 #ifdef CONFIG_TCG 2486 void helper_store_msr(CPUPPCState *env, target_ulong val) 2487 { 2488 uint32_t excp = hreg_store_msr(env, val, 0); 2489 2490 if (excp != 0) { 2491 CPUState *cs = env_cpu(env); 2492 cpu_interrupt_exittb(cs); 2493 raise_exception(env, excp); 2494 } 2495 } 2496 2497 #if defined(TARGET_PPC64) 2498 void helper_scv(CPUPPCState *env, uint32_t lev) 2499 { 2500 if (env->spr[SPR_FSCR] & (1ull << FSCR_SCV)) { 2501 raise_exception_err(env, POWERPC_EXCP_SYSCALL_VECTORED, lev); 2502 } else { 2503 raise_exception_err(env, POWERPC_EXCP_FU, FSCR_IC_SCV); 2504 } 2505 } 2506 2507 void helper_pminsn(CPUPPCState *env, powerpc_pm_insn_t insn) 2508 { 2509 CPUState *cs; 2510 2511 cs = env_cpu(env); 2512 cs->halted = 1; 2513 2514 /* Condition for waking up at 0x100 */ 2515 env->resume_as_sreset = (insn != PPC_PM_STOP) || 2516 (env->spr[SPR_PSSCR] & PSSCR_EC); 2517 } 2518 #endif /* defined(TARGET_PPC64) */ 2519 2520 static void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr) 2521 { 2522 CPUState *cs = env_cpu(env); 2523 2524 /* MSR:POW cannot be set by any form of rfi */ 2525 msr &= ~(1ULL << MSR_POW); 2526 2527 /* MSR:TGPR cannot be set by any form of rfi */ 2528 if (env->flags & POWERPC_FLAG_TGPR) 2529 msr &= ~(1ULL << MSR_TGPR); 2530 2531 #if defined(TARGET_PPC64) 2532 /* Switching to 32-bit ? Crop the nip */ 2533 if (!msr_is_64bit(env, msr)) { 2534 nip = (uint32_t)nip; 2535 } 2536 #else 2537 nip = (uint32_t)nip; 2538 #endif 2539 /* XXX: beware: this is false if VLE is supported */ 2540 env->nip = nip & ~((target_ulong)0x00000003); 2541 hreg_store_msr(env, msr, 1); 2542 trace_ppc_excp_rfi(env->nip, env->msr); 2543 /* 2544 * No need to raise an exception here, as rfi is always the last 2545 * insn of a TB 2546 */ 2547 cpu_interrupt_exittb(cs); 2548 /* Reset the reservation */ 2549 env->reserve_addr = -1; 2550 2551 /* Context synchronizing: check if TCG TLB needs flush */ 2552 check_tlb_flush(env, false); 2553 } 2554 2555 void helper_rfi(CPUPPCState *env) 2556 { 2557 do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1] & 0xfffffffful); 2558 } 2559 2560 #define MSR_BOOK3S_MASK 2561 #if defined(TARGET_PPC64) 2562 void helper_rfid(CPUPPCState *env) 2563 { 2564 /* 2565 * The architecture defines a number of rules for which bits can 2566 * change but in practice, we handle this in hreg_store_msr() 2567 * which will be called by do_rfi(), so there is no need to filter 2568 * here 2569 */ 2570 do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1]); 2571 } 2572 2573 void helper_rfscv(CPUPPCState *env) 2574 { 2575 do_rfi(env, env->lr, env->ctr); 2576 } 2577 2578 void helper_hrfid(CPUPPCState *env) 2579 { 2580 do_rfi(env, env->spr[SPR_HSRR0], env->spr[SPR_HSRR1]); 2581 } 2582 #endif 2583 2584 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) 2585 void helper_rfebb(CPUPPCState *env, target_ulong s) 2586 { 2587 target_ulong msr = env->msr; 2588 2589 /* 2590 * Handling of BESCR bits 32:33 according to PowerISA v3.1: 2591 * 2592 * "If BESCR 32:33 != 0b00 the instruction is treated as if 2593 * the instruction form were invalid." 2594 */ 2595 if (env->spr[SPR_BESCR] & BESCR_INVALID) { 2596 raise_exception_err(env, POWERPC_EXCP_PROGRAM, 2597 POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL); 2598 } 2599 2600 env->nip = env->spr[SPR_EBBRR]; 2601 2602 /* Switching to 32-bit ? Crop the nip */ 2603 if (!msr_is_64bit(env, msr)) { 2604 env->nip = (uint32_t)env->spr[SPR_EBBRR]; 2605 } 2606 2607 if (s) { 2608 env->spr[SPR_BESCR] |= BESCR_GE; 2609 } else { 2610 env->spr[SPR_BESCR] &= ~BESCR_GE; 2611 } 2612 } 2613 #endif 2614 2615 /*****************************************************************************/ 2616 /* Embedded PowerPC specific helpers */ 2617 void helper_40x_rfci(CPUPPCState *env) 2618 { 2619 do_rfi(env, env->spr[SPR_40x_SRR2], env->spr[SPR_40x_SRR3]); 2620 } 2621 2622 void helper_rfci(CPUPPCState *env) 2623 { 2624 do_rfi(env, env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1]); 2625 } 2626 2627 void helper_rfdi(CPUPPCState *env) 2628 { 2629 /* FIXME: choose CSRR1 or DSRR1 based on cpu type */ 2630 do_rfi(env, env->spr[SPR_BOOKE_DSRR0], env->spr[SPR_BOOKE_DSRR1]); 2631 } 2632 2633 void helper_rfmci(CPUPPCState *env) 2634 { 2635 /* FIXME: choose CSRR1 or MCSRR1 based on cpu type */ 2636 do_rfi(env, env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1]); 2637 } 2638 #endif /* CONFIG_TCG */ 2639 #endif /* !defined(CONFIG_USER_ONLY) */ 2640 2641 #ifdef CONFIG_TCG 2642 void helper_tw(CPUPPCState *env, target_ulong arg1, target_ulong arg2, 2643 uint32_t flags) 2644 { 2645 if (!likely(!(((int32_t)arg1 < (int32_t)arg2 && (flags & 0x10)) || 2646 ((int32_t)arg1 > (int32_t)arg2 && (flags & 0x08)) || 2647 ((int32_t)arg1 == (int32_t)arg2 && (flags & 0x04)) || 2648 ((uint32_t)arg1 < (uint32_t)arg2 && (flags & 0x02)) || 2649 ((uint32_t)arg1 > (uint32_t)arg2 && (flags & 0x01))))) { 2650 raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, 2651 POWERPC_EXCP_TRAP, GETPC()); 2652 } 2653 } 2654 2655 #if defined(TARGET_PPC64) 2656 void helper_td(CPUPPCState *env, target_ulong arg1, target_ulong arg2, 2657 uint32_t flags) 2658 { 2659 if (!likely(!(((int64_t)arg1 < (int64_t)arg2 && (flags & 0x10)) || 2660 ((int64_t)arg1 > (int64_t)arg2 && (flags & 0x08)) || 2661 ((int64_t)arg1 == (int64_t)arg2 && (flags & 0x04)) || 2662 ((uint64_t)arg1 < (uint64_t)arg2 && (flags & 0x02)) || 2663 ((uint64_t)arg1 > (uint64_t)arg2 && (flags & 0x01))))) { 2664 raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, 2665 POWERPC_EXCP_TRAP, GETPC()); 2666 } 2667 } 2668 #endif 2669 #endif 2670 2671 #if !defined(CONFIG_USER_ONLY) 2672 2673 #ifdef CONFIG_TCG 2674 2675 /* Embedded.Processor Control */ 2676 static int dbell2irq(target_ulong rb) 2677 { 2678 int msg = rb & DBELL_TYPE_MASK; 2679 int irq = -1; 2680 2681 switch (msg) { 2682 case DBELL_TYPE_DBELL: 2683 irq = PPC_INTERRUPT_DOORBELL; 2684 break; 2685 case DBELL_TYPE_DBELL_CRIT: 2686 irq = PPC_INTERRUPT_CDOORBELL; 2687 break; 2688 case DBELL_TYPE_G_DBELL: 2689 case DBELL_TYPE_G_DBELL_CRIT: 2690 case DBELL_TYPE_G_DBELL_MC: 2691 /* XXX implement */ 2692 default: 2693 break; 2694 } 2695 2696 return irq; 2697 } 2698 2699 void helper_msgclr(CPUPPCState *env, target_ulong rb) 2700 { 2701 int irq = dbell2irq(rb); 2702 2703 if (irq < 0) { 2704 return; 2705 } 2706 2707 env->pending_interrupts &= ~(1 << irq); 2708 } 2709 2710 void helper_msgsnd(target_ulong rb) 2711 { 2712 int irq = dbell2irq(rb); 2713 int pir = rb & DBELL_PIRTAG_MASK; 2714 CPUState *cs; 2715 2716 if (irq < 0) { 2717 return; 2718 } 2719 2720 qemu_mutex_lock_iothread(); 2721 CPU_FOREACH(cs) { 2722 PowerPCCPU *cpu = POWERPC_CPU(cs); 2723 CPUPPCState *cenv = &cpu->env; 2724 2725 if ((rb & DBELL_BRDCAST) || (cenv->spr[SPR_BOOKE_PIR] == pir)) { 2726 cenv->pending_interrupts |= 1 << irq; 2727 cpu_interrupt(cs, CPU_INTERRUPT_HARD); 2728 } 2729 } 2730 qemu_mutex_unlock_iothread(); 2731 } 2732 2733 /* Server Processor Control */ 2734 2735 static bool dbell_type_server(target_ulong rb) 2736 { 2737 /* 2738 * A Directed Hypervisor Doorbell message is sent only if the 2739 * message type is 5. All other types are reserved and the 2740 * instruction is a no-op 2741 */ 2742 return (rb & DBELL_TYPE_MASK) == DBELL_TYPE_DBELL_SERVER; 2743 } 2744 2745 void helper_book3s_msgclr(CPUPPCState *env, target_ulong rb) 2746 { 2747 if (!dbell_type_server(rb)) { 2748 return; 2749 } 2750 2751 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDOORBELL); 2752 } 2753 2754 static void book3s_msgsnd_common(int pir, int irq) 2755 { 2756 CPUState *cs; 2757 2758 qemu_mutex_lock_iothread(); 2759 CPU_FOREACH(cs) { 2760 PowerPCCPU *cpu = POWERPC_CPU(cs); 2761 CPUPPCState *cenv = &cpu->env; 2762 2763 /* TODO: broadcast message to all threads of the same processor */ 2764 if (cenv->spr_cb[SPR_PIR].default_value == pir) { 2765 cenv->pending_interrupts |= 1 << irq; 2766 cpu_interrupt(cs, CPU_INTERRUPT_HARD); 2767 } 2768 } 2769 qemu_mutex_unlock_iothread(); 2770 } 2771 2772 void helper_book3s_msgsnd(target_ulong rb) 2773 { 2774 int pir = rb & DBELL_PROCIDTAG_MASK; 2775 2776 if (!dbell_type_server(rb)) { 2777 return; 2778 } 2779 2780 book3s_msgsnd_common(pir, PPC_INTERRUPT_HDOORBELL); 2781 } 2782 2783 #if defined(TARGET_PPC64) 2784 void helper_book3s_msgclrp(CPUPPCState *env, target_ulong rb) 2785 { 2786 helper_hfscr_facility_check(env, HFSCR_MSGP, "msgclrp", HFSCR_IC_MSGP); 2787 2788 if (!dbell_type_server(rb)) { 2789 return; 2790 } 2791 2792 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL); 2793 } 2794 2795 /* 2796 * sends a message to other threads that are on the same 2797 * multi-threaded processor 2798 */ 2799 void helper_book3s_msgsndp(CPUPPCState *env, target_ulong rb) 2800 { 2801 int pir = env->spr_cb[SPR_PIR].default_value; 2802 2803 helper_hfscr_facility_check(env, HFSCR_MSGP, "msgsndp", HFSCR_IC_MSGP); 2804 2805 if (!dbell_type_server(rb)) { 2806 return; 2807 } 2808 2809 /* TODO: TCG supports only one thread */ 2810 2811 book3s_msgsnd_common(pir, PPC_INTERRUPT_DOORBELL); 2812 } 2813 #endif /* TARGET_PPC64 */ 2814 2815 void ppc_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr, 2816 MMUAccessType access_type, 2817 int mmu_idx, uintptr_t retaddr) 2818 { 2819 CPUPPCState *env = cs->env_ptr; 2820 uint32_t insn; 2821 2822 /* Restore state and reload the insn we executed, for filling in DSISR. */ 2823 cpu_restore_state(cs, retaddr, true); 2824 insn = cpu_ldl_code(env, env->nip); 2825 2826 switch (env->mmu_model) { 2827 case POWERPC_MMU_SOFT_4xx: 2828 env->spr[SPR_40x_DEAR] = vaddr; 2829 break; 2830 case POWERPC_MMU_BOOKE: 2831 case POWERPC_MMU_BOOKE206: 2832 env->spr[SPR_BOOKE_DEAR] = vaddr; 2833 break; 2834 default: 2835 env->spr[SPR_DAR] = vaddr; 2836 break; 2837 } 2838 2839 cs->exception_index = POWERPC_EXCP_ALIGN; 2840 env->error_code = insn & 0x03FF0000; 2841 cpu_loop_exit(cs); 2842 } 2843 #endif /* CONFIG_TCG */ 2844 #endif /* !CONFIG_USER_ONLY */ 2845