target/ppc: 6xx: Software TLB exceptions cleanup
[qemu/rayw.git] / target / ppc / excp_helper.c
blob80168355bdfa6a9911882368fa45865f0a56634a
1 /*
2 * PowerPC exception emulation helpers for QEMU.
4 * Copyright (c) 2003-2007 Jocelyn Mayer
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.
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.
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/>.
19 #include "qemu/osdep.h"
20 #include "qemu/main-loop.h"
21 #include "cpu.h"
22 #include "exec/exec-all.h"
23 #include "internal.h"
24 #include "helper_regs.h"
26 #include "trace.h"
28 #ifdef CONFIG_TCG
29 #include "exec/helper-proto.h"
30 #include "exec/cpu_ldst.h"
31 #endif
33 /*****************************************************************************/
34 /* Exception processing */
35 #if !defined(CONFIG_USER_ONLY)
37 static const char *powerpc_excp_name(int excp)
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();
107 static void dump_syscall(CPUPPCState *env)
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);
119 static void dump_hcall(CPUPPCState *env)
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);
134 static void ppc_excp_debug_sw_tlb(CPUPPCState *env, int excp)
136 const char *es;
137 target_ulong *miss, *cmp;
138 int en;
140 if (!qemu_loglevel_mask(CPU_LOG_MMU)) {
141 return;
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";
155 en = 'D';
156 miss = &env->spr[SPR_DMISS];
157 cmp = &env->spr[SPR_DCMP];
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);
167 static int powerpc_reset_wakeup(CPUState *cs, CPUPPCState *env, int excp,
168 target_ulong *msr)
170 /* We no longer are in a PM state */
171 env->resume_as_sreset = false;
173 /* Pretend to be returning from doze always as we don't lose state */
174 *msr |= SRR1_WS_NOLOSS;
176 /* Machine checks are sent normally */
177 if (excp == POWERPC_EXCP_MCHECK) {
178 return excp;
180 switch (excp) {
181 case POWERPC_EXCP_RESET:
182 *msr |= SRR1_WAKERESET;
183 break;
184 case POWERPC_EXCP_EXTERNAL:
185 *msr |= SRR1_WAKEEE;
186 break;
187 case POWERPC_EXCP_DECR:
188 *msr |= SRR1_WAKEDEC;
189 break;
190 case POWERPC_EXCP_SDOOR:
191 *msr |= SRR1_WAKEDBELL;
192 break;
193 case POWERPC_EXCP_SDOOR_HV:
194 *msr |= SRR1_WAKEHDBELL;
195 break;
196 case POWERPC_EXCP_HV_MAINT:
197 *msr |= SRR1_WAKEHMI;
198 break;
199 case POWERPC_EXCP_HVIRT:
200 *msr |= SRR1_WAKEHVI;
201 break;
202 default:
203 cpu_abort(cs, "Unsupported exception %d in Power Save mode\n",
204 excp);
206 return POWERPC_EXCP_RESET;
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).
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.
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).
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]).
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 * +-------------------------------------------------------+
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 * +-------------------------------------------------------+
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.
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).
253 * HAIL=1 is equivalent to AIL=3, for interrupts delivered with MSR[HV]=1.
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 * +--------------------------------------------------------------------+
265 static void ppc_excp_apply_ail(PowerPCCPU *cpu, int excp_model, int excp,
266 target_ulong msr,
267 target_ulong *new_msr,
268 target_ulong *vector)
270 #if defined(TARGET_PPC64)
271 CPUPPCState *env = &cpu->env;
272 bool mmu_all_on = ((msr >> MSR_IR) & 1) && ((msr >> MSR_DR) & 1);
273 bool hv_escalation = !(msr & MSR_HVB) && (*new_msr & MSR_HVB);
274 int ail = 0;
276 if (excp == POWERPC_EXCP_MCHECK ||
277 excp == POWERPC_EXCP_RESET ||
278 excp == POWERPC_EXCP_HV_MAINT) {
279 /* SRESET, MCE, HMI never apply AIL */
280 return;
283 if (excp_model == POWERPC_EXCP_POWER8 ||
284 excp_model == POWERPC_EXCP_POWER9) {
285 if (!mmu_all_on) {
286 /* AIL only works if MSR[IR] and MSR[DR] are both enabled. */
287 return;
289 if (hv_escalation && !(env->spr[SPR_LPCR] & LPCR_HR)) {
291 * AIL does not work if there is a MSR[HV] 0->1 transition and the
292 * partition is in HPT mode. For radix guests, such interrupts are
293 * allowed to be delivered to the hypervisor in ail mode.
295 return;
298 ail = (env->spr[SPR_LPCR] & LPCR_AIL) >> LPCR_AIL_SHIFT;
299 if (ail == 0) {
300 return;
302 if (ail == 1) {
303 /* AIL=1 is reserved, treat it like AIL=0 */
304 return;
307 } else if (excp_model == POWERPC_EXCP_POWER10) {
308 if (!mmu_all_on && !hv_escalation) {
310 * AIL works for HV interrupts even with guest MSR[IR/DR] disabled.
311 * Guest->guest and HV->HV interrupts do require MMU on.
313 return;
316 if (*new_msr & MSR_HVB) {
317 if (!(env->spr[SPR_LPCR] & LPCR_HAIL)) {
318 /* HV interrupts depend on LPCR[HAIL] */
319 return;
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;
325 if (ail == 0) {
326 return;
328 if (ail == 1 || ail == 2) {
329 /* AIL=1 and AIL=2 are reserved, treat them like AIL=0 */
330 return;
332 } else {
333 /* Other processors do not support AIL */
334 return;
338 * AIL applies, so the new MSR gets IR and DR set, and an offset applied
339 * to the new IP.
341 *new_msr |= (1 << MSR_IR) | (1 << MSR_DR);
343 if (excp != POWERPC_EXCP_SYSCALL_VECTORED) {
344 if (ail == 2) {
345 *vector |= 0x0000000000018000ull;
346 } else if (ail == 3) {
347 *vector |= 0xc000000000004000ull;
349 } else {
351 * scv AIL is a little different. AIL=2 does not change the address,
352 * only the MSR. AIL=3 replaces the 0x17000 base with 0xc...3000.
354 if (ail == 3) {
355 *vector &= ~0x0000000000017000ull; /* Un-apply the base offset */
356 *vector |= 0xc000000000003000ull; /* Apply scv's AIL=3 offset */
359 #endif
362 static void powerpc_set_excp_state(PowerPCCPU *cpu,
363 target_ulong vector, target_ulong msr)
365 CPUState *cs = CPU(cpu);
366 CPUPPCState *env = &cpu->env;
369 * We don't use hreg_store_msr here as already have treated any
370 * special case that could occur. Just store MSR and update hflags
372 * Note: We *MUST* not use hreg_store_msr() as-is anyway because it
373 * will prevent setting of the HV bit which some exceptions might need
374 * to do.
376 env->msr = msr & env->msr_mask;
377 hreg_compute_hflags(env);
378 env->nip = vector;
379 /* Reset exception state */
380 cs->exception_index = POWERPC_EXCP_NONE;
381 env->error_code = 0;
383 /* Reset the reservation */
384 env->reserve_addr = -1;
387 * Any interrupt is context synchronizing, check if TCG TLB needs
388 * a delayed flush on ppc64
390 check_tlb_flush(env, false);
393 static void powerpc_excp_40x(PowerPCCPU *cpu, int excp)
395 CPUState *cs = CPU(cpu);
396 CPUPPCState *env = &cpu->env;
397 target_ulong msr, new_msr, vector;
398 int srr0, srr1;
400 if (excp <= POWERPC_EXCP_NONE || excp >= POWERPC_EXCP_NB) {
401 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
404 qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx
405 " => %s (%d) error=%02x\n", env->nip, powerpc_excp_name(excp),
406 excp, env->error_code);
408 /* new srr1 value excluding must-be-zero bits */
409 msr = env->msr & ~0x783f0000ULL;
412 * new interrupt handler msr preserves existing ME unless
413 * explicitly overriden.
415 new_msr = env->msr & (((target_ulong)1 << MSR_ME));
417 /* target registers */
418 srr0 = SPR_SRR0;
419 srr1 = SPR_SRR1;
422 * Hypervisor emulation assistance interrupt only exists on server
423 * arch 2.05 server or later.
425 if (excp == POWERPC_EXCP_HV_EMU) {
426 excp = POWERPC_EXCP_PROGRAM;
429 vector = env->excp_vectors[excp];
430 if (vector == (target_ulong)-1ULL) {
431 cpu_abort(cs, "Raised an exception without defined vector %d\n",
432 excp);
435 vector |= env->excp_prefix;
437 switch (excp) {
438 case POWERPC_EXCP_CRITICAL: /* Critical input */
439 srr0 = SPR_40x_SRR2;
440 srr1 = SPR_40x_SRR3;
441 break;
442 case POWERPC_EXCP_MCHECK: /* Machine check exception */
443 if (msr_me == 0) {
445 * Machine check exception is not enabled. Enter
446 * checkstop state.
448 fprintf(stderr, "Machine check while not allowed. "
449 "Entering checkstop state\n");
450 if (qemu_log_separate()) {
451 qemu_log("Machine check while not allowed. "
452 "Entering checkstop state\n");
454 cs->halted = 1;
455 cpu_interrupt_exittb(cs);
458 /* machine check exceptions don't have ME set */
459 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 ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) {
478 trace_ppc_excp_fp_ignore();
479 cs->exception_index = POWERPC_EXCP_NONE;
480 env->error_code = 0;
481 return;
483 env->spr[SPR_40x_ESR] = ESR_FP;
484 break;
485 case POWERPC_EXCP_INVAL:
486 trace_ppc_excp_inval(env->nip);
487 env->spr[SPR_40x_ESR] = ESR_PIL;
488 break;
489 case POWERPC_EXCP_PRIV:
490 env->spr[SPR_40x_ESR] = ESR_PPR;
491 break;
492 case POWERPC_EXCP_TRAP:
493 env->spr[SPR_40x_ESR] = ESR_PTR;
494 break;
495 default:
496 cpu_abort(cs, "Invalid program exception %d. Aborting\n",
497 env->error_code);
498 break;
500 break;
501 case POWERPC_EXCP_SYSCALL: /* System call exception */
502 dump_syscall(env);
505 * We need to correct the NIP which in this case is supposed
506 * to point to the next instruction
508 env->nip += 4;
509 break;
510 case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt */
511 trace_ppc_excp_print("FIT");
512 break;
513 case POWERPC_EXCP_WDT: /* Watchdog timer interrupt */
514 trace_ppc_excp_print("WDT");
515 break;
516 case POWERPC_EXCP_DTLB: /* Data TLB error */
517 case POWERPC_EXCP_ITLB: /* Instruction TLB error */
518 break;
519 case POWERPC_EXCP_PIT: /* Programmable interval timer interrupt */
520 trace_ppc_excp_print("PIT");
521 break;
522 case POWERPC_EXCP_DEBUG: /* Debug interrupt */
523 cpu_abort(cs, "%s exception not implemented\n",
524 powerpc_excp_name(excp));
525 break;
526 default:
527 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
528 break;
531 /* Sanity check */
532 if (!(env->msr_mask & MSR_HVB)) {
533 if (new_msr & MSR_HVB) {
534 cpu_abort(cs, "Trying to deliver HV exception (MSR) %d with "
535 "no HV support\n", excp);
537 if (srr0 == SPR_HSRR0) {
538 cpu_abort(cs, "Trying to deliver HV exception (HSRR) %d with "
539 "no HV support\n", excp);
543 /* Save PC */
544 env->spr[srr0] = env->nip;
546 /* Save MSR */
547 env->spr[srr1] = msr;
549 powerpc_set_excp_state(cpu, vector, new_msr);
552 static void powerpc_excp_6xx(PowerPCCPU *cpu, int excp)
554 CPUState *cs = CPU(cpu);
555 CPUPPCState *env = &cpu->env;
556 target_ulong msr, new_msr, vector;
557 int srr0, srr1;
559 if (excp <= POWERPC_EXCP_NONE || excp >= POWERPC_EXCP_NB) {
560 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
563 qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx
564 " => %s (%d) error=%02x\n", env->nip, powerpc_excp_name(excp),
565 excp, env->error_code);
567 /* new srr1 value excluding must-be-zero bits */
568 msr = env->msr & ~0x783f0000ULL;
571 * new interrupt handler msr preserves existing ME unless
572 * explicitly overriden
574 new_msr = env->msr & ((target_ulong)1 << MSR_ME);
576 /* target registers */
577 srr0 = SPR_SRR0;
578 srr1 = SPR_SRR1;
581 * Hypervisor emulation assistance interrupt only exists on server
582 * arch 2.05 server or later.
584 if (excp == POWERPC_EXCP_HV_EMU) {
585 excp = POWERPC_EXCP_PROGRAM;
588 vector = env->excp_vectors[excp];
589 if (vector == (target_ulong)-1ULL) {
590 cpu_abort(cs, "Raised an exception without defined vector %d\n",
591 excp);
594 vector |= env->excp_prefix;
596 switch (excp) {
597 case POWERPC_EXCP_CRITICAL: /* Critical input */
598 break;
599 case POWERPC_EXCP_MCHECK: /* Machine check exception */
600 if (msr_me == 0) {
602 * Machine check exception is not enabled. Enter
603 * checkstop state.
605 fprintf(stderr, "Machine check while not allowed. "
606 "Entering checkstop state\n");
607 if (qemu_log_separate()) {
608 qemu_log("Machine check while not allowed. "
609 "Entering checkstop state\n");
611 cs->halted = 1;
612 cpu_interrupt_exittb(cs);
615 /* machine check exceptions don't have ME set */
616 new_msr &= ~((target_ulong)1 << MSR_ME);
618 break;
619 case POWERPC_EXCP_DSI: /* Data storage exception */
620 trace_ppc_excp_dsi(env->spr[SPR_DSISR], env->spr[SPR_DAR]);
621 break;
622 case POWERPC_EXCP_ISI: /* Instruction storage exception */
623 trace_ppc_excp_isi(msr, env->nip);
624 msr |= env->error_code;
625 break;
626 case POWERPC_EXCP_EXTERNAL: /* External input */
627 break;
628 case POWERPC_EXCP_ALIGN: /* Alignment exception */
629 /* Get rS/rD and rA from faulting opcode */
631 * Note: the opcode fields will not be set properly for a
632 * direct store load/store, but nobody cares as nobody
633 * actually uses direct store segments.
635 env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16;
636 break;
637 case POWERPC_EXCP_PROGRAM: /* Program exception */
638 switch (env->error_code & ~0xF) {
639 case POWERPC_EXCP_FP:
640 if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) {
641 trace_ppc_excp_fp_ignore();
642 cs->exception_index = POWERPC_EXCP_NONE;
643 env->error_code = 0;
644 return;
648 * FP exceptions always have NIP pointing to the faulting
649 * instruction, so always use store_next and claim we are
650 * precise in the MSR.
652 msr |= 0x00100000;
653 break;
654 case POWERPC_EXCP_INVAL:
655 trace_ppc_excp_inval(env->nip);
656 msr |= 0x00080000;
657 break;
658 case POWERPC_EXCP_PRIV:
659 msr |= 0x00040000;
660 break;
661 case POWERPC_EXCP_TRAP:
662 msr |= 0x00020000;
663 break;
664 default:
665 /* Should never occur */
666 cpu_abort(cs, "Invalid program exception %d. Aborting\n",
667 env->error_code);
668 break;
670 break;
671 case POWERPC_EXCP_SYSCALL: /* System call exception */
672 dump_syscall(env);
675 * We need to correct the NIP which in this case is supposed
676 * to point to the next instruction
678 env->nip += 4;
679 break;
680 case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
681 case POWERPC_EXCP_DECR: /* Decrementer exception */
682 break;
683 case POWERPC_EXCP_DTLB: /* Data TLB error */
684 case POWERPC_EXCP_ITLB: /* Instruction TLB error */
685 break;
686 case POWERPC_EXCP_RESET: /* System reset exception */
687 if (msr_pow) {
688 cpu_abort(cs, "Trying to deliver power-saving system reset "
689 "exception %d with no HV support\n", excp);
691 break;
692 case POWERPC_EXCP_TRACE: /* Trace exception */
693 break;
694 case POWERPC_EXCP_IFTLB: /* Instruction fetch TLB error */
695 case POWERPC_EXCP_DLTLB: /* Data load TLB miss */
696 case POWERPC_EXCP_DSTLB: /* Data store TLB miss */
697 /* Swap temporary saved registers with GPRs */
698 if (!(new_msr & ((target_ulong)1 << MSR_TGPR))) {
699 new_msr |= (target_ulong)1 << MSR_TGPR;
700 hreg_swap_gpr_tgpr(env);
703 ppc_excp_debug_sw_tlb(env, excp);
705 msr |= env->crf[0] << 28;
706 msr |= env->error_code; /* key, D/I, S/L bits */
707 /* Set way using a LRU mechanism */
708 msr |= ((env->last_way + 1) & (env->nb_ways - 1)) << 17;
709 break;
710 case POWERPC_EXCP_FPA: /* Floating-point assist exception */
711 case POWERPC_EXCP_DABR: /* Data address breakpoint */
712 case POWERPC_EXCP_IABR: /* Instruction address breakpoint */
713 case POWERPC_EXCP_SMI: /* System management interrupt */
714 case POWERPC_EXCP_MEXTBR: /* Maskable external breakpoint */
715 case POWERPC_EXCP_NMEXTBR: /* Non maskable external breakpoint */
716 cpu_abort(cs, "%s exception not implemented\n",
717 powerpc_excp_name(excp));
718 break;
719 default:
720 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
721 break;
724 /* Sanity check */
725 if (!(env->msr_mask & MSR_HVB)) {
726 if (new_msr & MSR_HVB) {
727 cpu_abort(cs, "Trying to deliver HV exception (MSR) %d with "
728 "no HV support\n", excp);
730 if (srr0 == SPR_HSRR0) {
731 cpu_abort(cs, "Trying to deliver HV exception (HSRR) %d with "
732 "no HV support\n", excp);
737 * Sort out endianness of interrupt, this differs depending on the
738 * CPU, the HV mode, etc...
740 if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) {
741 new_msr |= (target_ulong)1 << MSR_LE;
744 /* Save PC */
745 env->spr[srr0] = env->nip;
747 /* Save MSR */
748 env->spr[srr1] = msr;
750 powerpc_set_excp_state(cpu, vector, new_msr);
753 static void powerpc_excp_74xx(PowerPCCPU *cpu, int excp)
755 CPUState *cs = CPU(cpu);
756 CPUPPCState *env = &cpu->env;
757 target_ulong msr, new_msr, vector;
759 if (excp <= POWERPC_EXCP_NONE || excp >= POWERPC_EXCP_NB) {
760 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
763 qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx
764 " => %s (%d) error=%02x\n", env->nip, powerpc_excp_name(excp),
765 excp, env->error_code);
767 /* new srr1 value excluding must-be-zero bits */
768 msr = env->msr & ~0x783f0000ULL;
771 * new interrupt handler msr preserves existing ME unless
772 * explicitly overriden
774 new_msr = env->msr & ((target_ulong)1 << MSR_ME);
777 * Hypervisor emulation assistance interrupt only exists on server
778 * arch 2.05 server or later.
780 if (excp == POWERPC_EXCP_HV_EMU) {
781 excp = POWERPC_EXCP_PROGRAM;
784 vector = env->excp_vectors[excp];
785 if (vector == (target_ulong)-1ULL) {
786 cpu_abort(cs, "Raised an exception without defined vector %d\n",
787 excp);
790 vector |= env->excp_prefix;
792 switch (excp) {
793 case POWERPC_EXCP_MCHECK: /* Machine check exception */
794 if (msr_me == 0) {
796 * Machine check exception is not enabled. Enter
797 * checkstop state.
799 fprintf(stderr, "Machine check while not allowed. "
800 "Entering checkstop state\n");
801 if (qemu_log_separate()) {
802 qemu_log("Machine check while not allowed. "
803 "Entering checkstop state\n");
805 cs->halted = 1;
806 cpu_interrupt_exittb(cs);
809 /* machine check exceptions don't have ME set */
810 new_msr &= ~((target_ulong)1 << MSR_ME);
812 break;
813 case POWERPC_EXCP_DSI: /* Data storage exception */
814 trace_ppc_excp_dsi(env->spr[SPR_DSISR], env->spr[SPR_DAR]);
815 break;
816 case POWERPC_EXCP_ISI: /* Instruction storage exception */
817 trace_ppc_excp_isi(msr, env->nip);
818 msr |= env->error_code;
819 break;
820 case POWERPC_EXCP_EXTERNAL: /* External input */
821 break;
822 case POWERPC_EXCP_ALIGN: /* Alignment exception */
823 /* Get rS/rD and rA from faulting opcode */
825 * Note: the opcode fields will not be set properly for a
826 * direct store load/store, but nobody cares as nobody
827 * actually uses direct store segments.
829 env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16;
830 break;
831 case POWERPC_EXCP_PROGRAM: /* Program exception */
832 switch (env->error_code & ~0xF) {
833 case POWERPC_EXCP_FP:
834 if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) {
835 trace_ppc_excp_fp_ignore();
836 cs->exception_index = POWERPC_EXCP_NONE;
837 env->error_code = 0;
838 return;
842 * FP exceptions always have NIP pointing to the faulting
843 * instruction, so always use store_next and claim we are
844 * precise in the MSR.
846 msr |= 0x00100000;
847 break;
848 case POWERPC_EXCP_INVAL:
849 trace_ppc_excp_inval(env->nip);
850 msr |= 0x00080000;
851 break;
852 case POWERPC_EXCP_PRIV:
853 msr |= 0x00040000;
854 break;
855 case POWERPC_EXCP_TRAP:
856 msr |= 0x00020000;
857 break;
858 default:
859 /* Should never occur */
860 cpu_abort(cs, "Invalid program exception %d. Aborting\n",
861 env->error_code);
862 break;
864 break;
865 case POWERPC_EXCP_SYSCALL: /* System call exception */
867 int lev = env->error_code;
869 if ((lev == 1) && cpu->vhyp) {
870 dump_hcall(env);
871 } else {
872 dump_syscall(env);
876 * We need to correct the NIP which in this case is supposed
877 * to point to the next instruction
879 env->nip += 4;
882 * The Virtual Open Firmware (VOF) relies on the 'sc 1'
883 * instruction to communicate with QEMU. The pegasos2 machine
884 * uses VOF and the 74xx CPUs, so although the 74xx don't have
885 * HV mode, we need to keep hypercall support.
887 if ((lev == 1) && cpu->vhyp) {
888 PPCVirtualHypervisorClass *vhc =
889 PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
890 vhc->hypercall(cpu->vhyp, cpu);
891 return;
894 break;
896 case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
897 case POWERPC_EXCP_DECR: /* Decrementer exception */
898 break;
899 case POWERPC_EXCP_RESET: /* System reset exception */
900 if (msr_pow) {
901 cpu_abort(cs, "Trying to deliver power-saving system reset "
902 "exception %d with no HV support\n", excp);
904 break;
905 case POWERPC_EXCP_TRACE: /* Trace exception */
906 break;
907 case POWERPC_EXCP_VPU: /* Vector unavailable exception */
908 break;
909 case POWERPC_EXCP_IABR: /* Instruction address breakpoint */
910 case POWERPC_EXCP_SMI: /* System management interrupt */
911 case POWERPC_EXCP_THERM: /* Thermal interrupt */
912 case POWERPC_EXCP_PERFM: /* Embedded performance monitor interrupt */
913 case POWERPC_EXCP_VPUA: /* Vector assist exception */
914 cpu_abort(cs, "%s exception not implemented\n",
915 powerpc_excp_name(excp));
916 break;
917 default:
918 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
919 break;
922 /* Sanity check */
923 if (!(env->msr_mask & MSR_HVB)) {
924 if (new_msr & MSR_HVB) {
925 cpu_abort(cs, "Trying to deliver HV exception (MSR) %d with "
926 "no HV support\n", excp);
931 * Sort out endianness of interrupt, this differs depending on the
932 * CPU, the HV mode, etc...
934 if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) {
935 new_msr |= (target_ulong)1 << MSR_LE;
938 /* Save PC */
939 env->spr[SPR_SRR0] = env->nip;
941 /* Save MSR */
942 env->spr[SPR_SRR1] = msr;
944 powerpc_set_excp_state(cpu, vector, new_msr);
947 static void powerpc_excp_booke(PowerPCCPU *cpu, int excp)
949 CPUState *cs = CPU(cpu);
950 CPUPPCState *env = &cpu->env;
951 target_ulong msr, new_msr, vector;
952 int srr0, srr1;
954 if (excp <= POWERPC_EXCP_NONE || excp >= POWERPC_EXCP_NB) {
955 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
958 qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx
959 " => %s (%d) error=%02x\n", env->nip, powerpc_excp_name(excp),
960 excp, env->error_code);
962 msr = env->msr;
965 * new interrupt handler msr preserves existing ME unless
966 * explicitly overriden
968 new_msr = env->msr & ((target_ulong)1 << MSR_ME);
970 /* target registers */
971 srr0 = SPR_SRR0;
972 srr1 = SPR_SRR1;
975 * Hypervisor emulation assistance interrupt only exists on server
976 * arch 2.05 server or later.
978 if (excp == POWERPC_EXCP_HV_EMU) {
979 excp = POWERPC_EXCP_PROGRAM;
982 #ifdef TARGET_PPC64
984 * SPEU and VPU share the same IVOR but they exist in different
985 * processors. SPEU is e500v1/2 only and VPU is e6500 only.
987 if (excp == POWERPC_EXCP_VPU) {
988 excp = POWERPC_EXCP_SPEU;
990 #endif
992 vector = env->excp_vectors[excp];
993 if (vector == (target_ulong)-1ULL) {
994 cpu_abort(cs, "Raised an exception without defined vector %d\n",
995 excp);
998 vector |= env->excp_prefix;
1000 switch (excp) {
1001 case POWERPC_EXCP_CRITICAL: /* Critical input */
1002 srr0 = SPR_BOOKE_CSRR0;
1003 srr1 = SPR_BOOKE_CSRR1;
1004 break;
1005 case POWERPC_EXCP_MCHECK: /* Machine check exception */
1006 if (msr_me == 0) {
1008 * Machine check exception is not enabled. Enter
1009 * checkstop state.
1011 fprintf(stderr, "Machine check while not allowed. "
1012 "Entering checkstop state\n");
1013 if (qemu_log_separate()) {
1014 qemu_log("Machine check while not allowed. "
1015 "Entering checkstop state\n");
1017 cs->halted = 1;
1018 cpu_interrupt_exittb(cs);
1021 /* machine check exceptions don't have ME set */
1022 new_msr &= ~((target_ulong)1 << MSR_ME);
1024 /* FIXME: choose one or the other based on CPU type */
1025 srr0 = SPR_BOOKE_MCSRR0;
1026 srr1 = SPR_BOOKE_MCSRR1;
1028 env->spr[SPR_BOOKE_CSRR0] = env->nip;
1029 env->spr[SPR_BOOKE_CSRR1] = msr;
1031 break;
1032 case POWERPC_EXCP_DSI: /* Data storage exception */
1033 trace_ppc_excp_dsi(env->spr[SPR_BOOKE_ESR], env->spr[SPR_BOOKE_DEAR]);
1034 break;
1035 case POWERPC_EXCP_ISI: /* Instruction storage exception */
1036 trace_ppc_excp_isi(msr, env->nip);
1037 break;
1038 case POWERPC_EXCP_EXTERNAL: /* External input */
1039 if (env->mpic_proxy) {
1040 /* IACK the IRQ on delivery */
1041 env->spr[SPR_BOOKE_EPR] = ldl_phys(cs->as, env->mpic_iack);
1043 break;
1044 case POWERPC_EXCP_ALIGN: /* Alignment exception */
1045 break;
1046 case POWERPC_EXCP_PROGRAM: /* Program exception */
1047 switch (env->error_code & ~0xF) {
1048 case POWERPC_EXCP_FP:
1049 if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) {
1050 trace_ppc_excp_fp_ignore();
1051 cs->exception_index = POWERPC_EXCP_NONE;
1052 env->error_code = 0;
1053 return;
1057 * FP exceptions always have NIP pointing to the faulting
1058 * instruction, so always use store_next and claim we are
1059 * precise in the MSR.
1061 msr |= 0x00100000;
1062 env->spr[SPR_BOOKE_ESR] = ESR_FP;
1063 break;
1064 case POWERPC_EXCP_INVAL:
1065 trace_ppc_excp_inval(env->nip);
1066 msr |= 0x00080000;
1067 env->spr[SPR_BOOKE_ESR] = ESR_PIL;
1068 break;
1069 case POWERPC_EXCP_PRIV:
1070 msr |= 0x00040000;
1071 env->spr[SPR_BOOKE_ESR] = ESR_PPR;
1072 break;
1073 case POWERPC_EXCP_TRAP:
1074 msr |= 0x00020000;
1075 env->spr[SPR_BOOKE_ESR] = ESR_PTR;
1076 break;
1077 default:
1078 /* Should never occur */
1079 cpu_abort(cs, "Invalid program exception %d. Aborting\n",
1080 env->error_code);
1081 break;
1083 break;
1084 case POWERPC_EXCP_SYSCALL: /* System call exception */
1085 dump_syscall(env);
1088 * We need to correct the NIP which in this case is supposed
1089 * to point to the next instruction
1091 env->nip += 4;
1092 break;
1093 case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
1094 case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */
1095 case POWERPC_EXCP_DECR: /* Decrementer exception */
1096 break;
1097 case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt */
1098 /* FIT on 4xx */
1099 trace_ppc_excp_print("FIT");
1100 break;
1101 case POWERPC_EXCP_WDT: /* Watchdog timer interrupt */
1102 trace_ppc_excp_print("WDT");
1103 srr0 = SPR_BOOKE_CSRR0;
1104 srr1 = SPR_BOOKE_CSRR1;
1105 break;
1106 case POWERPC_EXCP_DTLB: /* Data TLB error */
1107 case POWERPC_EXCP_ITLB: /* Instruction TLB error */
1108 break;
1109 case POWERPC_EXCP_DEBUG: /* Debug interrupt */
1110 if (env->flags & POWERPC_FLAG_DE) {
1111 /* FIXME: choose one or the other based on CPU type */
1112 srr0 = SPR_BOOKE_DSRR0;
1113 srr1 = SPR_BOOKE_DSRR1;
1115 env->spr[SPR_BOOKE_CSRR0] = env->nip;
1116 env->spr[SPR_BOOKE_CSRR1] = msr;
1118 /* DBSR already modified by caller */
1119 } else {
1120 cpu_abort(cs, "Debug exception triggered on unsupported model\n");
1122 break;
1123 case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavailable/VPU */
1124 env->spr[SPR_BOOKE_ESR] = ESR_SPV;
1125 break;
1126 case POWERPC_EXCP_RESET: /* System reset exception */
1127 if (msr_pow) {
1128 cpu_abort(cs, "Trying to deliver power-saving system reset "
1129 "exception %d with no HV support\n", excp);
1131 break;
1132 case POWERPC_EXCP_EFPDI: /* Embedded floating-point data interrupt */
1133 case POWERPC_EXCP_EFPRI: /* Embedded floating-point round interrupt */
1134 cpu_abort(cs, "%s exception not implemented\n",
1135 powerpc_excp_name(excp));
1136 break;
1137 default:
1138 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
1139 break;
1142 /* Sanity check */
1143 if (!(env->msr_mask & MSR_HVB)) {
1144 if (new_msr & MSR_HVB) {
1145 cpu_abort(cs, "Trying to deliver HV exception (MSR) %d with "
1146 "no HV support\n", excp);
1148 if (srr0 == SPR_HSRR0) {
1149 cpu_abort(cs, "Trying to deliver HV exception (HSRR) %d with "
1150 "no HV support\n", excp);
1154 #if defined(TARGET_PPC64)
1155 if (env->spr[SPR_BOOKE_EPCR] & EPCR_ICM) {
1156 /* Cat.64-bit: EPCR.ICM is copied to MSR.CM */
1157 new_msr |= (target_ulong)1 << MSR_CM;
1158 } else {
1159 vector = (uint32_t)vector;
1161 #endif
1163 /* Save PC */
1164 env->spr[srr0] = env->nip;
1166 /* Save MSR */
1167 env->spr[srr1] = msr;
1169 powerpc_set_excp_state(cpu, vector, new_msr);
1172 #ifdef TARGET_PPC64
1173 static void powerpc_excp_books(PowerPCCPU *cpu, int excp)
1175 CPUState *cs = CPU(cpu);
1176 CPUPPCState *env = &cpu->env;
1177 int excp_model = env->excp_model;
1178 target_ulong msr, new_msr, vector;
1179 int srr0, srr1, lev = -1;
1181 if (excp <= POWERPC_EXCP_NONE || excp >= POWERPC_EXCP_NB) {
1182 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
1185 qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx
1186 " => %s (%d) error=%02x\n", env->nip, powerpc_excp_name(excp),
1187 excp, env->error_code);
1189 /* new srr1 value excluding must-be-zero bits */
1190 msr = env->msr & ~0x783f0000ULL;
1193 * new interrupt handler msr preserves existing HV and ME unless
1194 * explicitly overriden
1196 new_msr = env->msr & (((target_ulong)1 << MSR_ME) | MSR_HVB);
1198 /* target registers */
1199 srr0 = SPR_SRR0;
1200 srr1 = SPR_SRR1;
1203 * check for special resume at 0x100 from doze/nap/sleep/winkle on
1204 * P7/P8/P9
1206 if (env->resume_as_sreset) {
1207 excp = powerpc_reset_wakeup(cs, env, excp, &msr);
1211 * We don't want to generate a Hypervisor Emulation Assistance
1212 * Interrupt if we don't have HVB in msr_mask (PAPR mode).
1214 if (excp == POWERPC_EXCP_HV_EMU && !(env->msr_mask & MSR_HVB)) {
1215 excp = POWERPC_EXCP_PROGRAM;
1218 vector = env->excp_vectors[excp];
1219 if (vector == (target_ulong)-1ULL) {
1220 cpu_abort(cs, "Raised an exception without defined vector %d\n",
1221 excp);
1224 vector |= env->excp_prefix;
1226 switch (excp) {
1227 case POWERPC_EXCP_MCHECK: /* Machine check exception */
1228 if (msr_me == 0) {
1230 * Machine check exception is not enabled. Enter
1231 * checkstop state.
1233 fprintf(stderr, "Machine check while not allowed. "
1234 "Entering checkstop state\n");
1235 if (qemu_log_separate()) {
1236 qemu_log("Machine check while not allowed. "
1237 "Entering checkstop state\n");
1239 cs->halted = 1;
1240 cpu_interrupt_exittb(cs);
1242 if (env->msr_mask & MSR_HVB) {
1244 * ISA specifies HV, but can be delivered to guest with HV
1245 * clear (e.g., see FWNMI in PAPR).
1247 new_msr |= (target_ulong)MSR_HVB;
1250 /* machine check exceptions don't have ME set */
1251 new_msr &= ~((target_ulong)1 << MSR_ME);
1253 break;
1254 case POWERPC_EXCP_DSI: /* Data storage exception */
1255 trace_ppc_excp_dsi(env->spr[SPR_DSISR], env->spr[SPR_DAR]);
1256 break;
1257 case POWERPC_EXCP_ISI: /* Instruction storage exception */
1258 trace_ppc_excp_isi(msr, env->nip);
1259 msr |= env->error_code;
1260 break;
1261 case POWERPC_EXCP_EXTERNAL: /* External input */
1263 bool lpes0;
1266 * LPES0 is only taken into consideration if we support HV
1267 * mode for this CPU.
1269 if (!env->has_hv_mode) {
1270 break;
1273 lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0);
1275 if (!lpes0) {
1276 new_msr |= (target_ulong)MSR_HVB;
1277 new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
1278 srr0 = SPR_HSRR0;
1279 srr1 = SPR_HSRR1;
1282 break;
1284 case POWERPC_EXCP_ALIGN: /* Alignment exception */
1285 /* Get rS/rD and rA from faulting opcode */
1287 * Note: the opcode fields will not be set properly for a
1288 * direct store load/store, but nobody cares as nobody
1289 * actually uses direct store segments.
1291 env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16;
1292 break;
1293 case POWERPC_EXCP_PROGRAM: /* Program exception */
1294 switch (env->error_code & ~0xF) {
1295 case POWERPC_EXCP_FP:
1296 if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) {
1297 trace_ppc_excp_fp_ignore();
1298 cs->exception_index = POWERPC_EXCP_NONE;
1299 env->error_code = 0;
1300 return;
1304 * FP exceptions always have NIP pointing to the faulting
1305 * instruction, so always use store_next and claim we are
1306 * precise in the MSR.
1308 msr |= 0x00100000;
1309 break;
1310 case POWERPC_EXCP_INVAL:
1311 trace_ppc_excp_inval(env->nip);
1312 msr |= 0x00080000;
1313 break;
1314 case POWERPC_EXCP_PRIV:
1315 msr |= 0x00040000;
1316 break;
1317 case POWERPC_EXCP_TRAP:
1318 msr |= 0x00020000;
1319 break;
1320 default:
1321 /* Should never occur */
1322 cpu_abort(cs, "Invalid program exception %d. Aborting\n",
1323 env->error_code);
1324 break;
1326 break;
1327 case POWERPC_EXCP_SYSCALL: /* System call exception */
1328 lev = env->error_code;
1330 if ((lev == 1) && cpu->vhyp) {
1331 dump_hcall(env);
1332 } else {
1333 dump_syscall(env);
1337 * We need to correct the NIP which in this case is supposed
1338 * to point to the next instruction
1340 env->nip += 4;
1342 /* "PAPR mode" built-in hypercall emulation */
1343 if ((lev == 1) && cpu->vhyp) {
1344 PPCVirtualHypervisorClass *vhc =
1345 PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
1346 vhc->hypercall(cpu->vhyp, cpu);
1347 return;
1349 if (lev == 1) {
1350 new_msr |= (target_ulong)MSR_HVB;
1352 break;
1353 case POWERPC_EXCP_SYSCALL_VECTORED: /* scv exception */
1354 lev = env->error_code;
1355 dump_syscall(env);
1356 env->nip += 4;
1357 new_msr |= env->msr & ((target_ulong)1 << MSR_EE);
1358 new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
1360 vector += lev * 0x20;
1362 env->lr = env->nip;
1363 env->ctr = msr;
1364 break;
1365 case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
1366 case POWERPC_EXCP_DECR: /* Decrementer exception */
1367 break;
1368 case POWERPC_EXCP_RESET: /* System reset exception */
1369 /* A power-saving exception sets ME, otherwise it is unchanged */
1370 if (msr_pow) {
1371 /* indicate that we resumed from power save mode */
1372 msr |= 0x10000;
1373 new_msr |= ((target_ulong)1 << MSR_ME);
1375 if (env->msr_mask & MSR_HVB) {
1377 * ISA specifies HV, but can be delivered to guest with HV
1378 * clear (e.g., see FWNMI in PAPR, NMI injection in QEMU).
1380 new_msr |= (target_ulong)MSR_HVB;
1381 } else {
1382 if (msr_pow) {
1383 cpu_abort(cs, "Trying to deliver power-saving system reset "
1384 "exception %d with no HV support\n", excp);
1387 break;
1388 case POWERPC_EXCP_DSEG: /* Data segment exception */
1389 case POWERPC_EXCP_ISEG: /* Instruction segment exception */
1390 case POWERPC_EXCP_TRACE: /* Trace exception */
1391 break;
1392 case POWERPC_EXCP_HISI: /* Hypervisor instruction storage exception */
1393 msr |= env->error_code;
1394 /* fall through */
1395 case POWERPC_EXCP_HDECR: /* Hypervisor decrementer exception */
1396 case POWERPC_EXCP_HDSI: /* Hypervisor data storage exception */
1397 case POWERPC_EXCP_SDOOR_HV: /* Hypervisor Doorbell interrupt */
1398 case POWERPC_EXCP_HV_EMU:
1399 case POWERPC_EXCP_HVIRT: /* Hypervisor virtualization */
1400 srr0 = SPR_HSRR0;
1401 srr1 = SPR_HSRR1;
1402 new_msr |= (target_ulong)MSR_HVB;
1403 new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
1404 break;
1405 case POWERPC_EXCP_VPU: /* Vector unavailable exception */
1406 case POWERPC_EXCP_VSXU: /* VSX unavailable exception */
1407 case POWERPC_EXCP_FU: /* Facility unavailable exception */
1408 env->spr[SPR_FSCR] |= ((target_ulong)env->error_code << 56);
1409 break;
1410 case POWERPC_EXCP_HV_FU: /* Hypervisor Facility Unavailable Exception */
1411 env->spr[SPR_HFSCR] |= ((target_ulong)env->error_code << FSCR_IC_POS);
1412 srr0 = SPR_HSRR0;
1413 srr1 = SPR_HSRR1;
1414 new_msr |= (target_ulong)MSR_HVB;
1415 new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
1416 break;
1417 case POWERPC_EXCP_THERM: /* Thermal interrupt */
1418 case POWERPC_EXCP_PERFM: /* Embedded performance monitor interrupt */
1419 case POWERPC_EXCP_VPUA: /* Vector assist exception */
1420 case POWERPC_EXCP_MAINT: /* Maintenance exception */
1421 case POWERPC_EXCP_SDOOR: /* Doorbell interrupt */
1422 case POWERPC_EXCP_HV_MAINT: /* Hypervisor Maintenance exception */
1423 cpu_abort(cs, "%s exception not implemented\n",
1424 powerpc_excp_name(excp));
1425 break;
1426 default:
1427 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
1428 break;
1431 /* Sanity check */
1432 if (!(env->msr_mask & MSR_HVB)) {
1433 if (new_msr & MSR_HVB) {
1434 cpu_abort(cs, "Trying to deliver HV exception (MSR) %d with "
1435 "no HV support\n", excp);
1437 if (srr0 == SPR_HSRR0) {
1438 cpu_abort(cs, "Trying to deliver HV exception (HSRR) %d with "
1439 "no HV support\n", excp);
1444 * Sort out endianness of interrupt, this differs depending on the
1445 * CPU, the HV mode, etc...
1447 if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) {
1448 new_msr |= (target_ulong)1 << MSR_LE;
1451 new_msr |= (target_ulong)1 << MSR_SF;
1453 if (excp != POWERPC_EXCP_SYSCALL_VECTORED) {
1454 /* Save PC */
1455 env->spr[srr0] = env->nip;
1457 /* Save MSR */
1458 env->spr[srr1] = msr;
1461 /* This can update new_msr and vector if AIL applies */
1462 ppc_excp_apply_ail(cpu, excp_model, excp, msr, &new_msr, &vector);
1464 powerpc_set_excp_state(cpu, vector, new_msr);
1466 #else
1467 static inline void powerpc_excp_books(PowerPCCPU *cpu, int excp)
1469 g_assert_not_reached();
1471 #endif
1474 * Note that this function should be greatly optimized when called
1475 * with a constant excp, from ppc_hw_interrupt
1477 static inline void powerpc_excp_legacy(PowerPCCPU *cpu, int excp)
1479 CPUState *cs = CPU(cpu);
1480 CPUPPCState *env = &cpu->env;
1481 int excp_model = env->excp_model;
1482 target_ulong msr, new_msr, vector;
1483 int srr0, srr1, lev = -1;
1485 if (excp <= POWERPC_EXCP_NONE || excp >= POWERPC_EXCP_NB) {
1486 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
1489 qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx
1490 " => %s (%d) error=%02x\n", env->nip, powerpc_excp_name(excp),
1491 excp, env->error_code);
1493 /* new srr1 value excluding must-be-zero bits */
1494 if (excp_model == POWERPC_EXCP_BOOKE) {
1495 msr = env->msr;
1496 } else {
1497 msr = env->msr & ~0x783f0000ULL;
1501 * new interrupt handler msr preserves existing HV and ME unless
1502 * explicitly overriden
1504 new_msr = env->msr & (((target_ulong)1 << MSR_ME) | MSR_HVB);
1506 /* target registers */
1507 srr0 = SPR_SRR0;
1508 srr1 = SPR_SRR1;
1511 * check for special resume at 0x100 from doze/nap/sleep/winkle on
1512 * P7/P8/P9
1514 if (env->resume_as_sreset) {
1515 excp = powerpc_reset_wakeup(cs, env, excp, &msr);
1519 * Hypervisor emulation assistance interrupt only exists on server
1520 * arch 2.05 server or later. We also don't want to generate it if
1521 * we don't have HVB in msr_mask (PAPR mode).
1523 if (excp == POWERPC_EXCP_HV_EMU
1524 #if defined(TARGET_PPC64)
1525 && !(mmu_is_64bit(env->mmu_model) && (env->msr_mask & MSR_HVB))
1526 #endif /* defined(TARGET_PPC64) */
1529 excp = POWERPC_EXCP_PROGRAM;
1532 #ifdef TARGET_PPC64
1534 * SPEU and VPU share the same IVOR but they exist in different
1535 * processors. SPEU is e500v1/2 only and VPU is e6500 only.
1537 if (excp_model == POWERPC_EXCP_BOOKE && excp == POWERPC_EXCP_VPU) {
1538 excp = POWERPC_EXCP_SPEU;
1540 #endif
1542 vector = env->excp_vectors[excp];
1543 if (vector == (target_ulong)-1ULL) {
1544 cpu_abort(cs, "Raised an exception without defined vector %d\n",
1545 excp);
1548 vector |= env->excp_prefix;
1550 switch (excp) {
1551 case POWERPC_EXCP_CRITICAL: /* Critical input */
1552 switch (excp_model) {
1553 case POWERPC_EXCP_40x:
1554 srr0 = SPR_40x_SRR2;
1555 srr1 = SPR_40x_SRR3;
1556 break;
1557 case POWERPC_EXCP_BOOKE:
1558 srr0 = SPR_BOOKE_CSRR0;
1559 srr1 = SPR_BOOKE_CSRR1;
1560 break;
1561 case POWERPC_EXCP_6xx:
1562 break;
1563 default:
1564 goto excp_invalid;
1566 break;
1567 case POWERPC_EXCP_MCHECK: /* Machine check exception */
1568 if (msr_me == 0) {
1570 * Machine check exception is not enabled. Enter
1571 * checkstop state.
1573 fprintf(stderr, "Machine check while not allowed. "
1574 "Entering checkstop state\n");
1575 if (qemu_log_separate()) {
1576 qemu_log("Machine check while not allowed. "
1577 "Entering checkstop state\n");
1579 cs->halted = 1;
1580 cpu_interrupt_exittb(cs);
1582 if (env->msr_mask & MSR_HVB) {
1584 * ISA specifies HV, but can be delivered to guest with HV
1585 * clear (e.g., see FWNMI in PAPR).
1587 new_msr |= (target_ulong)MSR_HVB;
1590 /* machine check exceptions don't have ME set */
1591 new_msr &= ~((target_ulong)1 << MSR_ME);
1593 /* XXX: should also have something loaded in DAR / DSISR */
1594 switch (excp_model) {
1595 case POWERPC_EXCP_40x:
1596 srr0 = SPR_40x_SRR2;
1597 srr1 = SPR_40x_SRR3;
1598 break;
1599 case POWERPC_EXCP_BOOKE:
1600 /* FIXME: choose one or the other based on CPU type */
1601 srr0 = SPR_BOOKE_MCSRR0;
1602 srr1 = SPR_BOOKE_MCSRR1;
1604 env->spr[SPR_BOOKE_CSRR0] = env->nip;
1605 env->spr[SPR_BOOKE_CSRR1] = msr;
1606 break;
1607 default:
1608 break;
1610 break;
1611 case POWERPC_EXCP_DSI: /* Data storage exception */
1612 trace_ppc_excp_dsi(env->spr[SPR_DSISR], env->spr[SPR_DAR]);
1613 break;
1614 case POWERPC_EXCP_ISI: /* Instruction storage exception */
1615 trace_ppc_excp_isi(msr, env->nip);
1616 msr |= env->error_code;
1617 break;
1618 case POWERPC_EXCP_EXTERNAL: /* External input */
1620 bool lpes0;
1622 cs = CPU(cpu);
1625 * Exception targeting modifiers
1627 * LPES0 is supported on POWER7/8/9
1628 * LPES1 is not supported (old iSeries mode)
1630 * On anything else, we behave as if LPES0 is 1
1631 * (externals don't alter MSR:HV)
1633 #if defined(TARGET_PPC64)
1634 if (excp_model == POWERPC_EXCP_POWER7 ||
1635 excp_model == POWERPC_EXCP_POWER8 ||
1636 excp_model == POWERPC_EXCP_POWER9 ||
1637 excp_model == POWERPC_EXCP_POWER10) {
1638 lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0);
1639 } else
1640 #endif /* defined(TARGET_PPC64) */
1642 lpes0 = true;
1645 if (!lpes0) {
1646 new_msr |= (target_ulong)MSR_HVB;
1647 new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
1648 srr0 = SPR_HSRR0;
1649 srr1 = SPR_HSRR1;
1651 if (env->mpic_proxy) {
1652 /* IACK the IRQ on delivery */
1653 env->spr[SPR_BOOKE_EPR] = ldl_phys(cs->as, env->mpic_iack);
1655 break;
1657 case POWERPC_EXCP_ALIGN: /* Alignment exception */
1658 /* Get rS/rD and rA from faulting opcode */
1660 * Note: the opcode fields will not be set properly for a
1661 * direct store load/store, but nobody cares as nobody
1662 * actually uses direct store segments.
1664 env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16;
1665 break;
1666 case POWERPC_EXCP_PROGRAM: /* Program exception */
1667 switch (env->error_code & ~0xF) {
1668 case POWERPC_EXCP_FP:
1669 if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) {
1670 trace_ppc_excp_fp_ignore();
1671 cs->exception_index = POWERPC_EXCP_NONE;
1672 env->error_code = 0;
1673 return;
1677 * FP exceptions always have NIP pointing to the faulting
1678 * instruction, so always use store_next and claim we are
1679 * precise in the MSR.
1681 msr |= 0x00100000;
1682 env->spr[SPR_BOOKE_ESR] = ESR_FP;
1683 break;
1684 case POWERPC_EXCP_INVAL:
1685 trace_ppc_excp_inval(env->nip);
1686 msr |= 0x00080000;
1687 env->spr[SPR_BOOKE_ESR] = ESR_PIL;
1688 break;
1689 case POWERPC_EXCP_PRIV:
1690 msr |= 0x00040000;
1691 env->spr[SPR_BOOKE_ESR] = ESR_PPR;
1692 break;
1693 case POWERPC_EXCP_TRAP:
1694 msr |= 0x00020000;
1695 env->spr[SPR_BOOKE_ESR] = ESR_PTR;
1696 break;
1697 default:
1698 /* Should never occur */
1699 cpu_abort(cs, "Invalid program exception %d. Aborting\n",
1700 env->error_code);
1701 break;
1703 break;
1704 case POWERPC_EXCP_SYSCALL: /* System call exception */
1705 lev = env->error_code;
1707 if ((lev == 1) && cpu->vhyp) {
1708 dump_hcall(env);
1709 } else {
1710 dump_syscall(env);
1714 * We need to correct the NIP which in this case is supposed
1715 * to point to the next instruction
1717 env->nip += 4;
1719 /* "PAPR mode" built-in hypercall emulation */
1720 if ((lev == 1) && cpu->vhyp) {
1721 PPCVirtualHypervisorClass *vhc =
1722 PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
1723 vhc->hypercall(cpu->vhyp, cpu);
1724 return;
1726 if (lev == 1) {
1727 new_msr |= (target_ulong)MSR_HVB;
1729 break;
1730 case POWERPC_EXCP_SYSCALL_VECTORED: /* scv exception */
1731 lev = env->error_code;
1732 dump_syscall(env);
1733 env->nip += 4;
1734 new_msr |= env->msr & ((target_ulong)1 << MSR_EE);
1735 new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
1737 vector += lev * 0x20;
1739 env->lr = env->nip;
1740 env->ctr = msr;
1741 break;
1742 case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
1743 case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */
1744 case POWERPC_EXCP_DECR: /* Decrementer exception */
1745 break;
1746 case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt */
1747 /* FIT on 4xx */
1748 trace_ppc_excp_print("FIT");
1749 break;
1750 case POWERPC_EXCP_WDT: /* Watchdog timer interrupt */
1751 trace_ppc_excp_print("WDT");
1752 switch (excp_model) {
1753 case POWERPC_EXCP_BOOKE:
1754 srr0 = SPR_BOOKE_CSRR0;
1755 srr1 = SPR_BOOKE_CSRR1;
1756 break;
1757 default:
1758 break;
1760 break;
1761 case POWERPC_EXCP_DTLB: /* Data TLB error */
1762 case POWERPC_EXCP_ITLB: /* Instruction TLB error */
1763 break;
1764 case POWERPC_EXCP_DEBUG: /* Debug interrupt */
1765 if (env->flags & POWERPC_FLAG_DE) {
1766 /* FIXME: choose one or the other based on CPU type */
1767 srr0 = SPR_BOOKE_DSRR0;
1768 srr1 = SPR_BOOKE_DSRR1;
1770 env->spr[SPR_BOOKE_CSRR0] = env->nip;
1771 env->spr[SPR_BOOKE_CSRR1] = msr;
1773 /* DBSR already modified by caller */
1774 } else {
1775 cpu_abort(cs, "Debug exception triggered on unsupported model\n");
1777 break;
1778 case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavailable/VPU */
1779 env->spr[SPR_BOOKE_ESR] = ESR_SPV;
1780 break;
1781 case POWERPC_EXCP_DOORI: /* Embedded doorbell interrupt */
1782 break;
1783 case POWERPC_EXCP_DOORCI: /* Embedded doorbell critical interrupt */
1784 srr0 = SPR_BOOKE_CSRR0;
1785 srr1 = SPR_BOOKE_CSRR1;
1786 break;
1787 case POWERPC_EXCP_RESET: /* System reset exception */
1788 /* A power-saving exception sets ME, otherwise it is unchanged */
1789 if (msr_pow) {
1790 /* indicate that we resumed from power save mode */
1791 msr |= 0x10000;
1792 new_msr |= ((target_ulong)1 << MSR_ME);
1794 if (env->msr_mask & MSR_HVB) {
1796 * ISA specifies HV, but can be delivered to guest with HV
1797 * clear (e.g., see FWNMI in PAPR, NMI injection in QEMU).
1799 new_msr |= (target_ulong)MSR_HVB;
1800 } else {
1801 if (msr_pow) {
1802 cpu_abort(cs, "Trying to deliver power-saving system reset "
1803 "exception %d with no HV support\n", excp);
1806 break;
1807 case POWERPC_EXCP_DSEG: /* Data segment exception */
1808 case POWERPC_EXCP_ISEG: /* Instruction segment exception */
1809 case POWERPC_EXCP_TRACE: /* Trace exception */
1810 break;
1811 case POWERPC_EXCP_HISI: /* Hypervisor instruction storage exception */
1812 msr |= env->error_code;
1813 /* fall through */
1814 case POWERPC_EXCP_HDECR: /* Hypervisor decrementer exception */
1815 case POWERPC_EXCP_HDSI: /* Hypervisor data storage exception */
1816 case POWERPC_EXCP_HDSEG: /* Hypervisor data segment exception */
1817 case POWERPC_EXCP_HISEG: /* Hypervisor instruction segment exception */
1818 case POWERPC_EXCP_SDOOR_HV: /* Hypervisor Doorbell interrupt */
1819 case POWERPC_EXCP_HV_EMU:
1820 case POWERPC_EXCP_HVIRT: /* Hypervisor virtualization */
1821 srr0 = SPR_HSRR0;
1822 srr1 = SPR_HSRR1;
1823 new_msr |= (target_ulong)MSR_HVB;
1824 new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
1825 break;
1826 case POWERPC_EXCP_VPU: /* Vector unavailable exception */
1827 case POWERPC_EXCP_VSXU: /* VSX unavailable exception */
1828 case POWERPC_EXCP_FU: /* Facility unavailable exception */
1829 #ifdef TARGET_PPC64
1830 env->spr[SPR_FSCR] |= ((target_ulong)env->error_code << 56);
1831 #endif
1832 break;
1833 case POWERPC_EXCP_HV_FU: /* Hypervisor Facility Unavailable Exception */
1834 #ifdef TARGET_PPC64
1835 env->spr[SPR_HFSCR] |= ((target_ulong)env->error_code << FSCR_IC_POS);
1836 srr0 = SPR_HSRR0;
1837 srr1 = SPR_HSRR1;
1838 new_msr |= (target_ulong)MSR_HVB;
1839 new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
1840 #endif
1841 break;
1842 case POWERPC_EXCP_PIT: /* Programmable interval timer interrupt */
1843 trace_ppc_excp_print("PIT");
1844 break;
1845 case POWERPC_EXCP_IFTLB: /* Instruction fetch TLB error */
1846 case POWERPC_EXCP_DLTLB: /* Data load TLB miss */
1847 case POWERPC_EXCP_DSTLB: /* Data store TLB miss */
1848 switch (excp_model) {
1849 case POWERPC_EXCP_6xx:
1850 /* Swap temporary saved registers with GPRs */
1851 if (!(new_msr & ((target_ulong)1 << MSR_TGPR))) {
1852 new_msr |= (target_ulong)1 << MSR_TGPR;
1853 hreg_swap_gpr_tgpr(env);
1855 /* fall through */
1856 case POWERPC_EXCP_7x5:
1857 ppc_excp_debug_sw_tlb(env, excp);
1859 msr |= env->crf[0] << 28;
1860 msr |= env->error_code; /* key, D/I, S/L bits */
1861 /* Set way using a LRU mechanism */
1862 msr |= ((env->last_way + 1) & (env->nb_ways - 1)) << 17;
1863 break;
1864 default:
1865 cpu_abort(cs, "Invalid TLB miss exception\n");
1866 break;
1868 break;
1869 case POWERPC_EXCP_EFPDI: /* Embedded floating-point data interrupt */
1870 case POWERPC_EXCP_EFPRI: /* Embedded floating-point round interrupt */
1871 case POWERPC_EXCP_EPERFM: /* Embedded performance monitor interrupt */
1872 case POWERPC_EXCP_FPA: /* Floating-point assist exception */
1873 case POWERPC_EXCP_DABR: /* Data address breakpoint */
1874 case POWERPC_EXCP_IABR: /* Instruction address breakpoint */
1875 case POWERPC_EXCP_SMI: /* System management interrupt */
1876 case POWERPC_EXCP_THERM: /* Thermal interrupt */
1877 case POWERPC_EXCP_PERFM: /* Embedded performance monitor interrupt */
1878 case POWERPC_EXCP_VPUA: /* Vector assist exception */
1879 case POWERPC_EXCP_SOFTP: /* Soft patch exception */
1880 case POWERPC_EXCP_MAINT: /* Maintenance exception */
1881 case POWERPC_EXCP_MEXTBR: /* Maskable external breakpoint */
1882 case POWERPC_EXCP_NMEXTBR: /* Non maskable external breakpoint */
1883 cpu_abort(cs, "%s exception not implemented\n",
1884 powerpc_excp_name(excp));
1885 break;
1886 default:
1887 excp_invalid:
1888 cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
1889 break;
1892 /* Sanity check */
1893 if (!(env->msr_mask & MSR_HVB)) {
1894 if (new_msr & MSR_HVB) {
1895 cpu_abort(cs, "Trying to deliver HV exception (MSR) %d with "
1896 "no HV support\n", excp);
1898 if (srr0 == SPR_HSRR0) {
1899 cpu_abort(cs, "Trying to deliver HV exception (HSRR) %d with "
1900 "no HV support\n", excp);
1905 * Sort out endianness of interrupt, this differs depending on the
1906 * CPU, the HV mode, etc...
1908 if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) {
1909 new_msr |= (target_ulong)1 << MSR_LE;
1912 #if defined(TARGET_PPC64)
1913 if (excp_model == POWERPC_EXCP_BOOKE) {
1914 if (env->spr[SPR_BOOKE_EPCR] & EPCR_ICM) {
1915 /* Cat.64-bit: EPCR.ICM is copied to MSR.CM */
1916 new_msr |= (target_ulong)1 << MSR_CM;
1917 } else {
1918 vector = (uint32_t)vector;
1920 } else {
1921 if (!msr_isf && !mmu_is_64bit(env->mmu_model)) {
1922 vector = (uint32_t)vector;
1923 } else {
1924 new_msr |= (target_ulong)1 << MSR_SF;
1927 #endif
1929 if (excp != POWERPC_EXCP_SYSCALL_VECTORED) {
1930 /* Save PC */
1931 env->spr[srr0] = env->nip;
1933 /* Save MSR */
1934 env->spr[srr1] = msr;
1937 /* This can update new_msr and vector if AIL applies */
1938 ppc_excp_apply_ail(cpu, excp_model, excp, msr, &new_msr, &vector);
1940 powerpc_set_excp_state(cpu, vector, new_msr);
1943 static void powerpc_excp(PowerPCCPU *cpu, int excp)
1945 CPUPPCState *env = &cpu->env;
1947 switch (env->excp_model) {
1948 case POWERPC_EXCP_40x:
1949 powerpc_excp_40x(cpu, excp);
1950 break;
1951 case POWERPC_EXCP_6xx:
1952 powerpc_excp_6xx(cpu, excp);
1953 break;
1954 case POWERPC_EXCP_74xx:
1955 powerpc_excp_74xx(cpu, excp);
1956 break;
1957 case POWERPC_EXCP_BOOKE:
1958 powerpc_excp_booke(cpu, excp);
1959 break;
1960 case POWERPC_EXCP_970:
1961 case POWERPC_EXCP_POWER7:
1962 case POWERPC_EXCP_POWER8:
1963 case POWERPC_EXCP_POWER9:
1964 case POWERPC_EXCP_POWER10:
1965 powerpc_excp_books(cpu, excp);
1966 break;
1967 default:
1968 powerpc_excp_legacy(cpu, excp);
1972 void ppc_cpu_do_interrupt(CPUState *cs)
1974 PowerPCCPU *cpu = POWERPC_CPU(cs);
1976 powerpc_excp(cpu, cs->exception_index);
1979 static void ppc_hw_interrupt(CPUPPCState *env)
1981 PowerPCCPU *cpu = env_archcpu(env);
1982 bool async_deliver;
1984 /* External reset */
1985 if (env->pending_interrupts & (1 << PPC_INTERRUPT_RESET)) {
1986 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_RESET);
1987 powerpc_excp(cpu, POWERPC_EXCP_RESET);
1988 return;
1990 /* Machine check exception */
1991 if (env->pending_interrupts & (1 << PPC_INTERRUPT_MCK)) {
1992 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_MCK);
1993 powerpc_excp(cpu, POWERPC_EXCP_MCHECK);
1994 return;
1996 #if 0 /* TODO */
1997 /* External debug exception */
1998 if (env->pending_interrupts & (1 << PPC_INTERRUPT_DEBUG)) {
1999 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DEBUG);
2000 powerpc_excp(cpu, POWERPC_EXCP_DEBUG);
2001 return;
2003 #endif
2006 * For interrupts that gate on MSR:EE, we need to do something a
2007 * bit more subtle, as we need to let them through even when EE is
2008 * clear when coming out of some power management states (in order
2009 * for them to become a 0x100).
2011 async_deliver = (msr_ee != 0) || env->resume_as_sreset;
2013 /* Hypervisor decrementer exception */
2014 if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDECR)) {
2015 /* LPCR will be clear when not supported so this will work */
2016 bool hdice = !!(env->spr[SPR_LPCR] & LPCR_HDICE);
2017 if ((async_deliver || msr_hv == 0) && hdice) {
2018 /* HDEC clears on delivery */
2019 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDECR);
2020 powerpc_excp(cpu, POWERPC_EXCP_HDECR);
2021 return;
2025 /* Hypervisor virtualization interrupt */
2026 if (env->pending_interrupts & (1 << PPC_INTERRUPT_HVIRT)) {
2027 /* LPCR will be clear when not supported so this will work */
2028 bool hvice = !!(env->spr[SPR_LPCR] & LPCR_HVICE);
2029 if ((async_deliver || msr_hv == 0) && hvice) {
2030 powerpc_excp(cpu, POWERPC_EXCP_HVIRT);
2031 return;
2035 /* External interrupt can ignore MSR:EE under some circumstances */
2036 if (env->pending_interrupts & (1 << PPC_INTERRUPT_EXT)) {
2037 bool lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0);
2038 bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
2039 /* HEIC blocks delivery to the hypervisor */
2040 if ((async_deliver && !(heic && msr_hv && !msr_pr)) ||
2041 (env->has_hv_mode && msr_hv == 0 && !lpes0)) {
2042 powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL);
2043 return;
2046 if (msr_ce != 0) {
2047 /* External critical interrupt */
2048 if (env->pending_interrupts & (1 << PPC_INTERRUPT_CEXT)) {
2049 powerpc_excp(cpu, POWERPC_EXCP_CRITICAL);
2050 return;
2053 if (async_deliver != 0) {
2054 /* Watchdog timer on embedded PowerPC */
2055 if (env->pending_interrupts & (1 << PPC_INTERRUPT_WDT)) {
2056 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_WDT);
2057 powerpc_excp(cpu, POWERPC_EXCP_WDT);
2058 return;
2060 if (env->pending_interrupts & (1 << PPC_INTERRUPT_CDOORBELL)) {
2061 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_CDOORBELL);
2062 powerpc_excp(cpu, POWERPC_EXCP_DOORCI);
2063 return;
2065 /* Fixed interval timer on embedded PowerPC */
2066 if (env->pending_interrupts & (1 << PPC_INTERRUPT_FIT)) {
2067 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_FIT);
2068 powerpc_excp(cpu, POWERPC_EXCP_FIT);
2069 return;
2071 /* Programmable interval timer on embedded PowerPC */
2072 if (env->pending_interrupts & (1 << PPC_INTERRUPT_PIT)) {
2073 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PIT);
2074 powerpc_excp(cpu, POWERPC_EXCP_PIT);
2075 return;
2077 /* Decrementer exception */
2078 if (env->pending_interrupts & (1 << PPC_INTERRUPT_DECR)) {
2079 if (ppc_decr_clear_on_delivery(env)) {
2080 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DECR);
2082 powerpc_excp(cpu, POWERPC_EXCP_DECR);
2083 return;
2085 if (env->pending_interrupts & (1 << PPC_INTERRUPT_DOORBELL)) {
2086 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL);
2087 if (is_book3s_arch2x(env)) {
2088 powerpc_excp(cpu, POWERPC_EXCP_SDOOR);
2089 } else {
2090 powerpc_excp(cpu, POWERPC_EXCP_DOORI);
2092 return;
2094 if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDOORBELL)) {
2095 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDOORBELL);
2096 powerpc_excp(cpu, POWERPC_EXCP_SDOOR_HV);
2097 return;
2099 if (env->pending_interrupts & (1 << PPC_INTERRUPT_PERFM)) {
2100 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PERFM);
2101 powerpc_excp(cpu, POWERPC_EXCP_PERFM);
2102 return;
2104 /* Thermal interrupt */
2105 if (env->pending_interrupts & (1 << PPC_INTERRUPT_THERM)) {
2106 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_THERM);
2107 powerpc_excp(cpu, POWERPC_EXCP_THERM);
2108 return;
2112 if (env->resume_as_sreset) {
2114 * This is a bug ! It means that has_work took us out of halt without
2115 * anything to deliver while in a PM state that requires getting
2116 * out via a 0x100
2118 * This means we will incorrectly execute past the power management
2119 * instruction instead of triggering a reset.
2121 * It generally means a discrepancy between the wakeup conditions in the
2122 * processor has_work implementation and the logic in this function.
2124 cpu_abort(env_cpu(env),
2125 "Wakeup from PM state but interrupt Undelivered");
2129 void ppc_cpu_do_system_reset(CPUState *cs)
2131 PowerPCCPU *cpu = POWERPC_CPU(cs);
2133 powerpc_excp(cpu, POWERPC_EXCP_RESET);
2136 void ppc_cpu_do_fwnmi_machine_check(CPUState *cs, target_ulong vector)
2138 PowerPCCPU *cpu = POWERPC_CPU(cs);
2139 CPUPPCState *env = &cpu->env;
2140 target_ulong msr = 0;
2143 * Set MSR and NIP for the handler, SRR0/1, DAR and DSISR have already
2144 * been set by KVM.
2146 msr = (1ULL << MSR_ME);
2147 msr |= env->msr & (1ULL << MSR_SF);
2148 if (ppc_interrupts_little_endian(cpu, false)) {
2149 msr |= (1ULL << MSR_LE);
2152 powerpc_set_excp_state(cpu, vector, msr);
2155 bool ppc_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
2157 PowerPCCPU *cpu = POWERPC_CPU(cs);
2158 CPUPPCState *env = &cpu->env;
2160 if (interrupt_request & CPU_INTERRUPT_HARD) {
2161 ppc_hw_interrupt(env);
2162 if (env->pending_interrupts == 0) {
2163 cs->interrupt_request &= ~CPU_INTERRUPT_HARD;
2165 return true;
2167 return false;
2170 #endif /* !CONFIG_USER_ONLY */
2172 /*****************************************************************************/
2173 /* Exceptions processing helpers */
2175 void raise_exception_err_ra(CPUPPCState *env, uint32_t exception,
2176 uint32_t error_code, uintptr_t raddr)
2178 CPUState *cs = env_cpu(env);
2180 cs->exception_index = exception;
2181 env->error_code = error_code;
2182 cpu_loop_exit_restore(cs, raddr);
2185 void raise_exception_err(CPUPPCState *env, uint32_t exception,
2186 uint32_t error_code)
2188 raise_exception_err_ra(env, exception, error_code, 0);
2191 void raise_exception(CPUPPCState *env, uint32_t exception)
2193 raise_exception_err_ra(env, exception, 0, 0);
2196 void raise_exception_ra(CPUPPCState *env, uint32_t exception,
2197 uintptr_t raddr)
2199 raise_exception_err_ra(env, exception, 0, raddr);
2202 #ifdef CONFIG_TCG
2203 void helper_raise_exception_err(CPUPPCState *env, uint32_t exception,
2204 uint32_t error_code)
2206 raise_exception_err_ra(env, exception, error_code, 0);
2209 void helper_raise_exception(CPUPPCState *env, uint32_t exception)
2211 raise_exception_err_ra(env, exception, 0, 0);
2213 #endif
2215 #if !defined(CONFIG_USER_ONLY)
2216 #ifdef CONFIG_TCG
2217 void helper_store_msr(CPUPPCState *env, target_ulong val)
2219 uint32_t excp = hreg_store_msr(env, val, 0);
2221 if (excp != 0) {
2222 CPUState *cs = env_cpu(env);
2223 cpu_interrupt_exittb(cs);
2224 raise_exception(env, excp);
2228 #if defined(TARGET_PPC64)
2229 void helper_scv(CPUPPCState *env, uint32_t lev)
2231 if (env->spr[SPR_FSCR] & (1ull << FSCR_SCV)) {
2232 raise_exception_err(env, POWERPC_EXCP_SYSCALL_VECTORED, lev);
2233 } else {
2234 raise_exception_err(env, POWERPC_EXCP_FU, FSCR_IC_SCV);
2238 void helper_pminsn(CPUPPCState *env, powerpc_pm_insn_t insn)
2240 CPUState *cs;
2242 cs = env_cpu(env);
2243 cs->halted = 1;
2245 /* Condition for waking up at 0x100 */
2246 env->resume_as_sreset = (insn != PPC_PM_STOP) ||
2247 (env->spr[SPR_PSSCR] & PSSCR_EC);
2249 #endif /* defined(TARGET_PPC64) */
2251 static void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr)
2253 CPUState *cs = env_cpu(env);
2255 /* MSR:POW cannot be set by any form of rfi */
2256 msr &= ~(1ULL << MSR_POW);
2258 /* MSR:TGPR cannot be set by any form of rfi */
2259 if (env->flags & POWERPC_FLAG_TGPR)
2260 msr &= ~(1ULL << MSR_TGPR);
2262 #if defined(TARGET_PPC64)
2263 /* Switching to 32-bit ? Crop the nip */
2264 if (!msr_is_64bit(env, msr)) {
2265 nip = (uint32_t)nip;
2267 #else
2268 nip = (uint32_t)nip;
2269 #endif
2270 /* XXX: beware: this is false if VLE is supported */
2271 env->nip = nip & ~((target_ulong)0x00000003);
2272 hreg_store_msr(env, msr, 1);
2273 trace_ppc_excp_rfi(env->nip, env->msr);
2275 * No need to raise an exception here, as rfi is always the last
2276 * insn of a TB
2278 cpu_interrupt_exittb(cs);
2279 /* Reset the reservation */
2280 env->reserve_addr = -1;
2282 /* Context synchronizing: check if TCG TLB needs flush */
2283 check_tlb_flush(env, false);
2286 void helper_rfi(CPUPPCState *env)
2288 do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1] & 0xfffffffful);
2291 #define MSR_BOOK3S_MASK
2292 #if defined(TARGET_PPC64)
2293 void helper_rfid(CPUPPCState *env)
2296 * The architecture defines a number of rules for which bits can
2297 * change but in practice, we handle this in hreg_store_msr()
2298 * which will be called by do_rfi(), so there is no need to filter
2299 * here
2301 do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1]);
2304 void helper_rfscv(CPUPPCState *env)
2306 do_rfi(env, env->lr, env->ctr);
2309 void helper_hrfid(CPUPPCState *env)
2311 do_rfi(env, env->spr[SPR_HSRR0], env->spr[SPR_HSRR1]);
2313 #endif
2315 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
2316 void helper_rfebb(CPUPPCState *env, target_ulong s)
2318 target_ulong msr = env->msr;
2321 * Handling of BESCR bits 32:33 according to PowerISA v3.1:
2323 * "If BESCR 32:33 != 0b00 the instruction is treated as if
2324 * the instruction form were invalid."
2326 if (env->spr[SPR_BESCR] & BESCR_INVALID) {
2327 raise_exception_err(env, POWERPC_EXCP_PROGRAM,
2328 POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL);
2331 env->nip = env->spr[SPR_EBBRR];
2333 /* Switching to 32-bit ? Crop the nip */
2334 if (!msr_is_64bit(env, msr)) {
2335 env->nip = (uint32_t)env->spr[SPR_EBBRR];
2338 if (s) {
2339 env->spr[SPR_BESCR] |= BESCR_GE;
2340 } else {
2341 env->spr[SPR_BESCR] &= ~BESCR_GE;
2344 #endif
2346 /*****************************************************************************/
2347 /* Embedded PowerPC specific helpers */
2348 void helper_40x_rfci(CPUPPCState *env)
2350 do_rfi(env, env->spr[SPR_40x_SRR2], env->spr[SPR_40x_SRR3]);
2353 void helper_rfci(CPUPPCState *env)
2355 do_rfi(env, env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1]);
2358 void helper_rfdi(CPUPPCState *env)
2360 /* FIXME: choose CSRR1 or DSRR1 based on cpu type */
2361 do_rfi(env, env->spr[SPR_BOOKE_DSRR0], env->spr[SPR_BOOKE_DSRR1]);
2364 void helper_rfmci(CPUPPCState *env)
2366 /* FIXME: choose CSRR1 or MCSRR1 based on cpu type */
2367 do_rfi(env, env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1]);
2369 #endif /* CONFIG_TCG */
2370 #endif /* !defined(CONFIG_USER_ONLY) */
2372 #ifdef CONFIG_TCG
2373 void helper_tw(CPUPPCState *env, target_ulong arg1, target_ulong arg2,
2374 uint32_t flags)
2376 if (!likely(!(((int32_t)arg1 < (int32_t)arg2 && (flags & 0x10)) ||
2377 ((int32_t)arg1 > (int32_t)arg2 && (flags & 0x08)) ||
2378 ((int32_t)arg1 == (int32_t)arg2 && (flags & 0x04)) ||
2379 ((uint32_t)arg1 < (uint32_t)arg2 && (flags & 0x02)) ||
2380 ((uint32_t)arg1 > (uint32_t)arg2 && (flags & 0x01))))) {
2381 raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
2382 POWERPC_EXCP_TRAP, GETPC());
2386 #if defined(TARGET_PPC64)
2387 void helper_td(CPUPPCState *env, target_ulong arg1, target_ulong arg2,
2388 uint32_t flags)
2390 if (!likely(!(((int64_t)arg1 < (int64_t)arg2 && (flags & 0x10)) ||
2391 ((int64_t)arg1 > (int64_t)arg2 && (flags & 0x08)) ||
2392 ((int64_t)arg1 == (int64_t)arg2 && (flags & 0x04)) ||
2393 ((uint64_t)arg1 < (uint64_t)arg2 && (flags & 0x02)) ||
2394 ((uint64_t)arg1 > (uint64_t)arg2 && (flags & 0x01))))) {
2395 raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
2396 POWERPC_EXCP_TRAP, GETPC());
2399 #endif
2400 #endif
2402 #if !defined(CONFIG_USER_ONLY)
2404 #ifdef CONFIG_TCG
2406 /* Embedded.Processor Control */
2407 static int dbell2irq(target_ulong rb)
2409 int msg = rb & DBELL_TYPE_MASK;
2410 int irq = -1;
2412 switch (msg) {
2413 case DBELL_TYPE_DBELL:
2414 irq = PPC_INTERRUPT_DOORBELL;
2415 break;
2416 case DBELL_TYPE_DBELL_CRIT:
2417 irq = PPC_INTERRUPT_CDOORBELL;
2418 break;
2419 case DBELL_TYPE_G_DBELL:
2420 case DBELL_TYPE_G_DBELL_CRIT:
2421 case DBELL_TYPE_G_DBELL_MC:
2422 /* XXX implement */
2423 default:
2424 break;
2427 return irq;
2430 void helper_msgclr(CPUPPCState *env, target_ulong rb)
2432 int irq = dbell2irq(rb);
2434 if (irq < 0) {
2435 return;
2438 env->pending_interrupts &= ~(1 << irq);
2441 void helper_msgsnd(target_ulong rb)
2443 int irq = dbell2irq(rb);
2444 int pir = rb & DBELL_PIRTAG_MASK;
2445 CPUState *cs;
2447 if (irq < 0) {
2448 return;
2451 qemu_mutex_lock_iothread();
2452 CPU_FOREACH(cs) {
2453 PowerPCCPU *cpu = POWERPC_CPU(cs);
2454 CPUPPCState *cenv = &cpu->env;
2456 if ((rb & DBELL_BRDCAST) || (cenv->spr[SPR_BOOKE_PIR] == pir)) {
2457 cenv->pending_interrupts |= 1 << irq;
2458 cpu_interrupt(cs, CPU_INTERRUPT_HARD);
2461 qemu_mutex_unlock_iothread();
2464 /* Server Processor Control */
2466 static bool dbell_type_server(target_ulong rb)
2469 * A Directed Hypervisor Doorbell message is sent only if the
2470 * message type is 5. All other types are reserved and the
2471 * instruction is a no-op
2473 return (rb & DBELL_TYPE_MASK) == DBELL_TYPE_DBELL_SERVER;
2476 void helper_book3s_msgclr(CPUPPCState *env, target_ulong rb)
2478 if (!dbell_type_server(rb)) {
2479 return;
2482 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDOORBELL);
2485 static void book3s_msgsnd_common(int pir, int irq)
2487 CPUState *cs;
2489 qemu_mutex_lock_iothread();
2490 CPU_FOREACH(cs) {
2491 PowerPCCPU *cpu = POWERPC_CPU(cs);
2492 CPUPPCState *cenv = &cpu->env;
2494 /* TODO: broadcast message to all threads of the same processor */
2495 if (cenv->spr_cb[SPR_PIR].default_value == pir) {
2496 cenv->pending_interrupts |= 1 << irq;
2497 cpu_interrupt(cs, CPU_INTERRUPT_HARD);
2500 qemu_mutex_unlock_iothread();
2503 void helper_book3s_msgsnd(target_ulong rb)
2505 int pir = rb & DBELL_PROCIDTAG_MASK;
2507 if (!dbell_type_server(rb)) {
2508 return;
2511 book3s_msgsnd_common(pir, PPC_INTERRUPT_HDOORBELL);
2514 #if defined(TARGET_PPC64)
2515 void helper_book3s_msgclrp(CPUPPCState *env, target_ulong rb)
2517 helper_hfscr_facility_check(env, HFSCR_MSGP, "msgclrp", HFSCR_IC_MSGP);
2519 if (!dbell_type_server(rb)) {
2520 return;
2523 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL);
2527 * sends a message to other threads that are on the same
2528 * multi-threaded processor
2530 void helper_book3s_msgsndp(CPUPPCState *env, target_ulong rb)
2532 int pir = env->spr_cb[SPR_PIR].default_value;
2534 helper_hfscr_facility_check(env, HFSCR_MSGP, "msgsndp", HFSCR_IC_MSGP);
2536 if (!dbell_type_server(rb)) {
2537 return;
2540 /* TODO: TCG supports only one thread */
2542 book3s_msgsnd_common(pir, PPC_INTERRUPT_DOORBELL);
2544 #endif /* TARGET_PPC64 */
2546 void ppc_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
2547 MMUAccessType access_type,
2548 int mmu_idx, uintptr_t retaddr)
2550 CPUPPCState *env = cs->env_ptr;
2551 uint32_t insn;
2553 /* Restore state and reload the insn we executed, for filling in DSISR. */
2554 cpu_restore_state(cs, retaddr, true);
2555 insn = cpu_ldl_code(env, env->nip);
2557 switch (env->mmu_model) {
2558 case POWERPC_MMU_SOFT_4xx:
2559 env->spr[SPR_40x_DEAR] = vaddr;
2560 break;
2561 case POWERPC_MMU_BOOKE:
2562 case POWERPC_MMU_BOOKE206:
2563 env->spr[SPR_BOOKE_DEAR] = vaddr;
2564 break;
2565 default:
2566 env->spr[SPR_DAR] = vaddr;
2567 break;
2570 cs->exception_index = POWERPC_EXCP_ALIGN;
2571 env->error_code = insn & 0x03FF0000;
2572 cpu_loop_exit(cs);
2574 #endif /* CONFIG_TCG */
2575 #endif /* !CONFIG_USER_ONLY */