target/arm: Implement FEAT_ATS1A
Implement FEAT_ATS1A and enable for -cpu max. Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20250830054128.448363-13-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
committed by
Peter Maydell
parent
171a302a04
commit
2b5daf79c3
@@ -23,6 +23,7 @@ the following architecture extensions:
|
||||
- FEAT_AFP (Alternate floating-point behavior)
|
||||
- FEAT_Armv9_Crypto (Armv9 Cryptographic Extension)
|
||||
- FEAT_ASID16 (16 bit ASID)
|
||||
- FEAT_ATS1A (Address Translation operations that ignore stage 1 permissions)
|
||||
- FEAT_BBM at level 2 (Translation table break-before-make levels)
|
||||
- FEAT_BF16 (AArch64 BFloat16 instructions)
|
||||
- FEAT_BTI (Branch Target Identification)
|
||||
|
||||
@@ -854,6 +854,7 @@ typedef enum FGTBit {
|
||||
DO_BIT(HFGITR, DVPRCTX),
|
||||
DO_BIT(HFGITR, CPPRCTX),
|
||||
DO_BIT(HFGITR, DCCVAC),
|
||||
DO_BIT(HFGITR, ATS1E1A),
|
||||
} FGTBit;
|
||||
|
||||
#undef DO_BIT
|
||||
|
||||
@@ -619,6 +619,11 @@ static inline bool isar_feature_aa64_lut(const ARMISARegisters *id)
|
||||
return FIELD_EX64_IDREG(id, ID_AA64ISAR2, LUT);
|
||||
}
|
||||
|
||||
static inline bool isar_feature_aa64_ats1a(const ARMISARegisters *id)
|
||||
{
|
||||
return FIELD_EX64_IDREG(id, ID_AA64ISAR2, ATS1A);
|
||||
}
|
||||
|
||||
static inline bool isar_feature_aa64_fp_simd(const ARMISARegisters *id)
|
||||
{
|
||||
/* We always set the AdvSIMD and FP fields identically. */
|
||||
|
||||
@@ -488,6 +488,47 @@ static const ARMCPRegInfo ats1cp_reginfo[] = {
|
||||
.writefn = ats_write },
|
||||
};
|
||||
|
||||
static void ats_s1e1a(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
|
||||
{
|
||||
uint64_t hcr_el2 = arm_hcr_el2_eff(env);
|
||||
bool regime_e20 = (hcr_el2 & (HCR_E2H | HCR_TGE)) == (HCR_E2H | HCR_TGE);
|
||||
ARMMMUIdx mmu_idx = regime_e20 ? ARMMMUIdx_E20_2 : ARMMMUIdx_Stage1_E1;
|
||||
ARMSecuritySpace ss = arm_security_space_below_el3(env);
|
||||
|
||||
env->cp15.par_el[1] = do_ats_write(env, value, 0, mmu_idx, ss);
|
||||
}
|
||||
|
||||
static void ats_s1e2a(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
|
||||
{
|
||||
uint64_t hcr_el2 = arm_hcr_el2_eff(env);
|
||||
ARMMMUIdx mmu_idx = hcr_el2 & HCR_E2H ? ARMMMUIdx_E20_2 : ARMMMUIdx_E2;
|
||||
ARMSecuritySpace ss = arm_security_space_below_el3(env);
|
||||
|
||||
env->cp15.par_el[1] = do_ats_write(env, value, 0, mmu_idx, ss);
|
||||
}
|
||||
|
||||
static void ats_s1e3a(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
|
||||
{
|
||||
env->cp15.par_el[1] = do_ats_write(env, value, 0, ARMMMUIdx_E3,
|
||||
arm_security_space(env));
|
||||
}
|
||||
|
||||
static const ARMCPRegInfo ats1a_reginfo[] = {
|
||||
{ .name = "AT_S1E1A", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 2,
|
||||
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
|
||||
.fgt = FGT_ATS1E1A,
|
||||
.accessfn = at_s1e01_access, .writefn = ats_s1e1a },
|
||||
{ .name = "AT_S1E2A", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 1, .opc1 = 4, .crn = 7, .crm = 9, .opc2 = 2,
|
||||
.access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
|
||||
.accessfn = at_s1e2_access, .writefn = ats_s1e2a },
|
||||
{ .name = "AT_S1E3A", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 1, .opc1 = 6, .crn = 7, .crm = 9, .opc2 = 2,
|
||||
.access = PL3_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
|
||||
.writefn = ats_s1e3a },
|
||||
};
|
||||
|
||||
void define_at_insn_regs(ARMCPU *cpu)
|
||||
{
|
||||
CPUARMState *env = &cpu->env;
|
||||
@@ -509,4 +550,7 @@ void define_at_insn_regs(ARMCPU *cpu)
|
||||
if (cpu_isar_feature(aa32_ats1e1, cpu)) {
|
||||
define_arm_cp_regs(cpu, ats1cp_reginfo);
|
||||
}
|
||||
if (cpu_isar_feature(aa64_ats1a, cpu)) {
|
||||
define_arm_cp_regs(cpu, ats1a_reginfo);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1179,6 +1179,7 @@ void aarch64_max_tcg_initfn(Object *obj)
|
||||
t = FIELD_DP64(t, ID_AA64ISAR2, BC, 1); /* FEAT_HBC */
|
||||
t = FIELD_DP64(t, ID_AA64ISAR2, WFXT, 2); /* FEAT_WFxT */
|
||||
t = FIELD_DP64(t, ID_AA64ISAR2, CSSC, 1); /* FEAT_CSSC */
|
||||
t = FIELD_DP64(t, ID_AA64ISAR2, ATS1A, 1); /* FEAT_ATS1A */
|
||||
SET_IDREG(isar, ID_AA64ISAR2, t);
|
||||
|
||||
t = GET_IDREG(isar, ID_AA64PFR0);
|
||||
|
||||
Reference in New Issue
Block a user