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 #if defined(TARGET_PPC64) 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 CPUPPCState *env = &cpu->env; 271 bool mmu_all_on = ((msr >> MSR_IR) & 1) && ((msr >> MSR_DR) & 1); 272 bool hv_escalation = !(msr & MSR_HVB) && (*new_msr & MSR_HVB); 273 int ail = 0; 274 275 if (excp == POWERPC_EXCP_MCHECK || 276 excp == POWERPC_EXCP_RESET || 277 excp == POWERPC_EXCP_HV_MAINT) { 278 /* SRESET, MCE, HMI never apply AIL */ 279 return; 280 } 281 282 if (excp_model == POWERPC_EXCP_POWER8 || 283 excp_model == POWERPC_EXCP_POWER9) { 284 if (!mmu_all_on) { 285 /* AIL only works if MSR[IR] and MSR[DR] are both enabled. */ 286 return; 287 } 288 if (hv_escalation && !(env->spr[SPR_LPCR] & LPCR_HR)) { 289 /* 290 * AIL does not work if there is a MSR[HV] 0->1 transition and the 291 * partition is in HPT mode. For radix guests, such interrupts are 292 * allowed to be delivered to the hypervisor in ail mode. 293 */ 294 return; 295 } 296 297 ail = (env->spr[SPR_LPCR] & LPCR_AIL) >> LPCR_AIL_SHIFT; 298 if (ail == 0) { 299 return; 300 } 301 if (ail == 1) { 302 /* AIL=1 is reserved, treat it like AIL=0 */ 303 return; 304 } 305 306 } else if (excp_model == POWERPC_EXCP_POWER10) { 307 if (!mmu_all_on && !hv_escalation) { 308 /* 309 * AIL works for HV interrupts even with guest MSR[IR/DR] disabled. 310 * Guest->guest and HV->HV interrupts do require MMU on. 311 */ 312 return; 313 } 314 315 if (*new_msr & MSR_HVB) { 316 if (!(env->spr[SPR_LPCR] & LPCR_HAIL)) { 317 /* HV interrupts depend on LPCR[HAIL] */ 318 return; 319 } 320 ail = 3; /* HAIL=1 gives AIL=3 behaviour for HV interrupts */ 321 } else { 322 ail = (env->spr[SPR_LPCR] & LPCR_AIL) >> LPCR_AIL_SHIFT; 323 } 324 if (ail == 0) { 325 return; 326 } 327 if (ail == 1 || ail == 2) { 328 /* AIL=1 and AIL=2 are reserved, treat them like AIL=0 */ 329 return; 330 } 331 } else { 332 /* Other processors do not support AIL */ 333 return; 334 } 335 336 /* 337 * AIL applies, so the new MSR gets IR and DR set, and an offset applied 338 * to the new IP. 339 */ 340 *new_msr |= (1 << MSR_IR) | (1 << MSR_DR); 341 342 if (excp != POWERPC_EXCP_SYSCALL_VECTORED) { 343 if (ail == 2) { 344 *vector |= 0x0000000000018000ull; 345 } else if (ail == 3) { 346 *vector |= 0xc000000000004000ull; 347 } 348 } else { 349 /* 350 * scv AIL is a little different. AIL=2 does not change the address, 351 * only the MSR. AIL=3 replaces the 0x17000 base with 0xc...3000. 352 */ 353 if (ail == 3) { 354 *vector &= ~0x0000000000017000ull; /* Un-apply the base offset */ 355 *vector |= 0xc000000000003000ull; /* Apply scv's AIL=3 offset */ 356 } 357 } 358 } 359 #endif 360 361 static void powerpc_set_excp_state(PowerPCCPU *cpu, 362 target_ulong vector, target_ulong msr) 363 { 364 CPUState *cs = CPU(cpu); 365 CPUPPCState *env = &cpu->env; 366 367 /* 368 * We don't use hreg_store_msr here as already have treated any 369 * special case that could occur. Just store MSR and update hflags 370 * 371 * Note: We *MUST* not use hreg_store_msr() as-is anyway because it 372 * will prevent setting of the HV bit which some exceptions might need 373 * to do. 374 */ 375 env->msr = msr & env->msr_mask; 376 hreg_compute_hflags(env); 377 env->nip = vector; 378 /* Reset exception state */ 379 cs->exception_index = POWERPC_EXCP_NONE; 380 env->error_code = 0; 381 382 /* Reset the reservation */ 383 env->reserve_addr = -1; 384 385 /* 386 * Any interrupt is context synchronizing, check if TCG TLB needs 387 * a delayed flush on ppc64 388 */ 389 check_tlb_flush(env, false); 390 } 391 392 static void powerpc_excp_40x(PowerPCCPU *cpu, int excp) 393 { 394 CPUState *cs = CPU(cpu); 395 CPUPPCState *env = &cpu->env; 396 target_ulong msr, new_msr, vector; 397 int srr0, srr1; 398 399 if (excp <= POWERPC_EXCP_NONE || excp >= POWERPC_EXCP_NB) { 400 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); 401 } 402 403 qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx 404 " => %s (%d) error=%02x\n", env->nip, powerpc_excp_name(excp), 405 excp, env->error_code); 406 407 /* new srr1 value excluding must-be-zero bits */ 408 msr = env->msr & ~0x783f0000ULL; 409 410 /* 411 * new interrupt handler msr preserves existing ME unless 412 * explicitly overriden. 413 */ 414 new_msr = env->msr & (((target_ulong)1 << MSR_ME)); 415 416 /* target registers */ 417 srr0 = SPR_SRR0; 418 srr1 = SPR_SRR1; 419 420 /* 421 * Hypervisor emulation assistance interrupt only exists on server 422 * arch 2.05 server or later. 423 */ 424 if (excp == POWERPC_EXCP_HV_EMU) { 425 excp = POWERPC_EXCP_PROGRAM; 426 } 427 428 vector = env->excp_vectors[excp]; 429 if (vector == (target_ulong)-1ULL) { 430 cpu_abort(cs, "Raised an exception without defined vector %d\n", 431 excp); 432 } 433 434 vector |= env->excp_prefix; 435 436 switch (excp) { 437 case POWERPC_EXCP_CRITICAL: /* Critical input */ 438 srr0 = SPR_40x_SRR2; 439 srr1 = SPR_40x_SRR3; 440 break; 441 case POWERPC_EXCP_MCHECK: /* Machine check exception */ 442 if (msr_me == 0) { 443 /* 444 * Machine check exception is not enabled. Enter 445 * checkstop state. 446 */ 447 fprintf(stderr, "Machine check while not allowed. " 448 "Entering checkstop state\n"); 449 if (qemu_log_separate()) { 450 qemu_log("Machine check while not allowed. " 451 "Entering checkstop state\n"); 452 } 453 cs->halted = 1; 454 cpu_interrupt_exittb(cs); 455 } 456 457 /* machine check exceptions don't have ME set */ 458 new_msr &= ~((target_ulong)1 << MSR_ME); 459 460 srr0 = SPR_40x_SRR2; 461 srr1 = SPR_40x_SRR3; 462 break; 463 case POWERPC_EXCP_DSI: /* Data storage exception */ 464 trace_ppc_excp_dsi(env->spr[SPR_40x_ESR], env->spr[SPR_40x_DEAR]); 465 break; 466 case POWERPC_EXCP_ISI: /* Instruction storage exception */ 467 trace_ppc_excp_isi(msr, env->nip); 468 break; 469 case POWERPC_EXCP_EXTERNAL: /* External input */ 470 break; 471 case POWERPC_EXCP_ALIGN: /* Alignment exception */ 472 break; 473 case POWERPC_EXCP_PROGRAM: /* Program exception */ 474 switch (env->error_code & ~0xF) { 475 case POWERPC_EXCP_FP: 476 if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) { 477 trace_ppc_excp_fp_ignore(); 478 cs->exception_index = POWERPC_EXCP_NONE; 479 env->error_code = 0; 480 return; 481 } 482 env->spr[SPR_40x_ESR] = ESR_FP; 483 break; 484 case POWERPC_EXCP_INVAL: 485 trace_ppc_excp_inval(env->nip); 486 env->spr[SPR_40x_ESR] = ESR_PIL; 487 break; 488 case POWERPC_EXCP_PRIV: 489 env->spr[SPR_40x_ESR] = ESR_PPR; 490 break; 491 case POWERPC_EXCP_TRAP: 492 env->spr[SPR_40x_ESR] = ESR_PTR; 493 break; 494 default: 495 cpu_abort(cs, "Invalid program exception %d. Aborting\n", 496 env->error_code); 497 break; 498 } 499 break; 500 case POWERPC_EXCP_SYSCALL: /* System call exception */ 501 dump_syscall(env); 502 503 /* 504 * We need to correct the NIP which in this case is supposed 505 * to point to the next instruction 506 */ 507 env->nip += 4; 508 break; 509 case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt */ 510 trace_ppc_excp_print("FIT"); 511 break; 512 case POWERPC_EXCP_WDT: /* Watchdog timer interrupt */ 513 trace_ppc_excp_print("WDT"); 514 break; 515 case POWERPC_EXCP_DTLB: /* Data TLB error */ 516 case POWERPC_EXCP_ITLB: /* Instruction TLB error */ 517 break; 518 case POWERPC_EXCP_PIT: /* Programmable interval timer interrupt */ 519 trace_ppc_excp_print("PIT"); 520 break; 521 case POWERPC_EXCP_DEBUG: /* Debug interrupt */ 522 cpu_abort(cs, "%s exception not implemented\n", 523 powerpc_excp_name(excp)); 524 break; 525 default: 526 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); 527 break; 528 } 529 530 /* Sanity check */ 531 if (!(env->msr_mask & MSR_HVB)) { 532 if (new_msr & MSR_HVB) { 533 cpu_abort(cs, "Trying to deliver HV exception (MSR) %d with " 534 "no HV support\n", excp); 535 } 536 if (srr0 == SPR_HSRR0) { 537 cpu_abort(cs, "Trying to deliver HV exception (HSRR) %d with " 538 "no HV support\n", excp); 539 } 540 } 541 542 /* Save PC */ 543 env->spr[srr0] = env->nip; 544 545 /* Save MSR */ 546 env->spr[srr1] = msr; 547 548 powerpc_set_excp_state(cpu, vector, new_msr); 549 } 550 551 static void powerpc_excp_6xx(PowerPCCPU *cpu, int excp) 552 { 553 CPUState *cs = CPU(cpu); 554 CPUPPCState *env = &cpu->env; 555 target_ulong msr, new_msr, vector; 556 557 if (excp <= POWERPC_EXCP_NONE || excp >= POWERPC_EXCP_NB) { 558 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); 559 } 560 561 qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx 562 " => %s (%d) error=%02x\n", env->nip, powerpc_excp_name(excp), 563 excp, env->error_code); 564 565 /* new srr1 value excluding must-be-zero bits */ 566 msr = env->msr & ~0x783f0000ULL; 567 568 /* 569 * new interrupt handler msr preserves existing ME unless 570 * explicitly overriden 571 */ 572 new_msr = env->msr & ((target_ulong)1 << MSR_ME); 573 574 /* 575 * Hypervisor emulation assistance interrupt only exists on server 576 * arch 2.05 server or later. 577 */ 578 if (excp == POWERPC_EXCP_HV_EMU) { 579 excp = POWERPC_EXCP_PROGRAM; 580 } 581 582 vector = env->excp_vectors[excp]; 583 if (vector == (target_ulong)-1ULL) { 584 cpu_abort(cs, "Raised an exception without defined vector %d\n", 585 excp); 586 } 587 588 vector |= env->excp_prefix; 589 590 switch (excp) { 591 case POWERPC_EXCP_CRITICAL: /* Critical input */ 592 break; 593 case POWERPC_EXCP_MCHECK: /* Machine check exception */ 594 if (msr_me == 0) { 595 /* 596 * Machine check exception is not enabled. Enter 597 * checkstop state. 598 */ 599 fprintf(stderr, "Machine check while not allowed. " 600 "Entering checkstop state\n"); 601 if (qemu_log_separate()) { 602 qemu_log("Machine check while not allowed. " 603 "Entering checkstop state\n"); 604 } 605 cs->halted = 1; 606 cpu_interrupt_exittb(cs); 607 } 608 609 /* machine check exceptions don't have ME set */ 610 new_msr &= ~((target_ulong)1 << MSR_ME); 611 612 break; 613 case POWERPC_EXCP_DSI: /* Data storage exception */ 614 trace_ppc_excp_dsi(env->spr[SPR_DSISR], env->spr[SPR_DAR]); 615 break; 616 case POWERPC_EXCP_ISI: /* Instruction storage exception */ 617 trace_ppc_excp_isi(msr, env->nip); 618 msr |= env->error_code; 619 break; 620 case POWERPC_EXCP_EXTERNAL: /* External input */ 621 break; 622 case POWERPC_EXCP_ALIGN: /* Alignment exception */ 623 /* Get rS/rD and rA from faulting opcode */ 624 /* 625 * Note: the opcode fields will not be set properly for a 626 * direct store load/store, but nobody cares as nobody 627 * actually uses direct store segments. 628 */ 629 env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16; 630 break; 631 case POWERPC_EXCP_PROGRAM: /* Program exception */ 632 switch (env->error_code & ~0xF) { 633 case POWERPC_EXCP_FP: 634 if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) { 635 trace_ppc_excp_fp_ignore(); 636 cs->exception_index = POWERPC_EXCP_NONE; 637 env->error_code = 0; 638 return; 639 } 640 641 /* 642 * FP exceptions always have NIP pointing to the faulting 643 * instruction, so always use store_next and claim we are 644 * precise in the MSR. 645 */ 646 msr |= 0x00100000; 647 break; 648 case POWERPC_EXCP_INVAL: 649 trace_ppc_excp_inval(env->nip); 650 msr |= 0x00080000; 651 break; 652 case POWERPC_EXCP_PRIV: 653 msr |= 0x00040000; 654 break; 655 case POWERPC_EXCP_TRAP: 656 msr |= 0x00020000; 657 break; 658 default: 659 /* Should never occur */ 660 cpu_abort(cs, "Invalid program exception %d. Aborting\n", 661 env->error_code); 662 break; 663 } 664 break; 665 case POWERPC_EXCP_SYSCALL: /* System call exception */ 666 dump_syscall(env); 667 668 /* 669 * We need to correct the NIP which in this case is supposed 670 * to point to the next instruction 671 */ 672 env->nip += 4; 673 break; 674 case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */ 675 case POWERPC_EXCP_DECR: /* Decrementer exception */ 676 break; 677 case POWERPC_EXCP_DTLB: /* Data TLB error */ 678 case POWERPC_EXCP_ITLB: /* Instruction TLB error */ 679 break; 680 case POWERPC_EXCP_RESET: /* System reset exception */ 681 if (msr_pow) { 682 cpu_abort(cs, "Trying to deliver power-saving system reset " 683 "exception %d with no HV support\n", excp); 684 } 685 break; 686 case POWERPC_EXCP_TRACE: /* Trace exception */ 687 break; 688 case POWERPC_EXCP_IFTLB: /* Instruction fetch TLB error */ 689 case POWERPC_EXCP_DLTLB: /* Data load TLB miss */ 690 case POWERPC_EXCP_DSTLB: /* Data store TLB miss */ 691 /* Swap temporary saved registers with GPRs */ 692 if (!(new_msr & ((target_ulong)1 << MSR_TGPR))) { 693 new_msr |= (target_ulong)1 << MSR_TGPR; 694 hreg_swap_gpr_tgpr(env); 695 } 696 697 ppc_excp_debug_sw_tlb(env, excp); 698 699 msr |= env->crf[0] << 28; 700 msr |= env->error_code; /* key, D/I, S/L bits */ 701 /* Set way using a LRU mechanism */ 702 msr |= ((env->last_way + 1) & (env->nb_ways - 1)) << 17; 703 break; 704 case POWERPC_EXCP_FPA: /* Floating-point assist exception */ 705 case POWERPC_EXCP_DABR: /* Data address breakpoint */ 706 case POWERPC_EXCP_IABR: /* Instruction address breakpoint */ 707 case POWERPC_EXCP_SMI: /* System management interrupt */ 708 case POWERPC_EXCP_MEXTBR: /* Maskable external breakpoint */ 709 case POWERPC_EXCP_NMEXTBR: /* Non maskable external breakpoint */ 710 cpu_abort(cs, "%s exception not implemented\n", 711 powerpc_excp_name(excp)); 712 break; 713 default: 714 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); 715 break; 716 } 717 718 /* Sanity check */ 719 if (!(env->msr_mask & MSR_HVB)) { 720 if (new_msr & MSR_HVB) { 721 cpu_abort(cs, "Trying to deliver HV exception (MSR) %d with " 722 "no HV support\n", excp); 723 } 724 } 725 726 /* 727 * Sort out endianness of interrupt, this differs depending on the 728 * CPU, the HV mode, etc... 729 */ 730 if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) { 731 new_msr |= (target_ulong)1 << MSR_LE; 732 } 733 734 /* Save PC */ 735 env->spr[SPR_SRR0] = env->nip; 736 737 /* Save MSR */ 738 env->spr[SPR_SRR1] = msr; 739 740 powerpc_set_excp_state(cpu, vector, new_msr); 741 } 742 743 static void powerpc_excp_7xx(PowerPCCPU *cpu, int excp) 744 { 745 CPUState *cs = CPU(cpu); 746 CPUPPCState *env = &cpu->env; 747 target_ulong msr, new_msr, vector; 748 749 if (excp <= POWERPC_EXCP_NONE || excp >= POWERPC_EXCP_NB) { 750 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); 751 } 752 753 qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx 754 " => %s (%d) error=%02x\n", env->nip, powerpc_excp_name(excp), 755 excp, env->error_code); 756 757 /* new srr1 value excluding must-be-zero bits */ 758 msr = env->msr & ~0x783f0000ULL; 759 760 /* 761 * new interrupt handler msr preserves existing ME unless 762 * explicitly overriden 763 */ 764 new_msr = env->msr & ((target_ulong)1 << MSR_ME); 765 766 /* 767 * Hypervisor emulation assistance interrupt only exists on server 768 * arch 2.05 server or later. 769 */ 770 if (excp == POWERPC_EXCP_HV_EMU) { 771 excp = POWERPC_EXCP_PROGRAM; 772 } 773 774 vector = env->excp_vectors[excp]; 775 if (vector == (target_ulong)-1ULL) { 776 cpu_abort(cs, "Raised an exception without defined vector %d\n", 777 excp); 778 } 779 780 vector |= env->excp_prefix; 781 782 switch (excp) { 783 case POWERPC_EXCP_MCHECK: /* Machine check exception */ 784 if (msr_me == 0) { 785 /* 786 * Machine check exception is not enabled. Enter 787 * checkstop state. 788 */ 789 fprintf(stderr, "Machine check while not allowed. " 790 "Entering checkstop state\n"); 791 if (qemu_log_separate()) { 792 qemu_log("Machine check while not allowed. " 793 "Entering checkstop state\n"); 794 } 795 cs->halted = 1; 796 cpu_interrupt_exittb(cs); 797 } 798 799 /* machine check exceptions don't have ME set */ 800 new_msr &= ~((target_ulong)1 << MSR_ME); 801 802 break; 803 case POWERPC_EXCP_DSI: /* Data storage exception */ 804 trace_ppc_excp_dsi(env->spr[SPR_DSISR], env->spr[SPR_DAR]); 805 break; 806 case POWERPC_EXCP_ISI: /* Instruction storage exception */ 807 trace_ppc_excp_isi(msr, env->nip); 808 msr |= env->error_code; 809 break; 810 case POWERPC_EXCP_EXTERNAL: /* External input */ 811 break; 812 case POWERPC_EXCP_ALIGN: /* Alignment exception */ 813 /* Get rS/rD and rA from faulting opcode */ 814 /* 815 * Note: the opcode fields will not be set properly for a 816 * direct store load/store, but nobody cares as nobody 817 * actually uses direct store segments. 818 */ 819 env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16; 820 break; 821 case POWERPC_EXCP_PROGRAM: /* Program exception */ 822 switch (env->error_code & ~0xF) { 823 case POWERPC_EXCP_FP: 824 if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) { 825 trace_ppc_excp_fp_ignore(); 826 cs->exception_index = POWERPC_EXCP_NONE; 827 env->error_code = 0; 828 return; 829 } 830 831 /* 832 * FP exceptions always have NIP pointing to the faulting 833 * instruction, so always use store_next and claim we are 834 * precise in the MSR. 835 */ 836 msr |= 0x00100000; 837 break; 838 case POWERPC_EXCP_INVAL: 839 trace_ppc_excp_inval(env->nip); 840 msr |= 0x00080000; 841 break; 842 case POWERPC_EXCP_PRIV: 843 msr |= 0x00040000; 844 break; 845 case POWERPC_EXCP_TRAP: 846 msr |= 0x00020000; 847 break; 848 default: 849 /* Should never occur */ 850 cpu_abort(cs, "Invalid program exception %d. Aborting\n", 851 env->error_code); 852 break; 853 } 854 break; 855 case POWERPC_EXCP_SYSCALL: /* System call exception */ 856 { 857 int lev = env->error_code; 858 859 if (lev == 1 && cpu->vhyp) { 860 dump_hcall(env); 861 } else { 862 dump_syscall(env); 863 } 864 865 /* 866 * We need to correct the NIP which in this case is supposed 867 * to point to the next instruction 868 */ 869 env->nip += 4; 870 871 /* 872 * The Virtual Open Firmware (VOF) relies on the 'sc 1' 873 * instruction to communicate with QEMU. The pegasos2 machine 874 * uses VOF and the 7xx CPUs, so although the 7xx don't have 875 * HV mode, we need to keep hypercall support. 876 */ 877 if (lev == 1 && cpu->vhyp) { 878 PPCVirtualHypervisorClass *vhc = 879 PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp); 880 vhc->hypercall(cpu->vhyp, cpu); 881 return; 882 } 883 884 break; 885 } 886 case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */ 887 case POWERPC_EXCP_DECR: /* Decrementer exception */ 888 break; 889 case POWERPC_EXCP_RESET: /* System reset exception */ 890 if (msr_pow) { 891 cpu_abort(cs, "Trying to deliver power-saving system reset " 892 "exception %d with no HV support\n", excp); 893 } 894 break; 895 case POWERPC_EXCP_TRACE: /* Trace exception */ 896 break; 897 case POWERPC_EXCP_IFTLB: /* Instruction fetch TLB error */ 898 case POWERPC_EXCP_DLTLB: /* Data load TLB miss */ 899 case POWERPC_EXCP_DSTLB: /* Data store TLB miss */ 900 ppc_excp_debug_sw_tlb(env, excp); 901 902 msr |= env->crf[0] << 28; 903 msr |= env->error_code; /* key, D/I, S/L bits */ 904 /* Set way using a LRU mechanism */ 905 msr |= ((env->last_way + 1) & (env->nb_ways - 1)) << 17; 906 907 break; 908 case POWERPC_EXCP_IABR: /* Instruction address breakpoint */ 909 case POWERPC_EXCP_SMI: /* System management interrupt */ 910 case POWERPC_EXCP_THERM: /* Thermal interrupt */ 911 case POWERPC_EXCP_PERFM: /* Embedded performance monitor interrupt */ 912 cpu_abort(cs, "%s exception not implemented\n", 913 powerpc_excp_name(excp)); 914 break; 915 default: 916 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); 917 break; 918 } 919 920 /* Sanity check */ 921 if (!(env->msr_mask & MSR_HVB)) { 922 if (new_msr & MSR_HVB) { 923 cpu_abort(cs, "Trying to deliver HV exception (MSR) %d with " 924 "no HV support\n", excp); 925 } 926 } 927 928 /* 929 * Sort out endianness of interrupt, this differs depending on the 930 * CPU, the HV mode, etc... 931 */ 932 if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) { 933 new_msr |= (target_ulong)1 << MSR_LE; 934 } 935 936 /* Save PC */ 937 env->spr[SPR_SRR0] = env->nip; 938 939 /* Save MSR */ 940 env->spr[SPR_SRR1] = msr; 941 942 powerpc_set_excp_state(cpu, vector, new_msr); 943 } 944 945 static void powerpc_excp_74xx(PowerPCCPU *cpu, int excp) 946 { 947 CPUState *cs = CPU(cpu); 948 CPUPPCState *env = &cpu->env; 949 target_ulong msr, new_msr, vector; 950 951 if (excp <= POWERPC_EXCP_NONE || excp >= POWERPC_EXCP_NB) { 952 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); 953 } 954 955 qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx 956 " => %s (%d) error=%02x\n", env->nip, powerpc_excp_name(excp), 957 excp, env->error_code); 958 959 /* new srr1 value excluding must-be-zero bits */ 960 msr = env->msr & ~0x783f0000ULL; 961 962 /* 963 * new interrupt handler msr preserves existing ME unless 964 * explicitly overriden 965 */ 966 new_msr = env->msr & ((target_ulong)1 << MSR_ME); 967 968 /* 969 * Hypervisor emulation assistance interrupt only exists on server 970 * arch 2.05 server or later. 971 */ 972 if (excp == POWERPC_EXCP_HV_EMU) { 973 excp = POWERPC_EXCP_PROGRAM; 974 } 975 976 vector = env->excp_vectors[excp]; 977 if (vector == (target_ulong)-1ULL) { 978 cpu_abort(cs, "Raised an exception without defined vector %d\n", 979 excp); 980 } 981 982 vector |= env->excp_prefix; 983 984 switch (excp) { 985 case POWERPC_EXCP_MCHECK: /* Machine check exception */ 986 if (msr_me == 0) { 987 /* 988 * Machine check exception is not enabled. Enter 989 * checkstop state. 990 */ 991 fprintf(stderr, "Machine check while not allowed. " 992 "Entering checkstop state\n"); 993 if (qemu_log_separate()) { 994 qemu_log("Machine check while not allowed. " 995 "Entering checkstop state\n"); 996 } 997 cs->halted = 1; 998 cpu_interrupt_exittb(cs); 999 } 1000 1001 /* machine check exceptions don't have ME set */ 1002 new_msr &= ~((target_ulong)1 << MSR_ME); 1003 1004 break; 1005 case POWERPC_EXCP_DSI: /* Data storage exception */ 1006 trace_ppc_excp_dsi(env->spr[SPR_DSISR], env->spr[SPR_DAR]); 1007 break; 1008 case POWERPC_EXCP_ISI: /* Instruction storage exception */ 1009 trace_ppc_excp_isi(msr, env->nip); 1010 msr |= env->error_code; 1011 break; 1012 case POWERPC_EXCP_EXTERNAL: /* External input */ 1013 break; 1014 case POWERPC_EXCP_ALIGN: /* Alignment exception */ 1015 /* Get rS/rD and rA from faulting opcode */ 1016 /* 1017 * Note: the opcode fields will not be set properly for a 1018 * direct store load/store, but nobody cares as nobody 1019 * actually uses direct store segments. 1020 */ 1021 env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16; 1022 break; 1023 case POWERPC_EXCP_PROGRAM: /* Program exception */ 1024 switch (env->error_code & ~0xF) { 1025 case POWERPC_EXCP_FP: 1026 if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) { 1027 trace_ppc_excp_fp_ignore(); 1028 cs->exception_index = POWERPC_EXCP_NONE; 1029 env->error_code = 0; 1030 return; 1031 } 1032 1033 /* 1034 * FP exceptions always have NIP pointing to the faulting 1035 * instruction, so always use store_next and claim we are 1036 * precise in the MSR. 1037 */ 1038 msr |= 0x00100000; 1039 break; 1040 case POWERPC_EXCP_INVAL: 1041 trace_ppc_excp_inval(env->nip); 1042 msr |= 0x00080000; 1043 break; 1044 case POWERPC_EXCP_PRIV: 1045 msr |= 0x00040000; 1046 break; 1047 case POWERPC_EXCP_TRAP: 1048 msr |= 0x00020000; 1049 break; 1050 default: 1051 /* Should never occur */ 1052 cpu_abort(cs, "Invalid program exception %d. Aborting\n", 1053 env->error_code); 1054 break; 1055 } 1056 break; 1057 case POWERPC_EXCP_SYSCALL: /* System call exception */ 1058 { 1059 int lev = env->error_code; 1060 1061 if ((lev == 1) && cpu->vhyp) { 1062 dump_hcall(env); 1063 } else { 1064 dump_syscall(env); 1065 } 1066 1067 /* 1068 * We need to correct the NIP which in this case is supposed 1069 * to point to the next instruction 1070 */ 1071 env->nip += 4; 1072 1073 /* 1074 * The Virtual Open Firmware (VOF) relies on the 'sc 1' 1075 * instruction to communicate with QEMU. The pegasos2 machine 1076 * uses VOF and the 74xx CPUs, so although the 74xx don't have 1077 * HV mode, we need to keep hypercall support. 1078 */ 1079 if ((lev == 1) && cpu->vhyp) { 1080 PPCVirtualHypervisorClass *vhc = 1081 PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp); 1082 vhc->hypercall(cpu->vhyp, cpu); 1083 return; 1084 } 1085 1086 break; 1087 } 1088 case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */ 1089 case POWERPC_EXCP_DECR: /* Decrementer exception */ 1090 break; 1091 case POWERPC_EXCP_RESET: /* System reset exception */ 1092 if (msr_pow) { 1093 cpu_abort(cs, "Trying to deliver power-saving system reset " 1094 "exception %d with no HV support\n", excp); 1095 } 1096 break; 1097 case POWERPC_EXCP_TRACE: /* Trace exception */ 1098 break; 1099 case POWERPC_EXCP_VPU: /* Vector unavailable exception */ 1100 break; 1101 case POWERPC_EXCP_IABR: /* Instruction address breakpoint */ 1102 case POWERPC_EXCP_SMI: /* System management interrupt */ 1103 case POWERPC_EXCP_THERM: /* Thermal interrupt */ 1104 case POWERPC_EXCP_PERFM: /* Embedded performance monitor interrupt */ 1105 case POWERPC_EXCP_VPUA: /* Vector assist exception */ 1106 cpu_abort(cs, "%s exception not implemented\n", 1107 powerpc_excp_name(excp)); 1108 break; 1109 default: 1110 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); 1111 break; 1112 } 1113 1114 /* Sanity check */ 1115 if (!(env->msr_mask & MSR_HVB)) { 1116 if (new_msr & MSR_HVB) { 1117 cpu_abort(cs, "Trying to deliver HV exception (MSR) %d with " 1118 "no HV support\n", excp); 1119 } 1120 } 1121 1122 /* 1123 * Sort out endianness of interrupt, this differs depending on the 1124 * CPU, the HV mode, etc... 1125 */ 1126 if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) { 1127 new_msr |= (target_ulong)1 << MSR_LE; 1128 } 1129 1130 /* Save PC */ 1131 env->spr[SPR_SRR0] = env->nip; 1132 1133 /* Save MSR */ 1134 env->spr[SPR_SRR1] = msr; 1135 1136 powerpc_set_excp_state(cpu, vector, new_msr); 1137 } 1138 1139 static void powerpc_excp_booke(PowerPCCPU *cpu, int excp) 1140 { 1141 CPUState *cs = CPU(cpu); 1142 CPUPPCState *env = &cpu->env; 1143 target_ulong msr, new_msr, vector; 1144 int srr0, srr1; 1145 1146 if (excp <= POWERPC_EXCP_NONE || excp >= POWERPC_EXCP_NB) { 1147 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); 1148 } 1149 1150 qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx 1151 " => %s (%d) error=%02x\n", env->nip, powerpc_excp_name(excp), 1152 excp, env->error_code); 1153 1154 msr = env->msr; 1155 1156 /* 1157 * new interrupt handler msr preserves existing ME unless 1158 * explicitly overriden 1159 */ 1160 new_msr = env->msr & ((target_ulong)1 << MSR_ME); 1161 1162 /* target registers */ 1163 srr0 = SPR_SRR0; 1164 srr1 = SPR_SRR1; 1165 1166 /* 1167 * Hypervisor emulation assistance interrupt only exists on server 1168 * arch 2.05 server or later. 1169 */ 1170 if (excp == POWERPC_EXCP_HV_EMU) { 1171 excp = POWERPC_EXCP_PROGRAM; 1172 } 1173 1174 #ifdef TARGET_PPC64 1175 /* 1176 * SPEU and VPU share the same IVOR but they exist in different 1177 * processors. SPEU is e500v1/2 only and VPU is e6500 only. 1178 */ 1179 if (excp == POWERPC_EXCP_VPU) { 1180 excp = POWERPC_EXCP_SPEU; 1181 } 1182 #endif 1183 1184 vector = env->excp_vectors[excp]; 1185 if (vector == (target_ulong)-1ULL) { 1186 cpu_abort(cs, "Raised an exception without defined vector %d\n", 1187 excp); 1188 } 1189 1190 vector |= env->excp_prefix; 1191 1192 switch (excp) { 1193 case POWERPC_EXCP_CRITICAL: /* Critical input */ 1194 srr0 = SPR_BOOKE_CSRR0; 1195 srr1 = SPR_BOOKE_CSRR1; 1196 break; 1197 case POWERPC_EXCP_MCHECK: /* Machine check exception */ 1198 if (msr_me == 0) { 1199 /* 1200 * Machine check exception is not enabled. Enter 1201 * checkstop state. 1202 */ 1203 fprintf(stderr, "Machine check while not allowed. " 1204 "Entering checkstop state\n"); 1205 if (qemu_log_separate()) { 1206 qemu_log("Machine check while not allowed. " 1207 "Entering checkstop state\n"); 1208 } 1209 cs->halted = 1; 1210 cpu_interrupt_exittb(cs); 1211 } 1212 1213 /* machine check exceptions don't have ME set */ 1214 new_msr &= ~((target_ulong)1 << MSR_ME); 1215 1216 /* FIXME: choose one or the other based on CPU type */ 1217 srr0 = SPR_BOOKE_MCSRR0; 1218 srr1 = SPR_BOOKE_MCSRR1; 1219 1220 env->spr[SPR_BOOKE_CSRR0] = env->nip; 1221 env->spr[SPR_BOOKE_CSRR1] = msr; 1222 1223 break; 1224 case POWERPC_EXCP_DSI: /* Data storage exception */ 1225 trace_ppc_excp_dsi(env->spr[SPR_BOOKE_ESR], env->spr[SPR_BOOKE_DEAR]); 1226 break; 1227 case POWERPC_EXCP_ISI: /* Instruction storage exception */ 1228 trace_ppc_excp_isi(msr, env->nip); 1229 break; 1230 case POWERPC_EXCP_EXTERNAL: /* External input */ 1231 if (env->mpic_proxy) { 1232 /* IACK the IRQ on delivery */ 1233 env->spr[SPR_BOOKE_EPR] = ldl_phys(cs->as, env->mpic_iack); 1234 } 1235 break; 1236 case POWERPC_EXCP_ALIGN: /* Alignment exception */ 1237 break; 1238 case POWERPC_EXCP_PROGRAM: /* Program exception */ 1239 switch (env->error_code & ~0xF) { 1240 case POWERPC_EXCP_FP: 1241 if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) { 1242 trace_ppc_excp_fp_ignore(); 1243 cs->exception_index = POWERPC_EXCP_NONE; 1244 env->error_code = 0; 1245 return; 1246 } 1247 1248 /* 1249 * FP exceptions always have NIP pointing to the faulting 1250 * instruction, so always use store_next and claim we are 1251 * precise in the MSR. 1252 */ 1253 msr |= 0x00100000; 1254 env->spr[SPR_BOOKE_ESR] = ESR_FP; 1255 break; 1256 case POWERPC_EXCP_INVAL: 1257 trace_ppc_excp_inval(env->nip); 1258 msr |= 0x00080000; 1259 env->spr[SPR_BOOKE_ESR] = ESR_PIL; 1260 break; 1261 case POWERPC_EXCP_PRIV: 1262 msr |= 0x00040000; 1263 env->spr[SPR_BOOKE_ESR] = ESR_PPR; 1264 break; 1265 case POWERPC_EXCP_TRAP: 1266 msr |= 0x00020000; 1267 env->spr[SPR_BOOKE_ESR] = ESR_PTR; 1268 break; 1269 default: 1270 /* Should never occur */ 1271 cpu_abort(cs, "Invalid program exception %d. Aborting\n", 1272 env->error_code); 1273 break; 1274 } 1275 break; 1276 case POWERPC_EXCP_SYSCALL: /* System call exception */ 1277 dump_syscall(env); 1278 1279 /* 1280 * We need to correct the NIP which in this case is supposed 1281 * to point to the next instruction 1282 */ 1283 env->nip += 4; 1284 break; 1285 case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */ 1286 case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */ 1287 case POWERPC_EXCP_DECR: /* Decrementer exception */ 1288 break; 1289 case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt */ 1290 /* FIT on 4xx */ 1291 trace_ppc_excp_print("FIT"); 1292 break; 1293 case POWERPC_EXCP_WDT: /* Watchdog timer interrupt */ 1294 trace_ppc_excp_print("WDT"); 1295 srr0 = SPR_BOOKE_CSRR0; 1296 srr1 = SPR_BOOKE_CSRR1; 1297 break; 1298 case POWERPC_EXCP_DTLB: /* Data TLB error */ 1299 case POWERPC_EXCP_ITLB: /* Instruction TLB error */ 1300 break; 1301 case POWERPC_EXCP_DEBUG: /* Debug interrupt */ 1302 if (env->flags & POWERPC_FLAG_DE) { 1303 /* FIXME: choose one or the other based on CPU type */ 1304 srr0 = SPR_BOOKE_DSRR0; 1305 srr1 = SPR_BOOKE_DSRR1; 1306 1307 env->spr[SPR_BOOKE_CSRR0] = env->nip; 1308 env->spr[SPR_BOOKE_CSRR1] = msr; 1309 1310 /* DBSR already modified by caller */ 1311 } else { 1312 cpu_abort(cs, "Debug exception triggered on unsupported model\n"); 1313 } 1314 break; 1315 case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavailable/VPU */ 1316 env->spr[SPR_BOOKE_ESR] = ESR_SPV; 1317 break; 1318 case POWERPC_EXCP_RESET: /* System reset exception */ 1319 if (msr_pow) { 1320 cpu_abort(cs, "Trying to deliver power-saving system reset " 1321 "exception %d with no HV support\n", excp); 1322 } 1323 break; 1324 case POWERPC_EXCP_EFPDI: /* Embedded floating-point data interrupt */ 1325 case POWERPC_EXCP_EFPRI: /* Embedded floating-point round interrupt */ 1326 cpu_abort(cs, "%s exception not implemented\n", 1327 powerpc_excp_name(excp)); 1328 break; 1329 default: 1330 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); 1331 break; 1332 } 1333 1334 /* Sanity check */ 1335 if (!(env->msr_mask & MSR_HVB)) { 1336 if (new_msr & MSR_HVB) { 1337 cpu_abort(cs, "Trying to deliver HV exception (MSR) %d with " 1338 "no HV support\n", excp); 1339 } 1340 if (srr0 == SPR_HSRR0) { 1341 cpu_abort(cs, "Trying to deliver HV exception (HSRR) %d with " 1342 "no HV support\n", excp); 1343 } 1344 } 1345 1346 #if defined(TARGET_PPC64) 1347 if (env->spr[SPR_BOOKE_EPCR] & EPCR_ICM) { 1348 /* Cat.64-bit: EPCR.ICM is copied to MSR.CM */ 1349 new_msr |= (target_ulong)1 << MSR_CM; 1350 } else { 1351 vector = (uint32_t)vector; 1352 } 1353 #endif 1354 1355 /* Save PC */ 1356 env->spr[srr0] = env->nip; 1357 1358 /* Save MSR */ 1359 env->spr[srr1] = msr; 1360 1361 powerpc_set_excp_state(cpu, vector, new_msr); 1362 } 1363 1364 #ifdef TARGET_PPC64 1365 static void powerpc_excp_books(PowerPCCPU *cpu, int excp) 1366 { 1367 CPUState *cs = CPU(cpu); 1368 CPUPPCState *env = &cpu->env; 1369 int excp_model = env->excp_model; 1370 target_ulong msr, new_msr, vector; 1371 int srr0, srr1, lev = -1; 1372 1373 if (excp <= POWERPC_EXCP_NONE || excp >= POWERPC_EXCP_NB) { 1374 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); 1375 } 1376 1377 qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx 1378 " => %s (%d) error=%02x\n", env->nip, powerpc_excp_name(excp), 1379 excp, env->error_code); 1380 1381 /* new srr1 value excluding must-be-zero bits */ 1382 msr = env->msr & ~0x783f0000ULL; 1383 1384 /* 1385 * new interrupt handler msr preserves existing HV and ME unless 1386 * explicitly overriden 1387 */ 1388 new_msr = env->msr & (((target_ulong)1 << MSR_ME) | MSR_HVB); 1389 1390 /* target registers */ 1391 srr0 = SPR_SRR0; 1392 srr1 = SPR_SRR1; 1393 1394 /* 1395 * check for special resume at 0x100 from doze/nap/sleep/winkle on 1396 * P7/P8/P9 1397 */ 1398 if (env->resume_as_sreset) { 1399 excp = powerpc_reset_wakeup(cs, env, excp, &msr); 1400 } 1401 1402 /* 1403 * We don't want to generate a Hypervisor Emulation Assistance 1404 * Interrupt if we don't have HVB in msr_mask (PAPR mode). 1405 */ 1406 if (excp == POWERPC_EXCP_HV_EMU && !(env->msr_mask & MSR_HVB)) { 1407 excp = POWERPC_EXCP_PROGRAM; 1408 } 1409 1410 vector = env->excp_vectors[excp]; 1411 if (vector == (target_ulong)-1ULL) { 1412 cpu_abort(cs, "Raised an exception without defined vector %d\n", 1413 excp); 1414 } 1415 1416 vector |= env->excp_prefix; 1417 1418 switch (excp) { 1419 case POWERPC_EXCP_MCHECK: /* Machine check exception */ 1420 if (msr_me == 0) { 1421 /* 1422 * Machine check exception is not enabled. Enter 1423 * checkstop state. 1424 */ 1425 fprintf(stderr, "Machine check while not allowed. " 1426 "Entering checkstop state\n"); 1427 if (qemu_log_separate()) { 1428 qemu_log("Machine check while not allowed. " 1429 "Entering checkstop state\n"); 1430 } 1431 cs->halted = 1; 1432 cpu_interrupt_exittb(cs); 1433 } 1434 if (env->msr_mask & MSR_HVB) { 1435 /* 1436 * ISA specifies HV, but can be delivered to guest with HV 1437 * clear (e.g., see FWNMI in PAPR). 1438 */ 1439 new_msr |= (target_ulong)MSR_HVB; 1440 } 1441 1442 /* machine check exceptions don't have ME set */ 1443 new_msr &= ~((target_ulong)1 << MSR_ME); 1444 1445 break; 1446 case POWERPC_EXCP_DSI: /* Data storage exception */ 1447 trace_ppc_excp_dsi(env->spr[SPR_DSISR], env->spr[SPR_DAR]); 1448 break; 1449 case POWERPC_EXCP_ISI: /* Instruction storage exception */ 1450 trace_ppc_excp_isi(msr, env->nip); 1451 msr |= env->error_code; 1452 break; 1453 case POWERPC_EXCP_EXTERNAL: /* External input */ 1454 { 1455 bool lpes0; 1456 1457 /* 1458 * LPES0 is only taken into consideration if we support HV 1459 * mode for this CPU. 1460 */ 1461 if (!env->has_hv_mode) { 1462 break; 1463 } 1464 1465 lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0); 1466 1467 if (!lpes0) { 1468 new_msr |= (target_ulong)MSR_HVB; 1469 new_msr |= env->msr & ((target_ulong)1 << MSR_RI); 1470 srr0 = SPR_HSRR0; 1471 srr1 = SPR_HSRR1; 1472 } 1473 1474 break; 1475 } 1476 case POWERPC_EXCP_ALIGN: /* Alignment exception */ 1477 /* Get rS/rD and rA from faulting opcode */ 1478 /* 1479 * Note: the opcode fields will not be set properly for a 1480 * direct store load/store, but nobody cares as nobody 1481 * actually uses direct store segments. 1482 */ 1483 env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16; 1484 break; 1485 case POWERPC_EXCP_PROGRAM: /* Program exception */ 1486 switch (env->error_code & ~0xF) { 1487 case POWERPC_EXCP_FP: 1488 if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) { 1489 trace_ppc_excp_fp_ignore(); 1490 cs->exception_index = POWERPC_EXCP_NONE; 1491 env->error_code = 0; 1492 return; 1493 } 1494 1495 /* 1496 * FP exceptions always have NIP pointing to the faulting 1497 * instruction, so always use store_next and claim we are 1498 * precise in the MSR. 1499 */ 1500 msr |= 0x00100000; 1501 break; 1502 case POWERPC_EXCP_INVAL: 1503 trace_ppc_excp_inval(env->nip); 1504 msr |= 0x00080000; 1505 break; 1506 case POWERPC_EXCP_PRIV: 1507 msr |= 0x00040000; 1508 break; 1509 case POWERPC_EXCP_TRAP: 1510 msr |= 0x00020000; 1511 break; 1512 default: 1513 /* Should never occur */ 1514 cpu_abort(cs, "Invalid program exception %d. Aborting\n", 1515 env->error_code); 1516 break; 1517 } 1518 break; 1519 case POWERPC_EXCP_SYSCALL: /* System call exception */ 1520 lev = env->error_code; 1521 1522 if ((lev == 1) && cpu->vhyp) { 1523 dump_hcall(env); 1524 } else { 1525 dump_syscall(env); 1526 } 1527 1528 /* 1529 * We need to correct the NIP which in this case is supposed 1530 * to point to the next instruction 1531 */ 1532 env->nip += 4; 1533 1534 /* "PAPR mode" built-in hypercall emulation */ 1535 if ((lev == 1) && cpu->vhyp) { 1536 PPCVirtualHypervisorClass *vhc = 1537 PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp); 1538 vhc->hypercall(cpu->vhyp, cpu); 1539 return; 1540 } 1541 if (lev == 1) { 1542 new_msr |= (target_ulong)MSR_HVB; 1543 } 1544 break; 1545 case POWERPC_EXCP_SYSCALL_VECTORED: /* scv exception */ 1546 lev = env->error_code; 1547 dump_syscall(env); 1548 env->nip += 4; 1549 new_msr |= env->msr & ((target_ulong)1 << MSR_EE); 1550 new_msr |= env->msr & ((target_ulong)1 << MSR_RI); 1551 1552 vector += lev * 0x20; 1553 1554 env->lr = env->nip; 1555 env->ctr = msr; 1556 break; 1557 case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */ 1558 case POWERPC_EXCP_DECR: /* Decrementer exception */ 1559 break; 1560 case POWERPC_EXCP_RESET: /* System reset exception */ 1561 /* A power-saving exception sets ME, otherwise it is unchanged */ 1562 if (msr_pow) { 1563 /* indicate that we resumed from power save mode */ 1564 msr |= 0x10000; 1565 new_msr |= ((target_ulong)1 << MSR_ME); 1566 } 1567 if (env->msr_mask & MSR_HVB) { 1568 /* 1569 * ISA specifies HV, but can be delivered to guest with HV 1570 * clear (e.g., see FWNMI in PAPR, NMI injection in QEMU). 1571 */ 1572 new_msr |= (target_ulong)MSR_HVB; 1573 } else { 1574 if (msr_pow) { 1575 cpu_abort(cs, "Trying to deliver power-saving system reset " 1576 "exception %d with no HV support\n", excp); 1577 } 1578 } 1579 break; 1580 case POWERPC_EXCP_DSEG: /* Data segment exception */ 1581 case POWERPC_EXCP_ISEG: /* Instruction segment exception */ 1582 case POWERPC_EXCP_TRACE: /* Trace exception */ 1583 break; 1584 case POWERPC_EXCP_HISI: /* Hypervisor instruction storage exception */ 1585 msr |= env->error_code; 1586 /* fall through */ 1587 case POWERPC_EXCP_HDECR: /* Hypervisor decrementer exception */ 1588 case POWERPC_EXCP_HDSI: /* Hypervisor data storage exception */ 1589 case POWERPC_EXCP_SDOOR_HV: /* Hypervisor Doorbell interrupt */ 1590 case POWERPC_EXCP_HV_EMU: 1591 case POWERPC_EXCP_HVIRT: /* Hypervisor virtualization */ 1592 srr0 = SPR_HSRR0; 1593 srr1 = SPR_HSRR1; 1594 new_msr |= (target_ulong)MSR_HVB; 1595 new_msr |= env->msr & ((target_ulong)1 << MSR_RI); 1596 break; 1597 case POWERPC_EXCP_VPU: /* Vector unavailable exception */ 1598 case POWERPC_EXCP_VSXU: /* VSX unavailable exception */ 1599 case POWERPC_EXCP_FU: /* Facility unavailable exception */ 1600 env->spr[SPR_FSCR] |= ((target_ulong)env->error_code << 56); 1601 break; 1602 case POWERPC_EXCP_HV_FU: /* Hypervisor Facility Unavailable Exception */ 1603 env->spr[SPR_HFSCR] |= ((target_ulong)env->error_code << FSCR_IC_POS); 1604 srr0 = SPR_HSRR0; 1605 srr1 = SPR_HSRR1; 1606 new_msr |= (target_ulong)MSR_HVB; 1607 new_msr |= env->msr & ((target_ulong)1 << MSR_RI); 1608 break; 1609 case POWERPC_EXCP_THERM: /* Thermal interrupt */ 1610 case POWERPC_EXCP_PERFM: /* Embedded performance monitor interrupt */ 1611 case POWERPC_EXCP_VPUA: /* Vector assist exception */ 1612 case POWERPC_EXCP_MAINT: /* Maintenance exception */ 1613 case POWERPC_EXCP_SDOOR: /* Doorbell interrupt */ 1614 case POWERPC_EXCP_HV_MAINT: /* Hypervisor Maintenance exception */ 1615 cpu_abort(cs, "%s exception not implemented\n", 1616 powerpc_excp_name(excp)); 1617 break; 1618 default: 1619 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); 1620 break; 1621 } 1622 1623 /* Sanity check */ 1624 if (!(env->msr_mask & MSR_HVB)) { 1625 if (new_msr & MSR_HVB) { 1626 cpu_abort(cs, "Trying to deliver HV exception (MSR) %d with " 1627 "no HV support\n", excp); 1628 } 1629 if (srr0 == SPR_HSRR0) { 1630 cpu_abort(cs, "Trying to deliver HV exception (HSRR) %d with " 1631 "no HV support\n", excp); 1632 } 1633 } 1634 1635 /* 1636 * Sort out endianness of interrupt, this differs depending on the 1637 * CPU, the HV mode, etc... 1638 */ 1639 if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) { 1640 new_msr |= (target_ulong)1 << MSR_LE; 1641 } 1642 1643 new_msr |= (target_ulong)1 << MSR_SF; 1644 1645 if (excp != POWERPC_EXCP_SYSCALL_VECTORED) { 1646 /* Save PC */ 1647 env->spr[srr0] = env->nip; 1648 1649 /* Save MSR */ 1650 env->spr[srr1] = msr; 1651 } 1652 1653 /* This can update new_msr and vector if AIL applies */ 1654 ppc_excp_apply_ail(cpu, excp_model, excp, msr, &new_msr, &vector); 1655 1656 powerpc_set_excp_state(cpu, vector, new_msr); 1657 } 1658 #else 1659 static inline void powerpc_excp_books(PowerPCCPU *cpu, int excp) 1660 { 1661 g_assert_not_reached(); 1662 } 1663 #endif 1664 1665 static void powerpc_excp(PowerPCCPU *cpu, int excp) 1666 { 1667 CPUPPCState *env = &cpu->env; 1668 1669 switch (env->excp_model) { 1670 case POWERPC_EXCP_40x: 1671 powerpc_excp_40x(cpu, excp); 1672 break; 1673 case POWERPC_EXCP_6xx: 1674 powerpc_excp_6xx(cpu, excp); 1675 break; 1676 case POWERPC_EXCP_7xx: 1677 powerpc_excp_7xx(cpu, excp); 1678 break; 1679 case POWERPC_EXCP_74xx: 1680 powerpc_excp_74xx(cpu, excp); 1681 break; 1682 case POWERPC_EXCP_BOOKE: 1683 powerpc_excp_booke(cpu, excp); 1684 break; 1685 case POWERPC_EXCP_970: 1686 case POWERPC_EXCP_POWER7: 1687 case POWERPC_EXCP_POWER8: 1688 case POWERPC_EXCP_POWER9: 1689 case POWERPC_EXCP_POWER10: 1690 powerpc_excp_books(cpu, excp); 1691 break; 1692 default: 1693 g_assert_not_reached(); 1694 } 1695 } 1696 1697 void ppc_cpu_do_interrupt(CPUState *cs) 1698 { 1699 PowerPCCPU *cpu = POWERPC_CPU(cs); 1700 1701 powerpc_excp(cpu, cs->exception_index); 1702 } 1703 1704 static void ppc_hw_interrupt(CPUPPCState *env) 1705 { 1706 PowerPCCPU *cpu = env_archcpu(env); 1707 bool async_deliver; 1708 1709 /* External reset */ 1710 if (env->pending_interrupts & (1 << PPC_INTERRUPT_RESET)) { 1711 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_RESET); 1712 powerpc_excp(cpu, POWERPC_EXCP_RESET); 1713 return; 1714 } 1715 /* Machine check exception */ 1716 if (env->pending_interrupts & (1 << PPC_INTERRUPT_MCK)) { 1717 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_MCK); 1718 powerpc_excp(cpu, POWERPC_EXCP_MCHECK); 1719 return; 1720 } 1721 #if 0 /* TODO */ 1722 /* External debug exception */ 1723 if (env->pending_interrupts & (1 << PPC_INTERRUPT_DEBUG)) { 1724 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DEBUG); 1725 powerpc_excp(cpu, POWERPC_EXCP_DEBUG); 1726 return; 1727 } 1728 #endif 1729 1730 /* 1731 * For interrupts that gate on MSR:EE, we need to do something a 1732 * bit more subtle, as we need to let them through even when EE is 1733 * clear when coming out of some power management states (in order 1734 * for them to become a 0x100). 1735 */ 1736 async_deliver = (msr_ee != 0) || env->resume_as_sreset; 1737 1738 /* Hypervisor decrementer exception */ 1739 if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDECR)) { 1740 /* LPCR will be clear when not supported so this will work */ 1741 bool hdice = !!(env->spr[SPR_LPCR] & LPCR_HDICE); 1742 if ((async_deliver || msr_hv == 0) && hdice) { 1743 /* HDEC clears on delivery */ 1744 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDECR); 1745 powerpc_excp(cpu, POWERPC_EXCP_HDECR); 1746 return; 1747 } 1748 } 1749 1750 /* Hypervisor virtualization interrupt */ 1751 if (env->pending_interrupts & (1 << PPC_INTERRUPT_HVIRT)) { 1752 /* LPCR will be clear when not supported so this will work */ 1753 bool hvice = !!(env->spr[SPR_LPCR] & LPCR_HVICE); 1754 if ((async_deliver || msr_hv == 0) && hvice) { 1755 powerpc_excp(cpu, POWERPC_EXCP_HVIRT); 1756 return; 1757 } 1758 } 1759 1760 /* External interrupt can ignore MSR:EE under some circumstances */ 1761 if (env->pending_interrupts & (1 << PPC_INTERRUPT_EXT)) { 1762 bool lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0); 1763 bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC); 1764 /* HEIC blocks delivery to the hypervisor */ 1765 if ((async_deliver && !(heic && msr_hv && !msr_pr)) || 1766 (env->has_hv_mode && msr_hv == 0 && !lpes0)) { 1767 powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL); 1768 return; 1769 } 1770 } 1771 if (msr_ce != 0) { 1772 /* External critical interrupt */ 1773 if (env->pending_interrupts & (1 << PPC_INTERRUPT_CEXT)) { 1774 powerpc_excp(cpu, POWERPC_EXCP_CRITICAL); 1775 return; 1776 } 1777 } 1778 if (async_deliver != 0) { 1779 /* Watchdog timer on embedded PowerPC */ 1780 if (env->pending_interrupts & (1 << PPC_INTERRUPT_WDT)) { 1781 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_WDT); 1782 powerpc_excp(cpu, POWERPC_EXCP_WDT); 1783 return; 1784 } 1785 if (env->pending_interrupts & (1 << PPC_INTERRUPT_CDOORBELL)) { 1786 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_CDOORBELL); 1787 powerpc_excp(cpu, POWERPC_EXCP_DOORCI); 1788 return; 1789 } 1790 /* Fixed interval timer on embedded PowerPC */ 1791 if (env->pending_interrupts & (1 << PPC_INTERRUPT_FIT)) { 1792 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_FIT); 1793 powerpc_excp(cpu, POWERPC_EXCP_FIT); 1794 return; 1795 } 1796 /* Programmable interval timer on embedded PowerPC */ 1797 if (env->pending_interrupts & (1 << PPC_INTERRUPT_PIT)) { 1798 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PIT); 1799 powerpc_excp(cpu, POWERPC_EXCP_PIT); 1800 return; 1801 } 1802 /* Decrementer exception */ 1803 if (env->pending_interrupts & (1 << PPC_INTERRUPT_DECR)) { 1804 if (ppc_decr_clear_on_delivery(env)) { 1805 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DECR); 1806 } 1807 powerpc_excp(cpu, POWERPC_EXCP_DECR); 1808 return; 1809 } 1810 if (env->pending_interrupts & (1 << PPC_INTERRUPT_DOORBELL)) { 1811 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL); 1812 if (is_book3s_arch2x(env)) { 1813 powerpc_excp(cpu, POWERPC_EXCP_SDOOR); 1814 } else { 1815 powerpc_excp(cpu, POWERPC_EXCP_DOORI); 1816 } 1817 return; 1818 } 1819 if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDOORBELL)) { 1820 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDOORBELL); 1821 powerpc_excp(cpu, POWERPC_EXCP_SDOOR_HV); 1822 return; 1823 } 1824 if (env->pending_interrupts & (1 << PPC_INTERRUPT_PERFM)) { 1825 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PERFM); 1826 powerpc_excp(cpu, POWERPC_EXCP_PERFM); 1827 return; 1828 } 1829 /* Thermal interrupt */ 1830 if (env->pending_interrupts & (1 << PPC_INTERRUPT_THERM)) { 1831 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_THERM); 1832 powerpc_excp(cpu, POWERPC_EXCP_THERM); 1833 return; 1834 } 1835 } 1836 1837 if (env->resume_as_sreset) { 1838 /* 1839 * This is a bug ! It means that has_work took us out of halt without 1840 * anything to deliver while in a PM state that requires getting 1841 * out via a 0x100 1842 * 1843 * This means we will incorrectly execute past the power management 1844 * instruction instead of triggering a reset. 1845 * 1846 * It generally means a discrepancy between the wakeup conditions in the 1847 * processor has_work implementation and the logic in this function. 1848 */ 1849 cpu_abort(env_cpu(env), 1850 "Wakeup from PM state but interrupt Undelivered"); 1851 } 1852 } 1853 1854 void ppc_cpu_do_system_reset(CPUState *cs) 1855 { 1856 PowerPCCPU *cpu = POWERPC_CPU(cs); 1857 1858 powerpc_excp(cpu, POWERPC_EXCP_RESET); 1859 } 1860 1861 void ppc_cpu_do_fwnmi_machine_check(CPUState *cs, target_ulong vector) 1862 { 1863 PowerPCCPU *cpu = POWERPC_CPU(cs); 1864 CPUPPCState *env = &cpu->env; 1865 target_ulong msr = 0; 1866 1867 /* 1868 * Set MSR and NIP for the handler, SRR0/1, DAR and DSISR have already 1869 * been set by KVM. 1870 */ 1871 msr = (1ULL << MSR_ME); 1872 msr |= env->msr & (1ULL << MSR_SF); 1873 if (ppc_interrupts_little_endian(cpu, false)) { 1874 msr |= (1ULL << MSR_LE); 1875 } 1876 1877 powerpc_set_excp_state(cpu, vector, msr); 1878 } 1879 1880 bool ppc_cpu_exec_interrupt(CPUState *cs, int interrupt_request) 1881 { 1882 PowerPCCPU *cpu = POWERPC_CPU(cs); 1883 CPUPPCState *env = &cpu->env; 1884 1885 if (interrupt_request & CPU_INTERRUPT_HARD) { 1886 ppc_hw_interrupt(env); 1887 if (env->pending_interrupts == 0) { 1888 cs->interrupt_request &= ~CPU_INTERRUPT_HARD; 1889 } 1890 return true; 1891 } 1892 return false; 1893 } 1894 1895 #endif /* !CONFIG_USER_ONLY */ 1896 1897 /*****************************************************************************/ 1898 /* Exceptions processing helpers */ 1899 1900 void raise_exception_err_ra(CPUPPCState *env, uint32_t exception, 1901 uint32_t error_code, uintptr_t raddr) 1902 { 1903 CPUState *cs = env_cpu(env); 1904 1905 cs->exception_index = exception; 1906 env->error_code = error_code; 1907 cpu_loop_exit_restore(cs, raddr); 1908 } 1909 1910 void raise_exception_err(CPUPPCState *env, uint32_t exception, 1911 uint32_t error_code) 1912 { 1913 raise_exception_err_ra(env, exception, error_code, 0); 1914 } 1915 1916 void raise_exception(CPUPPCState *env, uint32_t exception) 1917 { 1918 raise_exception_err_ra(env, exception, 0, 0); 1919 } 1920 1921 void raise_exception_ra(CPUPPCState *env, uint32_t exception, 1922 uintptr_t raddr) 1923 { 1924 raise_exception_err_ra(env, exception, 0, raddr); 1925 } 1926 1927 #ifdef CONFIG_TCG 1928 void helper_raise_exception_err(CPUPPCState *env, uint32_t exception, 1929 uint32_t error_code) 1930 { 1931 raise_exception_err_ra(env, exception, error_code, 0); 1932 } 1933 1934 void helper_raise_exception(CPUPPCState *env, uint32_t exception) 1935 { 1936 raise_exception_err_ra(env, exception, 0, 0); 1937 } 1938 #endif 1939 1940 #if !defined(CONFIG_USER_ONLY) 1941 #ifdef CONFIG_TCG 1942 void helper_store_msr(CPUPPCState *env, target_ulong val) 1943 { 1944 uint32_t excp = hreg_store_msr(env, val, 0); 1945 1946 if (excp != 0) { 1947 CPUState *cs = env_cpu(env); 1948 cpu_interrupt_exittb(cs); 1949 raise_exception(env, excp); 1950 } 1951 } 1952 1953 #if defined(TARGET_PPC64) 1954 void helper_scv(CPUPPCState *env, uint32_t lev) 1955 { 1956 if (env->spr[SPR_FSCR] & (1ull << FSCR_SCV)) { 1957 raise_exception_err(env, POWERPC_EXCP_SYSCALL_VECTORED, lev); 1958 } else { 1959 raise_exception_err(env, POWERPC_EXCP_FU, FSCR_IC_SCV); 1960 } 1961 } 1962 1963 void helper_pminsn(CPUPPCState *env, powerpc_pm_insn_t insn) 1964 { 1965 CPUState *cs; 1966 1967 cs = env_cpu(env); 1968 cs->halted = 1; 1969 1970 /* Condition for waking up at 0x100 */ 1971 env->resume_as_sreset = (insn != PPC_PM_STOP) || 1972 (env->spr[SPR_PSSCR] & PSSCR_EC); 1973 } 1974 #endif /* defined(TARGET_PPC64) */ 1975 1976 static void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr) 1977 { 1978 CPUState *cs = env_cpu(env); 1979 1980 /* MSR:POW cannot be set by any form of rfi */ 1981 msr &= ~(1ULL << MSR_POW); 1982 1983 /* MSR:TGPR cannot be set by any form of rfi */ 1984 if (env->flags & POWERPC_FLAG_TGPR) 1985 msr &= ~(1ULL << MSR_TGPR); 1986 1987 #if defined(TARGET_PPC64) 1988 /* Switching to 32-bit ? Crop the nip */ 1989 if (!msr_is_64bit(env, msr)) { 1990 nip = (uint32_t)nip; 1991 } 1992 #else 1993 nip = (uint32_t)nip; 1994 #endif 1995 /* XXX: beware: this is false if VLE is supported */ 1996 env->nip = nip & ~((target_ulong)0x00000003); 1997 hreg_store_msr(env, msr, 1); 1998 trace_ppc_excp_rfi(env->nip, env->msr); 1999 /* 2000 * No need to raise an exception here, as rfi is always the last 2001 * insn of a TB 2002 */ 2003 cpu_interrupt_exittb(cs); 2004 /* Reset the reservation */ 2005 env->reserve_addr = -1; 2006 2007 /* Context synchronizing: check if TCG TLB needs flush */ 2008 check_tlb_flush(env, false); 2009 } 2010 2011 void helper_rfi(CPUPPCState *env) 2012 { 2013 do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1] & 0xfffffffful); 2014 } 2015 2016 #define MSR_BOOK3S_MASK 2017 #if defined(TARGET_PPC64) 2018 void helper_rfid(CPUPPCState *env) 2019 { 2020 /* 2021 * The architecture defines a number of rules for which bits can 2022 * change but in practice, we handle this in hreg_store_msr() 2023 * which will be called by do_rfi(), so there is no need to filter 2024 * here 2025 */ 2026 do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1]); 2027 } 2028 2029 void helper_rfscv(CPUPPCState *env) 2030 { 2031 do_rfi(env, env->lr, env->ctr); 2032 } 2033 2034 void helper_hrfid(CPUPPCState *env) 2035 { 2036 do_rfi(env, env->spr[SPR_HSRR0], env->spr[SPR_HSRR1]); 2037 } 2038 #endif 2039 2040 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) 2041 void helper_rfebb(CPUPPCState *env, target_ulong s) 2042 { 2043 target_ulong msr = env->msr; 2044 2045 /* 2046 * Handling of BESCR bits 32:33 according to PowerISA v3.1: 2047 * 2048 * "If BESCR 32:33 != 0b00 the instruction is treated as if 2049 * the instruction form were invalid." 2050 */ 2051 if (env->spr[SPR_BESCR] & BESCR_INVALID) { 2052 raise_exception_err(env, POWERPC_EXCP_PROGRAM, 2053 POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL); 2054 } 2055 2056 env->nip = env->spr[SPR_EBBRR]; 2057 2058 /* Switching to 32-bit ? Crop the nip */ 2059 if (!msr_is_64bit(env, msr)) { 2060 env->nip = (uint32_t)env->spr[SPR_EBBRR]; 2061 } 2062 2063 if (s) { 2064 env->spr[SPR_BESCR] |= BESCR_GE; 2065 } else { 2066 env->spr[SPR_BESCR] &= ~BESCR_GE; 2067 } 2068 } 2069 #endif 2070 2071 /*****************************************************************************/ 2072 /* Embedded PowerPC specific helpers */ 2073 void helper_40x_rfci(CPUPPCState *env) 2074 { 2075 do_rfi(env, env->spr[SPR_40x_SRR2], env->spr[SPR_40x_SRR3]); 2076 } 2077 2078 void helper_rfci(CPUPPCState *env) 2079 { 2080 do_rfi(env, env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1]); 2081 } 2082 2083 void helper_rfdi(CPUPPCState *env) 2084 { 2085 /* FIXME: choose CSRR1 or DSRR1 based on cpu type */ 2086 do_rfi(env, env->spr[SPR_BOOKE_DSRR0], env->spr[SPR_BOOKE_DSRR1]); 2087 } 2088 2089 void helper_rfmci(CPUPPCState *env) 2090 { 2091 /* FIXME: choose CSRR1 or MCSRR1 based on cpu type */ 2092 do_rfi(env, env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1]); 2093 } 2094 #endif /* CONFIG_TCG */ 2095 #endif /* !defined(CONFIG_USER_ONLY) */ 2096 2097 #ifdef CONFIG_TCG 2098 void helper_tw(CPUPPCState *env, target_ulong arg1, target_ulong arg2, 2099 uint32_t flags) 2100 { 2101 if (!likely(!(((int32_t)arg1 < (int32_t)arg2 && (flags & 0x10)) || 2102 ((int32_t)arg1 > (int32_t)arg2 && (flags & 0x08)) || 2103 ((int32_t)arg1 == (int32_t)arg2 && (flags & 0x04)) || 2104 ((uint32_t)arg1 < (uint32_t)arg2 && (flags & 0x02)) || 2105 ((uint32_t)arg1 > (uint32_t)arg2 && (flags & 0x01))))) { 2106 raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, 2107 POWERPC_EXCP_TRAP, GETPC()); 2108 } 2109 } 2110 2111 #if defined(TARGET_PPC64) 2112 void helper_td(CPUPPCState *env, target_ulong arg1, target_ulong arg2, 2113 uint32_t flags) 2114 { 2115 if (!likely(!(((int64_t)arg1 < (int64_t)arg2 && (flags & 0x10)) || 2116 ((int64_t)arg1 > (int64_t)arg2 && (flags & 0x08)) || 2117 ((int64_t)arg1 == (int64_t)arg2 && (flags & 0x04)) || 2118 ((uint64_t)arg1 < (uint64_t)arg2 && (flags & 0x02)) || 2119 ((uint64_t)arg1 > (uint64_t)arg2 && (flags & 0x01))))) { 2120 raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, 2121 POWERPC_EXCP_TRAP, GETPC()); 2122 } 2123 } 2124 #endif 2125 #endif 2126 2127 #if !defined(CONFIG_USER_ONLY) 2128 2129 #ifdef CONFIG_TCG 2130 2131 /* Embedded.Processor Control */ 2132 static int dbell2irq(target_ulong rb) 2133 { 2134 int msg = rb & DBELL_TYPE_MASK; 2135 int irq = -1; 2136 2137 switch (msg) { 2138 case DBELL_TYPE_DBELL: 2139 irq = PPC_INTERRUPT_DOORBELL; 2140 break; 2141 case DBELL_TYPE_DBELL_CRIT: 2142 irq = PPC_INTERRUPT_CDOORBELL; 2143 break; 2144 case DBELL_TYPE_G_DBELL: 2145 case DBELL_TYPE_G_DBELL_CRIT: 2146 case DBELL_TYPE_G_DBELL_MC: 2147 /* XXX implement */ 2148 default: 2149 break; 2150 } 2151 2152 return irq; 2153 } 2154 2155 void helper_msgclr(CPUPPCState *env, target_ulong rb) 2156 { 2157 int irq = dbell2irq(rb); 2158 2159 if (irq < 0) { 2160 return; 2161 } 2162 2163 env->pending_interrupts &= ~(1 << irq); 2164 } 2165 2166 void helper_msgsnd(target_ulong rb) 2167 { 2168 int irq = dbell2irq(rb); 2169 int pir = rb & DBELL_PIRTAG_MASK; 2170 CPUState *cs; 2171 2172 if (irq < 0) { 2173 return; 2174 } 2175 2176 qemu_mutex_lock_iothread(); 2177 CPU_FOREACH(cs) { 2178 PowerPCCPU *cpu = POWERPC_CPU(cs); 2179 CPUPPCState *cenv = &cpu->env; 2180 2181 if ((rb & DBELL_BRDCAST) || (cenv->spr[SPR_BOOKE_PIR] == pir)) { 2182 cenv->pending_interrupts |= 1 << irq; 2183 cpu_interrupt(cs, CPU_INTERRUPT_HARD); 2184 } 2185 } 2186 qemu_mutex_unlock_iothread(); 2187 } 2188 2189 /* Server Processor Control */ 2190 2191 static bool dbell_type_server(target_ulong rb) 2192 { 2193 /* 2194 * A Directed Hypervisor Doorbell message is sent only if the 2195 * message type is 5. All other types are reserved and the 2196 * instruction is a no-op 2197 */ 2198 return (rb & DBELL_TYPE_MASK) == DBELL_TYPE_DBELL_SERVER; 2199 } 2200 2201 void helper_book3s_msgclr(CPUPPCState *env, target_ulong rb) 2202 { 2203 if (!dbell_type_server(rb)) { 2204 return; 2205 } 2206 2207 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDOORBELL); 2208 } 2209 2210 static void book3s_msgsnd_common(int pir, int irq) 2211 { 2212 CPUState *cs; 2213 2214 qemu_mutex_lock_iothread(); 2215 CPU_FOREACH(cs) { 2216 PowerPCCPU *cpu = POWERPC_CPU(cs); 2217 CPUPPCState *cenv = &cpu->env; 2218 2219 /* TODO: broadcast message to all threads of the same processor */ 2220 if (cenv->spr_cb[SPR_PIR].default_value == pir) { 2221 cenv->pending_interrupts |= 1 << irq; 2222 cpu_interrupt(cs, CPU_INTERRUPT_HARD); 2223 } 2224 } 2225 qemu_mutex_unlock_iothread(); 2226 } 2227 2228 void helper_book3s_msgsnd(target_ulong rb) 2229 { 2230 int pir = rb & DBELL_PROCIDTAG_MASK; 2231 2232 if (!dbell_type_server(rb)) { 2233 return; 2234 } 2235 2236 book3s_msgsnd_common(pir, PPC_INTERRUPT_HDOORBELL); 2237 } 2238 2239 #if defined(TARGET_PPC64) 2240 void helper_book3s_msgclrp(CPUPPCState *env, target_ulong rb) 2241 { 2242 helper_hfscr_facility_check(env, HFSCR_MSGP, "msgclrp", HFSCR_IC_MSGP); 2243 2244 if (!dbell_type_server(rb)) { 2245 return; 2246 } 2247 2248 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL); 2249 } 2250 2251 /* 2252 * sends a message to other threads that are on the same 2253 * multi-threaded processor 2254 */ 2255 void helper_book3s_msgsndp(CPUPPCState *env, target_ulong rb) 2256 { 2257 int pir = env->spr_cb[SPR_PIR].default_value; 2258 2259 helper_hfscr_facility_check(env, HFSCR_MSGP, "msgsndp", HFSCR_IC_MSGP); 2260 2261 if (!dbell_type_server(rb)) { 2262 return; 2263 } 2264 2265 /* TODO: TCG supports only one thread */ 2266 2267 book3s_msgsnd_common(pir, PPC_INTERRUPT_DOORBELL); 2268 } 2269 #endif /* TARGET_PPC64 */ 2270 2271 void ppc_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr, 2272 MMUAccessType access_type, 2273 int mmu_idx, uintptr_t retaddr) 2274 { 2275 CPUPPCState *env = cs->env_ptr; 2276 uint32_t insn; 2277 2278 /* Restore state and reload the insn we executed, for filling in DSISR. */ 2279 cpu_restore_state(cs, retaddr, true); 2280 insn = cpu_ldl_code(env, env->nip); 2281 2282 switch (env->mmu_model) { 2283 case POWERPC_MMU_SOFT_4xx: 2284 env->spr[SPR_40x_DEAR] = vaddr; 2285 break; 2286 case POWERPC_MMU_BOOKE: 2287 case POWERPC_MMU_BOOKE206: 2288 env->spr[SPR_BOOKE_DEAR] = vaddr; 2289 break; 2290 default: 2291 env->spr[SPR_DAR] = vaddr; 2292 break; 2293 } 2294 2295 cs->exception_index = POWERPC_EXCP_ALIGN; 2296 env->error_code = insn & 0x03FF0000; 2297 cpu_loop_exit(cs); 2298 } 2299 #endif /* CONFIG_TCG */ 2300 #endif /* !CONFIG_USER_ONLY */ 2301