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