refactor(cpufeat): bring MPAM and DIT to the feat_detect pattern

The enablement for FEAT_MPAM and FEAT_DIT happened when the feat_state
framework was fairly fresh so they don't follow the patterns that have
emerged since. Convert them to follow these patterns.

Change-Id: Id04915a3d1d5c3e4f8702f03e53494703e6de6dc
Signed-off-by: Boyan Karatotev <boyan.karatotev@arm.com>
This commit is contained in:
Boyan Karatotev 2026-04-30 12:22:55 +01:00
parent 18a8df195b
commit a92e87b68d
4 changed files with 33 additions and 48 deletions

View File

@ -242,9 +242,11 @@
#define ID_AA64PFR0_SEL2_MASK ULL(0xf) #define ID_AA64PFR0_SEL2_MASK ULL(0xf)
#define ID_AA64PFR0_MPAM_SHIFT U(40) #define ID_AA64PFR0_MPAM_SHIFT U(40)
#define ID_AA64PFR0_MPAM_WIDTH UL(4)
#define ID_AA64PFR0_MPAM_MASK ULL(0xf) #define ID_AA64PFR0_MPAM_MASK ULL(0xf)
#define ID_AA64PFR0_DIT_SHIFT U(48) #define ID_AA64PFR0_DIT_SHIFT U(48)
#define ID_AA64PFR0_DIT_WIDTH U(4)
#define ID_AA64PFR0_DIT_MASK ULL(0xf) #define ID_AA64PFR0_DIT_MASK ULL(0xf)
#define ID_AA64PFR0_DIT_LENGTH U(4) #define ID_AA64PFR0_DIT_LENGTH U(4)
#define DIT_IMPLEMENTED ULL(1) #define DIT_IMPLEMENTED ULL(1)
@ -610,6 +612,7 @@
#define MTE_IMPLEMENTED_ASY U(3) #define MTE_IMPLEMENTED_ASY U(3)
#define ID_AA64PFR1_MPAM_FRAC_SHIFT ULL(16) #define ID_AA64PFR1_MPAM_FRAC_SHIFT ULL(16)
#define ID_AA64PFR1_MPAM_FRAC_WIDTH ULL(4)
#define ID_AA64PFR1_MPAM_FRAC_MASK ULL(0xf) #define ID_AA64PFR1_MPAM_FRAC_MASK ULL(0xf)
#define ID_AA64PFR1_EL1_SME_SHIFT U(24) #define ID_AA64PFR1_EL1_SME_SHIFT U(24)

View File

@ -350,6 +350,23 @@
* *
* Clobbers: reg * Clobbers: reg
*/ */
.macro is_feat_dit_present_asm reg:req
mrs \reg, ID_AA64PFR0_EL1
ands \reg, \reg, #MASK(ID_AA64PFR0_DIT)
.endm
.macro is_feat_mpam_present_asm reg:req, clobber:req
/* Get MPAM major version */
mrs \reg, ID_AA64PFR0_EL1
ubfx \reg, \reg, #ID_AA64PFR0_MPAM_SHIFT, #ID_AA64PFR0_MPAM_WIDTH
/* Get MPAM minor version */
mrs \clobber, ID_AA64PFR1_EL1
ubfx \clobber, \clobber, #ID_AA64PFR1_MPAM_FRAC_SHIFT, #ID_AA64PFR1_MPAM_FRAC_WIDTH
/* output as MAJOR.MINOR so that a 0 comparison works */
lsr \clobber, \clobber, #ID_AA64PFR0_MPAM_WIDTH
orr \reg, \reg, \clobber
.endm
.macro is_feat_sysreg128_present_asm reg:req .macro is_feat_sysreg128_present_asm reg:req
mrs \reg, ID_AA64ISAR2_EL1 mrs \reg, ID_AA64ISAR2_EL1
ands \reg, \reg, #(ID_AA64ISAR2_SYSREG128_MASK << ID_AA64ISAR2_SYSREG128_SHIFT) ands \reg, \reg, #(ID_AA64ISAR2_SYSREG128_MASK << ID_AA64ISAR2_SYSREG128_SHIFT)

View File

