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