xref: /qemu/target/ppc/excp_helper.c (revision 94a37684a59e320a32ba948e9f8d75810c6dcdea)
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/tcg.h"
23 #include "system/system.h"
24 #include "system/runstate.h"
25 #include "cpu.h"
26 #include "exec/exec-all.h"
27 #include "internal.h"
28 #include "helper_regs.h"
29 #include "hw/ppc/ppc.h"
30 
31 #include "trace.h"
32 
33 #ifdef CONFIG_TCG
34 #include "exec/helper-proto.h"
35 #include "exec/cpu_ldst.h"
36 #endif
37 
38 /*****************************************************************************/
39 /* Exception processing */
40 #ifndef CONFIG_USER_ONLY
41 
42 static const char *powerpc_excp_name(int excp)
43 {
44     switch (excp) {
45     case POWERPC_EXCP_CRITICAL: return "CRITICAL";
46     case POWERPC_EXCP_MCHECK:   return "MCHECK";
47     case POWERPC_EXCP_DSI:      return "DSI";
48     case POWERPC_EXCP_ISI:      return "ISI";
49     case POWERPC_EXCP_EXTERNAL: return "EXTERNAL";
50     case POWERPC_EXCP_ALIGN:    return "ALIGN";
51     case POWERPC_EXCP_PROGRAM:  return "PROGRAM";
52     case POWERPC_EXCP_FPU:      return "FPU";
53     case POWERPC_EXCP_SYSCALL:  return "SYSCALL";
54     case POWERPC_EXCP_APU:      return "APU";
55     case POWERPC_EXCP_DECR:     return "DECR";
56     case POWERPC_EXCP_FIT:      return "FIT";
57     case POWERPC_EXCP_WDT:      return "WDT";
58     case POWERPC_EXCP_DTLB:     return "DTLB";
59     case POWERPC_EXCP_ITLB:     return "ITLB";
60     case POWERPC_EXCP_DEBUG:    return "DEBUG";
61     case POWERPC_EXCP_SPEU:     return "SPEU";
62     case POWERPC_EXCP_EFPDI:    return "EFPDI";
63     case POWERPC_EXCP_EFPRI:    return "EFPRI";
64     case POWERPC_EXCP_EPERFM:   return "EPERFM";
65     case POWERPC_EXCP_DOORI:    return "DOORI";
66     case POWERPC_EXCP_DOORCI:   return "DOORCI";
67     case POWERPC_EXCP_GDOORI:   return "GDOORI";
68     case POWERPC_EXCP_GDOORCI:  return "GDOORCI";
69     case POWERPC_EXCP_HYPPRIV:  return "HYPPRIV";
70     case POWERPC_EXCP_RESET:    return "RESET";
71     case POWERPC_EXCP_DSEG:     return "DSEG";
72     case POWERPC_EXCP_ISEG:     return "ISEG";
73     case POWERPC_EXCP_HDECR:    return "HDECR";
74     case POWERPC_EXCP_TRACE:    return "TRACE";
75     case POWERPC_EXCP_HDSI:     return "HDSI";
76     case POWERPC_EXCP_HISI:     return "HISI";
77     case POWERPC_EXCP_HDSEG:    return "HDSEG";
78     case POWERPC_EXCP_HISEG:    return "HISEG";
79     case POWERPC_EXCP_VPU:      return "VPU";
80     case POWERPC_EXCP_PIT:      return "PIT";
81     case POWERPC_EXCP_EMUL:     return "EMUL";
82     case POWERPC_EXCP_IFTLB:    return "IFTLB";
83     case POWERPC_EXCP_DLTLB:    return "DLTLB";
84     case POWERPC_EXCP_DSTLB:    return "DSTLB";
85     case POWERPC_EXCP_FPA:      return "FPA";
86     case POWERPC_EXCP_DABR:     return "DABR";
87     case POWERPC_EXCP_IABR:     return "IABR";
88     case POWERPC_EXCP_SMI:      return "SMI";
89     case POWERPC_EXCP_PERFM:    return "PERFM";
90     case POWERPC_EXCP_THERM:    return "THERM";
91     case POWERPC_EXCP_VPUA:     return "VPUA";
92     case POWERPC_EXCP_SOFTP:    return "SOFTP";
93     case POWERPC_EXCP_MAINT:    return "MAINT";
94     case POWERPC_EXCP_MEXTBR:   return "MEXTBR";
95     case POWERPC_EXCP_NMEXTBR:  return "NMEXTBR";
96     case POWERPC_EXCP_ITLBE:    return "ITLBE";
97     case POWERPC_EXCP_DTLBE:    return "DTLBE";
98     case POWERPC_EXCP_VSXU:     return "VSXU";
99     case POWERPC_EXCP_FU:       return "FU";
100     case POWERPC_EXCP_HV_EMU:   return "HV_EMU";
101     case POWERPC_EXCP_HV_MAINT: return "HV_MAINT";
102     case POWERPC_EXCP_HV_FU:    return "HV_FU";
103     case POWERPC_EXCP_SDOOR:    return "SDOOR";
104     case POWERPC_EXCP_SDOOR_HV: return "SDOOR_HV";
105     case POWERPC_EXCP_HVIRT:    return "HVIRT";
106     case POWERPC_EXCP_SYSCALL_VECTORED: return "SYSCALL_VECTORED";
107     default:
108         g_assert_not_reached();
109     }
110 }
111 
112 static void dump_syscall(CPUPPCState *env)
113 {
114     qemu_log_mask(CPU_LOG_INT, "syscall r0=%016" PRIx64
115                   " r3=%016" PRIx64 " r4=%016" PRIx64 " r5=%016" PRIx64
116                   " r6=%016" PRIx64 " r7=%016" PRIx64 " r8=%016" PRIx64
117                   " nip=" TARGET_FMT_lx "\n",
118                   ppc_dump_gpr(env, 0), ppc_dump_gpr(env, 3),
119                   ppc_dump_gpr(env, 4), ppc_dump_gpr(env, 5),
120                   ppc_dump_gpr(env, 6), ppc_dump_gpr(env, 7),
121                   ppc_dump_gpr(env, 8), env->nip);
122 }
123 
124 static void dump_hcall(CPUPPCState *env)
125 {
126     qemu_log_mask(CPU_LOG_INT, "hypercall r3=%016" PRIx64
127                   " r4=%016" PRIx64 " r5=%016" PRIx64 " r6=%016" PRIx64
128                   " r7=%016" PRIx64 " r8=%016" PRIx64 " r9=%016" PRIx64
129                   " r10=%016" PRIx64 " r11=%016" PRIx64 " r12=%016" PRIx64
130                   " nip=" TARGET_FMT_lx "\n",
131                   ppc_dump_gpr(env, 3), ppc_dump_gpr(env, 4),
132                   ppc_dump_gpr(env, 5), ppc_dump_gpr(env, 6),
133                   ppc_dump_gpr(env, 7), ppc_dump_gpr(env, 8),
134                   ppc_dump_gpr(env, 9), ppc_dump_gpr(env, 10),
135                   ppc_dump_gpr(env, 11), ppc_dump_gpr(env, 12),
136                   env->nip);
137 }
138 
139 static void ppc_excp_debug_sw_tlb(CPUPPCState *env, int excp)
140 {
141     const char *es;
142     target_ulong *miss, *cmp;
143     int en;
144 
145     if (!qemu_loglevel_mask(CPU_LOG_MMU)) {
146         return;
147     }
148 
149     if (excp == POWERPC_EXCP_IFTLB) {
150         es = "I";
151         en = 'I';
152         miss = &env->spr[SPR_IMISS];
153         cmp = &env->spr[SPR_ICMP];
154     } else {
155         if (excp == POWERPC_EXCP_DLTLB) {
156             es = "DL";
157         } else {
158             es = "DS";
159         }
160         en = 'D';
161         miss = &env->spr[SPR_DMISS];
162         cmp = &env->spr[SPR_DCMP];
163     }
164     qemu_log("6xx %sTLB miss: %cM " TARGET_FMT_lx " %cC "
165              TARGET_FMT_lx " H1 " TARGET_FMT_lx " H2 "
166              TARGET_FMT_lx " %08x\n", es, en, *miss, en, *cmp,
167              env->spr[SPR_HASH1], env->spr[SPR_HASH2],
168              env->error_code);
169 }
170 
171 #ifdef TARGET_PPC64
172 static int powerpc_reset_wakeup(CPUPPCState *env, int excp, target_ulong *msr)
173 {
174     /* We no longer are in a PM state */
175     env->resume_as_sreset = false;
176 
177     /* Pretend to be returning from doze always as we don't lose state */
178     *msr |= SRR1_WS_NOLOSS;
179 
180     /* Machine checks are sent normally */
181     if (excp == POWERPC_EXCP_MCHECK) {
182         return excp;
183     }
184     switch (excp) {
185     case POWERPC_EXCP_RESET:
186         *msr |= SRR1_WAKERESET;
187         break;
188     case POWERPC_EXCP_EXTERNAL:
189         *msr |= SRR1_WAKEEE;
190         break;
191     case POWERPC_EXCP_DECR:
192         *msr |= SRR1_WAKEDEC;
193         break;
194     case POWERPC_EXCP_SDOOR:
195         *msr |= SRR1_WAKEDBELL;
196         break;
197     case POWERPC_EXCP_SDOOR_HV:
198         *msr |= SRR1_WAKEHDBELL;
199         break;
200     case POWERPC_EXCP_HV_MAINT:
201         *msr |= SRR1_WAKEHMI;
202         break;
203     case POWERPC_EXCP_HVIRT:
204         *msr |= SRR1_WAKEHVI;
205         break;
206     default:
207         cpu_abort(env_cpu(env),
208                   "Unsupported exception %d in Power Save mode\n", excp);
209     }
210     return POWERPC_EXCP_RESET;
211 }
212 
213 /*
214  * AIL - Alternate Interrupt Location, a mode that allows interrupts to be
215  * taken with the MMU on, and which uses an alternate location (e.g., so the
216  * kernel/hv can map the vectors there with an effective address).
217  *
218  * An interrupt is considered to be taken "with AIL" or "AIL applies" if they
219  * are delivered in this way. AIL requires the LPCR to be set to enable this
220  * mode, and then a number of conditions have to be true for AIL to apply.
221  *
222  * First of all, SRESET, MCE, and HMI are always delivered without AIL, because
223  * they specifically want to be in real mode (e.g., the MCE might be signaling
224  * a SLB multi-hit which requires SLB flush before the MMU can be enabled).
225  *
226  * After that, behaviour depends on the current MSR[IR], MSR[DR], MSR[HV],
227  * whether or not the interrupt changes MSR[HV] from 0 to 1, and the current
228  * radix mode (LPCR[HR]).
229  *
230  * POWER8, POWER9 with LPCR[HR]=0
231  * | LPCR[AIL] | MSR[IR||DR] | MSR[HV] | new MSR[HV] | AIL |
232  * +-----------+-------------+---------+-------------+-----+
233  * | a         | 00/01/10    | x       | x           | 0   |
234  * | a         | 11          | 0       | 1           | 0   |
235  * | a         | 11          | 1       | 1           | a   |
236  * | a         | 11          | 0       | 0           | a   |
237  * +-------------------------------------------------------+
238  *
239  * POWER9 with LPCR[HR]=1
240  * | LPCR[AIL] | MSR[IR||DR] | MSR[HV] | new MSR[HV] | AIL |
241  * +-----------+-------------+---------+-------------+-----+
242  * | a         | 00/01/10    | x       | x           | 0   |
243  * | a         | 11          | x       | x           | a   |
244  * +-------------------------------------------------------+
245  *
246  * The difference with POWER9 being that MSR[HV] 0->1 interrupts can be sent to
247  * the hypervisor in AIL mode if the guest is radix. This is good for
248  * performance but allows the guest to influence the AIL of hypervisor
249  * interrupts using its MSR, and also the hypervisor must disallow guest
250  * interrupts (MSR[HV] 0->0) from using AIL if the hypervisor does not want to
251  * use AIL for its MSR[HV] 0->1 interrupts.
252  *
253  * POWER10 addresses those issues with a new LPCR[HAIL] bit that is applied to
254  * interrupts that begin execution with MSR[HV]=1 (so both MSR[HV] 0->1 and
255  * MSR[HV] 1->1).
256  *
257  * HAIL=1 is equivalent to AIL=3, for interrupts delivered with MSR[HV]=1.
258  *
259  * POWER10 behaviour is
260  * | LPCR[AIL] | LPCR[HAIL] | MSR[IR||DR] | MSR[HV] | new MSR[HV] | AIL |
261  * +-----------+------------+-------------+---------+-------------+-----+
262  * | a         | h          | 00/01/10    | 0       | 0           | 0   |
263  * | a         | h          | 11          | 0       | 0           | a   |
264  * | a         | h          | x           | 0       | 1           | h   |
265  * | a         | h          | 00/01/10    | 1       | 1           | 0   |
266  * | a         | h          | 11          | 1       | 1           | h   |
267  * +--------------------------------------------------------------------+
268  */
269 static void ppc_excp_apply_ail(PowerPCCPU *cpu, int excp, target_ulong msr,
270                                target_ulong *new_msr, target_ulong *vector)
271 {
272     PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
273     CPUPPCState *env = &cpu->env;
274     bool mmu_all_on = ((msr >> MSR_IR) & 1) && ((msr >> MSR_DR) & 1);
275     bool hv_escalation = !(msr & MSR_HVB) && (*new_msr & MSR_HVB);
276     int ail = 0;
277 
278     if (excp == POWERPC_EXCP_MCHECK ||
279         excp == POWERPC_EXCP_RESET ||
280         excp == POWERPC_EXCP_HV_MAINT) {
281         /* SRESET, MCE, HMI never apply AIL */
282         return;
283     }
284 
285     if (!(pcc->lpcr_mask & LPCR_AIL)) {
286         /* This CPU does not have AIL */
287         return;
288     }
289 
290     /* P8 & P9 */
291     if (!(pcc->lpcr_mask & LPCR_HAIL)) {
292         if (!mmu_all_on) {
293             /* AIL only works if MSR[IR] and MSR[DR] are both enabled. */
294             return;
295         }
296         if (hv_escalation && !(env->spr[SPR_LPCR] & LPCR_HR)) {
297             /*
298              * AIL does not work if there is a MSR[HV] 0->1 transition and the
299              * partition is in HPT mode. For radix guests, such interrupts are
300              * allowed to be delivered to the hypervisor in ail mode.
301              */
302             return;
303         }
304 
305         ail = (env->spr[SPR_LPCR] & LPCR_AIL) >> LPCR_AIL_SHIFT;
306         if (ail == 0 || ail == 1) {
307             /* AIL=1 is reserved, treat it like AIL=0 */
308             return;
309         }
310 
311     /* P10 and up */
312     } else {
313         if (!mmu_all_on && !hv_escalation) {
314             /*
315              * AIL works for HV interrupts even with guest MSR[IR/DR] disabled.
316              * Guest->guest and HV->HV interrupts do require MMU on.
317              */
318             return;
319         }
320 
321         if (*new_msr & MSR_HVB) {
322             if (!(env->spr[SPR_LPCR] & LPCR_HAIL)) {
323                 /* HV interrupts depend on LPCR[HAIL] */
324                 return;
325             }
326             ail = 3; /* HAIL=1 gives AIL=3 behaviour for HV interrupts */
327         } else {
328             ail = (env->spr[SPR_LPCR] & LPCR_AIL) >> LPCR_AIL_SHIFT;
329         }
330         if (ail == 0 || ail == 1 || ail == 2) {
331             /* AIL=1 and AIL=2 are reserved, treat them like AIL=0 */
332             return;
333         }
334     }
335 
336     /*
337      * AIL applies, so the new MSR gets IR and DR set, and an offset applied
338      * to the new IP.
339      */
340     *new_msr |= (1 << MSR_IR) | (1 << MSR_DR);
341 
342     if (excp != POWERPC_EXCP_SYSCALL_VECTORED) {
343         if (ail == 2) {
344             *vector |= 0x0000000000018000ull;
345         } else if (ail == 3) {
346             *vector |= 0xc000000000004000ull;
347         }
348     } else {
349         /*
350          * scv AIL is a little different. AIL=2 does not change the address,
351          * only the MSR. AIL=3 replaces the 0x17000 base with 0xc...3000.
352          */
353         if (ail == 3) {
354             *vector &= ~0x0000000000017000ull; /* Un-apply the base offset */
355             *vector |= 0xc000000000003000ull; /* Apply scv's AIL=3 offset */
356         }
357     }
358 }
359 #endif /* TARGET_PPC64 */
360 
361 static void powerpc_reset_excp_state(PowerPCCPU *cpu)
362 {
363     CPUState *cs = CPU(cpu);
364     CPUPPCState *env = &cpu->env;
365 
366     /* Reset exception state */
367     cs->exception_index = POWERPC_EXCP_NONE;
368     env->error_code = 0;
369 }
370 
371 static void powerpc_set_excp_state(PowerPCCPU *cpu, target_ulong vector,
372                                    target_ulong msr)
373 {
374     CPUPPCState *env = &cpu->env;
375 
376     assert((msr & env->msr_mask) == msr);
377 
378     /*
379      * We don't use hreg_store_msr here as already have treated any
380      * special case that could occur. Just store MSR and update hflags
381      *
382      * Note: We *MUST* not use hreg_store_msr() as-is anyway because it will
383      * prevent setting of the HV bit which some exceptions might need to do.
384      */
385     env->nip = vector;
386     env->msr = msr;
387     hreg_compute_hflags(env);
388     ppc_maybe_interrupt(env);
389 
390     powerpc_reset_excp_state(cpu);
391 
392     /*
393      * Any interrupt is context synchronizing, check if TCG TLB needs
394      * a delayed flush on ppc64
395      */
396     check_tlb_flush(env, false);
397 
398     /* Reset the reservation */
399     env->reserve_addr = -1;
400 }
401 
402 #ifdef CONFIG_TCG
403 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
404 void helper_attn(CPUPPCState *env)
405 {
406     /* POWER attn is unprivileged when enabled by HID, otherwise illegal */
407     if ((*env->check_attn)(env)) {
408         powerpc_checkstop(env, "host executed attn");
409     } else {
410         raise_exception_err(env, POWERPC_EXCP_HV_EMU,
411                             POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL);
412     }
413 }
414 #endif
415 #endif /* CONFIG_TCG */
416 
417 static void powerpc_mcheck_checkstop(CPUPPCState *env)
418 {
419     /* KVM guests always have MSR[ME] enabled */
420     if (FIELD_EX64(env->msr, MSR, ME)) {
421         return;
422     }
423     assert(tcg_enabled());
424     powerpc_checkstop(env, "machine check with MSR[ME]=0");
425 }
426 
427 static void powerpc_excp_40x(PowerPCCPU *cpu, int excp)
428 {
429     CPUPPCState *env = &cpu->env;
430     target_ulong msr, new_msr, vector;
431     int srr0 = SPR_SRR0, srr1 = SPR_SRR1;
432 
433     /* new srr1 value excluding must-be-zero bits */
434     msr = env->msr & ~0x783f0000ULL;
435 
436     /* new interrupt handler msr preserves ME unless explicitly overridden */
437     new_msr = env->msr & (((target_ulong)1 << MSR_ME));
438 
439     /* HV emu assistance interrupt only exists on server arch 2.05 or later */
440     if (excp == POWERPC_EXCP_HV_EMU) {
441         excp = POWERPC_EXCP_PROGRAM;
442     }
443 
444     vector = env->excp_vectors[excp];
445     if (vector == (target_ulong)-1ULL) {
446         cpu_abort(env_cpu(env),
447                   "Raised an exception without defined vector %d\n", excp);
448     }
449     vector |= env->excp_prefix;
450 
451     switch (excp) {
452     case POWERPC_EXCP_CRITICAL:    /* Critical input                         */
453         srr0 = SPR_40x_SRR2;
454         srr1 = SPR_40x_SRR3;
455         break;
456     case POWERPC_EXCP_MCHECK:    /* Machine check exception                  */
457         powerpc_mcheck_checkstop(env);
458         /* machine check exceptions don't have ME set */
459         new_msr &= ~((target_ulong)1 << MSR_ME);
460         srr0 = SPR_40x_SRR2;
461         srr1 = SPR_40x_SRR3;
462         break;
463     case POWERPC_EXCP_DSI:       /* Data storage exception                   */
464         trace_ppc_excp_dsi(env->spr[SPR_40x_ESR], env->spr[SPR_40x_DEAR]);
465         break;
466     case POWERPC_EXCP_ISI:       /* Instruction storage exception            */
467         trace_ppc_excp_isi(msr, env->nip);
468         break;
469     case POWERPC_EXCP_EXTERNAL:  /* External input                           */
470         break;
471     case POWERPC_EXCP_ALIGN:     /* Alignment exception                      */
472         break;
473     case POWERPC_EXCP_PROGRAM:   /* Program exception                        */
474         switch (env->error_code & ~0xF) {
475         case POWERPC_EXCP_FP:
476             if (!FIELD_EX64_FE(env->msr) || !FIELD_EX64(env->msr, MSR, FP)) {
477                 trace_ppc_excp_fp_ignore();
478                 powerpc_reset_excp_state(cpu);
479                 return;
480             }
481             env->spr[SPR_40x_ESR] = ESR_FP;
482             break;
483         case POWERPC_EXCP_INVAL:
484             trace_ppc_excp_inval(env->nip);
485             env->spr[SPR_40x_ESR] = ESR_PIL;
486             break;
487         case POWERPC_EXCP_PRIV:
488             env->spr[SPR_40x_ESR] = ESR_PPR;
489             break;
490         case POWERPC_EXCP_TRAP:
491             env->spr[SPR_40x_ESR] = ESR_PTR;
492             break;
493         default:
494             cpu_abort(env_cpu(env), "Invalid program exception %d. Aborting\n",
495                       env->error_code);
496             break;
497         }
498         break;
499     case POWERPC_EXCP_SYSCALL:   /* System call exception                    */
500         dump_syscall(env);
501 
502         /*
503          * We need to correct the NIP which in this case is supposed
504          * to point to the next instruction
505          */
506         env->nip += 4;
507         break;
508     case POWERPC_EXCP_FIT:       /* Fixed-interval timer interrupt           */
509         trace_ppc_excp_print("FIT");
510         break;
511     case POWERPC_EXCP_WDT:       /* Watchdog timer interrupt                 */
512         trace_ppc_excp_print("WDT");
513         break;
514     case POWERPC_EXCP_DTLB:      /* Data TLB error                           */
515     case POWERPC_EXCP_ITLB:      /* Instruction TLB error                    */
516         break;
517     case POWERPC_EXCP_PIT:       /* Programmable interval timer interrupt    */
518         trace_ppc_excp_print("PIT");
519         break;
520     case POWERPC_EXCP_DEBUG:     /* Debug interrupt                          */
521         cpu_abort(env_cpu(env), "%s exception not implemented\n",
522                   powerpc_excp_name(excp));
523         break;
524     default:
525         cpu_abort(env_cpu(env), "Invalid PowerPC exception %d. Aborting\n",
526                   excp);
527         break;
528     }
529 
530     env->spr[srr0] = env->nip;
531     env->spr[srr1] = msr;
532     powerpc_set_excp_state(cpu, vector, new_msr);
533 }
534 
535 static void powerpc_excp_6xx(PowerPCCPU *cpu, int excp)
536 {
537     CPUPPCState *env = &cpu->env;
538     target_ulong msr, new_msr, vector;
539 
540     /* new srr1 value excluding must-be-zero bits */
541     msr = env->msr & ~0x783f0000ULL;
542 
543     /* new interrupt handler msr preserves ME unless explicitly overridden */
544     new_msr = env->msr & ((target_ulong)1 << MSR_ME);
545 
546     /* HV emu assistance interrupt only exists on server arch 2.05 or later */
547     if (excp == POWERPC_EXCP_HV_EMU) {
548         excp = POWERPC_EXCP_PROGRAM;
549     }
550 
551     vector = env->excp_vectors[excp];
552     if (vector == (target_ulong)-1ULL) {
553         cpu_abort(env_cpu(env),
554                   "Raised an exception without defined vector %d\n", excp);
555     }
556     vector |= env->excp_prefix;
557 
558     switch (excp) {
559     case POWERPC_EXCP_CRITICAL:    /* Critical input                         */
560         break;
561     case POWERPC_EXCP_MCHECK:    /* Machine check exception                  */
562         powerpc_mcheck_checkstop(env);
563         /* machine check exceptions don't have ME set */
564         new_msr &= ~((target_ulong)1 << MSR_ME);
565         break;
566     case POWERPC_EXCP_DSI:       /* Data storage exception                   */
567         trace_ppc_excp_dsi(env->spr[SPR_DSISR], env->spr[SPR_DAR]);
568         break;
569     case POWERPC_EXCP_ISI:       /* Instruction storage exception            */
570         trace_ppc_excp_isi(msr, env->nip);
571         msr |= env->error_code;
572         break;
573     case POWERPC_EXCP_EXTERNAL:  /* External input                           */
574         break;
575     case POWERPC_EXCP_ALIGN:     /* Alignment exception                      */
576         /* Get rS/rD and rA from faulting opcode */
577         /*
578          * Note: the opcode fields will not be set properly for a
579          * direct store load/store, but nobody cares as nobody
580          * actually uses direct store segments.
581          */
582         env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16;
583         break;
584     case POWERPC_EXCP_PROGRAM:   /* Program exception                        */
585         switch (env->error_code & ~0xF) {
586         case POWERPC_EXCP_FP:
587             if (!FIELD_EX64_FE(env->msr) || !FIELD_EX64(env->msr, MSR, FP)) {
588                 trace_ppc_excp_fp_ignore();
589                 powerpc_reset_excp_state(cpu);
590                 return;
591             }
592             /*
593              * NIP always points to the faulting instruction for FP exceptions,
594              * so always use store_next and claim we are precise in the MSR.
595              */
596             msr |= 0x00100000;
597             break;
598         case POWERPC_EXCP_INVAL:
599             trace_ppc_excp_inval(env->nip);
600             msr |= 0x00080000;
601             break;
602         case POWERPC_EXCP_PRIV:
603             msr |= 0x00040000;
604             break;
605         case POWERPC_EXCP_TRAP:
606             msr |= 0x00020000;
607             break;
608         default:
609             /* Should never occur */
610             cpu_abort(env_cpu(env), "Invalid program exception %d. Aborting\n",
611                       env->error_code);
612             break;
613         }
614         break;
615     case POWERPC_EXCP_SYSCALL:   /* System call exception                    */
616         dump_syscall(env);
617 
618         /*
619          * We need to correct the NIP which in this case is supposed
620          * to point to the next instruction
621          */
622         env->nip += 4;
623         break;
624     case POWERPC_EXCP_FPU:       /* Floating-point unavailable exception     */
625     case POWERPC_EXCP_DECR:      /* Decrementer exception                    */
626         break;
627     case POWERPC_EXCP_DTLB:      /* Data TLB error                           */
628     case POWERPC_EXCP_ITLB:      /* Instruction TLB error                    */
629         break;
630     case POWERPC_EXCP_RESET:     /* System reset exception                   */
631         if (FIELD_EX64(env->msr, MSR, POW)) {
632             cpu_abort(env_cpu(env),
633                       "Trying to deliver power-saving system reset exception "
634                       "%d with no HV support\n", excp);
635         }
636         break;
637     case POWERPC_EXCP_TRACE:     /* Trace exception                          */
638         break;
639     case POWERPC_EXCP_IFTLB:     /* Instruction fetch TLB error              */
640     case POWERPC_EXCP_DLTLB:     /* Data load TLB miss                       */
641     case POWERPC_EXCP_DSTLB:     /* Data store TLB miss                      */
642         /* Swap temporary saved registers with GPRs */
643         if (!(new_msr & ((target_ulong)1 << MSR_TGPR))) {
644             new_msr |= (target_ulong)1 << MSR_TGPR;
645             hreg_swap_gpr_tgpr(env);
646         }
647 
648         ppc_excp_debug_sw_tlb(env, excp);
649 
650         msr |= env->crf[0] << 28;
651         msr |= env->error_code; /* key, D/I, S/L bits */
652         /* Set way using a LRU mechanism */
653         msr |= ((env->last_way + 1) & (env->nb_ways - 1)) << 17;
654         break;
655     case POWERPC_EXCP_FPA:       /* Floating-point assist exception          */
656     case POWERPC_EXCP_DABR:      /* Data address breakpoint                  */
657     case POWERPC_EXCP_IABR:      /* Instruction address breakpoint           */
658     case POWERPC_EXCP_SMI:       /* System management interrupt              */
659     case POWERPC_EXCP_MEXTBR:    /* Maskable external breakpoint             */
660     case POWERPC_EXCP_NMEXTBR:   /* Non maskable external breakpoint         */
661         cpu_abort(env_cpu(env), "%s exception not implemented\n",
662                   powerpc_excp_name(excp));
663         break;
664     default:
665         cpu_abort(env_cpu(env), "Invalid PowerPC exception %d. Aborting\n",
666                   excp);
667         break;
668     }
669 
670     if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) {
671         new_msr |= (target_ulong)1 << MSR_LE;
672     }
673     env->spr[SPR_SRR0] = env->nip;
674     env->spr[SPR_SRR1] = msr;
675     powerpc_set_excp_state(cpu, vector, new_msr);
676 }
677 
678 static void powerpc_excp_7xx(PowerPCCPU *cpu, int excp)
679 {
680     CPUPPCState *env = &cpu->env;
681     target_ulong msr, new_msr, vector;
682 
683     /* new srr1 value excluding must-be-zero bits */
684     msr = env->msr & ~0x783f0000ULL;
685 
686     /* new interrupt handler msr preserves ME unless explicitly overridden */
687     new_msr = env->msr & ((target_ulong)1 << MSR_ME);
688 
689     /* HV emu assistance interrupt only exists on server arch 2.05 or later */
690     if (excp == POWERPC_EXCP_HV_EMU) {
691         excp = POWERPC_EXCP_PROGRAM;
692     }
693 
694     vector = env->excp_vectors[excp];
695     if (vector == (target_ulong)-1ULL) {
696         cpu_abort(env_cpu(env),
697                   "Raised an exception without defined vector %d\n", excp);
698     }
699     vector |= env->excp_prefix;
700 
701     switch (excp) {
702     case POWERPC_EXCP_MCHECK:    /* Machine check exception                  */
703         powerpc_mcheck_checkstop(env);
704         /* machine check exceptions don't have ME set */
705         new_msr &= ~((target_ulong)1 << MSR_ME);
706         break;
707     case POWERPC_EXCP_DSI:       /* Data storage exception                   */
708         trace_ppc_excp_dsi(env->spr[SPR_DSISR], env->spr[SPR_DAR]);
709         break;
710     case POWERPC_EXCP_ISI:       /* Instruction storage exception            */
711         trace_ppc_excp_isi(msr, env->nip);
712         msr |= env->error_code;
713         break;
714     case POWERPC_EXCP_EXTERNAL:  /* External input                           */
715         break;
716     case POWERPC_EXCP_ALIGN:     /* Alignment exception                      */
717         /* Get rS/rD and rA from faulting opcode */
718         /*
719          * Note: the opcode fields will not be set properly for a
720          * direct store load/store, but nobody cares as nobody
721          * actually uses direct store segments.
722          */
723         env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16;
724         break;
725     case POWERPC_EXCP_PROGRAM:   /* Program exception                        */
726         switch (env->error_code & ~0xF) {
727         case POWERPC_EXCP_FP:
728             if (!FIELD_EX64_FE(env->msr) || !FIELD_EX64(env->msr, MSR, FP)) {
729                 trace_ppc_excp_fp_ignore();
730                 powerpc_reset_excp_state(cpu);
731                 return;
732             }
733             /*
734              * NIP always points to the faulting instruction for FP exceptions,
735              * so always use store_next and claim we are precise in the MSR.
736              */
737             msr |= 0x00100000;
738             break;
739         case POWERPC_EXCP_INVAL:
740             trace_ppc_excp_inval(env->nip);
741             msr |= 0x00080000;
742             break;
743         case POWERPC_EXCP_PRIV:
744             msr |= 0x00040000;
745             break;
746         case POWERPC_EXCP_TRAP:
747             msr |= 0x00020000;
748             break;
749         default:
750             /* Should never occur */
751             cpu_abort(env_cpu(env), "Invalid program exception %d. Aborting\n",
752                       env->error_code);
753             break;
754         }
755         break;
756     case POWERPC_EXCP_SYSCALL:   /* System call exception                    */
757     {
758         int lev = env->error_code;
759 
760         if (lev == 1 && cpu->vhyp) {
761             dump_hcall(env);
762         } else {
763             dump_syscall(env);
764         }
765 
766         /*
767          * We need to correct the NIP which in this case is supposed
768          * to point to the next instruction
769          */
770         env->nip += 4;
771 
772         /*
773          * The Virtual Open Firmware (VOF) relies on the 'sc 1'
774          * instruction to communicate with QEMU. The pegasos2 machine
775          * uses VOF and the 7xx CPUs, so although the 7xx don't have
776          * HV mode, we need to keep hypercall support.
777          */
778         if (lev == 1 && cpu->vhyp) {
779             cpu->vhyp_class->hypercall(cpu->vhyp, cpu);
780             powerpc_reset_excp_state(cpu);
781             return;
782         }
783 
784         break;
785     }
786     case POWERPC_EXCP_FPU:       /* Floating-point unavailable exception     */
787     case POWERPC_EXCP_DECR:      /* Decrementer exception                    */
788         break;
789     case POWERPC_EXCP_RESET:     /* System reset exception                   */
790         if (FIELD_EX64(env->msr, MSR, POW)) {
791             cpu_abort(env_cpu(env),
792                       "Trying to deliver power-saving system reset exception "
793                       "%d with no HV support\n", excp);
794         }
795         break;
796     case POWERPC_EXCP_TRACE:     /* Trace exception                          */
797         break;
798     case POWERPC_EXCP_IFTLB:     /* Instruction fetch TLB error              */
799     case POWERPC_EXCP_DLTLB:     /* Data load TLB miss                       */
800     case POWERPC_EXCP_DSTLB:     /* Data store TLB miss                      */
801         ppc_excp_debug_sw_tlb(env, excp);
802         msr |= env->crf[0] << 28;
803         msr |= env->error_code; /* key, D/I, S/L bits */
804         /* Set way using a LRU mechanism */
805         msr |= ((env->last_way + 1) & (env->nb_ways - 1)) << 17;
806         break;
807     case POWERPC_EXCP_IABR:      /* Instruction address breakpoint           */
808     case POWERPC_EXCP_SMI:       /* System management interrupt              */
809     case POWERPC_EXCP_THERM:     /* Thermal interrupt                        */
810     case POWERPC_EXCP_PERFM:     /* Embedded performance monitor interrupt   */
811         cpu_abort(env_cpu(env), "%s exception not implemented\n",
812                   powerpc_excp_name(excp));
813         break;
814     default:
815         cpu_abort(env_cpu(env), "Invalid PowerPC exception %d. Aborting\n",
816                   excp);
817         break;
818     }
819 
820     if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) {
821         new_msr |= (target_ulong)1 << MSR_LE;
822     }
823     env->spr[SPR_SRR0] = env->nip;
824     env->spr[SPR_SRR1] = msr;
825     powerpc_set_excp_state(cpu, vector, new_msr);
826 }
827 
828 static void powerpc_excp_74xx(PowerPCCPU *cpu, int excp)
829 {
830     CPUPPCState *env = &cpu->env;
831     target_ulong msr, new_msr, vector;
832 
833     /* new srr1 value excluding must-be-zero bits */
834     msr = env->msr & ~0x783f0000ULL;
835 
836     /* new interrupt handler msr preserves ME unless explicitly overridden */
837     new_msr = env->msr & ((target_ulong)1 << MSR_ME);
838 
839     /* HV emu assistance interrupt only exists on server arch 2.05 or later */
840     if (excp == POWERPC_EXCP_HV_EMU) {
841         excp = POWERPC_EXCP_PROGRAM;
842     }
843 
844     vector = env->excp_vectors[excp];
845     if (vector == (target_ulong)-1ULL) {
846         cpu_abort(env_cpu(env),
847                   "Raised an exception without defined vector %d\n", excp);
848     }
849     vector |= env->excp_prefix;
850 
851     switch (excp) {
852     case POWERPC_EXCP_MCHECK:    /* Machine check exception                  */
853         powerpc_mcheck_checkstop(env);
854         /* machine check exceptions don't have ME set */
855         new_msr &= ~((target_ulong)1 << MSR_ME);
856         break;
857     case POWERPC_EXCP_DSI:       /* Data storage exception                   */
858         trace_ppc_excp_dsi(env->spr[SPR_DSISR], env->spr[SPR_DAR]);
859         break;
860     case POWERPC_EXCP_ISI:       /* Instruction storage exception            */
861         trace_ppc_excp_isi(msr, env->nip);
862         msr |= env->error_code;
863         break;
864     case POWERPC_EXCP_EXTERNAL:  /* External input                           */
865         break;
866     case POWERPC_EXCP_ALIGN:     /* Alignment exception                      */
867         /* Get rS/rD and rA from faulting opcode */
868         /*
869          * Note: the opcode fields will not be set properly for a
870          * direct store load/store, but nobody cares as nobody
871          * actually uses direct store segments.
872          */
873         env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16;
874         break;
875     case POWERPC_EXCP_PROGRAM:   /* Program exception                        */
876         switch (env->error_code & ~0xF) {
877         case POWERPC_EXCP_FP:
878             if (!FIELD_EX64_FE(env->msr) || !FIELD_EX64(env->msr, MSR, FP)) {
879                 trace_ppc_excp_fp_ignore();
880                 powerpc_reset_excp_state(cpu);
881                 return;
882             }
883             /*
884              * NIP always points to the faulting instruction for FP exceptions,
885              * so always use store_next and claim we are precise in the MSR.
886              */
887             msr |= 0x00100000;
888             break;
889         case POWERPC_EXCP_INVAL:
890             trace_ppc_excp_inval(env->nip);
891             msr |= 0x00080000;
892             break;
893         case POWERPC_EXCP_PRIV:
894             msr |= 0x00040000;
895             break;
896         case POWERPC_EXCP_TRAP:
897             msr |= 0x00020000;
898             break;
899         default:
900             /* Should never occur */
901             cpu_abort(env_cpu(env), "Invalid program exception %d. Aborting\n",
902                       env->error_code);
903             break;
904         }
905         break;
906     case POWERPC_EXCP_SYSCALL:   /* System call exception                    */
907     {
908         int lev = env->error_code;
909 
910         if (lev == 1 && cpu->vhyp) {
911             dump_hcall(env);
912         } else {
913             dump_syscall(env);
914         }
915 
916         /*
917          * We need to correct the NIP which in this case is supposed
918          * to point to the next instruction
919          */
920         env->nip += 4;
921 
922         /*
923          * The Virtual Open Firmware (VOF) relies on the 'sc 1'
924          * instruction to communicate with QEMU. The pegasos2 machine
925          * uses VOF and the 74xx CPUs, so although the 74xx don't have
926          * HV mode, we need to keep hypercall support.
927          */
928         if (lev == 1 && cpu->vhyp) {
929             cpu->vhyp_class->hypercall(cpu->vhyp, cpu);
930             powerpc_reset_excp_state(cpu);
931             return;
932         }
933 
934         break;
935     }
936     case POWERPC_EXCP_FPU:       /* Floating-point unavailable exception     */
937     case POWERPC_EXCP_DECR:      /* Decrementer exception                    */
938         break;
939     case POWERPC_EXCP_RESET:     /* System reset exception                   */
940         if (FIELD_EX64(env->msr, MSR, POW)) {
941             cpu_abort(env_cpu(env),
942                       "Trying to deliver power-saving system reset "
943                       "exception %d with no HV support\n", excp);
944         }
945         break;
946     case POWERPC_EXCP_TRACE:     /* Trace exception                          */
947         break;
948     case POWERPC_EXCP_VPU:       /* Vector unavailable exception             */
949         break;
950     case POWERPC_EXCP_IABR:      /* Instruction address breakpoint           */
951     case POWERPC_EXCP_SMI:       /* System management interrupt              */
952     case POWERPC_EXCP_THERM:     /* Thermal interrupt                        */
953     case POWERPC_EXCP_PERFM:     /* Embedded performance monitor interrupt   */
954     case POWERPC_EXCP_VPUA:      /* Vector assist exception                  */
955         cpu_abort(env_cpu(env), "%s exception not implemented\n",
956                   powerpc_excp_name(excp));
957         break;
958     default:
959         cpu_abort(env_cpu(env), "Invalid PowerPC exception %d. Aborting\n",
960                   excp);
961         break;
962     }
963 
964     if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) {
965         new_msr |= (target_ulong)1 << MSR_LE;
966     }
967     env->spr[SPR_SRR0] = env->nip;
968     env->spr[SPR_SRR1] = msr;
969     powerpc_set_excp_state(cpu, vector, new_msr);
970 }
971 
972 static void powerpc_excp_booke(PowerPCCPU *cpu, int excp)
973 {
974     CPUPPCState *env = &cpu->env;
975     target_ulong msr, new_msr, vector;
976     int srr0 = SPR_SRR0, srr1 = SPR_SRR1;
977 
978     /*
979      * Book E does not play games with certain bits of xSRR1 being MSR save
980      * bits and others being error status. xSRR1 is the old MSR, period.
981      */
982     msr = env->msr;
983 
984     /* new interrupt handler msr preserves ME unless explicitly overridden */
985     new_msr = env->msr & ((target_ulong)1 << MSR_ME);
986 
987     /* HV emu assistance interrupt only exists on server arch 2.05 or later */
988     if (excp == POWERPC_EXCP_HV_EMU) {
989         excp = POWERPC_EXCP_PROGRAM;
990     }
991 
992 #ifdef TARGET_PPC64
993     /*
994      * SPEU and VPU share the same IVOR but they exist in different
995      * processors. SPEU is e500v1/2 only and VPU is e6500 only.
996      */
997     if (excp == POWERPC_EXCP_VPU) {
998         excp = POWERPC_EXCP_SPEU;
999     }
1000 #endif
1001 
1002     vector = env->excp_vectors[excp];
1003     if (vector == (target_ulong)-1ULL) {
1004         cpu_abort(env_cpu(env),
1005                   "Raised an exception without defined vector %d\n", excp);
1006     }
1007     vector |= env->excp_prefix;
1008 
1009     switch (excp) {
1010     case POWERPC_EXCP_CRITICAL:    /* Critical input                         */
1011         srr0 = SPR_BOOKE_CSRR0;
1012         srr1 = SPR_BOOKE_CSRR1;
1013         break;
1014     case POWERPC_EXCP_MCHECK:    /* Machine check exception                  */
1015         powerpc_mcheck_checkstop(env);
1016         /* machine check exceptions don't have ME set */
1017         new_msr &= ~((target_ulong)1 << MSR_ME);
1018 
1019         /* FIXME: choose one or the other based on CPU type */
1020         srr0 = SPR_BOOKE_MCSRR0;
1021         srr1 = SPR_BOOKE_MCSRR1;
1022 
1023         env->spr[SPR_BOOKE_CSRR0] = env->nip;
1024         env->spr[SPR_BOOKE_CSRR1] = msr;
1025 
1026         break;
1027     case POWERPC_EXCP_DSI:       /* Data storage exception                   */
1028         trace_ppc_excp_dsi(env->spr[SPR_BOOKE_ESR], env->spr[SPR_BOOKE_DEAR]);
1029         break;
1030     case POWERPC_EXCP_ISI:       /* Instruction storage exception            */
1031         trace_ppc_excp_isi(msr, env->nip);
1032         break;
1033     case POWERPC_EXCP_EXTERNAL:  /* External input                           */
1034         if (env->mpic_proxy) {
1035             CPUState *cs = env_cpu(env);
1036             /* IACK the IRQ on delivery */
1037             env->spr[SPR_BOOKE_EPR] = ldl_phys(cs->as, env->mpic_iack);
1038         }
1039         break;
1040     case POWERPC_EXCP_ALIGN:     /* Alignment exception                      */
1041         break;
1042     case POWERPC_EXCP_PROGRAM:   /* Program exception                        */
1043         switch (env->error_code & ~0xF) {
1044         case POWERPC_EXCP_FP:
1045             if (!FIELD_EX64_FE(env->msr) || !FIELD_EX64(env->msr, MSR, FP)) {
1046                 trace_ppc_excp_fp_ignore();
1047                 powerpc_reset_excp_state(cpu);
1048                 return;
1049             }
1050             /*
1051              * NIP always points to the faulting instruction for FP exceptions,
1052              * so always use store_next and claim we are precise in the MSR.
1053              */
1054             msr |= 0x00100000;
1055             env->spr[SPR_BOOKE_ESR] = ESR_FP;
1056             break;
1057         case POWERPC_EXCP_INVAL:
1058             trace_ppc_excp_inval(env->nip);
1059             msr |= 0x00080000;
1060             env->spr[SPR_BOOKE_ESR] = ESR_PIL;
1061             break;
1062         case POWERPC_EXCP_PRIV:
1063             msr |= 0x00040000;
1064             env->spr[SPR_BOOKE_ESR] = ESR_PPR;
1065             break;
1066         case POWERPC_EXCP_TRAP:
1067             msr |= 0x00020000;
1068             env->spr[SPR_BOOKE_ESR] = ESR_PTR;
1069             break;
1070         default:
1071             /* Should never occur */
1072             cpu_abort(env_cpu(env), "Invalid program exception %d. Aborting\n",
1073                       env->error_code);
1074             break;
1075         }
1076         break;
1077     case POWERPC_EXCP_SYSCALL:   /* System call exception                    */
1078         dump_syscall(env);
1079 
1080         /*
1081          * We need to correct the NIP which in this case is supposed
1082          * to point to the next instruction
1083          */
1084         env->nip += 4;
1085         break;
1086     case POWERPC_EXCP_FPU:       /* Floating-point unavailable exception     */
1087     case POWERPC_EXCP_APU:       /* Auxiliary processor unavailable          */
1088     case POWERPC_EXCP_DECR:      /* Decrementer exception                    */
1089         break;
1090     case POWERPC_EXCP_FIT:       /* Fixed-interval timer interrupt           */
1091         /* FIT on 4xx */
1092         trace_ppc_excp_print("FIT");
1093         break;
1094     case POWERPC_EXCP_WDT:       /* Watchdog timer interrupt                 */
1095         trace_ppc_excp_print("WDT");
1096         srr0 = SPR_BOOKE_CSRR0;
1097         srr1 = SPR_BOOKE_CSRR1;
1098         break;
1099     case POWERPC_EXCP_DTLB:      /* Data TLB error                           */
1100     case POWERPC_EXCP_ITLB:      /* Instruction TLB error                    */
1101         break;
1102     case POWERPC_EXCP_DEBUG:     /* Debug interrupt                          */
1103         if (env->flags & POWERPC_FLAG_DE) {
1104             /* FIXME: choose one or the other based on CPU type */
1105             srr0 = SPR_BOOKE_DSRR0;
1106             srr1 = SPR_BOOKE_DSRR1;
1107 
1108             env->spr[SPR_BOOKE_CSRR0] = env->nip;
1109             env->spr[SPR_BOOKE_CSRR1] = msr;
1110 
1111             /* DBSR already modified by caller */
1112         } else {
1113             cpu_abort(env_cpu(env),
1114                       "Debug exception triggered on unsupported model\n");
1115         }
1116         break;
1117     case POWERPC_EXCP_SPEU:   /* SPE/embedded floating-point unavailable/VPU  */
1118         env->spr[SPR_BOOKE_ESR] = ESR_SPV;
1119         break;
1120     case POWERPC_EXCP_DOORI:     /* Embedded doorbell interrupt              */
1121         break;
1122     case POWERPC_EXCP_DOORCI:    /* Embedded doorbell critical interrupt     */
1123         srr0 = SPR_BOOKE_CSRR0;
1124         srr1 = SPR_BOOKE_CSRR1;
1125         break;
1126     case POWERPC_EXCP_RESET:     /* System reset exception                   */
1127         if (FIELD_EX64(env->msr, MSR, POW)) {
1128             cpu_abort(env_cpu(env),
1129                       "Trying to deliver power-saving system reset "
1130                       "exception %d with no HV support\n", excp);
1131         }
1132         break;
1133     case POWERPC_EXCP_EFPDI:     /* Embedded floating-point data interrupt   */
1134     case POWERPC_EXCP_EFPRI:     /* Embedded floating-point round interrupt  */
1135         cpu_abort(env_cpu(env), "%s exception not implemented\n",
1136                   powerpc_excp_name(excp));
1137         break;
1138     default:
1139         cpu_abort(env_cpu(env), "Invalid PowerPC exception %d. Aborting\n",
1140                   excp);
1141         break;
1142     }
1143 
1144 #ifdef TARGET_PPC64
1145     if (env->spr[SPR_BOOKE_EPCR] & EPCR_ICM) {
1146         /* Cat.64-bit: EPCR.ICM is copied to MSR.CM */
1147         new_msr |= (target_ulong)1 << MSR_CM;
1148     } else {
1149         vector = (uint32_t)vector;
1150     }
1151 #endif
1152 
1153     env->spr[srr0] = env->nip;
1154     env->spr[srr1] = msr;
1155     powerpc_set_excp_state(cpu, vector, new_msr);
1156 }
1157 
1158 /*
1159  * When running a nested HV guest under vhyp, external interrupts are
1160  * delivered as HVIRT.
1161  */
1162 static bool books_vhyp_promotes_external_to_hvirt(PowerPCCPU *cpu)
1163 {
1164     if (cpu->vhyp) {
1165         return vhyp_cpu_in_nested(cpu);
1166     }
1167     return false;
1168 }
1169 
1170 #ifdef TARGET_PPC64
1171 /*
1172  * When running under vhyp, hcalls are always intercepted and sent to the
1173  * vhc->hypercall handler.
1174  */
1175 static bool books_vhyp_handles_hcall(PowerPCCPU *cpu)
1176 {
1177     if (cpu->vhyp) {
1178         return !vhyp_cpu_in_nested(cpu);
1179     }
1180     return false;
1181 }
1182 
1183 /*
1184  * When running a nested KVM HV guest under vhyp, HV exceptions are not
1185  * delivered to the guest (because there is no concept of HV support), but
1186  * rather they are sent to the vhyp to exit from the L2 back to the L1 and
1187  * return from the H_ENTER_NESTED hypercall.
1188  */
1189 static bool books_vhyp_handles_hv_excp(PowerPCCPU *cpu)
1190 {
1191     if (cpu->vhyp) {
1192         return vhyp_cpu_in_nested(cpu);
1193     }
1194     return false;
1195 }
1196 
1197 #ifdef CONFIG_TCG
1198 static bool is_prefix_insn(CPUPPCState *env, uint32_t insn)
1199 {
1200     if (!(env->insns_flags2 & PPC2_ISA310)) {
1201         return false;
1202     }
1203     return ((insn & 0xfc000000) == 0x04000000);
1204 }
1205 
1206 static bool is_prefix_insn_excp(PowerPCCPU *cpu, int excp)
1207 {
1208     CPUPPCState *env = &cpu->env;
1209 
1210     if (!(env->insns_flags2 & PPC2_ISA310)) {
1211         return false;
1212     }
1213 
1214     if (!tcg_enabled()) {
1215         /*
1216          * This does not load instructions and set the prefix bit correctly
1217          * for injected interrupts with KVM. That may have to be discovered
1218          * and set by the KVM layer before injecting.
1219          */
1220         return false;
1221     }
1222 
1223     switch (excp) {
1224     case POWERPC_EXCP_MCHECK:
1225         if (!(env->error_code & PPC_BIT(42))) {
1226             /*
1227              * Fetch attempt caused a machine check, so attempting to fetch
1228              * again would cause a recursive machine check.
1229              */
1230             return false;
1231         }
1232         break;
1233     case POWERPC_EXCP_HDSI:
1234         /* HDSI PRTABLE_FAULT has the originating access type in error_code */
1235         if ((env->spr[SPR_HDSISR] & DSISR_PRTABLE_FAULT) &&
1236             (env->error_code == MMU_INST_FETCH)) {
1237             /*
1238              * Fetch failed due to partition scope translation, so prefix
1239              * indication is not relevant (and attempting to load the
1240              * instruction at NIP would cause recursive faults with the same
1241              * translation).
1242              */
1243             return false;
1244         }
1245         break;
1246 
1247     case POWERPC_EXCP_DSI:
1248     case POWERPC_EXCP_DSEG:
1249     case POWERPC_EXCP_ALIGN:
1250     case POWERPC_EXCP_PROGRAM:
1251     case POWERPC_EXCP_FPU:
1252     case POWERPC_EXCP_TRACE:
1253     case POWERPC_EXCP_HV_EMU:
1254     case POWERPC_EXCP_VPU:
1255     case POWERPC_EXCP_VSXU:
1256     case POWERPC_EXCP_FU:
1257     case POWERPC_EXCP_HV_FU:
1258         break;
1259     default:
1260         return false;
1261     }
1262 
1263     return is_prefix_insn(env, ppc_ldl_code(env, env->nip));
1264 }
1265 #else
1266 static bool is_prefix_insn_excp(PowerPCCPU *cpu, int excp)
1267 {
1268     return false;
1269 }
1270 #endif
1271 
1272 static void powerpc_excp_books(PowerPCCPU *cpu, int excp)
1273 {
1274     CPUPPCState *env = &cpu->env;
1275     target_ulong msr, new_msr, vector;
1276     int srr0 = SPR_SRR0, srr1 = SPR_SRR1, lev = -1;
1277 
1278     /* new srr1 value excluding must-be-zero bits */
1279     msr = env->msr & ~0x783f0000ULL;
1280 
1281     /*
1282      * new interrupt handler msr preserves HV and ME unless explicitly
1283      * overridden
1284      */
1285     new_msr = env->msr & (((target_ulong)1 << MSR_ME) | MSR_HVB);
1286 
1287     /*
1288      * check for special resume at 0x100 from doze/nap/sleep/winkle on
1289      * P7/P8/P9
1290      */
1291     if (env->resume_as_sreset) {
1292         excp = powerpc_reset_wakeup(env, excp, &msr);
1293     }
1294 
1295     /*
1296      * We don't want to generate a Hypervisor Emulation Assistance
1297      * Interrupt if we don't have HVB in msr_mask (PAPR mode),
1298      * unless running a nested-hv guest, in which case the L1
1299      * kernel wants the interrupt.
1300      */
1301     if (excp == POWERPC_EXCP_HV_EMU && !(env->msr_mask & MSR_HVB) &&
1302             !books_vhyp_handles_hv_excp(cpu)) {
1303         excp = POWERPC_EXCP_PROGRAM;
1304     }
1305 
1306     vector = env->excp_vectors[excp];
1307     if (vector == (target_ulong)-1ULL) {
1308         cpu_abort(env_cpu(env),
1309                   "Raised an exception without defined vector %d\n", excp);
1310     }
1311     vector |= env->excp_prefix;
1312 
1313     if (is_prefix_insn_excp(cpu, excp)) {
1314         msr |= PPC_BIT(34);
1315     }
1316 
1317     switch (excp) {
1318     case POWERPC_EXCP_MCHECK:    /* Machine check exception                  */
1319         powerpc_mcheck_checkstop(env);
1320         if (env->msr_mask & MSR_HVB) {
1321             /*
1322              * ISA specifies HV, but can be delivered to guest with HV
1323              * clear (e.g., see FWNMI in PAPR).
1324              */
1325             new_msr |= (target_ulong)MSR_HVB;
1326 
1327             /* HV machine check exceptions don't have ME set */
1328             new_msr &= ~((target_ulong)1 << MSR_ME);
1329         }
1330 
1331         msr |= env->error_code;
1332         break;
1333 
1334     case POWERPC_EXCP_DSI:       /* Data storage exception                   */
1335         trace_ppc_excp_dsi(env->spr[SPR_DSISR], env->spr[SPR_DAR]);
1336         break;
1337     case POWERPC_EXCP_ISI:       /* Instruction storage exception            */
1338         trace_ppc_excp_isi(msr, env->nip);
1339         msr |= env->error_code;
1340         break;
1341     case POWERPC_EXCP_EXTERNAL:  /* External input                           */
1342     {
1343         bool lpes0;
1344 
1345         /* LPES0 is only taken into consideration if we support HV mode */
1346         if (!env->has_hv_mode) {
1347             break;
1348         }
1349         lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0);
1350         if (!lpes0) {
1351             new_msr |= (target_ulong)MSR_HVB;
1352             new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
1353             srr0 = SPR_HSRR0;
1354             srr1 = SPR_HSRR1;
1355         }
1356         break;
1357     }
1358     case POWERPC_EXCP_ALIGN:     /* Alignment exception                      */
1359         /* Optional DSISR update was removed from ISA v3.0 */
1360         if (!(env->insns_flags2 & PPC2_ISA300)) {
1361             /* Get rS/rD and rA from faulting opcode */
1362             /*
1363              * Note: the opcode fields will not be set properly for a
1364              * direct store load/store, but nobody cares as nobody
1365              * actually uses direct store segments.
1366              */
1367             env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16;
1368         }
1369         break;
1370     case POWERPC_EXCP_PROGRAM:   /* Program exception                        */
1371         switch (env->error_code & ~0xF) {
1372         case POWERPC_EXCP_FP:
1373             if (!FIELD_EX64_FE(env->msr) || !FIELD_EX64(env->msr, MSR, FP)) {
1374                 trace_ppc_excp_fp_ignore();
1375                 powerpc_reset_excp_state(cpu);
1376                 return;
1377             }
1378             /*
1379              * NIP always points to the faulting instruction for FP exceptions,
1380              * so always use store_next and claim we are precise in the MSR.
1381              */
1382             msr |= 0x00100000;
1383             break;
1384         case POWERPC_EXCP_INVAL:
1385             trace_ppc_excp_inval(env->nip);
1386             msr |= 0x00080000;
1387             break;
1388         case POWERPC_EXCP_PRIV:
1389             msr |= 0x00040000;
1390             break;
1391         case POWERPC_EXCP_TRAP:
1392             msr |= 0x00020000;
1393             break;
1394         default:
1395             /* Should never occur */
1396             cpu_abort(env_cpu(env), "Invalid program exception %d. Aborting\n",
1397                       env->error_code);
1398             break;
1399         }
1400         break;
1401     case POWERPC_EXCP_SYSCALL:   /* System call exception                    */
1402         lev = env->error_code;
1403 
1404         if (lev == 1 && cpu->vhyp) {
1405             dump_hcall(env);
1406         } else {
1407             dump_syscall(env);
1408         }
1409 
1410         /*
1411          * We need to correct the NIP which in this case is supposed
1412          * to point to the next instruction
1413          */
1414         env->nip += 4;
1415 
1416         /* "PAPR mode" built-in hypercall emulation */
1417         if (lev == 1 && books_vhyp_handles_hcall(cpu)) {
1418             cpu->vhyp_class->hypercall(cpu->vhyp, cpu);
1419             powerpc_reset_excp_state(cpu);
1420             return;
1421         }
1422         if (env->insns_flags2 & PPC2_ISA310) {
1423             /* ISAv3.1 puts LEV into SRR1 */
1424             msr |= lev << 20;
1425         }
1426         if (lev == 1) {
1427             new_msr |= (target_ulong)MSR_HVB;
1428         }
1429         break;
1430     case POWERPC_EXCP_SYSCALL_VECTORED: /* scv exception                     */
1431         lev = env->error_code;
1432         dump_syscall(env);
1433         env->nip += 4;
1434         new_msr |= env->msr & ((target_ulong)1 << MSR_EE);
1435         new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
1436 
1437         vector += lev * 0x20;
1438 
1439         env->lr = env->nip;
1440         env->ctr = msr;
1441         break;
1442     case POWERPC_EXCP_FPU:       /* Floating-point unavailable exception     */
1443     case POWERPC_EXCP_DECR:      /* Decrementer exception                    */
1444         break;
1445     case POWERPC_EXCP_RESET:     /* System reset exception                   */
1446         /* A power-saving exception sets ME, otherwise it is unchanged */
1447         if (FIELD_EX64(env->msr, MSR, POW)) {
1448             /* indicate that we resumed from power save mode */
1449             msr |= 0x10000;
1450             new_msr |= ((target_ulong)1 << MSR_ME);
1451         }
1452         if (env->msr_mask & MSR_HVB) {
1453             /*
1454              * ISA specifies HV, but can be delivered to guest with HV
1455              * clear (e.g., see FWNMI in PAPR, NMI injection in QEMU).
1456              */
1457             new_msr |= (target_ulong)MSR_HVB;
1458         } else {
1459             if (FIELD_EX64(env->msr, MSR, POW)) {
1460                 cpu_abort(env_cpu(env),
1461                           "Trying to deliver power-saving system reset "
1462                           "exception %d with no HV support\n", excp);
1463             }
1464         }
1465         break;
1466     case POWERPC_EXCP_TRACE:     /* Trace exception                          */
1467         msr |= env->error_code;
1468         /* fall through */
1469     case POWERPC_EXCP_DSEG:      /* Data segment exception                   */
1470     case POWERPC_EXCP_ISEG:      /* Instruction segment exception            */
1471     case POWERPC_EXCP_SDOOR:     /* Doorbell interrupt                       */
1472     case POWERPC_EXCP_PERFM:     /* Performance monitor interrupt            */
1473         break;
1474     case POWERPC_EXCP_HISI:      /* Hypervisor instruction storage exception */
1475         msr |= env->error_code;
1476         /* fall through */
1477     case POWERPC_EXCP_HDECR:     /* Hypervisor decrementer exception         */
1478     case POWERPC_EXCP_HDSI:      /* Hypervisor data storage exception        */
1479     case POWERPC_EXCP_SDOOR_HV:  /* Hypervisor Doorbell interrupt            */
1480     case POWERPC_EXCP_HVIRT:     /* Hypervisor virtualization                */
1481         srr0 = SPR_HSRR0;
1482         srr1 = SPR_HSRR1;
1483         new_msr |= (target_ulong)MSR_HVB;
1484         new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
1485         break;
1486 #ifdef CONFIG_TCG
1487     case POWERPC_EXCP_HV_EMU: {
1488         uint32_t insn = ppc_ldl_code(env, env->nip);
1489         env->spr[SPR_HEIR] = insn;
1490         if (is_prefix_insn(env, insn)) {
1491             uint32_t insn2 = ppc_ldl_code(env, env->nip + 4);
1492             env->spr[SPR_HEIR] <<= 32;
1493             env->spr[SPR_HEIR] |= insn2;
1494         }
1495         srr0 = SPR_HSRR0;
1496         srr1 = SPR_HSRR1;
1497         new_msr |= (target_ulong)MSR_HVB;
1498         new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
1499         break;
1500     }
1501 #endif
1502     case POWERPC_EXCP_VPU:       /* Vector unavailable exception             */
1503     case POWERPC_EXCP_VSXU:       /* VSX unavailable exception               */
1504     case POWERPC_EXCP_FU:         /* Facility unavailable exception          */
1505         env->spr[SPR_FSCR] |= ((target_ulong)env->error_code << 56);
1506         break;
1507     case POWERPC_EXCP_HV_FU:     /* Hypervisor Facility Unavailable Exception */
1508         env->spr[SPR_HFSCR] |= ((target_ulong)env->error_code << FSCR_IC_POS);
1509         srr0 = SPR_HSRR0;
1510         srr1 = SPR_HSRR1;
1511         new_msr |= (target_ulong)MSR_HVB;
1512         new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
1513         break;
1514     case POWERPC_EXCP_PERFM_EBB:        /* Performance Monitor EBB Exception  */
1515     case POWERPC_EXCP_EXTERNAL_EBB:     /* External EBB Exception             */
1516         env->spr[SPR_BESCR] &= ~BESCR_GE;
1517 
1518         /*
1519          * Save NIP for rfebb insn in SPR_EBBRR. Next nip is
1520          * stored in the EBB Handler SPR_EBBHR.
1521          */
1522         env->spr[SPR_EBBRR] = env->nip;
1523         powerpc_set_excp_state(cpu, env->spr[SPR_EBBHR], env->msr);
1524 
1525         /*
1526          * This exception is handled in userspace. No need to proceed.
1527          */
1528         return;
1529     case POWERPC_EXCP_THERM:     /* Thermal interrupt                        */
1530     case POWERPC_EXCP_VPUA:      /* Vector assist exception                  */
1531     case POWERPC_EXCP_MAINT:     /* Maintenance exception                    */
1532     case POWERPC_EXCP_HV_MAINT:  /* Hypervisor Maintenance exception         */
1533         cpu_abort(env_cpu(env), "%s exception not implemented\n",
1534                   powerpc_excp_name(excp));
1535         break;
1536     default:
1537         cpu_abort(env_cpu(env), "Invalid PowerPC exception %d. Aborting\n",
1538                   excp);
1539         break;
1540     }
1541 
1542     if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) {
1543         new_msr |= (target_ulong)1 << MSR_LE;
1544     }
1545     new_msr |= (target_ulong)1 << MSR_SF;
1546 
1547     if (excp != POWERPC_EXCP_SYSCALL_VECTORED) {
1548         env->spr[srr0] = env->nip;
1549         env->spr[srr1] = msr;
1550     }
1551 
1552     if ((new_msr & MSR_HVB) && books_vhyp_handles_hv_excp(cpu)) {
1553         /* Deliver interrupt to L1 by returning from the H_ENTER_NESTED call */
1554         cpu->vhyp_class->deliver_hv_excp(cpu, excp);
1555         powerpc_reset_excp_state(cpu);
1556     } else {
1557         /* Sanity check */
1558         if (!(env->msr_mask & MSR_HVB) && srr0 == SPR_HSRR0) {
1559             cpu_abort(env_cpu(env), "Trying to deliver HV exception (HSRR) %d "
1560                       "with no HV support\n", excp);
1561         }
1562         /* This can update new_msr and vector if AIL applies */
1563         ppc_excp_apply_ail(cpu, excp, msr, &new_msr, &vector);
1564         powerpc_set_excp_state(cpu, vector, new_msr);
1565     }
1566 }
1567 #else
1568 static inline void powerpc_excp_books(PowerPCCPU *cpu, int excp)
1569 {
1570     g_assert_not_reached();
1571 }
1572 #endif /* TARGET_PPC64 */
1573 
1574 static void powerpc_excp(PowerPCCPU *cpu, int excp)
1575 {
1576     CPUPPCState *env = &cpu->env;
1577 
1578     if (excp <= POWERPC_EXCP_NONE || excp >= POWERPC_EXCP_NB) {
1579         cpu_abort(env_cpu(env), "Invalid PowerPC exception %d. Aborting\n",
1580                   excp);
1581     }
1582 
1583     qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx
1584                   " => %s (%d) error=%02x\n", env->nip, powerpc_excp_name(excp),
1585                   excp, env->error_code);
1586     env->excp_stats[excp]++;
1587 
1588     switch (env->excp_model) {
1589     case POWERPC_EXCP_40x:
1590         powerpc_excp_40x(cpu, excp);
1591         break;
1592     case POWERPC_EXCP_6xx:
1593         powerpc_excp_6xx(cpu, excp);
1594         break;
1595     case POWERPC_EXCP_7xx:
1596         powerpc_excp_7xx(cpu, excp);
1597         break;
1598     case POWERPC_EXCP_74xx:
1599         powerpc_excp_74xx(cpu, excp);
1600         break;
1601     case POWERPC_EXCP_BOOKE:
1602         powerpc_excp_booke(cpu, excp);
1603         break;
1604     case POWERPC_EXCP_970:
1605     case POWERPC_EXCP_POWER7:
1606     case POWERPC_EXCP_POWER8:
1607     case POWERPC_EXCP_POWER9:
1608     case POWERPC_EXCP_POWER10:
1609     case POWERPC_EXCP_POWER11:
1610         powerpc_excp_books(cpu, excp);
1611         break;
1612     default:
1613         g_assert_not_reached();
1614     }
1615 }
1616 
1617 void ppc_cpu_do_interrupt(CPUState *cs)
1618 {
1619     PowerPCCPU *cpu = POWERPC_CPU(cs);
1620 
1621     powerpc_excp(cpu, cs->exception_index);
1622 }
1623 
1624 #ifdef TARGET_PPC64
1625 #define P7_UNUSED_INTERRUPTS \
1626     (PPC_INTERRUPT_RESET | PPC_INTERRUPT_HVIRT | PPC_INTERRUPT_CEXT |       \
1627      PPC_INTERRUPT_WDT | PPC_INTERRUPT_CDOORBELL | PPC_INTERRUPT_FIT |      \
1628      PPC_INTERRUPT_PIT | PPC_INTERRUPT_DOORBELL | PPC_INTERRUPT_HDOORBELL | \
1629      PPC_INTERRUPT_THERM | PPC_INTERRUPT_EBB)
1630 
1631 static int p7_interrupt_powersave(uint32_t pending_interrupts,
1632                                   target_ulong lpcr)
1633 {
1634     if ((pending_interrupts & PPC_INTERRUPT_EXT) &&
1635         (lpcr & LPCR_P7_PECE0)) {
1636         return PPC_INTERRUPT_EXT;
1637     }
1638     if ((pending_interrupts & PPC_INTERRUPT_DECR) &&
1639         (lpcr & LPCR_P7_PECE1)) {
1640         return PPC_INTERRUPT_DECR;
1641     }
1642     if ((pending_interrupts & PPC_INTERRUPT_MCK) &&
1643         (lpcr & LPCR_P7_PECE2)) {
1644         return PPC_INTERRUPT_MCK;
1645     }
1646     if ((pending_interrupts & PPC_INTERRUPT_HMI) &&
1647         (lpcr & LPCR_P7_PECE2)) {
1648         return PPC_INTERRUPT_HMI;
1649     }
1650     if (pending_interrupts & PPC_INTERRUPT_RESET) {
1651         return PPC_INTERRUPT_RESET;
1652     }
1653     return 0;
1654 }
1655 
1656 static int p7_next_unmasked_interrupt(CPUPPCState *env,
1657                                       uint32_t pending_interrupts,
1658                                       target_ulong lpcr)
1659 {
1660     CPUState *cs = env_cpu(env);
1661 
1662     /* Ignore MSR[EE] when coming out of some power management states */
1663     bool msr_ee = FIELD_EX64(env->msr, MSR, EE) || env->resume_as_sreset;
1664 
1665     assert((pending_interrupts & P7_UNUSED_INTERRUPTS) == 0);
1666 
1667     if (cs->halted) {
1668         /* LPCR[PECE] controls which interrupts can exit power-saving mode */
1669         return p7_interrupt_powersave(pending_interrupts, lpcr);
1670     }
1671 
1672     /* Machine check exception */
1673     if (pending_interrupts & PPC_INTERRUPT_MCK) {
1674         return PPC_INTERRUPT_MCK;
1675     }
1676 
1677     /* Hypervisor decrementer exception */
1678     if (pending_interrupts & PPC_INTERRUPT_HDECR) {
1679         /* LPCR will be clear when not supported so this will work */
1680         bool hdice = !!(env->spr[SPR_LPCR] & LPCR_HDICE);
1681         if ((msr_ee || !FIELD_EX64_HV(env->msr)) && hdice) {
1682             /* HDEC clears on delivery */
1683             return PPC_INTERRUPT_HDECR;
1684         }
1685     }
1686 
1687     /* External interrupt can ignore MSR:EE under some circumstances */
1688     if (pending_interrupts & PPC_INTERRUPT_EXT) {
1689         bool lpes0 = !!(lpcr & LPCR_LPES0);
1690         bool heic = !!(lpcr & LPCR_HEIC);
1691         /* HEIC blocks delivery to the hypervisor */
1692         if ((msr_ee && !(heic && FIELD_EX64_HV(env->msr) &&
1693             !FIELD_EX64(env->msr, MSR, PR))) ||
1694             (env->has_hv_mode && !FIELD_EX64_HV(env->msr) && !lpes0)) {
1695             return PPC_INTERRUPT_EXT;
1696         }
1697     }
1698     if (msr_ee != 0) {
1699         /* Decrementer exception */
1700         if (pending_interrupts & PPC_INTERRUPT_DECR) {
1701             return PPC_INTERRUPT_DECR;
1702         }
1703         if (pending_interrupts & PPC_INTERRUPT_PERFM) {
1704             return PPC_INTERRUPT_PERFM;
1705         }
1706     }
1707 
1708     return 0;
1709 }
1710 
1711 #define P8_UNUSED_INTERRUPTS \
1712     (PPC_INTERRUPT_RESET | PPC_INTERRUPT_DEBUG | PPC_INTERRUPT_HVIRT |  \
1713     PPC_INTERRUPT_CEXT | PPC_INTERRUPT_WDT | PPC_INTERRUPT_CDOORBELL |  \
1714     PPC_INTERRUPT_FIT | PPC_INTERRUPT_PIT | PPC_INTERRUPT_THERM)
1715 
1716 static int p8_interrupt_powersave(uint32_t pending_interrupts,
1717                                   target_ulong lpcr)
1718 {
1719     if ((pending_interrupts & PPC_INTERRUPT_EXT) &&
1720         (lpcr & LPCR_P8_PECE2)) {
1721         return PPC_INTERRUPT_EXT;
1722     }
1723     if ((pending_interrupts & PPC_INTERRUPT_DECR) &&
1724         (lpcr & LPCR_P8_PECE3)) {
1725         return PPC_INTERRUPT_DECR;
1726     }
1727     if ((pending_interrupts & PPC_INTERRUPT_MCK) &&
1728         (lpcr & LPCR_P8_PECE4)) {
1729         return PPC_INTERRUPT_MCK;
1730     }
1731     if ((pending_interrupts & PPC_INTERRUPT_HMI) &&
1732         (lpcr & LPCR_P8_PECE4)) {
1733         return PPC_INTERRUPT_HMI;
1734     }
1735     if ((pending_interrupts & PPC_INTERRUPT_DOORBELL) &&
1736         (lpcr & LPCR_P8_PECE0)) {
1737         return PPC_INTERRUPT_DOORBELL;
1738     }
1739     if ((pending_interrupts & PPC_INTERRUPT_HDOORBELL) &&
1740         (lpcr & LPCR_P8_PECE1)) {
1741         return PPC_INTERRUPT_HDOORBELL;
1742     }
1743     if (pending_interrupts & PPC_INTERRUPT_RESET) {
1744         return PPC_INTERRUPT_RESET;
1745     }
1746     return 0;
1747 }
1748 
1749 static int p8_next_unmasked_interrupt(CPUPPCState *env,
1750                                       uint32_t pending_interrupts,
1751                                       target_ulong lpcr)
1752 {
1753     CPUState *cs = env_cpu(env);
1754 
1755     /* Ignore MSR[EE] when coming out of some power management states */
1756     bool msr_ee = FIELD_EX64(env->msr, MSR, EE) || env->resume_as_sreset;
1757 
1758     assert((env->pending_interrupts & P8_UNUSED_INTERRUPTS) == 0);
1759 
1760     if (cs->halted) {
1761         /* LPCR[PECE] controls which interrupts can exit power-saving mode */
1762         return p8_interrupt_powersave(pending_interrupts, lpcr);
1763     }
1764 
1765     /* Machine check exception */
1766     if (pending_interrupts & PPC_INTERRUPT_MCK) {
1767         return PPC_INTERRUPT_MCK;
1768     }
1769 
1770     /* Hypervisor decrementer exception */
1771     if (pending_interrupts & PPC_INTERRUPT_HDECR) {
1772         /* LPCR will be clear when not supported so this will work */
1773         bool hdice = !!(lpcr & LPCR_HDICE);
1774         if ((msr_ee || !FIELD_EX64_HV(env->msr)) && hdice) {
1775             /* HDEC clears on delivery */
1776             return PPC_INTERRUPT_HDECR;
1777         }
1778     }
1779 
1780     /* External interrupt can ignore MSR:EE under some circumstances */
1781     if (pending_interrupts & PPC_INTERRUPT_EXT) {
1782         bool lpes0 = !!(lpcr & LPCR_LPES0);
1783         bool heic = !!(lpcr & LPCR_HEIC);
1784         /* HEIC blocks delivery to the hypervisor */
1785         if ((msr_ee && !(heic && FIELD_EX64_HV(env->msr) &&
1786             !FIELD_EX64(env->msr, MSR, PR))) ||
1787             (env->has_hv_mode && !FIELD_EX64_HV(env->msr) && !lpes0)) {
1788             return PPC_INTERRUPT_EXT;
1789         }
1790     }
1791     if (msr_ee != 0) {
1792         /* Decrementer exception */
1793         if (pending_interrupts & PPC_INTERRUPT_DECR) {
1794             return PPC_INTERRUPT_DECR;
1795         }
1796         if (pending_interrupts & PPC_INTERRUPT_DOORBELL) {
1797             return PPC_INTERRUPT_DOORBELL;
1798         }
1799         if (pending_interrupts & PPC_INTERRUPT_HDOORBELL) {
1800             return PPC_INTERRUPT_HDOORBELL;
1801         }
1802         if (pending_interrupts & PPC_INTERRUPT_PERFM) {
1803             return PPC_INTERRUPT_PERFM;
1804         }
1805         /* EBB exception */
1806         if (pending_interrupts & PPC_INTERRUPT_EBB) {
1807             /*
1808              * EBB exception must be taken in problem state and
1809              * with BESCR_GE set.
1810              */
1811             if (FIELD_EX64(env->msr, MSR, PR) &&
1812                 (env->spr[SPR_BESCR] & BESCR_GE)) {
1813                 return PPC_INTERRUPT_EBB;
1814             }
1815         }
1816     }
1817 
1818     return 0;
1819 }
1820 
1821 #define P9_UNUSED_INTERRUPTS \
1822     (PPC_INTERRUPT_RESET | PPC_INTERRUPT_DEBUG | PPC_INTERRUPT_CEXT |   \
1823      PPC_INTERRUPT_WDT | PPC_INTERRUPT_CDOORBELL | PPC_INTERRUPT_FIT |  \
1824      PPC_INTERRUPT_PIT | PPC_INTERRUPT_THERM)
1825 
1826 static int p9_interrupt_powersave(CPUPPCState *env,
1827                                   uint32_t pending_interrupts,
1828                                   target_ulong lpcr)
1829 {
1830 
1831     /* External Exception */
1832     if ((pending_interrupts & PPC_INTERRUPT_EXT) &&
1833         (lpcr & LPCR_EEE)) {
1834         bool heic = !!(lpcr & LPCR_HEIC);
1835         if (!heic || !FIELD_EX64_HV(env->msr) ||
1836             FIELD_EX64(env->msr, MSR, PR)) {
1837             return PPC_INTERRUPT_EXT;
1838         }
1839     }
1840     /* Decrementer Exception */
1841     if ((pending_interrupts & PPC_INTERRUPT_DECR) &&
1842         (lpcr & LPCR_DEE)) {
1843         return PPC_INTERRUPT_DECR;
1844     }
1845     /* Machine Check or Hypervisor Maintenance Exception */
1846     if (lpcr & LPCR_OEE) {
1847         if (pending_interrupts & PPC_INTERRUPT_MCK) {
1848             return PPC_INTERRUPT_MCK;
1849         }
1850         if (pending_interrupts & PPC_INTERRUPT_HMI) {
1851             return PPC_INTERRUPT_HMI;
1852         }
1853     }
1854     /* Privileged Doorbell Exception */
1855     if ((pending_interrupts & PPC_INTERRUPT_DOORBELL) &&
1856         (lpcr & LPCR_PDEE)) {
1857         return PPC_INTERRUPT_DOORBELL;
1858     }
1859     /* Hypervisor Doorbell Exception */
1860     if ((pending_interrupts & PPC_INTERRUPT_HDOORBELL) &&
1861         (lpcr & LPCR_HDEE)) {
1862         return PPC_INTERRUPT_HDOORBELL;
1863     }
1864     /* Hypervisor virtualization exception */
1865     if ((pending_interrupts & PPC_INTERRUPT_HVIRT) &&
1866         (lpcr & LPCR_HVEE)) {
1867         return PPC_INTERRUPT_HVIRT;
1868     }
1869     if (pending_interrupts & PPC_INTERRUPT_RESET) {
1870         return PPC_INTERRUPT_RESET;
1871     }
1872     return 0;
1873 }
1874 
1875 static int p9_next_unmasked_interrupt(CPUPPCState *env,
1876                                       uint32_t pending_interrupts,
1877                                       target_ulong lpcr)
1878 {
1879     CPUState *cs = env_cpu(env);
1880 
1881     /* Ignore MSR[EE] when coming out of some power management states */
1882     bool msr_ee = FIELD_EX64(env->msr, MSR, EE) || env->resume_as_sreset;
1883 
1884     assert((pending_interrupts & P9_UNUSED_INTERRUPTS) == 0);
1885 
1886     if (cs->halted) {
1887         if (env->spr[SPR_PSSCR] & PSSCR_EC) {
1888             /*
1889              * When PSSCR[EC] is set, LPCR[PECE] controls which interrupts can
1890              * wakeup the processor
1891              */
1892             return p9_interrupt_powersave(env, pending_interrupts, lpcr);
1893         } else {
1894             /*
1895              * When it's clear, any system-caused exception exits power-saving
1896              * mode, even the ones that gate on MSR[EE].
1897              */
1898             msr_ee = true;
1899         }
1900     }
1901 
1902     /* Machine check exception */
1903     if (pending_interrupts & PPC_INTERRUPT_MCK) {
1904         return PPC_INTERRUPT_MCK;
1905     }
1906 
1907     /* Hypervisor decrementer exception */
1908     if (pending_interrupts & PPC_INTERRUPT_HDECR) {
1909         /* LPCR will be clear when not supported so this will work */
1910         bool hdice = !!(lpcr & LPCR_HDICE);
1911         if ((msr_ee || !FIELD_EX64_HV(env->msr)) && hdice) {
1912             /* HDEC clears on delivery */
1913             return PPC_INTERRUPT_HDECR;
1914         }
1915     }
1916 
1917     /* Hypervisor virtualization interrupt */
1918     if (pending_interrupts & PPC_INTERRUPT_HVIRT) {
1919         /* LPCR will be clear when not supported so this will work */
1920         bool hvice = !!(lpcr & LPCR_HVICE);
1921         if ((msr_ee || !FIELD_EX64_HV(env->msr)) && hvice) {
1922             return PPC_INTERRUPT_HVIRT;
1923         }
1924     }
1925 
1926     /* External interrupt can ignore MSR:EE under some circumstances */
1927     if (pending_interrupts & PPC_INTERRUPT_EXT) {
1928         bool lpes0 = !!(lpcr & LPCR_LPES0);
1929         bool heic = !!(lpcr & LPCR_HEIC);
1930         /* HEIC blocks delivery to the hypervisor */
1931         if ((msr_ee && !(heic && FIELD_EX64_HV(env->msr) &&
1932             !FIELD_EX64(env->msr, MSR, PR))) ||
1933             (env->has_hv_mode && !FIELD_EX64_HV(env->msr) && !lpes0)) {
1934             return PPC_INTERRUPT_EXT;
1935         }
1936     }
1937     if (msr_ee != 0) {
1938         /* Decrementer exception */
1939         if (pending_interrupts & PPC_INTERRUPT_DECR) {
1940             return PPC_INTERRUPT_DECR;
1941         }
1942         if (pending_interrupts & PPC_INTERRUPT_DOORBELL) {
1943             return PPC_INTERRUPT_DOORBELL;
1944         }
1945         if (pending_interrupts & PPC_INTERRUPT_HDOORBELL) {
1946             return PPC_INTERRUPT_HDOORBELL;
1947         }
1948         if (pending_interrupts & PPC_INTERRUPT_PERFM) {
1949             return PPC_INTERRUPT_PERFM;
1950         }
1951         /* EBB exception */
1952         if (pending_interrupts & PPC_INTERRUPT_EBB) {
1953             /*
1954              * EBB exception must be taken in problem state and
1955              * with BESCR_GE set.
1956              */
1957             if (FIELD_EX64(env->msr, MSR, PR) &&
1958                 (env->spr[SPR_BESCR] & BESCR_GE)) {
1959                 return PPC_INTERRUPT_EBB;
1960             }
1961         }
1962     }
1963 
1964     return 0;
1965 }
1966 #endif /* TARGET_PPC64 */
1967 
1968 static int ppc_next_unmasked_interrupt(CPUPPCState *env)
1969 {
1970     uint32_t pending_interrupts = env->pending_interrupts;
1971     target_ulong lpcr = env->spr[SPR_LPCR];
1972     bool async_deliver;
1973 
1974 #ifdef TARGET_PPC64
1975     switch (env->excp_model) {
1976     case POWERPC_EXCP_POWER7:
1977         return p7_next_unmasked_interrupt(env, pending_interrupts, lpcr);
1978     case POWERPC_EXCP_POWER8:
1979         return p8_next_unmasked_interrupt(env, pending_interrupts, lpcr);
1980     case POWERPC_EXCP_POWER9:
1981     case POWERPC_EXCP_POWER10:
1982     case POWERPC_EXCP_POWER11:
1983         return p9_next_unmasked_interrupt(env, pending_interrupts, lpcr);
1984     default:
1985         break;
1986     }
1987 #endif
1988 
1989     /* External reset */
1990     if (pending_interrupts & PPC_INTERRUPT_RESET) {
1991         return PPC_INTERRUPT_RESET;
1992     }
1993     /* Machine check exception */
1994     if (pending_interrupts & PPC_INTERRUPT_MCK) {
1995         return PPC_INTERRUPT_MCK;
1996     }
1997 #if 0 /* TODO */
1998     /* External debug exception */
1999     if (env->pending_interrupts & PPC_INTERRUPT_DEBUG) {
2000         return PPC_INTERRUPT_DEBUG;
2001     }
2002 #endif
2003 
2004     /*
2005      * For interrupts that gate on MSR:EE, we need to do something a
2006      * bit more subtle, as we need to let them through even when EE is
2007      * clear when coming out of some power management states (in order
2008      * for them to become a 0x100).
2009      */
2010     async_deliver = FIELD_EX64(env->msr, MSR, EE) || env->resume_as_sreset;
2011 
2012     /* Hypervisor decrementer exception */
2013     if (pending_interrupts & PPC_INTERRUPT_HDECR) {
2014         /* LPCR will be clear when not supported so this will work */
2015         bool hdice = !!(lpcr & LPCR_HDICE);
2016         if ((async_deliver || !FIELD_EX64_HV(env->msr)) && hdice) {
2017             /* HDEC clears on delivery */
2018             return PPC_INTERRUPT_HDECR;
2019         }
2020     }
2021 
2022     /* Hypervisor virtualization interrupt */
2023     if (pending_interrupts & PPC_INTERRUPT_HVIRT) {
2024         /* LPCR will be clear when not supported so this will work */
2025         bool hvice = !!(lpcr & LPCR_HVICE);
2026         if ((async_deliver || !FIELD_EX64_HV(env->msr)) && hvice) {
2027             return PPC_INTERRUPT_HVIRT;
2028         }
2029     }
2030 
2031     /* External interrupt can ignore MSR:EE under some circumstances */
2032     if (pending_interrupts & PPC_INTERRUPT_EXT) {
2033         bool lpes0 = !!(lpcr & LPCR_LPES0);
2034         bool heic = !!(lpcr & LPCR_HEIC);
2035         /* HEIC blocks delivery to the hypervisor */
2036         if ((async_deliver && !(heic && FIELD_EX64_HV(env->msr) &&
2037             !FIELD_EX64(env->msr, MSR, PR))) ||
2038             (env->has_hv_mode && !FIELD_EX64_HV(env->msr) && !lpes0)) {
2039             return PPC_INTERRUPT_EXT;
2040         }
2041     }
2042     if (FIELD_EX64(env->msr, MSR, CE)) {
2043         /* External critical interrupt */
2044         if (pending_interrupts & PPC_INTERRUPT_CEXT) {
2045             return PPC_INTERRUPT_CEXT;
2046         }
2047     }
2048     if (async_deliver != 0) {
2049         /* Watchdog timer on embedded PowerPC */
2050         if (pending_interrupts & PPC_INTERRUPT_WDT) {
2051             return PPC_INTERRUPT_WDT;
2052         }
2053         if (pending_interrupts & PPC_INTERRUPT_CDOORBELL) {
2054             return PPC_INTERRUPT_CDOORBELL;
2055         }
2056         /* Fixed interval timer on embedded PowerPC */
2057         if (pending_interrupts & PPC_INTERRUPT_FIT) {
2058             return PPC_INTERRUPT_FIT;
2059         }
2060         /* Programmable interval timer on embedded PowerPC */
2061         if (pending_interrupts & PPC_INTERRUPT_PIT) {
2062             return PPC_INTERRUPT_PIT;
2063         }
2064         /* Decrementer exception */
2065         if (pending_interrupts & PPC_INTERRUPT_DECR) {
2066             return PPC_INTERRUPT_DECR;
2067         }
2068         if (pending_interrupts & PPC_INTERRUPT_DOORBELL) {
2069             return PPC_INTERRUPT_DOORBELL;
2070         }
2071         if (pending_interrupts & PPC_INTERRUPT_HDOORBELL) {
2072             return PPC_INTERRUPT_HDOORBELL;
2073         }
2074         if (pending_interrupts & PPC_INTERRUPT_PERFM) {
2075             return PPC_INTERRUPT_PERFM;
2076         }
2077         /* Thermal interrupt */
2078         if (pending_interrupts & PPC_INTERRUPT_THERM) {
2079             return PPC_INTERRUPT_THERM;
2080         }
2081         /* EBB exception */
2082         if (pending_interrupts & PPC_INTERRUPT_EBB) {
2083             /*
2084              * EBB exception must be taken in problem state and
2085              * with BESCR_GE set.
2086              */
2087             if (FIELD_EX64(env->msr, MSR, PR) &&
2088                 (env->spr[SPR_BESCR] & BESCR_GE)) {
2089                 return PPC_INTERRUPT_EBB;
2090             }
2091         }
2092     }
2093 
2094     return 0;
2095 }
2096 
2097 /*
2098  * Sets CPU_INTERRUPT_HARD if there is at least one unmasked interrupt to be
2099  * delivered and clears CPU_INTERRUPT_HARD otherwise.
2100  *
2101  * This method is called by ppc_set_interrupt when an interrupt is raised or
2102  * lowered, and should also be called whenever an interrupt masking condition
2103  * is changed, e.g.:
2104  *  - When relevant bits of MSR are altered, like EE, HV, PR, etc.;
2105  *  - When relevant bits of LPCR are altered, like PECE, HDICE, HVICE, etc.;
2106  *  - When PSSCR[EC] or env->resume_as_sreset are changed;
2107  *  - When cs->halted is changed and the CPU has a different interrupt masking
2108  *    logic in power-saving mode (e.g., POWER7/8/9/10);
2109  */
2110 void ppc_maybe_interrupt(CPUPPCState *env)
2111 {
2112     CPUState *cs = env_cpu(env);
2113     BQL_LOCK_GUARD();
2114 
2115     if (ppc_next_unmasked_interrupt(env)) {
2116         cpu_interrupt(cs, CPU_INTERRUPT_HARD);
2117     } else {
2118         cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
2119     }
2120 }
2121 
2122 #ifdef TARGET_PPC64
2123 static void p7_deliver_interrupt(CPUPPCState *env, int interrupt)
2124 {
2125     PowerPCCPU *cpu = env_archcpu(env);
2126 
2127     switch (interrupt) {
2128     case PPC_INTERRUPT_MCK: /* Machine check exception */
2129         env->pending_interrupts &= ~PPC_INTERRUPT_MCK;
2130         powerpc_excp(cpu, POWERPC_EXCP_MCHECK);
2131         break;
2132 
2133     case PPC_INTERRUPT_HDECR: /* Hypervisor decrementer exception */
2134         /* HDEC clears on delivery */
2135         env->pending_interrupts &= ~PPC_INTERRUPT_HDECR;
2136         powerpc_excp(cpu, POWERPC_EXCP_HDECR);
2137         break;
2138 
2139     case PPC_INTERRUPT_EXT:
2140         if (books_vhyp_promotes_external_to_hvirt(cpu)) {
2141             powerpc_excp(cpu, POWERPC_EXCP_HVIRT);
2142         } else {
2143             powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL);
2144         }
2145         break;
2146 
2147     case PPC_INTERRUPT_DECR: /* Decrementer exception */
2148         powerpc_excp(cpu, POWERPC_EXCP_DECR);
2149         break;
2150     case PPC_INTERRUPT_PERFM:
2151         powerpc_excp(cpu, POWERPC_EXCP_PERFM);
2152         break;
2153     case 0:
2154         /*
2155          * This is a bug ! It means that has_work took us out of halt without
2156          * anything to deliver while in a PM state that requires getting
2157          * out via a 0x100
2158          *
2159          * This means we will incorrectly execute past the power management
2160          * instruction instead of triggering a reset.
2161          *
2162          * It generally means a discrepancy between the wakeup conditions in the
2163          * processor has_work implementation and the logic in this function.
2164          */
2165         assert(!env->resume_as_sreset);
2166         break;
2167     default:
2168         cpu_abort(env_cpu(env), "Invalid PowerPC interrupt %d. Aborting\n",
2169                   interrupt);
2170     }
2171 }
2172 
2173 static void p8_deliver_interrupt(CPUPPCState *env, int interrupt)
2174 {
2175     PowerPCCPU *cpu = env_archcpu(env);
2176 
2177     switch (interrupt) {
2178     case PPC_INTERRUPT_MCK: /* Machine check exception */
2179         env->pending_interrupts &= ~PPC_INTERRUPT_MCK;
2180         powerpc_excp(cpu, POWERPC_EXCP_MCHECK);
2181         break;
2182 
2183     case PPC_INTERRUPT_HDECR: /* Hypervisor decrementer exception */
2184         /* HDEC clears on delivery */
2185         env->pending_interrupts &= ~PPC_INTERRUPT_HDECR;
2186         powerpc_excp(cpu, POWERPC_EXCP_HDECR);
2187         break;
2188 
2189     case PPC_INTERRUPT_EXT:
2190         if (books_vhyp_promotes_external_to_hvirt(cpu)) {
2191             powerpc_excp(cpu, POWERPC_EXCP_HVIRT);
2192         } else {
2193             powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL);
2194         }
2195         break;
2196 
2197     case PPC_INTERRUPT_DECR: /* Decrementer exception */
2198         powerpc_excp(cpu, POWERPC_EXCP_DECR);
2199         break;
2200     case PPC_INTERRUPT_DOORBELL:
2201         if (!env->resume_as_sreset) {
2202             env->pending_interrupts &= ~PPC_INTERRUPT_DOORBELL;
2203         }
2204         if (is_book3s_arch2x(env)) {
2205             powerpc_excp(cpu, POWERPC_EXCP_SDOOR);
2206         } else {
2207             powerpc_excp(cpu, POWERPC_EXCP_DOORI);
2208         }
2209         break;
2210     case PPC_INTERRUPT_HDOORBELL:
2211         if (!env->resume_as_sreset) {
2212             env->pending_interrupts &= ~PPC_INTERRUPT_HDOORBELL;
2213         }
2214         powerpc_excp(cpu, POWERPC_EXCP_SDOOR_HV);
2215         break;
2216     case PPC_INTERRUPT_PERFM:
2217         powerpc_excp(cpu, POWERPC_EXCP_PERFM);
2218         break;
2219     case PPC_INTERRUPT_EBB: /* EBB exception */
2220         env->pending_interrupts &= ~PPC_INTERRUPT_EBB;
2221         if (env->spr[SPR_BESCR] & BESCR_PMEO) {
2222             powerpc_excp(cpu, POWERPC_EXCP_PERFM_EBB);
2223         } else if (env->spr[SPR_BESCR] & BESCR_EEO) {
2224             powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL_EBB);
2225         }
2226         break;
2227     case 0:
2228         /*
2229          * This is a bug ! It means that has_work took us out of halt without
2230          * anything to deliver while in a PM state that requires getting
2231          * out via a 0x100
2232          *
2233          * This means we will incorrectly execute past the power management
2234          * instruction instead of triggering a reset.
2235          *
2236          * It generally means a discrepancy between the wakeup conditions in the
2237          * processor has_work implementation and the logic in this function.
2238          */
2239         assert(!env->resume_as_sreset);
2240         break;
2241     default:
2242         cpu_abort(env_cpu(env), "Invalid PowerPC interrupt %d. Aborting\n",
2243                   interrupt);
2244     }
2245 }
2246 
2247 static void p9_deliver_interrupt(CPUPPCState *env, int interrupt)
2248 {
2249     PowerPCCPU *cpu = env_archcpu(env);
2250     CPUState *cs = env_cpu(env);
2251 
2252     if (cs->halted && !(env->spr[SPR_PSSCR] & PSSCR_EC) &&
2253         !FIELD_EX64(env->msr, MSR, EE)) {
2254         /*
2255          * A pending interrupt took us out of power-saving, but MSR[EE] says
2256          * that we should return to NIP+4 instead of delivering it.
2257          */
2258         return;
2259     }
2260 
2261     switch (interrupt) {
2262     case PPC_INTERRUPT_MCK: /* Machine check exception */
2263         env->pending_interrupts &= ~PPC_INTERRUPT_MCK;
2264         powerpc_excp(cpu, POWERPC_EXCP_MCHECK);
2265         break;
2266 
2267     case PPC_INTERRUPT_HDECR: /* Hypervisor decrementer exception */
2268         /* HDEC clears on delivery */
2269         /* XXX: should not see an HDEC if resume_as_sreset. assert? */
2270         env->pending_interrupts &= ~PPC_INTERRUPT_HDECR;
2271         powerpc_excp(cpu, POWERPC_EXCP_HDECR);
2272         break;
2273     case PPC_INTERRUPT_HVIRT: /* Hypervisor virtualization interrupt */
2274         powerpc_excp(cpu, POWERPC_EXCP_HVIRT);
2275         break;
2276 
2277     case PPC_INTERRUPT_EXT:
2278         if (books_vhyp_promotes_external_to_hvirt(cpu)) {
2279             powerpc_excp(cpu, POWERPC_EXCP_HVIRT);
2280         } else {
2281             powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL);
2282         }
2283         break;
2284 
2285     case PPC_INTERRUPT_DECR: /* Decrementer exception */
2286         powerpc_excp(cpu, POWERPC_EXCP_DECR);
2287         break;
2288     case PPC_INTERRUPT_DOORBELL:
2289         if (!env->resume_as_sreset) {
2290             env->pending_interrupts &= ~PPC_INTERRUPT_DOORBELL;
2291         }
2292         powerpc_excp(cpu, POWERPC_EXCP_SDOOR);
2293         break;
2294     case PPC_INTERRUPT_HDOORBELL:
2295         if (!env->resume_as_sreset) {
2296             env->pending_interrupts &= ~PPC_INTERRUPT_HDOORBELL;
2297         }
2298         powerpc_excp(cpu, POWERPC_EXCP_SDOOR_HV);
2299         break;
2300     case PPC_INTERRUPT_PERFM:
2301         powerpc_excp(cpu, POWERPC_EXCP_PERFM);
2302         break;
2303     case PPC_INTERRUPT_EBB: /* EBB exception */
2304         env->pending_interrupts &= ~PPC_INTERRUPT_EBB;
2305         if (env->spr[SPR_BESCR] & BESCR_PMEO) {
2306             powerpc_excp(cpu, POWERPC_EXCP_PERFM_EBB);
2307         } else if (env->spr[SPR_BESCR] & BESCR_EEO) {
2308             powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL_EBB);
2309         }
2310         break;
2311     case 0:
2312         /*
2313          * This is a bug ! It means that has_work took us out of halt without
2314          * anything to deliver while in a PM state that requires getting
2315          * out via a 0x100
2316          *
2317          * This means we will incorrectly execute past the power management
2318          * instruction instead of triggering a reset.
2319          *
2320          * It generally means a discrepancy between the wakeup conditions in the
2321          * processor has_work implementation and the logic in this function.
2322          */
2323         assert(!env->resume_as_sreset);
2324         break;
2325     default:
2326         cpu_abort(env_cpu(env), "Invalid PowerPC interrupt %d. Aborting\n",
2327                   interrupt);
2328     }
2329 }
2330 #endif /* TARGET_PPC64 */
2331 
2332 static void ppc_deliver_interrupt(CPUPPCState *env, int interrupt)
2333 {
2334 #ifdef TARGET_PPC64
2335     switch (env->excp_model) {
2336     case POWERPC_EXCP_POWER7:
2337         return p7_deliver_interrupt(env, interrupt);
2338     case POWERPC_EXCP_POWER8:
2339         return p8_deliver_interrupt(env, interrupt);
2340     case POWERPC_EXCP_POWER9:
2341     case POWERPC_EXCP_POWER10:
2342     case POWERPC_EXCP_POWER11:
2343         return p9_deliver_interrupt(env, interrupt);
2344     default:
2345         break;
2346     }
2347 #endif
2348     PowerPCCPU *cpu = env_archcpu(env);
2349 
2350     switch (interrupt) {
2351     case PPC_INTERRUPT_RESET: /* External reset */
2352         env->pending_interrupts &= ~PPC_INTERRUPT_RESET;
2353         powerpc_excp(cpu, POWERPC_EXCP_RESET);
2354         break;
2355     case PPC_INTERRUPT_MCK: /* Machine check exception */
2356         env->pending_interrupts &= ~PPC_INTERRUPT_MCK;
2357         powerpc_excp(cpu, POWERPC_EXCP_MCHECK);
2358         break;
2359 
2360     case PPC_INTERRUPT_HDECR: /* Hypervisor decrementer exception */
2361         /* HDEC clears on delivery */
2362         env->pending_interrupts &= ~PPC_INTERRUPT_HDECR;
2363         powerpc_excp(cpu, POWERPC_EXCP_HDECR);
2364         break;
2365     case PPC_INTERRUPT_HVIRT: /* Hypervisor virtualization interrupt */
2366         powerpc_excp(cpu, POWERPC_EXCP_HVIRT);
2367         break;
2368 
2369     case PPC_INTERRUPT_EXT:
2370         if (books_vhyp_promotes_external_to_hvirt(cpu)) {
2371             powerpc_excp(cpu, POWERPC_EXCP_HVIRT);
2372         } else {
2373             powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL);
2374         }
2375         break;
2376     case PPC_INTERRUPT_CEXT: /* External critical interrupt */
2377         powerpc_excp(cpu, POWERPC_EXCP_CRITICAL);
2378         break;
2379 
2380     case PPC_INTERRUPT_WDT: /* Watchdog timer on embedded PowerPC */
2381         env->pending_interrupts &= ~PPC_INTERRUPT_WDT;
2382         powerpc_excp(cpu, POWERPC_EXCP_WDT);
2383         break;
2384     case PPC_INTERRUPT_CDOORBELL:
2385         env->pending_interrupts &= ~PPC_INTERRUPT_CDOORBELL;
2386         powerpc_excp(cpu, POWERPC_EXCP_DOORCI);
2387         break;
2388     case PPC_INTERRUPT_FIT: /* Fixed interval timer on embedded PowerPC */
2389         env->pending_interrupts &= ~PPC_INTERRUPT_FIT;
2390         powerpc_excp(cpu, POWERPC_EXCP_FIT);
2391         break;
2392     case PPC_INTERRUPT_PIT: /* Programmable interval timer on embedded ppc */
2393         env->pending_interrupts &= ~PPC_INTERRUPT_PIT;
2394         powerpc_excp(cpu, POWERPC_EXCP_PIT);
2395         break;
2396     case PPC_INTERRUPT_DECR: /* Decrementer exception */
2397         if (ppc_decr_clear_on_delivery(env)) {
2398             env->pending_interrupts &= ~PPC_INTERRUPT_DECR;
2399         }
2400         powerpc_excp(cpu, POWERPC_EXCP_DECR);
2401         break;
2402     case PPC_INTERRUPT_DOORBELL:
2403         env->pending_interrupts &= ~PPC_INTERRUPT_DOORBELL;
2404         if (is_book3s_arch2x(env)) {
2405             powerpc_excp(cpu, POWERPC_EXCP_SDOOR);
2406         } else {
2407             powerpc_excp(cpu, POWERPC_EXCP_DOORI);
2408         }
2409         break;
2410     case PPC_INTERRUPT_HDOORBELL:
2411         env->pending_interrupts &= ~PPC_INTERRUPT_HDOORBELL;
2412         powerpc_excp(cpu, POWERPC_EXCP_SDOOR_HV);
2413         break;
2414     case PPC_INTERRUPT_PERFM:
2415         powerpc_excp(cpu, POWERPC_EXCP_PERFM);
2416         break;
2417     case PPC_INTERRUPT_THERM:  /* Thermal interrupt */
2418         env->pending_interrupts &= ~PPC_INTERRUPT_THERM;
2419         powerpc_excp(cpu, POWERPC_EXCP_THERM);
2420         break;
2421     case PPC_INTERRUPT_EBB: /* EBB exception */
2422         env->pending_interrupts &= ~PPC_INTERRUPT_EBB;
2423         if (env->spr[SPR_BESCR] & BESCR_PMEO) {
2424             powerpc_excp(cpu, POWERPC_EXCP_PERFM_EBB);
2425         } else if (env->spr[SPR_BESCR] & BESCR_EEO) {
2426             powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL_EBB);
2427         }
2428         break;
2429     case 0:
2430         /*
2431          * This is a bug ! It means that has_work took us out of halt without
2432          * anything to deliver while in a PM state that requires getting
2433          * out via a 0x100
2434          *
2435          * This means we will incorrectly execute past the power management
2436          * instruction instead of triggering a reset.
2437          *
2438          * It generally means a discrepancy between the wakeup conditions in the
2439          * processor has_work implementation and the logic in this function.
2440          */
2441         assert(!env->resume_as_sreset);
2442         break;
2443     default:
2444         cpu_abort(env_cpu(env), "Invalid PowerPC interrupt %d. Aborting\n",
2445                   interrupt);
2446     }
2447 }
2448 
2449 /*
2450  * system reset is not delivered via normal irq method, so have to set
2451  * halted = 0 to resume CPU running if it was halted. Possibly we should
2452  * move it over to using PPC_INTERRUPT_RESET rather than async_run_on_cpu.
2453  */
2454 void ppc_cpu_do_system_reset(CPUState *cs)
2455 {
2456     PowerPCCPU *cpu = POWERPC_CPU(cs);
2457 
2458     cs->halted = 0;
2459     powerpc_excp(cpu, POWERPC_EXCP_RESET);
2460 }
2461 
2462 void ppc_cpu_do_fwnmi_machine_check(CPUState *cs, target_ulong vector)
2463 {
2464     PowerPCCPU *cpu = POWERPC_CPU(cs);
2465     CPUPPCState *env = &cpu->env;
2466     target_ulong msr = 0;
2467 
2468     /*
2469      * Set MSR and NIP for the handler, SRR0/1, DAR and DSISR have already
2470      * been set by KVM.
2471      */
2472     msr = (1ULL << MSR_ME);
2473     msr |= env->msr & (1ULL << MSR_SF);
2474     if (ppc_interrupts_little_endian(cpu, false)) {
2475         msr |= (1ULL << MSR_LE);
2476     }
2477 
2478     /* Anything for nested required here? MSR[HV] bit? */
2479 
2480     cs->halted = 0;
2481     powerpc_set_excp_state(cpu, vector, msr);
2482 }
2483 
2484 bool ppc_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
2485 {
2486     CPUPPCState *env = cpu_env(cs);
2487     int interrupt;
2488 
2489     if ((interrupt_request & CPU_INTERRUPT_HARD) == 0) {
2490         return false;
2491     }
2492 
2493     interrupt = ppc_next_unmasked_interrupt(env);
2494     if (interrupt == 0) {
2495         return false;
2496     }
2497 
2498     ppc_deliver_interrupt(env, interrupt);
2499     if (env->pending_interrupts == 0) {
2500         cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
2501     }
2502     return true;
2503 }
2504 
2505 #endif /* !CONFIG_USER_ONLY */
2506 
2507 /*****************************************************************************/
2508 /* Exceptions processing helpers */
2509 
2510 void raise_exception_err_ra(CPUPPCState *env, uint32_t exception,
2511                             uint32_t error_code, uintptr_t raddr)
2512 {
2513     CPUState *cs = env_cpu(env);
2514 
2515     cs->exception_index = exception;
2516     env->error_code = error_code;
2517     cpu_loop_exit_restore(cs, raddr);
2518 }
2519 
2520 void raise_exception_err(CPUPPCState *env, uint32_t exception,
2521                          uint32_t error_code)
2522 {
2523     raise_exception_err_ra(env, exception, error_code, 0);
2524 }
2525 
2526 void raise_exception(CPUPPCState *env, uint32_t exception)
2527 {
2528     raise_exception_err_ra(env, exception, 0, 0);
2529 }
2530 
2531 #ifdef CONFIG_TCG
2532 void helper_raise_exception_err(CPUPPCState *env, uint32_t exception,
2533                                 uint32_t error_code)
2534 {
2535     raise_exception_err_ra(env, exception, error_code, 0);
2536 }
2537 
2538 void helper_raise_exception(CPUPPCState *env, uint32_t exception)
2539 {
2540     raise_exception_err_ra(env, exception, 0, 0);
2541 }
2542 
2543 #ifndef CONFIG_USER_ONLY
2544 void helper_store_msr(CPUPPCState *env, target_ulong val)
2545 {
2546     uint32_t excp = hreg_store_msr(env, val, 0);
2547 
2548     if (excp != 0) {
2549         cpu_interrupt_exittb(env_cpu(env));
2550         raise_exception(env, excp);
2551     }
2552 }
2553 
2554 void helper_ppc_maybe_interrupt(CPUPPCState *env)
2555 {
2556     ppc_maybe_interrupt(env);
2557 }
2558 
2559 #ifdef TARGET_PPC64
2560 void helper_scv(CPUPPCState *env, uint32_t lev)
2561 {
2562     if (env->spr[SPR_FSCR] & (1ull << FSCR_SCV)) {
2563         raise_exception_err(env, POWERPC_EXCP_SYSCALL_VECTORED, lev);
2564     } else {
2565         raise_exception_err(env, POWERPC_EXCP_FU, FSCR_IC_SCV);
2566     }
2567 }
2568 
2569 void helper_pminsn(CPUPPCState *env, uint32_t insn)
2570 {
2571     CPUState *cs = env_cpu(env);
2572 
2573     cs->halted = 1;
2574 
2575     /* Condition for waking up at 0x100 */
2576     env->resume_as_sreset = (insn != PPC_PM_STOP) ||
2577         (env->spr[SPR_PSSCR] & PSSCR_EC);
2578 
2579     /* HDECR is not to wake from PM state, it may have already fired */
2580     if (env->resume_as_sreset) {
2581         PowerPCCPU *cpu = env_archcpu(env);
2582         ppc_set_irq(cpu, PPC_INTERRUPT_HDECR, 0);
2583     }
2584 
2585     ppc_maybe_interrupt(env);
2586 }
2587 #endif /* TARGET_PPC64 */
2588 
2589 static void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr)
2590 {
2591     /* MSR:POW cannot be set by any form of rfi */
2592     msr &= ~(1ULL << MSR_POW);
2593 
2594     /* MSR:TGPR cannot be set by any form of rfi */
2595     if (env->flags & POWERPC_FLAG_TGPR)
2596         msr &= ~(1ULL << MSR_TGPR);
2597 
2598 #ifdef TARGET_PPC64
2599     /* Switching to 32-bit ? Crop the nip */
2600     if (!msr_is_64bit(env, msr)) {
2601         nip = (uint32_t)nip;
2602     }
2603 #else
2604     nip = (uint32_t)nip;
2605 #endif
2606     /* XXX: beware: this is false if VLE is supported */
2607     env->nip = nip & ~((target_ulong)0x00000003);
2608     hreg_store_msr(env, msr, 1);
2609     trace_ppc_excp_rfi(env->nip, env->msr);
2610     /*
2611      * No need to raise an exception here, as rfi is always the last
2612      * insn of a TB
2613      */
2614     cpu_interrupt_exittb(env_cpu(env));
2615     /* Reset the reservation */
2616     env->reserve_addr = -1;
2617 
2618     /* Context synchronizing: check if TCG TLB needs flush */
2619     check_tlb_flush(env, false);
2620 }
2621 
2622 void helper_rfi(CPUPPCState *env)
2623 {
2624     do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1] & 0xfffffffful);
2625 }
2626 
2627 #ifdef TARGET_PPC64
2628 void helper_rfid(CPUPPCState *env)
2629 {
2630     /*
2631      * The architecture defines a number of rules for which bits can
2632      * change but in practice, we handle this in hreg_store_msr()
2633      * which will be called by do_rfi(), so there is no need to filter
2634      * here
2635      */
2636     do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1]);
2637 }
2638 
2639 void helper_rfscv(CPUPPCState *env)
2640 {
2641     do_rfi(env, env->lr, env->ctr);
2642 }
2643 
2644 void helper_hrfid(CPUPPCState *env)
2645 {
2646     do_rfi(env, env->spr[SPR_HSRR0], env->spr[SPR_HSRR1]);
2647 }
2648 
2649 void helper_rfebb(CPUPPCState *env, target_ulong s)
2650 {
2651     target_ulong msr = env->msr;
2652 
2653     /*
2654      * Handling of BESCR bits 32:33 according to PowerISA v3.1:
2655      *
2656      * "If BESCR 32:33 != 0b00 the instruction is treated as if
2657      *  the instruction form were invalid."
2658      */
2659     if (env->spr[SPR_BESCR] & BESCR_INVALID) {
2660         raise_exception_err(env, POWERPC_EXCP_PROGRAM,
2661                             POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL);
2662     }
2663 
2664     env->nip = env->spr[SPR_EBBRR];
2665 
2666     /* Switching to 32-bit ? Crop the nip */
2667     if (!msr_is_64bit(env, msr)) {
2668         env->nip = (uint32_t)env->spr[SPR_EBBRR];
2669     }
2670 
2671     if (s) {
2672         env->spr[SPR_BESCR] |= BESCR_GE;
2673     } else {
2674         env->spr[SPR_BESCR] &= ~BESCR_GE;
2675     }
2676 }
2677 
2678 /*
2679  * Triggers or queues an 'ebb_excp' EBB exception. All checks
2680  * but FSCR, HFSCR and msr_pr must be done beforehand.
2681  *
2682  * PowerISA v3.1 isn't clear about whether an EBB should be
2683  * postponed or cancelled if the EBB facility is unavailable.
2684  * Our assumption here is that the EBB is cancelled if both
2685  * FSCR and HFSCR EBB facilities aren't available.
2686  */
2687 static void do_ebb(CPUPPCState *env, int ebb_excp)
2688 {
2689     PowerPCCPU *cpu = env_archcpu(env);
2690 
2691     /*
2692      * FSCR_EBB and FSCR_IC_EBB are the same bits used with
2693      * HFSCR.
2694      */
2695     helper_fscr_facility_check(env, FSCR_EBB, 0, FSCR_IC_EBB);
2696     helper_hfscr_facility_check(env, FSCR_EBB, "EBB", FSCR_IC_EBB);
2697 
2698     if (ebb_excp == POWERPC_EXCP_PERFM_EBB) {
2699         env->spr[SPR_BESCR] |= BESCR_PMEO;
2700     } else if (ebb_excp == POWERPC_EXCP_EXTERNAL_EBB) {
2701         env->spr[SPR_BESCR] |= BESCR_EEO;
2702     }
2703 
2704     if (FIELD_EX64(env->msr, MSR, PR)) {
2705         powerpc_excp(cpu, ebb_excp);
2706     } else {
2707         ppc_set_irq(cpu, PPC_INTERRUPT_EBB, 1);
2708     }
2709 }
2710 
2711 void raise_ebb_perfm_exception(CPUPPCState *env)
2712 {
2713     bool perfm_ebb_enabled = env->spr[SPR_POWER_MMCR0] & MMCR0_EBE &&
2714                              env->spr[SPR_BESCR] & BESCR_PME &&
2715                              env->spr[SPR_BESCR] & BESCR_GE;
2716 
2717     if (!perfm_ebb_enabled) {
2718         return;
2719     }
2720 
2721     do_ebb(env, POWERPC_EXCP_PERFM_EBB);
2722 }
2723 #endif /* TARGET_PPC64 */
2724 
2725 /*****************************************************************************/
2726 /* Embedded PowerPC specific helpers */
2727 void helper_40x_rfci(CPUPPCState *env)
2728 {
2729     do_rfi(env, env->spr[SPR_40x_SRR2], env->spr[SPR_40x_SRR3]);
2730 }
2731 
2732 void helper_rfci(CPUPPCState *env)
2733 {
2734     do_rfi(env, env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1]);
2735 }
2736 
2737 void helper_rfdi(CPUPPCState *env)
2738 {
2739     /* FIXME: choose CSRR1 or DSRR1 based on cpu type */
2740     do_rfi(env, env->spr[SPR_BOOKE_DSRR0], env->spr[SPR_BOOKE_DSRR1]);
2741 }
2742 
2743 void helper_rfmci(CPUPPCState *env)
2744 {
2745     /* FIXME: choose CSRR1 or MCSRR1 based on cpu type */
2746     do_rfi(env, env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1]);
2747 }
2748 #endif /* !CONFIG_USER_ONLY */
2749 
2750 void helper_TW(CPUPPCState *env, target_ulong arg1, target_ulong arg2,
2751                uint32_t flags)
2752 {
2753     if (!likely(!(((int32_t)arg1 < (int32_t)arg2 && (flags & 0x10)) ||
2754                   ((int32_t)arg1 > (int32_t)arg2 && (flags & 0x08)) ||
2755                   ((int32_t)arg1 == (int32_t)arg2 && (flags & 0x04)) ||
2756                   ((uint32_t)arg1 < (uint32_t)arg2 && (flags & 0x02)) ||
2757                   ((uint32_t)arg1 > (uint32_t)arg2 && (flags & 0x01))))) {
2758         raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
2759                                POWERPC_EXCP_TRAP, GETPC());
2760     }
2761 }
2762 
2763 #ifdef TARGET_PPC64
2764 void helper_TD(CPUPPCState *env, target_ulong arg1, target_ulong arg2,
2765                uint32_t flags)
2766 {
2767     if (!likely(!(((int64_t)arg1 < (int64_t)arg2 && (flags & 0x10)) ||
2768                   ((int64_t)arg1 > (int64_t)arg2 && (flags & 0x08)) ||
2769                   ((int64_t)arg1 == (int64_t)arg2 && (flags & 0x04)) ||
2770                   ((uint64_t)arg1 < (uint64_t)arg2 && (flags & 0x02)) ||
2771                   ((uint64_t)arg1 > (uint64_t)arg2 && (flags & 0x01))))) {
2772         raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
2773                                POWERPC_EXCP_TRAP, GETPC());
2774     }
2775 }
2776 #endif /* TARGET_PPC64 */
2777 
2778 static uint32_t helper_SIMON_LIKE_32_64(uint32_t x, uint64_t key, uint32_t lane)
2779 {
2780     const uint16_t c = 0xfffc;
2781     const uint64_t z0 = 0xfa2561cdf44ac398ULL;
2782     uint16_t z = 0, temp;
2783     uint16_t k[32], eff_k[32], xleft[33], xright[33], fxleft[32];
2784 
2785     for (int i = 3; i >= 0; i--) {
2786         k[i] = key & 0xffff;
2787         key >>= 16;
2788     }
2789     xleft[0] = x & 0xffff;
2790     xright[0] = (x >> 16) & 0xffff;
2791 
2792     for (int i = 0; i < 28; i++) {
2793         z = (z0 >> (63 - i)) & 1;
2794         temp = ror16(k[i + 3], 3) ^ k[i + 1];
2795         k[i + 4] = c ^ z ^ k[i] ^ temp ^ ror16(temp, 1);
2796     }
2797 
2798     for (int i = 0; i < 8; i++) {
2799         eff_k[4 * i + 0] = k[4 * i + ((0 + lane) % 4)];
2800         eff_k[4 * i + 1] = k[4 * i + ((1 + lane) % 4)];
2801         eff_k[4 * i + 2] = k[4 * i + ((2 + lane) % 4)];
2802         eff_k[4 * i + 3] = k[4 * i + ((3 + lane) % 4)];
2803     }
2804 
2805     for (int i = 0; i < 32; i++) {
2806         fxleft[i] = (rol16(xleft[i], 1) &
2807             rol16(xleft[i], 8)) ^ rol16(xleft[i], 2);
2808         xleft[i + 1] = xright[i] ^ fxleft[i] ^ eff_k[i];
2809         xright[i + 1] = xleft[i];
2810     }
2811 
2812     return (((uint32_t)xright[32]) << 16) | xleft[32];
2813 }
2814 
2815 static uint64_t hash_digest(uint64_t ra, uint64_t rb, uint64_t key)
2816 {
2817     uint64_t stage0_h = 0ULL, stage0_l = 0ULL;
2818     uint64_t stage1_h, stage1_l;
2819 
2820     for (int i = 0; i < 4; i++) {
2821         stage0_h |= ror64(rb & 0xff, 8 * (2 * i + 1));
2822         stage0_h |= ((ra >> 32) & 0xff) << (8 * 2 * i);
2823         stage0_l |= ror64((rb >> 32) & 0xff, 8 * (2 * i + 1));
2824         stage0_l |= (ra & 0xff) << (8 * 2 * i);
2825         rb >>= 8;
2826         ra >>= 8;
2827     }
2828 
2829     stage1_h = (uint64_t)helper_SIMON_LIKE_32_64(stage0_h >> 32, key, 0) << 32;
2830     stage1_h |= helper_SIMON_LIKE_32_64(stage0_h, key, 1);
2831     stage1_l = (uint64_t)helper_SIMON_LIKE_32_64(stage0_l >> 32, key, 2) << 32;
2832     stage1_l |= helper_SIMON_LIKE_32_64(stage0_l, key, 3);
2833 
2834     return stage1_h ^ stage1_l;
2835 }
2836 
2837 static void do_hash(CPUPPCState *env, target_ulong ea, target_ulong ra,
2838                     target_ulong rb, uint64_t key, bool store)
2839 {
2840     uint64_t calculated_hash = hash_digest(ra, rb, key), loaded_hash;
2841 
2842     if (store) {
2843         cpu_stq_data_ra(env, ea, calculated_hash, GETPC());
2844     } else {
2845         loaded_hash = cpu_ldq_data_ra(env, ea, GETPC());
2846         if (loaded_hash != calculated_hash) {
2847             raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
2848                 POWERPC_EXCP_TRAP, GETPC());
2849         }
2850     }
2851 }
2852 
2853 #include "qemu/guest-random.h"
2854 
2855 #ifdef TARGET_PPC64
2856 #define HELPER_HASH(op, key, store, dexcr_aspect)                             \
2857 void helper_##op(CPUPPCState *env, target_ulong ea, target_ulong ra,          \
2858                  target_ulong rb)                                             \
2859 {                                                                             \
2860     if (env->msr & R_MSR_PR_MASK) {                                           \
2861         if (!(env->spr[SPR_DEXCR] & R_DEXCR_PRO_##dexcr_aspect##_MASK ||      \
2862             env->spr[SPR_HDEXCR] & R_HDEXCR_ENF_##dexcr_aspect##_MASK))       \
2863             return;                                                           \
2864     } else if (!(env->msr & R_MSR_HV_MASK)) {                                 \
2865         if (!(env->spr[SPR_DEXCR] & R_DEXCR_PNH_##dexcr_aspect##_MASK ||      \
2866             env->spr[SPR_HDEXCR] & R_HDEXCR_ENF_##dexcr_aspect##_MASK))       \
2867             return;                                                           \
2868     } else if (!(env->msr & R_MSR_S_MASK)) {                                  \
2869         if (!(env->spr[SPR_HDEXCR] & R_HDEXCR_HNU_##dexcr_aspect##_MASK))     \
2870             return;                                                           \
2871     }                                                                         \
2872                                                                               \
2873     do_hash(env, ea, ra, rb, key, store);                                     \
2874 }
2875 #else
2876 #define HELPER_HASH(op, key, store, dexcr_aspect)                             \
2877 void helper_##op(CPUPPCState *env, target_ulong ea, target_ulong ra,          \
2878                  target_ulong rb)                                             \
2879 {                                                                             \
2880     do_hash(env, ea, ra, rb, key, store);                                     \
2881 }
2882 #endif /* TARGET_PPC64 */
2883 
2884 HELPER_HASH(HASHST, env->spr[SPR_HASHKEYR], true, NPHIE)
2885 HELPER_HASH(HASHCHK, env->spr[SPR_HASHKEYR], false, NPHIE)
2886 HELPER_HASH(HASHSTP, env->spr[SPR_HASHPKEYR], true, PHIE)
2887 HELPER_HASH(HASHCHKP, env->spr[SPR_HASHPKEYR], false, PHIE)
2888 
2889 #ifndef CONFIG_USER_ONLY
2890 /* Embedded.Processor Control */
2891 static int dbell2irq(target_ulong rb)
2892 {
2893     int msg = rb & DBELL_TYPE_MASK;
2894     int irq = -1;
2895 
2896     switch (msg) {
2897     case DBELL_TYPE_DBELL:
2898         irq = PPC_INTERRUPT_DOORBELL;
2899         break;
2900     case DBELL_TYPE_DBELL_CRIT:
2901         irq = PPC_INTERRUPT_CDOORBELL;
2902         break;
2903     case DBELL_TYPE_G_DBELL:
2904     case DBELL_TYPE_G_DBELL_CRIT:
2905     case DBELL_TYPE_G_DBELL_MC:
2906         /* XXX implement */
2907     default:
2908         break;
2909     }
2910 
2911     return irq;
2912 }
2913 
2914 void helper_msgclr(CPUPPCState *env, target_ulong rb)
2915 {
2916     int irq = dbell2irq(rb);
2917 
2918     if (irq < 0) {
2919         return;
2920     }
2921 
2922     ppc_set_irq(env_archcpu(env), irq, 0);
2923 }
2924 
2925 void helper_msgsnd(target_ulong rb)
2926 {
2927     int irq = dbell2irq(rb);
2928     int pir = rb & DBELL_PIRTAG_MASK;
2929     CPUState *cs;
2930 
2931     if (irq < 0) {
2932         return;
2933     }
2934 
2935     bql_lock();
2936     CPU_FOREACH(cs) {
2937         PowerPCCPU *cpu = POWERPC_CPU(cs);
2938         CPUPPCState *cenv = &cpu->env;
2939 
2940         if ((rb & DBELL_BRDCAST_MASK) || (cenv->spr[SPR_BOOKE_PIR] == pir)) {
2941             ppc_set_irq(cpu, irq, 1);
2942         }
2943     }
2944     bql_unlock();
2945 }
2946 
2947 /* Server Processor Control */
2948 
2949 static bool dbell_type_server(target_ulong rb)
2950 {
2951     /*
2952      * A Directed Hypervisor Doorbell message is sent only if the
2953      * message type is 5. All other types are reserved and the
2954      * instruction is a no-op
2955      */
2956     return (rb & DBELL_TYPE_MASK) == DBELL_TYPE_DBELL_SERVER;
2957 }
2958 
2959 static inline bool dbell_bcast_core(target_ulong rb)
2960 {
2961     return (rb & DBELL_BRDCAST_MASK) == DBELL_BRDCAST_CORE;
2962 }
2963 
2964 static inline bool dbell_bcast_subproc(target_ulong rb)
2965 {
2966     return (rb & DBELL_BRDCAST_MASK) == DBELL_BRDCAST_SUBPROC;
2967 }
2968 
2969 /*
2970  * Send an interrupt to a thread in the same core as env).
2971  */
2972 static void msgsnd_core_tir(CPUPPCState *env, uint32_t target_tir, int irq)
2973 {
2974     PowerPCCPU *cpu = env_archcpu(env);
2975     CPUState *cs = env_cpu(env);
2976 
2977     if (ppc_cpu_lpar_single_threaded(cs)) {
2978         if (target_tir == 0) {
2979             ppc_set_irq(cpu, irq, 1);
2980         }
2981     } else {
2982         CPUState *ccs;
2983 
2984         /* Does iothread need to be locked for walking CPU list? */
2985         bql_lock();
2986         THREAD_SIBLING_FOREACH(cs, ccs) {
2987             PowerPCCPU *ccpu = POWERPC_CPU(ccs);
2988             if (target_tir == ppc_cpu_tir(ccpu)) {
2989                 ppc_set_irq(ccpu, irq, 1);
2990                 break;
2991             }
2992         }
2993         bql_unlock();
2994     }
2995 }
2996 
2997 void helper_book3s_msgclr(CPUPPCState *env, target_ulong rb)
2998 {
2999     if (!dbell_type_server(rb)) {
3000         return;
3001     }
3002 
3003     ppc_set_irq(env_archcpu(env), PPC_INTERRUPT_HDOORBELL, 0);
3004 }
3005 
3006 void helper_book3s_msgsnd(CPUPPCState *env, target_ulong rb)
3007 {
3008     int pir = rb & DBELL_PROCIDTAG_MASK;
3009     bool brdcast = false;
3010     CPUState *cs, *ccs;
3011     PowerPCCPU *cpu;
3012 
3013     if (!dbell_type_server(rb)) {
3014         return;
3015     }
3016 
3017     /* POWER8 msgsnd is like msgsndp (targets a thread within core) */
3018     if (!(env->insns_flags2 & PPC2_ISA300)) {
3019         msgsnd_core_tir(env, rb & PPC_BITMASK(57, 63), PPC_INTERRUPT_HDOORBELL);
3020         return;
3021     }
3022 
3023     /* POWER9 and later msgsnd is a global (targets any thread) */
3024     cpu = ppc_get_vcpu_by_pir(pir);
3025     if (!cpu) {
3026         return;
3027     }
3028     cs = CPU(cpu);
3029 
3030     if (dbell_bcast_core(rb) || (dbell_bcast_subproc(rb) &&
3031                                  (env->flags & POWERPC_FLAG_SMT_1LPAR))) {
3032         brdcast = true;
3033     }
3034 
3035     if (ppc_cpu_core_single_threaded(cs) || !brdcast) {
3036         ppc_set_irq(cpu, PPC_INTERRUPT_HDOORBELL, 1);
3037         return;
3038     }
3039 
3040     /*
3041      * Why is bql needed for walking CPU list? Answer seems to be because ppc
3042      * irq handling needs it, but ppc_set_irq takes the lock itself if needed,
3043      * so could this be removed?
3044      */
3045     bql_lock();
3046     THREAD_SIBLING_FOREACH(cs, ccs) {
3047         ppc_set_irq(POWERPC_CPU(ccs), PPC_INTERRUPT_HDOORBELL, 1);
3048     }
3049     bql_unlock();
3050 }
3051 
3052 #ifdef TARGET_PPC64
3053 void helper_book3s_msgclrp(CPUPPCState *env, target_ulong rb)
3054 {
3055     helper_hfscr_facility_check(env, HFSCR_MSGP, "msgclrp", HFSCR_IC_MSGP);
3056 
3057     if (!dbell_type_server(rb)) {
3058         return;
3059     }
3060 
3061     ppc_set_irq(env_archcpu(env), PPC_INTERRUPT_DOORBELL, 0);
3062 }
3063 
3064 /*
3065  * sends a message to another thread  on the same
3066  * multi-threaded processor
3067  */
3068 void helper_book3s_msgsndp(CPUPPCState *env, target_ulong rb)
3069 {
3070     helper_hfscr_facility_check(env, HFSCR_MSGP, "msgsndp", HFSCR_IC_MSGP);
3071 
3072     if (!dbell_type_server(rb)) {
3073         return;
3074     }
3075 
3076     msgsnd_core_tir(env, rb & PPC_BITMASK(57, 63), PPC_INTERRUPT_DOORBELL);
3077 }
3078 #endif /* TARGET_PPC64 */
3079 
3080 /* Single-step tracing */
3081 void helper_book3s_trace(CPUPPCState *env, target_ulong prev_ip)
3082 {
3083     uint32_t error_code = 0;
3084     if (env->insns_flags2 & PPC2_ISA207S) {
3085         /* Load/store reporting, SRR1[35, 36] and SDAR, are not implemented. */
3086         env->spr[SPR_POWER_SIAR] = prev_ip;
3087         error_code = PPC_BIT(33);
3088     }
3089     raise_exception_err(env, POWERPC_EXCP_TRACE, error_code);
3090 }
3091 
3092 #endif /* !CONFIG_USER_ONLY */
3093 #endif /* CONFIG_TCG */
3094