While the event register is either set or not due to the
implementation defined nature of bool types we can't set it directly
from TCG code. By wrapping in a union we can alias a 32 bit value to
the bool in a future patch.
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
---
target/arm/cpu.h | 9 +++++++--
hw/intc/armv7m_nvic.c | 2 +-
target/arm/machine.c | 4 ++--
target/arm/tcg/m_helper.c | 4 ++--
target/arm/tcg/op_helper.c | 6 +++---
5 files changed, 15 insertions(+), 10 deletions(-)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index bf6cf74c2e1..9c25b60ae83 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -763,9 +763,14 @@ typedef struct CPUArchState {
/*
* The event register is shared by all ARM profiles (A/R/M),
* so it is stored in the top-level CPU state.
- * WFE/SEV handling is currently implemented only for M-profile.
+ *
+ * It is treated as a boolean but we need the union so we can set
+ * it from TCG.
*/
- bool event_register;
+ union {
+ bool as_bool;
+ uint32_t as_uint32;
+ } event_register;
/* Fields up to this point are cleared by a CPU reset */
struct {} end_reset_fields;
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index a7651f831eb..d630f80e51a 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -238,7 +238,7 @@ static void nvic_update_pending_state(NVICState *s, VecInfo *vec,
int scr_bank = exc_targets_secure(s, irq) ? M_REG_S : M_REG_NS;
/* SEVONPEND: interrupt going to pending is a WFE wakeup event */
if (s->cpu->env.v7m.scr[scr_bank] & R_V7M_SCR_SEVONPEND_MASK) {
- s->cpu->env.event_register = true;
+ s->cpu->env.event_register.as_bool = true;
qemu_cpu_kick(CPU(s->cpu));
}
}
diff --git a/target/arm/machine.c b/target/arm/machine.c
index b0e499515cf..844e6a37c77 100644
--- a/target/arm/machine.c
+++ b/target/arm/machine.c
@@ -514,7 +514,7 @@ static bool event_needed(void *opaque)
{
ARMCPU *cpu = opaque;
- return cpu->env.event_register;
+ return cpu->env.event_register.as_bool;
}
static const VMStateDescription vmstate_event = {
@@ -523,7 +523,7 @@ static const VMStateDescription vmstate_event = {
.minimum_version_id = 1,
.needed = event_needed,
.fields = (const VMStateField[]) {
- VMSTATE_BOOL(env.event_register, ARMCPU),
+ VMSTATE_BOOL(env.event_register.as_bool, ARMCPU),
VMSTATE_END_OF_LIST()
}
};
diff --git a/target/arm/tcg/m_helper.c b/target/arm/tcg/m_helper.c
index a0cb8cb021e..3259e624e02 100644
--- a/target/arm/tcg/m_helper.c
+++ b/target/arm/tcg/m_helper.c
@@ -964,7 +964,7 @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
* take (which might now be the derived exception).
* Exception entry sets the event register (ARM ARM R_BPBR)
*/
- env->event_register = true;
+ env->event_register.as_bool = true;
armv7m_nvic_acknowledge_irq(env->nvic);
/* Switch to target security state -- must do this before writing SPSEL */
@@ -1910,7 +1910,7 @@ static void do_v7m_exception_exit(ARMCPU *cpu)
arm_rebuild_hflags(env);
/* Exception return sets the event register (ARM ARM R_BPBR) */
- env->event_register = true;
+ env->event_register.as_bool = true;
qemu_log_mask(CPU_LOG_INT, "...successful exception return\n");
}
diff --git a/target/arm/tcg/op_helper.c b/target/arm/tcg/op_helper.c
index 635c538ed4b..b5c8024ace7 100644
--- a/target/arm/tcg/op_helper.c
+++ b/target/arm/tcg/op_helper.c
@@ -476,7 +476,7 @@ void HELPER(sev)(CPUARMState *env)
CPU_FOREACH(cs) {
ARMCPU *target_cpu = ARM_CPU(cs);
if (arm_feature(&target_cpu->env, ARM_FEATURE_M)) {
- target_cpu->env.event_register = true;
+ target_cpu->env.event_register.as_bool = true;
}
if (!qemu_cpu_is_self(cs)) {
qemu_cpu_kick(cs);
@@ -503,8 +503,8 @@ void HELPER(wfe)(CPUARMState *env)
if (arm_feature(env, ARM_FEATURE_M)) {
CPUState *cs = env_cpu(env);
- if (env->event_register) {
- env->event_register = false;
+ if (env->event_register.as_bool) {
+ env->event_register.as_bool = false;
return;
}
--
2.47.3