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