[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 15/17] target/ppc: Move powerpc_excp_booke into cpu_booke.c
From: |
Fabiano Rosas |
Subject: |
[PATCH 15/17] target/ppc: Move powerpc_excp_booke into cpu_booke.c |
Date: |
Tue, 1 Mar 2022 10:56:18 -0300 |
Signed-off-by: Fabiano Rosas <farosas@linux.ibm.com>
---
target/ppc/cpu.h | 1 +
target/ppc/cpu_booke.c | 216 ++++++++++++++++++++++++++++++++++++++-
target/ppc/excp_helper.c | 204 ------------------------------------
3 files changed, 216 insertions(+), 205 deletions(-)
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 614a92954c..03ca593095 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -184,6 +184,7 @@ void powerpc_excp_40x(PowerPCCPU *cpu, int excp);
void powerpc_excp_6xx(PowerPCCPU *cpu, int excp);
void powerpc_excp_7xx(PowerPCCPU *cpu, int excp);
void powerpc_excp_74xx(PowerPCCPU *cpu, int excp);
+void powerpc_excp_booke(PowerPCCPU *cpu, int excp);
#define PPC_INPUT(env) ((env)->bus_model)
diff --git a/target/ppc/cpu_booke.c b/target/ppc/cpu_booke.c
index 18e16bd3bf..b73cfe224d 100644
--- a/target/ppc/cpu_booke.c
+++ b/target/ppc/cpu_booke.c
@@ -1,5 +1,5 @@
/*
- * CPU initialization for PowerPC BookE CPUs
+ * CPU initialization and exception dispatching for PowerPC BookE CPUs
*
* Copyright IBM Corp. 2022
*
@@ -8,9 +8,12 @@
*/
#include "qemu/osdep.h"
+#include "qemu/log.h"
#include "hw/ppc/ppc.h"
#include "cpu.h"
#include "spr_common.h"
+#include "trace.h"
+#include "helper_regs.h"
static int check_pow_hid0(CPUPPCState *env)
{
@@ -21,6 +24,217 @@ static int check_pow_hid0(CPUPPCState *env)
return 0;
}
+#if !defined(CONFIG_USER_ONLY)
+void powerpc_excp_booke(PowerPCCPU *cpu, int excp)
+{
+ CPUState *cs = CPU(cpu);
+ CPUPPCState *env = &cpu->env;
+ target_ulong msr, new_msr, vector;
+ int srr0, srr1;
+
+ msr = env->msr;
+
+ /*
+ * new interrupt handler msr preserves existing ME unless
+ * explicitly overriden
+ */
+ new_msr = env->msr & ((target_ulong)1 << MSR_ME);
+
+ /* target registers */
+ srr0 = SPR_SRR0;
+ srr1 = SPR_SRR1;
+
+ /*
+ * Hypervisor emulation assistance interrupt only exists on server
+ * arch 2.05 server or later.
+ */
+ if (excp == POWERPC_EXCP_HV_EMU) {
+ excp = POWERPC_EXCP_PROGRAM;
+ }
+
+#ifdef TARGET_PPC64
+ /*
+ * SPEU and VPU share the same IVOR but they exist in different
+ * processors. SPEU is e500v1/2 only and VPU is e6500 only.
+ */
+ if (excp == POWERPC_EXCP_VPU) {
+ excp = POWERPC_EXCP_SPEU;
+ }
+#endif
+
+ vector = env->excp_vectors[excp];
+ if (vector == (target_ulong)-1ULL) {
+ cpu_abort(cs, "Raised an exception without defined vector %d\n",
+ excp);
+ }
+
+ vector |= env->excp_prefix;
+
+ switch (excp) {
+ case POWERPC_EXCP_CRITICAL: /* Critical input */
+ srr0 = SPR_BOOKE_CSRR0;
+ srr1 = SPR_BOOKE_CSRR1;
+ break;
+ case POWERPC_EXCP_MCHECK: /* Machine check exception */
+ if (msr_me == 0) {
+ /*
+ * Machine check exception is not enabled. Enter
+ * checkstop state.
+ */
+ fprintf(stderr, "Machine check while not allowed. "
+ "Entering checkstop state\n");
+ if (qemu_log_separate()) {
+ qemu_log("Machine check while not allowed. "
+ "Entering checkstop state\n");
+ }
+ cs->halted = 1;
+ cpu_interrupt_exittb(cs);
+ }
+
+ /* machine check exceptions don't have ME set */
+ new_msr &= ~((target_ulong)1 << MSR_ME);
+
+ /* FIXME: choose one or the other based on CPU type */
+ srr0 = SPR_BOOKE_MCSRR0;
+ srr1 = SPR_BOOKE_MCSRR1;
+
+ env->spr[SPR_BOOKE_CSRR0] = env->nip;
+ env->spr[SPR_BOOKE_CSRR1] = msr;
+
+ break;
+ case POWERPC_EXCP_DSI: /* Data storage exception */
+ trace_ppc_excp_dsi(env->spr[SPR_BOOKE_ESR], env->spr[SPR_BOOKE_DEAR]);
+ break;
+ case POWERPC_EXCP_ISI: /* Instruction storage exception */
+ trace_ppc_excp_isi(msr, env->nip);
+ break;
+ case POWERPC_EXCP_EXTERNAL: /* External input */
+ if (env->mpic_proxy) {
+ /* IACK the IRQ on delivery */
+ env->spr[SPR_BOOKE_EPR] = ldl_phys(cs->as, env->mpic_iack);
+ }
+ break;
+ case POWERPC_EXCP_ALIGN: /* Alignment exception */
+ break;
+ case POWERPC_EXCP_PROGRAM: /* Program exception */
+ switch (env->error_code & ~0xF) {
+ case POWERPC_EXCP_FP:
+ if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) {
+ trace_ppc_excp_fp_ignore();
+ powerpc_reset_excp_state(cpu);
+ return;
+ }
+
+ /*
+ * FP exceptions always have NIP pointing to the faulting
+ * instruction, so always use store_next and claim we are
+ * precise in the MSR.
+ */
+ msr |= 0x00100000;
+ env->spr[SPR_BOOKE_ESR] = ESR_FP;
+ break;
+ case POWERPC_EXCP_INVAL:
+ trace_ppc_excp_inval(env->nip);
+ msr |= 0x00080000;
+ env->spr[SPR_BOOKE_ESR] = ESR_PIL;
+ break;
+ case POWERPC_EXCP_PRIV:
+ msr |= 0x00040000;
+ env->spr[SPR_BOOKE_ESR] = ESR_PPR;
+ break;
+ case POWERPC_EXCP_TRAP:
+ msr |= 0x00020000;
+ env->spr[SPR_BOOKE_ESR] = ESR_PTR;
+ break;
+ default:
+ /* Should never occur */
+ cpu_abort(cs, "Invalid program exception %d. Aborting\n",
+ env->error_code);
+ break;
+ }
+ break;
+ case POWERPC_EXCP_SYSCALL: /* System call exception */
+ trace_ppc_syscall(env, 0);
+
+ /*
+ * We need to correct the NIP which in this case is supposed
+ * to point to the next instruction
+ */
+ env->nip += 4;
+ break;
+ case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
+ case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */
+ case POWERPC_EXCP_DECR: /* Decrementer exception */
+ break;
+ case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt */
+ /* FIT on 4xx */
+ trace_ppc_excp_print("FIT");
+ break;
+ case POWERPC_EXCP_WDT: /* Watchdog timer interrupt */
+ trace_ppc_excp_print("WDT");
+ srr0 = SPR_BOOKE_CSRR0;
+ srr1 = SPR_BOOKE_CSRR1;
+ break;
+ case POWERPC_EXCP_DTLB: /* Data TLB error */
+ case POWERPC_EXCP_ITLB: /* Instruction TLB error */
+ break;
+ case POWERPC_EXCP_DEBUG: /* Debug interrupt */
+ if (env->flags & POWERPC_FLAG_DE) {
+ /* FIXME: choose one or the other based on CPU type */
+ srr0 = SPR_BOOKE_DSRR0;
+ srr1 = SPR_BOOKE_DSRR1;
+
+ env->spr[SPR_BOOKE_CSRR0] = env->nip;
+ env->spr[SPR_BOOKE_CSRR1] = msr;
+
+ /* DBSR already modified by caller */
+ } else {
+ cpu_abort(cs, "Debug exception triggered on unsupported model\n");
+ }
+ break;
+ case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavailable/VPU
*/
+ env->spr[SPR_BOOKE_ESR] = ESR_SPV;
+ break;
+ case POWERPC_EXCP_RESET: /* System reset exception */
+ if (msr_pow) {
+ cpu_abort(cs, "Trying to deliver power-saving system reset "
+ "exception %d with no HV support\n", excp);
+ }
+ break;
+ case POWERPC_EXCP_EFPDI: /* Embedded floating-point data interrupt */
+ case POWERPC_EXCP_EFPRI: /* Embedded floating-point round interrupt */
+ cpu_abort(cs, "%s exception not implemented\n",
+ powerpc_excp_name(excp));
+ break;
+ default:
+ cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
+ break;
+ }
+
+#if defined(TARGET_PPC64)
+ if (env->spr[SPR_BOOKE_EPCR] & EPCR_ICM) {
+ /* Cat.64-bit: EPCR.ICM is copied to MSR.CM */
+ new_msr |= (target_ulong)1 << MSR_CM;
+ } else {
+ vector = (uint32_t)vector;
+ }
+#endif
+
+ /* Save PC */
+ env->spr[srr0] = env->nip;
+
+ /* Save MSR */
+ env->spr[srr1] = msr;
+
+ powerpc_set_excp_state(cpu, vector, new_msr);
+}
+#else
+void powerpc_excp_booke(PowerPCCPU *cpu, int excp)
+{
+ g_assert_not_reached();
+}
+#endif
+
static void register_BookE_sprs(CPUPPCState *env, uint64_t ivor_mask)
{
const char *ivor_names[64] = {
diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index b2b8c991bf..a6a721d21c 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -376,210 +376,6 @@ void powerpc_set_excp_state(PowerPCCPU *cpu, target_ulong
vector,
env->reserve_addr = -1;
}
-static void powerpc_excp_booke(PowerPCCPU *cpu, int excp)
-{
- CPUState *cs = CPU(cpu);
- CPUPPCState *env = &cpu->env;
- target_ulong msr, new_msr, vector;
- int srr0, srr1;
-
- msr = env->msr;
-
- /*
- * new interrupt handler msr preserves existing ME unless
- * explicitly overriden
- */
- new_msr = env->msr & ((target_ulong)1 << MSR_ME);
-
- /* target registers */
- srr0 = SPR_SRR0;
- srr1 = SPR_SRR1;
-
- /*
- * Hypervisor emulation assistance interrupt only exists on server
- * arch 2.05 server or later.
- */
- if (excp == POWERPC_EXCP_HV_EMU) {
- excp = POWERPC_EXCP_PROGRAM;
- }
-
-#ifdef TARGET_PPC64
- /*
- * SPEU and VPU share the same IVOR but they exist in different
- * processors. SPEU is e500v1/2 only and VPU is e6500 only.
- */
- if (excp == POWERPC_EXCP_VPU) {
- excp = POWERPC_EXCP_SPEU;
- }
-#endif
-
- vector = env->excp_vectors[excp];
- if (vector == (target_ulong)-1ULL) {
- cpu_abort(cs, "Raised an exception without defined vector %d\n",
- excp);
- }
-
- vector |= env->excp_prefix;
-
- switch (excp) {
- case POWERPC_EXCP_CRITICAL: /* Critical input */
- srr0 = SPR_BOOKE_CSRR0;
- srr1 = SPR_BOOKE_CSRR1;
- break;
- case POWERPC_EXCP_MCHECK: /* Machine check exception */
- if (msr_me == 0) {
- /*
- * Machine check exception is not enabled. Enter
- * checkstop state.
- */
- fprintf(stderr, "Machine check while not allowed. "
- "Entering checkstop state\n");
- if (qemu_log_separate()) {
- qemu_log("Machine check while not allowed. "
- "Entering checkstop state\n");
- }
- cs->halted = 1;
- cpu_interrupt_exittb(cs);
- }
-
- /* machine check exceptions don't have ME set */
- new_msr &= ~((target_ulong)1 << MSR_ME);
-
- /* FIXME: choose one or the other based on CPU type */
- srr0 = SPR_BOOKE_MCSRR0;
- srr1 = SPR_BOOKE_MCSRR1;
-
- env->spr[SPR_BOOKE_CSRR0] = env->nip;
- env->spr[SPR_BOOKE_CSRR1] = msr;
-
- break;
- case POWERPC_EXCP_DSI: /* Data storage exception */
- trace_ppc_excp_dsi(env->spr[SPR_BOOKE_ESR], env->spr[SPR_BOOKE_DEAR]);
- break;
- case POWERPC_EXCP_ISI: /* Instruction storage exception */
- trace_ppc_excp_isi(msr, env->nip);
- break;
- case POWERPC_EXCP_EXTERNAL: /* External input */
- if (env->mpic_proxy) {
- /* IACK the IRQ on delivery */
- env->spr[SPR_BOOKE_EPR] = ldl_phys(cs->as, env->mpic_iack);
- }
- break;
- case POWERPC_EXCP_ALIGN: /* Alignment exception */
- break;
- case POWERPC_EXCP_PROGRAM: /* Program exception */
- switch (env->error_code & ~0xF) {
- case POWERPC_EXCP_FP:
- if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) {
- trace_ppc_excp_fp_ignore();
- powerpc_reset_excp_state(cpu);
- return;
- }
-
- /*
- * FP exceptions always have NIP pointing to the faulting
- * instruction, so always use store_next and claim we are
- * precise in the MSR.
- */
- msr |= 0x00100000;
- env->spr[SPR_BOOKE_ESR] = ESR_FP;
- break;
- case POWERPC_EXCP_INVAL:
- trace_ppc_excp_inval(env->nip);
- msr |= 0x00080000;
- env->spr[SPR_BOOKE_ESR] = ESR_PIL;
- break;
- case POWERPC_EXCP_PRIV:
- msr |= 0x00040000;
- env->spr[SPR_BOOKE_ESR] = ESR_PPR;
- break;
- case POWERPC_EXCP_TRAP:
- msr |= 0x00020000;
- env->spr[SPR_BOOKE_ESR] = ESR_PTR;
- break;
- default:
- /* Should never occur */
- cpu_abort(cs, "Invalid program exception %d. Aborting\n",
- env->error_code);
- break;
- }
- break;
- case POWERPC_EXCP_SYSCALL: /* System call exception */
- trace_ppc_syscall(env, 0);
-
- /*
- * We need to correct the NIP which in this case is supposed
- * to point to the next instruction
- */
- env->nip += 4;
- break;
- case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
- case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */
- case POWERPC_EXCP_DECR: /* Decrementer exception */
- break;
- case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt */
- /* FIT on 4xx */
- trace_ppc_excp_print("FIT");
- break;
- case POWERPC_EXCP_WDT: /* Watchdog timer interrupt */
- trace_ppc_excp_print("WDT");
- srr0 = SPR_BOOKE_CSRR0;
- srr1 = SPR_BOOKE_CSRR1;
- break;
- case POWERPC_EXCP_DTLB: /* Data TLB error */
- case POWERPC_EXCP_ITLB: /* Instruction TLB error */
- break;
- case POWERPC_EXCP_DEBUG: /* Debug interrupt */
- if (env->flags & POWERPC_FLAG_DE) {
- /* FIXME: choose one or the other based on CPU type */
- srr0 = SPR_BOOKE_DSRR0;
- srr1 = SPR_BOOKE_DSRR1;
-
- env->spr[SPR_BOOKE_CSRR0] = env->nip;
- env->spr[SPR_BOOKE_CSRR1] = msr;
-
- /* DBSR already modified by caller */
- } else {
- cpu_abort(cs, "Debug exception triggered on unsupported model\n");
- }
- break;
- case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavailable/VPU
*/
- env->spr[SPR_BOOKE_ESR] = ESR_SPV;
- break;
- case POWERPC_EXCP_RESET: /* System reset exception */
- if (msr_pow) {
- cpu_abort(cs, "Trying to deliver power-saving system reset "
- "exception %d with no HV support\n", excp);
- }
- break;
- case POWERPC_EXCP_EFPDI: /* Embedded floating-point data interrupt */
- case POWERPC_EXCP_EFPRI: /* Embedded floating-point round interrupt */
- cpu_abort(cs, "%s exception not implemented\n",
- powerpc_excp_name(excp));
- break;
- default:
- cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
- break;
- }
-
-#if defined(TARGET_PPC64)
- if (env->spr[SPR_BOOKE_EPCR] & EPCR_ICM) {
- /* Cat.64-bit: EPCR.ICM is copied to MSR.CM */
- new_msr |= (target_ulong)1 << MSR_CM;
- } else {
- vector = (uint32_t)vector;
- }
-#endif
-
- /* Save PC */
- env->spr[srr0] = env->nip;
-
- /* Save MSR */
- env->spr[srr1] = msr;
-
- powerpc_set_excp_state(cpu, vector, new_msr);
-}
-
/*
* When running a nested HV guest under vhyp, external interrupts are
* delivered as HVIRT.
--
2.34.1
- [PATCH 04/17] target/ppc: Move 6xx CPUs code to their own file, (continued)
- [PATCH 04/17] target/ppc: Move 6xx CPUs code to their own file, Fabiano Rosas, 2022/03/01
- [PATCH 07/17] target/ppc: Move BookE CPUs code to their own file, Fabiano Rosas, 2022/03/01
- [PATCH 05/17] target/ppc: Move 7xx CPUs code to their own file, Fabiano Rosas, 2022/03/01
- [PATCH 08/17] target/ppc: Move BookS CPUs to their own file, Fabiano Rosas, 2022/03/01
- [PATCH 09/17] target/ppc: Remove leftover comments from cpu_init, Fabiano Rosas, 2022/03/01
- [PATCH 10/17] target/ppc: Expose some excp_helper functions, Fabiano Rosas, 2022/03/01
- [PATCH 14/17] target/ppc: Move powerpc_excp_74xx into cpu_74xx.c, Fabiano Rosas, 2022/03/01
- [PATCH 13/17] target/ppc: Move powerpc_excp_7xx into cpu_7xx.c, Fabiano Rosas, 2022/03/01
- [PATCH 17/17] target/ppc: Move powerpc_excp* to the PowerPCCPU Class, Fabiano Rosas, 2022/03/01
- [PATCH 11/17] target/ppc: Move powerpc_excp_40x into cpu_40x.c, Fabiano Rosas, 2022/03/01
- [PATCH 15/17] target/ppc: Move powerpc_excp_booke into cpu_booke.c,
Fabiano Rosas <=
- [PATCH 02/17] target/ppc: Use trace-events instead of CPU_LOG_INT, Fabiano Rosas, 2022/03/01
- [PATCH 12/17] target/ppc: Move powerpc_excp_6xx into cpu_6xx.c, Fabiano Rosas, 2022/03/01
- [PATCH 16/17] target/ppc: Move powerpc_excp_books into cpu_books.c, Fabiano Rosas, 2022/03/01