@ -564,9 +564,8 @@ feat_sctlr2_not_supported\@:
msr cptr_el3, x15 msr cptr_el3, x15
#if ENABLE_FEAT_DIT #if ENABLE_FEAT_DIT
#if ENABLE_FEAT_DIT > 1 #if ENABLE_FEAT_DIT == 2
mrs x15, id_aa64pfr0_el1 is_feat_dit_present_asm x15
ubfx x15, x15, #ID_AA64PFR0_DIT_SHIFT, #ID_AA64PFR0_DIT_LENGTH
cbz x15, 1f cbz x15, 1f
#endif #endif
mov x15, #DIT_BIT mov x15, #DIT_BIT

View File

@ -286,9 +286,8 @@ endfunc sve_context_restore
* always enable DIT in EL3 * always enable DIT in EL3
*/ */
#if ENABLE_FEAT_DIT #if ENABLE_FEAT_DIT
#if ENABLE_FEAT_DIT >= 2 #if ENABLE_FEAT_DIT == 2
mrs x8, id_aa64pfr0_el1 is_feat_dit_present_asm, x8
and x8, x8, #(ID_AA64PFR0_DIT_MASK << ID_AA64PFR0_DIT_SHIFT)
cbz x8, 1f cbz x8, 1f
#endif #endif
mov x8, #DIT_BIT mov x8, #DIT_BIT
@ -297,44 +296,6 @@ endfunc sve_context_restore
#endif /* ENABLE_FEAT_DIT */ #endif /* ENABLE_FEAT_DIT */
.endm /* set_unset_pstate_bits */ .endm /* set_unset_pstate_bits */
/*-------------------------------------------------------------------------
* This macro checks the ENABLE_FEAT_MPAM state, performs ID register
* check to see if the platform supports MPAM extension and restores MPAM3
* register value if it is FEAT_STATE_ENABLED/FEAT_STATE_CHECKED.
*
* This is particularly more complicated because we can't check
* if the platform supports MPAM by looking for status of a particular bit
* in the MDCR_EL3 or CPTR_EL3 register like other extensions.
* ------------------------------------------------------------------------
*/
.macro restore_mpam3_el3
#if ENABLE_FEAT_MPAM
#if ENABLE_FEAT_MPAM >= 2
mrs x8, id_aa64pfr0_el1
lsr x8, x8, #(ID_AA64PFR0_MPAM_SHIFT)
and x8, x8, #(ID_AA64PFR0_MPAM_MASK)
mrs x7, id_aa64pfr1_el1
lsr x7, x7, #(ID_AA64PFR1_MPAM_FRAC_SHIFT)
and x7, x7, #(ID_AA64PFR1_MPAM_FRAC_MASK)
orr x7, x7, x8
cbz x7, no_mpam
#endif
/* -----------------------------------------------------------
* Restore MPAM3_EL3 register as per context state
* Currently we only enable MPAM for NS world and trap to EL3
* for MPAM access in lower ELs of Secure and Realm world
* x9 holds address of the per_world context
* -----------------------------------------------------------
*/
ldr x17, [x9, #CTX_MPAM3_EL3]
msr S3_6_C10_C5_0, x17 /* mpam3_el3 */
no_mpam:
#endif
.endm /* restore_mpam3_el3 */
/* ------------------------------------------------------------------ /* ------------------------------------------------------------------
* The following macro is used to save all the general purpose * The following macro is used to save all the general purpose
* registers and swap the FEAT_PAUTH keys with BL31's keys in * registers and swap the FEAT_PAUTH keys with BL31's keys in
@ -684,10 +645,15 @@ func el3_exit
ldp x19, x20, [x9, #CTX_CPTR_EL3] ldp x19, x20, [x9, #CTX_CPTR_EL3]
msr cptr_el3, x19 msr cptr_el3, x19
#if IMAGE_BL31 #if ENABLE_FEAT_MPAM && IMAGE_BL31
restore_mpam3_el3 #if ENABLE_FEAT_MPAM == 2
is_feat_mpam_present_asm x7, x8
#endif /* IMAGE_BL31 */ cbz x7, no_mpam
#endif
ldr x17, [x9, #CTX_MPAM3_EL3]
msr MPAM3_EL3, x17
no_mpam:
#endif
#if IMAGE_BL31 && DYNAMIC_WORKAROUND_CVE_2018_3639 #if IMAGE_BL31 && DYNAMIC_WORKAROUND_CVE_2018_3639
/* ---------------------------------------------------------- /* ----------------------------------------------------------