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 #ifdef CONFIG_TCG 27 #include "exec/helper-proto.h" 28 #include "exec/cpu_ldst.h" 29 #endif 30 31 /* #define DEBUG_OP */ 32 /* #define DEBUG_SOFTWARE_TLB */ 33 /* #define DEBUG_EXCEPTIONS */ 34 35 #ifdef DEBUG_EXCEPTIONS 36 # define LOG_EXCP(...) qemu_log(__VA_ARGS__) 37 #else 38 # define LOG_EXCP(...) do { } while (0) 39 #endif 40 41 /*****************************************************************************/ 42 /* Exception processing */ 43 #if !defined(CONFIG_USER_ONLY) 44 45 static inline void dump_syscall(CPUPPCState *env) 46 { 47 qemu_log_mask(CPU_LOG_INT, "syscall r0=%016" PRIx64 48 " r3=%016" PRIx64 " r4=%016" PRIx64 " r5=%016" PRIx64 49 " r6=%016" PRIx64 " r7=%016" PRIx64 " r8=%016" PRIx64 50 " nip=" TARGET_FMT_lx "\n", 51 ppc_dump_gpr(env, 0), ppc_dump_gpr(env, 3), 52 ppc_dump_gpr(env, 4), ppc_dump_gpr(env, 5), 53 ppc_dump_gpr(env, 6), ppc_dump_gpr(env, 7), 54 ppc_dump_gpr(env, 8), env->nip); 55 } 56 57 static inline void dump_hcall(CPUPPCState *env) 58 { 59 qemu_log_mask(CPU_LOG_INT, "hypercall r3=%016" PRIx64 60 " r4=%016" PRIx64 " r5=%016" PRIx64 " r6=%016" PRIx64 61 " r7=%016" PRIx64 " r8=%016" PRIx64 " r9=%016" PRIx64 62 " r10=%016" PRIx64 " r11=%016" PRIx64 " r12=%016" PRIx64 63 " nip=" TARGET_FMT_lx "\n", 64 ppc_dump_gpr(env, 3), ppc_dump_gpr(env, 4), 65 ppc_dump_gpr(env, 5), ppc_dump_gpr(env, 6), 66 ppc_dump_gpr(env, 7), ppc_dump_gpr(env, 8), 67 ppc_dump_gpr(env, 9), ppc_dump_gpr(env, 10), 68 ppc_dump_gpr(env, 11), ppc_dump_gpr(env, 12), 69 env->nip); 70 } 71 72 static int powerpc_reset_wakeup(CPUState *cs, CPUPPCState *env, int excp, 73 target_ulong *msr) 74 { 75 /* We no longer are in a PM state */ 76 env->resume_as_sreset = false; 77 78 /* Pretend to be returning from doze always as we don't lose state */ 79 *msr |= SRR1_WS_NOLOSS; 80 81 /* Machine checks are sent normally */ 82 if (excp == POWERPC_EXCP_MCHECK) { 83 return excp; 84 } 85 switch (excp) { 86 case POWERPC_EXCP_RESET: 87 *msr |= SRR1_WAKERESET; 88 break; 89 case POWERPC_EXCP_EXTERNAL: 90 *msr |= SRR1_WAKEEE; 91 break; 92 case POWERPC_EXCP_DECR: 93 *msr |= SRR1_WAKEDEC; 94 break; 95 case POWERPC_EXCP_SDOOR: 96 *msr |= SRR1_WAKEDBELL; 97 break; 98 case POWERPC_EXCP_SDOOR_HV: 99 *msr |= SRR1_WAKEHDBELL; 100 break; 101 case POWERPC_EXCP_HV_MAINT: 102 *msr |= SRR1_WAKEHMI; 103 break; 104 case POWERPC_EXCP_HVIRT: 105 *msr |= SRR1_WAKEHVI; 106 break; 107 default: 108 cpu_abort(cs, "Unsupported exception %d in Power Save mode\n", 109 excp); 110 } 111 return POWERPC_EXCP_RESET; 112 } 113 114 /* 115 * AIL - Alternate Interrupt Location, a mode that allows interrupts to be 116 * taken with the MMU on, and which uses an alternate location (e.g., so the 117 * kernel/hv can map the vectors there with an effective address). 118 * 119 * An interrupt is considered to be taken "with AIL" or "AIL applies" if they 120 * are delivered in this way. AIL requires the LPCR to be set to enable this 121 * mode, and then a number of conditions have to be true for AIL to apply. 122 * 123 * First of all, SRESET, MCE, and HMI are always delivered without AIL, because 124 * they specifically want to be in real mode (e.g., the MCE might be signaling 125 * a SLB multi-hit which requires SLB flush before the MMU can be enabled). 126 * 127 * After that, behaviour depends on the current MSR[IR], MSR[DR], MSR[HV], 128 * whether or not the interrupt changes MSR[HV] from 0 to 1, and the current 129 * radix mode (LPCR[HR]). 130 * 131 * POWER8, POWER9 with LPCR[HR]=0 132 * | LPCR[AIL] | MSR[IR||DR] | MSR[HV] | new MSR[HV] | AIL | 133 * +-----------+-------------+---------+-------------+-----+ 134 * | a | 00/01/10 | x | x | 0 | 135 * | a | 11 | 0 | 1 | 0 | 136 * | a | 11 | 1 | 1 | a | 137 * | a | 11 | 0 | 0 | a | 138 * +-------------------------------------------------------+ 139 * 140 * POWER9 with LPCR[HR]=1 141 * | LPCR[AIL] | MSR[IR||DR] | MSR[HV] | new MSR[HV] | AIL | 142 * +-----------+-------------+---------+-------------+-----+ 143 * | a | 00/01/10 | x | x | 0 | 144 * | a | 11 | x | x | a | 145 * +-------------------------------------------------------+ 146 * 147 * The difference with POWER9 being that MSR[HV] 0->1 interrupts can be sent to 148 * the hypervisor in AIL mode if the guest is radix. This is good for 149 * performance but allows the guest to influence the AIL of hypervisor 150 * interrupts using its MSR, and also the hypervisor must disallow guest 151 * interrupts (MSR[HV] 0->0) from using AIL if the hypervisor does not want to 152 * use AIL for its MSR[HV] 0->1 interrupts. 153 * 154 * POWER10 addresses those issues with a new LPCR[HAIL] bit that is applied to 155 * interrupts that begin execution with MSR[HV]=1 (so both MSR[HV] 0->1 and 156 * MSR[HV] 1->1). 157 * 158 * HAIL=1 is equivalent to AIL=3, for interrupts delivered with MSR[HV]=1. 159 * 160 * POWER10 behaviour is 161 * | LPCR[AIL] | LPCR[HAIL] | MSR[IR||DR] | MSR[HV] | new MSR[HV] | AIL | 162 * +-----------+------------+-------------+---------+-------------+-----+ 163 * | a | h | 00/01/10 | 0 | 0 | 0 | 164 * | a | h | 11 | 0 | 0 | a | 165 * | a | h | x | 0 | 1 | h | 166 * | a | h | 00/01/10 | 1 | 1 | 0 | 167 * | a | h | 11 | 1 | 1 | h | 168 * +--------------------------------------------------------------------+ 169 */ 170 static inline void ppc_excp_apply_ail(PowerPCCPU *cpu, int excp_model, int excp, 171 target_ulong msr, 172 target_ulong *new_msr, 173 target_ulong *vector) 174 { 175 #if defined(TARGET_PPC64) 176 CPUPPCState *env = &cpu->env; 177 bool mmu_all_on = ((msr >> MSR_IR) & 1) && ((msr >> MSR_DR) & 1); 178 bool hv_escalation = !(msr & MSR_HVB) && (*new_msr & MSR_HVB); 179 int ail = 0; 180 181 if (excp == POWERPC_EXCP_MCHECK || 182 excp == POWERPC_EXCP_RESET || 183 excp == POWERPC_EXCP_HV_MAINT) { 184 /* SRESET, MCE, HMI never apply AIL */ 185 return; 186 } 187 188 if (excp_model == POWERPC_EXCP_POWER8 || 189 excp_model == POWERPC_EXCP_POWER9) { 190 if (!mmu_all_on) { 191 /* AIL only works if MSR[IR] and MSR[DR] are both enabled. */ 192 return; 193 } 194 if (hv_escalation && !(env->spr[SPR_LPCR] & LPCR_HR)) { 195 /* 196 * AIL does not work if there is a MSR[HV] 0->1 transition and the 197 * partition is in HPT mode. For radix guests, such interrupts are 198 * allowed to be delivered to the hypervisor in ail mode. 199 */ 200 return; 201 } 202 203 ail = (env->spr[SPR_LPCR] & LPCR_AIL) >> LPCR_AIL_SHIFT; 204 if (ail == 0) { 205 return; 206 } 207 if (ail == 1) { 208 /* AIL=1 is reserved, treat it like AIL=0 */ 209 return; 210 } 211 212 } else if (excp_model == POWERPC_EXCP_POWER10) { 213 if (!mmu_all_on && !hv_escalation) { 214 /* 215 * AIL works for HV interrupts even with guest MSR[IR/DR] disabled. 216 * Guest->guest and HV->HV interrupts do require MMU on. 217 */ 218 return; 219 } 220 221 if (*new_msr & MSR_HVB) { 222 if (!(env->spr[SPR_LPCR] & LPCR_HAIL)) { 223 /* HV interrupts depend on LPCR[HAIL] */ 224 return; 225 } 226 ail = 3; /* HAIL=1 gives AIL=3 behaviour for HV interrupts */ 227 } else { 228 ail = (env->spr[SPR_LPCR] & LPCR_AIL) >> LPCR_AIL_SHIFT; 229 } 230 if (ail == 0) { 231 return; 232 } 233 if (ail == 1 || ail == 2) { 234 /* AIL=1 and AIL=2 are reserved, treat them like AIL=0 */ 235 return; 236 } 237 } else { 238 /* Other processors do not support AIL */ 239 return; 240 } 241 242 /* 243 * AIL applies, so the new MSR gets IR and DR set, and an offset applied 244 * to the new IP. 245 */ 246 *new_msr |= (1 << MSR_IR) | (1 << MSR_DR); 247 248 if (excp != POWERPC_EXCP_SYSCALL_VECTORED) { 249 if (ail == 2) { 250 *vector |= 0x0000000000018000ull; 251 } else if (ail == 3) { 252 *vector |= 0xc000000000004000ull; 253 } 254 } else { 255 /* 256 * scv AIL is a little different. AIL=2 does not change the address, 257 * only the MSR. AIL=3 replaces the 0x17000 base with 0xc...3000. 258 */ 259 if (ail == 3) { 260 *vector &= ~0x0000000000017000ull; /* Un-apply the base offset */ 261 *vector |= 0xc000000000003000ull; /* Apply scv's AIL=3 offset */ 262 } 263 } 264 #endif 265 } 266 267 static inline void powerpc_set_excp_state(PowerPCCPU *cpu, 268 target_ulong vector, target_ulong msr) 269 { 270 CPUState *cs = CPU(cpu); 271 CPUPPCState *env = &cpu->env; 272 273 /* 274 * We don't use hreg_store_msr here as already have treated any 275 * special case that could occur. Just store MSR and update hflags 276 * 277 * Note: We *MUST* not use hreg_store_msr() as-is anyway because it 278 * will prevent setting of the HV bit which some exceptions might need 279 * to do. 280 */ 281 env->msr = msr & env->msr_mask; 282 hreg_compute_hflags(env); 283 env->nip = vector; 284 /* Reset exception state */ 285 cs->exception_index = POWERPC_EXCP_NONE; 286 env->error_code = 0; 287 288 /* Reset the reservation */ 289 env->reserve_addr = -1; 290 291 /* 292 * Any interrupt is context synchronizing, check if TCG TLB needs 293 * a delayed flush on ppc64 294 */ 295 check_tlb_flush(env, false); 296 } 297 298 /* 299 * Note that this function should be greatly optimized when called 300 * with a constant excp, from ppc_hw_interrupt 301 */ 302 static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) 303 { 304 CPUState *cs = CPU(cpu); 305 CPUPPCState *env = &cpu->env; 306 target_ulong msr, new_msr, vector; 307 int srr0, srr1, asrr0, asrr1, lev = -1; 308 309 qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx 310 " => %08x (%02x)\n", env->nip, excp, env->error_code); 311 312 /* new srr1 value excluding must-be-zero bits */ 313 if (excp_model == POWERPC_EXCP_BOOKE) { 314 msr = env->msr; 315 } else { 316 msr = env->msr & ~0x783f0000ULL; 317 } 318 319 /* 320 * new interrupt handler msr preserves existing HV and ME unless 321 * explicitly overriden 322 */ 323 new_msr = env->msr & (((target_ulong)1 << MSR_ME) | MSR_HVB); 324 325 /* target registers */ 326 srr0 = SPR_SRR0; 327 srr1 = SPR_SRR1; 328 asrr0 = -1; 329 asrr1 = -1; 330 331 /* 332 * check for special resume at 0x100 from doze/nap/sleep/winkle on 333 * P7/P8/P9 334 */ 335 if (env->resume_as_sreset) { 336 excp = powerpc_reset_wakeup(cs, env, excp, &msr); 337 } 338 339 /* 340 * Hypervisor emulation assistance interrupt only exists on server 341 * arch 2.05 server or later. We also don't want to generate it if 342 * we don't have HVB in msr_mask (PAPR mode). 343 */ 344 if (excp == POWERPC_EXCP_HV_EMU 345 #if defined(TARGET_PPC64) 346 && !(mmu_is_64bit(env->mmu_model) && (env->msr_mask & MSR_HVB)) 347 #endif /* defined(TARGET_PPC64) */ 348 349 ) { 350 excp = POWERPC_EXCP_PROGRAM; 351 } 352 353 switch (excp) { 354 case POWERPC_EXCP_NONE: 355 /* Should never happen */ 356 return; 357 case POWERPC_EXCP_CRITICAL: /* Critical input */ 358 switch (excp_model) { 359 case POWERPC_EXCP_40x: 360 srr0 = SPR_40x_SRR2; 361 srr1 = SPR_40x_SRR3; 362 break; 363 case POWERPC_EXCP_BOOKE: 364 srr0 = SPR_BOOKE_CSRR0; 365 srr1 = SPR_BOOKE_CSRR1; 366 break; 367 case POWERPC_EXCP_G2: 368 break; 369 default: 370 goto excp_invalid; 371 } 372 break; 373 case POWERPC_EXCP_MCHECK: /* Machine check exception */ 374 if (msr_me == 0) { 375 /* 376 * Machine check exception is not enabled. Enter 377 * checkstop state. 378 */ 379 fprintf(stderr, "Machine check while not allowed. " 380 "Entering checkstop state\n"); 381 if (qemu_log_separate()) { 382 qemu_log("Machine check while not allowed. " 383 "Entering checkstop state\n"); 384 } 385 cs->halted = 1; 386 cpu_interrupt_exittb(cs); 387 } 388 if (env->msr_mask & MSR_HVB) { 389 /* 390 * ISA specifies HV, but can be delivered to guest with HV 391 * clear (e.g., see FWNMI in PAPR). 392 */ 393 new_msr |= (target_ulong)MSR_HVB; 394 } 395 396 /* machine check exceptions don't have ME set */ 397 new_msr &= ~((target_ulong)1 << MSR_ME); 398 399 /* XXX: should also have something loaded in DAR / DSISR */ 400 switch (excp_model) { 401 case POWERPC_EXCP_40x: 402 srr0 = SPR_40x_SRR2; 403 srr1 = SPR_40x_SRR3; 404 break; 405 case POWERPC_EXCP_BOOKE: 406 /* FIXME: choose one or the other based on CPU type */ 407 srr0 = SPR_BOOKE_MCSRR0; 408 srr1 = SPR_BOOKE_MCSRR1; 409 asrr0 = SPR_BOOKE_CSRR0; 410 asrr1 = SPR_BOOKE_CSRR1; 411 break; 412 default: 413 break; 414 } 415 break; 416 case POWERPC_EXCP_DSI: /* Data storage exception */ 417 LOG_EXCP("DSI exception: DSISR=" TARGET_FMT_lx" DAR=" TARGET_FMT_lx 418 "\n", env->spr[SPR_DSISR], env->spr[SPR_DAR]); 419 break; 420 case POWERPC_EXCP_ISI: /* Instruction storage exception */ 421 LOG_EXCP("ISI exception: msr=" TARGET_FMT_lx ", nip=" TARGET_FMT_lx 422 "\n", msr, env->nip); 423 msr |= env->error_code; 424 break; 425 case POWERPC_EXCP_EXTERNAL: /* External input */ 426 { 427 bool lpes0; 428 429 cs = CPU(cpu); 430 431 /* 432 * Exception targeting modifiers 433 * 434 * LPES0 is supported on POWER7/8/9 435 * LPES1 is not supported (old iSeries mode) 436 * 437 * On anything else, we behave as if LPES0 is 1 438 * (externals don't alter MSR:HV) 439 */ 440 #if defined(TARGET_PPC64) 441 if (excp_model == POWERPC_EXCP_POWER7 || 442 excp_model == POWERPC_EXCP_POWER8 || 443 excp_model == POWERPC_EXCP_POWER9 || 444 excp_model == POWERPC_EXCP_POWER10) { 445 lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0); 446 } else 447 #endif /* defined(TARGET_PPC64) */ 448 { 449 lpes0 = true; 450 } 451 452 if (!lpes0) { 453 new_msr |= (target_ulong)MSR_HVB; 454 new_msr |= env->msr & ((target_ulong)1 << MSR_RI); 455 srr0 = SPR_HSRR0; 456 srr1 = SPR_HSRR1; 457 } 458 if (env->mpic_proxy) { 459 /* IACK the IRQ on delivery */ 460 env->spr[SPR_BOOKE_EPR] = ldl_phys(cs->as, env->mpic_iack); 461 } 462 break; 463 } 464 case POWERPC_EXCP_ALIGN: /* Alignment exception */ 465 /* Get rS/rD and rA from faulting opcode */ 466 /* 467 * Note: the opcode fields will not be set properly for a 468 * direct store load/store, but nobody cares as nobody 469 * actually uses direct store segments. 470 */ 471 env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16; 472 break; 473 case POWERPC_EXCP_PROGRAM: /* Program exception */ 474 switch (env->error_code & ~0xF) { 475 case POWERPC_EXCP_FP: 476 if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) { 477 LOG_EXCP("Ignore floating point exception\n"); 478 cs->exception_index = POWERPC_EXCP_NONE; 479 env->error_code = 0; 480 return; 481 } 482 483 /* 484 * FP exceptions always have NIP pointing to the faulting 485 * instruction, so always use store_next and claim we are 486 * precise in the MSR. 487 */ 488 msr |= 0x00100000; 489 env->spr[SPR_BOOKE_ESR] = ESR_FP; 490 break; 491 case POWERPC_EXCP_INVAL: 492 LOG_EXCP("Invalid instruction at " TARGET_FMT_lx "\n", env->nip); 493 msr |= 0x00080000; 494 env->spr[SPR_BOOKE_ESR] = ESR_PIL; 495 break; 496 case POWERPC_EXCP_PRIV: 497 msr |= 0x00040000; 498 env->spr[SPR_BOOKE_ESR] = ESR_PPR; 499 break; 500 case POWERPC_EXCP_TRAP: 501 msr |= 0x00020000; 502 env->spr[SPR_BOOKE_ESR] = ESR_PTR; 503 break; 504 default: 505 /* Should never occur */ 506 cpu_abort(cs, "Invalid program exception %d. Aborting\n", 507 env->error_code); 508 break; 509 } 510 break; 511 case POWERPC_EXCP_SYSCALL: /* System call exception */ 512 lev = env->error_code; 513 514 if ((lev == 1) && cpu->vhyp) { 515 dump_hcall(env); 516 } else { 517 dump_syscall(env); 518 } 519 520 /* 521 * We need to correct the NIP which in this case is supposed 522 * to point to the next instruction 523 */ 524 env->nip += 4; 525 526 /* "PAPR mode" built-in hypercall emulation */ 527 if ((lev == 1) && cpu->vhyp) { 528 PPCVirtualHypervisorClass *vhc = 529 PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp); 530 vhc->hypercall(cpu->vhyp, cpu); 531 return; 532 } 533 if (lev == 1) { 534 new_msr |= (target_ulong)MSR_HVB; 535 } 536 break; 537 case POWERPC_EXCP_SYSCALL_VECTORED: /* scv exception */ 538 lev = env->error_code; 539 dump_syscall(env); 540 env->nip += 4; 541 new_msr |= env->msr & ((target_ulong)1 << MSR_EE); 542 new_msr |= env->msr & ((target_ulong)1 << MSR_RI); 543 break; 544 case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */ 545 case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */ 546 case POWERPC_EXCP_DECR: /* Decrementer exception */ 547 break; 548 case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt */ 549 /* FIT on 4xx */ 550 LOG_EXCP("FIT exception\n"); 551 break; 552 case POWERPC_EXCP_WDT: /* Watchdog timer interrupt */ 553 LOG_EXCP("WDT exception\n"); 554 switch (excp_model) { 555 case POWERPC_EXCP_BOOKE: 556 srr0 = SPR_BOOKE_CSRR0; 557 srr1 = SPR_BOOKE_CSRR1; 558 break; 559 default: 560 break; 561 } 562 break; 563 case POWERPC_EXCP_DTLB: /* Data TLB error */ 564 case POWERPC_EXCP_ITLB: /* Instruction TLB error */ 565 break; 566 case POWERPC_EXCP_DEBUG: /* Debug interrupt */ 567 if (env->flags & POWERPC_FLAG_DE) { 568 /* FIXME: choose one or the other based on CPU type */ 569 srr0 = SPR_BOOKE_DSRR0; 570 srr1 = SPR_BOOKE_DSRR1; 571 asrr0 = SPR_BOOKE_CSRR0; 572 asrr1 = SPR_BOOKE_CSRR1; 573 /* DBSR already modified by caller */ 574 } else { 575 cpu_abort(cs, "Debug exception triggered on unsupported model\n"); 576 } 577 break; 578 case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavailable */ 579 env->spr[SPR_BOOKE_ESR] = ESR_SPV; 580 break; 581 case POWERPC_EXCP_EFPDI: /* Embedded floating-point data interrupt */ 582 /* XXX: TODO */ 583 cpu_abort(cs, "Embedded floating point data exception " 584 "is not implemented yet !\n"); 585 env->spr[SPR_BOOKE_ESR] = ESR_SPV; 586 break; 587 case POWERPC_EXCP_EFPRI: /* Embedded floating-point round interrupt */ 588 /* XXX: TODO */ 589 cpu_abort(cs, "Embedded floating point round exception " 590 "is not implemented yet !\n"); 591 env->spr[SPR_BOOKE_ESR] = ESR_SPV; 592 break; 593 case POWERPC_EXCP_EPERFM: /* Embedded performance monitor interrupt */ 594 /* XXX: TODO */ 595 cpu_abort(cs, 596 "Performance counter exception is not implemented yet !\n"); 597 break; 598 case POWERPC_EXCP_DOORI: /* Embedded doorbell interrupt */ 599 break; 600 case POWERPC_EXCP_DOORCI: /* Embedded doorbell critical interrupt */ 601 srr0 = SPR_BOOKE_CSRR0; 602 srr1 = SPR_BOOKE_CSRR1; 603 break; 604 case POWERPC_EXCP_RESET: /* System reset exception */ 605 /* A power-saving exception sets ME, otherwise it is unchanged */ 606 if (msr_pow) { 607 /* indicate that we resumed from power save mode */ 608 msr |= 0x10000; 609 new_msr |= ((target_ulong)1 << MSR_ME); 610 } 611 if (env->msr_mask & MSR_HVB) { 612 /* 613 * ISA specifies HV, but can be delivered to guest with HV 614 * clear (e.g., see FWNMI in PAPR, NMI injection in QEMU). 615 */ 616 new_msr |= (target_ulong)MSR_HVB; 617 } else { 618 if (msr_pow) { 619 cpu_abort(cs, "Trying to deliver power-saving system reset " 620 "exception %d with no HV support\n", excp); 621 } 622 } 623 break; 624 case POWERPC_EXCP_DSEG: /* Data segment exception */ 625 case POWERPC_EXCP_ISEG: /* Instruction segment exception */ 626 case POWERPC_EXCP_TRACE: /* Trace exception */ 627 break; 628 case POWERPC_EXCP_HISI: /* Hypervisor instruction storage exception */ 629 msr |= env->error_code; 630 /* fall through */ 631 case POWERPC_EXCP_HDECR: /* Hypervisor decrementer exception */ 632 case POWERPC_EXCP_HDSI: /* Hypervisor data storage exception */ 633 case POWERPC_EXCP_HDSEG: /* Hypervisor data segment exception */ 634 case POWERPC_EXCP_HISEG: /* Hypervisor instruction segment exception */ 635 case POWERPC_EXCP_SDOOR_HV: /* Hypervisor Doorbell interrupt */ 636 case POWERPC_EXCP_HV_EMU: 637 case POWERPC_EXCP_HVIRT: /* Hypervisor virtualization */ 638 srr0 = SPR_HSRR0; 639 srr1 = SPR_HSRR1; 640 new_msr |= (target_ulong)MSR_HVB; 641 new_msr |= env->msr & ((target_ulong)1 << MSR_RI); 642 break; 643 case POWERPC_EXCP_VPU: /* Vector unavailable exception */ 644 case POWERPC_EXCP_VSXU: /* VSX unavailable exception */ 645 case POWERPC_EXCP_FU: /* Facility unavailable exception */ 646 #ifdef TARGET_PPC64 647 env->spr[SPR_FSCR] |= ((target_ulong)env->error_code << 56); 648 #endif 649 break; 650 case POWERPC_EXCP_HV_FU: /* Hypervisor Facility Unavailable Exception */ 651 #ifdef TARGET_PPC64 652 env->spr[SPR_HFSCR] |= ((target_ulong)env->error_code << FSCR_IC_POS); 653 srr0 = SPR_HSRR0; 654 srr1 = SPR_HSRR1; 655 new_msr |= (target_ulong)MSR_HVB; 656 new_msr |= env->msr & ((target_ulong)1 << MSR_RI); 657 #endif 658 break; 659 case POWERPC_EXCP_PIT: /* Programmable interval timer interrupt */ 660 LOG_EXCP("PIT exception\n"); 661 break; 662 case POWERPC_EXCP_IO: /* IO error exception */ 663 /* XXX: TODO */ 664 cpu_abort(cs, "601 IO error exception is not implemented yet !\n"); 665 break; 666 case POWERPC_EXCP_RUNM: /* Run mode exception */ 667 /* XXX: TODO */ 668 cpu_abort(cs, "601 run mode exception is not implemented yet !\n"); 669 break; 670 case POWERPC_EXCP_EMUL: /* Emulation trap exception */ 671 /* XXX: TODO */ 672 cpu_abort(cs, "602 emulation trap exception " 673 "is not implemented yet !\n"); 674 break; 675 case POWERPC_EXCP_IFTLB: /* Instruction fetch TLB error */ 676 case POWERPC_EXCP_DLTLB: /* Data load TLB miss */ 677 case POWERPC_EXCP_DSTLB: /* Data store TLB miss */ 678 switch (excp_model) { 679 case POWERPC_EXCP_602: 680 case POWERPC_EXCP_603: 681 case POWERPC_EXCP_603E: 682 case POWERPC_EXCP_G2: 683 /* Swap temporary saved registers with GPRs */ 684 if (!(new_msr & ((target_ulong)1 << MSR_TGPR))) { 685 new_msr |= (target_ulong)1 << MSR_TGPR; 686 hreg_swap_gpr_tgpr(env); 687 } 688 /* fall through */ 689 case POWERPC_EXCP_7x5: 690 #if defined(DEBUG_SOFTWARE_TLB) 691 if (qemu_log_enabled()) { 692 const char *es; 693 target_ulong *miss, *cmp; 694 int en; 695 696 if (excp == POWERPC_EXCP_IFTLB) { 697 es = "I"; 698 en = 'I'; 699 miss = &env->spr[SPR_IMISS]; 700 cmp = &env->spr[SPR_ICMP]; 701 } else { 702 if (excp == POWERPC_EXCP_DLTLB) { 703 es = "DL"; 704 } else { 705 es = "DS"; 706 } 707 en = 'D'; 708 miss = &env->spr[SPR_DMISS]; 709 cmp = &env->spr[SPR_DCMP]; 710 } 711 qemu_log("6xx %sTLB miss: %cM " TARGET_FMT_lx " %cC " 712 TARGET_FMT_lx " H1 " TARGET_FMT_lx " H2 " 713 TARGET_FMT_lx " %08x\n", es, en, *miss, en, *cmp, 714 env->spr[SPR_HASH1], env->spr[SPR_HASH2], 715 env->error_code); 716 } 717 #endif 718 msr |= env->crf[0] << 28; 719 msr |= env->error_code; /* key, D/I, S/L bits */ 720 /* Set way using a LRU mechanism */ 721 msr |= ((env->last_way + 1) & (env->nb_ways - 1)) << 17; 722 break; 723 case POWERPC_EXCP_74xx: 724 #if defined(DEBUG_SOFTWARE_TLB) 725 if (qemu_log_enabled()) { 726 const char *es; 727 target_ulong *miss, *cmp; 728 int en; 729 730 if (excp == POWERPC_EXCP_IFTLB) { 731 es = "I"; 732 en = 'I'; 733 miss = &env->spr[SPR_TLBMISS]; 734 cmp = &env->spr[SPR_PTEHI]; 735 } else { 736 if (excp == POWERPC_EXCP_DLTLB) { 737 es = "DL"; 738 } else { 739 es = "DS"; 740 } 741 en = 'D'; 742 miss = &env->spr[SPR_TLBMISS]; 743 cmp = &env->spr[SPR_PTEHI]; 744 } 745 qemu_log("74xx %sTLB miss: %cM " TARGET_FMT_lx " %cC " 746 TARGET_FMT_lx " %08x\n", es, en, *miss, en, *cmp, 747 env->error_code); 748 } 749 #endif 750 msr |= env->error_code; /* key bit */ 751 break; 752 default: 753 cpu_abort(cs, "Invalid TLB miss exception\n"); 754 break; 755 } 756 break; 757 case POWERPC_EXCP_FPA: /* Floating-point assist exception */ 758 /* XXX: TODO */ 759 cpu_abort(cs, "Floating point assist exception " 760 "is not implemented yet !\n"); 761 break; 762 case POWERPC_EXCP_DABR: /* Data address breakpoint */ 763 /* XXX: TODO */ 764 cpu_abort(cs, "DABR exception is not implemented yet !\n"); 765 break; 766 case POWERPC_EXCP_IABR: /* Instruction address breakpoint */ 767 /* XXX: TODO */ 768 cpu_abort(cs, "IABR exception is not implemented yet !\n"); 769 break; 770 case POWERPC_EXCP_SMI: /* System management interrupt */ 771 /* XXX: TODO */ 772 cpu_abort(cs, "SMI exception is not implemented yet !\n"); 773 break; 774 case POWERPC_EXCP_THERM: /* Thermal interrupt */ 775 /* XXX: TODO */ 776 cpu_abort(cs, "Thermal management exception " 777 "is not implemented yet !\n"); 778 break; 779 case POWERPC_EXCP_PERFM: /* Embedded performance monitor interrupt */ 780 /* XXX: TODO */ 781 cpu_abort(cs, 782 "Performance counter exception is not implemented yet !\n"); 783 break; 784 case POWERPC_EXCP_VPUA: /* Vector assist exception */ 785 /* XXX: TODO */ 786 cpu_abort(cs, "VPU assist exception is not implemented yet !\n"); 787 break; 788 case POWERPC_EXCP_SOFTP: /* Soft patch exception */ 789 /* XXX: TODO */ 790 cpu_abort(cs, 791 "970 soft-patch exception is not implemented yet !\n"); 792 break; 793 case POWERPC_EXCP_MAINT: /* Maintenance exception */ 794 /* XXX: TODO */ 795 cpu_abort(cs, 796 "970 maintenance exception is not implemented yet !\n"); 797 break; 798 case POWERPC_EXCP_MEXTBR: /* Maskable external breakpoint */ 799 /* XXX: TODO */ 800 cpu_abort(cs, "Maskable external exception " 801 "is not implemented yet !\n"); 802 break; 803 case POWERPC_EXCP_NMEXTBR: /* Non maskable external breakpoint */ 804 /* XXX: TODO */ 805 cpu_abort(cs, "Non maskable external exception " 806 "is not implemented yet !\n"); 807 break; 808 default: 809 excp_invalid: 810 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); 811 break; 812 } 813 814 /* Sanity check */ 815 if (!(env->msr_mask & MSR_HVB)) { 816 if (new_msr & MSR_HVB) { 817 cpu_abort(cs, "Trying to deliver HV exception (MSR) %d with " 818 "no HV support\n", excp); 819 } 820 if (srr0 == SPR_HSRR0) { 821 cpu_abort(cs, "Trying to deliver HV exception (HSRR) %d with " 822 "no HV support\n", excp); 823 } 824 } 825 826 /* 827 * Sort out endianness of interrupt, this differs depending on the 828 * CPU, the HV mode, etc... 829 */ 830 #ifdef TARGET_PPC64 831 if (excp_model == POWERPC_EXCP_POWER7) { 832 if (!(new_msr & MSR_HVB) && (env->spr[SPR_LPCR] & LPCR_ILE)) { 833 new_msr |= (target_ulong)1 << MSR_LE; 834 } 835 } else if (excp_model == POWERPC_EXCP_POWER8) { 836 if (new_msr & MSR_HVB) { 837 if (env->spr[SPR_HID0] & HID0_HILE) { 838 new_msr |= (target_ulong)1 << MSR_LE; 839 } 840 } else if (env->spr[SPR_LPCR] & LPCR_ILE) { 841 new_msr |= (target_ulong)1 << MSR_LE; 842 } 843 } else if (excp_model == POWERPC_EXCP_POWER9 || 844 excp_model == POWERPC_EXCP_POWER10) { 845 if (new_msr & MSR_HVB) { 846 if (env->spr[SPR_HID0] & HID0_POWER9_HILE) { 847 new_msr |= (target_ulong)1 << MSR_LE; 848 } 849 } else if (env->spr[SPR_LPCR] & LPCR_ILE) { 850 new_msr |= (target_ulong)1 << MSR_LE; 851 } 852 } else if (msr_ile) { 853 new_msr |= (target_ulong)1 << MSR_LE; 854 } 855 #else 856 if (msr_ile) { 857 new_msr |= (target_ulong)1 << MSR_LE; 858 } 859 #endif 860 861 vector = env->excp_vectors[excp]; 862 if (vector == (target_ulong)-1ULL) { 863 cpu_abort(cs, "Raised an exception without defined vector %d\n", 864 excp); 865 } 866 867 vector |= env->excp_prefix; 868 869 /* If any alternate SRR register are defined, duplicate saved values */ 870 if (asrr0 != -1) { 871 env->spr[asrr0] = env->nip; 872 } 873 if (asrr1 != -1) { 874 env->spr[asrr1] = msr; 875 } 876 877 #if defined(TARGET_PPC64) 878 if (excp_model == POWERPC_EXCP_BOOKE) { 879 if (env->spr[SPR_BOOKE_EPCR] & EPCR_ICM) { 880 /* Cat.64-bit: EPCR.ICM is copied to MSR.CM */ 881 new_msr |= (target_ulong)1 << MSR_CM; 882 } else { 883 vector = (uint32_t)vector; 884 } 885 } else { 886 if (!msr_isf && !mmu_is_64bit(env->mmu_model)) { 887 vector = (uint32_t)vector; 888 } else { 889 new_msr |= (target_ulong)1 << MSR_SF; 890 } 891 } 892 #endif 893 894 if (excp != POWERPC_EXCP_SYSCALL_VECTORED) { 895 /* Save PC */ 896 env->spr[srr0] = env->nip; 897 898 /* Save MSR */ 899 env->spr[srr1] = msr; 900 901 #if defined(TARGET_PPC64) 902 } else { 903 vector += lev * 0x20; 904 905 env->lr = env->nip; 906 env->ctr = msr; 907 #endif 908 } 909 910 /* This can update new_msr and vector if AIL applies */ 911 ppc_excp_apply_ail(cpu, excp_model, excp, msr, &new_msr, &vector); 912 913 powerpc_set_excp_state(cpu, vector, new_msr); 914 } 915 916 void ppc_cpu_do_interrupt(CPUState *cs) 917 { 918 PowerPCCPU *cpu = POWERPC_CPU(cs); 919 CPUPPCState *env = &cpu->env; 920 921 powerpc_excp(cpu, env->excp_model, cs->exception_index); 922 } 923 924 static void ppc_hw_interrupt(CPUPPCState *env) 925 { 926 PowerPCCPU *cpu = env_archcpu(env); 927 bool async_deliver; 928 929 /* External reset */ 930 if (env->pending_interrupts & (1 << PPC_INTERRUPT_RESET)) { 931 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_RESET); 932 powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_RESET); 933 return; 934 } 935 /* Machine check exception */ 936 if (env->pending_interrupts & (1 << PPC_INTERRUPT_MCK)) { 937 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_MCK); 938 powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_MCHECK); 939 return; 940 } 941 #if 0 /* TODO */ 942 /* External debug exception */ 943 if (env->pending_interrupts & (1 << PPC_INTERRUPT_DEBUG)) { 944 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DEBUG); 945 powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DEBUG); 946 return; 947 } 948 #endif 949 950 /* 951 * For interrupts that gate on MSR:EE, we need to do something a 952 * bit more subtle, as we need to let them through even when EE is 953 * clear when coming out of some power management states (in order 954 * for them to become a 0x100). 955 */ 956 async_deliver = (msr_ee != 0) || env->resume_as_sreset; 957 958 /* Hypervisor decrementer exception */ 959 if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDECR)) { 960 /* LPCR will be clear when not supported so this will work */ 961 bool hdice = !!(env->spr[SPR_LPCR] & LPCR_HDICE); 962 if ((async_deliver || msr_hv == 0) && hdice) { 963 /* HDEC clears on delivery */ 964 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDECR); 965 powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_HDECR); 966 return; 967 } 968 } 969 970 /* Hypervisor virtualization interrupt */ 971 if (env->pending_interrupts & (1 << PPC_INTERRUPT_HVIRT)) { 972 /* LPCR will be clear when not supported so this will work */ 973 bool hvice = !!(env->spr[SPR_LPCR] & LPCR_HVICE); 974 if ((async_deliver || msr_hv == 0) && hvice) { 975 powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_HVIRT); 976 return; 977 } 978 } 979 980 /* External interrupt can ignore MSR:EE under some circumstances */ 981 if (env->pending_interrupts & (1 << PPC_INTERRUPT_EXT)) { 982 bool lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0); 983 bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC); 984 /* HEIC blocks delivery to the hypervisor */ 985 if ((async_deliver && !(heic && msr_hv && !msr_pr)) || 986 (env->has_hv_mode && msr_hv == 0 && !lpes0)) { 987 powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_EXTERNAL); 988 return; 989 } 990 } 991 if (msr_ce != 0) { 992 /* External critical interrupt */ 993 if (env->pending_interrupts & (1 << PPC_INTERRUPT_CEXT)) { 994 powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_CRITICAL); 995 return; 996 } 997 } 998 if (async_deliver != 0) { 999 /* Watchdog timer on embedded PowerPC */ 1000 if (env->pending_interrupts & (1 << PPC_INTERRUPT_WDT)) { 1001 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_WDT); 1002 powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_WDT); 1003 return; 1004 } 1005 if (env->pending_interrupts & (1 << PPC_INTERRUPT_CDOORBELL)) { 1006 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_CDOORBELL); 1007 powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DOORCI); 1008 return; 1009 } 1010 /* Fixed interval timer on embedded PowerPC */ 1011 if (env->pending_interrupts & (1 << PPC_INTERRUPT_FIT)) { 1012 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_FIT); 1013 powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_FIT); 1014 return; 1015 } 1016 /* Programmable interval timer on embedded PowerPC */ 1017 if (env->pending_interrupts & (1 << PPC_INTERRUPT_PIT)) { 1018 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PIT); 1019 powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_PIT); 1020 return; 1021 } 1022 /* Decrementer exception */ 1023 if (env->pending_interrupts & (1 << PPC_INTERRUPT_DECR)) { 1024 if (ppc_decr_clear_on_delivery(env)) { 1025 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DECR); 1026 } 1027 powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DECR); 1028 return; 1029 } 1030 if (env->pending_interrupts & (1 << PPC_INTERRUPT_DOORBELL)) { 1031 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL); 1032 if (is_book3s_arch2x(env)) { 1033 powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_SDOOR); 1034 } else { 1035 powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DOORI); 1036 } 1037 return; 1038 } 1039 if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDOORBELL)) { 1040 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDOORBELL); 1041 powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_SDOOR_HV); 1042 return; 1043 } 1044 if (env->pending_interrupts & (1 << PPC_INTERRUPT_PERFM)) { 1045 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PERFM); 1046 powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_PERFM); 1047 return; 1048 } 1049 /* Thermal interrupt */ 1050 if (env->pending_interrupts & (1 << PPC_INTERRUPT_THERM)) { 1051 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_THERM); 1052 powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_THERM); 1053 return; 1054 } 1055 } 1056 1057 if (env->resume_as_sreset) { 1058 /* 1059 * This is a bug ! It means that has_work took us out of halt without 1060 * anything to deliver while in a PM state that requires getting 1061 * out via a 0x100 1062 * 1063 * This means we will incorrectly execute past the power management 1064 * instruction instead of triggering a reset. 1065 * 1066 * It generally means a discrepancy between the wakeup conditions in the 1067 * processor has_work implementation and the logic in this function. 1068 */ 1069 cpu_abort(env_cpu(env), 1070 "Wakeup from PM state but interrupt Undelivered"); 1071 } 1072 } 1073 1074 void ppc_cpu_do_system_reset(CPUState *cs) 1075 { 1076 PowerPCCPU *cpu = POWERPC_CPU(cs); 1077 CPUPPCState *env = &cpu->env; 1078 1079 powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_RESET); 1080 } 1081 1082 void ppc_cpu_do_fwnmi_machine_check(CPUState *cs, target_ulong vector) 1083 { 1084 PowerPCCPU *cpu = POWERPC_CPU(cs); 1085 CPUPPCState *env = &cpu->env; 1086 target_ulong msr = 0; 1087 1088 /* 1089 * Set MSR and NIP for the handler, SRR0/1, DAR and DSISR have already 1090 * been set by KVM. 1091 */ 1092 msr = (1ULL << MSR_ME); 1093 msr |= env->msr & (1ULL << MSR_SF); 1094 if (ppc_interrupts_little_endian(cpu)) { 1095 msr |= (1ULL << MSR_LE); 1096 } 1097 1098 powerpc_set_excp_state(cpu, vector, msr); 1099 } 1100 1101 bool ppc_cpu_exec_interrupt(CPUState *cs, int interrupt_request) 1102 { 1103 PowerPCCPU *cpu = POWERPC_CPU(cs); 1104 CPUPPCState *env = &cpu->env; 1105 1106 if (interrupt_request & CPU_INTERRUPT_HARD) { 1107 ppc_hw_interrupt(env); 1108 if (env->pending_interrupts == 0) { 1109 cs->interrupt_request &= ~CPU_INTERRUPT_HARD; 1110 } 1111 return true; 1112 } 1113 return false; 1114 } 1115 1116 #endif /* !CONFIG_USER_ONLY */ 1117 1118 #if defined(DEBUG_OP) 1119 static void cpu_dump_rfi(target_ulong RA, target_ulong msr) 1120 { 1121 qemu_log("Return from exception at " TARGET_FMT_lx " with flags " 1122 TARGET_FMT_lx "\n", RA, msr); 1123 } 1124 #endif 1125 1126 /*****************************************************************************/ 1127 /* Exceptions processing helpers */ 1128 1129 void raise_exception_err_ra(CPUPPCState *env, uint32_t exception, 1130 uint32_t error_code, uintptr_t raddr) 1131 { 1132 CPUState *cs = env_cpu(env); 1133 1134 cs->exception_index = exception; 1135 env->error_code = error_code; 1136 cpu_loop_exit_restore(cs, raddr); 1137 } 1138 1139 void raise_exception_err(CPUPPCState *env, uint32_t exception, 1140 uint32_t error_code) 1141 { 1142 raise_exception_err_ra(env, exception, error_code, 0); 1143 } 1144 1145 void raise_exception(CPUPPCState *env, uint32_t exception) 1146 { 1147 raise_exception_err_ra(env, exception, 0, 0); 1148 } 1149 1150 void raise_exception_ra(CPUPPCState *env, uint32_t exception, 1151 uintptr_t raddr) 1152 { 1153 raise_exception_err_ra(env, exception, 0, raddr); 1154 } 1155 1156 #ifdef CONFIG_TCG 1157 void helper_raise_exception_err(CPUPPCState *env, uint32_t exception, 1158 uint32_t error_code) 1159 { 1160 raise_exception_err_ra(env, exception, error_code, 0); 1161 } 1162 1163 void helper_raise_exception(CPUPPCState *env, uint32_t exception) 1164 { 1165 raise_exception_err_ra(env, exception, 0, 0); 1166 } 1167 #endif 1168 1169 #if !defined(CONFIG_USER_ONLY) 1170 #ifdef CONFIG_TCG 1171 void helper_store_msr(CPUPPCState *env, target_ulong val) 1172 { 1173 uint32_t excp = hreg_store_msr(env, val, 0); 1174 1175 if (excp != 0) { 1176 CPUState *cs = env_cpu(env); 1177 cpu_interrupt_exittb(cs); 1178 raise_exception(env, excp); 1179 } 1180 } 1181 1182 #if defined(TARGET_PPC64) 1183 void helper_scv(CPUPPCState *env, uint32_t lev) 1184 { 1185 if (env->spr[SPR_FSCR] & (1ull << FSCR_SCV)) { 1186 raise_exception_err(env, POWERPC_EXCP_SYSCALL_VECTORED, lev); 1187 } else { 1188 raise_exception_err(env, POWERPC_EXCP_FU, FSCR_IC_SCV); 1189 } 1190 } 1191 1192 void helper_pminsn(CPUPPCState *env, powerpc_pm_insn_t insn) 1193 { 1194 CPUState *cs; 1195 1196 cs = env_cpu(env); 1197 cs->halted = 1; 1198 1199 /* Condition for waking up at 0x100 */ 1200 env->resume_as_sreset = (insn != PPC_PM_STOP) || 1201 (env->spr[SPR_PSSCR] & PSSCR_EC); 1202 } 1203 #endif /* defined(TARGET_PPC64) */ 1204 #endif /* CONFIG_TCG */ 1205 1206 static inline void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr) 1207 { 1208 CPUState *cs = env_cpu(env); 1209 1210 /* MSR:POW cannot be set by any form of rfi */ 1211 msr &= ~(1ULL << MSR_POW); 1212 1213 #if defined(TARGET_PPC64) 1214 /* Switching to 32-bit ? Crop the nip */ 1215 if (!msr_is_64bit(env, msr)) { 1216 nip = (uint32_t)nip; 1217 } 1218 #else 1219 nip = (uint32_t)nip; 1220 #endif 1221 /* XXX: beware: this is false if VLE is supported */ 1222 env->nip = nip & ~((target_ulong)0x00000003); 1223 hreg_store_msr(env, msr, 1); 1224 #if defined(DEBUG_OP) 1225 cpu_dump_rfi(env->nip, env->msr); 1226 #endif 1227 /* 1228 * No need to raise an exception here, as rfi is always the last 1229 * insn of a TB 1230 */ 1231 cpu_interrupt_exittb(cs); 1232 /* Reset the reservation */ 1233 env->reserve_addr = -1; 1234 1235 /* Context synchronizing: check if TCG TLB needs flush */ 1236 check_tlb_flush(env, false); 1237 } 1238 1239 #ifdef CONFIG_TCG 1240 void helper_rfi(CPUPPCState *env) 1241 { 1242 do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1] & 0xfffffffful); 1243 } 1244 1245 #define MSR_BOOK3S_MASK 1246 #if defined(TARGET_PPC64) 1247 void helper_rfid(CPUPPCState *env) 1248 { 1249 /* 1250 * The architecture defines a number of rules for which bits can 1251 * change but in practice, we handle this in hreg_store_msr() 1252 * which will be called by do_rfi(), so there is no need to filter 1253 * here 1254 */ 1255 do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1]); 1256 } 1257 1258 void helper_rfscv(CPUPPCState *env) 1259 { 1260 do_rfi(env, env->lr, env->ctr); 1261 } 1262 1263 void helper_hrfid(CPUPPCState *env) 1264 { 1265 do_rfi(env, env->spr[SPR_HSRR0], env->spr[SPR_HSRR1]); 1266 } 1267 #endif 1268 1269 /*****************************************************************************/ 1270 /* Embedded PowerPC specific helpers */ 1271 void helper_40x_rfci(CPUPPCState *env) 1272 { 1273 do_rfi(env, env->spr[SPR_40x_SRR2], env->spr[SPR_40x_SRR3]); 1274 } 1275 1276 void helper_rfci(CPUPPCState *env) 1277 { 1278 do_rfi(env, env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1]); 1279 } 1280 1281 void helper_rfdi(CPUPPCState *env) 1282 { 1283 /* FIXME: choose CSRR1 or DSRR1 based on cpu type */ 1284 do_rfi(env, env->spr[SPR_BOOKE_DSRR0], env->spr[SPR_BOOKE_DSRR1]); 1285 } 1286 1287 void helper_rfmci(CPUPPCState *env) 1288 { 1289 /* FIXME: choose CSRR1 or MCSRR1 based on cpu type */ 1290 do_rfi(env, env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1]); 1291 } 1292 #endif /* CONFIG_TCG */ 1293 #endif /* !defined(CONFIG_USER_ONLY) */ 1294 1295 #ifdef CONFIG_TCG 1296 void helper_tw(CPUPPCState *env, target_ulong arg1, target_ulong arg2, 1297 uint32_t flags) 1298 { 1299 if (!likely(!(((int32_t)arg1 < (int32_t)arg2 && (flags & 0x10)) || 1300 ((int32_t)arg1 > (int32_t)arg2 && (flags & 0x08)) || 1301 ((int32_t)arg1 == (int32_t)arg2 && (flags & 0x04)) || 1302 ((uint32_t)arg1 < (uint32_t)arg2 && (flags & 0x02)) || 1303 ((uint32_t)arg1 > (uint32_t)arg2 && (flags & 0x01))))) { 1304 raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, 1305 POWERPC_EXCP_TRAP, GETPC()); 1306 } 1307 } 1308 1309 #if defined(TARGET_PPC64) 1310 void helper_td(CPUPPCState *env, target_ulong arg1, target_ulong arg2, 1311 uint32_t flags) 1312 { 1313 if (!likely(!(((int64_t)arg1 < (int64_t)arg2 && (flags & 0x10)) || 1314 ((int64_t)arg1 > (int64_t)arg2 && (flags & 0x08)) || 1315 ((int64_t)arg1 == (int64_t)arg2 && (flags & 0x04)) || 1316 ((uint64_t)arg1 < (uint64_t)arg2 && (flags & 0x02)) || 1317 ((uint64_t)arg1 > (uint64_t)arg2 && (flags & 0x01))))) { 1318 raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, 1319 POWERPC_EXCP_TRAP, GETPC()); 1320 } 1321 } 1322 #endif 1323 #endif 1324 1325 #if !defined(CONFIG_USER_ONLY) 1326 /*****************************************************************************/ 1327 /* PowerPC 601 specific instructions (POWER bridge) */ 1328 1329 #ifdef CONFIG_TCG 1330 void helper_rfsvc(CPUPPCState *env) 1331 { 1332 do_rfi(env, env->lr, env->ctr & 0x0000FFFF); 1333 } 1334 1335 /* Embedded.Processor Control */ 1336 static int dbell2irq(target_ulong rb) 1337 { 1338 int msg = rb & DBELL_TYPE_MASK; 1339 int irq = -1; 1340 1341 switch (msg) { 1342 case DBELL_TYPE_DBELL: 1343 irq = PPC_INTERRUPT_DOORBELL; 1344 break; 1345 case DBELL_TYPE_DBELL_CRIT: 1346 irq = PPC_INTERRUPT_CDOORBELL; 1347 break; 1348 case DBELL_TYPE_G_DBELL: 1349 case DBELL_TYPE_G_DBELL_CRIT: 1350 case DBELL_TYPE_G_DBELL_MC: 1351 /* XXX implement */ 1352 default: 1353 break; 1354 } 1355 1356 return irq; 1357 } 1358 1359 void helper_msgclr(CPUPPCState *env, target_ulong rb) 1360 { 1361 int irq = dbell2irq(rb); 1362 1363 if (irq < 0) { 1364 return; 1365 } 1366 1367 env->pending_interrupts &= ~(1 << irq); 1368 } 1369 1370 void helper_msgsnd(target_ulong rb) 1371 { 1372 int irq = dbell2irq(rb); 1373 int pir = rb & DBELL_PIRTAG_MASK; 1374 CPUState *cs; 1375 1376 if (irq < 0) { 1377 return; 1378 } 1379 1380 qemu_mutex_lock_iothread(); 1381 CPU_FOREACH(cs) { 1382 PowerPCCPU *cpu = POWERPC_CPU(cs); 1383 CPUPPCState *cenv = &cpu->env; 1384 1385 if ((rb & DBELL_BRDCAST) || (cenv->spr[SPR_BOOKE_PIR] == pir)) { 1386 cenv->pending_interrupts |= 1 << irq; 1387 cpu_interrupt(cs, CPU_INTERRUPT_HARD); 1388 } 1389 } 1390 qemu_mutex_unlock_iothread(); 1391 } 1392 1393 /* Server Processor Control */ 1394 1395 static bool dbell_type_server(target_ulong rb) 1396 { 1397 /* 1398 * A Directed Hypervisor Doorbell message is sent only if the 1399 * message type is 5. All other types are reserved and the 1400 * instruction is a no-op 1401 */ 1402 return (rb & DBELL_TYPE_MASK) == DBELL_TYPE_DBELL_SERVER; 1403 } 1404 1405 void helper_book3s_msgclr(CPUPPCState *env, target_ulong rb) 1406 { 1407 if (!dbell_type_server(rb)) { 1408 return; 1409 } 1410 1411 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDOORBELL); 1412 } 1413 1414 static void book3s_msgsnd_common(int pir, int irq) 1415 { 1416 CPUState *cs; 1417 1418 qemu_mutex_lock_iothread(); 1419 CPU_FOREACH(cs) { 1420 PowerPCCPU *cpu = POWERPC_CPU(cs); 1421 CPUPPCState *cenv = &cpu->env; 1422 1423 /* TODO: broadcast message to all threads of the same processor */ 1424 if (cenv->spr_cb[SPR_PIR].default_value == pir) { 1425 cenv->pending_interrupts |= 1 << irq; 1426 cpu_interrupt(cs, CPU_INTERRUPT_HARD); 1427 } 1428 } 1429 qemu_mutex_unlock_iothread(); 1430 } 1431 1432 void helper_book3s_msgsnd(target_ulong rb) 1433 { 1434 int pir = rb & DBELL_PROCIDTAG_MASK; 1435 1436 if (!dbell_type_server(rb)) { 1437 return; 1438 } 1439 1440 book3s_msgsnd_common(pir, PPC_INTERRUPT_HDOORBELL); 1441 } 1442 1443 #if defined(TARGET_PPC64) 1444 void helper_book3s_msgclrp(CPUPPCState *env, target_ulong rb) 1445 { 1446 helper_hfscr_facility_check(env, HFSCR_MSGP, "msgclrp", HFSCR_IC_MSGP); 1447 1448 if (!dbell_type_server(rb)) { 1449 return; 1450 } 1451 1452 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL); 1453 } 1454 1455 /* 1456 * sends a message to other threads that are on the same 1457 * multi-threaded processor 1458 */ 1459 void helper_book3s_msgsndp(CPUPPCState *env, target_ulong rb) 1460 { 1461 int pir = env->spr_cb[SPR_PIR].default_value; 1462 1463 helper_hfscr_facility_check(env, HFSCR_MSGP, "msgsndp", HFSCR_IC_MSGP); 1464 1465 if (!dbell_type_server(rb)) { 1466 return; 1467 } 1468 1469 /* TODO: TCG supports only one thread */ 1470 1471 book3s_msgsnd_common(pir, PPC_INTERRUPT_DOORBELL); 1472 } 1473 #endif 1474 #endif /* CONFIG_TCG */ 1475 #endif 1476 1477 #ifdef CONFIG_TCG 1478 void ppc_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr, 1479 MMUAccessType access_type, 1480 int mmu_idx, uintptr_t retaddr) 1481 { 1482 CPUPPCState *env = cs->env_ptr; 1483 uint32_t insn; 1484 1485 /* Restore state and reload the insn we executed, for filling in DSISR. */ 1486 cpu_restore_state(cs, retaddr, true); 1487 insn = cpu_ldl_code(env, env->nip); 1488 1489 cs->exception_index = POWERPC_EXCP_ALIGN; 1490 env->error_code = insn & 0x03FF0000; 1491 cpu_loop_exit(cs); 1492 } 1493 #endif 1494