[RFC PATCH 27/35] target/arm: wrap event_register in a union

Alex Bennée posted 35 patches 7 hours ago
Maintainers: Peter Maydell <peter.maydell@linaro.org>, Alexander Graf <agraf@csgraf.de>, Pedro Barbuda <pbarbuda@microsoft.com>, Mohamed Mediouni <mohamed@unpredictable.fr>
[RFC PATCH 27/35] target/arm: wrap event_register in a union
Posted by Alex Bennée 7 hours ago
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