target/ppc: Readability improvements in exception handlers
[qemu/armbru.git] / target / ppc / excp_helper.c
blobc15cd904d129ea27a44a2cba7a063c584a919222
1 /*
2 * PowerPC exception emulation helpers for QEMU.
4 * Copyright (c) 2003-2007 Jocelyn Mayer
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.
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.
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/>.
19 #include "qemu/osdep.h"
20 #include "qemu/main-loop.h"
21 #include "qemu/log.h"
22 #include "cpu.h"
23 #include "exec/exec-all.h"
24 #include "internal.h"
25 #include "helper_regs.h"
26 #include "hw/ppc/ppc.h"
28 #include "trace.h"
30 #ifdef CONFIG_TCG
31 #include "sysemu/tcg.h"
32 #include "exec/helper-proto.h"
33 #include "exec/cpu_ldst.h"
34 #endif
36 /*****************************************************************************/
37 /* Exception processing */
38 #if !defined(CONFIG_USER_ONLY)
40 static const char *powerpc_excp_name(int excp)
42 switch (excp) {
43 case POWERPC_EXCP_CRITICAL: return "CRITICAL";
44 case POWERPC_EXCP_MCHECK: return "MCHECK";
45 case POWERPC_EXCP_DSI: return "DSI";
46 case POWERPC_EXCP_ISI: return "ISI";
47 case POWERPC_EXCP_EXTERNAL: return "EXTERNAL";
48 case POWERPC_EXCP_ALIGN: return "ALIGN";
49 case POWERPC_EXCP_PROGRAM: return "PROGRAM";
50 case POWERPC_EXCP_FPU: return "FPU";
51 case POWERPC_EXCP_SYSCALL: return "SYSCALL";
52 case POWERPC_EXCP_APU: return "APU";
53 case POWERPC_EXCP_DECR: return "DECR";
54 case POWERPC_EXCP_FIT: return "FIT";
55 case POWERPC_EXCP_WDT: return "WDT";
56 case POWERPC_EXCP_DTLB: return "DTLB";
57 case POWERPC_EXCP_ITLB: return "ITLB";
58 case POWERPC_EXCP_DEBUG: return "DEBUG";
59 case POWERPC_EXCP_SPEU: return "SPEU";
60 case POWERPC_EXCP_EFPDI: return "EFPDI";
61 case POWERPC_EXCP_EFPRI: return "EFPRI";
62 case POWERPC_EXCP_EPERFM: return "EPERFM";
63 case POWERPC_EXCP_DOORI: return "DOORI";
64 case POWERPC_EXCP_DOORCI: return "DOORCI";
65 case POWERPC_EXCP_GDOORI: return "GDOORI";
66 case POWERPC_EXCP_GDOORCI: return "GDOORCI";
67 case POWERPC_EXCP_HYPPRIV: return "HYPPRIV";
68 case POWERPC_EXCP_RESET: return "RESET";
69 case POWERPC_EXCP_DSEG: return "DSEG";
70 case POWERPC_EXCP_ISEG: return "ISEG";
71 case POWERPC_EXCP_HDECR: return "HDECR";
72 case POWERPC_EXCP_TRACE: return "TRACE";
73 case POWERPC_EXCP_HDSI: return "HDSI";
74 case POWERPC_EXCP_HISI: return "HISI";
75 case POWERPC_EXCP_HDSEG: return "HDSEG";
76 case POWERPC_EXCP_HISEG: return "HISEG";
77 case POWERPC_EXCP_VPU: return "VPU";
78 case POWERPC_EXCP_PIT: return "PIT";
79 case POWERPC_EXCP_EMUL: return "EMUL";
80 case POWERPC_EXCP_IFTLB: return "IFTLB";
81 case POWERPC_EXCP_DLTLB: return "DLTLB";
82 case POWERPC_EXCP_DSTLB: return "DSTLB";
83 case POWERPC_EXCP_FPA: return "FPA";
84 case POWERPC_EXCP_DABR: return "DABR";
85 case POWERPC_EXCP_IABR: return "IABR";
86 case POWERPC_EXCP_SMI: return "SMI";
87 case POWERPC_EXCP_PERFM: return "PERFM";
88 case POWERPC_EXCP_THERM: return "THERM";
89 case POWERPC_EXCP_VPUA: return "VPUA";
90 case POWERPC_EXCP_SOFTP: return "SOFTP";
91 case POWERPC_EXCP_MAINT: return "MAINT";
92 case POWERPC_EXCP_MEXTBR: return "MEXTBR";
93 case POWERPC_EXCP_NMEXTBR: return "NMEXTBR";
94 case POWERPC_EXCP_ITLBE: return "ITLBE";
95 case POWERPC_EXCP_DTLBE: return "DTLBE";
96 case POWERPC_EXCP_VSXU: return "VSXU";
97 case POWERPC_EXCP_FU: return "FU";
98 case POWERPC_EXCP_HV_EMU: return "HV_EMU";
99 case POWERPC_EXCP_HV_MAINT: return "HV_MAINT";
100 case POWERPC_EXCP_HV_FU: return "HV_FU";
101 case POWERPC_EXCP_SDOOR: return "SDOOR";
102 case POWERPC_EXCP_SDOOR_HV: return "SDOOR_HV";
103 case POWERPC_EXCP_HVIRT: return "HVIRT";
104 case POWERPC_EXCP_SYSCALL_VECTORED: return "SYSCALL_VECTORED";
105 default:
106 g_assert_not_reached();
110 static void dump_syscall(CPUPPCState *env)
112 qemu_log_mask(CPU_LOG_INT, "syscall r0=%016" PRIx64
113 " r3=%016" PRIx64 " r4=%016" PRIx64 " r5=%016" PRIx64
114 " r6=%016" PRIx64 " r7=%016" PRIx64 " r8=%016" PRIx64
115 " nip=" TARGET_FMT_lx "\n",
116 ppc_dump_gpr(env, 0), ppc_dump_gpr(env, 3),
117 ppc_dump_gpr(env, 4), ppc_dump_gpr(env, 5),
118 ppc_dump_gpr(env, 6), ppc_dump_gpr(env, 7),
119 ppc_dump_gpr(env, 8), env->nip);
122 static void dump_hcall(CPUPPCState *env)
124 qemu_log_mask(CPU_LOG_INT, "hypercall r3=%016" PRIx64
125 " r4=%016" PRIx64 " r5=%016" PRIx64 " r6=%016" PRIx64
126 " r7=%016" PRIx64 " r8=%016" PRIx64 " r9=%016" PRIx64
127 " r10=%016" PRIx64 " r11=%016" PRIx64 " r12=%016" PRIx64
128 " nip=" TARGET_FMT_lx "\n",
129 ppc_dump_gpr(env, 3), ppc_dump_gpr(env, 4),
130 ppc_dump_gpr(env, 5), ppc_dump_gpr(env, 6),
131 ppc_dump_gpr(env, 7), ppc_dump_gpr(env, 8),
132 ppc_dump_gpr(env, 9), ppc_dump_gpr(env, 10),
133 ppc_dump_gpr(env, 11), ppc_dump_gpr(env, 12),
134 env->nip);
137 #ifdef CONFIG_TCG
138 /* Return true iff byteswap is needed to load instruction */
139 static inline bool insn_need_byteswap(CPUArchState *env)
141 /* SYSTEM builds TARGET_BIG_ENDIAN. Need to swap when MSR[LE] is set */
142 return !!(env->msr & ((target_ulong)1 << MSR_LE));
145 static uint32_t ppc_ldl_code(CPUArchState *env, abi_ptr addr)
147 uint32_t insn = cpu_ldl_code(env, addr);
149 if (insn_need_byteswap(env)) {
150 insn = bswap32(insn);
153 return insn;
155 #endif
157 static void ppc_excp_debug_sw_tlb(CPUPPCState *env, int excp)
159 const char *es;
160 target_ulong *miss, *cmp;
161 int en;
163 if (!qemu_loglevel_mask(CPU_LOG_MMU)) {
164 return;
167 if (excp == POWERPC_EXCP_IFTLB) {
168 es = "I";
169 en = 'I';
170 miss = &env->spr[SPR_IMISS];
171 cmp = &env->spr[SPR_ICMP];
172 } else {
173 if (excp == POWERPC_EXCP_DLTLB) {
174 es = "DL";
175 } else {
176 es = "DS";
178 en = 'D';
179 miss = &env->spr[SPR_DMISS];
180 cmp = &env->spr[SPR_DCMP];
182 qemu_log("6xx %sTLB miss: %cM " TARGET_FMT_lx " %cC "
183 TARGET_FMT_lx " H1 " TARGET_FMT_lx " H2 "
184 TARGET_FMT_lx " %08x\n", es, en, *miss, en, *cmp,
185 env->spr[SPR_HASH1], env->spr[SPR_HASH2],
186 env->error_code);
189 #if defined(TARGET_PPC64)
190 static int powerpc_reset_wakeup(CPUPPCState *env, int excp, target_ulong *msr)
192 /* We no longer are in a PM state */
193 env->resume_as_sreset = false;
195 /* Pretend to be returning from doze always as we don't lose state */
196 *msr |= SRR1_WS_NOLOSS;
198 /* Machine checks are sent normally */
199 if (excp == POWERPC_EXCP_MCHECK) {
200 return excp;
202 switch (excp) {
203 case POWERPC_EXCP_RESET:
204 *msr |= SRR1_WAKERESET;
205 break;
206 case POWERPC_EXCP_EXTERNAL:
207 *msr |= SRR1_WAKEEE;
208 break;
209 case POWERPC_EXCP_DECR:
210 *msr |= SRR1_WAKEDEC;
211 break;
212 case POWERPC_EXCP_SDOOR:
213 *msr |= SRR1_WAKEDBELL;
214 break;
215 case POWERPC_EXCP_SDOOR_HV:
216 *msr |= SRR1_WAKEHDBELL;
217 break;
218 case POWERPC_EXCP_HV_MAINT:
219 *msr |= SRR1_WAKEHMI;
220 break;
221 case POWERPC_EXCP_HVIRT:
222 *msr |= SRR1_WAKEHVI;
223 break;
224 default:
225 cpu_abort(env_cpu(env),
226 "Unsupported exception %d in Power Save mode\n", excp);
228 return POWERPC_EXCP_RESET;
232 * AIL - Alternate Interrupt Location, a mode that allows interrupts to be
233 * taken with the MMU on, and which uses an alternate location (e.g., so the
234 * kernel/hv can map the vectors there with an effective address).
236 * An interrupt is considered to be taken "with AIL" or "AIL applies" if they
237 * are delivered in this way. AIL requires the LPCR to be set to enable this
238 * mode, and then a number of conditions have to be true for AIL to apply.
240 * First of all, SRESET, MCE, and HMI are always delivered without AIL, because
241 * they specifically want to be in real mode (e.g., the MCE might be signaling
242 * a SLB multi-hit which requires SLB flush before the MMU can be enabled).
244 * After that, behaviour depends on the current MSR[IR], MSR[DR], MSR[HV],
245 * whether or not the interrupt changes MSR[HV] from 0 to 1, and the current
246 * radix mode (LPCR[HR]).
248 * POWER8, POWER9 with LPCR[HR]=0
249 * | LPCR[AIL] | MSR[IR||DR] | MSR[HV] | new MSR[HV] | AIL |
250 * +-----------+-------------+---------+-------------+-----+
251 * | a | 00/01/10 | x | x | 0 |
252 * | a | 11 | 0 | 1 | 0 |
253 * | a | 11 | 1 | 1 | a |
254 * | a | 11 | 0 | 0 | a |
255 * +-------------------------------------------------------+
257 * POWER9 with LPCR[HR]=1
258 * | LPCR[AIL] | MSR[IR||DR] | MSR[HV] | new MSR[HV] | AIL |
259 * +-----------+-------------+---------+-------------+-----+
260 * | a | 00/01/10 | x | x | 0 |
261 * | a | 11 | x | x | a |
262 * +-------------------------------------------------------+
264 * The difference with POWER9 being that MSR[HV] 0->1 interrupts can be sent to
265 * the hypervisor in AIL mode if the guest is radix. This is good for
266 * performance but allows the guest to influence the AIL of hypervisor
267 * interrupts using its MSR, and also the hypervisor must disallow guest
268 * interrupts (MSR[HV] 0->0) from using AIL if the hypervisor does not want to
269 * use AIL for its MSR[HV] 0->1 interrupts.
271 * POWER10 addresses those issues with a new LPCR[HAIL] bit that is applied to
272 * interrupts that begin execution with MSR[HV]=1 (so both MSR[HV] 0->1 and
273 * MSR[HV] 1->1).
275 * HAIL=1 is equivalent to AIL=3, for interrupts delivered with MSR[HV]=1.
277 * POWER10 behaviour is
278 * | LPCR[AIL] | LPCR[HAIL] | MSR[IR||DR] | MSR[HV] | new MSR[HV] | AIL |
279 * +-----------+------------+-------------+---------+-------------+-----+
280 * | a | h | 00/01/10 | 0 | 0 | 0 |
281 * | a | h | 11 | 0 | 0 | a |
282 * | a | h | x | 0 | 1 | h |
283 * | a | h | 00/01/10 | 1 | 1 | 0 |
284 * | a | h | 11 | 1 | 1 | h |
285 * +--------------------------------------------------------------------+
287 static void ppc_excp_apply_ail(PowerPCCPU *cpu, int excp, target_ulong msr,
288 target_ulong *new_msr, target_ulong *vector)
290 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
291 CPUPPCState *env = &cpu->env;
292 bool mmu_all_on = ((msr >> MSR_IR) & 1) && ((msr >> MSR_DR) & 1);
293 bool hv_escalation = !(msr & MSR_HVB) && (*new_msr & MSR_HVB);
294 int ail = 0;
296 if (excp == POWERPC_EXCP_MCHECK ||
297 excp == POWERPC_EXCP_RESET ||
298 excp == POWERPC_EXCP_HV_MAINT) {
299 /* SRESET, MCE, HMI never apply AIL */
300 return;
303 if (!(pcc->lpcr_mask & LPCR_AIL)) {
304 /* This CPU does not have AIL */
305 return;
308 /* P8 & P9 */
309 if (!(pcc->lpcr_mask & LPCR_HAIL)) {
310 if (!mmu_all_on) {
311 /* AIL only works if MSR[IR] and MSR[DR] are both enabled. */
312 return;
314 if (hv_escalation && !(env->spr[SPR_LPCR] & LPCR_HR)) {
316 * AIL does not work if there is a MSR[HV] 0->1 transition and the
317 * partition is in HPT mode. For radix guests, such interrupts are
318 * allowed to be delivered to the hypervisor in ail mode.
320 return;
323 ail = (env->spr[SPR_LPCR] & LPCR_AIL) >> LPCR_AIL_SHIFT;
324 if (ail == 0) {
325 return;
327 if (ail == 1) {
328 /* AIL=1 is reserved, treat it like AIL=0 */
329 return;
332 /* P10 and up */
333 } else {
334 if (!mmu_all_on && !hv_escalation) {
336 * AIL works for HV interrupts even with guest MSR[IR/DR] disabled.
337 * Guest->guest and HV->HV interrupts do require MMU on.
339 return;
342 if (*new_msr & MSR_HVB) {
343 if (!(env->spr[SPR_LPCR] & LPCR_HAIL)) {
344 /* HV interrupts depend on LPCR[HAIL] */
345 return;
347 ail = 3; /* HAIL=1 gives AIL=3 behaviour for HV interrupts */
348 } else {
349 ail = (env->spr[SPR_LPCR] & LPCR_AIL) >> LPCR_AIL_SHIFT;
351 if (ail == 0) {
352 return;
354 if (ail == 1 || ail == 2) {
355 /* AIL=1 and AIL=2 are reserved, treat them like AIL=0 */
356 return;
361 * AIL applies, so the new MSR gets IR and DR set, and an offset applied
362 * to the new IP.
364 *new_msr |= (1 << MSR_IR) | (1 << MSR_DR);
366 if (excp != POWERPC_EXCP_SYSCALL_VECTORED) {
367 if (ail == 2) {
368 *vector |= 0x0000000000018000ull;
369 } else if (ail == 3) {
370 *vector |= 0xc000000000004000ull;
372 } else {
374 * scv AIL is a little different. AIL=2 does not change the address,
375 * only the MSR. AIL=3 replaces the 0x17000 base with 0xc...3000.
377 if (ail == 3) {
378 *vector &= ~0x0000000000017000ull; /* Un-apply the base offset */
379 *vector |= 0xc000000000003000ull; /* Apply scv's AIL=3 offset */
383 #endif
385 static void powerpc_reset_excp_state(PowerPCCPU *cpu)
387 CPUState *cs = CPU(cpu);
388 CPUPPCState *env = &cpu->env;
390 /* Reset exception state */
391 cs->exception_index = POWERPC_EXCP_NONE;
392 env->error_code = 0;
395 static void powerpc_set_excp_state(PowerPCCPU *cpu, target_ulong vector,
396 target_ulong msr)
398 CPUPPCState *env = &cpu->env;
400 assert((msr & env->msr_mask) == msr);
403 * We don't use hreg_store_msr here as already have treated any
404 * special case that could occur. Just store MSR and update hflags
406 * Note: We *MUST* not use hreg_store_msr() as-is anyway because it will
407 * prevent setting of the HV bit which some exceptions might need to do.
409 env->nip = vector;
410 env->msr = msr;
411 hreg_compute_hflags(env);
412 ppc_maybe_interrupt(env);
414 powerpc_reset_excp_state(cpu);
417 * Any interrupt is context synchronizing, check if TCG TLB needs
418 * a delayed flush on ppc64
420 check_tlb_flush(env, false);
422 /* Reset the reservation */
423 env->reserve_addr = -1;
426 static void powerpc_mcheck_checkstop(CPUPPCState *env)
428 CPUState *cs = env_cpu(env);
430 if (FIELD_EX64(env->msr, MSR, ME)) {
431 return;
434 /* Machine check exception is not enabled. Enter checkstop state. */
435 fprintf(stderr, "Machine check while not allowed. "
436 "Entering checkstop state\n");
437 if (qemu_log_separate()) {
438 qemu_log("Machine check while not allowed. "
439 "Entering checkstop state\n");
441 cs->halted = 1;
442 cpu_interrupt_exittb(cs);
445 static void powerpc_excp_40x(PowerPCCPU *cpu, int excp)
447 CPUPPCState *env = &cpu->env;
448 target_ulong msr, new_msr, vector;
449 int srr0 = SPR_SRR0, srr1 = SPR_SRR1;
451 /* new srr1 value excluding must-be-zero bits */
452 msr = env->msr & ~0x783f0000ULL;
454 /* new interrupt handler msr preserves ME unless explicitly overridden */
455 new_msr = env->msr & (((target_ulong)1 << MSR_ME));
457 /* HV emu assistance interrupt only exists on server arch 2.05 or later */
458 if (excp == POWERPC_EXCP_HV_EMU) {
459 excp = POWERPC_EXCP_PROGRAM;
462 vector = env->excp_vectors[excp];
463 if (vector == (target_ulong)-1ULL) {
464 cpu_abort(env_cpu(env),
465 "Raised an exception without defined vector %d\n", excp);
467 vector |= env->excp_prefix;
469 switch (excp) {
470 case POWERPC_EXCP_CRITICAL: /* Critical input */
471 srr0 = SPR_40x_SRR2;
472 srr1 = SPR_40x_SRR3;
473 break;
474 case POWERPC_EXCP_MCHECK: /* Machine check exception */
475 powerpc_mcheck_checkstop(env);
476 /* machine check exceptions don't have ME set */
477 new_msr &= ~((target_ulong)1 << MSR_ME);
478 srr0 = SPR_40x_SRR2;
479 srr1 = SPR_40x_SRR3;
480 break;
481 case POWERPC_EXCP_DSI: /* Data storage exception */
482 trace_ppc_excp_dsi(env->spr[SPR_40x_ESR], env->spr[SPR_40x_DEAR]);
483 break;
484 case POWERPC_EXCP_ISI: /* Instruction storage exception */
485 trace_ppc_excp_isi(msr, env->nip);
486 break;
487 case POWERPC_EXCP_EXTERNAL: /* External input */
488 break;
489 case POWERPC_EXCP_ALIGN: /* Alignment exception */
490 break;
491 case POWERPC_EXCP_PROGRAM: /* Program exception */
492 switch (env->error_code & ~0xF) {
493 case POWERPC_EXCP_FP:
494 if (!FIELD_EX64_FE(env->msr) || !FIELD_EX64(env->msr, MSR, FP)) {
495 trace_ppc_excp_fp_ignore();
496 powerpc_reset_excp_state(cpu);
497 return;
499 env->spr[SPR_40x_ESR] = ESR_FP;
500 break;
501 case POWERPC_EXCP_INVAL:
502 trace_ppc_excp_inval(env->nip);
503 env->spr[SPR_40x_ESR] = ESR_PIL;
504 break;
505 case POWERPC_EXCP_PRIV:
506 env->spr[SPR_40x_ESR] = ESR_PPR;
507 break;
508 case POWERPC_EXCP_TRAP:
509 env->spr[SPR_40x_ESR] = ESR_PTR;
510 break;
511 default:
512 cpu_abort(env_cpu(env), "Invalid program exception %d. Aborting\n",
513 env->error_code);
514 break;
516 break;
517 case POWERPC_EXCP_SYSCALL: /* System call exception */
518 dump_syscall(env);
521 * We need to correct the NIP which in this case is supposed
522 * to point to the next instruction
524 env->nip += 4;
525 break;
526 case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt */
527 trace_ppc_excp_print("FIT");
528 break;
529 case POWERPC_EXCP_WDT: /* Watchdog timer interrupt */
530 trace_ppc_excp_print("WDT");
531 break;
532 case POWERPC_EXCP_DTLB: /* Data TLB error */
533 case POWERPC_EXCP_ITLB: /* Instruction TLB error */
534 break;
535 case POWERPC_EXCP_PIT: /* Programmable interval timer interrupt */
536 trace_ppc_excp_print("PIT");
537 break;
538 case POWERPC_EXCP_DEBUG: /* Debug interrupt */
539 cpu_abort(env_cpu(env), "%s exception not implemented\n",
540 powerpc_excp_name(excp));
541 break;
542 default:
543 cpu_abort(env_cpu(env), "Invalid PowerPC exception %d. Aborting\n",
544 excp);
545 break;
548 env->spr[srr0] = env->nip;
549 env->spr[srr1] = msr;
550 powerpc_set_excp_state(cpu, vector, new_msr);
553 static void powerpc_excp_6xx(PowerPCCPU *cpu, int excp)
555 CPUPPCState *env = &cpu->env;
556 target_ulong msr, new_msr, vector;
558 /* new srr1 value excluding must-be-zero bits */
559 msr = env->msr & ~0x783f0000ULL;
561 /* new interrupt handler msr preserves ME unless explicitly overridden */
562 new_msr = env->msr & ((target_ulong)1 << MSR_ME);
564 /* HV emu assistance interrupt only exists on server arch 2.05 or later */
565 if (excp == POWERPC_EXCP_HV_EMU) {
566 excp = POWERPC_EXCP_PROGRAM;
569 vector = env->excp_vectors[excp];
570 if (vector == (target_ulong)-1ULL) {
571 cpu_abort(env_cpu(env),
572 "Raised an exception without defined vector %d\n", excp);
574 vector |= env->excp_prefix;
576 switch (excp) {
577 case POWERPC_EXCP_CRITICAL: /* Critical input */
578 break;
579 case POWERPC_EXCP_MCHECK: /* Machine check exception */
580 powerpc_mcheck_checkstop(env);
581 /* machine check exceptions don't have ME set */
582 new_msr &= ~((target_ulong)1 << MSR_ME);
583 break;
584 case POWERPC_EXCP_DSI: /* Data storage exception */
585 trace_ppc_excp_dsi(env->spr[SPR_DSISR], env->spr[SPR_DAR]);
586 break;
587 case POWERPC_EXCP_ISI: /* Instruction storage exception */
588 trace_ppc_excp_isi(msr, env->nip);
589 msr |= env->error_code;
590 break;
591 case POWERPC_EXCP_EXTERNAL: /* External input */
592 break;
593 case POWERPC_EXCP_ALIGN: /* Alignment exception */
594 /* Get rS/rD and rA from faulting opcode */
596 * Note: the opcode fields will not be set properly for a
597 * direct store load/store, but nobody cares as nobody
598 * actually uses direct store segments.
600 env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16;
601 break;
602 case POWERPC_EXCP_PROGRAM: /* Program exception */
603 switch (env->error_code & ~0xF) {
604 case POWERPC_EXCP_FP:
605 if (!FIELD_EX64_FE(env->msr) || !FIELD_EX64(env->msr, MSR, FP)) {
606 trace_ppc_excp_fp_ignore();
607 powerpc_reset_excp_state(cpu);
608 return;
611 * NIP always points to the faulting instruction for FP exceptions,
612 * so always use store_next and claim we are precise in the MSR.
614 msr |= 0x00100000;
615 break;
616 case POWERPC_EXCP_INVAL:
617 trace_ppc_excp_inval(env->nip);
618 msr |= 0x00080000;
619 break;
620 case POWERPC_EXCP_PRIV:
621 msr |= 0x00040000;
622 break;
623 case POWERPC_EXCP_TRAP:
624 msr |= 0x00020000;
625 break;
626 default:
627 /* Should never occur */
628 cpu_abort(env_cpu(env), "Invalid program exception %d. Aborting\n",
629 env->error_code);
630 break;
632 break;
633 case POWERPC_EXCP_SYSCALL: /* System call exception */
634 dump_syscall(env);
637 * We need to correct the NIP which in this case is supposed
638 * to point to the next instruction
640 env->nip += 4;
641 break;
642 case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
643 case POWERPC_EXCP_DECR: /* Decrementer exception */
644 break;
645 case POWERPC_EXCP_DTLB: /* Data TLB error */
646 case POWERPC_EXCP_ITLB: /* Instruction TLB error */
647 break;
648 case POWERPC_EXCP_RESET: /* System reset exception */
649 if (FIELD_EX64(env->msr, MSR, POW)) {
650 cpu_abort(env_cpu(env),
651 "Trying to deliver power-saving system reset exception "
652 "%d with no HV support\n", excp);
654 break;
655 case POWERPC_EXCP_TRACE: /* Trace exception */
656 break;
657 case POWERPC_EXCP_IFTLB: /* Instruction fetch TLB error */
658 case POWERPC_EXCP_DLTLB: /* Data load TLB miss */
659 case POWERPC_EXCP_DSTLB: /* Data store TLB miss */
660 /* Swap temporary saved registers with GPRs */
661 if (!(new_msr & ((target_ulong)1 << MSR_TGPR))) {
662 new_msr |= (target_ulong)1 << MSR_TGPR;
663 hreg_swap_gpr_tgpr(env);
666 ppc_excp_debug_sw_tlb(env, excp);
668 msr |= env->crf[0] << 28;
669 msr |= env->error_code; /* key, D/I, S/L bits */
670 /* Set way using a LRU mechanism */
671 msr |= ((env->last_way + 1) & (env->nb_ways - 1)) << 17;
672 break;
673 case POWERPC_EXCP_FPA: /* Floating-point assist exception */
674 case POWERPC_EXCP_DABR: /* Data address breakpoint */
675 case POWERPC_EXCP_IABR: /* Instruction address breakpoint */
676 case POWERPC_EXCP_SMI: /* System management interrupt */
677 case POWERPC_EXCP_MEXTBR: /* Maskable external breakpoint */
678 case POWERPC_EXCP_NMEXTBR: /* Non maskable external breakpoint */
679 cpu_abort(env_cpu(env), "%s exception not implemented\n",
680 powerpc_excp_name(excp));
681 break;
682 default:
683 cpu_abort(env_cpu(env), "Invalid PowerPC exception %d. Aborting\n",
684 excp);
685 break;
688 if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) {
689 new_msr |= (target_ulong)1 << MSR_LE;
691 env->spr[SPR_SRR0] = env->nip;
692 env->spr[SPR_SRR1] = msr;
693 powerpc_set_excp_state(cpu, vector, new_msr);
696 static void powerpc_excp_7xx(PowerPCCPU *cpu, int excp)
698 CPUPPCState *env = &cpu->env;
699 target_ulong msr, new_msr, vector;
701 /* new srr1 value excluding must-be-zero bits */
702 msr = env->msr & ~0x783f0000ULL;
704 /* new interrupt handler msr preserves ME unless explicitly overridden */
705 new_msr = env->msr & ((target_ulong)1 << MSR_ME);
707 /* HV emu assistance interrupt only exists on server arch 2.05 or later */
708 if (excp == POWERPC_EXCP_HV_EMU) {
709 excp = POWERPC_EXCP_PROGRAM;
712 vector = env->excp_vectors[excp];
713 if (vector == (target_ulong)-1ULL) {
714 cpu_abort(env_cpu(env),
715 "Raised an exception without defined vector %d\n", excp);
717 vector |= env->excp_prefix;
719 switch (excp) {
720 case POWERPC_EXCP_MCHECK: /* Machine check exception */
721 powerpc_mcheck_checkstop(env);
722 /* machine check exceptions don't have ME set */
723 new_msr &= ~((target_ulong)1 << MSR_ME);
724 break;
725 case POWERPC_EXCP_DSI: /* Data storage exception */
726 trace_ppc_excp_dsi(env->spr[SPR_DSISR], env->spr[SPR_DAR]);
727 break;
728 case POWERPC_EXCP_ISI: /* Instruction storage exception */
729 trace_ppc_excp_isi(msr, env->nip);
730 msr |= env->error_code;
731 break;
732 case POWERPC_EXCP_EXTERNAL: /* External input */
733 break;
734 case POWERPC_EXCP_ALIGN: /* Alignment exception */
735 /* Get rS/rD and rA from faulting opcode */
737 * Note: the opcode fields will not be set properly for a
738 * direct store load/store, but nobody cares as nobody
739 * actually uses direct store segments.
741 env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16;
742 break;
743 case POWERPC_EXCP_PROGRAM: /* Program exception */
744 switch (env->error_code & ~0xF) {
745 case POWERPC_EXCP_FP:
746 if (!FIELD_EX64_FE(env->msr) || !FIELD_EX64(env->msr, MSR, FP)) {
747 trace_ppc_excp_fp_ignore();
748 powerpc_reset_excp_state(cpu);
749 return;
752 * NIP always points to the faulting instruction for FP exceptions,
753 * so always use store_next and claim we are precise in the MSR.
755 msr |= 0x00100000;
756 break;
757 case POWERPC_EXCP_INVAL:
758 trace_ppc_excp_inval(env->nip);
759 msr |= 0x00080000;
760 break;
761 case POWERPC_EXCP_PRIV:
762 msr |= 0x00040000;
763 break;
764 case POWERPC_EXCP_TRAP:
765 msr |= 0x00020000;
766 break;
767 default:
768 /* Should never occur */
769 cpu_abort(env_cpu(env), "Invalid program exception %d. Aborting\n",
770 env->error_code);
771 break;
773 break;
774 case POWERPC_EXCP_SYSCALL: /* System call exception */
776 int lev = env->error_code;
778 if (lev == 1 && cpu->vhyp) {
779 dump_hcall(env);
780 } else {
781 dump_syscall(env);
785 * We need to correct the NIP which in this case is supposed
786 * to point to the next instruction
788 env->nip += 4;
791 * The Virtual Open Firmware (VOF) relies on the 'sc 1'
792 * instruction to communicate with QEMU. The pegasos2 machine
793 * uses VOF and the 7xx CPUs, so although the 7xx don't have
794 * HV mode, we need to keep hypercall support.
796 if (lev == 1 && cpu->vhyp) {
797 PPCVirtualHypervisorClass *vhc =
798 PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
799 vhc->hypercall(cpu->vhyp, cpu);
800 powerpc_reset_excp_state(cpu);
801 return;
804 break;
806 case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
807 case POWERPC_EXCP_DECR: /* Decrementer exception */
808 break;
809 case POWERPC_EXCP_RESET: /* System reset exception */
810 if (FIELD_EX64(env->msr, MSR, POW)) {
811 cpu_abort(env_cpu(env),
812 "Trying to deliver power-saving system reset exception "
813 "%d with no HV support\n", excp);
815 break;
816 case POWERPC_EXCP_TRACE: /* Trace exception */
817 break;
818 case POWERPC_EXCP_IFTLB: /* Instruction fetch TLB error */
819 case POWERPC_EXCP_DLTLB: /* Data load TLB miss */
820 case POWERPC_EXCP_DSTLB: /* Data store TLB miss */
821 ppc_excp_debug_sw_tlb(env, excp);
822 msr |= env->crf[0] << 28;
823 msr |= env->error_code; /* key, D/I, S/L bits */
824 /* Set way using a LRU mechanism */
825 msr |= ((env->last_way + 1) & (env->nb_ways - 1)) << 17;
826 break;
827 case POWERPC_EXCP_IABR: /* Instruction address breakpoint */
828 case POWERPC_EXCP_SMI: /* System management interrupt */
829 case POWERPC_EXCP_THERM: /* Thermal interrupt */
830 case POWERPC_EXCP_PERFM: /* Embedded performance monitor interrupt */
831 cpu_abort(env_cpu(env), "%s exception not implemented\n",
832 powerpc_excp_name(excp));
833 break;
834 default:
835 cpu_abort(env_cpu(env), "Invalid PowerPC exception %d. Aborting\n",
836 excp);
837 break;
840 if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) {
841 new_msr |= (target_ulong)1 << MSR_LE;
843 env->spr[SPR_SRR0] = env->nip;
844 env->spr[SPR_SRR1] = msr;
845 powerpc_set_excp_state(cpu, vector, new_msr);
848 static void powerpc_excp_74xx(PowerPCCPU *cpu, int excp)
850 CPUPPCState *env = &cpu->env;
851 target_ulong msr, new_msr, vector;
853 /* new srr1 value excluding must-be-zero bits */
854 msr = env->msr & ~0x783f0000ULL;
856 /* new interrupt handler msr preserves ME unless explicitly overridden */
857 new_msr = env->msr & ((target_ulong)1 << MSR_ME);
859 /* HV emu assistance interrupt only exists on server arch 2.05 or later */
860 if (excp == POWERPC_EXCP_HV_EMU) {
861 excp = POWERPC_EXCP_PROGRAM;
864 vector = env->excp_vectors[excp];
865 if (vector == (target_ulong)-1ULL) {
866 cpu_abort(env_cpu(env),
867 "Raised an exception without defined vector %d\n", excp);
869 vector |= env->excp_prefix;
871 switch (excp) {
872 case POWERPC_EXCP_MCHECK: /* Machine check exception */
873 powerpc_mcheck_checkstop(env);
874 /* machine check exceptions don't have ME set */
875 new_msr &= ~((target_ulong)1 << MSR_ME);
876 break;
877 case POWERPC_EXCP_DSI: /* Data storage exception */
878 trace_ppc_excp_dsi(env->spr[SPR_DSISR], env->spr[SPR_DAR]);
879 break;
880 case POWERPC_EXCP_ISI: /* Instruction storage exception */
881 trace_ppc_excp_isi(msr, env->nip);
882 msr |= env->error_code;
883 break;
884 case POWERPC_EXCP_EXTERNAL: /* External input */
885 break;
886 case POWERPC_EXCP_ALIGN: /* Alignment exception */
887 /* Get rS/rD and rA from faulting opcode */
889 * Note: the opcode fields will not be set properly for a
890 * direct store load/store, but nobody cares as nobody
891 * actually uses direct store segments.
893 env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16;
894 break;
895 case POWERPC_EXCP_PROGRAM: /* Program exception */
896 switch (env->error_code & ~0xF) {
897 case POWERPC_EXCP_FP:
898 if (!FIELD_EX64_FE(env->msr) || !FIELD_EX64(env->msr, MSR, FP)) {
899 trace_ppc_excp_fp_ignore();
900 powerpc_reset_excp_state(cpu);
901 return;
904 * NIP always points to the faulting instruction for FP exceptions,
905 * so always use store_next and claim we are precise in the MSR.
907 msr |= 0x00100000;
908 break;
909 case POWERPC_EXCP_INVAL:
910 trace_ppc_excp_inval(env->nip);
911 msr |= 0x00080000;
912 break;
913 case POWERPC_EXCP_PRIV:
914 msr |= 0x00040000;
915 break;
916 case POWERPC_EXCP_TRAP:
917 msr |= 0x00020000;
918 break;
919 default:
920 /* Should never occur */
921 cpu_abort(env_cpu(env), "Invalid program exception %d. Aborting\n",
922 env->error_code);
923 break;
925 break;
926 case POWERPC_EXCP_SYSCALL: /* System call exception */
928 int lev = env->error_code;
930 if (lev == 1 && cpu->vhyp) {
931 dump_hcall(env);
932 } else {
933 dump_syscall(env);
937 * We need to correct the NIP which in this case is supposed
938 * to point to the next instruction
940 env->nip += 4;
943 * The Virtual Open Firmware (VOF) relies on the 'sc 1'
944 * instruction to communicate with QEMU. The pegasos2 machine
945 * uses VOF and the 74xx CPUs, so although the 74xx don't have
946 * HV mode, we need to keep hypercall support.
948 if (lev == 1 && cpu->vhyp) {
949 PPCVirtualHypervisorClass *vhc =
950 PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
951 vhc->hypercall(cpu->vhyp, cpu);
952 powerpc_reset_excp_state(cpu);
953 return;
956 break;
958 case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
959 case POWERPC_EXCP_DECR: /* Decrementer exception */
960 break;
961 case POWERPC_EXCP_RESET: /* System reset exception */
962 if (FIELD_EX64(env->msr, MSR, POW)) {
963 cpu_abort(env_cpu(env),
964 "Trying to deliver power-saving system reset "
965 "exception %d with no HV support\n", excp);
967 break;
968 case POWERPC_EXCP_TRACE: /* Trace exception */
969 break;
970 case POWERPC_EXCP_VPU: /* Vector unavailable exception */
971 break;
972 case POWERPC_EXCP_IABR: /* Instruction address breakpoint */
973 case POWERPC_EXCP_SMI: /* System management interrupt */
974 case POWERPC_EXCP_THERM: /* Thermal interrupt */
975 case POWERPC_EXCP_PERFM: /* Embedded performance monitor interrupt */
976 case POWERPC_EXCP_VPUA: /* Vector assist exception */
977 cpu_abort(env_cpu(env), "%s exception not implemented\n",
978 powerpc_excp_name(excp));
979 break;
980 default:
981 cpu_abort(env_cpu(env), "Invalid PowerPC exception %d. Aborting\n",
982 excp);
983 break;
986 if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) {
987 new_msr |= (target_ulong)1 << MSR_LE;
989 env->spr[SPR_SRR0] = env->nip;
990 env->spr[SPR_SRR1] = msr;
991 powerpc_set_excp_state(cpu, vector, new_msr);
994 static void powerpc_excp_booke(PowerPCCPU *cpu, int excp)
996 CPUPPCState *env = &cpu->env;
997 target_ulong msr, new_msr, vector;
998 int srr0 = SPR_SRR0, srr1 = SPR_SRR1;
1001 * Book E does not play games with certain bits of xSRR1 being MSR save
1002 * bits and others being error status. xSRR1 is the old MSR, period.
1004 msr = env->msr;
1006 /* new interrupt handler msr preserves ME unless explicitly overridden */
1007 new_msr = env->msr & ((target_ulong)1 << MSR_ME);
1009 /* HV emu assistance interrupt only exists on server arch 2.05 or later */
1010 if (excp == POWERPC_EXCP_HV_EMU) {
1011 excp = POWERPC_EXCP_PROGRAM;
1014 #ifdef TARGET_PPC64
1016 * SPEU and VPU share the same IVOR but they exist in different
1017 * processors. SPEU is e500v1/2 only and VPU is e6500 only.
1019 if (excp == POWERPC_EXCP_VPU) {
1020 excp = POWERPC_EXCP_SPEU;
1022 #endif
1024 vector = env->excp_vectors[excp];
1025 if (vector == (target_ulong)-1ULL) {
1026 cpu_abort(env_cpu(env),
1027 "Raised an exception without defined vector %d\n", excp);
1029 vector |= env->excp_prefix;
1031 switch (excp) {
1032 case POWERPC_EXCP_CRITICAL: /* Critical input */
1033 srr0 = SPR_BOOKE_CSRR0;
1034 srr1 = SPR_BOOKE_CSRR1;
1035 break;
1036 case POWERPC_EXCP_MCHECK: /* Machine check exception */
1037 powerpc_mcheck_checkstop(env);
1038 /* machine check exceptions don't have ME set */
1039 new_msr &= ~((target_ulong)1 << MSR_ME);
1041 /* FIXME: choose one or the other based on CPU type */
1042 srr0 = SPR_BOOKE_MCSRR0;
1043 srr1 = SPR_BOOKE_MCSRR1;
1045 env->spr[SPR_BOOKE_CSRR0] = env->nip;
1046 env->spr[SPR_BOOKE_CSRR1] = msr;
1048 break;
1049 case POWERPC_EXCP_DSI: /* Data storage exception */
1050 trace_ppc_excp_dsi(env->spr[SPR_BOOKE_ESR], env->spr[SPR_BOOKE_DEAR]);
1051 break;
1052 case POWERPC_EXCP_ISI: /* Instruction storage exception */
1053 trace_ppc_excp_isi(msr, env->nip);
1054 break;
1055 case POWERPC_EXCP_EXTERNAL: /* External input */
1056 if (env->mpic_proxy) {
1057 CPUState *cs = env_cpu(env);
1058 /* IACK the IRQ on delivery */
1059 env->spr[SPR_BOOKE_EPR] = ldl_phys(cs->as, env->mpic_iack);
1061 break;
1062 case POWERPC_EXCP_ALIGN: /* Alignment exception */
1063 break;
1064 case POWERPC_EXCP_PROGRAM: /* Program exception */
1065 switch (env->error_code & ~0xF) {
1066 case POWERPC_EXCP_FP:
1067 if (!FIELD_EX64_FE(env->msr) || !FIELD_EX64(env->msr, MSR, FP)) {
1068 trace_ppc_excp_fp_ignore();
1069 powerpc_reset_excp_state(cpu);
1070 return;
1073 * NIP always points to the faulting instruction for FP exceptions,
1074 * so always use store_next and claim we are precise in the MSR.
1076 msr |= 0x00100000;
1077 env->spr[SPR_BOOKE_ESR] = ESR_FP;
1078 break;
1079 case POWERPC_EXCP_INVAL:
1080 trace_ppc_excp_inval(env->nip);
1081 msr |= 0x00080000;
1082 env->spr[SPR_BOOKE_ESR] = ESR_PIL;
1083 break;
1084 case POWERPC_EXCP_PRIV:
1085 msr |= 0x00040000;
1086 env->spr[SPR_BOOKE_ESR] = ESR_PPR;
1087 break;
1088 case POWERPC_EXCP_TRAP:
1089 msr |= 0x00020000;
1090 env->spr[SPR_BOOKE_ESR] = ESR_PTR;
1091 break;
1092 default:
1093 /* Should never occur */
1094 cpu_abort(env_cpu(env), "Invalid program exception %d. Aborting\n",
1095 env->error_code);
1096 break;
1098 break;
1099 case POWERPC_EXCP_SYSCALL: /* System call exception */
1100 dump_syscall(env);
1103 * We need to correct the NIP which in this case is supposed
1104 * to point to the next instruction
1106 env->nip += 4;
1107 break;
1108 case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
1109 case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */
1110 case POWERPC_EXCP_DECR: /* Decrementer exception */
1111 break;
1112 case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt */
1113 /* FIT on 4xx */
1114 trace_ppc_excp_print("FIT");
1115 break;
1116 case POWERPC_EXCP_WDT: /* Watchdog timer interrupt */
1117 trace_ppc_excp_print("WDT");
1118 srr0 = SPR_BOOKE_CSRR0;
1119 srr1 = SPR_BOOKE_CSRR1;
1120 break;
1121 case POWERPC_EXCP_DTLB: /* Data TLB error */
1122 case POWERPC_EXCP_ITLB: /* Instruction TLB error */
1123 break;
1124 case POWERPC_EXCP_DEBUG: /* Debug interrupt */
1125 if (env->flags & POWERPC_FLAG_DE) {
1126 /* FIXME: choose one or the other based on CPU type */
1127 srr0 = SPR_BOOKE_DSRR0;
1128 srr1 = SPR_BOOKE_DSRR1;
1130 env->spr[SPR_BOOKE_CSRR0] = env->nip;
1131 env->spr[SPR_BOOKE_CSRR1] = msr;
1133 /* DBSR already modified by caller */
1134 } else {
1135 cpu_abort(env_cpu(env),
1136 "Debug exception triggered on unsupported model\n");
1138 break;
1139 case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavailable/VPU */
1140 env->spr[SPR_BOOKE_ESR] = ESR_SPV;
1141 break;
1142 case POWERPC_EXCP_DOORI: /* Embedded doorbell interrupt */
1143 break;
1144 case POWERPC_EXCP_DOORCI: /* Embedded doorbell critical interrupt */
1145 srr0 = SPR_BOOKE_CSRR0;
1146 srr1 = SPR_BOOKE_CSRR1;
1147 break;
1148 case POWERPC_EXCP_RESET: /* System reset exception */
1149 if (FIELD_EX64(env->msr, MSR, POW)) {
1150 cpu_abort(env_cpu(env),
1151 "Trying to deliver power-saving system reset "
1152 "exception %d with no HV support\n", excp);
1154 break;
1155 case POWERPC_EXCP_EFPDI: /* Embedded floating-point data interrupt */
1156 case POWERPC_EXCP_EFPRI: /* Embedded floating-point round interrupt */
1157 cpu_abort(env_cpu(env), "%s exception not implemented\n",
1158 powerpc_excp_name(excp));
1159 break;
1160 default:
1161 cpu_abort(env_cpu(env), "Invalid PowerPC exception %d. Aborting\n",
1162 excp);
1163 break;
1166 #if defined(TARGET_PPC64)
1167 if (env->spr[SPR_BOOKE_EPCR] & EPCR_ICM) {
1168 /* Cat.64-bit: EPCR.ICM is copied to MSR.CM */
1169 new_msr |= (target_ulong)1 << MSR_CM;
1170 } else {
1171 vector = (uint32_t)vector;
1173 #endif
1175 env->spr[srr0] = env->nip;
1176 env->spr[srr1] = msr;
1177 powerpc_set_excp_state(cpu, vector, new_msr);
1181 * When running a nested HV guest under vhyp, external interrupts are
1182 * delivered as HVIRT.
1184 static bool books_vhyp_promotes_external_to_hvirt(PowerPCCPU *cpu)
1186 if (cpu->vhyp) {
1187 return vhyp_cpu_in_nested(cpu);
1189 return false;
1192 #ifdef TARGET_PPC64
1194 * When running under vhyp, hcalls are always intercepted and sent to the
1195 * vhc->hypercall handler.
1197 static bool books_vhyp_handles_hcall(PowerPCCPU *cpu)
1199 if (cpu->vhyp) {
1200 return !vhyp_cpu_in_nested(cpu);
1202 return false;
1206 * When running a nested KVM HV guest under vhyp, HV exceptions are not
1207 * delivered to the guest (because there is no concept of HV support), but
1208 * rather they are sent to the vhyp to exit from the L2 back to the L1 and
1209 * return from the H_ENTER_NESTED hypercall.
1211 static bool books_vhyp_handles_hv_excp(PowerPCCPU *cpu)
1213 if (cpu->vhyp) {
1214 return vhyp_cpu_in_nested(cpu);
1216 return false;
1219 #ifdef CONFIG_TCG
1220 static bool is_prefix_insn(CPUPPCState *env, uint32_t insn)
1222 if (!(env->insns_flags2 & PPC2_ISA310)) {
1223 return false;
1225 return ((insn & 0xfc000000) == 0x04000000);
1228 static bool is_prefix_insn_excp(PowerPCCPU *cpu, int excp)
1230 CPUPPCState *env = &cpu->env;
1232 if (!(env->insns_flags2 & PPC2_ISA310)) {
1233 return false;
1236 if (!tcg_enabled()) {
1238 * This does not load instructions and set the prefix bit correctly
1239 * for injected interrupts with KVM. That may have to be discovered
1240 * and set by the KVM layer before injecting.
1242 return false;
1245 switch (excp) {
1246 case POWERPC_EXCP_MCHECK:
1247 if (!(env->error_code & PPC_BIT(42))) {
1249 * Fetch attempt caused a machine check, so attempting to fetch
1250 * again would cause a recursive machine check.
1252 return false;
1254 break;
1255 case POWERPC_EXCP_HDSI:
1256 /* HDSI PRTABLE_FAULT has the originating access type in error_code */
1257 if ((env->spr[SPR_HDSISR] & DSISR_PRTABLE_FAULT) &&
1258 (env->error_code == MMU_INST_FETCH)) {
1260 * Fetch failed due to partition scope translation, so prefix
1261 * indication is not relevant (and attempting to load the
1262 * instruction at NIP would cause recursive faults with the same
1263 * translation).
1265 return false;
1267 break;
1269 case POWERPC_EXCP_DSI:
1270 case POWERPC_EXCP_DSEG:
1271 case POWERPC_EXCP_ALIGN:
1272 case POWERPC_EXCP_PROGRAM:
1273 case POWERPC_EXCP_FPU:
1274 case POWERPC_EXCP_TRACE:
1275 case POWERPC_EXCP_HV_EMU:
1276 case POWERPC_EXCP_VPU:
1277 case POWERPC_EXCP_VSXU:
1278 case POWERPC_EXCP_FU:
1279 case POWERPC_EXCP_HV_FU:
1280 break;
1281 default:
1282 return false;
1285 return is_prefix_insn(env, ppc_ldl_code(env, env->nip));
1287 #else
1288 static bool is_prefix_insn_excp(PowerPCCPU *cpu, int excp)
1290 return false;
1292 #endif
1294 static void powerpc_excp_books(PowerPCCPU *cpu, int excp)
1296 CPUPPCState *env = &cpu->env;
1297 target_ulong msr, new_msr, vector;
1298 int srr0 = SPR_SRR0, srr1 = SPR_SRR1, lev = -1;
1300 /* new srr1 value excluding must-be-zero bits */
1301 msr = env->msr & ~0x783f0000ULL;
1304 * new interrupt handler msr preserves HV and ME unless explicitly
1305 * overridden
1307 new_msr = env->msr & (((target_ulong)1 << MSR_ME) | MSR_HVB);
1310 * check for special resume at 0x100 from doze/nap/sleep/winkle on
1311 * P7/P8/P9
1313 if (env->resume_as_sreset) {
1314 excp = powerpc_reset_wakeup(env, excp, &msr);
1318 * We don't want to generate a Hypervisor Emulation Assistance
1319 * Interrupt if we don't have HVB in msr_mask (PAPR mode),
1320 * unless running a nested-hv guest, in which case the L1
1321 * kernel wants the interrupt.
1323 if (excp == POWERPC_EXCP_HV_EMU && !(env->msr_mask & MSR_HVB) &&
1324 !books_vhyp_handles_hv_excp(cpu)) {
1325 excp = POWERPC_EXCP_PROGRAM;
1328 vector = env->excp_vectors[excp];
1329 if (vector == (target_ulong)-1ULL) {
1330 cpu_abort(env_cpu(env),
1331 "Raised an exception without defined vector %d\n", excp);
1333 vector |= env->excp_prefix;
1335 if (is_prefix_insn_excp(cpu, excp)) {
1336 msr |= PPC_BIT(34);
1339 switch (excp) {
1340 case POWERPC_EXCP_MCHECK: /* Machine check exception */
1341 powerpc_mcheck_checkstop(env);
1342 if (env->msr_mask & MSR_HVB) {
1344 * ISA specifies HV, but can be delivered to guest with HV
1345 * clear (e.g., see FWNMI in PAPR).
1347 new_msr |= (target_ulong)MSR_HVB;
1349 /* machine check exceptions don't have ME set */
1350 new_msr &= ~((target_ulong)1 << MSR_ME);
1352 msr |= env->error_code;
1353 break;
1355 case POWERPC_EXCP_DSI: /* Data storage exception */
1356 trace_ppc_excp_dsi(env->spr[SPR_DSISR], env->spr[SPR_DAR]);
1357 break;
1358 case POWERPC_EXCP_ISI: /* Instruction storage exception */
1359 trace_ppc_excp_isi(msr, env->nip);
1360 msr |= env->error_code;
1361 break;
1362 case POWERPC_EXCP_EXTERNAL: /* External input */
1364 bool lpes0;
1366 /* LPES0 is only taken into consideration if we support HV mode */
1367 if (!env->has_hv_mode) {
1368 break;
1370 lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0);
1371 if (!lpes0) {
1372 new_msr |= (target_ulong)MSR_HVB;
1373 new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
1374 srr0 = SPR_HSRR0;
1375 srr1 = SPR_HSRR1;
1377 break;
1379 case POWERPC_EXCP_ALIGN: /* Alignment exception */
1380 /* Optional DSISR update was removed from ISA v3.0 */
1381 if (!(env->insns_flags2 & PPC2_ISA300)) {
1382 /* Get rS/rD and rA from faulting opcode */
1384 * Note: the opcode fields will not be set properly for a
1385 * direct store load/store, but nobody cares as nobody
1386 * actually uses direct store segments.
1388 env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16;
1390 break;
1391 case POWERPC_EXCP_PROGRAM: /* Program exception */
1392 switch (env->error_code & ~0xF) {
1393 case POWERPC_EXCP_FP:
1394 if (!FIELD_EX64_FE(env->msr) || !FIELD_EX64(env->msr, MSR, FP)) {
1395 trace_ppc_excp_fp_ignore();
1396 powerpc_reset_excp_state(cpu);
1397 return;
1400 * NIP always points to the faulting instruction for FP exceptions,
1401 * so always use store_next and claim we are precise in the MSR.
1403 msr |= 0x00100000;
1404 break;
1405 case POWERPC_EXCP_INVAL:
1406 trace_ppc_excp_inval(env->nip);
1407 msr |= 0x00080000;
1408 break;
1409 case POWERPC_EXCP_PRIV:
1410 msr |= 0x00040000;
1411 break;
1412 case POWERPC_EXCP_TRAP:
1413 msr |= 0x00020000;
1414 break;
1415 default:
1416 /* Should never occur */
1417 cpu_abort(env_cpu(env), "Invalid program exception %d. Aborting\n",
1418 env->error_code);
1419 break;
1421 break;
1422 case POWERPC_EXCP_SYSCALL: /* System call exception */
1423 lev = env->error_code;
1425 if (lev == 1 && cpu->vhyp) {
1426 dump_hcall(env);
1427 } else {
1428 dump_syscall(env);
1432 * We need to correct the NIP which in this case is supposed
1433 * to point to the next instruction
1435 env->nip += 4;
1437 /* "PAPR mode" built-in hypercall emulation */
1438 if (lev == 1 && books_vhyp_handles_hcall(cpu)) {
1439 PPCVirtualHypervisorClass *vhc =
1440 PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
1441 vhc->hypercall(cpu->vhyp, cpu);
1442 powerpc_reset_excp_state(cpu);
1443 return;
1445 if (env->insns_flags2 & PPC2_ISA310) {
1446 /* ISAv3.1 puts LEV into SRR1 */
1447 msr |= lev << 20;
1449 if (lev == 1) {
1450 new_msr |= (target_ulong)MSR_HVB;
1452 break;
1453 case POWERPC_EXCP_SYSCALL_VECTORED: /* scv exception */
1454 lev = env->error_code;
1455 dump_syscall(env);
1456 env->nip += 4;
1457 new_msr |= env->msr & ((target_ulong)1 << MSR_EE);
1458 new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
1460 vector += lev * 0x20;
1462 env->lr = env->nip;
1463 env->ctr = msr;
1464 break;
1465 case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
1466 case POWERPC_EXCP_DECR: /* Decrementer exception */
1467 break;
1468 case POWERPC_EXCP_RESET: /* System reset exception */
1469 /* A power-saving exception sets ME, otherwise it is unchanged */
1470 if (FIELD_EX64(env->msr, MSR, POW)) {
1471 /* indicate that we resumed from power save mode */
1472 msr |= 0x10000;
1473 new_msr |= ((target_ulong)1 << MSR_ME);
1475 if (env->msr_mask & MSR_HVB) {
1477 * ISA specifies HV, but can be delivered to guest with HV
1478 * clear (e.g., see FWNMI in PAPR, NMI injection in QEMU).
1480 new_msr |= (target_ulong)MSR_HVB;
1481 } else {
1482 if (FIELD_EX64(env->msr, MSR, POW)) {
1483 cpu_abort(env_cpu(env),
1484 "Trying to deliver power-saving system reset "
1485 "exception %d with no HV support\n", excp);
1488 break;
1489 case POWERPC_EXCP_TRACE: /* Trace exception */
1490 msr |= env->error_code;
1491 /* fall through */
1492 case POWERPC_EXCP_DSEG: /* Data segment exception */
1493 case POWERPC_EXCP_ISEG: /* Instruction segment exception */
1494 case POWERPC_EXCP_SDOOR: /* Doorbell interrupt */
1495 case POWERPC_EXCP_PERFM: /* Performance monitor interrupt */
1496 break;
1497 case POWERPC_EXCP_HISI: /* Hypervisor instruction storage exception */
1498 msr |= env->error_code;
1499 /* fall through */
1500 case POWERPC_EXCP_HDECR: /* Hypervisor decrementer exception */
1501 case POWERPC_EXCP_HDSI: /* Hypervisor data storage exception */
1502 case POWERPC_EXCP_SDOOR_HV: /* Hypervisor Doorbell interrupt */
1503 case POWERPC_EXCP_HVIRT: /* Hypervisor virtualization */
1504 srr0 = SPR_HSRR0;
1505 srr1 = SPR_HSRR1;
1506 new_msr |= (target_ulong)MSR_HVB;
1507 new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
1508 break;
1509 #ifdef CONFIG_TCG
1510 case POWERPC_EXCP_HV_EMU: {
1511 uint32_t insn = ppc_ldl_code(env, env->nip);
1512 env->spr[SPR_HEIR] = insn;
1513 if (is_prefix_insn(env, insn)) {
1514 uint32_t insn2 = ppc_ldl_code(env, env->nip + 4);
1515 env->spr[SPR_HEIR] <<= 32;
1516 env->spr[SPR_HEIR] |= insn2;
1518 srr0 = SPR_HSRR0;
1519 srr1 = SPR_HSRR1;
1520 new_msr |= (target_ulong)MSR_HVB;
1521 new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
1522 break;
1524 #endif
1525 case POWERPC_EXCP_VPU: /* Vector unavailable exception */
1526 case POWERPC_EXCP_VSXU: /* VSX unavailable exception */
1527 case POWERPC_EXCP_FU: /* Facility unavailable exception */
1528 env->spr[SPR_FSCR] |= ((target_ulong)env->error_code << 56);
1529 break;
1530 case POWERPC_EXCP_HV_FU: /* Hypervisor Facility Unavailable Exception */
1531 env->spr[SPR_HFSCR] |= ((target_ulong)env->error_code << FSCR_IC_POS);
1532 srr0 = SPR_HSRR0;
1533 srr1 = SPR_HSRR1;
1534 new_msr |= (target_ulong)MSR_HVB;
1535 new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
1536 break;
1537 case POWERPC_EXCP_PERFM_EBB: /* Performance Monitor EBB Exception */
1538 case POWERPC_EXCP_EXTERNAL_EBB: /* External EBB Exception */
1539 env->spr[SPR_BESCR] &= ~BESCR_GE;
1542 * Save NIP for rfebb insn in SPR_EBBRR. Next nip is
1543 * stored in the EBB Handler SPR_EBBHR.
1545 env->spr[SPR_EBBRR] = env->nip;
1546 powerpc_set_excp_state(cpu, env->spr[SPR_EBBHR], env->msr);
1549 * This exception is handled in userspace. No need to proceed.
1551 return;
1552 case POWERPC_EXCP_THERM: /* Thermal interrupt */
1553 case POWERPC_EXCP_VPUA: /* Vector assist exception */
1554 case POWERPC_EXCP_MAINT: /* Maintenance exception */
1555 case POWERPC_EXCP_HV_MAINT: /* Hypervisor Maintenance exception */
1556 cpu_abort(env_cpu(env), "%s exception not implemented\n",
1557 powerpc_excp_name(excp));
1558 break;
1559 default:
1560 cpu_abort(env_cpu(env), "Invalid PowerPC exception %d. Aborting\n",
1561 excp);
1562 break;
1565 if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) {
1566 new_msr |= (target_ulong)1 << MSR_LE;
1568 new_msr |= (target_ulong)1 << MSR_SF;
1570 if (excp != POWERPC_EXCP_SYSCALL_VECTORED) {
1571 env->spr[srr0] = env->nip;
1572 env->spr[srr1] = msr;
1575 if ((new_msr & MSR_HVB) && books_vhyp_handles_hv_excp(cpu)) {
1576 PPCVirtualHypervisorClass *vhc =
1577 PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
1578 /* Deliver interrupt to L1 by returning from the H_ENTER_NESTED call */
1579 vhc->deliver_hv_excp(cpu, excp);
1580 powerpc_reset_excp_state(cpu);
1581 } else {
1582 /* Sanity check */
1583 if (!(env->msr_mask & MSR_HVB) && srr0 == SPR_HSRR0) {
1584 cpu_abort(env_cpu(env), "Trying to deliver HV exception (HSRR) %d "
1585 "with no HV support\n", excp);
1587 /* This can update new_msr and vector if AIL applies */
1588 ppc_excp_apply_ail(cpu, excp, msr, &new_msr, &vector);
1589 powerpc_set_excp_state(cpu, vector, new_msr);
1592 #else
1593 static inline void powerpc_excp_books(PowerPCCPU *cpu, int excp)
1595 g_assert_not_reached();
1597 #endif
1599 static void powerpc_excp(PowerPCCPU *cpu, int excp)
1601 CPUPPCState *env = &cpu->env;
1603 if (excp <= POWERPC_EXCP_NONE || excp >= POWERPC_EXCP_NB) {
1604 cpu_abort(env_cpu(env), "Invalid PowerPC exception %d. Aborting\n",
1605 excp);
1608 qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx
1609 " => %s (%d) error=%02x\n", env->nip, powerpc_excp_name(excp),
1610 excp, env->error_code);
1611 env->excp_stats[excp]++;
1613 switch (env->excp_model) {
1614 case POWERPC_EXCP_40x:
1615 powerpc_excp_40x(cpu, excp);
1616 break;
1617 case POWERPC_EXCP_6xx:
1618 powerpc_excp_6xx(cpu, excp);
1619 break;
1620 case POWERPC_EXCP_7xx:
1621 powerpc_excp_7xx(cpu, excp);
1622 break;
1623 case POWERPC_EXCP_74xx:
1624 powerpc_excp_74xx(cpu, excp);
1625 break;
1626 case POWERPC_EXCP_BOOKE:
1627 powerpc_excp_booke(cpu, excp);
1628 break;
1629 case POWERPC_EXCP_970:
1630 case POWERPC_EXCP_POWER7:
1631 case POWERPC_EXCP_POWER8:
1632 case POWERPC_EXCP_POWER9:
1633 case POWERPC_EXCP_POWER10:
1634 powerpc_excp_books(cpu, excp);
1635 break;
1636 default:
1637 g_assert_not_reached();
1641 void ppc_cpu_do_interrupt(CPUState *cs)
1643 PowerPCCPU *cpu = POWERPC_CPU(cs);
1645 powerpc_excp(cpu, cs->exception_index);
1648 #if defined(TARGET_PPC64)
1649 #define P7_UNUSED_INTERRUPTS \
1650 (PPC_INTERRUPT_RESET | PPC_INTERRUPT_HVIRT | PPC_INTERRUPT_CEXT | \
1651 PPC_INTERRUPT_WDT | PPC_INTERRUPT_CDOORBELL | PPC_INTERRUPT_FIT | \
1652 PPC_INTERRUPT_PIT | PPC_INTERRUPT_DOORBELL | PPC_INTERRUPT_HDOORBELL | \
1653 PPC_INTERRUPT_THERM | PPC_INTERRUPT_EBB)
1655 static int p7_interrupt_powersave(CPUPPCState *env)
1657 if ((env->pending_interrupts & PPC_INTERRUPT_EXT) &&
1658 (env->spr[SPR_LPCR] & LPCR_P7_PECE0)) {
1659 return PPC_INTERRUPT_EXT;
1661 if ((env->pending_interrupts & PPC_INTERRUPT_DECR) &&
1662 (env->spr[SPR_LPCR] & LPCR_P7_PECE1)) {
1663 return PPC_INTERRUPT_DECR;
1665 if ((env->pending_interrupts & PPC_INTERRUPT_MCK) &&
1666 (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) {
1667 return PPC_INTERRUPT_MCK;
1669 if ((env->pending_interrupts & PPC_INTERRUPT_HMI) &&
1670 (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) {
1671 return PPC_INTERRUPT_HMI;
1673 if (env->pending_interrupts & PPC_INTERRUPT_RESET) {
1674 return PPC_INTERRUPT_RESET;
1676 return 0;
1679 static int p7_next_unmasked_interrupt(CPUPPCState *env)
1681 CPUState *cs = env_cpu(env);
1683 /* Ignore MSR[EE] when coming out of some power management states */
1684 bool msr_ee = FIELD_EX64(env->msr, MSR, EE) || env->resume_as_sreset;
1686 assert((env->pending_interrupts & P7_UNUSED_INTERRUPTS) == 0);
1688 if (cs->halted) {
1689 /* LPCR[PECE] controls which interrupts can exit power-saving mode */
1690 return p7_interrupt_powersave(env);
1693 /* Machine check exception */
1694 if (env->pending_interrupts & PPC_INTERRUPT_MCK) {
1695 return PPC_INTERRUPT_MCK;
1698 /* Hypervisor decrementer exception */
1699 if (env->pending_interrupts & PPC_INTERRUPT_HDECR) {
1700 /* LPCR will be clear when not supported so this will work */
1701 bool hdice = !!(env->spr[SPR_LPCR] & LPCR_HDICE);
1702 if ((msr_ee || !FIELD_EX64_HV(env->msr)) && hdice) {
1703 /* HDEC clears on delivery */
1704 return PPC_INTERRUPT_HDECR;
1708 /* External interrupt can ignore MSR:EE under some circumstances */
1709 if (env->pending_interrupts & PPC_INTERRUPT_EXT) {
1710 bool lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0);
1711 bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
1712 /* HEIC blocks delivery to the hypervisor */
1713 if ((msr_ee && !(heic && FIELD_EX64_HV(env->msr) &&
1714 !FIELD_EX64(env->msr, MSR, PR))) ||
1715 (env->has_hv_mode && !FIELD_EX64_HV(env->msr) && !lpes0)) {
1716 return PPC_INTERRUPT_EXT;
1719 if (msr_ee != 0) {
1720 /* Decrementer exception */
1721 if (env->pending_interrupts & PPC_INTERRUPT_DECR) {
1722 return PPC_INTERRUPT_DECR;
1724 if (env->pending_interrupts & PPC_INTERRUPT_PERFM) {
1725 return PPC_INTERRUPT_PERFM;
1729 return 0;
1732 #define P8_UNUSED_INTERRUPTS \
1733 (PPC_INTERRUPT_RESET | PPC_INTERRUPT_DEBUG | PPC_INTERRUPT_HVIRT | \
1734 PPC_INTERRUPT_CEXT | PPC_INTERRUPT_WDT | PPC_INTERRUPT_CDOORBELL | \
1735 PPC_INTERRUPT_FIT | PPC_INTERRUPT_PIT | PPC_INTERRUPT_THERM)
1737 static int p8_interrupt_powersave(CPUPPCState *env)
1739 if ((env->pending_interrupts & PPC_INTERRUPT_EXT) &&
1740 (env->spr[SPR_LPCR] & LPCR_P8_PECE2)) {
1741 return PPC_INTERRUPT_EXT;
1743 if ((env->pending_interrupts & PPC_INTERRUPT_DECR) &&
1744 (env->spr[SPR_LPCR] & LPCR_P8_PECE3)) {
1745 return PPC_INTERRUPT_DECR;
1747 if ((env->pending_interrupts & PPC_INTERRUPT_MCK) &&
1748 (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) {
1749 return PPC_INTERRUPT_MCK;
1751 if ((env->pending_interrupts & PPC_INTERRUPT_HMI) &&
1752 (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) {
1753 return PPC_INTERRUPT_HMI;
1755 if ((env->pending_interrupts & PPC_INTERRUPT_DOORBELL) &&
1756 (env->spr[SPR_LPCR] & LPCR_P8_PECE0)) {
1757 return PPC_INTERRUPT_DOORBELL;
1759 if ((env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) &&
1760 (env->spr[SPR_LPCR] & LPCR_P8_PECE1)) {
1761 return PPC_INTERRUPT_HDOORBELL;
1763 if (env->pending_interrupts & PPC_INTERRUPT_RESET) {
1764 return PPC_INTERRUPT_RESET;
1766 return 0;
1769 static int p8_next_unmasked_interrupt(CPUPPCState *env)
1771 CPUState *cs = env_cpu(env);
1773 /* Ignore MSR[EE] when coming out of some power management states */
1774 bool msr_ee = FIELD_EX64(env->msr, MSR, EE) || env->resume_as_sreset;
1776 assert((env->pending_interrupts & P8_UNUSED_INTERRUPTS) == 0);
1778 if (cs->halted) {
1779 /* LPCR[PECE] controls which interrupts can exit power-saving mode */
1780 return p8_interrupt_powersave(env);
1783 /* Machine check exception */
1784 if (env->pending_interrupts & PPC_INTERRUPT_MCK) {
1785 return PPC_INTERRUPT_MCK;
1788 /* Hypervisor decrementer exception */
1789 if (env->pending_interrupts & PPC_INTERRUPT_HDECR) {
1790 /* LPCR will be clear when not supported so this will work */
1791 bool hdice = !!(env->spr[SPR_LPCR] & LPCR_HDICE);
1792 if ((msr_ee || !FIELD_EX64_HV(env->msr)) && hdice) {
1793 /* HDEC clears on delivery */
1794 return PPC_INTERRUPT_HDECR;
1798 /* External interrupt can ignore MSR:EE under some circumstances */
1799 if (env->pending_interrupts & PPC_INTERRUPT_EXT) {
1800 bool lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0);
1801 bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
1802 /* HEIC blocks delivery to the hypervisor */
1803 if ((msr_ee && !(heic && FIELD_EX64_HV(env->msr) &&
1804 !FIELD_EX64(env->msr, MSR, PR))) ||
1805 (env->has_hv_mode && !FIELD_EX64_HV(env->msr) && !lpes0)) {
1806 return PPC_INTERRUPT_EXT;
1809 if (msr_ee != 0) {
1810 /* Decrementer exception */
1811 if (env->pending_interrupts & PPC_INTERRUPT_DECR) {
1812 return PPC_INTERRUPT_DECR;
1814 if (env->pending_interrupts & PPC_INTERRUPT_DOORBELL) {
1815 return PPC_INTERRUPT_DOORBELL;
1817 if (env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) {
1818 return PPC_INTERRUPT_HDOORBELL;
1820 if (env->pending_interrupts & PPC_INTERRUPT_PERFM) {
1821 return PPC_INTERRUPT_PERFM;
1823 /* EBB exception */
1824 if (env->pending_interrupts & PPC_INTERRUPT_EBB) {
1826 * EBB exception must be taken in problem state and
1827 * with BESCR_GE set.
1829 if (FIELD_EX64(env->msr, MSR, PR) &&
1830 (env->spr[SPR_BESCR] & BESCR_GE)) {
1831 return PPC_INTERRUPT_EBB;
1836 return 0;
1839 #define P9_UNUSED_INTERRUPTS \
1840 (PPC_INTERRUPT_RESET | PPC_INTERRUPT_DEBUG | PPC_INTERRUPT_CEXT | \
1841 PPC_INTERRUPT_WDT | PPC_INTERRUPT_CDOORBELL | PPC_INTERRUPT_FIT | \
1842 PPC_INTERRUPT_PIT | PPC_INTERRUPT_THERM)
1844 static int p9_interrupt_powersave(CPUPPCState *env)
1846 /* External Exception */
1847 if ((env->pending_interrupts & PPC_INTERRUPT_EXT) &&
1848 (env->spr[SPR_LPCR] & LPCR_EEE)) {
1849 bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
1850 if (!heic || !FIELD_EX64_HV(env->msr) ||
1851 FIELD_EX64(env->msr, MSR, PR)) {
1852 return PPC_INTERRUPT_EXT;
1855 /* Decrementer Exception */
1856 if ((env->pending_interrupts & PPC_INTERRUPT_DECR) &&
1857 (env->spr[SPR_LPCR] & LPCR_DEE)) {
1858 return PPC_INTERRUPT_DECR;
1860 /* Machine Check or Hypervisor Maintenance Exception */
1861 if (env->spr[SPR_LPCR] & LPCR_OEE) {
1862 if (env->pending_interrupts & PPC_INTERRUPT_MCK) {
1863 return PPC_INTERRUPT_MCK;
1865 if (env->pending_interrupts & PPC_INTERRUPT_HMI) {
1866 return PPC_INTERRUPT_HMI;
1869 /* Privileged Doorbell Exception */
1870 if ((env->pending_interrupts & PPC_INTERRUPT_DOORBELL) &&
1871 (env->spr[SPR_LPCR] & LPCR_PDEE)) {
1872 return PPC_INTERRUPT_DOORBELL;
1874 /* Hypervisor Doorbell Exception */
1875 if ((env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) &&
1876 (env->spr[SPR_LPCR] & LPCR_HDEE)) {
1877 return PPC_INTERRUPT_HDOORBELL;
1879 /* Hypervisor virtualization exception */
1880 if ((env->pending_interrupts & PPC_INTERRUPT_HVIRT) &&
1881 (env->spr[SPR_LPCR] & LPCR_HVEE)) {
1882 return PPC_INTERRUPT_HVIRT;
1884 if (env->pending_interrupts & PPC_INTERRUPT_RESET) {
1885 return PPC_INTERRUPT_RESET;
1887 return 0;
1890 static int p9_next_unmasked_interrupt(CPUPPCState *env)
1892 CPUState *cs = env_cpu(env);
1894 /* Ignore MSR[EE] when coming out of some power management states */
1895 bool msr_ee = FIELD_EX64(env->msr, MSR, EE) || env->resume_as_sreset;
1897 assert((env->pending_interrupts & P9_UNUSED_INTERRUPTS) == 0);
1899 if (cs->halted) {
1900 if (env->spr[SPR_PSSCR] & PSSCR_EC) {
1902 * When PSSCR[EC] is set, LPCR[PECE] controls which interrupts can
1903 * wakeup the processor
1905 return p9_interrupt_powersave(env);
1906 } else {
1908 * When it's clear, any system-caused exception exits power-saving
1909 * mode, even the ones that gate on MSR[EE].
1911 msr_ee = true;
1915 /* Machine check exception */
1916 if (env->pending_interrupts & PPC_INTERRUPT_MCK) {
1917 return PPC_INTERRUPT_MCK;
1920 /* Hypervisor decrementer exception */
1921 if (env->pending_interrupts & PPC_INTERRUPT_HDECR) {
1922 /* LPCR will be clear when not supported so this will work */
1923 bool hdice = !!(env->spr[SPR_LPCR] & LPCR_HDICE);
1924 if ((msr_ee || !FIELD_EX64_HV(env->msr)) && hdice) {
1925 /* HDEC clears on delivery */
1926 return PPC_INTERRUPT_HDECR;
1930 /* Hypervisor virtualization interrupt */
1931 if (env->pending_interrupts & PPC_INTERRUPT_HVIRT) {
1932 /* LPCR will be clear when not supported so this will work */
1933 bool hvice = !!(env->spr[SPR_LPCR] & LPCR_HVICE);
1934 if ((msr_ee || !FIELD_EX64_HV(env->msr)) && hvice) {
1935 return PPC_INTERRUPT_HVIRT;
1939 /* External interrupt can ignore MSR:EE under some circumstances */
1940 if (env->pending_interrupts & PPC_INTERRUPT_EXT) {
1941 bool lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0);
1942 bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
1943 /* HEIC blocks delivery to the hypervisor */
1944 if ((msr_ee && !(heic && FIELD_EX64_HV(env->msr) &&
1945 !FIELD_EX64(env->msr, MSR, PR))) ||
1946 (env->has_hv_mode && !FIELD_EX64_HV(env->msr) && !lpes0)) {
1947 return PPC_INTERRUPT_EXT;
1950 if (msr_ee != 0) {
1951 /* Decrementer exception */
1952 if (env->pending_interrupts & PPC_INTERRUPT_DECR) {
1953 return PPC_INTERRUPT_DECR;
1955 if (env->pending_interrupts & PPC_INTERRUPT_DOORBELL) {
1956 return PPC_INTERRUPT_DOORBELL;
1958 if (env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) {
1959 return PPC_INTERRUPT_HDOORBELL;
1961 if (env->pending_interrupts & PPC_INTERRUPT_PERFM) {
1962 return PPC_INTERRUPT_PERFM;
1964 /* EBB exception */
1965 if (env->pending_interrupts & PPC_INTERRUPT_EBB) {
1967 * EBB exception must be taken in problem state and
1968 * with BESCR_GE set.
1970 if (FIELD_EX64(env->msr, MSR, PR) &&
1971 (env->spr[SPR_BESCR] & BESCR_GE)) {
1972 return PPC_INTERRUPT_EBB;
1977 return 0;
1979 #endif
1981 static int ppc_next_unmasked_interrupt_generic(CPUPPCState *env)
1983 bool async_deliver;
1985 /* External reset */
1986 if (env->pending_interrupts & PPC_INTERRUPT_RESET) {
1987 return PPC_INTERRUPT_RESET;
1989 /* Machine check exception */
1990 if (env->pending_interrupts & PPC_INTERRUPT_MCK) {
1991 return PPC_INTERRUPT_MCK;
1993 #if 0 /* TODO */
1994 /* External debug exception */
1995 if (env->pending_interrupts & PPC_INTERRUPT_DEBUG) {
1996 return PPC_INTERRUPT_DEBUG;
1998 #endif
2001 * For interrupts that gate on MSR:EE, we need to do something a
2002 * bit more subtle, as we need to let them through even when EE is
2003 * clear when coming out of some power management states (in order
2004 * for them to become a 0x100).
2006 async_deliver = FIELD_EX64(env->msr, MSR, EE) || env->resume_as_sreset;
2008 /* Hypervisor decrementer exception */
2009 if (env->pending_interrupts & PPC_INTERRUPT_HDECR) {
2010 /* LPCR will be clear when not supported so this will work */
2011 bool hdice = !!(env->spr[SPR_LPCR] & LPCR_HDICE);
2012 if ((async_deliver || !FIELD_EX64_HV(env->msr)) && hdice) {
2013 /* HDEC clears on delivery */
2014 return PPC_INTERRUPT_HDECR;
2018 /* Hypervisor virtualization interrupt */
2019 if (env->pending_interrupts & PPC_INTERRUPT_HVIRT) {
2020 /* LPCR will be clear when not supported so this will work */
2021 bool hvice = !!(env->spr[SPR_LPCR] & LPCR_HVICE);
2022 if ((async_deliver || !FIELD_EX64_HV(env->msr)) && hvice) {
2023 return PPC_INTERRUPT_HVIRT;
2027 /* External interrupt can ignore MSR:EE under some circumstances */
2028 if (env->pending_interrupts & PPC_INTERRUPT_EXT) {
2029 bool lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0);
2030 bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
2031 /* HEIC blocks delivery to the hypervisor */
2032 if ((async_deliver && !(heic && FIELD_EX64_HV(env->msr) &&
2033 !FIELD_EX64(env->msr, MSR, PR))) ||
2034 (env->has_hv_mode && !FIELD_EX64_HV(env->msr) && !lpes0)) {
2035 return PPC_INTERRUPT_EXT;
2038 if (FIELD_EX64(env->msr, MSR, CE)) {
2039 /* External critical interrupt */
2040 if (env->pending_interrupts & PPC_INTERRUPT_CEXT) {
2041 return PPC_INTERRUPT_CEXT;
2044 if (async_deliver != 0) {
2045 /* Watchdog timer on embedded PowerPC */
2046 if (env->pending_interrupts & PPC_INTERRUPT_WDT) {
2047 return PPC_INTERRUPT_WDT;
2049 if (env->pending_interrupts & PPC_INTERRUPT_CDOORBELL) {
2050 return PPC_INTERRUPT_CDOORBELL;
2052 /* Fixed interval timer on embedded PowerPC */
2053 if (env->pending_interrupts & PPC_INTERRUPT_FIT) {
2054 return PPC_INTERRUPT_FIT;
2056 /* Programmable interval timer on embedded PowerPC */
2057 if (env->pending_interrupts & PPC_INTERRUPT_PIT) {
2058 return PPC_INTERRUPT_PIT;
2060 /* Decrementer exception */
2061 if (env->pending_interrupts & PPC_INTERRUPT_DECR) {
2062 return PPC_INTERRUPT_DECR;
2064 if (env->pending_interrupts & PPC_INTERRUPT_DOORBELL) {
2065 return PPC_INTERRUPT_DOORBELL;
2067 if (env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) {
2068 return PPC_INTERRUPT_HDOORBELL;
2070 if (env->pending_interrupts & PPC_INTERRUPT_PERFM) {
2071 return PPC_INTERRUPT_PERFM;
2073 /* Thermal interrupt */
2074 if (env->pending_interrupts & PPC_INTERRUPT_THERM) {
2075 return PPC_INTERRUPT_THERM;
2077 /* EBB exception */
2078 if (env->pending_interrupts & PPC_INTERRUPT_EBB) {
2080 * EBB exception must be taken in problem state and
2081 * with BESCR_GE set.
2083 if (FIELD_EX64(env->msr, MSR, PR) &&
2084 (env->spr[SPR_BESCR] & BESCR_GE)) {
2085 return PPC_INTERRUPT_EBB;
2090 return 0;
2093 static int ppc_next_unmasked_interrupt(CPUPPCState *env)
2095 switch (env->excp_model) {
2096 #if defined(TARGET_PPC64)
2097 case POWERPC_EXCP_POWER7:
2098 return p7_next_unmasked_interrupt(env);
2099 case POWERPC_EXCP_POWER8:
2100 return p8_next_unmasked_interrupt(env);
2101 case POWERPC_EXCP_POWER9:
2102 case POWERPC_EXCP_POWER10:
2103 return p9_next_unmasked_interrupt(env);
2104 #endif
2105 default:
2106 return ppc_next_unmasked_interrupt_generic(env);
2111 * Sets CPU_INTERRUPT_HARD if there is at least one unmasked interrupt to be
2112 * delivered and clears CPU_INTERRUPT_HARD otherwise.
2114 * This method is called by ppc_set_interrupt when an interrupt is raised or
2115 * lowered, and should also be called whenever an interrupt masking condition
2116 * is changed, e.g.:
2117 * - When relevant bits of MSR are altered, like EE, HV, PR, etc.;
2118 * - When relevant bits of LPCR are altered, like PECE, HDICE, HVICE, etc.;
2119 * - When PSSCR[EC] or env->resume_as_sreset are changed;
2120 * - When cs->halted is changed and the CPU has a different interrupt masking
2121 * logic in power-saving mode (e.g., POWER7/8/9/10);
2123 void ppc_maybe_interrupt(CPUPPCState *env)
2125 CPUState *cs = env_cpu(env);
2126 BQL_LOCK_GUARD();
2128 if (ppc_next_unmasked_interrupt(env)) {
2129 cpu_interrupt(cs, CPU_INTERRUPT_HARD);
2130 } else {
2131 cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
2135 #if defined(TARGET_PPC64)
2136 static void p7_deliver_interrupt(CPUPPCState *env, int interrupt)
2138 PowerPCCPU *cpu = env_archcpu(env);
2140 switch (interrupt) {
2141 case PPC_INTERRUPT_MCK: /* Machine check exception */
2142 env->pending_interrupts &= ~PPC_INTERRUPT_MCK;
2143 powerpc_excp(cpu, POWERPC_EXCP_MCHECK);
2144 break;
2146 case PPC_INTERRUPT_HDECR: /* Hypervisor decrementer exception */
2147 /* HDEC clears on delivery */
2148 env->pending_interrupts &= ~PPC_INTERRUPT_HDECR;
2149 powerpc_excp(cpu, POWERPC_EXCP_HDECR);
2150 break;
2152 case PPC_INTERRUPT_EXT:
2153 if (books_vhyp_promotes_external_to_hvirt(cpu)) {
2154 powerpc_excp(cpu, POWERPC_EXCP_HVIRT);
2155 } else {
2156 powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL);
2158 break;
2160 case PPC_INTERRUPT_DECR: /* Decrementer exception */
2161 powerpc_excp(cpu, POWERPC_EXCP_DECR);
2162 break;
2163 case PPC_INTERRUPT_PERFM:
2164 env->pending_interrupts &= ~PPC_INTERRUPT_PERFM;
2165 powerpc_excp(cpu, POWERPC_EXCP_PERFM);
2166 break;
2167 case 0:
2169 * This is a bug ! It means that has_work took us out of halt without
2170 * anything to deliver while in a PM state that requires getting
2171 * out via a 0x100
2173 * This means we will incorrectly execute past the power management
2174 * instruction instead of triggering a reset.
2176 * It generally means a discrepancy between the wakeup conditions in the
2177 * processor has_work implementation and the logic in this function.
2179 assert(!env->resume_as_sreset);
2180 break;
2181 default:
2182 cpu_abort(env_cpu(env), "Invalid PowerPC interrupt %d. Aborting\n",
2183 interrupt);
2187 static void p8_deliver_interrupt(CPUPPCState *env, int interrupt)
2189 PowerPCCPU *cpu = env_archcpu(env);
2191 switch (interrupt) {
2192 case PPC_INTERRUPT_MCK: /* Machine check exception */
2193 env->pending_interrupts &= ~PPC_INTERRUPT_MCK;
2194 powerpc_excp(cpu, POWERPC_EXCP_MCHECK);
2195 break;
2197 case PPC_INTERRUPT_HDECR: /* Hypervisor decrementer exception */
2198 /* HDEC clears on delivery */
2199 env->pending_interrupts &= ~PPC_INTERRUPT_HDECR;
2200 powerpc_excp(cpu, POWERPC_EXCP_HDECR);
2201 break;
2203 case PPC_INTERRUPT_EXT:
2204 if (books_vhyp_promotes_external_to_hvirt(cpu)) {
2205 powerpc_excp(cpu, POWERPC_EXCP_HVIRT);
2206 } else {
2207 powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL);
2209 break;
2211 case PPC_INTERRUPT_DECR: /* Decrementer exception */
2212 powerpc_excp(cpu, POWERPC_EXCP_DECR);
2213 break;
2214 case PPC_INTERRUPT_DOORBELL:
2215 env->pending_interrupts &= ~PPC_INTERRUPT_DOORBELL;
2216 if (is_book3s_arch2x(env)) {
2217 powerpc_excp(cpu, POWERPC_EXCP_SDOOR);
2218 } else {
2219 powerpc_excp(cpu, POWERPC_EXCP_DOORI);
2221 break;
2222 case PPC_INTERRUPT_HDOORBELL:
2223 env->pending_interrupts &= ~PPC_INTERRUPT_HDOORBELL;
2224 powerpc_excp(cpu, POWERPC_EXCP_SDOOR_HV);
2225 break;
2226 case PPC_INTERRUPT_PERFM:
2227 env->pending_interrupts &= ~PPC_INTERRUPT_PERFM;
2228 powerpc_excp(cpu, POWERPC_EXCP_PERFM);
2229 break;
2230 case PPC_INTERRUPT_EBB: /* EBB exception */
2231 env->pending_interrupts &= ~PPC_INTERRUPT_EBB;
2232 if (env->spr[SPR_BESCR] & BESCR_PMEO) {
2233 powerpc_excp(cpu, POWERPC_EXCP_PERFM_EBB);
2234 } else if (env->spr[SPR_BESCR] & BESCR_EEO) {
2235 powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL_EBB);
2237 break;
2238 case 0:
2240 * This is a bug ! It means that has_work took us out of halt without
2241 * anything to deliver while in a PM state that requires getting
2242 * out via a 0x100
2244 * This means we will incorrectly execute past the power management
2245 * instruction instead of triggering a reset.
2247 * It generally means a discrepancy between the wakeup conditions in the
2248 * processor has_work implementation and the logic in this function.
2250 assert(!env->resume_as_sreset);
2251 break;
2252 default:
2253 cpu_abort(env_cpu(env), "Invalid PowerPC interrupt %d. Aborting\n",
2254 interrupt);
2258 static void p9_deliver_interrupt(CPUPPCState *env, int interrupt)
2260 PowerPCCPU *cpu = env_archcpu(env);
2261 CPUState *cs = env_cpu(env);
2263 if (cs->halted && !(env->spr[SPR_PSSCR] & PSSCR_EC) &&
2264 !FIELD_EX64(env->msr, MSR, EE)) {
2266 * A pending interrupt took us out of power-saving, but MSR[EE] says
2267 * that we should return to NIP+4 instead of delivering it.
2269 return;
2272 switch (interrupt) {
2273 case PPC_INTERRUPT_MCK: /* Machine check exception */
2274 env->pending_interrupts &= ~PPC_INTERRUPT_MCK;
2275 powerpc_excp(cpu, POWERPC_EXCP_MCHECK);
2276 break;
2278 case PPC_INTERRUPT_HDECR: /* Hypervisor decrementer exception */
2279 /* HDEC clears on delivery */
2280 env->pending_interrupts &= ~PPC_INTERRUPT_HDECR;
2281 powerpc_excp(cpu, POWERPC_EXCP_HDECR);
2282 break;
2283 case PPC_INTERRUPT_HVIRT: /* Hypervisor virtualization interrupt */
2284 powerpc_excp(cpu, POWERPC_EXCP_HVIRT);
2285 break;
2287 case PPC_INTERRUPT_EXT:
2288 if (books_vhyp_promotes_external_to_hvirt(cpu)) {
2289 powerpc_excp(cpu, POWERPC_EXCP_HVIRT);
2290 } else {
2291 powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL);
2293 break;
2295 case PPC_INTERRUPT_DECR: /* Decrementer exception */
2296 powerpc_excp(cpu, POWERPC_EXCP_DECR);
2297 break;
2298 case PPC_INTERRUPT_DOORBELL:
2299 env->pending_interrupts &= ~PPC_INTERRUPT_DOORBELL;
2300 powerpc_excp(cpu, POWERPC_EXCP_SDOOR);
2301 break;
2302 case PPC_INTERRUPT_HDOORBELL:
2303 env->pending_interrupts &= ~PPC_INTERRUPT_HDOORBELL;
2304 powerpc_excp(cpu, POWERPC_EXCP_SDOOR_HV);
2305 break;
2306 case PPC_INTERRUPT_PERFM:
2307 env->pending_interrupts &= ~PPC_INTERRUPT_PERFM;
2308 powerpc_excp(cpu, POWERPC_EXCP_PERFM);
2309 break;
2310 case PPC_INTERRUPT_EBB: /* EBB exception */
2311 env->pending_interrupts &= ~PPC_INTERRUPT_EBB;
2312 if (env->spr[SPR_BESCR] & BESCR_PMEO) {
2313 powerpc_excp(cpu, POWERPC_EXCP_PERFM_EBB);
2314 } else if (env->spr[SPR_BESCR] & BESCR_EEO) {
2315 powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL_EBB);
2317 break;
2318 case 0:
2320 * This is a bug ! It means that has_work took us out of halt without
2321 * anything to deliver while in a PM state that requires getting
2322 * out via a 0x100
2324 * This means we will incorrectly execute past the power management
2325 * instruction instead of triggering a reset.
2327 * It generally means a discrepancy between the wakeup conditions in the
2328 * processor has_work implementation and the logic in this function.
2330 assert(!env->resume_as_sreset);
2331 break;
2332 default:
2333 cpu_abort(env_cpu(env), "Invalid PowerPC interrupt %d. Aborting\n",
2334 interrupt);
2337 #endif
2339 static void ppc_deliver_interrupt_generic(CPUPPCState *env, int interrupt)
2341 PowerPCCPU *cpu = env_archcpu(env);
2343 switch (interrupt) {
2344 case PPC_INTERRUPT_RESET: /* External reset */
2345 env->pending_interrupts &= ~PPC_INTERRUPT_RESET;
2346 powerpc_excp(cpu, POWERPC_EXCP_RESET);
2347 break;
2348 case PPC_INTERRUPT_MCK: /* Machine check exception */
2349 env->pending_interrupts &= ~PPC_INTERRUPT_MCK;
2350 powerpc_excp(cpu, POWERPC_EXCP_MCHECK);
2351 break;
2353 case PPC_INTERRUPT_HDECR: /* Hypervisor decrementer exception */
2354 /* HDEC clears on delivery */
2355 env->pending_interrupts &= ~PPC_INTERRUPT_HDECR;
2356 powerpc_excp(cpu, POWERPC_EXCP_HDECR);
2357 break;
2358 case PPC_INTERRUPT_HVIRT: /* Hypervisor virtualization interrupt */
2359 powerpc_excp(cpu, POWERPC_EXCP_HVIRT);
2360 break;
2362 case PPC_INTERRUPT_EXT:
2363 if (books_vhyp_promotes_external_to_hvirt(cpu)) {
2364 powerpc_excp(cpu, POWERPC_EXCP_HVIRT);
2365 } else {
2366 powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL);
2368 break;
2369 case PPC_INTERRUPT_CEXT: /* External critical interrupt */
2370 powerpc_excp(cpu, POWERPC_EXCP_CRITICAL);
2371 break;
2373 case PPC_INTERRUPT_WDT: /* Watchdog timer on embedded PowerPC */
2374 env->pending_interrupts &= ~PPC_INTERRUPT_WDT;
2375 powerpc_excp(cpu, POWERPC_EXCP_WDT);
2376 break;
2377 case PPC_INTERRUPT_CDOORBELL:
2378 env->pending_interrupts &= ~PPC_INTERRUPT_CDOORBELL;
2379 powerpc_excp(cpu, POWERPC_EXCP_DOORCI);
2380 break;
2381 case PPC_INTERRUPT_FIT: /* Fixed interval timer on embedded PowerPC */
2382 env->pending_interrupts &= ~PPC_INTERRUPT_FIT;
2383 powerpc_excp(cpu, POWERPC_EXCP_FIT);
2384 break;
2385 case PPC_INTERRUPT_PIT: /* Programmable interval timer on embedded ppc */
2386 env->pending_interrupts &= ~PPC_INTERRUPT_PIT;
2387 powerpc_excp(cpu, POWERPC_EXCP_PIT);
2388 break;
2389 case PPC_INTERRUPT_DECR: /* Decrementer exception */
2390 if (ppc_decr_clear_on_delivery(env)) {
2391 env->pending_interrupts &= ~PPC_INTERRUPT_DECR;
2393 powerpc_excp(cpu, POWERPC_EXCP_DECR);
2394 break;
2395 case PPC_INTERRUPT_DOORBELL:
2396 env->pending_interrupts &= ~PPC_INTERRUPT_DOORBELL;
2397 if (is_book3s_arch2x(env)) {
2398 powerpc_excp(cpu, POWERPC_EXCP_SDOOR);
2399 } else {
2400 powerpc_excp(cpu, POWERPC_EXCP_DOORI);
2402 break;
2403 case PPC_INTERRUPT_HDOORBELL:
2404 env->pending_interrupts &= ~PPC_INTERRUPT_HDOORBELL;
2405 powerpc_excp(cpu, POWERPC_EXCP_SDOOR_HV);
2406 break;
2407 case PPC_INTERRUPT_PERFM:
2408 env->pending_interrupts &= ~PPC_INTERRUPT_PERFM;
2409 powerpc_excp(cpu, POWERPC_EXCP_PERFM);
2410 break;
2411 case PPC_INTERRUPT_THERM: /* Thermal interrupt */
2412 env->pending_interrupts &= ~PPC_INTERRUPT_THERM;
2413 powerpc_excp(cpu, POWERPC_EXCP_THERM);
2414 break;
2415 case PPC_INTERRUPT_EBB: /* EBB exception */
2416 env->pending_interrupts &= ~PPC_INTERRUPT_EBB;
2417 if (env->spr[SPR_BESCR] & BESCR_PMEO) {
2418 powerpc_excp(cpu, POWERPC_EXCP_PERFM_EBB);
2419 } else if (env->spr[SPR_BESCR] & BESCR_EEO) {
2420 powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL_EBB);
2422 break;
2423 case 0:
2425 * This is a bug ! It means that has_work took us out of halt without
2426 * anything to deliver while in a PM state that requires getting
2427 * out via a 0x100
2429 * This means we will incorrectly execute past the power management
2430 * instruction instead of triggering a reset.
2432 * It generally means a discrepancy between the wakeup conditions in the
2433 * processor has_work implementation and the logic in this function.
2435 assert(!env->resume_as_sreset);
2436 break;
2437 default:
2438 cpu_abort(env_cpu(env), "Invalid PowerPC interrupt %d. Aborting\n",
2439 interrupt);
2443 static void ppc_deliver_interrupt(CPUPPCState *env, int interrupt)
2445 switch (env->excp_model) {
2446 #if defined(TARGET_PPC64)
2447 case POWERPC_EXCP_POWER7:
2448 p7_deliver_interrupt(env, interrupt);
2449 break;
2450 case POWERPC_EXCP_POWER8:
2451 p8_deliver_interrupt(env, interrupt);
2452 break;
2453 case POWERPC_EXCP_POWER9:
2454 case POWERPC_EXCP_POWER10:
2455 p9_deliver_interrupt(env, interrupt);
2456 break;
2457 #endif
2458 default:
2459 ppc_deliver_interrupt_generic(env, interrupt);
2463 void ppc_cpu_do_system_reset(CPUState *cs)
2465 PowerPCCPU *cpu = POWERPC_CPU(cs);
2467 powerpc_excp(cpu, POWERPC_EXCP_RESET);
2470 void ppc_cpu_do_fwnmi_machine_check(CPUState *cs, target_ulong vector)
2472 PowerPCCPU *cpu = POWERPC_CPU(cs);
2473 CPUPPCState *env = &cpu->env;
2474 target_ulong msr = 0;
2477 * Set MSR and NIP for the handler, SRR0/1, DAR and DSISR have already
2478 * been set by KVM.
2480 msr = (1ULL << MSR_ME);
2481 msr |= env->msr & (1ULL << MSR_SF);
2482 if (ppc_interrupts_little_endian(cpu, false)) {
2483 msr |= (1ULL << MSR_LE);
2486 /* Anything for nested required here? MSR[HV] bit? */
2488 powerpc_set_excp_state(cpu, vector, msr);
2491 bool ppc_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
2493 PowerPCCPU *cpu = POWERPC_CPU(cs);
2494 CPUPPCState *env = &cpu->env;
2495 int interrupt;
2497 if ((interrupt_request & CPU_INTERRUPT_HARD) == 0) {
2498 return false;
2501 interrupt = ppc_next_unmasked_interrupt(env);
2502 if (interrupt == 0) {
2503 return false;
2506 ppc_deliver_interrupt(env, interrupt);
2507 if (env->pending_interrupts == 0) {
2508 cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
2510 return true;
2513 #endif /* !CONFIG_USER_ONLY */
2515 /*****************************************************************************/
2516 /* Exceptions processing helpers */
2518 void raise_exception_err_ra(CPUPPCState *env, uint32_t exception,
2519 uint32_t error_code, uintptr_t raddr)
2521 CPUState *cs = env_cpu(env);
2523 cs->exception_index = exception;
2524 env->error_code = error_code;
2525 cpu_loop_exit_restore(cs, raddr);
2528 void raise_exception_err(CPUPPCState *env, uint32_t exception,
2529 uint32_t error_code)
2531 raise_exception_err_ra(env, exception, error_code, 0);
2534 void raise_exception(CPUPPCState *env, uint32_t exception)
2536 raise_exception_err_ra(env, exception, 0, 0);
2539 void raise_exception_ra(CPUPPCState *env, uint32_t exception,
2540 uintptr_t raddr)
2542 raise_exception_err_ra(env, exception, 0, raddr);
2545 #ifdef CONFIG_TCG
2546 void helper_raise_exception_err(CPUPPCState *env, uint32_t exception,
2547 uint32_t error_code)
2549 raise_exception_err_ra(env, exception, error_code, 0);
2552 void helper_raise_exception(CPUPPCState *env, uint32_t exception)
2554 raise_exception_err_ra(env, exception, 0, 0);
2556 #endif
2558 #if !defined(CONFIG_USER_ONLY)
2559 #ifdef CONFIG_TCG
2560 void helper_store_msr(CPUPPCState *env, target_ulong val)
2562 uint32_t excp = hreg_store_msr(env, val, 0);
2564 if (excp != 0) {
2565 cpu_interrupt_exittb(env_cpu(env));
2566 raise_exception(env, excp);
2570 void helper_ppc_maybe_interrupt(CPUPPCState *env)
2572 ppc_maybe_interrupt(env);
2575 #if defined(TARGET_PPC64)
2576 void helper_scv(CPUPPCState *env, uint32_t lev)
2578 if (env->spr[SPR_FSCR] & (1ull << FSCR_SCV)) {
2579 raise_exception_err(env, POWERPC_EXCP_SYSCALL_VECTORED, lev);
2580 } else {
2581 raise_exception_err(env, POWERPC_EXCP_FU, FSCR_IC_SCV);
2585 void helper_pminsn(CPUPPCState *env, uint32_t insn)
2587 CPUState *cs = env_cpu(env);
2589 cs->halted = 1;
2591 /* Condition for waking up at 0x100 */
2592 env->resume_as_sreset = (insn != PPC_PM_STOP) ||
2593 (env->spr[SPR_PSSCR] & PSSCR_EC);
2595 /* HDECR is not to wake from PM state, it may have already fired */
2596 if (env->resume_as_sreset) {
2597 PowerPCCPU *cpu = env_archcpu(env);
2598 ppc_set_irq(cpu, PPC_INTERRUPT_HDECR, 0);
2601 ppc_maybe_interrupt(env);
2603 #endif /* defined(TARGET_PPC64) */
2605 static void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr)
2607 /* MSR:POW cannot be set by any form of rfi */
2608 msr &= ~(1ULL << MSR_POW);
2610 /* MSR:TGPR cannot be set by any form of rfi */
2611 if (env->flags & POWERPC_FLAG_TGPR)
2612 msr &= ~(1ULL << MSR_TGPR);
2614 #if defined(TARGET_PPC64)
2615 /* Switching to 32-bit ? Crop the nip */
2616 if (!msr_is_64bit(env, msr)) {
2617 nip = (uint32_t)nip;
2619 #else
2620 nip = (uint32_t)nip;
2621 #endif
2622 /* XXX: beware: this is false if VLE is supported */
2623 env->nip = nip & ~((target_ulong)0x00000003);
2624 hreg_store_msr(env, msr, 1);
2625 trace_ppc_excp_rfi(env->nip, env->msr);
2627 * No need to raise an exception here, as rfi is always the last
2628 * insn of a TB
2630 cpu_interrupt_exittb(env_cpu(env));
2631 /* Reset the reservation */
2632 env->reserve_addr = -1;
2634 /* Context synchronizing: check if TCG TLB needs flush */
2635 check_tlb_flush(env, false);
2638 void helper_rfi(CPUPPCState *env)
2640 do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1] & 0xfffffffful);
2643 #if defined(TARGET_PPC64)
2644 void helper_rfid(CPUPPCState *env)
2647 * The architecture defines a number of rules for which bits can
2648 * change but in practice, we handle this in hreg_store_msr()
2649 * which will be called by do_rfi(), so there is no need to filter
2650 * here
2652 do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1]);
2655 void helper_rfscv(CPUPPCState *env)
2657 do_rfi(env, env->lr, env->ctr);
2660 void helper_hrfid(CPUPPCState *env)
2662 do_rfi(env, env->spr[SPR_HSRR0], env->spr[SPR_HSRR1]);
2664 #endif
2666 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
2667 void helper_rfebb(CPUPPCState *env, target_ulong s)
2669 target_ulong msr = env->msr;
2672 * Handling of BESCR bits 32:33 according to PowerISA v3.1:
2674 * "If BESCR 32:33 != 0b00 the instruction is treated as if
2675 * the instruction form were invalid."
2677 if (env->spr[SPR_BESCR] & BESCR_INVALID) {
2678 raise_exception_err(env, POWERPC_EXCP_PROGRAM,
2679 POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL);
2682 env->nip = env->spr[SPR_EBBRR];
2684 /* Switching to 32-bit ? Crop the nip */
2685 if (!msr_is_64bit(env, msr)) {
2686 env->nip = (uint32_t)env->spr[SPR_EBBRR];
2689 if (s) {
2690 env->spr[SPR_BESCR] |= BESCR_GE;
2691 } else {
2692 env->spr[SPR_BESCR] &= ~BESCR_GE;
2697 * Triggers or queues an 'ebb_excp' EBB exception. All checks
2698 * but FSCR, HFSCR and msr_pr must be done beforehand.
2700 * PowerISA v3.1 isn't clear about whether an EBB should be
2701 * postponed or cancelled if the EBB facility is unavailable.
2702 * Our assumption here is that the EBB is cancelled if both
2703 * FSCR and HFSCR EBB facilities aren't available.
2705 static void do_ebb(CPUPPCState *env, int ebb_excp)
2707 PowerPCCPU *cpu = env_archcpu(env);
2710 * FSCR_EBB and FSCR_IC_EBB are the same bits used with
2711 * HFSCR.
2713 helper_fscr_facility_check(env, FSCR_EBB, 0, FSCR_IC_EBB);
2714 helper_hfscr_facility_check(env, FSCR_EBB, "EBB", FSCR_IC_EBB);
2716 if (ebb_excp == POWERPC_EXCP_PERFM_EBB) {
2717 env->spr[SPR_BESCR] |= BESCR_PMEO;
2718 } else if (ebb_excp == POWERPC_EXCP_EXTERNAL_EBB) {
2719 env->spr[SPR_BESCR] |= BESCR_EEO;
2722 if (FIELD_EX64(env->msr, MSR, PR)) {
2723 powerpc_excp(cpu, ebb_excp);
2724 } else {
2725 ppc_set_irq(cpu, PPC_INTERRUPT_EBB, 1);
2729 void raise_ebb_perfm_exception(CPUPPCState *env)
2731 bool perfm_ebb_enabled = env->spr[SPR_POWER_MMCR0] & MMCR0_EBE &&
2732 env->spr[SPR_BESCR] & BESCR_PME &&
2733 env->spr[SPR_BESCR] & BESCR_GE;
2735 if (!perfm_ebb_enabled) {
2736 return;
2739 do_ebb(env, POWERPC_EXCP_PERFM_EBB);
2741 #endif
2743 /*****************************************************************************/
2744 /* Embedded PowerPC specific helpers */
2745 void helper_40x_rfci(CPUPPCState *env)
2747 do_rfi(env, env->spr[SPR_40x_SRR2], env->spr[SPR_40x_SRR3]);
2750 void helper_rfci(CPUPPCState *env)
2752 do_rfi(env, env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1]);
2755 void helper_rfdi(CPUPPCState *env)
2757 /* FIXME: choose CSRR1 or DSRR1 based on cpu type */
2758 do_rfi(env, env->spr[SPR_BOOKE_DSRR0], env->spr[SPR_BOOKE_DSRR1]);
2761 void helper_rfmci(CPUPPCState *env)
2763 /* FIXME: choose CSRR1 or MCSRR1 based on cpu type */
2764 do_rfi(env, env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1]);
2766 #endif /* CONFIG_TCG */
2767 #endif /* !defined(CONFIG_USER_ONLY) */
2769 #ifdef CONFIG_TCG
2770 void helper_tw(CPUPPCState *env, target_ulong arg1, target_ulong arg2,
2771 uint32_t flags)
2773 if (!likely(!(((int32_t)arg1 < (int32_t)arg2 && (flags & 0x10)) ||
2774 ((int32_t)arg1 > (int32_t)arg2 && (flags & 0x08)) ||
2775 ((int32_t)arg1 == (int32_t)arg2 && (flags & 0x04)) ||
2776 ((uint32_t)arg1 < (uint32_t)arg2 && (flags & 0x02)) ||
2777 ((uint32_t)arg1 > (uint32_t)arg2 && (flags & 0x01))))) {
2778 raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
2779 POWERPC_EXCP_TRAP, GETPC());
2783 #if defined(TARGET_PPC64)
2784 void helper_td(CPUPPCState *env, target_ulong arg1, target_ulong arg2,
2785 uint32_t flags)
2787 if (!likely(!(((int64_t)arg1 < (int64_t)arg2 && (flags & 0x10)) ||
2788 ((int64_t)arg1 > (int64_t)arg2 && (flags & 0x08)) ||
2789 ((int64_t)arg1 == (int64_t)arg2 && (flags & 0x04)) ||
2790 ((uint64_t)arg1 < (uint64_t)arg2 && (flags & 0x02)) ||
2791 ((uint64_t)arg1 > (uint64_t)arg2 && (flags & 0x01))))) {
2792 raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
2793 POWERPC_EXCP_TRAP, GETPC());
2796 #endif
2797 #endif
2799 #ifdef CONFIG_TCG
2800 static uint32_t helper_SIMON_LIKE_32_64(uint32_t x, uint64_t key, uint32_t lane)
2802 const uint16_t c = 0xfffc;
2803 const uint64_t z0 = 0xfa2561cdf44ac398ULL;
2804 uint16_t z = 0, temp;
2805 uint16_t k[32], eff_k[32], xleft[33], xright[33], fxleft[32];
2807 for (int i = 3; i >= 0; i--) {
2808 k[i] = key & 0xffff;
2809 key >>= 16;
2811 xleft[0] = x & 0xffff;
2812 xright[0] = (x >> 16) & 0xffff;
2814 for (int i = 0; i < 28; i++) {
2815 z = (z0 >> (63 - i)) & 1;
2816 temp = ror16(k[i + 3], 3) ^ k[i + 1];
2817 k[i + 4] = c ^ z ^ k[i] ^ temp ^ ror16(temp, 1);
2820 for (int i = 0; i < 8; i++) {
2821 eff_k[4 * i + 0] = k[4 * i + ((0 + lane) % 4)];
2822 eff_k[4 * i + 1] = k[4 * i + ((1 + lane) % 4)];
2823 eff_k[4 * i + 2] = k[4 * i + ((2 + lane) % 4)];
2824 eff_k[4 * i + 3] = k[4 * i + ((3 + lane) % 4)];
2827 for (int i = 0; i < 32; i++) {
2828 fxleft[i] = (rol16(xleft[i], 1) &
2829 rol16(xleft[i], 8)) ^ rol16(xleft[i], 2);
2830 xleft[i + 1] = xright[i] ^ fxleft[i] ^ eff_k[i];
2831 xright[i + 1] = xleft[i];
2834 return (((uint32_t)xright[32]) << 16) | xleft[32];
2837 static uint64_t hash_digest(uint64_t ra, uint64_t rb, uint64_t key)
2839 uint64_t stage0_h = 0ULL, stage0_l = 0ULL;
2840 uint64_t stage1_h, stage1_l;
2842 for (int i = 0; i < 4; i++) {
2843 stage0_h |= ror64(rb & 0xff, 8 * (2 * i + 1));
2844 stage0_h |= ((ra >> 32) & 0xff) << (8 * 2 * i);
2845 stage0_l |= ror64((rb >> 32) & 0xff, 8 * (2 * i + 1));
2846 stage0_l |= (ra & 0xff) << (8 * 2 * i);
2847 rb >>= 8;
2848 ra >>= 8;
2851 stage1_h = (uint64_t)helper_SIMON_LIKE_32_64(stage0_h >> 32, key, 0) << 32;
2852 stage1_h |= helper_SIMON_LIKE_32_64(stage0_h, key, 1);
2853 stage1_l = (uint64_t)helper_SIMON_LIKE_32_64(stage0_l >> 32, key, 2) << 32;
2854 stage1_l |= helper_SIMON_LIKE_32_64(stage0_l, key, 3);
2856 return stage1_h ^ stage1_l;
2859 static void do_hash(CPUPPCState *env, target_ulong ea, target_ulong ra,
2860 target_ulong rb, uint64_t key, bool store)
2862 uint64_t calculated_hash = hash_digest(ra, rb, key), loaded_hash;
2864 if (store) {
2865 cpu_stq_data_ra(env, ea, calculated_hash, GETPC());
2866 } else {
2867 loaded_hash = cpu_ldq_data_ra(env, ea, GETPC());
2868 if (loaded_hash != calculated_hash) {
2869 raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
2870 POWERPC_EXCP_TRAP, GETPC());
2875 #include "qemu/guest-random.h"
2877 #ifdef TARGET_PPC64
2878 #define HELPER_HASH(op, key, store, dexcr_aspect) \
2879 void helper_##op(CPUPPCState *env, target_ulong ea, target_ulong ra, \
2880 target_ulong rb) \
2882 if (env->msr & R_MSR_PR_MASK) { \
2883 if (!(env->spr[SPR_DEXCR] & R_DEXCR_PRO_##dexcr_aspect##_MASK || \
2884 env->spr[SPR_HDEXCR] & R_HDEXCR_ENF_##dexcr_aspect##_MASK)) \
2885 return; \
2886 } else if (!(env->msr & R_MSR_HV_MASK)) { \
2887 if (!(env->spr[SPR_DEXCR] & R_DEXCR_PNH_##dexcr_aspect##_MASK || \
2888 env->spr[SPR_HDEXCR] & R_HDEXCR_ENF_##dexcr_aspect##_MASK)) \
2889 return; \
2890 } else if (!(env->msr & R_MSR_S_MASK)) { \
2891 if (!(env->spr[SPR_HDEXCR] & R_HDEXCR_HNU_##dexcr_aspect##_MASK)) \
2892 return; \
2895 do_hash(env, ea, ra, rb, key, store); \
2897 #else
2898 #define HELPER_HASH(op, key, store, dexcr_aspect) \
2899 void helper_##op(CPUPPCState *env, target_ulong ea, target_ulong ra, \
2900 target_ulong rb) \
2902 do_hash(env, ea, ra, rb, key, store); \
2904 #endif /* TARGET_PPC64 */
2906 HELPER_HASH(HASHST, env->spr[SPR_HASHKEYR], true, NPHIE)
2907 HELPER_HASH(HASHCHK, env->spr[SPR_HASHKEYR], false, NPHIE)
2908 HELPER_HASH(HASHSTP, env->spr[SPR_HASHPKEYR], true, PHIE)
2909 HELPER_HASH(HASHCHKP, env->spr[SPR_HASHPKEYR], false, PHIE)
2910 #endif /* CONFIG_TCG */
2912 #if !defined(CONFIG_USER_ONLY)
2914 #ifdef CONFIG_TCG
2916 /* Embedded.Processor Control */
2917 static int dbell2irq(target_ulong rb)
2919 int msg = rb & DBELL_TYPE_MASK;
2920 int irq = -1;
2922 switch (msg) {
2923 case DBELL_TYPE_DBELL:
2924 irq = PPC_INTERRUPT_DOORBELL;
2925 break;
2926 case DBELL_TYPE_DBELL_CRIT:
2927 irq = PPC_INTERRUPT_CDOORBELL;
2928 break;
2929 case DBELL_TYPE_G_DBELL:
2930 case DBELL_TYPE_G_DBELL_CRIT:
2931 case DBELL_TYPE_G_DBELL_MC:
2932 /* XXX implement */
2933 default:
2934 break;
2937 return irq;
2940 void helper_msgclr(CPUPPCState *env, target_ulong rb)
2942 int irq = dbell2irq(rb);
2944 if (irq < 0) {
2945 return;
2948 ppc_set_irq(env_archcpu(env), irq, 0);
2951 void helper_msgsnd(target_ulong rb)
2953 int irq = dbell2irq(rb);
2954 int pir = rb & DBELL_PIRTAG_MASK;
2955 CPUState *cs;
2957 if (irq < 0) {
2958 return;
2961 bql_lock();
2962 CPU_FOREACH(cs) {
2963 PowerPCCPU *cpu = POWERPC_CPU(cs);
2964 CPUPPCState *cenv = &cpu->env;
2966 if ((rb & DBELL_BRDCAST) || (cenv->spr[SPR_BOOKE_PIR] == pir)) {
2967 ppc_set_irq(cpu, irq, 1);
2970 bql_unlock();
2973 /* Server Processor Control */
2975 static bool dbell_type_server(target_ulong rb)
2978 * A Directed Hypervisor Doorbell message is sent only if the
2979 * message type is 5. All other types are reserved and the
2980 * instruction is a no-op
2982 return (rb & DBELL_TYPE_MASK) == DBELL_TYPE_DBELL_SERVER;
2985 void helper_book3s_msgclr(CPUPPCState *env, target_ulong rb)
2987 if (!dbell_type_server(rb)) {
2988 return;
2991 ppc_set_irq(env_archcpu(env), PPC_INTERRUPT_HDOORBELL, 0);
2994 static void book3s_msgsnd_common(int pir, int irq)
2996 CPUState *cs;
2998 bql_lock();
2999 CPU_FOREACH(cs) {
3000 PowerPCCPU *cpu = POWERPC_CPU(cs);
3001 CPUPPCState *cenv = &cpu->env;
3003 /* TODO: broadcast message to all threads of the same processor */
3004 if (cenv->spr_cb[SPR_PIR].default_value == pir) {
3005 ppc_set_irq(cpu, irq, 1);
3008 bql_unlock();
3011 void helper_book3s_msgsnd(target_ulong rb)
3013 int pir = rb & DBELL_PROCIDTAG_MASK;
3015 if (!dbell_type_server(rb)) {
3016 return;
3019 book3s_msgsnd_common(pir, PPC_INTERRUPT_HDOORBELL);
3022 #if defined(TARGET_PPC64)
3023 void helper_book3s_msgclrp(CPUPPCState *env, target_ulong rb)
3025 helper_hfscr_facility_check(env, HFSCR_MSGP, "msgclrp", HFSCR_IC_MSGP);
3027 if (!dbell_type_server(rb)) {
3028 return;
3031 ppc_set_irq(env_archcpu(env), PPC_INTERRUPT_DOORBELL, 0);
3035 * sends a message to another thread on the same
3036 * multi-threaded processor
3038 void helper_book3s_msgsndp(CPUPPCState *env, target_ulong rb)
3040 CPUState *cs = env_cpu(env);
3041 PowerPCCPU *cpu = env_archcpu(env);
3042 CPUState *ccs;
3043 uint32_t nr_threads = cs->nr_threads;
3044 int ttir = rb & PPC_BITMASK(57, 63);
3046 helper_hfscr_facility_check(env, HFSCR_MSGP, "msgsndp", HFSCR_IC_MSGP);
3048 if (!(env->flags & POWERPC_FLAG_SMT_1LPAR)) {
3049 nr_threads = 1; /* msgsndp behaves as 1-thread in LPAR-per-thread mode*/
3052 if (!dbell_type_server(rb) || ttir >= nr_threads) {
3053 return;
3056 if (nr_threads == 1) {
3057 ppc_set_irq(cpu, PPC_INTERRUPT_DOORBELL, 1);
3058 return;
3061 /* Does iothread need to be locked for walking CPU list? */
3062 bql_lock();
3063 THREAD_SIBLING_FOREACH(cs, ccs) {
3064 PowerPCCPU *ccpu = POWERPC_CPU(ccs);
3065 uint32_t thread_id = ppc_cpu_tir(ccpu);
3067 if (ttir == thread_id) {
3068 ppc_set_irq(ccpu, PPC_INTERRUPT_DOORBELL, 1);
3069 bql_unlock();
3070 return;
3074 g_assert_not_reached();
3076 #endif /* TARGET_PPC64 */
3078 /* Single-step tracing */
3079 void helper_book3s_trace(CPUPPCState *env, target_ulong prev_ip)
3081 uint32_t error_code = 0;
3082 if (env->insns_flags2 & PPC2_ISA207S) {
3083 /* Load/store reporting, SRR1[35, 36] and SDAR, are not implemented. */
3084 env->spr[SPR_POWER_SIAR] = prev_ip;
3085 error_code = PPC_BIT(33);
3087 raise_exception_err(env, POWERPC_EXCP_TRACE, error_code);
3090 void ppc_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
3091 MMUAccessType access_type,
3092 int mmu_idx, uintptr_t retaddr)
3094 CPUPPCState *env = cpu_env(cs);
3095 uint32_t insn;
3097 /* Restore state and reload the insn we executed, for filling in DSISR. */
3098 cpu_restore_state(cs, retaddr);
3099 insn = ppc_ldl_code(env, env->nip);
3101 switch (env->mmu_model) {
3102 case POWERPC_MMU_SOFT_4xx:
3103 env->spr[SPR_40x_DEAR] = vaddr;
3104 break;
3105 case POWERPC_MMU_BOOKE:
3106 case POWERPC_MMU_BOOKE206:
3107 env->spr[SPR_BOOKE_DEAR] = vaddr;
3108 break;
3109 default:
3110 env->spr[SPR_DAR] = vaddr;
3111 break;
3114 cs->exception_index = POWERPC_EXCP_ALIGN;
3115 env->error_code = insn & 0x03FF0000;
3116 cpu_loop_exit(cs);
3119 void ppc_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
3120 vaddr vaddr, unsigned size,
3121 MMUAccessType access_type,
3122 int mmu_idx, MemTxAttrs attrs,
3123 MemTxResult response, uintptr_t retaddr)
3125 CPUPPCState *env = cpu_env(cs);
3127 switch (env->excp_model) {
3128 #if defined(TARGET_PPC64)
3129 case POWERPC_EXCP_POWER8:
3130 case POWERPC_EXCP_POWER9:
3131 case POWERPC_EXCP_POWER10:
3133 * Machine check codes can be found in processor User Manual or
3134 * Linux or skiboot source.
3136 if (access_type == MMU_DATA_LOAD) {
3137 env->spr[SPR_DAR] = vaddr;
3138 env->spr[SPR_DSISR] = PPC_BIT(57);
3139 env->error_code = PPC_BIT(42);
3141 } else if (access_type == MMU_DATA_STORE) {
3143 * MCE for stores in POWER is asynchronous so hardware does
3144 * not set DAR, but QEMU can do better.
3146 env->spr[SPR_DAR] = vaddr;
3147 env->error_code = PPC_BIT(36) | PPC_BIT(43) | PPC_BIT(45);
3148 env->error_code |= PPC_BIT(42);
3150 } else { /* Fetch */
3152 * is_prefix_insn_excp() tests !PPC_BIT(42) to avoid fetching
3153 * the instruction, so that must always be clear for fetches.
3155 env->error_code = PPC_BIT(36) | PPC_BIT(44) | PPC_BIT(45);
3157 break;
3158 #endif
3159 default:
3161 * TODO: Check behaviour for other CPUs, for now do nothing.
3162 * Could add a basic MCE even if real hardware ignores.
3164 return;
3167 cs->exception_index = POWERPC_EXCP_MCHECK;
3168 cpu_loop_exit_restore(cs, retaddr);
3171 void ppc_cpu_debug_excp_handler(CPUState *cs)
3173 #if defined(TARGET_PPC64)
3174 CPUPPCState *env = cpu_env(cs);
3176 if (env->insns_flags2 & PPC2_ISA207S) {
3177 if (cs->watchpoint_hit) {
3178 if (cs->watchpoint_hit->flags & BP_CPU) {
3179 env->spr[SPR_DAR] = cs->watchpoint_hit->hitaddr;
3180 env->spr[SPR_DSISR] = PPC_BIT(41);
3181 cs->watchpoint_hit = NULL;
3182 raise_exception(env, POWERPC_EXCP_DSI);
3184 cs->watchpoint_hit = NULL;
3185 } else if (cpu_breakpoint_test(cs, env->nip, BP_CPU)) {
3186 raise_exception_err(env, POWERPC_EXCP_TRACE,
3187 PPC_BIT(33) | PPC_BIT(43));
3190 #endif
3193 bool ppc_cpu_debug_check_breakpoint(CPUState *cs)
3195 #if defined(TARGET_PPC64)
3196 CPUPPCState *env = cpu_env(cs);
3198 if (env->insns_flags2 & PPC2_ISA207S) {
3199 target_ulong priv;
3201 priv = env->spr[SPR_CIABR] & PPC_BITMASK(62, 63);
3202 switch (priv) {
3203 case 0x1: /* problem */
3204 return env->msr & ((target_ulong)1 << MSR_PR);
3205 case 0x2: /* supervisor */
3206 return (!(env->msr & ((target_ulong)1 << MSR_PR)) &&
3207 !(env->msr & ((target_ulong)1 << MSR_HV)));
3208 case 0x3: /* hypervisor */
3209 return (!(env->msr & ((target_ulong)1 << MSR_PR)) &&
3210 (env->msr & ((target_ulong)1 << MSR_HV)));
3211 default:
3212 g_assert_not_reached();
3215 #endif
3217 return false;
3220 bool ppc_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp)
3222 #if defined(TARGET_PPC64)
3223 CPUPPCState *env = cpu_env(cs);
3225 if (env->insns_flags2 & PPC2_ISA207S) {
3226 if (wp == env->dawr0_watchpoint) {
3227 uint32_t dawrx = env->spr[SPR_DAWRX0];
3228 bool wt = extract32(dawrx, PPC_BIT_NR(59), 1);
3229 bool wti = extract32(dawrx, PPC_BIT_NR(60), 1);
3230 bool hv = extract32(dawrx, PPC_BIT_NR(61), 1);
3231 bool sv = extract32(dawrx, PPC_BIT_NR(62), 1);
3232 bool pr = extract32(dawrx, PPC_BIT_NR(62), 1);
3234 if ((env->msr & ((target_ulong)1 << MSR_PR)) && !pr) {
3235 return false;
3236 } else if ((env->msr & ((target_ulong)1 << MSR_HV)) && !hv) {
3237 return false;
3238 } else if (!sv) {
3239 return false;
3242 if (!wti) {
3243 if (env->msr & ((target_ulong)1 << MSR_DR)) {
3244 if (!wt) {
3245 return false;
3247 } else {
3248 if (wt) {
3249 return false;
3254 return true;
3257 #endif
3259 return false;
3262 #endif /* CONFIG_TCG */
3263 #endif /* !CONFIG_USER_ONLY */