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