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