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 <[email protected]> --- 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
