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