xref: /qemu/target/ppc/excp_helper.c (revision fe4b5c4c335c874ab05f3bdf40f2b62641d81c72)
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     target_ulong msr, new_msr, vector;
749 
750     if (excp <= POWERPC_EXCP_NONE || excp >= POWERPC_EXCP_NB) {
751         cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
752     }
753 
754     qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx
755                   " => %s (%d) error=%02x\n", env->nip, powerpc_excp_name(excp),
756                   excp, env->error_code);
757 
758     /* new srr1 value excluding must-be-zero bits */
759     msr = env->msr & ~0x783f0000ULL;
760 
761     /*
762      * new interrupt handler msr preserves existing ME unless
763      * explicitly overriden
764      */
765     new_msr = env->msr & ((target_ulong)1 << MSR_ME);
766 
767     /*
768      * Hypervisor emulation assistance interrupt only exists on server
769      * arch 2.05 server or later.
770      */
771     if (excp == POWERPC_EXCP_HV_EMU) {
772         excp = POWERPC_EXCP_PROGRAM;
773     }
774 
775     vector = env->excp_vectors[excp];
776     if (vector == (target_ulong)-1ULL) {
777         cpu_abort(cs, "Raised an exception without defined vector %d\n",
778                   excp);
779     }
780 
781     vector |= env->excp_prefix;
782 
783     switch (excp) {
784     case POWERPC_EXCP_MCHECK:    /* Machine check exception                  */
785         if (msr_me == 0) {
786             /*
787              * Machine check exception is not enabled.  Enter
788              * checkstop state.
789              */
790             fprintf(stderr, "Machine check while not allowed. "
791                     "Entering checkstop state\n");
792             if (qemu_log_separate()) {
793                 qemu_log("Machine check while not allowed. "
794                         "Entering checkstop state\n");
795             }
796             cs->halted = 1;
797             cpu_interrupt_exittb(cs);
798         }
799 
800         /* machine check exceptions don't have ME set */
801         new_msr &= ~((target_ulong)1 << MSR_ME);
802 
803         break;
804     case POWERPC_EXCP_DSI:       /* Data storage exception                   */
805         trace_ppc_excp_dsi(env->spr[SPR_DSISR], env->spr[SPR_DAR]);
806         break;
807     case POWERPC_EXCP_ISI:       /* Instruction storage exception            */
808         trace_ppc_excp_isi(msr, env->nip);
809         msr |= env->error_code;
810         break;
811     case POWERPC_EXCP_EXTERNAL:  /* External input                           */
812         break;
813     case POWERPC_EXCP_ALIGN:     /* Alignment exception                      */
814         /* Get rS/rD and rA from faulting opcode */
815         /*
816          * Note: the opcode fields will not be set properly for a
817          * direct store load/store, but nobody cares as nobody
818          * actually uses direct store segments.
819          */
820         env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16;
821         break;
822     case POWERPC_EXCP_PROGRAM:   /* Program exception                        */
823         switch (env->error_code & ~0xF) {
824         case POWERPC_EXCP_FP:
825             if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) {
826                 trace_ppc_excp_fp_ignore();
827                 cs->exception_index = POWERPC_EXCP_NONE;
828                 env->error_code = 0;
829                 return;
830             }
831 
832             /*
833              * FP exceptions always have NIP pointing to the faulting
834              * instruction, so always use store_next and claim we are
835              * precise in the MSR.
836              */
837             msr |= 0x00100000;
838             break;
839         case POWERPC_EXCP_INVAL:
840             trace_ppc_excp_inval(env->nip);
841             msr |= 0x00080000;
842             break;
843         case POWERPC_EXCP_PRIV:
844             msr |= 0x00040000;
845             break;
846         case POWERPC_EXCP_TRAP:
847             msr |= 0x00020000;
848             break;
849         default:
850             /* Should never occur */
851             cpu_abort(cs, "Invalid program exception %d. Aborting\n",
852                       env->error_code);
853             break;
854         }
855         break;
856     case POWERPC_EXCP_SYSCALL:   /* System call exception                    */
857     {
858         int lev = env->error_code;
859 
860         if (lev == 1 && cpu->vhyp) {
861             dump_hcall(env);
862         } else {
863             dump_syscall(env);
864         }
865 
866         /*
867          * We need to correct the NIP which in this case is supposed
868          * to point to the next instruction
869          */
870         env->nip += 4;
871 
872         /*
873          * The Virtual Open Firmware (VOF) relies on the 'sc 1'
874          * instruction to communicate with QEMU. The pegasos2 machine
875          * uses VOF and the 7xx CPUs, so although the 7xx don't have
876          * HV mode, we need to keep hypercall support.
877          */
878         if (lev == 1 && cpu->vhyp) {
879             PPCVirtualHypervisorClass *vhc =
880                 PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
881             vhc->hypercall(cpu->vhyp, cpu);
882             return;
883         }
884 
885         break;
886     }
887     case POWERPC_EXCP_FPU:       /* Floating-point unavailable exception     */
888     case POWERPC_EXCP_DECR:      /* Decrementer exception                    */
889         break;
890     case POWERPC_EXCP_RESET:     /* System reset exception                   */
891         if (msr_pow) {
892             cpu_abort(cs, "Trying to deliver power-saving system reset "
893                       "exception %d with no HV support\n", excp);
894         }
895         break;
896     case POWERPC_EXCP_TRACE:     /* Trace exception                          */
897         break;
898     case POWERPC_EXCP_IFTLB:     /* Instruction fetch TLB error              */
899     case POWERPC_EXCP_DLTLB:     /* Data load TLB miss                       */
900     case POWERPC_EXCP_DSTLB:     /* Data store TLB miss                      */
901         ppc_excp_debug_sw_tlb(env, excp);
902 
903         msr |= env->crf[0] << 28;
904         msr |= env->error_code; /* key, D/I, S/L bits */
905         /* Set way using a LRU mechanism */
906         msr |= ((env->last_way + 1) & (env->nb_ways - 1)) << 17;
907 
908         break;
909     case POWERPC_EXCP_IABR:      /* Instruction address breakpoint           */
910     case POWERPC_EXCP_SMI:       /* System management interrupt              */
911     case POWERPC_EXCP_THERM:     /* Thermal interrupt                        */
912     case POWERPC_EXCP_PERFM:     /* Embedded performance monitor interrupt   */
913         cpu_abort(cs, "%s exception not implemented\n",
914                   powerpc_excp_name(excp));
915         break;
916     default:
917         cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
918         break;
919     }
920 
921     /* Sanity check */
922     if (!(env->msr_mask & MSR_HVB)) {
923         if (new_msr & MSR_HVB) {
924             cpu_abort(cs, "Trying to deliver HV exception (MSR) %d with "
925                       "no HV support\n", excp);
926         }
927     }
928 
929     /*
930      * Sort out endianness of interrupt, this differs depending on the
931      * CPU, the HV mode, etc...
932      */
933     if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) {
934         new_msr |= (target_ulong)1 << MSR_LE;
935     }
936 
937     /* Save PC */
938     env->spr[SPR_SRR0] = env->nip;
939 
940     /* Save MSR */
941     env->spr[SPR_SRR1] = msr;
942 
943     powerpc_set_excp_state(cpu, vector, new_msr);
944 }
945 
946 static void powerpc_excp_74xx(PowerPCCPU *cpu, int excp)
947 {
948     CPUState *cs = CPU(cpu);
949     CPUPPCState *env = &cpu->env;
950     target_ulong msr, new_msr, vector;
951 
952     if (excp <= POWERPC_EXCP_NONE || excp >= POWERPC_EXCP_NB) {
953         cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
954     }
955 
956     qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx
957                   " => %s (%d) error=%02x\n", env->nip, powerpc_excp_name(excp),
958                   excp, env->error_code);
959 
960     /* new srr1 value excluding must-be-zero bits */
961     msr = env->msr & ~0x783f0000ULL;
962 
963     /*
964      * new interrupt handler msr preserves existing ME unless
965      * explicitly overriden
966      */
967     new_msr = env->msr & ((target_ulong)1 << MSR_ME);
968 
969     /*
970      * Hypervisor emulation assistance interrupt only exists on server
971      * arch 2.05 server or later.
972      */
973     if (excp == POWERPC_EXCP_HV_EMU) {
974         excp = POWERPC_EXCP_PROGRAM;
975     }
976 
977     vector = env->excp_vectors[excp];
978     if (vector == (target_ulong)-1ULL) {
979         cpu_abort(cs, "Raised an exception without defined vector %d\n",
980                   excp);
981     }
982 
983     vector |= env->excp_prefix;
984 
985     switch (excp) {
986     case POWERPC_EXCP_MCHECK:    /* Machine check exception                  */
987         if (msr_me == 0) {
988             /*
989              * Machine check exception is not enabled.  Enter
990              * checkstop state.
991              */
992             fprintf(stderr, "Machine check while not allowed. "
993                     "Entering checkstop state\n");
994             if (qemu_log_separate()) {
995                 qemu_log("Machine check while not allowed. "
996                         "Entering checkstop state\n");
997             }
998             cs->halted = 1;
999             cpu_interrupt_exittb(cs);
1000         }
1001 
1002         /* machine check exceptions don't have ME set */
1003         new_msr &= ~((target_ulong)1 << MSR_ME);
1004 
1005         break;
1006     case POWERPC_EXCP_DSI:       /* Data storage exception                   */
1007         trace_ppc_excp_dsi(env->spr[SPR_DSISR], env->spr[SPR_DAR]);
1008         break;
1009     case POWERPC_EXCP_ISI:       /* Instruction storage exception            */
1010         trace_ppc_excp_isi(msr, env->nip);
1011         msr |= env->error_code;
1012         break;
1013     case POWERPC_EXCP_EXTERNAL:  /* External input                           */
1014         break;
1015     case POWERPC_EXCP_ALIGN:     /* Alignment exception                      */
1016         /* Get rS/rD and rA from faulting opcode */
1017         /*
1018          * Note: the opcode fields will not be set properly for a
1019          * direct store load/store, but nobody cares as nobody
1020          * actually uses direct store segments.
1021          */
1022         env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16;
1023         break;
1024     case POWERPC_EXCP_PROGRAM:   /* Program exception                        */
1025         switch (env->error_code & ~0xF) {
1026         case POWERPC_EXCP_FP:
1027             if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) {
1028                 trace_ppc_excp_fp_ignore();
1029                 cs->exception_index = POWERPC_EXCP_NONE;
1030                 env->error_code = 0;
1031                 return;
1032             }
1033 
1034             /*
1035              * FP exceptions always have NIP pointing to the faulting
1036              * instruction, so always use store_next and claim we are
1037              * precise in the MSR.
1038              */
1039             msr |= 0x00100000;
1040             break;
1041         case POWERPC_EXCP_INVAL:
1042             trace_ppc_excp_inval(env->nip);
1043             msr |= 0x00080000;
1044             break;
1045         case POWERPC_EXCP_PRIV:
1046             msr |= 0x00040000;
1047             break;
1048         case POWERPC_EXCP_TRAP:
1049             msr |= 0x00020000;
1050             break;
1051         default:
1052             /* Should never occur */
1053             cpu_abort(cs, "Invalid program exception %d. Aborting\n",
1054                       env->error_code);
1055             break;
1056         }
1057         break;
1058     case POWERPC_EXCP_SYSCALL:   /* System call exception                    */
1059     {
1060         int lev = env->error_code;
1061 
1062         if ((lev == 1) && cpu->vhyp) {
1063             dump_hcall(env);
1064         } else {
1065             dump_syscall(env);
1066         }
1067 
1068         /*
1069          * We need to correct the NIP which in this case is supposed
1070          * to point to the next instruction
1071          */
1072         env->nip += 4;
1073 
1074         /*
1075          * The Virtual Open Firmware (VOF) relies on the 'sc 1'
1076          * instruction to communicate with QEMU. The pegasos2 machine
1077          * uses VOF and the 74xx CPUs, so although the 74xx don't have
1078          * HV mode, we need to keep hypercall support.
1079          */
1080         if ((lev == 1) && cpu->vhyp) {
1081             PPCVirtualHypervisorClass *vhc =
1082                 PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
1083             vhc->hypercall(cpu->vhyp, cpu);
1084             return;
1085         }
1086 
1087         break;
1088     }
1089     case POWERPC_EXCP_FPU:       /* Floating-point unavailable exception     */
1090     case POWERPC_EXCP_DECR:      /* Decrementer exception                    */
1091         break;
1092     case POWERPC_EXCP_RESET:     /* System reset exception                   */
1093         if (msr_pow) {
1094             cpu_abort(cs, "Trying to deliver power-saving system reset "
1095                       "exception %d with no HV support\n", excp);
1096         }
1097         break;
1098     case POWERPC_EXCP_TRACE:     /* Trace exception                          */
1099         break;
1100     case POWERPC_EXCP_VPU:       /* Vector unavailable exception             */
1101         break;
1102     case POWERPC_EXCP_IABR:      /* Instruction address breakpoint           */
1103     case POWERPC_EXCP_SMI:       /* System management interrupt              */
1104     case POWERPC_EXCP_THERM:     /* Thermal interrupt                        */
1105     case POWERPC_EXCP_PERFM:     /* Embedded performance monitor interrupt   */
1106     case POWERPC_EXCP_VPUA:      /* Vector assist exception                  */
1107         cpu_abort(cs, "%s exception not implemented\n",
1108                   powerpc_excp_name(excp));
1109         break;
1110     default:
1111         cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
1112         break;
1113     }
1114 
1115     /* Sanity check */
1116     if (!(env->msr_mask & MSR_HVB)) {
1117         if (new_msr & MSR_HVB) {
1118             cpu_abort(cs, "Trying to deliver HV exception (MSR) %d with "
1119                       "no HV support\n", excp);
1120         }
1121     }
1122 
1123     /*
1124      * Sort out endianness of interrupt, this differs depending on the
1125      * CPU, the HV mode, etc...
1126      */
1127     if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) {
1128         new_msr |= (target_ulong)1 << MSR_LE;
1129     }
1130 
1131     /* Save PC */
1132     env->spr[SPR_SRR0] = env->nip;
1133 
1134     /* Save MSR */
1135     env->spr[SPR_SRR1] = msr;
1136 
1137     powerpc_set_excp_state(cpu, vector, new_msr);
1138 }
1139 
1140 static void powerpc_excp_booke(PowerPCCPU *cpu, int excp)
1141 {
1142     CPUState *cs = CPU(cpu);
1143     CPUPPCState *env = &cpu->env;
1144     target_ulong msr, new_msr, vector;
1145     int srr0, srr1;
1146 
1147     if (excp <= POWERPC_EXCP_NONE || excp >= POWERPC_EXCP_NB) {
1148         cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
1149     }
1150 
1151     qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx
1152                   " => %s (%d) error=%02x\n", env->nip, powerpc_excp_name(excp),
1153                   excp, env->error_code);
1154 
1155     msr = env->msr;
1156 
1157     /*
1158      * new interrupt handler msr preserves existing ME unless
1159      * explicitly overriden
1160      */
1161     new_msr = env->msr & ((target_ulong)1 << MSR_ME);
1162 
1163     /* target registers */
1164     srr0 = SPR_SRR0;
1165     srr1 = SPR_SRR1;
1166 
1167     /*
1168      * Hypervisor emulation assistance interrupt only exists on server
1169      * arch 2.05 server or later.
1170      */
1171     if (excp == POWERPC_EXCP_HV_EMU) {
1172         excp = POWERPC_EXCP_PROGRAM;
1173     }
1174 
1175 #ifdef TARGET_PPC64
1176     /*
1177      * SPEU and VPU share the same IVOR but they exist in different
1178      * processors. SPEU is e500v1/2 only and VPU is e6500 only.
1179      */
1180     if (excp == POWERPC_EXCP_VPU) {
1181         excp = POWERPC_EXCP_SPEU;
1182     }
1183 #endif
1184 
1185     vector = env->excp_vectors[excp];
1186     if (vector == (target_ulong)-1ULL) {
1187         cpu_abort(cs, "Raised an exception without defined vector %d\n",
1188                   excp);
1189     }
1190 
1191     vector |= env->excp_prefix;
1192 
1193     switch (excp) {
1194     case POWERPC_EXCP_CRITICAL:    /* Critical input                         */
1195         srr0 = SPR_BOOKE_CSRR0;
1196         srr1 = SPR_BOOKE_CSRR1;
1197         break;
1198     case POWERPC_EXCP_MCHECK:    /* Machine check exception                  */
1199         if (msr_me == 0) {
1200             /*
1201              * Machine check exception is not enabled.  Enter
1202              * checkstop state.
1203              */
1204             fprintf(stderr, "Machine check while not allowed. "
1205                     "Entering checkstop state\n");
1206             if (qemu_log_separate()) {
1207                 qemu_log("Machine check while not allowed. "
1208                         "Entering checkstop state\n");
1209             }
1210             cs->halted = 1;
1211             cpu_interrupt_exittb(cs);
1212         }
1213 
1214         /* machine check exceptions don't have ME set */
1215         new_msr &= ~((target_ulong)1 << MSR_ME);
1216 
1217         /* FIXME: choose one or the other based on CPU type */
1218         srr0 = SPR_BOOKE_MCSRR0;
1219         srr1 = SPR_BOOKE_MCSRR1;
1220 
1221         env->spr[SPR_BOOKE_CSRR0] = env->nip;
1222         env->spr[SPR_BOOKE_CSRR1] = msr;
1223 
1224         break;
1225     case POWERPC_EXCP_DSI:       /* Data storage exception                   */
1226         trace_ppc_excp_dsi(env->spr[SPR_BOOKE_ESR], env->spr[SPR_BOOKE_DEAR]);
1227         break;
1228     case POWERPC_EXCP_ISI:       /* Instruction storage exception            */
1229         trace_ppc_excp_isi(msr, env->nip);
1230         break;
1231     case POWERPC_EXCP_EXTERNAL:  /* External input                           */
1232         if (env->mpic_proxy) {
1233             /* IACK the IRQ on delivery */
1234             env->spr[SPR_BOOKE_EPR] = ldl_phys(cs->as, env->mpic_iack);
1235         }
1236         break;
1237     case POWERPC_EXCP_ALIGN:     /* Alignment exception                      */
1238         break;
1239     case POWERPC_EXCP_PROGRAM:   /* Program exception                        */
1240         switch (env->error_code & ~0xF) {
1241         case POWERPC_EXCP_FP:
1242             if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) {
1243                 trace_ppc_excp_fp_ignore();
1244                 cs->exception_index = POWERPC_EXCP_NONE;
1245                 env->error_code = 0;
1246                 return;
1247             }
1248 
1249             /*
1250              * FP exceptions always have NIP pointing to the faulting
1251              * instruction, so always use store_next and claim we are
1252              * precise in the MSR.
1253              */
1254             msr |= 0x00100000;
1255             env->spr[SPR_BOOKE_ESR] = ESR_FP;
1256             break;
1257         case POWERPC_EXCP_INVAL:
1258             trace_ppc_excp_inval(env->nip);
1259             msr |= 0x00080000;
1260             env->spr[SPR_BOOKE_ESR] = ESR_PIL;
1261             break;
1262         case POWERPC_EXCP_PRIV:
1263             msr |= 0x00040000;
1264             env->spr[SPR_BOOKE_ESR] = ESR_PPR;
1265             break;
1266         case POWERPC_EXCP_TRAP:
1267             msr |= 0x00020000;
1268             env->spr[SPR_BOOKE_ESR] = ESR_PTR;
1269             break;
1270         default:
1271             /* Should never occur */
1272             cpu_abort(cs, "Invalid program exception %d. Aborting\n",
1273                       env->error_code);
1274             break;
1275         }
1276         break;
1277     case POWERPC_EXCP_SYSCALL:   /* System call exception                    */
1278         dump_syscall(env);
1279 
1280         /*
1281          * We need to correct the NIP which in this case is supposed
1282          * to point to the next instruction
1283          */
1284         env->nip += 4;
1285         break;
1286     case POWERPC_EXCP_FPU:       /* Floating-point unavailable exception     */
1287     case POWERPC_EXCP_APU:       /* Auxiliary processor unavailable          */
1288     case POWERPC_EXCP_DECR:      /* Decrementer exception                    */
1289         break;
1290     case POWERPC_EXCP_FIT:       /* Fixed-interval timer interrupt           */
1291         /* FIT on 4xx */
1292         trace_ppc_excp_print("FIT");
1293         break;
1294     case POWERPC_EXCP_WDT:       /* Watchdog timer interrupt                 */
1295         trace_ppc_excp_print("WDT");
1296         srr0 = SPR_BOOKE_CSRR0;
1297         srr1 = SPR_BOOKE_CSRR1;
1298         break;
1299     case POWERPC_EXCP_DTLB:      /* Data TLB error                           */
1300     case POWERPC_EXCP_ITLB:      /* Instruction TLB error                    */
1301         break;
1302     case POWERPC_EXCP_DEBUG:     /* Debug interrupt                          */
1303         if (env->flags & POWERPC_FLAG_DE) {
1304             /* FIXME: choose one or the other based on CPU type */
1305             srr0 = SPR_BOOKE_DSRR0;
1306             srr1 = SPR_BOOKE_DSRR1;
1307 
1308             env->spr[SPR_BOOKE_CSRR0] = env->nip;
1309             env->spr[SPR_BOOKE_CSRR1] = msr;
1310 
1311             /* DBSR already modified by caller */
1312         } else {
1313             cpu_abort(cs, "Debug exception triggered on unsupported model\n");
1314         }
1315         break;
1316     case POWERPC_EXCP_SPEU:   /* SPE/embedded floating-point unavailable/VPU  */
1317         env->spr[SPR_BOOKE_ESR] = ESR_SPV;
1318         break;
1319     case POWERPC_EXCP_RESET:     /* System reset exception                   */
1320         if (msr_pow) {
1321             cpu_abort(cs, "Trying to deliver power-saving system reset "
1322                       "exception %d with no HV support\n", excp);
1323         }
1324         break;
1325     case POWERPC_EXCP_EFPDI:     /* Embedded floating-point data interrupt   */
1326     case POWERPC_EXCP_EFPRI:     /* Embedded floating-point round interrupt  */
1327         cpu_abort(cs, "%s exception not implemented\n",
1328                   powerpc_excp_name(excp));
1329         break;
1330     default:
1331         cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
1332         break;
1333     }
1334 
1335     /* Sanity check */
1336     if (!(env->msr_mask & MSR_HVB)) {
1337         if (new_msr & MSR_HVB) {
1338             cpu_abort(cs, "Trying to deliver HV exception (MSR) %d with "
1339                       "no HV support\n", excp);
1340         }
1341         if (srr0 == SPR_HSRR0) {
1342             cpu_abort(cs, "Trying to deliver HV exception (HSRR) %d with "
1343                       "no HV support\n", excp);
1344         }
1345     }
1346 
1347 #if defined(TARGET_PPC64)
1348     if (env->spr[SPR_BOOKE_EPCR] & EPCR_ICM) {
1349         /* Cat.64-bit: EPCR.ICM is copied to MSR.CM */
1350         new_msr |= (target_ulong)1 << MSR_CM;
1351     } else {
1352         vector = (uint32_t)vector;
1353     }
1354 #endif
1355 
1356     /* Save PC */
1357     env->spr[srr0] = env->nip;
1358 
1359     /* Save MSR */
1360     env->spr[srr1] = msr;
1361 
1362     powerpc_set_excp_state(cpu, vector, new_msr);
1363 }
1364 
1365 #ifdef TARGET_PPC64
1366 static void powerpc_excp_books(PowerPCCPU *cpu, int excp)
1367 {
1368     CPUState *cs = CPU(cpu);
1369     CPUPPCState *env = &cpu->env;
1370     int excp_model = env->excp_model;
1371     target_ulong msr, new_msr, vector;
1372     int srr0, srr1, lev = -1;
1373 
1374     if (excp <= POWERPC_EXCP_NONE || excp >= POWERPC_EXCP_NB) {
1375         cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
1376     }
1377 
1378     qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx
1379                   " => %s (%d) error=%02x\n", env->nip, powerpc_excp_name(excp),
1380                   excp, env->error_code);
1381 
1382     /* new srr1 value excluding must-be-zero bits */
1383     msr = env->msr & ~0x783f0000ULL;
1384 
1385     /*
1386      * new interrupt handler msr preserves existing HV and ME unless
1387      * explicitly overriden
1388      */
1389     new_msr = env->msr & (((target_ulong)1 << MSR_ME) | MSR_HVB);
1390 
1391     /* target registers */
1392     srr0 = SPR_SRR0;
1393     srr1 = SPR_SRR1;
1394 
1395     /*
1396      * check for special resume at 0x100 from doze/nap/sleep/winkle on
1397      * P7/P8/P9
1398      */
1399     if (env->resume_as_sreset) {
1400         excp = powerpc_reset_wakeup(cs, env, excp, &msr);
1401     }
1402 
1403     /*
1404      * We don't want to generate a Hypervisor Emulation Assistance
1405      * Interrupt if we don't have HVB in msr_mask (PAPR mode).
1406      */
1407     if (excp == POWERPC_EXCP_HV_EMU && !(env->msr_mask & MSR_HVB)) {
1408         excp = POWERPC_EXCP_PROGRAM;
1409     }
1410 
1411     vector = env->excp_vectors[excp];
1412     if (vector == (target_ulong)-1ULL) {
1413         cpu_abort(cs, "Raised an exception without defined vector %d\n",
1414                   excp);
1415     }
1416 
1417     vector |= env->excp_prefix;
1418 
1419     switch (excp) {
1420     case POWERPC_EXCP_MCHECK:    /* Machine check exception                  */
1421         if (msr_me == 0) {
1422             /*
1423              * Machine check exception is not enabled.  Enter
1424              * checkstop state.
1425              */
1426             fprintf(stderr, "Machine check while not allowed. "
1427                     "Entering checkstop state\n");
1428             if (qemu_log_separate()) {
1429                 qemu_log("Machine check while not allowed. "
1430                         "Entering checkstop state\n");
1431             }
1432             cs->halted = 1;
1433             cpu_interrupt_exittb(cs);
1434         }
1435         if (env->msr_mask & MSR_HVB) {
1436             /*
1437              * ISA specifies HV, but can be delivered to guest with HV
1438              * clear (e.g., see FWNMI in PAPR).
1439              */
1440             new_msr |= (target_ulong)MSR_HVB;
1441         }
1442 
1443         /* machine check exceptions don't have ME set */
1444         new_msr &= ~((target_ulong)1 << MSR_ME);
1445 
1446         break;
1447     case POWERPC_EXCP_DSI:       /* Data storage exception                   */
1448         trace_ppc_excp_dsi(env->spr[SPR_DSISR], env->spr[SPR_DAR]);
1449         break;
1450     case POWERPC_EXCP_ISI:       /* Instruction storage exception            */
1451         trace_ppc_excp_isi(msr, env->nip);
1452         msr |= env->error_code;
1453         break;
1454     case POWERPC_EXCP_EXTERNAL:  /* External input                           */
1455     {
1456         bool lpes0;
1457 
1458         /*
1459          * LPES0 is only taken into consideration if we support HV
1460          * mode for this CPU.
1461          */
1462         if (!env->has_hv_mode) {
1463             break;
1464         }
1465 
1466         lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0);
1467 
1468         if (!lpes0) {
1469             new_msr |= (target_ulong)MSR_HVB;
1470             new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
1471             srr0 = SPR_HSRR0;
1472             srr1 = SPR_HSRR1;
1473         }
1474 
1475         break;
1476     }
1477     case POWERPC_EXCP_ALIGN:     /* Alignment exception                      */
1478         /* Get rS/rD and rA from faulting opcode */
1479         /*
1480          * Note: the opcode fields will not be set properly for a
1481          * direct store load/store, but nobody cares as nobody
1482          * actually uses direct store segments.
1483          */
1484         env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16;
1485         break;
1486     case POWERPC_EXCP_PROGRAM:   /* Program exception                        */
1487         switch (env->error_code & ~0xF) {
1488         case POWERPC_EXCP_FP:
1489             if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) {
1490                 trace_ppc_excp_fp_ignore();
1491                 cs->exception_index = POWERPC_EXCP_NONE;
1492                 env->error_code = 0;
1493                 return;
1494             }
1495 
1496             /*
1497              * FP exceptions always have NIP pointing to the faulting
1498              * instruction, so always use store_next and claim we are
1499              * precise in the MSR.
1500              */
1501             msr |= 0x00100000;
1502             break;
1503         case POWERPC_EXCP_INVAL:
1504             trace_ppc_excp_inval(env->nip);
1505             msr |= 0x00080000;
1506             break;
1507         case POWERPC_EXCP_PRIV:
1508             msr |= 0x00040000;
1509             break;
1510         case POWERPC_EXCP_TRAP:
1511             msr |= 0x00020000;
1512             break;
1513         default:
1514             /* Should never occur */
1515             cpu_abort(cs, "Invalid program exception %d. Aborting\n",
1516                       env->error_code);
1517             break;
1518         }
1519         break;
1520     case POWERPC_EXCP_SYSCALL:   /* System call exception                    */
1521         lev = env->error_code;
1522 
1523         if ((lev == 1) && cpu->vhyp) {
1524             dump_hcall(env);
1525         } else {
1526             dump_syscall(env);
1527         }
1528 
1529         /*
1530          * We need to correct the NIP which in this case is supposed
1531          * to point to the next instruction
1532          */
1533         env->nip += 4;
1534 
1535         /* "PAPR mode" built-in hypercall emulation */
1536         if ((lev == 1) && cpu->vhyp) {
1537             PPCVirtualHypervisorClass *vhc =
1538                 PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
1539             vhc->hypercall(cpu->vhyp, cpu);
1540             return;
1541         }
1542         if (lev == 1) {
1543             new_msr |= (target_ulong)MSR_HVB;
1544         }
1545         break;
1546     case POWERPC_EXCP_SYSCALL_VECTORED: /* scv exception                     */
1547         lev = env->error_code;
1548         dump_syscall(env);
1549         env->nip += 4;
1550         new_msr |= env->msr & ((target_ulong)1 << MSR_EE);
1551         new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
1552 
1553         vector += lev * 0x20;
1554 
1555         env->lr = env->nip;
1556         env->ctr = msr;
1557         break;
1558     case POWERPC_EXCP_FPU:       /* Floating-point unavailable exception     */
1559     case POWERPC_EXCP_DECR:      /* Decrementer exception                    */
1560         break;
1561     case POWERPC_EXCP_RESET:     /* System reset exception                   */
1562         /* A power-saving exception sets ME, otherwise it is unchanged */
1563         if (msr_pow) {
1564             /* indicate that we resumed from power save mode */
1565             msr |= 0x10000;
1566             new_msr |= ((target_ulong)1 << MSR_ME);
1567         }
1568         if (env->msr_mask & MSR_HVB) {
1569             /*
1570              * ISA specifies HV, but can be delivered to guest with HV
1571              * clear (e.g., see FWNMI in PAPR, NMI injection in QEMU).
1572              */
1573             new_msr |= (target_ulong)MSR_HVB;
1574         } else {
1575             if (msr_pow) {
1576                 cpu_abort(cs, "Trying to deliver power-saving system reset "
1577                           "exception %d with no HV support\n", excp);
1578             }
1579         }
1580         break;
1581     case POWERPC_EXCP_DSEG:      /* Data segment exception                   */
1582     case POWERPC_EXCP_ISEG:      /* Instruction segment exception            */
1583     case POWERPC_EXCP_TRACE:     /* Trace exception                          */
1584         break;
1585     case POWERPC_EXCP_HISI:      /* Hypervisor instruction storage exception */
1586         msr |= env->error_code;
1587         /* fall through */
1588     case POWERPC_EXCP_HDECR:     /* Hypervisor decrementer exception         */
1589     case POWERPC_EXCP_HDSI:      /* Hypervisor data storage exception        */
1590     case POWERPC_EXCP_SDOOR_HV:  /* Hypervisor Doorbell interrupt            */
1591     case POWERPC_EXCP_HV_EMU:
1592     case POWERPC_EXCP_HVIRT:     /* Hypervisor virtualization                */
1593         srr0 = SPR_HSRR0;
1594         srr1 = SPR_HSRR1;
1595         new_msr |= (target_ulong)MSR_HVB;
1596         new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
1597         break;
1598     case POWERPC_EXCP_VPU:       /* Vector unavailable exception             */
1599     case POWERPC_EXCP_VSXU:       /* VSX unavailable exception               */
1600     case POWERPC_EXCP_FU:         /* Facility unavailable exception          */
1601         env->spr[SPR_FSCR] |= ((target_ulong)env->error_code << 56);
1602         break;
1603     case POWERPC_EXCP_HV_FU:     /* Hypervisor Facility Unavailable Exception */
1604         env->spr[SPR_HFSCR] |= ((target_ulong)env->error_code << FSCR_IC_POS);
1605         srr0 = SPR_HSRR0;
1606         srr1 = SPR_HSRR1;
1607         new_msr |= (target_ulong)MSR_HVB;
1608         new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
1609         break;
1610     case POWERPC_EXCP_THERM:     /* Thermal interrupt                        */
1611     case POWERPC_EXCP_PERFM:     /* Embedded performance monitor interrupt   */
1612     case POWERPC_EXCP_VPUA:      /* Vector assist exception                  */
1613     case POWERPC_EXCP_MAINT:     /* Maintenance exception                    */
1614     case POWERPC_EXCP_SDOOR:     /* Doorbell interrupt                       */
1615     case POWERPC_EXCP_HV_MAINT:  /* Hypervisor Maintenance exception         */
1616         cpu_abort(cs, "%s exception not implemented\n",
1617                   powerpc_excp_name(excp));
1618         break;
1619     default:
1620         cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
1621         break;
1622     }
1623 
1624     /* Sanity check */
1625     if (!(env->msr_mask & MSR_HVB)) {
1626         if (new_msr & MSR_HVB) {
1627             cpu_abort(cs, "Trying to deliver HV exception (MSR) %d with "
1628                       "no HV support\n", excp);
1629         }
1630         if (srr0 == SPR_HSRR0) {
1631             cpu_abort(cs, "Trying to deliver HV exception (HSRR) %d with "
1632                       "no HV support\n", excp);
1633         }
1634     }
1635 
1636     /*
1637      * Sort out endianness of interrupt, this differs depending on the
1638      * CPU, the HV mode, etc...
1639      */
1640     if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) {
1641         new_msr |= (target_ulong)1 << MSR_LE;
1642     }
1643 
1644     new_msr |= (target_ulong)1 << MSR_SF;
1645 
1646     if (excp != POWERPC_EXCP_SYSCALL_VECTORED) {
1647         /* Save PC */
1648         env->spr[srr0] = env->nip;
1649 
1650         /* Save MSR */
1651         env->spr[srr1] = msr;
1652     }
1653 
1654     /* This can update new_msr and vector if AIL applies */
1655     ppc_excp_apply_ail(cpu, excp_model, excp, msr, &new_msr, &vector);
1656 
1657     powerpc_set_excp_state(cpu, vector, new_msr);
1658 }
1659 #else
1660 static inline void powerpc_excp_books(PowerPCCPU *cpu, int excp)
1661 {
1662     g_assert_not_reached();
1663 }
1664 #endif
1665 
1666 /*
1667  * Note that this function should be greatly optimized when called
1668  * with a constant excp, from ppc_hw_interrupt
1669  */
1670 static inline void powerpc_excp_legacy(PowerPCCPU *cpu, int excp)
1671 {
1672     CPUState *cs = CPU(cpu);
1673     CPUPPCState *env = &cpu->env;
1674     int excp_model = env->excp_model;
1675     target_ulong msr, new_msr, vector;
1676     int srr0, srr1, lev = -1;
1677 
1678     if (excp <= POWERPC_EXCP_NONE || excp >= POWERPC_EXCP_NB) {
1679         cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
1680     }
1681 
1682     qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx
1683                   " => %s (%d) error=%02x\n", env->nip, powerpc_excp_name(excp),
1684                   excp, env->error_code);
1685 
1686     /* new srr1 value excluding must-be-zero bits */
1687     if (excp_model == POWERPC_EXCP_BOOKE) {
1688         msr = env->msr;
1689     } else {
1690         msr = env->msr & ~0x783f0000ULL;
1691     }
1692 
1693     /*
1694      * new interrupt handler msr preserves existing HV and ME unless
1695      * explicitly overriden
1696      */
1697     new_msr = env->msr & (((target_ulong)1 << MSR_ME) | MSR_HVB);
1698 
1699     /* target registers */
1700     srr0 = SPR_SRR0;
1701     srr1 = SPR_SRR1;
1702 
1703     /*
1704      * check for special resume at 0x100 from doze/nap/sleep/winkle on
1705      * P7/P8/P9
1706      */
1707     if (env->resume_as_sreset) {
1708         excp = powerpc_reset_wakeup(cs, env, excp, &msr);
1709     }
1710 
1711     /*
1712      * Hypervisor emulation assistance interrupt only exists on server
1713      * arch 2.05 server or later. We also don't want to generate it if
1714      * we don't have HVB in msr_mask (PAPR mode).
1715      */
1716     if (excp == POWERPC_EXCP_HV_EMU
1717 #if defined(TARGET_PPC64)
1718         && !(mmu_is_64bit(env->mmu_model) && (env->msr_mask & MSR_HVB))
1719 #endif /* defined(TARGET_PPC64) */
1720 
1721     ) {
1722         excp = POWERPC_EXCP_PROGRAM;
1723     }
1724 
1725 #ifdef TARGET_PPC64
1726     /*
1727      * SPEU and VPU share the same IVOR but they exist in different
1728      * processors. SPEU is e500v1/2 only and VPU is e6500 only.
1729      */
1730     if (excp_model == POWERPC_EXCP_BOOKE && excp == POWERPC_EXCP_VPU) {
1731         excp = POWERPC_EXCP_SPEU;
1732     }
1733 #endif
1734 
1735     vector = env->excp_vectors[excp];
1736     if (vector == (target_ulong)-1ULL) {
1737         cpu_abort(cs, "Raised an exception without defined vector %d\n",
1738                   excp);
1739     }
1740 
1741     vector |= env->excp_prefix;
1742 
1743     switch (excp) {
1744     case POWERPC_EXCP_CRITICAL:    /* Critical input                         */
1745         switch (excp_model) {
1746         case POWERPC_EXCP_40x:
1747             srr0 = SPR_40x_SRR2;
1748             srr1 = SPR_40x_SRR3;
1749             break;
1750         case POWERPC_EXCP_BOOKE:
1751             srr0 = SPR_BOOKE_CSRR0;
1752             srr1 = SPR_BOOKE_CSRR1;
1753             break;
1754         case POWERPC_EXCP_6xx:
1755             break;
1756         default:
1757             goto excp_invalid;
1758         }
1759         break;
1760     case POWERPC_EXCP_MCHECK:    /* Machine check exception                  */
1761         if (msr_me == 0) {
1762             /*
1763              * Machine check exception is not enabled.  Enter
1764              * checkstop state.
1765              */
1766             fprintf(stderr, "Machine check while not allowed. "
1767                     "Entering checkstop state\n");
1768             if (qemu_log_separate()) {
1769                 qemu_log("Machine check while not allowed. "
1770                         "Entering checkstop state\n");
1771             }
1772             cs->halted = 1;
1773             cpu_interrupt_exittb(cs);
1774         }
1775         if (env->msr_mask & MSR_HVB) {
1776             /*
1777              * ISA specifies HV, but can be delivered to guest with HV
1778              * clear (e.g., see FWNMI in PAPR).
1779              */
1780             new_msr |= (target_ulong)MSR_HVB;
1781         }
1782 
1783         /* machine check exceptions don't have ME set */
1784         new_msr &= ~((target_ulong)1 << MSR_ME);
1785 
1786         /* XXX: should also have something loaded in DAR / DSISR */
1787         switch (excp_model) {
1788         case POWERPC_EXCP_40x:
1789             srr0 = SPR_40x_SRR2;
1790             srr1 = SPR_40x_SRR3;
1791             break;
1792         case POWERPC_EXCP_BOOKE:
1793             /* FIXME: choose one or the other based on CPU type */
1794             srr0 = SPR_BOOKE_MCSRR0;
1795             srr1 = SPR_BOOKE_MCSRR1;
1796 
1797             env->spr[SPR_BOOKE_CSRR0] = env->nip;
1798             env->spr[SPR_BOOKE_CSRR1] = msr;
1799             break;
1800         default:
1801             break;
1802         }
1803         break;
1804     case POWERPC_EXCP_DSI:       /* Data storage exception                   */
1805         trace_ppc_excp_dsi(env->spr[SPR_DSISR], env->spr[SPR_DAR]);
1806         break;
1807     case POWERPC_EXCP_ISI:       /* Instruction storage exception            */
1808         trace_ppc_excp_isi(msr, env->nip);
1809         msr |= env->error_code;
1810         break;
1811     case POWERPC_EXCP_EXTERNAL:  /* External input                           */
1812     {
1813         bool lpes0;
1814 
1815         cs = CPU(cpu);
1816 
1817         /*
1818          * Exception targeting modifiers
1819          *
1820          * LPES0 is supported on POWER7/8/9
1821          * LPES1 is not supported (old iSeries mode)
1822          *
1823          * On anything else, we behave as if LPES0 is 1
1824          * (externals don't alter MSR:HV)
1825          */
1826 #if defined(TARGET_PPC64)
1827         if (excp_model == POWERPC_EXCP_POWER7 ||
1828             excp_model == POWERPC_EXCP_POWER8 ||
1829             excp_model == POWERPC_EXCP_POWER9 ||
1830             excp_model == POWERPC_EXCP_POWER10) {
1831             lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0);
1832         } else
1833 #endif /* defined(TARGET_PPC64) */
1834         {
1835             lpes0 = true;
1836         }
1837 
1838         if (!lpes0) {
1839             new_msr |= (target_ulong)MSR_HVB;
1840             new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
1841             srr0 = SPR_HSRR0;
1842             srr1 = SPR_HSRR1;
1843         }
1844         if (env->mpic_proxy) {
1845             /* IACK the IRQ on delivery */
1846             env->spr[SPR_BOOKE_EPR] = ldl_phys(cs->as, env->mpic_iack);
1847         }
1848         break;
1849     }
1850     case POWERPC_EXCP_ALIGN:     /* Alignment exception                      */
1851         /* Get rS/rD and rA from faulting opcode */
1852         /*
1853          * Note: the opcode fields will not be set properly for a
1854          * direct store load/store, but nobody cares as nobody
1855          * actually uses direct store segments.
1856          */
1857         env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16;
1858         break;
1859     case POWERPC_EXCP_PROGRAM:   /* Program exception                        */
1860         switch (env->error_code & ~0xF) {
1861         case POWERPC_EXCP_FP:
1862             if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) {
1863                 trace_ppc_excp_fp_ignore();
1864                 cs->exception_index = POWERPC_EXCP_NONE;
1865                 env->error_code = 0;
1866                 return;
1867             }
1868 
1869             /*
1870              * FP exceptions always have NIP pointing to the faulting
1871              * instruction, so always use store_next and claim we are
1872              * precise in the MSR.
1873              */
1874             msr |= 0x00100000;
1875             env->spr[SPR_BOOKE_ESR] = ESR_FP;
1876             break;
1877         case POWERPC_EXCP_INVAL:
1878             trace_ppc_excp_inval(env->nip);
1879             msr |= 0x00080000;
1880             env->spr[SPR_BOOKE_ESR] = ESR_PIL;
1881             break;
1882         case POWERPC_EXCP_PRIV:
1883             msr |= 0x00040000;
1884             env->spr[SPR_BOOKE_ESR] = ESR_PPR;
1885             break;
1886         case POWERPC_EXCP_TRAP:
1887             msr |= 0x00020000;
1888             env->spr[SPR_BOOKE_ESR] = ESR_PTR;
1889             break;
1890         default:
1891             /* Should never occur */
1892             cpu_abort(cs, "Invalid program exception %d. Aborting\n",
1893                       env->error_code);
1894             break;
1895         }
1896         break;
1897     case POWERPC_EXCP_SYSCALL:   /* System call exception                    */
1898         lev = env->error_code;
1899 
1900         if ((lev == 1) && cpu->vhyp) {
1901             dump_hcall(env);
1902         } else {
1903             dump_syscall(env);
1904         }
1905 
1906         /*
1907          * We need to correct the NIP which in this case is supposed
1908          * to point to the next instruction
1909          */
1910         env->nip += 4;
1911 
1912         /* "PAPR mode" built-in hypercall emulation */
1913         if ((lev == 1) && cpu->vhyp) {
1914             PPCVirtualHypervisorClass *vhc =
1915                 PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
1916             vhc->hypercall(cpu->vhyp, cpu);
1917             return;
1918         }
1919         if (lev == 1) {
1920             new_msr |= (target_ulong)MSR_HVB;
1921         }
1922         break;
1923     case POWERPC_EXCP_SYSCALL_VECTORED: /* scv exception                     */
1924         lev = env->error_code;
1925         dump_syscall(env);
1926         env->nip += 4;
1927         new_msr |= env->msr & ((target_ulong)1 << MSR_EE);
1928         new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
1929 
1930         vector += lev * 0x20;
1931 
1932         env->lr = env->nip;
1933         env->ctr = msr;
1934         break;
1935     case POWERPC_EXCP_FPU:       /* Floating-point unavailable exception     */
1936     case POWERPC_EXCP_APU:       /* Auxiliary processor unavailable          */
1937     case POWERPC_EXCP_DECR:      /* Decrementer exception                    */
1938         break;
1939     case POWERPC_EXCP_FIT:       /* Fixed-interval timer interrupt           */
1940         /* FIT on 4xx */
1941         trace_ppc_excp_print("FIT");
1942         break;
1943     case POWERPC_EXCP_WDT:       /* Watchdog timer interrupt                 */
1944         trace_ppc_excp_print("WDT");
1945         switch (excp_model) {
1946         case POWERPC_EXCP_BOOKE:
1947             srr0 = SPR_BOOKE_CSRR0;
1948             srr1 = SPR_BOOKE_CSRR1;
1949             break;
1950         default:
1951             break;
1952         }
1953         break;
1954     case POWERPC_EXCP_DTLB:      /* Data TLB error                           */
1955     case POWERPC_EXCP_ITLB:      /* Instruction TLB error                    */
1956         break;
1957     case POWERPC_EXCP_DEBUG:     /* Debug interrupt                          */
1958         if (env->flags & POWERPC_FLAG_DE) {
1959             /* FIXME: choose one or the other based on CPU type */
1960             srr0 = SPR_BOOKE_DSRR0;
1961             srr1 = SPR_BOOKE_DSRR1;
1962 
1963             env->spr[SPR_BOOKE_CSRR0] = env->nip;
1964             env->spr[SPR_BOOKE_CSRR1] = msr;
1965 
1966             /* DBSR already modified by caller */
1967         } else {
1968             cpu_abort(cs, "Debug exception triggered on unsupported model\n");
1969         }
1970         break;
1971     case POWERPC_EXCP_SPEU:   /* SPE/embedded floating-point unavailable/VPU  */
1972         env->spr[SPR_BOOKE_ESR] = ESR_SPV;
1973         break;
1974     case POWERPC_EXCP_DOORI:     /* Embedded doorbell interrupt              */
1975         break;
1976     case POWERPC_EXCP_DOORCI:    /* Embedded doorbell critical interrupt     */
1977         srr0 = SPR_BOOKE_CSRR0;
1978         srr1 = SPR_BOOKE_CSRR1;
1979         break;
1980     case POWERPC_EXCP_RESET:     /* System reset exception                   */
1981         /* A power-saving exception sets ME, otherwise it is unchanged */
1982         if (msr_pow) {
1983             /* indicate that we resumed from power save mode */
1984             msr |= 0x10000;
1985             new_msr |= ((target_ulong)1 << MSR_ME);
1986         }
1987         if (env->msr_mask & MSR_HVB) {
1988             /*
1989              * ISA specifies HV, but can be delivered to guest with HV
1990              * clear (e.g., see FWNMI in PAPR, NMI injection in QEMU).
1991              */
1992             new_msr |= (target_ulong)MSR_HVB;
1993         } else {
1994             if (msr_pow) {
1995                 cpu_abort(cs, "Trying to deliver power-saving system reset "
1996                           "exception %d with no HV support\n", excp);
1997             }
1998         }
1999         break;
2000     case POWERPC_EXCP_DSEG:      /* Data segment exception                   */
2001     case POWERPC_EXCP_ISEG:      /* Instruction segment exception            */
2002     case POWERPC_EXCP_TRACE:     /* Trace exception                          */
2003         break;
2004     case POWERPC_EXCP_HISI:      /* Hypervisor instruction storage exception */
2005         msr |= env->error_code;
2006         /* fall through */
2007     case POWERPC_EXCP_HDECR:     /* Hypervisor decrementer exception         */
2008     case POWERPC_EXCP_HDSI:      /* Hypervisor data storage exception        */
2009     case POWERPC_EXCP_HDSEG:     /* Hypervisor data segment exception        */
2010     case POWERPC_EXCP_HISEG:     /* Hypervisor instruction segment exception */
2011     case POWERPC_EXCP_SDOOR_HV:  /* Hypervisor Doorbell interrupt            */
2012     case POWERPC_EXCP_HV_EMU:
2013     case POWERPC_EXCP_HVIRT:     /* Hypervisor virtualization                */
2014         srr0 = SPR_HSRR0;
2015         srr1 = SPR_HSRR1;
2016         new_msr |= (target_ulong)MSR_HVB;
2017         new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
2018         break;
2019     case POWERPC_EXCP_VPU:       /* Vector unavailable exception             */
2020     case POWERPC_EXCP_VSXU:       /* VSX unavailable exception               */
2021     case POWERPC_EXCP_FU:         /* Facility unavailable exception          */
2022 #ifdef TARGET_PPC64
2023         env->spr[SPR_FSCR] |= ((target_ulong)env->error_code << 56);
2024 #endif
2025         break;
2026     case POWERPC_EXCP_HV_FU:     /* Hypervisor Facility Unavailable Exception */
2027 #ifdef TARGET_PPC64
2028         env->spr[SPR_HFSCR] |= ((target_ulong)env->error_code << FSCR_IC_POS);
2029         srr0 = SPR_HSRR0;
2030         srr1 = SPR_HSRR1;
2031         new_msr |= (target_ulong)MSR_HVB;
2032         new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
2033 #endif
2034         break;
2035     case POWERPC_EXCP_PIT:       /* Programmable interval timer interrupt    */
2036         trace_ppc_excp_print("PIT");
2037         break;
2038     case POWERPC_EXCP_IFTLB:     /* Instruction fetch TLB error              */
2039     case POWERPC_EXCP_DLTLB:     /* Data load TLB miss                       */
2040     case POWERPC_EXCP_DSTLB:     /* Data store TLB miss                      */
2041         switch (excp_model) {
2042         case POWERPC_EXCP_6xx:
2043             /* Swap temporary saved registers with GPRs */
2044             if (!(new_msr & ((target_ulong)1 << MSR_TGPR))) {
2045                 new_msr |= (target_ulong)1 << MSR_TGPR;
2046                 hreg_swap_gpr_tgpr(env);
2047             }
2048             /* fall through */
2049         case POWERPC_EXCP_7xx:
2050             ppc_excp_debug_sw_tlb(env, excp);
2051 
2052             msr |= env->crf[0] << 28;
2053             msr |= env->error_code; /* key, D/I, S/L bits */
2054             /* Set way using a LRU mechanism */
2055             msr |= ((env->last_way + 1) & (env->nb_ways - 1)) << 17;
2056             break;
2057         default:
2058             cpu_abort(cs, "Invalid TLB miss exception\n");
2059             break;
2060         }
2061         break;
2062     case POWERPC_EXCP_EFPDI:     /* Embedded floating-point data interrupt   */
2063     case POWERPC_EXCP_EFPRI:     /* Embedded floating-point round interrupt  */
2064     case POWERPC_EXCP_EPERFM:    /* Embedded performance monitor interrupt   */
2065     case POWERPC_EXCP_FPA:       /* Floating-point assist exception          */
2066     case POWERPC_EXCP_DABR:      /* Data address breakpoint                  */
2067     case POWERPC_EXCP_IABR:      /* Instruction address breakpoint           */
2068     case POWERPC_EXCP_SMI:       /* System management interrupt              */
2069     case POWERPC_EXCP_THERM:     /* Thermal interrupt                        */
2070     case POWERPC_EXCP_PERFM:     /* Embedded performance monitor interrupt   */
2071     case POWERPC_EXCP_VPUA:      /* Vector assist exception                  */
2072     case POWERPC_EXCP_SOFTP:     /* Soft patch exception                     */
2073     case POWERPC_EXCP_MAINT:     /* Maintenance exception                    */
2074     case POWERPC_EXCP_MEXTBR:    /* Maskable external breakpoint             */
2075     case POWERPC_EXCP_NMEXTBR:   /* Non maskable external breakpoint         */
2076         cpu_abort(cs, "%s exception not implemented\n",
2077                   powerpc_excp_name(excp));
2078         break;
2079     default:
2080     excp_invalid:
2081         cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
2082         break;
2083     }
2084 
2085     /* Sanity check */
2086     if (!(env->msr_mask & MSR_HVB)) {
2087         if (new_msr & MSR_HVB) {
2088             cpu_abort(cs, "Trying to deliver HV exception (MSR) %d with "
2089                       "no HV support\n", excp);
2090         }
2091         if (srr0 == SPR_HSRR0) {
2092             cpu_abort(cs, "Trying to deliver HV exception (HSRR) %d with "
2093                       "no HV support\n", excp);
2094         }
2095     }
2096 
2097     /*
2098      * Sort out endianness of interrupt, this differs depending on the
2099      * CPU, the HV mode, etc...
2100      */
2101     if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) {
2102         new_msr |= (target_ulong)1 << MSR_LE;
2103     }
2104 
2105 #if defined(TARGET_PPC64)
2106     if (excp_model == POWERPC_EXCP_BOOKE) {
2107         if (env->spr[SPR_BOOKE_EPCR] & EPCR_ICM) {
2108             /* Cat.64-bit: EPCR.ICM is copied to MSR.CM */
2109             new_msr |= (target_ulong)1 << MSR_CM;
2110         } else {
2111             vector = (uint32_t)vector;
2112         }
2113     } else {
2114         if (!msr_isf && !mmu_is_64bit(env->mmu_model)) {
2115             vector = (uint32_t)vector;
2116         } else {
2117             new_msr |= (target_ulong)1 << MSR_SF;
2118         }
2119     }
2120 #endif
2121 
2122     if (excp != POWERPC_EXCP_SYSCALL_VECTORED) {
2123         /* Save PC */
2124         env->spr[srr0] = env->nip;
2125 
2126         /* Save MSR */
2127         env->spr[srr1] = msr;
2128     }
2129 
2130     /* This can update new_msr and vector if AIL applies */
2131     ppc_excp_apply_ail(cpu, excp_model, excp, msr, &new_msr, &vector);
2132 
2133     powerpc_set_excp_state(cpu, vector, new_msr);
2134 }
2135 
2136 static void powerpc_excp(PowerPCCPU *cpu, int excp)
2137 {
2138     CPUPPCState *env = &cpu->env;
2139 
2140     switch (env->excp_model) {
2141     case POWERPC_EXCP_40x:
2142         powerpc_excp_40x(cpu, excp);
2143         break;
2144     case POWERPC_EXCP_6xx:
2145         powerpc_excp_6xx(cpu, excp);
2146         break;
2147     case POWERPC_EXCP_7xx:
2148         powerpc_excp_7xx(cpu, excp);
2149         break;
2150     case POWERPC_EXCP_74xx:
2151         powerpc_excp_74xx(cpu, excp);
2152         break;
2153     case POWERPC_EXCP_BOOKE:
2154         powerpc_excp_booke(cpu, excp);
2155         break;
2156     case POWERPC_EXCP_970:
2157     case POWERPC_EXCP_POWER7:
2158     case POWERPC_EXCP_POWER8:
2159     case POWERPC_EXCP_POWER9:
2160     case POWERPC_EXCP_POWER10:
2161         powerpc_excp_books(cpu, excp);
2162         break;
2163     default:
2164         powerpc_excp_legacy(cpu, excp);
2165     }
2166 }
2167 
2168 void ppc_cpu_do_interrupt(CPUState *cs)
2169 {
2170     PowerPCCPU *cpu = POWERPC_CPU(cs);
2171 
2172     powerpc_excp(cpu, cs->exception_index);
2173 }
2174 
2175 static void ppc_hw_interrupt(CPUPPCState *env)
2176 {
2177     PowerPCCPU *cpu = env_archcpu(env);
2178     bool async_deliver;
2179 
2180     /* External reset */
2181     if (env->pending_interrupts & (1 << PPC_INTERRUPT_RESET)) {
2182         env->pending_interrupts &= ~(1 << PPC_INTERRUPT_RESET);
2183         powerpc_excp(cpu, POWERPC_EXCP_RESET);
2184         return;
2185     }
2186     /* Machine check exception */
2187     if (env->pending_interrupts & (1 << PPC_INTERRUPT_MCK)) {
2188         env->pending_interrupts &= ~(1 << PPC_INTERRUPT_MCK);
2189         powerpc_excp(cpu, POWERPC_EXCP_MCHECK);
2190         return;
2191     }
2192 #if 0 /* TODO */
2193     /* External debug exception */
2194     if (env->pending_interrupts & (1 << PPC_INTERRUPT_DEBUG)) {
2195         env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DEBUG);
2196         powerpc_excp(cpu, POWERPC_EXCP_DEBUG);
2197         return;
2198     }
2199 #endif
2200 
2201     /*
2202      * For interrupts that gate on MSR:EE, we need to do something a
2203      * bit more subtle, as we need to let them through even when EE is
2204      * clear when coming out of some power management states (in order
2205      * for them to become a 0x100).
2206      */
2207     async_deliver = (msr_ee != 0) || env->resume_as_sreset;
2208 
2209     /* Hypervisor decrementer exception */
2210     if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDECR)) {
2211         /* LPCR will be clear when not supported so this will work */
2212         bool hdice = !!(env->spr[SPR_LPCR] & LPCR_HDICE);
2213         if ((async_deliver || msr_hv == 0) && hdice) {
2214             /* HDEC clears on delivery */
2215             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDECR);
2216             powerpc_excp(cpu, POWERPC_EXCP_HDECR);
2217             return;
2218         }
2219     }
2220 
2221     /* Hypervisor virtualization interrupt */
2222     if (env->pending_interrupts & (1 << PPC_INTERRUPT_HVIRT)) {
2223         /* LPCR will be clear when not supported so this will work */
2224         bool hvice = !!(env->spr[SPR_LPCR] & LPCR_HVICE);
2225         if ((async_deliver || msr_hv == 0) && hvice) {
2226             powerpc_excp(cpu, POWERPC_EXCP_HVIRT);
2227             return;
2228         }
2229     }
2230 
2231     /* External interrupt can ignore MSR:EE under some circumstances */
2232     if (env->pending_interrupts & (1 << PPC_INTERRUPT_EXT)) {
2233         bool lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0);
2234         bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
2235         /* HEIC blocks delivery to the hypervisor */
2236         if ((async_deliver && !(heic && msr_hv && !msr_pr)) ||
2237             (env->has_hv_mode && msr_hv == 0 && !lpes0)) {
2238             powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL);
2239             return;
2240         }
2241     }
2242     if (msr_ce != 0) {
2243         /* External critical interrupt */
2244         if (env->pending_interrupts & (1 << PPC_INTERRUPT_CEXT)) {
2245             powerpc_excp(cpu, POWERPC_EXCP_CRITICAL);
2246             return;
2247         }
2248     }
2249     if (async_deliver != 0) {
2250         /* Watchdog timer on embedded PowerPC */
2251         if (env->pending_interrupts & (1 << PPC_INTERRUPT_WDT)) {
2252             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_WDT);
2253             powerpc_excp(cpu, POWERPC_EXCP_WDT);
2254             return;
2255         }
2256         if (env->pending_interrupts & (1 << PPC_INTERRUPT_CDOORBELL)) {
2257             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_CDOORBELL);
2258             powerpc_excp(cpu, POWERPC_EXCP_DOORCI);
2259             return;
2260         }
2261         /* Fixed interval timer on embedded PowerPC */
2262         if (env->pending_interrupts & (1 << PPC_INTERRUPT_FIT)) {
2263             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_FIT);
2264             powerpc_excp(cpu, POWERPC_EXCP_FIT);
2265             return;
2266         }
2267         /* Programmable interval timer on embedded PowerPC */
2268         if (env->pending_interrupts & (1 << PPC_INTERRUPT_PIT)) {
2269             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PIT);
2270             powerpc_excp(cpu, POWERPC_EXCP_PIT);
2271             return;
2272         }
2273         /* Decrementer exception */
2274         if (env->pending_interrupts & (1 << PPC_INTERRUPT_DECR)) {
2275             if (ppc_decr_clear_on_delivery(env)) {
2276                 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DECR);
2277             }
2278             powerpc_excp(cpu, POWERPC_EXCP_DECR);
2279             return;
2280         }
2281         if (env->pending_interrupts & (1 << PPC_INTERRUPT_DOORBELL)) {
2282             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL);
2283             if (is_book3s_arch2x(env)) {
2284                 powerpc_excp(cpu, POWERPC_EXCP_SDOOR);
2285             } else {
2286                 powerpc_excp(cpu, POWERPC_EXCP_DOORI);
2287             }
2288             return;
2289         }
2290         if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDOORBELL)) {
2291             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDOORBELL);
2292             powerpc_excp(cpu, POWERPC_EXCP_SDOOR_HV);
2293             return;
2294         }
2295         if (env->pending_interrupts & (1 << PPC_INTERRUPT_PERFM)) {
2296             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PERFM);
2297             powerpc_excp(cpu, POWERPC_EXCP_PERFM);
2298             return;
2299         }
2300         /* Thermal interrupt */
2301         if (env->pending_interrupts & (1 << PPC_INTERRUPT_THERM)) {
2302             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_THERM);
2303             powerpc_excp(cpu, POWERPC_EXCP_THERM);
2304             return;
2305         }
2306     }
2307 
2308     if (env->resume_as_sreset) {
2309         /*
2310          * This is a bug ! It means that has_work took us out of halt without
2311          * anything to deliver while in a PM state that requires getting
2312          * out via a 0x100
2313          *
2314          * This means we will incorrectly execute past the power management
2315          * instruction instead of triggering a reset.
2316          *
2317          * It generally means a discrepancy between the wakeup conditions in the
2318          * processor has_work implementation and the logic in this function.
2319          */
2320         cpu_abort(env_cpu(env),
2321                   "Wakeup from PM state but interrupt Undelivered");
2322     }
2323 }
2324 
2325 void ppc_cpu_do_system_reset(CPUState *cs)
2326 {
2327     PowerPCCPU *cpu = POWERPC_CPU(cs);
2328 
2329     powerpc_excp(cpu, POWERPC_EXCP_RESET);
2330 }
2331 
2332 void ppc_cpu_do_fwnmi_machine_check(CPUState *cs, target_ulong vector)
2333 {
2334     PowerPCCPU *cpu = POWERPC_CPU(cs);
2335     CPUPPCState *env = &cpu->env;
2336     target_ulong msr = 0;
2337 
2338     /*
2339      * Set MSR and NIP for the handler, SRR0/1, DAR and DSISR have already
2340      * been set by KVM.
2341      */
2342     msr = (1ULL << MSR_ME);
2343     msr |= env->msr & (1ULL << MSR_SF);
2344     if (ppc_interrupts_little_endian(cpu, false)) {
2345         msr |= (1ULL << MSR_LE);
2346     }
2347 
2348     powerpc_set_excp_state(cpu, vector, msr);
2349 }
2350 
2351 bool ppc_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
2352 {
2353     PowerPCCPU *cpu = POWERPC_CPU(cs);
2354     CPUPPCState *env = &cpu->env;
2355 
2356     if (interrupt_request & CPU_INTERRUPT_HARD) {
2357         ppc_hw_interrupt(env);
2358         if (env->pending_interrupts == 0) {
2359             cs->interrupt_request &= ~CPU_INTERRUPT_HARD;
2360         }
2361         return true;
2362     }
2363     return false;
2364 }
2365 
2366 #endif /* !CONFIG_USER_ONLY */
2367 
2368 /*****************************************************************************/
2369 /* Exceptions processing helpers */
2370 
2371 void raise_exception_err_ra(CPUPPCState *env, uint32_t exception,
2372                             uint32_t error_code, uintptr_t raddr)
2373 {
2374     CPUState *cs = env_cpu(env);
2375 
2376     cs->exception_index = exception;
2377     env->error_code = error_code;
2378     cpu_loop_exit_restore(cs, raddr);
2379 }
2380 
2381 void raise_exception_err(CPUPPCState *env, uint32_t exception,
2382                          uint32_t error_code)
2383 {
2384     raise_exception_err_ra(env, exception, error_code, 0);
2385 }
2386 
2387 void raise_exception(CPUPPCState *env, uint32_t exception)
2388 {
2389     raise_exception_err_ra(env, exception, 0, 0);
2390 }
2391 
2392 void raise_exception_ra(CPUPPCState *env, uint32_t exception,
2393                         uintptr_t raddr)
2394 {
2395     raise_exception_err_ra(env, exception, 0, raddr);
2396 }
2397 
2398 #ifdef CONFIG_TCG
2399 void helper_raise_exception_err(CPUPPCState *env, uint32_t exception,
2400                                 uint32_t error_code)
2401 {
2402     raise_exception_err_ra(env, exception, error_code, 0);
2403 }
2404 
2405 void helper_raise_exception(CPUPPCState *env, uint32_t exception)
2406 {
2407     raise_exception_err_ra(env, exception, 0, 0);
2408 }
2409 #endif
2410 
2411 #if !defined(CONFIG_USER_ONLY)
2412 #ifdef CONFIG_TCG
2413 void helper_store_msr(CPUPPCState *env, target_ulong val)
2414 {
2415     uint32_t excp = hreg_store_msr(env, val, 0);
2416 
2417     if (excp != 0) {
2418         CPUState *cs = env_cpu(env);
2419         cpu_interrupt_exittb(cs);
2420         raise_exception(env, excp);
2421     }
2422 }
2423 
2424 #if defined(TARGET_PPC64)
2425 void helper_scv(CPUPPCState *env, uint32_t lev)
2426 {
2427     if (env->spr[SPR_FSCR] & (1ull << FSCR_SCV)) {
2428         raise_exception_err(env, POWERPC_EXCP_SYSCALL_VECTORED, lev);
2429     } else {
2430         raise_exception_err(env, POWERPC_EXCP_FU, FSCR_IC_SCV);
2431     }
2432 }
2433 
2434 void helper_pminsn(CPUPPCState *env, powerpc_pm_insn_t insn)
2435 {
2436     CPUState *cs;
2437 
2438     cs = env_cpu(env);
2439     cs->halted = 1;
2440 
2441     /* Condition for waking up at 0x100 */
2442     env->resume_as_sreset = (insn != PPC_PM_STOP) ||
2443         (env->spr[SPR_PSSCR] & PSSCR_EC);
2444 }
2445 #endif /* defined(TARGET_PPC64) */
2446 
2447 static void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr)
2448 {
2449     CPUState *cs = env_cpu(env);
2450 
2451     /* MSR:POW cannot be set by any form of rfi */
2452     msr &= ~(1ULL << MSR_POW);
2453 
2454     /* MSR:TGPR cannot be set by any form of rfi */
2455     if (env->flags & POWERPC_FLAG_TGPR)
2456         msr &= ~(1ULL << MSR_TGPR);
2457 
2458 #if defined(TARGET_PPC64)
2459     /* Switching to 32-bit ? Crop the nip */
2460     if (!msr_is_64bit(env, msr)) {
2461         nip = (uint32_t)nip;
2462     }
2463 #else
2464     nip = (uint32_t)nip;
2465 #endif
2466     /* XXX: beware: this is false if VLE is supported */
2467     env->nip = nip & ~((target_ulong)0x00000003);
2468     hreg_store_msr(env, msr, 1);
2469     trace_ppc_excp_rfi(env->nip, env->msr);
2470     /*
2471      * No need to raise an exception here, as rfi is always the last
2472      * insn of a TB
2473      */
2474     cpu_interrupt_exittb(cs);
2475     /* Reset the reservation */
2476     env->reserve_addr = -1;
2477 
2478     /* Context synchronizing: check if TCG TLB needs flush */
2479     check_tlb_flush(env, false);
2480 }
2481 
2482 void helper_rfi(CPUPPCState *env)
2483 {
2484     do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1] & 0xfffffffful);
2485 }
2486 
2487 #define MSR_BOOK3S_MASK
2488 #if defined(TARGET_PPC64)
2489 void helper_rfid(CPUPPCState *env)
2490 {
2491     /*
2492      * The architecture defines a number of rules for which bits can
2493      * change but in practice, we handle this in hreg_store_msr()
2494      * which will be called by do_rfi(), so there is no need to filter
2495      * here
2496      */
2497     do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1]);
2498 }
2499 
2500 void helper_rfscv(CPUPPCState *env)
2501 {
2502     do_rfi(env, env->lr, env->ctr);
2503 }
2504 
2505 void helper_hrfid(CPUPPCState *env)
2506 {
2507     do_rfi(env, env->spr[SPR_HSRR0], env->spr[SPR_HSRR1]);
2508 }
2509 #endif
2510 
2511 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
2512 void helper_rfebb(CPUPPCState *env, target_ulong s)
2513 {
2514     target_ulong msr = env->msr;
2515 
2516     /*
2517      * Handling of BESCR bits 32:33 according to PowerISA v3.1:
2518      *
2519      * "If BESCR 32:33 != 0b00 the instruction is treated as if
2520      *  the instruction form were invalid."
2521      */
2522     if (env->spr[SPR_BESCR] & BESCR_INVALID) {
2523         raise_exception_err(env, POWERPC_EXCP_PROGRAM,
2524                             POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL);
2525     }
2526 
2527     env->nip = env->spr[SPR_EBBRR];
2528 
2529     /* Switching to 32-bit ? Crop the nip */
2530     if (!msr_is_64bit(env, msr)) {
2531         env->nip = (uint32_t)env->spr[SPR_EBBRR];
2532     }
2533 
2534     if (s) {
2535         env->spr[SPR_BESCR] |= BESCR_GE;
2536     } else {
2537         env->spr[SPR_BESCR] &= ~BESCR_GE;
2538     }
2539 }
2540 #endif
2541 
2542 /*****************************************************************************/
2543 /* Embedded PowerPC specific helpers */
2544 void helper_40x_rfci(CPUPPCState *env)
2545 {
2546     do_rfi(env, env->spr[SPR_40x_SRR2], env->spr[SPR_40x_SRR3]);
2547 }
2548 
2549 void helper_rfci(CPUPPCState *env)
2550 {
2551     do_rfi(env, env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1]);
2552 }
2553 
2554 void helper_rfdi(CPUPPCState *env)
2555 {
2556     /* FIXME: choose CSRR1 or DSRR1 based on cpu type */
2557     do_rfi(env, env->spr[SPR_BOOKE_DSRR0], env->spr[SPR_BOOKE_DSRR1]);
2558 }
2559 
2560 void helper_rfmci(CPUPPCState *env)
2561 {
2562     /* FIXME: choose CSRR1 or MCSRR1 based on cpu type */
2563     do_rfi(env, env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1]);
2564 }
2565 #endif /* CONFIG_TCG */
2566 #endif /* !defined(CONFIG_USER_ONLY) */
2567 
2568 #ifdef CONFIG_TCG
2569 void helper_tw(CPUPPCState *env, target_ulong arg1, target_ulong arg2,
2570                uint32_t flags)
2571 {
2572     if (!likely(!(((int32_t)arg1 < (int32_t)arg2 && (flags & 0x10)) ||
2573                   ((int32_t)arg1 > (int32_t)arg2 && (flags & 0x08)) ||
2574                   ((int32_t)arg1 == (int32_t)arg2 && (flags & 0x04)) ||
2575                   ((uint32_t)arg1 < (uint32_t)arg2 && (flags & 0x02)) ||
2576                   ((uint32_t)arg1 > (uint32_t)arg2 && (flags & 0x01))))) {
2577         raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
2578                                POWERPC_EXCP_TRAP, GETPC());
2579     }
2580 }
2581 
2582 #if defined(TARGET_PPC64)
2583 void helper_td(CPUPPCState *env, target_ulong arg1, target_ulong arg2,
2584                uint32_t flags)
2585 {
2586     if (!likely(!(((int64_t)arg1 < (int64_t)arg2 && (flags & 0x10)) ||
2587                   ((int64_t)arg1 > (int64_t)arg2 && (flags & 0x08)) ||
2588                   ((int64_t)arg1 == (int64_t)arg2 && (flags & 0x04)) ||
2589                   ((uint64_t)arg1 < (uint64_t)arg2 && (flags & 0x02)) ||
2590                   ((uint64_t)arg1 > (uint64_t)arg2 && (flags & 0x01))))) {
2591         raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
2592                                POWERPC_EXCP_TRAP, GETPC());
2593     }
2594 }
2595 #endif
2596 #endif
2597 
2598 #if !defined(CONFIG_USER_ONLY)
2599 
2600 #ifdef CONFIG_TCG
2601 
2602 /* Embedded.Processor Control */
2603 static int dbell2irq(target_ulong rb)
2604 {
2605     int msg = rb & DBELL_TYPE_MASK;
2606     int irq = -1;
2607 
2608     switch (msg) {
2609     case DBELL_TYPE_DBELL:
2610         irq = PPC_INTERRUPT_DOORBELL;
2611         break;
2612     case DBELL_TYPE_DBELL_CRIT:
2613         irq = PPC_INTERRUPT_CDOORBELL;
2614         break;
2615     case DBELL_TYPE_G_DBELL:
2616     case DBELL_TYPE_G_DBELL_CRIT:
2617     case DBELL_TYPE_G_DBELL_MC:
2618         /* XXX implement */
2619     default:
2620         break;
2621     }
2622 
2623     return irq;
2624 }
2625 
2626 void helper_msgclr(CPUPPCState *env, target_ulong rb)
2627 {
2628     int irq = dbell2irq(rb);
2629 
2630     if (irq < 0) {
2631         return;
2632     }
2633 
2634     env->pending_interrupts &= ~(1 << irq);
2635 }
2636 
2637 void helper_msgsnd(target_ulong rb)
2638 {
2639     int irq = dbell2irq(rb);
2640     int pir = rb & DBELL_PIRTAG_MASK;
2641     CPUState *cs;
2642 
2643     if (irq < 0) {
2644         return;
2645     }
2646 
2647     qemu_mutex_lock_iothread();
2648     CPU_FOREACH(cs) {
2649         PowerPCCPU *cpu = POWERPC_CPU(cs);
2650         CPUPPCState *cenv = &cpu->env;
2651 
2652         if ((rb & DBELL_BRDCAST) || (cenv->spr[SPR_BOOKE_PIR] == pir)) {
2653             cenv->pending_interrupts |= 1 << irq;
2654             cpu_interrupt(cs, CPU_INTERRUPT_HARD);
2655         }
2656     }
2657     qemu_mutex_unlock_iothread();
2658 }
2659 
2660 /* Server Processor Control */
2661 
2662 static bool dbell_type_server(target_ulong rb)
2663 {
2664     /*
2665      * A Directed Hypervisor Doorbell message is sent only if the
2666      * message type is 5. All other types are reserved and the
2667      * instruction is a no-op
2668      */
2669     return (rb & DBELL_TYPE_MASK) == DBELL_TYPE_DBELL_SERVER;
2670 }
2671 
2672 void helper_book3s_msgclr(CPUPPCState *env, target_ulong rb)
2673 {
2674     if (!dbell_type_server(rb)) {
2675         return;
2676     }
2677 
2678     env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDOORBELL);
2679 }
2680 
2681 static void book3s_msgsnd_common(int pir, int irq)
2682 {
2683     CPUState *cs;
2684 
2685     qemu_mutex_lock_iothread();
2686     CPU_FOREACH(cs) {
2687         PowerPCCPU *cpu = POWERPC_CPU(cs);
2688         CPUPPCState *cenv = &cpu->env;
2689 
2690         /* TODO: broadcast message to all threads of the same  processor */
2691         if (cenv->spr_cb[SPR_PIR].default_value == pir) {
2692             cenv->pending_interrupts |= 1 << irq;
2693             cpu_interrupt(cs, CPU_INTERRUPT_HARD);
2694         }
2695     }
2696     qemu_mutex_unlock_iothread();
2697 }
2698 
2699 void helper_book3s_msgsnd(target_ulong rb)
2700 {
2701     int pir = rb & DBELL_PROCIDTAG_MASK;
2702 
2703     if (!dbell_type_server(rb)) {
2704         return;
2705     }
2706 
2707     book3s_msgsnd_common(pir, PPC_INTERRUPT_HDOORBELL);
2708 }
2709 
2710 #if defined(TARGET_PPC64)
2711 void helper_book3s_msgclrp(CPUPPCState *env, target_ulong rb)
2712 {
2713     helper_hfscr_facility_check(env, HFSCR_MSGP, "msgclrp", HFSCR_IC_MSGP);
2714 
2715     if (!dbell_type_server(rb)) {
2716         return;
2717     }
2718 
2719     env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL);
2720 }
2721 
2722 /*
2723  * sends a message to other threads that are on the same
2724  * multi-threaded processor
2725  */
2726 void helper_book3s_msgsndp(CPUPPCState *env, target_ulong rb)
2727 {
2728     int pir = env->spr_cb[SPR_PIR].default_value;
2729 
2730     helper_hfscr_facility_check(env, HFSCR_MSGP, "msgsndp", HFSCR_IC_MSGP);
2731 
2732     if (!dbell_type_server(rb)) {
2733         return;
2734     }
2735 
2736     /* TODO: TCG supports only one thread */
2737 
2738     book3s_msgsnd_common(pir, PPC_INTERRUPT_DOORBELL);
2739 }
2740 #endif /* TARGET_PPC64 */
2741 
2742 void ppc_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
2743                                  MMUAccessType access_type,
2744                                  int mmu_idx, uintptr_t retaddr)
2745 {
2746     CPUPPCState *env = cs->env_ptr;
2747     uint32_t insn;
2748 
2749     /* Restore state and reload the insn we executed, for filling in DSISR.  */
2750     cpu_restore_state(cs, retaddr, true);
2751     insn = cpu_ldl_code(env, env->nip);
2752 
2753     switch (env->mmu_model) {
2754     case POWERPC_MMU_SOFT_4xx:
2755         env->spr[SPR_40x_DEAR] = vaddr;
2756         break;
2757     case POWERPC_MMU_BOOKE:
2758     case POWERPC_MMU_BOOKE206:
2759         env->spr[SPR_BOOKE_DEAR] = vaddr;
2760         break;
2761     default:
2762         env->spr[SPR_DAR] = vaddr;
2763         break;
2764     }
2765 
2766     cs->exception_index = POWERPC_EXCP_ALIGN;
2767     env->error_code = insn & 0x03FF0000;
2768     cpu_loop_exit(cs);
2769 }
2770 #endif /* CONFIG_TCG */
2771 #endif /* !CONFIG_USER_ONLY */
2772