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