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