It is IMPLEMENTATION DEFINED whether HCR_EL2.TID3 traps on registers within the range which are not explicitly listed. Previously we chose not to honor the TID3 bit.
However, with FEAT_IDTE3 it becomes mandatory to honor SCR_EL3.TID3 on these registers, so we might as well honor HCR_EL2.TID3 too. Signed-off-by: Richard Henderson <[email protected]> --- target/arm/cpregs.h | 8 ++++++++ target/arm/tcg/helper-defs.h | 1 + target/arm/tcg/op_helper.c | 19 +++++++++++++++++++ target/arm/tcg/translate-a64.c | 12 ++++++++++-- target/arm/tcg/translate.c | 8 ++++++++ 5 files changed, 46 insertions(+), 2 deletions(-) diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h index 9f2532fe66..b1fc1f9f85 100644 --- a/target/arm/cpregs.h +++ b/target/arm/cpregs.h @@ -1213,6 +1213,14 @@ static inline bool arm_cpreg_in_idspace(const ARMCPRegInfo *ri) ri->crn, ri->crm); } +/* The TID3 subset of idspace. */ +static inline bool +arm_cpreg_encoding_in_tid3(uint8_t opc0, uint8_t opc1, uint8_t opc2, + uint8_t crn, uint8_t crm) +{ + return opc0 == 3 && opc1 == 0 && crn == 0 && crm >= 2 && crm < 8; +} + #ifdef CONFIG_USER_ONLY static inline void define_cortex_a72_a57_a53_cp_reginfo(ARMCPU *cpu) { } #else diff --git a/target/arm/tcg/helper-defs.h b/target/arm/tcg/helper-defs.h index 0077aeb4e2..97b8678f19 100644 --- a/target/arm/tcg/helper-defs.h +++ b/target/arm/tcg/helper-defs.h @@ -86,6 +86,7 @@ DEF_HELPER_FLAGS_2(check_bxj_trap, TCG_CALL_NO_WG, void, env, i32) DEF_HELPER_4(access_check_cp_reg, cptr, env, i32, i32, i32) DEF_HELPER_FLAGS_2(lookup_cp_reg, TCG_CALL_NO_RWG_SE, cptr, env, i32) +DEF_HELPER_FLAGS_2(tid3_udef_el1, TCG_CALL_NO_WG, noreturn, env, i32) DEF_HELPER_FLAGS_2(tidcp_el0, TCG_CALL_NO_WG, void, env, i32) DEF_HELPER_FLAGS_2(tidcp_el1, TCG_CALL_NO_WG, void, env, i32) DEF_HELPER_3(set_cp_reg, void, env, cptr, i32) diff --git a/target/arm/tcg/op_helper.c b/target/arm/tcg/op_helper.c index d4186b3d0a..93336daf53 100644 --- a/target/arm/tcg/op_helper.c +++ b/target/arm/tcg/op_helper.c @@ -1187,6 +1187,25 @@ const void *HELPER(lookup_cp_reg)(CPUARMState *env, uint32_t key) return ri; } +/* Raise an exception for an unimplemented sysreg in TID3 space, from EL1. */ +void HELPER(tid3_udef_el1)(CPUARMState *env, uint32_t syndrome) +{ + int target_el = 1; + int excp = EXCP_UDEF; + + if (arm_hcr_el2_eff(env) & HCR_TID3) { + target_el = 2; + excp = EXCP_HYP_TRAP; + } else if (is_a64(env)) { + if (!cpu_isar_feature(aa64_idst, env_archcpu(env))) { + syndrome = syn_uncategorized(); + } + } else { + syndrome = syn_uncategorized(); + } + raise_exception(env, excp, syndrome, target_el); +} + /* * Test for HCR_EL2.TIDCP at EL1. * Since implementation defined registers are rare, and within QEMU diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c index b45e1b28b2..7e78d62496 100644 --- a/target/arm/tcg/translate-a64.c +++ b/target/arm/tcg/translate-a64.c @@ -2675,9 +2675,17 @@ static void gen_sysreg_undef(DisasContext *s, bool isread, */ uint32_t syndrome; - if (isread && dc_isar_feature(aa64_idst, s) && - arm_cpreg_encoding_in_idspace(op0, op1, op2, crn, crm)) { + if (isread && arm_cpreg_encoding_in_idspace(op0, op1, op2, crn, crm)) { syndrome = syn_aa64_sysregtrap(op0, op1, op2, crn, crm, rt, isread); + if (s->current_el == 1 && + arm_cpreg_encoding_in_tid3(op0, op1, op2, crn, crm)) { + gen_a64_update_pc(s, 0); + gen_helper_tid3_udef_el1(tcg_env, tcg_constant_i32(syndrome)); + return; + } + if (!dc_isar_feature(aa64_idst, s)) { + syndrome = syn_uncategorized(); + } } else { syndrome = syn_uncategorized(); } diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c index a1fc050618..3fa15f493a 100644 --- a/target/arm/tcg/translate.c +++ b/target/arm/tcg/translate.c @@ -1824,6 +1824,14 @@ static void do_coproc_insn(DisasContext *s, int cpnum, int is64, isread ? "read" : "write", cpnum, opc1, crn, crm, opc2, s->ns ? "non-secure" : "secure"); } + if (isread + && s->current_el == 1 + && cpnum == 15 + && arm_cpreg_encoding_in_tid3(3, opc1, opc2, crn, crm)) { + gen_set_condexec(s); + gen_update_pc(s, 0); + gen_helper_tid3_udef_el1(tcg_env, tcg_constant_i32(syndrome)); + } unallocated_encoding(s); return; } -- 2.43.0
