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