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