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