target/arm: report register in WFIT syndromes
Pass the register number (rd) to the wfit helper and report it in the syndrome ISS. Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Message-id: 20260422125250.1303100-24-alex.bennee@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Alex Bennée committed
Apr 22, 2026 at 13:52 UTC
4575da5ecb7a27544aa6da1f78e700e8100ceaea
4 files changed
+16
-6
target/arm/syndrome.h
+10
-1
@@ -670,7 +670,14 @@ FIELD(WFX_ISS, RN, 5, 5)
670
FIELD(WFX_ISS, COND, 20, 4)
671
FIELD(WFX_ISS, CV, 24, 1)
672
673
-static inline uint32_t syn_wfx(int cv, int cond, int ti, bool is_16bit)
673
+typedef enum {
674
+ WFI = 0b00,
675
+ WFE = 0b01,
676
+ WFIT = 0b10,
677
+ WFET = 0xb11
678
+} wfx_ti;
679
+
680
+static inline uint32_t syn_wfx(int cv, int cond, int rn, bool rv, wfx_ti ti, bool is_16bit)
681
{
682
uint32_t res = syn_set_ec(0, EC_WFX_TRAP);
683
res = FIELD_DP32(res, SYNDROME, IL, !is_16bit);
@@ -678,6 +685,8 @@ static inline uint32_t syn_wfx(int cv, int cond, int ti, bool is_16bit)
685
res = FIELD_DP32(res, WFX_ISS, CV, cv);
686
res = FIELD_DP32(res, WFX_ISS, COND, cond);
687
res = FIELD_DP32(res, WFX_ISS, TI, ti);
688
+ res = FIELD_DP32(res, WFX_ISS, RN, rn);
689
+ res = FIELD_DP32(res, WFX_ISS, RV, rv);
690
691
return res;
692
}
target/arm/tcg/helper-defs.h
+1
-1
@@ -55,7 +55,7 @@ DEF_HELPER_2(exception_pc_alignment, noreturn, env, vaddr)
55
DEF_HELPER_1(setend, void, env)
56
DEF_HELPER_2(wfi, void, env, i32)
57
DEF_HELPER_1(wfe, void, env)
58
-DEF_HELPER_2(wfit, void, env, i64)
58
+DEF_HELPER_2(wfit, void, env, i32)
59
DEF_HELPER_1(yield, void, env)
60
DEF_HELPER_1(pre_hvc, void, env)
61
DEF_HELPER_2(pre_smc, void, env, i32)
target/arm/tcg/op_helper.c
+4
-3
@@ -398,7 +398,7 @@ void HELPER(wfi)(CPUARMState *env, uint32_t insn_len)
398
env->regs[15] -= insn_len;
399
}
400
401
- raise_exception(env, excp, syn_wfx(1, 0xe, 0, insn_len == 2),
401
+ raise_exception(env, excp, syn_wfx(1, 0xe, 0, false, WFI, insn_len == 2),
402
target_el);
403
}
404
@@ -408,7 +408,7 @@ void HELPER(wfi)(CPUARMState *env, uint32_t insn_len)
408
#endif
409
}
410
411
-void HELPER(wfit)(CPUARMState *env, uint64_t timeout)
411
+void HELPER(wfit)(CPUARMState *env, uint32_t rd)
412
{
413
#ifdef CONFIG_USER_ONLY
414
/*
@@ -427,6 +427,7 @@ void HELPER(wfit)(CPUARMState *env, uint64_t timeout)
427
int target_el = check_wfx_trap(env, false, &excp);
428
/* The WFIT should time out when CNTVCT_EL0 >= the specified value. */
429
uint64_t cntval = gt_get_countervalue(env);
430
+ uint64_t timeout = env->xregs[rd];
431
/*
432
* We want the value that we would get if we read CNTVCT_EL0 from
433
* the current exception level, so the direct_access offset, not
@@ -447,7 +448,7 @@ void HELPER(wfit)(CPUARMState *env, uint64_t timeout)
448
449
if (target_el) {
450
env->pc -= 4;
450
- raise_exception(env, excp, syn_wfx(1, 0xe, 2, false), target_el);
451
+ raise_exception(env, excp, syn_wfx(1, 0xe, rd, true, WFIT, false), target_el);
452
}
453
454
if (uadd64_overflow(timeout, offset, &nexttick)) {
target/arm/tcg/translate-a64.c
+1
-1
@@ -2065,7 +2065,7 @@ static bool trans_WFIT(DisasContext *s, arg_WFIT *a)
2065
}
2066
2067
gen_a64_update_pc(s, 4);
2068
- gen_helper_wfit(tcg_env, cpu_reg(s, a->rd));
2068
+ gen_helper_wfit(tcg_env, tcg_constant_i32(a->rd));
2069
/* Go back to the main loop to check for interrupts */
2070
s->base.is_jmp = DISAS_EXIT;
2071
return true;