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