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