[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 11/17] target/ppc: Move powerpc_excp_40x into cpu_40x.c
From: |
Fabiano Rosas |
Subject: |
[PATCH 11/17] target/ppc: Move powerpc_excp_40x into cpu_40x.c |
Date: |
Tue, 1 Mar 2022 10:56:14 -0300 |
This change along with the next few patches which move the
powerpc_excp_foo functions into the cpu_foo.c files has the following
purposes:
- Move the exception dispatching (powerpc_excp) closer to the
exception vectors initialization (init_excp);
- Make it immediately clear which CPUs are affected by the exception
dispatching code;
- Move code which is not a TCG helper out of excp_helpers.c. Aside
from the obvious, this also helps with separation between TCG and
KVM code; excp_helpers could be TCG-only (we're not quite there
yet);
- We could start thinking about ways of simplifying the
init_excp/powerpc_excp relationship since both users of the
POWERPC_EXCP vector addresses are now in the same place.
Signed-off-by: Fabiano Rosas <farosas@linux.ibm.com>
---
target/ppc/cpu.h | 1 +
target/ppc/cpu_40x.c | 150 ++++++++++++++++++++++++++++++++++++++-
target/ppc/excp_helper.c | 138 -----------------------------------
3 files changed, 150 insertions(+), 139 deletions(-)
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index c7bb10b0bf..ba3740ea92 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -179,6 +179,7 @@ const char *powerpc_excp_name(int excp);
void powerpc_set_excp_state(PowerPCCPU *cpu,
target_ulong vector, target_ulong msr);
void powerpc_reset_excp_state(PowerPCCPU *cpu);
+void powerpc_excp_40x(PowerPCCPU *cpu, int excp);
#define PPC_INPUT(env) ((env)->bus_model)
diff --git a/target/ppc/cpu_40x.c b/target/ppc/cpu_40x.c
index 4ed2cbc305..4b7bbeb28c 100644
--- a/target/ppc/cpu_40x.c
+++ b/target/ppc/cpu_40x.c
@@ -1,5 +1,5 @@
/*
- * CPU initialization for PowerPC 40x CPUs
+ * CPU initialization and exception dispatching for PowerPC 40x CPUs
*
* Copyright IBM Corp. 2022
*
@@ -8,9 +8,157 @@
*/
#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"
+
+#if !defined(CONFIG_USER_ONLY)
+void powerpc_excp_40x(PowerPCCPU *cpu, int excp)
+{
+ CPUState *cs = CPU(cpu);
+ CPUPPCState *env = &cpu->env;
+ target_ulong msr, new_msr, vector;
+ int srr0, srr1;
+
+ /* new srr1 value excluding must-be-zero bits */
+ msr = env->msr & ~0x783f0000ULL;
+
+ /*
+ * 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;
+ }
+
+ 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_40x_SRR2;
+ srr1 = SPR_40x_SRR3;
+ 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);
+
+ srr0 = SPR_40x_SRR2;
+ srr1 = SPR_40x_SRR3;
+ break;
+ case POWERPC_EXCP_DSI: /* Data storage exception */
+ trace_ppc_excp_dsi(env->spr[SPR_40x_ESR], env->spr[SPR_40x_DEAR]);
+ break;
+ case POWERPC_EXCP_ISI: /* Instruction storage exception */
+ trace_ppc_excp_isi(msr, env->nip);
+ break;
+ case POWERPC_EXCP_EXTERNAL: /* External input */
+ 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;
+ }
+ env->spr[SPR_40x_ESR] = ESR_FP;
+ break;
+ case POWERPC_EXCP_INVAL:
+ trace_ppc_excp_inval(env->nip);
+ env->spr[SPR_40x_ESR] = ESR_PIL;
+ break;
+ case POWERPC_EXCP_PRIV:
+ env->spr[SPR_40x_ESR] = ESR_PPR;
+ break;
+ case POWERPC_EXCP_TRAP:
+ env->spr[SPR_40x_ESR] = ESR_PTR;
+ break;
+ default:
+ 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_FIT: /* Fixed-interval timer interrupt */
+ trace_ppc_excp_print("FIT");
+ break;
+ case POWERPC_EXCP_WDT: /* Watchdog timer interrupt */
+ trace_ppc_excp_print("WDT");
+ break;
+ case POWERPC_EXCP_DTLB: /* Data TLB error */
+ case POWERPC_EXCP_ITLB: /* Instruction TLB error */
+ break;
+ case POWERPC_EXCP_PIT: /* Programmable interval timer interrupt */
+ trace_ppc_excp_print("PIT");
+ break;
+ case POWERPC_EXCP_DEBUG: /* Debug 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;
+ }
+
+ /* 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_40x(PowerPCCPU *cpu, int excp)
+{
+ g_assert_not_reached();
+}
+#endif
/* SPR shared between PowerPC 40x implementations */
static void register_40x_sprs(CPUPPCState *env)
diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 07190d785a..3ae3f4cc45 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -376,144 +376,6 @@ void powerpc_set_excp_state(PowerPCCPU *cpu, target_ulong
vector,
env->reserve_addr = -1;
}
-static void powerpc_excp_40x(PowerPCCPU *cpu, int excp)
-{
- CPUState *cs = CPU(cpu);
- CPUPPCState *env = &cpu->env;
- target_ulong msr, new_msr, vector;
- int srr0, srr1;
-
- /* new srr1 value excluding must-be-zero bits */
- msr = env->msr & ~0x783f0000ULL;
-
- /*
- * 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;
- }
-
- 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_40x_SRR2;
- srr1 = SPR_40x_SRR3;
- 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);
-
- srr0 = SPR_40x_SRR2;
- srr1 = SPR_40x_SRR3;
- break;
- case POWERPC_EXCP_DSI: /* Data storage exception */
- trace_ppc_excp_dsi(env->spr[SPR_40x_ESR], env->spr[SPR_40x_DEAR]);
- break;
- case POWERPC_EXCP_ISI: /* Instruction storage exception */
- trace_ppc_excp_isi(msr, env->nip);
- break;
- case POWERPC_EXCP_EXTERNAL: /* External input */
- 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;
- }
- env->spr[SPR_40x_ESR] = ESR_FP;
- break;
- case POWERPC_EXCP_INVAL:
- trace_ppc_excp_inval(env->nip);
- env->spr[SPR_40x_ESR] = ESR_PIL;
- break;
- case POWERPC_EXCP_PRIV:
- env->spr[SPR_40x_ESR] = ESR_PPR;
- break;
- case POWERPC_EXCP_TRAP:
- env->spr[SPR_40x_ESR] = ESR_PTR;
- break;
- default:
- 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_FIT: /* Fixed-interval timer interrupt */
- trace_ppc_excp_print("FIT");
- break;
- case POWERPC_EXCP_WDT: /* Watchdog timer interrupt */
- trace_ppc_excp_print("WDT");
- break;
- case POWERPC_EXCP_DTLB: /* Data TLB error */
- case POWERPC_EXCP_ITLB: /* Instruction TLB error */
- break;
- case POWERPC_EXCP_PIT: /* Programmable interval timer interrupt */
- trace_ppc_excp_print("PIT");
- break;
- case POWERPC_EXCP_DEBUG: /* Debug 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;
- }
-
- /* Save PC */
- env->spr[srr0] = env->nip;
-
- /* Save MSR */
- env->spr[srr1] = msr;
-
- powerpc_set_excp_state(cpu, vector, new_msr);
-}
-
static void powerpc_excp_6xx(PowerPCCPU *cpu, int excp)
{
CPUState *cs = CPU(cpu);
--
2.34.1
- [PATCH 06/17] target/ppc: Move 74xx CPUs code to their own file, (continued)
- [PATCH 06/17] target/ppc: Move 74xx CPUs code to their own file, Fabiano Rosas, 2022/03/01
- [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 <=
- [PATCH 15/17] target/ppc: Move powerpc_excp_booke into cpu_booke.c, Fabiano Rosas, 2022/03/01
- [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