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