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