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