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