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