@samitouri / QOSamiQemu / commits / 4575da5ecb

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;