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