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