xref: /openbmc/qemu/target/ppc/excp_helper.c (revision ef17dd6a)
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 #if defined(TARGET_PPC64)
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, target_ulong msr,
266                                target_ulong *new_msr, target_ulong *vector)
267 {
268     PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
269     CPUPPCState *env = &cpu->env;
270     bool mmu_all_on = ((msr >> MSR_IR) & 1) && ((msr >> MSR_DR) & 1);
271     bool hv_escalation = !(msr & MSR_HVB) && (*new_msr & MSR_HVB);
272     int ail = 0;
273 
274     if (excp == POWERPC_EXCP_MCHECK ||
275         excp == POWERPC_EXCP_RESET ||
276         excp == POWERPC_EXCP_HV_MAINT) {
277         /* SRESET, MCE, HMI never apply AIL */
278         return;
279     }
280 
281     if (!(pcc->lpcr_mask & LPCR_AIL)) {
282         /* This CPU does not have AIL */
283         return;
284     }
285 
286     /* P8 & P9 */
287     if (!(pcc->lpcr_mask & LPCR_HAIL)) {
288         if (!mmu_all_on) {
289             /* AIL only works if MSR[IR] and MSR[DR] are both enabled. */
290             return;
291         }
292         if (hv_escalation && !(env->spr[SPR_LPCR] & LPCR_HR)) {
293             /*
294              * AIL does not work if there is a MSR[HV] 0->1 transition and the
295              * partition is in HPT mode. For radix guests, such interrupts are
296              * allowed to be delivered to the hypervisor in ail mode.
297              */
298             return;
299         }
300 
301         ail = (env->spr[SPR_LPCR] & LPCR_AIL) >> LPCR_AIL_SHIFT;
302         if (ail == 0) {
303             return;
304         }
305         if (ail == 1) {
306             /* AIL=1 is reserved, treat it like AIL=0 */
307             return;
308         }
309 
310     /* P10 and up */
311     } else {
312         if (!mmu_all_on && !hv_escalation) {
313             /*
314              * AIL works for HV interrupts even with guest MSR[IR/DR] disabled.
315              * Guest->guest and HV->HV interrupts do require MMU on.
316              */
317             return;
318         }
319 
320         if (*new_msr & MSR_HVB) {
321             if (!(env->spr[SPR_LPCR] & LPCR_HAIL)) {
322                 /* HV interrupts depend on LPCR[HAIL] */
323                 return;
324             }
325             ail = 3; /* HAIL=1 gives AIL=3 behaviour for HV interrupts */
326         } else {
327             ail = (env->spr[SPR_LPCR] & LPCR_AIL) >> LPCR_AIL_SHIFT;
328         }
329         if (ail == 0) {
330             return;
331         }
332         if (ail == 1 || ail == 2) {
333             /* AIL=1 and AIL=2 are reserved, treat them like AIL=0 */
334             return;
335         }
336     }
337 
338     /*
339      * AIL applies, so the new MSR gets IR and DR set, and an offset applied
340      * to the new IP.
341      */
342     *new_msr |= (1 << MSR_IR) | (1 << MSR_DR);
343 
344     if (excp != POWERPC_EXCP_SYSCALL_VECTORED) {
345         if (ail == 2) {
346             *vector |= 0x0000000000018000ull;
347         } else if (ail == 3) {
348             *vector |= 0xc000000000004000ull;
349         }
350     } else {
351         /*
352          * scv AIL is a little different. AIL=2 does not change the address,
353          * only the MSR. AIL=3 replaces the 0x17000 base with 0xc...3000.
354          */
355         if (ail == 3) {
356             *vector &= ~0x0000000000017000ull; /* Un-apply the base offset */
357             *vector |= 0xc000000000003000ull; /* Apply scv's AIL=3 offset */
358         }
359     }
360 }
361 #endif
362 
363 static void powerpc_set_excp_state(PowerPCCPU *cpu,
364                                           target_ulong vector, target_ulong msr)
365 {
366     CPUState *cs = CPU(cpu);
367     CPUPPCState *env = &cpu->env;
368 
369     assert((msr & env->msr_mask) == msr);
370 
371     /*
372      * We don't use hreg_store_msr here as already have treated any
373      * special case that could occur. Just store MSR and update hflags
374      *
375      * Note: We *MUST* not use hreg_store_msr() as-is anyway because it
376      * will prevent setting of the HV bit which some exceptions might need
377      * to do.
378      */
379     env->msr = msr;
380     hreg_compute_hflags(env);
381     env->nip = vector;
382     /* Reset exception state */
383     cs->exception_index = POWERPC_EXCP_NONE;
384     env->error_code = 0;
385 
386     /* Reset the reservation */
387     env->reserve_addr = -1;
388 
389     /*
390      * Any interrupt is context synchronizing, check if TCG TLB needs
391      * a delayed flush on ppc64
392      */
393     check_tlb_flush(env, false);
394 }
395 
396 static void powerpc_excp_40x(PowerPCCPU *cpu, int excp)
397 {
398     CPUState *cs = CPU(cpu);
399     CPUPPCState *env = &cpu->env;
400     target_ulong msr, new_msr, vector;
401     int srr0, srr1;
402 
403     /* new srr1 value excluding must-be-zero bits */
404     msr = env->msr & ~0x783f0000ULL;
405 
406     /*
407      * new interrupt handler msr preserves existing ME unless
408      * explicitly overriden.
409      */
410     new_msr = env->msr & (((target_ulong)1 << MSR_ME));
411 
412     /* target registers */
413     srr0 = SPR_SRR0;
414     srr1 = SPR_SRR1;
415 
416     /*
417      * Hypervisor emulation assistance interrupt only exists on server
418      * arch 2.05 server or later.
419      */
420     if (excp == POWERPC_EXCP_HV_EMU) {
421         excp = POWERPC_EXCP_PROGRAM;
422     }
423 
424     vector = env->excp_vectors[excp];
425     if (vector == (target_ulong)-1ULL) {
426         cpu_abort(cs, "Raised an exception without defined vector %d\n",
427                   excp);
428     }
429 
430     vector |= env->excp_prefix;
431 
432     switch (excp) {
433     case POWERPC_EXCP_CRITICAL:    /* Critical input                         */
434         srr0 = SPR_40x_SRR2;
435         srr1 = SPR_40x_SRR3;
436         break;
437     case POWERPC_EXCP_MCHECK:    /* Machine check exception                  */
438         if (msr_me == 0) {
439             /*
440              * Machine check exception is not enabled.  Enter
441              * checkstop state.
442              */
443             fprintf(stderr, "Machine check while not allowed. "
444                     "Entering checkstop state\n");
445             if (qemu_log_separate()) {
446                 qemu_log("Machine check while not allowed. "
447                         "Entering checkstop state\n");
448             }
449             cs->halted = 1;
450             cpu_interrupt_exittb(cs);
451         }
452 
453         /* machine check exceptions don't have ME set */
454         new_msr &= ~((target_ulong)1 << MSR_ME);
455 
456         srr0 = SPR_40x_SRR2;
457         srr1 = SPR_40x_SRR3;
458         break;
459     case POWERPC_EXCP_DSI:       /* Data storage exception                   */
460         trace_ppc_excp_dsi(env->spr[SPR_40x_ESR], env->spr[SPR_40x_DEAR]);
461         break;
462     case POWERPC_EXCP_ISI:       /* Instruction storage exception            */
463         trace_ppc_excp_isi(msr, env->nip);
464         break;
465     case POWERPC_EXCP_EXTERNAL:  /* External input                           */
466         break;
467     case POWERPC_EXCP_ALIGN:     /* Alignment exception                      */
468         break;
469     case POWERPC_EXCP_PROGRAM:   /* Program exception                        */
470         switch (env->error_code & ~0xF) {
471         case POWERPC_EXCP_FP:
472             if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) {
473                 trace_ppc_excp_fp_ignore();
474                 cs->exception_index = POWERPC_EXCP_NONE;
475                 env->error_code = 0;
476                 return;
477             }
478             env->spr[SPR_40x_ESR] = ESR_FP;
479             break;
480         case POWERPC_EXCP_INVAL:
481             trace_ppc_excp_inval(env->nip);
482             env->spr[SPR_40x_ESR] = ESR_PIL;
483             break;
484         case POWERPC_EXCP_PRIV:
485             env->spr[SPR_40x_ESR] = ESR_PPR;
486             break;
487         case POWERPC_EXCP_TRAP:
488             env->spr[SPR_40x_ESR] = ESR_PTR;
489             break;
490         default:
491             cpu_abort(cs, "Invalid program exception %d. Aborting\n",
492                       env->error_code);
493             break;
494         }
495         break;
496     case POWERPC_EXCP_SYSCALL:   /* System call exception                    */
497         dump_syscall(env);
498 
499         /*
500          * We need to correct the NIP which in this case is supposed
501          * to point to the next instruction
502          */
503         env->nip += 4;
504         break;
505     case POWERPC_EXCP_FIT:       /* Fixed-interval timer interrupt           */
506         trace_ppc_excp_print("FIT");
507         break;
508     case POWERPC_EXCP_WDT:       /* Watchdog timer interrupt                 */
509         trace_ppc_excp_print("WDT");
510         break;
511     case POWERPC_EXCP_DTLB:      /* Data TLB error                           */
512     case POWERPC_EXCP_ITLB:      /* Instruction TLB error                    */
513         break;
514     case POWERPC_EXCP_PIT:       /* Programmable interval timer interrupt    */
515         trace_ppc_excp_print("PIT");
516         break;
517     case POWERPC_EXCP_DEBUG:     /* Debug interrupt                          */
518         cpu_abort(cs, "%s exception not implemented\n",
519                   powerpc_excp_name(excp));
520         break;
521     default:
522         cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
523         break;
524     }
525 
526     /* Save PC */
527     env->spr[srr0] = env->nip;
528 
529     /* Save MSR */
530     env->spr[srr1] = msr;
531 
532     powerpc_set_excp_state(cpu, vector, new_msr);
533 }
534 
535 static void powerpc_excp_6xx(PowerPCCPU *cpu, int excp)
536 {
537     CPUState *cs = CPU(cpu);
538     CPUPPCState *env = &cpu->env;
539     target_ulong msr, new_msr, vector;
540 
541     /* new srr1 value excluding must-be-zero bits */
542     msr = env->msr & ~0x783f0000ULL;
543 
544     /*
545      * new interrupt handler msr preserves existing ME unless
546      * explicitly overriden
547      */
548     new_msr = env->msr & ((target_ulong)1 << MSR_ME);
549 
550     /*
551      * Hypervisor emulation assistance interrupt only exists on server
552      * arch 2.05 server or later.
553      */
554     if (excp == POWERPC_EXCP_HV_EMU) {
555         excp = POWERPC_EXCP_PROGRAM;
556     }
557 
558     vector = env->excp_vectors[excp];
559     if (vector == (target_ulong)-1ULL) {
560         cpu_abort(cs, "Raised an exception without defined vector %d\n",
561                   excp);
562     }
563 
564     vector |= env->excp_prefix;
565 
566     switch (excp) {
567     case POWERPC_EXCP_CRITICAL:    /* Critical input                         */
568         break;
569     case POWERPC_EXCP_MCHECK:    /* Machine check exception                  */
570         if (msr_me == 0) {
571             /*
572              * Machine check exception is not enabled.  Enter
573              * checkstop state.
574              */
575             fprintf(stderr, "Machine check while not allowed. "
576                     "Entering checkstop state\n");
577             if (qemu_log_separate()) {
578                 qemu_log("Machine check while not allowed. "
579                         "Entering checkstop state\n");
580             }
581             cs->halted = 1;
582             cpu_interrupt_exittb(cs);
583         }
584 
585         /* machine check exceptions don't have ME set */
586         new_msr &= ~((target_ulong)1 << MSR_ME);
587 
588         break;
589     case POWERPC_EXCP_DSI:       /* Data storage exception                   */
590         trace_ppc_excp_dsi(env->spr[SPR_DSISR], env->spr[SPR_DAR]);
591         break;
592     case POWERPC_EXCP_ISI:       /* Instruction storage exception            */
593         trace_ppc_excp_isi(msr, env->nip);
594         msr |= env->error_code;
595         break;
596     case POWERPC_EXCP_EXTERNAL:  /* External input                           */
597         break;
598     case POWERPC_EXCP_ALIGN:     /* Alignment exception                      */
599         /* Get rS/rD and rA from faulting opcode */
600         /*
601          * Note: the opcode fields will not be set properly for a
602          * direct store load/store, but nobody cares as nobody
603          * actually uses direct store segments.
604          */
605         env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16;
606         break;
607     case POWERPC_EXCP_PROGRAM:   /* Program exception                        */
608         switch (env->error_code & ~0xF) {
609         case POWERPC_EXCP_FP:
610             if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) {
611                 trace_ppc_excp_fp_ignore();
612                 cs->exception_index = POWERPC_EXCP_NONE;
613                 env->error_code = 0;
614                 return;
615             }
616 
617             /*
618              * FP exceptions always have NIP pointing to the faulting
619              * instruction, so always use store_next and claim we are
620              * precise in the MSR.
621              */
622             msr |= 0x00100000;
623             break;
624         case POWERPC_EXCP_INVAL:
625             trace_ppc_excp_inval(env->nip);
626             msr |= 0x00080000;
627             break;
628         case POWERPC_EXCP_PRIV:
629             msr |= 0x00040000;
630             break;
631         case POWERPC_EXCP_TRAP:
632             msr |= 0x00020000;
633             break;
634         default:
635             /* Should never occur */
636             cpu_abort(cs, "Invalid program exception %d. Aborting\n",
637                       env->error_code);
638             break;
639         }
640         break;
641     case POWERPC_EXCP_SYSCALL:   /* System call exception                    */
642         dump_syscall(env);
643 
644         /*
645          * We need to correct the NIP which in this case is supposed
646          * to point to the next instruction
647          */
648         env->nip += 4;
649         break;
650     case POWERPC_EXCP_FPU:       /* Floating-point unavailable exception     */
651     case POWERPC_EXCP_DECR:      /* Decrementer exception                    */
652         break;
653     case POWERPC_EXCP_DTLB:      /* Data TLB error                           */
654     case POWERPC_EXCP_ITLB:      /* Instruction TLB error                    */
655         break;
656     case POWERPC_EXCP_RESET:     /* System reset exception                   */
657         if (msr_pow) {
658             cpu_abort(cs, "Trying to deliver power-saving system reset "
659                       "exception %d with no HV support\n", excp);
660         }
661         break;
662     case POWERPC_EXCP_TRACE:     /* Trace exception                          */
663         break;
664     case POWERPC_EXCP_IFTLB:     /* Instruction fetch TLB error              */
665     case POWERPC_EXCP_DLTLB:     /* Data load TLB miss                       */
666     case POWERPC_EXCP_DSTLB:     /* Data store TLB miss                      */
667         /* Swap temporary saved registers with GPRs */
668         if (!(new_msr & ((target_ulong)1 << MSR_TGPR))) {
669             new_msr |= (target_ulong)1 << MSR_TGPR;
670             hreg_swap_gpr_tgpr(env);
671         }
672 
673         ppc_excp_debug_sw_tlb(env, excp);
674 
675         msr |= env->crf[0] << 28;
676         msr |= env->error_code; /* key, D/I, S/L bits */
677         /* Set way using a LRU mechanism */
678         msr |= ((env->last_way + 1) & (env->nb_ways - 1)) << 17;
679         break;
680     case POWERPC_EXCP_FPA:       /* Floating-point assist exception          */
681     case POWERPC_EXCP_DABR:      /* Data address breakpoint                  */
682     case POWERPC_EXCP_IABR:      /* Instruction address breakpoint           */
683     case POWERPC_EXCP_SMI:       /* System management interrupt              */
684     case POWERPC_EXCP_MEXTBR:    /* Maskable external breakpoint             */
685     case POWERPC_EXCP_NMEXTBR:   /* Non maskable external breakpoint         */
686         cpu_abort(cs, "%s exception not implemented\n",
687                   powerpc_excp_name(excp));
688         break;
689     default:
690         cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
691         break;
692     }
693 
694     /*
695      * Sort out endianness of interrupt, this differs depending on the
696      * CPU, the HV mode, etc...
697      */
698     if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) {
699         new_msr |= (target_ulong)1 << MSR_LE;
700     }
701 
702     /* Save PC */
703     env->spr[SPR_SRR0] = env->nip;
704 
705     /* Save MSR */
706     env->spr[SPR_SRR1] = msr;
707 
708     powerpc_set_excp_state(cpu, vector, new_msr);
709 }
710 
711 static void powerpc_excp_7xx(PowerPCCPU *cpu, int excp)
712 {
713     CPUState *cs = CPU(cpu);
714     CPUPPCState *env = &cpu->env;
715     target_ulong msr, new_msr, vector;
716 
717     /* new srr1 value excluding must-be-zero bits */
718     msr = env->msr & ~0x783f0000ULL;
719 
720     /*
721      * new interrupt handler msr preserves existing ME unless
722      * explicitly overriden
723      */
724     new_msr = env->msr & ((target_ulong)1 << MSR_ME);
725 
726     /*
727      * Hypervisor emulation assistance interrupt only exists on server
728      * arch 2.05 server or later.
729      */
730     if (excp == POWERPC_EXCP_HV_EMU) {
731         excp = POWERPC_EXCP_PROGRAM;
732     }
733 
734     vector = env->excp_vectors[excp];
735     if (vector == (target_ulong)-1ULL) {
736         cpu_abort(cs, "Raised an exception without defined vector %d\n",
737                   excp);
738     }
739 
740     vector |= env->excp_prefix;
741 
742     switch (excp) {
743     case POWERPC_EXCP_MCHECK:    /* Machine check exception                  */
744         if (msr_me == 0) {
745             /*
746              * Machine check exception is not enabled.  Enter
747              * checkstop state.
748              */
749             fprintf(stderr, "Machine check while not allowed. "
750                     "Entering checkstop state\n");
751             if (qemu_log_separate()) {
752                 qemu_log("Machine check while not allowed. "
753                         "Entering checkstop state\n");
754             }
755             cs->halted = 1;
756             cpu_interrupt_exittb(cs);
757         }
758 
759         /* machine check exceptions don't have ME set */
760         new_msr &= ~((target_ulong)1 << MSR_ME);
761 
762         break;
763     case POWERPC_EXCP_DSI:       /* Data storage exception                   */
764         trace_ppc_excp_dsi(env->spr[SPR_DSISR], env->spr[SPR_DAR]);
765         break;
766     case POWERPC_EXCP_ISI:       /* Instruction storage exception            */
767         trace_ppc_excp_isi(msr, env->nip);
768         msr |= env->error_code;
769         break;
770     case POWERPC_EXCP_EXTERNAL:  /* External input                           */
771         break;
772     case POWERPC_EXCP_ALIGN:     /* Alignment exception                      */
773         /* Get rS/rD and rA from faulting opcode */
774         /*
775          * Note: the opcode fields will not be set properly for a
776          * direct store load/store, but nobody cares as nobody
777          * actually uses direct store segments.
778          */
779         env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16;
780         break;
781     case POWERPC_EXCP_PROGRAM:   /* Program exception                        */
782         switch (env->error_code & ~0xF) {
783         case POWERPC_EXCP_FP:
784             if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) {
785                 trace_ppc_excp_fp_ignore();
786                 cs->exception_index = POWERPC_EXCP_NONE;
787                 env->error_code = 0;
788                 return;
789             }
790 
791             /*
792              * FP exceptions always have NIP pointing to the faulting
793              * instruction, so always use store_next and claim we are
794              * precise in the MSR.
795              */
796             msr |= 0x00100000;
797             break;
798         case POWERPC_EXCP_INVAL:
799             trace_ppc_excp_inval(env->nip);
800             msr |= 0x00080000;
801             break;
802         case POWERPC_EXCP_PRIV:
803             msr |= 0x00040000;
804             break;
805         case POWERPC_EXCP_TRAP:
806             msr |= 0x00020000;
807             break;
808         default:
809             /* Should never occur */
810             cpu_abort(cs, "Invalid program exception %d. Aborting\n",
811                       env->error_code);
812             break;
813         }
814         break;
815     case POWERPC_EXCP_SYSCALL:   /* System call exception                    */
816     {
817         int lev = env->error_code;
818 
819         if (lev == 1 && cpu->vhyp) {
820             dump_hcall(env);
821         } else {
822             dump_syscall(env);
823         }
824 
825         /*
826          * We need to correct the NIP which in this case is supposed
827          * to point to the next instruction
828          */
829         env->nip += 4;
830 
831         /*
832          * The Virtual Open Firmware (VOF) relies on the 'sc 1'
833          * instruction to communicate with QEMU. The pegasos2 machine
834          * uses VOF and the 7xx CPUs, so although the 7xx don't have
835          * HV mode, we need to keep hypercall support.
836          */
837         if (lev == 1 && cpu->vhyp) {
838             PPCVirtualHypervisorClass *vhc =
839                 PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
840             vhc->hypercall(cpu->vhyp, cpu);
841             return;
842         }
843 
844         break;
845     }
846     case POWERPC_EXCP_FPU:       /* Floating-point unavailable exception     */
847     case POWERPC_EXCP_DECR:      /* Decrementer exception                    */
848         break;
849     case POWERPC_EXCP_RESET:     /* System reset exception                   */
850         if (msr_pow) {
851             cpu_abort(cs, "Trying to deliver power-saving system reset "
852                       "exception %d with no HV support\n", excp);
853         }
854         break;
855     case POWERPC_EXCP_TRACE:     /* Trace exception                          */
856         break;
857     case POWERPC_EXCP_IFTLB:     /* Instruction fetch TLB error              */
858     case POWERPC_EXCP_DLTLB:     /* Data load TLB miss                       */
859     case POWERPC_EXCP_DSTLB:     /* Data store TLB miss                      */
860         ppc_excp_debug_sw_tlb(env, excp);
861 
862         msr |= env->crf[0] << 28;
863         msr |= env->error_code; /* key, D/I, S/L bits */
864         /* Set way using a LRU mechanism */
865         msr |= ((env->last_way + 1) & (env->nb_ways - 1)) << 17;
866 
867         break;
868     case POWERPC_EXCP_IABR:      /* Instruction address breakpoint           */
869     case POWERPC_EXCP_SMI:       /* System management interrupt              */
870     case POWERPC_EXCP_THERM:     /* Thermal interrupt                        */
871     case POWERPC_EXCP_PERFM:     /* Embedded performance monitor interrupt   */
872         cpu_abort(cs, "%s exception not implemented\n",
873                   powerpc_excp_name(excp));
874         break;
875     default:
876         cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
877         break;
878     }
879 
880     /*
881      * Sort out endianness of interrupt, this differs depending on the
882      * CPU, the HV mode, etc...
883      */
884     if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) {
885         new_msr |= (target_ulong)1 << MSR_LE;
886     }
887 
888     /* Save PC */
889     env->spr[SPR_SRR0] = env->nip;
890 
891     /* Save MSR */
892     env->spr[SPR_SRR1] = msr;
893 
894     powerpc_set_excp_state(cpu, vector, new_msr);
895 }
896 
897 static void powerpc_excp_74xx(PowerPCCPU *cpu, int excp)
898 {
899     CPUState *cs = CPU(cpu);
900     CPUPPCState *env = &cpu->env;
901     target_ulong msr, new_msr, vector;
902 
903     /* new srr1 value excluding must-be-zero bits */
904     msr = env->msr & ~0x783f0000ULL;
905 
906     /*
907      * new interrupt handler msr preserves existing ME unless
908      * explicitly overriden
909      */
910     new_msr = env->msr & ((target_ulong)1 << MSR_ME);
911 
912     /*
913      * Hypervisor emulation assistance interrupt only exists on server
914      * arch 2.05 server or later.
915      */
916     if (excp == POWERPC_EXCP_HV_EMU) {
917         excp = POWERPC_EXCP_PROGRAM;
918     }
919 
920     vector = env->excp_vectors[excp];
921     if (vector == (target_ulong)-1ULL) {
922         cpu_abort(cs, "Raised an exception without defined vector %d\n",
923                   excp);
924     }
925 
926     vector |= env->excp_prefix;
927 
928     switch (excp) {
929     case POWERPC_EXCP_MCHECK:    /* Machine check exception                  */
930         if (msr_me == 0) {
931             /*
932              * Machine check exception is not enabled.  Enter
933              * checkstop state.
934              */
935             fprintf(stderr, "Machine check while not allowed. "
936                     "Entering checkstop state\n");
937             if (qemu_log_separate()) {
938                 qemu_log("Machine check while not allowed. "
939                         "Entering checkstop state\n");
940             }
941             cs->halted = 1;
942             cpu_interrupt_exittb(cs);
943         }
944 
945         /* machine check exceptions don't have ME set */
946         new_msr &= ~((target_ulong)1 << MSR_ME);
947 
948         break;
949     case POWERPC_EXCP_DSI:       /* Data storage exception                   */
950         trace_ppc_excp_dsi(env->spr[SPR_DSISR], env->spr[SPR_DAR]);
951         break;
952     case POWERPC_EXCP_ISI:       /* Instruction storage exception            */
953         trace_ppc_excp_isi(msr, env->nip);
954         msr |= env->error_code;
955         break;
956     case POWERPC_EXCP_EXTERNAL:  /* External input                           */
957         break;
958     case POWERPC_EXCP_ALIGN:     /* Alignment exception                      */
959         /* Get rS/rD and rA from faulting opcode */
960         /*
961          * Note: the opcode fields will not be set properly for a
962          * direct store load/store, but nobody cares as nobody
963          * actually uses direct store segments.
964          */
965         env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16;
966         break;
967     case POWERPC_EXCP_PROGRAM:   /* Program exception                        */
968         switch (env->error_code & ~0xF) {
969         case POWERPC_EXCP_FP:
970             if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) {
971                 trace_ppc_excp_fp_ignore();
972                 cs->exception_index = POWERPC_EXCP_NONE;
973                 env->error_code = 0;
974                 return;
975             }
976 
977             /*
978              * FP exceptions always have NIP pointing to the faulting
979              * instruction, so always use store_next and claim we are
980              * precise in the MSR.
981              */
982             msr |= 0x00100000;
983             break;
984         case POWERPC_EXCP_INVAL:
985             trace_ppc_excp_inval(env->nip);
986             msr |= 0x00080000;
987             break;
988         case POWERPC_EXCP_PRIV:
989             msr |= 0x00040000;
990             break;
991         case POWERPC_EXCP_TRAP:
992             msr |= 0x00020000;
993             break;
994         default:
995             /* Should never occur */
996             cpu_abort(cs, "Invalid program exception %d. Aborting\n",
997                       env->error_code);
998             break;
999         }
1000         break;
1001     case POWERPC_EXCP_SYSCALL:   /* System call exception                    */
1002     {
1003         int lev = env->error_code;
1004 
1005         if ((lev == 1) && cpu->vhyp) {
1006             dump_hcall(env);
1007         } else {
1008             dump_syscall(env);
1009         }
1010 
1011         /*
1012          * We need to correct the NIP which in this case is supposed
1013          * to point to the next instruction
1014          */
1015         env->nip += 4;
1016 
1017         /*
1018          * The Virtual Open Firmware (VOF) relies on the 'sc 1'
1019          * instruction to communicate with QEMU. The pegasos2 machine
1020          * uses VOF and the 74xx CPUs, so although the 74xx don't have
1021          * HV mode, we need to keep hypercall support.
1022          */
1023         if ((lev == 1) && cpu->vhyp) {
1024             PPCVirtualHypervisorClass *vhc =
1025                 PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
1026             vhc->hypercall(cpu->vhyp, cpu);
1027             return;
1028         }
1029 
1030         break;
1031     }
1032     case POWERPC_EXCP_FPU:       /* Floating-point unavailable exception     */
1033     case POWERPC_EXCP_DECR:      /* Decrementer exception                    */
1034         break;
1035     case POWERPC_EXCP_RESET:     /* System reset exception                   */
1036         if (msr_pow) {
1037             cpu_abort(cs, "Trying to deliver power-saving system reset "
1038                       "exception %d with no HV support\n", excp);
1039         }
1040         break;
1041     case POWERPC_EXCP_TRACE:     /* Trace exception                          */
1042         break;
1043     case POWERPC_EXCP_VPU:       /* Vector unavailable exception             */
1044         break;
1045     case POWERPC_EXCP_IABR:      /* Instruction address breakpoint           */
1046     case POWERPC_EXCP_SMI:       /* System management interrupt              */
1047     case POWERPC_EXCP_THERM:     /* Thermal interrupt                        */
1048     case POWERPC_EXCP_PERFM:     /* Embedded performance monitor interrupt   */
1049     case POWERPC_EXCP_VPUA:      /* Vector assist exception                  */
1050         cpu_abort(cs, "%s exception not implemented\n",
1051                   powerpc_excp_name(excp));
1052         break;
1053     default:
1054         cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
1055         break;
1056     }
1057 
1058     /*
1059      * Sort out endianness of interrupt, this differs depending on the
1060      * CPU, the HV mode, etc...
1061      */
1062     if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) {
1063         new_msr |= (target_ulong)1 << MSR_LE;
1064     }
1065 
1066     /* Save PC */
1067     env->spr[SPR_SRR0] = env->nip;
1068 
1069     /* Save MSR */
1070     env->spr[SPR_SRR1] = msr;
1071 
1072     powerpc_set_excp_state(cpu, vector, new_msr);
1073 }
1074 
1075 static void powerpc_excp_booke(PowerPCCPU *cpu, int excp)
1076 {
1077     CPUState *cs = CPU(cpu);
1078     CPUPPCState *env = &cpu->env;
1079     target_ulong msr, new_msr, vector;
1080     int srr0, srr1;
1081 
1082     msr = env->msr;
1083 
1084     /*
1085      * new interrupt handler msr preserves existing ME unless
1086      * explicitly overriden
1087      */
1088     new_msr = env->msr & ((target_ulong)1 << MSR_ME);
1089 
1090     /* target registers */
1091     srr0 = SPR_SRR0;
1092     srr1 = SPR_SRR1;
1093 
1094     /*
1095      * Hypervisor emulation assistance interrupt only exists on server
1096      * arch 2.05 server or later.
1097      */
1098     if (excp == POWERPC_EXCP_HV_EMU) {
1099         excp = POWERPC_EXCP_PROGRAM;
1100     }
1101 
1102 #ifdef TARGET_PPC64
1103     /*
1104      * SPEU and VPU share the same IVOR but they exist in different
1105      * processors. SPEU is e500v1/2 only and VPU is e6500 only.
1106      */
1107     if (excp == POWERPC_EXCP_VPU) {
1108         excp = POWERPC_EXCP_SPEU;
1109     }
1110 #endif
1111 
1112     vector = env->excp_vectors[excp];
1113     if (vector == (target_ulong)-1ULL) {
1114         cpu_abort(cs, "Raised an exception without defined vector %d\n",
1115                   excp);
1116     }
1117 
1118     vector |= env->excp_prefix;
1119 
1120     switch (excp) {
1121     case POWERPC_EXCP_CRITICAL:    /* Critical input                         */
1122         srr0 = SPR_BOOKE_CSRR0;
1123         srr1 = SPR_BOOKE_CSRR1;
1124         break;
1125     case POWERPC_EXCP_MCHECK:    /* Machine check exception                  */
1126         if (msr_me == 0) {
1127             /*
1128              * Machine check exception is not enabled.  Enter
1129              * checkstop state.
1130              */
1131             fprintf(stderr, "Machine check while not allowed. "
1132                     "Entering checkstop state\n");
1133             if (qemu_log_separate()) {
1134                 qemu_log("Machine check while not allowed. "
1135                         "Entering checkstop state\n");
1136             }
1137             cs->halted = 1;
1138             cpu_interrupt_exittb(cs);
1139         }
1140 
1141         /* machine check exceptions don't have ME set */
1142         new_msr &= ~((target_ulong)1 << MSR_ME);
1143 
1144         /* FIXME: choose one or the other based on CPU type */
1145         srr0 = SPR_BOOKE_MCSRR0;
1146         srr1 = SPR_BOOKE_MCSRR1;
1147 
1148         env->spr[SPR_BOOKE_CSRR0] = env->nip;
1149         env->spr[SPR_BOOKE_CSRR1] = msr;
1150 
1151         break;
1152     case POWERPC_EXCP_DSI:       /* Data storage exception                   */
1153         trace_ppc_excp_dsi(env->spr[SPR_BOOKE_ESR], env->spr[SPR_BOOKE_DEAR]);
1154         break;
1155     case POWERPC_EXCP_ISI:       /* Instruction storage exception            */
1156         trace_ppc_excp_isi(msr, env->nip);
1157         break;
1158     case POWERPC_EXCP_EXTERNAL:  /* External input                           */
1159         if (env->mpic_proxy) {
1160             /* IACK the IRQ on delivery */
1161             env->spr[SPR_BOOKE_EPR] = ldl_phys(cs->as, env->mpic_iack);
1162         }
1163         break;
1164     case POWERPC_EXCP_ALIGN:     /* Alignment exception                      */
1165         break;
1166     case POWERPC_EXCP_PROGRAM:   /* Program exception                        */
1167         switch (env->error_code & ~0xF) {
1168         case POWERPC_EXCP_FP:
1169             if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) {
1170                 trace_ppc_excp_fp_ignore();
1171                 cs->exception_index = POWERPC_EXCP_NONE;
1172                 env->error_code = 0;
1173                 return;
1174             }
1175 
1176             /*
1177              * FP exceptions always have NIP pointing to the faulting
1178              * instruction, so always use store_next and claim we are
1179              * precise in the MSR.
1180              */
1181             msr |= 0x00100000;
1182             env->spr[SPR_BOOKE_ESR] = ESR_FP;
1183             break;
1184         case POWERPC_EXCP_INVAL:
1185             trace_ppc_excp_inval(env->nip);
1186             msr |= 0x00080000;
1187             env->spr[SPR_BOOKE_ESR] = ESR_PIL;
1188             break;
1189         case POWERPC_EXCP_PRIV:
1190             msr |= 0x00040000;
1191             env->spr[SPR_BOOKE_ESR] = ESR_PPR;
1192             break;
1193         case POWERPC_EXCP_TRAP:
1194             msr |= 0x00020000;
1195             env->spr[SPR_BOOKE_ESR] = ESR_PTR;
1196             break;
1197         default:
1198             /* Should never occur */
1199             cpu_abort(cs, "Invalid program exception %d. Aborting\n",
1200                       env->error_code);
1201             break;
1202         }
1203         break;
1204     case POWERPC_EXCP_SYSCALL:   /* System call exception                    */
1205         dump_syscall(env);
1206 
1207         /*
1208          * We need to correct the NIP which in this case is supposed
1209          * to point to the next instruction
1210          */
1211         env->nip += 4;
1212         break;
1213     case POWERPC_EXCP_FPU:       /* Floating-point unavailable exception     */
1214     case POWERPC_EXCP_APU:       /* Auxiliary processor unavailable          */
1215     case POWERPC_EXCP_DECR:      /* Decrementer exception                    */
1216         break;
1217     case POWERPC_EXCP_FIT:       /* Fixed-interval timer interrupt           */
1218         /* FIT on 4xx */
1219         trace_ppc_excp_print("FIT");
1220         break;
1221     case POWERPC_EXCP_WDT:       /* Watchdog timer interrupt                 */
1222         trace_ppc_excp_print("WDT");
1223         srr0 = SPR_BOOKE_CSRR0;
1224         srr1 = SPR_BOOKE_CSRR1;
1225         break;
1226     case POWERPC_EXCP_DTLB:      /* Data TLB error                           */
1227     case POWERPC_EXCP_ITLB:      /* Instruction TLB error                    */
1228         break;
1229     case POWERPC_EXCP_DEBUG:     /* Debug interrupt                          */
1230         if (env->flags & POWERPC_FLAG_DE) {
1231             /* FIXME: choose one or the other based on CPU type */
1232             srr0 = SPR_BOOKE_DSRR0;
1233             srr1 = SPR_BOOKE_DSRR1;
1234 
1235             env->spr[SPR_BOOKE_CSRR0] = env->nip;
1236             env->spr[SPR_BOOKE_CSRR1] = msr;
1237 
1238             /* DBSR already modified by caller */
1239         } else {
1240             cpu_abort(cs, "Debug exception triggered on unsupported model\n");
1241         }
1242         break;
1243     case POWERPC_EXCP_SPEU:   /* SPE/embedded floating-point unavailable/VPU  */
1244         env->spr[SPR_BOOKE_ESR] = ESR_SPV;
1245         break;
1246     case POWERPC_EXCP_RESET:     /* System reset exception                   */
1247         if (msr_pow) {
1248             cpu_abort(cs, "Trying to deliver power-saving system reset "
1249                       "exception %d with no HV support\n", excp);
1250         }
1251         break;
1252     case POWERPC_EXCP_EFPDI:     /* Embedded floating-point data interrupt   */
1253     case POWERPC_EXCP_EFPRI:     /* Embedded floating-point round interrupt  */
1254         cpu_abort(cs, "%s exception not implemented\n",
1255                   powerpc_excp_name(excp));
1256         break;
1257     default:
1258         cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
1259         break;
1260     }
1261 
1262 #if defined(TARGET_PPC64)
1263     if (env->spr[SPR_BOOKE_EPCR] & EPCR_ICM) {
1264         /* Cat.64-bit: EPCR.ICM is copied to MSR.CM */
1265         new_msr |= (target_ulong)1 << MSR_CM;
1266     } else {
1267         vector = (uint32_t)vector;
1268     }
1269 #endif
1270 
1271     /* Save PC */
1272     env->spr[srr0] = env->nip;
1273 
1274     /* Save MSR */
1275     env->spr[srr1] = msr;
1276 
1277     powerpc_set_excp_state(cpu, vector, new_msr);
1278 }
1279 
1280 #ifdef TARGET_PPC64
1281 static void powerpc_excp_books(PowerPCCPU *cpu, int excp)
1282 {
1283     CPUState *cs = CPU(cpu);
1284     CPUPPCState *env = &cpu->env;
1285     target_ulong msr, new_msr, vector;
1286     int srr0, srr1, lev = -1;
1287 
1288     /* new srr1 value excluding must-be-zero bits */
1289     msr = env->msr & ~0x783f0000ULL;
1290 
1291     /*
1292      * new interrupt handler msr preserves existing HV and ME unless
1293      * explicitly overriden
1294      */
1295     new_msr = env->msr & (((target_ulong)1 << MSR_ME) | MSR_HVB);
1296 
1297     /* target registers */
1298     srr0 = SPR_SRR0;
1299     srr1 = SPR_SRR1;
1300 
1301     /*
1302      * check for special resume at 0x100 from doze/nap/sleep/winkle on
1303      * P7/P8/P9
1304      */
1305     if (env->resume_as_sreset) {
1306         excp = powerpc_reset_wakeup(cs, env, excp, &msr);
1307     }
1308 
1309     /*
1310      * We don't want to generate a Hypervisor Emulation Assistance
1311      * Interrupt if we don't have HVB in msr_mask (PAPR mode).
1312      */
1313     if (excp == POWERPC_EXCP_HV_EMU && !(env->msr_mask & MSR_HVB)) {
1314         excp = POWERPC_EXCP_PROGRAM;
1315     }
1316 
1317     vector = env->excp_vectors[excp];
1318     if (vector == (target_ulong)-1ULL) {
1319         cpu_abort(cs, "Raised an exception without defined vector %d\n",
1320                   excp);
1321     }
1322 
1323     vector |= env->excp_prefix;
1324 
1325     switch (excp) {
1326     case POWERPC_EXCP_MCHECK:    /* Machine check exception                  */
1327         if (msr_me == 0) {
1328             /*
1329              * Machine check exception is not enabled.  Enter
1330              * checkstop state.
1331              */
1332             fprintf(stderr, "Machine check while not allowed. "
1333                     "Entering checkstop state\n");
1334             if (qemu_log_separate()) {
1335                 qemu_log("Machine check while not allowed. "
1336                         "Entering checkstop state\n");
1337             }
1338             cs->halted = 1;
1339             cpu_interrupt_exittb(cs);
1340         }
1341         if (env->msr_mask & MSR_HVB) {
1342             /*
1343              * ISA specifies HV, but can be delivered to guest with HV
1344              * clear (e.g., see FWNMI in PAPR).
1345              */
1346             new_msr |= (target_ulong)MSR_HVB;
1347         }
1348 
1349         /* machine check exceptions don't have ME set */
1350         new_msr &= ~((target_ulong)1 << MSR_ME);
1351 
1352         break;
1353     case POWERPC_EXCP_DSI:       /* Data storage exception                   */
1354         trace_ppc_excp_dsi(env->spr[SPR_DSISR], env->spr[SPR_DAR]);
1355         break;
1356     case POWERPC_EXCP_ISI:       /* Instruction storage exception            */
1357         trace_ppc_excp_isi(msr, env->nip);
1358         msr |= env->error_code;
1359         break;
1360     case POWERPC_EXCP_EXTERNAL:  /* External input                           */
1361     {
1362         bool lpes0;
1363 
1364         /*
1365          * LPES0 is only taken into consideration if we support HV
1366          * mode for this CPU.
1367          */
1368         if (!env->has_hv_mode) {
1369             break;
1370         }
1371 
1372         lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0);
1373 
1374         if (!lpes0) {
1375             new_msr |= (target_ulong)MSR_HVB;
1376             new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
1377             srr0 = SPR_HSRR0;
1378             srr1 = SPR_HSRR1;
1379         }
1380 
1381         break;
1382     }
1383     case POWERPC_EXCP_ALIGN:     /* Alignment exception                      */
1384         /* Get rS/rD and rA from faulting opcode */
1385         /*
1386          * Note: the opcode fields will not be set properly for a
1387          * direct store load/store, but nobody cares as nobody
1388          * actually uses direct store segments.
1389          */
1390         env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16;
1391         break;
1392     case POWERPC_EXCP_PROGRAM:   /* Program exception                        */
1393         switch (env->error_code & ~0xF) {
1394         case POWERPC_EXCP_FP:
1395             if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) {
1396                 trace_ppc_excp_fp_ignore();
1397                 cs->exception_index = POWERPC_EXCP_NONE;
1398                 env->error_code = 0;
1399                 return;
1400             }
1401 
1402             /*
1403              * FP exceptions always have NIP pointing to the faulting
1404              * instruction, so always use store_next and claim we are
1405              * precise in the MSR.
1406              */
1407             msr |= 0x00100000;
1408             break;
1409         case POWERPC_EXCP_INVAL:
1410             trace_ppc_excp_inval(env->nip);
1411             msr |= 0x00080000;
1412             break;
1413         case POWERPC_EXCP_PRIV:
1414             msr |= 0x00040000;
1415             break;
1416         case POWERPC_EXCP_TRAP:
1417             msr |= 0x00020000;
1418             break;
1419         default:
1420             /* Should never occur */
1421             cpu_abort(cs, "Invalid program exception %d. Aborting\n",
1422                       env->error_code);
1423             break;
1424         }
1425         break;
1426     case POWERPC_EXCP_SYSCALL:   /* System call exception                    */
1427         lev = env->error_code;
1428 
1429         if ((lev == 1) && cpu->vhyp) {
1430             dump_hcall(env);
1431         } else {
1432             dump_syscall(env);
1433         }
1434 
1435         /*
1436          * We need to correct the NIP which in this case is supposed
1437          * to point to the next instruction
1438          */
1439         env->nip += 4;
1440 
1441         /* "PAPR mode" built-in hypercall emulation */
1442         if ((lev == 1) && cpu->vhyp) {
1443             PPCVirtualHypervisorClass *vhc =
1444                 PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
1445             vhc->hypercall(cpu->vhyp, cpu);
1446             return;
1447         }
1448         if (lev == 1) {
1449             new_msr |= (target_ulong)MSR_HVB;
1450         }
1451         break;
1452     case POWERPC_EXCP_SYSCALL_VECTORED: /* scv exception                     */
1453         lev = env->error_code;
1454         dump_syscall(env);
1455         env->nip += 4;
1456         new_msr |= env->msr & ((target_ulong)1 << MSR_EE);
1457         new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
1458 
1459         vector += lev * 0x20;
1460 
1461         env->lr = env->nip;
1462         env->ctr = msr;
1463         break;
1464     case POWERPC_EXCP_FPU:       /* Floating-point unavailable exception     */
1465     case POWERPC_EXCP_DECR:      /* Decrementer exception                    */
1466         break;
1467     case POWERPC_EXCP_RESET:     /* System reset exception                   */
1468         /* A power-saving exception sets ME, otherwise it is unchanged */
1469         if (msr_pow) {
1470             /* indicate that we resumed from power save mode */
1471             msr |= 0x10000;
1472             new_msr |= ((target_ulong)1 << MSR_ME);
1473         }
1474         if (env->msr_mask & MSR_HVB) {
1475             /*
1476              * ISA specifies HV, but can be delivered to guest with HV
1477              * clear (e.g., see FWNMI in PAPR, NMI injection in QEMU).
1478              */
1479             new_msr |= (target_ulong)MSR_HVB;
1480         } else {
1481             if (msr_pow) {
1482                 cpu_abort(cs, "Trying to deliver power-saving system reset "
1483                           "exception %d with no HV support\n", excp);
1484             }
1485         }
1486         break;
1487     case POWERPC_EXCP_DSEG:      /* Data segment exception                   */
1488     case POWERPC_EXCP_ISEG:      /* Instruction segment exception            */
1489     case POWERPC_EXCP_TRACE:     /* Trace exception                          */
1490         break;
1491     case POWERPC_EXCP_HISI:      /* Hypervisor instruction storage exception */
1492         msr |= env->error_code;
1493         /* fall through */
1494     case POWERPC_EXCP_HDECR:     /* Hypervisor decrementer exception         */
1495     case POWERPC_EXCP_HDSI:      /* Hypervisor data storage exception        */
1496     case POWERPC_EXCP_SDOOR_HV:  /* Hypervisor Doorbell interrupt            */
1497     case POWERPC_EXCP_HV_EMU:
1498     case POWERPC_EXCP_HVIRT:     /* Hypervisor virtualization                */
1499         srr0 = SPR_HSRR0;
1500         srr1 = SPR_HSRR1;
1501         new_msr |= (target_ulong)MSR_HVB;
1502         new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
1503         break;
1504     case POWERPC_EXCP_VPU:       /* Vector unavailable exception             */
1505     case POWERPC_EXCP_VSXU:       /* VSX unavailable exception               */
1506     case POWERPC_EXCP_FU:         /* Facility unavailable exception          */
1507         env->spr[SPR_FSCR] |= ((target_ulong)env->error_code << 56);
1508         break;
1509     case POWERPC_EXCP_HV_FU:     /* Hypervisor Facility Unavailable Exception */
1510         env->spr[SPR_HFSCR] |= ((target_ulong)env->error_code << FSCR_IC_POS);
1511         srr0 = SPR_HSRR0;
1512         srr1 = SPR_HSRR1;
1513         new_msr |= (target_ulong)MSR_HVB;
1514         new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
1515         break;
1516     case POWERPC_EXCP_THERM:     /* Thermal interrupt                        */
1517     case POWERPC_EXCP_PERFM:     /* Embedded performance monitor interrupt   */
1518     case POWERPC_EXCP_VPUA:      /* Vector assist exception                  */
1519     case POWERPC_EXCP_MAINT:     /* Maintenance exception                    */
1520     case POWERPC_EXCP_SDOOR:     /* Doorbell interrupt                       */
1521     case POWERPC_EXCP_HV_MAINT:  /* Hypervisor Maintenance exception         */
1522         cpu_abort(cs, "%s exception not implemented\n",
1523                   powerpc_excp_name(excp));
1524         break;
1525     default:
1526         cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
1527         break;
1528     }
1529 
1530     /* Sanity check */
1531     if (!(env->msr_mask & MSR_HVB) && srr0 == SPR_HSRR0) {
1532         cpu_abort(cs, "Trying to deliver HV exception (HSRR) %d with "
1533                   "no HV support\n", excp);
1534     }
1535 
1536     /*
1537      * Sort out endianness of interrupt, this differs depending on the
1538      * CPU, the HV mode, etc...
1539      */
1540     if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) {
1541         new_msr |= (target_ulong)1 << MSR_LE;
1542     }
1543 
1544     new_msr |= (target_ulong)1 << MSR_SF;
1545 
1546     if (excp != POWERPC_EXCP_SYSCALL_VECTORED) {
1547         /* Save PC */
1548         env->spr[srr0] = env->nip;
1549 
1550         /* Save MSR */
1551         env->spr[srr1] = msr;
1552     }
1553 
1554     /* This can update new_msr and vector if AIL applies */
1555     ppc_excp_apply_ail(cpu, excp, msr, &new_msr, &vector);
1556 
1557     powerpc_set_excp_state(cpu, vector, new_msr);
1558 }
1559 #else
1560 static inline void powerpc_excp_books(PowerPCCPU *cpu, int excp)
1561 {
1562     g_assert_not_reached();
1563 }
1564 #endif
1565 
1566 static void powerpc_excp(PowerPCCPU *cpu, int excp)
1567 {
1568     CPUState *cs = CPU(cpu);
1569     CPUPPCState *env = &cpu->env;
1570 
1571     if (excp <= POWERPC_EXCP_NONE || excp >= POWERPC_EXCP_NB) {
1572         cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
1573     }
1574 
1575     qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx
1576                   " => %s (%d) error=%02x\n", env->nip, powerpc_excp_name(excp),
1577                   excp, env->error_code);
1578 
1579     switch (env->excp_model) {
1580     case POWERPC_EXCP_40x:
1581         powerpc_excp_40x(cpu, excp);
1582         break;
1583     case POWERPC_EXCP_6xx:
1584         powerpc_excp_6xx(cpu, excp);
1585         break;
1586     case POWERPC_EXCP_7xx:
1587         powerpc_excp_7xx(cpu, excp);
1588         break;
1589     case POWERPC_EXCP_74xx:
1590         powerpc_excp_74xx(cpu, excp);
1591         break;
1592     case POWERPC_EXCP_BOOKE:
1593         powerpc_excp_booke(cpu, excp);
1594         break;
1595     case POWERPC_EXCP_970:
1596     case POWERPC_EXCP_POWER7:
1597     case POWERPC_EXCP_POWER8:
1598     case POWERPC_EXCP_POWER9:
1599     case POWERPC_EXCP_POWER10:
1600         powerpc_excp_books(cpu, excp);
1601         break;
1602     default:
1603         g_assert_not_reached();
1604     }
1605 }
1606 
1607 void ppc_cpu_do_interrupt(CPUState *cs)
1608 {
1609     PowerPCCPU *cpu = POWERPC_CPU(cs);
1610 
1611     powerpc_excp(cpu, cs->exception_index);
1612 }
1613 
1614 static void ppc_hw_interrupt(CPUPPCState *env)
1615 {
1616     PowerPCCPU *cpu = env_archcpu(env);
1617     bool async_deliver;
1618 
1619     /* External reset */
1620     if (env->pending_interrupts & (1 << PPC_INTERRUPT_RESET)) {
1621         env->pending_interrupts &= ~(1 << PPC_INTERRUPT_RESET);
1622         powerpc_excp(cpu, POWERPC_EXCP_RESET);
1623         return;
1624     }
1625     /* Machine check exception */
1626     if (env->pending_interrupts & (1 << PPC_INTERRUPT_MCK)) {
1627         env->pending_interrupts &= ~(1 << PPC_INTERRUPT_MCK);
1628         powerpc_excp(cpu, POWERPC_EXCP_MCHECK);
1629         return;
1630     }
1631 #if 0 /* TODO */
1632     /* External debug exception */
1633     if (env->pending_interrupts & (1 << PPC_INTERRUPT_DEBUG)) {
1634         env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DEBUG);
1635         powerpc_excp(cpu, POWERPC_EXCP_DEBUG);
1636         return;
1637     }
1638 #endif
1639 
1640     /*
1641      * For interrupts that gate on MSR:EE, we need to do something a
1642      * bit more subtle, as we need to let them through even when EE is
1643      * clear when coming out of some power management states (in order
1644      * for them to become a 0x100).
1645      */
1646     async_deliver = (msr_ee != 0) || env->resume_as_sreset;
1647 
1648     /* Hypervisor decrementer exception */
1649     if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDECR)) {
1650         /* LPCR will be clear when not supported so this will work */
1651         bool hdice = !!(env->spr[SPR_LPCR] & LPCR_HDICE);
1652         if ((async_deliver || msr_hv == 0) && hdice) {
1653             /* HDEC clears on delivery */
1654             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDECR);
1655             powerpc_excp(cpu, POWERPC_EXCP_HDECR);
1656             return;
1657         }
1658     }
1659 
1660     /* Hypervisor virtualization interrupt */
1661     if (env->pending_interrupts & (1 << PPC_INTERRUPT_HVIRT)) {
1662         /* LPCR will be clear when not supported so this will work */
1663         bool hvice = !!(env->spr[SPR_LPCR] & LPCR_HVICE);
1664         if ((async_deliver || msr_hv == 0) && hvice) {
1665             powerpc_excp(cpu, POWERPC_EXCP_HVIRT);
1666             return;
1667         }
1668     }
1669 
1670     /* External interrupt can ignore MSR:EE under some circumstances */
1671     if (env->pending_interrupts & (1 << PPC_INTERRUPT_EXT)) {
1672         bool lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0);
1673         bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
1674         /* HEIC blocks delivery to the hypervisor */
1675         if ((async_deliver && !(heic && msr_hv && !msr_pr)) ||
1676             (env->has_hv_mode && msr_hv == 0 && !lpes0)) {
1677             powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL);
1678             return;
1679         }
1680     }
1681     if (msr_ce != 0) {
1682         /* External critical interrupt */
1683         if (env->pending_interrupts & (1 << PPC_INTERRUPT_CEXT)) {
1684             powerpc_excp(cpu, POWERPC_EXCP_CRITICAL);
1685             return;
1686         }
1687     }
1688     if (async_deliver != 0) {
1689         /* Watchdog timer on embedded PowerPC */
1690         if (env->pending_interrupts & (1 << PPC_INTERRUPT_WDT)) {
1691             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_WDT);
1692             powerpc_excp(cpu, POWERPC_EXCP_WDT);
1693             return;
1694         }
1695         if (env->pending_interrupts & (1 << PPC_INTERRUPT_CDOORBELL)) {
1696             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_CDOORBELL);
1697             powerpc_excp(cpu, POWERPC_EXCP_DOORCI);
1698             return;
1699         }
1700         /* Fixed interval timer on embedded PowerPC */
1701         if (env->pending_interrupts & (1 << PPC_INTERRUPT_FIT)) {
1702             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_FIT);
1703             powerpc_excp(cpu, POWERPC_EXCP_FIT);
1704             return;
1705         }
1706         /* Programmable interval timer on embedded PowerPC */
1707         if (env->pending_interrupts & (1 << PPC_INTERRUPT_PIT)) {
1708             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PIT);
1709             powerpc_excp(cpu, POWERPC_EXCP_PIT);
1710             return;
1711         }
1712         /* Decrementer exception */
1713         if (env->pending_interrupts & (1 << PPC_INTERRUPT_DECR)) {
1714             if (ppc_decr_clear_on_delivery(env)) {
1715                 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DECR);
1716             }
1717             powerpc_excp(cpu, POWERPC_EXCP_DECR);
1718             return;
1719         }
1720         if (env->pending_interrupts & (1 << PPC_INTERRUPT_DOORBELL)) {
1721             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL);
1722             if (is_book3s_arch2x(env)) {
1723                 powerpc_excp(cpu, POWERPC_EXCP_SDOOR);
1724             } else {
1725                 powerpc_excp(cpu, POWERPC_EXCP_DOORI);
1726             }
1727             return;
1728         }
1729         if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDOORBELL)) {
1730             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDOORBELL);
1731             powerpc_excp(cpu, POWERPC_EXCP_SDOOR_HV);
1732             return;
1733         }
1734         if (env->pending_interrupts & (1 << PPC_INTERRUPT_PERFM)) {
1735             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PERFM);
1736             powerpc_excp(cpu, POWERPC_EXCP_PERFM);
1737             return;
1738         }
1739         /* Thermal interrupt */
1740         if (env->pending_interrupts & (1 << PPC_INTERRUPT_THERM)) {
1741             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_THERM);
1742             powerpc_excp(cpu, POWERPC_EXCP_THERM);
1743             return;
1744         }
1745     }
1746 
1747     if (env->resume_as_sreset) {
1748         /*
1749          * This is a bug ! It means that has_work took us out of halt without
1750          * anything to deliver while in a PM state that requires getting
1751          * out via a 0x100
1752          *
1753          * This means we will incorrectly execute past the power management
1754          * instruction instead of triggering a reset.
1755          *
1756          * It generally means a discrepancy between the wakeup conditions in the
1757          * processor has_work implementation and the logic in this function.
1758          */
1759         cpu_abort(env_cpu(env),
1760                   "Wakeup from PM state but interrupt Undelivered");
1761     }
1762 }
1763 
1764 void ppc_cpu_do_system_reset(CPUState *cs)
1765 {
1766     PowerPCCPU *cpu = POWERPC_CPU(cs);
1767 
1768     powerpc_excp(cpu, POWERPC_EXCP_RESET);
1769 }
1770 
1771 void ppc_cpu_do_fwnmi_machine_check(CPUState *cs, target_ulong vector)
1772 {
1773     PowerPCCPU *cpu = POWERPC_CPU(cs);
1774     CPUPPCState *env = &cpu->env;
1775     target_ulong msr = 0;
1776 
1777     /*
1778      * Set MSR and NIP for the handler, SRR0/1, DAR and DSISR have already
1779      * been set by KVM.
1780      */
1781     msr = (1ULL << MSR_ME);
1782     msr |= env->msr & (1ULL << MSR_SF);
1783     if (ppc_interrupts_little_endian(cpu, false)) {
1784         msr |= (1ULL << MSR_LE);
1785     }
1786 
1787     powerpc_set_excp_state(cpu, vector, msr);
1788 }
1789 
1790 bool ppc_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
1791 {
1792     PowerPCCPU *cpu = POWERPC_CPU(cs);
1793     CPUPPCState *env = &cpu->env;
1794 
1795     if (interrupt_request & CPU_INTERRUPT_HARD) {
1796         ppc_hw_interrupt(env);
1797         if (env->pending_interrupts == 0) {
1798             cs->interrupt_request &= ~CPU_INTERRUPT_HARD;
1799         }
1800         return true;
1801     }
1802     return false;
1803 }
1804 
1805 #endif /* !CONFIG_USER_ONLY */
1806 
1807 /*****************************************************************************/
1808 /* Exceptions processing helpers */
1809 
1810 void raise_exception_err_ra(CPUPPCState *env, uint32_t exception,
1811                             uint32_t error_code, uintptr_t raddr)
1812 {
1813     CPUState *cs = env_cpu(env);
1814 
1815     cs->exception_index = exception;
1816     env->error_code = error_code;
1817     cpu_loop_exit_restore(cs, raddr);
1818 }
1819 
1820 void raise_exception_err(CPUPPCState *env, uint32_t exception,
1821                          uint32_t error_code)
1822 {
1823     raise_exception_err_ra(env, exception, error_code, 0);
1824 }
1825 
1826 void raise_exception(CPUPPCState *env, uint32_t exception)
1827 {
1828     raise_exception_err_ra(env, exception, 0, 0);
1829 }
1830 
1831 void raise_exception_ra(CPUPPCState *env, uint32_t exception,
1832                         uintptr_t raddr)
1833 {
1834     raise_exception_err_ra(env, exception, 0, raddr);
1835 }
1836 
1837 #ifdef CONFIG_TCG
1838 void helper_raise_exception_err(CPUPPCState *env, uint32_t exception,
1839                                 uint32_t error_code)
1840 {
1841     raise_exception_err_ra(env, exception, error_code, 0);
1842 }
1843 
1844 void helper_raise_exception(CPUPPCState *env, uint32_t exception)
1845 {
1846     raise_exception_err_ra(env, exception, 0, 0);
1847 }
1848 #endif
1849 
1850 #if !defined(CONFIG_USER_ONLY)
1851 #ifdef CONFIG_TCG
1852 void helper_store_msr(CPUPPCState *env, target_ulong val)
1853 {
1854     uint32_t excp = hreg_store_msr(env, val, 0);
1855 
1856     if (excp != 0) {
1857         CPUState *cs = env_cpu(env);
1858         cpu_interrupt_exittb(cs);
1859         raise_exception(env, excp);
1860     }
1861 }
1862 
1863 #if defined(TARGET_PPC64)
1864 void helper_scv(CPUPPCState *env, uint32_t lev)
1865 {
1866     if (env->spr[SPR_FSCR] & (1ull << FSCR_SCV)) {
1867         raise_exception_err(env, POWERPC_EXCP_SYSCALL_VECTORED, lev);
1868     } else {
1869         raise_exception_err(env, POWERPC_EXCP_FU, FSCR_IC_SCV);
1870     }
1871 }
1872 
1873 void helper_pminsn(CPUPPCState *env, powerpc_pm_insn_t insn)
1874 {
1875     CPUState *cs;
1876 
1877     cs = env_cpu(env);
1878     cs->halted = 1;
1879 
1880     /* Condition for waking up at 0x100 */
1881     env->resume_as_sreset = (insn != PPC_PM_STOP) ||
1882         (env->spr[SPR_PSSCR] & PSSCR_EC);
1883 }
1884 #endif /* defined(TARGET_PPC64) */
1885 
1886 static void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr)
1887 {
1888     CPUState *cs = env_cpu(env);
1889 
1890     /* MSR:POW cannot be set by any form of rfi */
1891     msr &= ~(1ULL << MSR_POW);
1892 
1893     /* MSR:TGPR cannot be set by any form of rfi */
1894     if (env->flags & POWERPC_FLAG_TGPR)
1895         msr &= ~(1ULL << MSR_TGPR);
1896 
1897 #if defined(TARGET_PPC64)
1898     /* Switching to 32-bit ? Crop the nip */
1899     if (!msr_is_64bit(env, msr)) {
1900         nip = (uint32_t)nip;
1901     }
1902 #else
1903     nip = (uint32_t)nip;
1904 #endif
1905     /* XXX: beware: this is false if VLE is supported */
1906     env->nip = nip & ~((target_ulong)0x00000003);
1907     hreg_store_msr(env, msr, 1);
1908     trace_ppc_excp_rfi(env->nip, env->msr);
1909     /*
1910      * No need to raise an exception here, as rfi is always the last
1911      * insn of a TB
1912      */
1913     cpu_interrupt_exittb(cs);
1914     /* Reset the reservation */
1915     env->reserve_addr = -1;
1916 
1917     /* Context synchronizing: check if TCG TLB needs flush */
1918     check_tlb_flush(env, false);
1919 }
1920 
1921 void helper_rfi(CPUPPCState *env)
1922 {
1923     do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1] & 0xfffffffful);
1924 }
1925 
1926 #define MSR_BOOK3S_MASK
1927 #if defined(TARGET_PPC64)
1928 void helper_rfid(CPUPPCState *env)
1929 {
1930     /*
1931      * The architecture defines a number of rules for which bits can
1932      * change but in practice, we handle this in hreg_store_msr()
1933      * which will be called by do_rfi(), so there is no need to filter
1934      * here
1935      */
1936     do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1]);
1937 }
1938 
1939 void helper_rfscv(CPUPPCState *env)
1940 {
1941     do_rfi(env, env->lr, env->ctr);
1942 }
1943 
1944 void helper_hrfid(CPUPPCState *env)
1945 {
1946     do_rfi(env, env->spr[SPR_HSRR0], env->spr[SPR_HSRR1]);
1947 }
1948 #endif
1949 
1950 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
1951 void helper_rfebb(CPUPPCState *env, target_ulong s)
1952 {
1953     target_ulong msr = env->msr;
1954 
1955     /*
1956      * Handling of BESCR bits 32:33 according to PowerISA v3.1:
1957      *
1958      * "If BESCR 32:33 != 0b00 the instruction is treated as if
1959      *  the instruction form were invalid."
1960      */
1961     if (env->spr[SPR_BESCR] & BESCR_INVALID) {
1962         raise_exception_err(env, POWERPC_EXCP_PROGRAM,
1963                             POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL);
1964     }
1965 
1966     env->nip = env->spr[SPR_EBBRR];
1967 
1968     /* Switching to 32-bit ? Crop the nip */
1969     if (!msr_is_64bit(env, msr)) {
1970         env->nip = (uint32_t)env->spr[SPR_EBBRR];
1971     }
1972 
1973     if (s) {
1974         env->spr[SPR_BESCR] |= BESCR_GE;
1975     } else {
1976         env->spr[SPR_BESCR] &= ~BESCR_GE;
1977     }
1978 }
1979 #endif
1980 
1981 /*****************************************************************************/
1982 /* Embedded PowerPC specific helpers */
1983 void helper_40x_rfci(CPUPPCState *env)
1984 {
1985     do_rfi(env, env->spr[SPR_40x_SRR2], env->spr[SPR_40x_SRR3]);
1986 }
1987 
1988 void helper_rfci(CPUPPCState *env)
1989 {
1990     do_rfi(env, env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1]);
1991 }
1992 
1993 void helper_rfdi(CPUPPCState *env)
1994 {
1995     /* FIXME: choose CSRR1 or DSRR1 based on cpu type */
1996     do_rfi(env, env->spr[SPR_BOOKE_DSRR0], env->spr[SPR_BOOKE_DSRR1]);
1997 }
1998 
1999 void helper_rfmci(CPUPPCState *env)
2000 {
2001     /* FIXME: choose CSRR1 or MCSRR1 based on cpu type */
2002     do_rfi(env, env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1]);
2003 }
2004 #endif /* CONFIG_TCG */
2005 #endif /* !defined(CONFIG_USER_ONLY) */
2006 
2007 #ifdef CONFIG_TCG
2008 void helper_tw(CPUPPCState *env, target_ulong arg1, target_ulong arg2,
2009                uint32_t flags)
2010 {
2011     if (!likely(!(((int32_t)arg1 < (int32_t)arg2 && (flags & 0x10)) ||
2012                   ((int32_t)arg1 > (int32_t)arg2 && (flags & 0x08)) ||
2013                   ((int32_t)arg1 == (int32_t)arg2 && (flags & 0x04)) ||
2014                   ((uint32_t)arg1 < (uint32_t)arg2 && (flags & 0x02)) ||
2015                   ((uint32_t)arg1 > (uint32_t)arg2 && (flags & 0x01))))) {
2016         raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
2017                                POWERPC_EXCP_TRAP, GETPC());
2018     }
2019 }
2020 
2021 #if defined(TARGET_PPC64)
2022 void helper_td(CPUPPCState *env, target_ulong arg1, target_ulong arg2,
2023                uint32_t flags)
2024 {
2025     if (!likely(!(((int64_t)arg1 < (int64_t)arg2 && (flags & 0x10)) ||
2026                   ((int64_t)arg1 > (int64_t)arg2 && (flags & 0x08)) ||
2027                   ((int64_t)arg1 == (int64_t)arg2 && (flags & 0x04)) ||
2028                   ((uint64_t)arg1 < (uint64_t)arg2 && (flags & 0x02)) ||
2029                   ((uint64_t)arg1 > (uint64_t)arg2 && (flags & 0x01))))) {
2030         raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
2031                                POWERPC_EXCP_TRAP, GETPC());
2032     }
2033 }
2034 #endif
2035 #endif
2036 
2037 #if !defined(CONFIG_USER_ONLY)
2038 
2039 #ifdef CONFIG_TCG
2040 
2041 /* Embedded.Processor Control */
2042 static int dbell2irq(target_ulong rb)
2043 {
2044     int msg = rb & DBELL_TYPE_MASK;
2045     int irq = -1;
2046 
2047     switch (msg) {
2048     case DBELL_TYPE_DBELL:
2049         irq = PPC_INTERRUPT_DOORBELL;
2050         break;
2051     case DBELL_TYPE_DBELL_CRIT:
2052         irq = PPC_INTERRUPT_CDOORBELL;
2053         break;
2054     case DBELL_TYPE_G_DBELL:
2055     case DBELL_TYPE_G_DBELL_CRIT:
2056     case DBELL_TYPE_G_DBELL_MC:
2057         /* XXX implement */
2058     default:
2059         break;
2060     }
2061 
2062     return irq;
2063 }
2064 
2065 void helper_msgclr(CPUPPCState *env, target_ulong rb)
2066 {
2067     int irq = dbell2irq(rb);
2068 
2069     if (irq < 0) {
2070         return;
2071     }
2072 
2073     env->pending_interrupts &= ~(1 << irq);
2074 }
2075 
2076 void helper_msgsnd(target_ulong rb)
2077 {
2078     int irq = dbell2irq(rb);
2079     int pir = rb & DBELL_PIRTAG_MASK;
2080     CPUState *cs;
2081 
2082     if (irq < 0) {
2083         return;
2084     }
2085 
2086     qemu_mutex_lock_iothread();
2087     CPU_FOREACH(cs) {
2088         PowerPCCPU *cpu = POWERPC_CPU(cs);
2089         CPUPPCState *cenv = &cpu->env;
2090 
2091         if ((rb & DBELL_BRDCAST) || (cenv->spr[SPR_BOOKE_PIR] == pir)) {
2092             cenv->pending_interrupts |= 1 << irq;
2093             cpu_interrupt(cs, CPU_INTERRUPT_HARD);
2094         }
2095     }
2096     qemu_mutex_unlock_iothread();
2097 }
2098 
2099 /* Server Processor Control */
2100 
2101 static bool dbell_type_server(target_ulong rb)
2102 {
2103     /*
2104      * A Directed Hypervisor Doorbell message is sent only if the
2105      * message type is 5. All other types are reserved and the
2106      * instruction is a no-op
2107      */
2108     return (rb & DBELL_TYPE_MASK) == DBELL_TYPE_DBELL_SERVER;
2109 }
2110 
2111 void helper_book3s_msgclr(CPUPPCState *env, target_ulong rb)
2112 {
2113     if (!dbell_type_server(rb)) {
2114         return;
2115     }
2116 
2117     env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDOORBELL);
2118 }
2119 
2120 static void book3s_msgsnd_common(int pir, int irq)
2121 {
2122     CPUState *cs;
2123 
2124     qemu_mutex_lock_iothread();
2125     CPU_FOREACH(cs) {
2126         PowerPCCPU *cpu = POWERPC_CPU(cs);
2127         CPUPPCState *cenv = &cpu->env;
2128 
2129         /* TODO: broadcast message to all threads of the same  processor */
2130         if (cenv->spr_cb[SPR_PIR].default_value == pir) {
2131             cenv->pending_interrupts |= 1 << irq;
2132             cpu_interrupt(cs, CPU_INTERRUPT_HARD);
2133         }
2134     }
2135     qemu_mutex_unlock_iothread();
2136 }
2137 
2138 void helper_book3s_msgsnd(target_ulong rb)
2139 {
2140     int pir = rb & DBELL_PROCIDTAG_MASK;
2141 
2142     if (!dbell_type_server(rb)) {
2143         return;
2144     }
2145 
2146     book3s_msgsnd_common(pir, PPC_INTERRUPT_HDOORBELL);
2147 }
2148 
2149 #if defined(TARGET_PPC64)
2150 void helper_book3s_msgclrp(CPUPPCState *env, target_ulong rb)
2151 {
2152     helper_hfscr_facility_check(env, HFSCR_MSGP, "msgclrp", HFSCR_IC_MSGP);
2153 
2154     if (!dbell_type_server(rb)) {
2155         return;
2156     }
2157 
2158     env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL);
2159 }
2160 
2161 /*
2162  * sends a message to other threads that are on the same
2163  * multi-threaded processor
2164  */
2165 void helper_book3s_msgsndp(CPUPPCState *env, target_ulong rb)
2166 {
2167     int pir = env->spr_cb[SPR_PIR].default_value;
2168 
2169     helper_hfscr_facility_check(env, HFSCR_MSGP, "msgsndp", HFSCR_IC_MSGP);
2170 
2171     if (!dbell_type_server(rb)) {
2172         return;
2173     }
2174 
2175     /* TODO: TCG supports only one thread */
2176 
2177     book3s_msgsnd_common(pir, PPC_INTERRUPT_DOORBELL);
2178 }
2179 #endif /* TARGET_PPC64 */
2180 
2181 void ppc_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
2182                                  MMUAccessType access_type,
2183                                  int mmu_idx, uintptr_t retaddr)
2184 {
2185     CPUPPCState *env = cs->env_ptr;
2186     uint32_t insn;
2187 
2188     /* Restore state and reload the insn we executed, for filling in DSISR.  */
2189     cpu_restore_state(cs, retaddr, true);
2190     insn = cpu_ldl_code(env, env->nip);
2191 
2192     switch (env->mmu_model) {
2193     case POWERPC_MMU_SOFT_4xx:
2194         env->spr[SPR_40x_DEAR] = vaddr;
2195         break;
2196     case POWERPC_MMU_BOOKE:
2197     case POWERPC_MMU_BOOKE206:
2198         env->spr[SPR_BOOKE_DEAR] = vaddr;
2199         break;
2200     default:
2201         env->spr[SPR_DAR] = vaddr;
2202         break;
2203     }
2204 
2205     cs->exception_index = POWERPC_EXCP_ALIGN;
2206     env->error_code = insn & 0x03FF0000;
2207     cpu_loop_exit(cs);
2208 }
2209 #endif /* CONFIG_TCG */
2210 #endif /* !CONFIG_USER_ONLY */
2211