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