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