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