diff options
author | Soby Mathew <soby.mathew@arm.com> | 2023-01-27 15:08:00 +0100 |
---|---|---|
committer | TrustedFirmware Code Review <review@review.trustedfirmware.org> | 2023-01-27 15:08:00 +0100 |
commit | 708eb9d6ef16700c38aa89232e63e8bdea18c486 (patch) | |
tree | b0410ef564c79b848fb5506cf0441267fa7cfc84 | |
parent | f56d37aa8a6d7c029d1650e67fe915cb4bbb3384 (diff) | |
parent | 7bb7a70a8d22f4db7fbda6f9520e588a5e5d67e0 (diff) | |
download | tf-rmm-708eb9d6ef16700c38aa89232e63e8bdea18c486.tar.gz |
Merge "feat(rmm): report PMU not supported" into integration
-rw-r--r-- | lib/arch/include/arch.h | 85 | ||||
-rw-r--r-- | lib/arch/include/arch_features.h | 4 | ||||
-rw-r--r-- | lib/smc/include/smc-rmi.h | 10 | ||||
-rw-r--r-- | runtime/core/sysregs.c | 175 | ||||
-rw-r--r-- | runtime/rmi/feature.c | 17 |
5 files changed, 235 insertions, 56 deletions
diff --git a/lib/arch/include/arch.h b/lib/arch/include/arch.h index 5db3d089..dce91721 100644 --- a/lib/arch/include/arch.h +++ b/lib/arch/include/arch.h @@ -415,6 +415,66 @@ #define ESR_EL2_xVC_IMM_WIDTH 16 #define ESR_EL2_xVC_IMM_MASK MASK(ESR_EL2_xVC_IMM) +/* ID_AA64DFR0_EL1 definitions */ +#define ID_AA64DFR0_EL1_HPMN0_SHIFT UL(60) +#define ID_AA64DFR0_EL1_HPMN0_WIDTH UL(4) +#define ID_AA64DFR0_EL1_HPMN0_MASK MASK(ID_AA64DFR0_EL1_HPMN0) + +#define ID_AA64DFR0_EL1_BRBE_SHIFT UL(52) +#define ID_AA64DFR0_EL1_BRBE_WIDTH UL(4) +#define ID_AA64DFR0_EL1_BRBE_MASK MASK(ID_AA64DFR0_EL1_BRBE) + +#define ID_AA64DFR0_EL1_MTPMU_SHIFT UL(48) +#define ID_AA64DFR0_EL1_MTPMU_WIDTH UL(4) +#define ID_AA64DFR0_EL1_MTPMU_MASK MASK(ID_AA64DFR0_EL1_MTPMU) + +#define ID_AA64DFR0_EL1_TraceBuffer_SHIFT UL(44) +#define ID_AA64DFR0_EL1_TraceBuffer_WIDTH UL(4) +#define ID_AA64DFR0_EL1_TraceBuffer_MASK MASK(ID_AA64DFR0_EL1_TraceBuffer) + +#define ID_AA64DFR0_EL1_TraceFilt_SHIFT UL(40) +#define ID_AA64DFR0_EL1_TraceFilt_WIDTH UL(4) +#define ID_AA64DFR0_EL1_TraceFilt_MASK MASK(ID_AA64DFR0_EL1_TraceFilt) + +#define ID_AA64DFR0_EL1_DoubleLock_SHIFT UL(36) +#define ID_AA64DFR0_EL1_DoubleLock_WIDTH UL(4) +#define ID_AA64DFR0_EL1_DoubleLock_MASK MASK(ID_AA64DFR0_EL1_DoubleLock) + +#define ID_AA64DFR0_EL1_PMSVer_SHIFT UL(32) +#define ID_AA64DFR0_EL1_PMSVer_WIDTH UL(4) +#define ID_AA64DFR0_EL1_PMSVer_MASK MASK(ID_AA64DFR0_EL1_PMSVer) + +#define ID_AA64DFR0_EL1_CTX_CMPS_SHIFT UL(28) +#define ID_AA64DFR0_EL1_CTX_CMPS_WIDTH UL(4) +#define ID_AA64DFR0_EL1_CTX_CMPS_MASK MASK(ID_AA64DFR0_EL1_CTX_CMPS) + +#define ID_AA64DFR0_EL1_WRPs_SHIFT UL(20) +#define ID_AA64DFR0_EL1_WRPs_WIDTH UL(4) +#define ID_AA64DFR0_EL1_WRPs_MASK MASK(ID_AA64DFR0_EL1_WRPs) + +#define ID_AA64DFR0_EL1_BRPs_SHIFT UL(12) +#define ID_AA64DFR0_EL1_BRPs_WIDTH UL(4) +#define ID_AA64DFR0_EL1_BRPs_MASK MASK(ID_AA64DFR0_EL1_BRPs) + +#define ID_AA64DFR0_EL1_PMUVer_SHIFT UL(8) +#define ID_AA64DFR0_EL1_PMUVer_WIDTH UL(4) +#define ID_AA64DFR0_EL1_PMUVer_MASK MASK(ID_AA64DFR0_EL1_PMUVer) + +#define ID_AA64DFR0_EL1_TraceVer_SHIFT UL(4) +#define ID_AA64DFR0_EL1_TraceVer_WIDTH UL(4) +#define ID_AA64DFR0_EL1_TraceVer_MASK MASK(ID_AA64DFR0_EL1_TraceVer) + +#define ID_AA64DFR0_EL1_DebugVer_SHIFT UL(0) +#define ID_AA64DFR0_EL1_DebugVer_WIDTH UL(4) +#define ID_AA64DFR0_EL1_DebugVer_MASK MASK(ID_AA64DFR0_EL1_DebugVer) + +/* Debug architecture version */ +#define ID_AA64DFR0_EL1_DebugVer_8 UL(6) +#define ID_AA64DFR0_EL1_DebugVer_8_VHE UL(7) +#define ID_AA64DFR0_EL1_DebugVer_8_2 UL(8) +#define ID_AA64DFR0_EL1_DebugVer_8_4 UL(9) +#define ID_AA64DFR0_EL1_DebugVer_8_8 UL(10) + /* ID_AA64PFR0_EL1 definitions */ #define ID_AA64PFR0_EL1_SVE_SHIFT UL(32) #define ID_AA64PFR0_EL1_SVE_WIDTH UL(4) @@ -478,8 +538,9 @@ #define ID_AA64MMFR0_EL1_TGRAN16_LPA2 UL(0x2) /* RNDR definitions */ -#define ID_AA64ISAR0_RNDR_SHIFT UL(60) -#define ID_AA64ISAR0_RNDR_MASK UL(0xF) +#define ID_AA64ISAR0_EL1_RNDR_SHIFT UL(60) +#define ID_AA64ISAR0_EL1_RNDR_WIDTH UL(4) +#define ID_AA64ISAR0_EL1_RNDR_MASK UL(0xF) /* ID_AA64MMFR1_EL1 definitions */ #define ID_AA64MMFR1_EL1_VMIDBits_SHIFT UL(4) @@ -850,10 +911,22 @@ #define ESR_EL2_SYSREG_ID_AA64MMFR1_EL1 SYSREG_ESR(3, 0, 0, 7, 1) #define ESR_EL2_SYSREG_ID_AA64MMFR2_EL1 SYSREG_ESR(3, 0, 0, 7, 2) -#define ESR_EL2_SYSREG_ID_AA64ISAR1_GPI_SHIFT 28 -#define ESR_EL2_SYSREG_ID_AA64ISAR1_GPA_SHIFT 24 -#define ESR_EL2_SYSREG_ID_AA64ISAR1_API_SHIFT 8 -#define ESR_EL2_SYSREG_ID_AA64ISAR1_APA_SHIFT 4 +/* ID_AA64ISAR1_EL1 definitions */ +#define ID_AA64ISAR1_EL1_GPI_SHIFT UL(28) +#define ID_AA64ISAR1_EL1_GPI_WIDTH UL(4) +#define ID_AA64ISAR1_EL1_GPI_MASK MASK(ID_AA64ISAR1_EL1_GPI) + +#define ID_AA64ISAR1_EL1_GPA_SHIFT UL(24) +#define ID_AA64ISAR1_EL1_GPA_WIDTH UL(4) +#define ID_AA64ISAR1_EL1_GPA_MASK MASK(ID_AA64ISAR1_EL1_GPA) + +#define ID_AA64ISAR1_EL1_API_SHIFT UL(8) +#define ID_AA64ISAR1_EL1_API_WIDTH UL(4) +#define ID_AA64ISAR1_EL1_API_MASK MASK(ID_AA64ISAR1_EL1_API) + +#define ID_AA64ISAR1_EL1_APA_SHIFT UL(4) +#define ID_AA64ISAR1_EL1_APA_WIDTH UL(4) +#define ID_AA64ISAR1_EL1_APA_MASK MASK(ID_AA64ISAR1_EL1_APA) #define ESR_EL2_SYSREG_TIMERS_MASK SYSREG_ESR(3, 3, 15, 12, 0) #define ESR_EL2_SYSREG_TIMERS SYSREG_ESR(3, 3, 14, 0, 0) diff --git a/lib/arch/include/arch_features.h b/lib/arch/include/arch_features.h index 96aa2e0b..c55e8246 100644 --- a/lib/arch/include/arch_features.h +++ b/lib/arch/include/arch_features.h @@ -32,8 +32,8 @@ static inline bool is_feat_sve_present(void) */ static inline bool is_feat_rng_present(void) { - return ((read_ID_AA64ISAR0_EL1() >> ID_AA64ISAR0_RNDR_SHIFT) & - ID_AA64ISAR0_RNDR_MASK) != 0UL; + return ((read_ID_AA64ISAR0_EL1() >> ID_AA64ISAR0_EL1_RNDR_SHIFT) & + ID_AA64ISAR0_EL1_RNDR_MASK) != 0UL; } /* diff --git a/lib/smc/include/smc-rmi.h b/lib/smc/include/smc-rmi.h index 5442f68d..678036b3 100644 --- a/lib/smc/include/smc-rmi.h +++ b/lib/smc/include/smc-rmi.h @@ -126,6 +126,10 @@ #define RMI_TABLE U(3) #define RMI_VALID_NS U(4) +/* RmiFeature enumerations */ +#define RMI_NOT_SUPPORTED UL(0) +#define RMI_SUPPORTED UL(1) + /* RmiFeatureRegister0 format */ #define RMM_FEATURE_REGISTER_0_INDEX UL(0) @@ -143,6 +147,12 @@ #define RMM_FEATURE_REGISTER_0_HASH_SHA_512_SHIFT UL(29) #define RMM_FEATURE_REGISTER_0_HASH_SHA_512_WIDTH UL(1) +#define RMM_FEATURE_REGISTER_0_PMU_EN_SHIFT UL(22) +#define RMM_FEATURE_REGISTER_0_PMU_EN_WIDTH UL(1) + +#define RMM_FEATURE_REGISTER_0_PMU_NUM_CTRS_SHIFT UL(23) +#define RMM_FEATURE_REGISTER_0_PMU_NUM_CTRS_WIDTH UL(5) + /* The RmmRipas enumeration representing realm IPA state */ #define RMI_EMPTY (0) #define RMI_RAM (1) diff --git a/runtime/core/sysregs.c b/runtime/core/sysregs.c index b2f7a666..7b8ab09b 100644 --- a/runtime/core/sysregs.c +++ b/runtime/core/sysregs.c @@ -12,33 +12,92 @@ #include <rec.h> #include <smc-rmi.h> -#define SYSREG_READ_CASE(reg) \ - case ESR_EL2_SYSREG_##reg: return read_##reg() +#define SYSREG_CASE(reg) \ + case ESR_EL2_SYSREG_##ID_AA64##reg##_EL1: -static unsigned long read_idreg(unsigned int idreg) -{ - switch (idreg) { - SYSREG_READ_CASE(ID_AA64PFR0_EL1); - SYSREG_READ_CASE(ID_AA64PFR1_EL1); - /* - * TODO: not supported without SVE: - * SYSREG_READ_CASE(ID_AA64ZFR0_EL1); - */ - SYSREG_READ_CASE(ID_AA64DFR0_EL1); - SYSREG_READ_CASE(ID_AA64DFR1_EL1); - SYSREG_READ_CASE(ID_AA64AFR0_EL1); - SYSREG_READ_CASE(ID_AA64AFR1_EL1); - SYSREG_READ_CASE(ID_AA64ISAR0_EL1); - SYSREG_READ_CASE(ID_AA64ISAR1_EL1); - SYSREG_READ_CASE(ID_AA64MMFR0_EL1); - SYSREG_READ_CASE(ID_AA64MMFR1_EL1); - SYSREG_READ_CASE(ID_AA64MMFR2_EL1); +#define SYSREG_READ(reg) \ + read_ID_AA64##reg##_EL1() - default: - /* All other encodings are in the RES0 space */ - return 0UL; - } -} +#define SYSREG_READ_CLEAR(reg) \ + (read_ID_AA64##reg##_EL1() & \ + ~(ID_AA64##reg##_EL1_CLEAR)) + +#define SYSREG_READ_CLEAR_SET(reg) \ + ((read_ID_AA64##reg##_EL1() & \ + ~(ID_AA64##reg##_EL1_CLEAR)) | \ + (ID_AA64##reg##_EL1_SET)) + +/* System registers ID_AA64xxx_EL1 feature clear masks and set values */ + +/* + * ID_AA64DFR0_EL1: + * + * Cleared fields: + * - Debug architecture version: + * set in ID_AA64DFR0_EL1_SET + * - Trace unit System registers not implemented + * - PMU is not implemented + * - Number of breakpoints: + * set in ID_AA64DFR0_EL1_SET + * - Number of watchpoints: + * set in ID_AA64DFR0_EL1_SET + * - Number of breakpoints that are context-aware + * - Statistical Profiling Extension not implemented + * - Armv8.4 Self-hosted Trace Extension not implemented + * - Trace Buffer Extension not implemented + * - FEAT_MTPMU not implemented + * - Branch Record Buffer Extension not implemented + */ +#define ID_AA64DFR0_EL1_CLEAR \ + ID_AA64DFR0_EL1_DebugVer_MASK | \ + ID_AA64DFR0_EL1_TraceVer_MASK | \ + ID_AA64DFR0_EL1_PMUVer_MASK | \ + ID_AA64DFR0_EL1_BRPs_MASK | \ + ID_AA64DFR0_EL1_WRPs_MASK | \ + ID_AA64DFR0_EL1_CTX_CMPS_MASK | \ + ID_AA64DFR0_EL1_PMSVer_MASK | \ + ID_AA64DFR0_EL1_TraceFilt_MASK | \ + ID_AA64DFR0_EL1_TraceBuffer_MASK | \ + ID_AA64DFR0_EL1_MTPMU_MASK | \ + ID_AA64DFR0_EL1_BRBE_MASK + +/* + * Set fields: + * - Armv8 debug architecture + * - Number of breakpoints: 2 + * - Number of watchpoints: 2 + */ +#define ID_AA64DFR0_EL1_SET \ + ID_AA64DFR0_EL1_DebugVer_8 | \ + INPLACE(ID_AA64DFR0_EL1_BRPs, 1UL) | \ + INPLACE(ID_AA64DFR0_EL1_WRPs, 1UL) + +/* + * ID_AA64ISAR1_EL1: + * + * Cleared fields: + * - Address and Generic Authentication are not implemented + */ +#define ID_AA64ISAR1_EL1_CLEAR \ + ID_AA64ISAR1_EL1_APA_MASK | \ + ID_AA64ISAR1_EL1_API_MASK | \ + ID_AA64ISAR1_EL1_GPA_MASK | \ + ID_AA64ISAR1_EL1_GPI_MASK + +/* + * ID_AA64PFR0_EL1: + * + * Cleared fields: + * - Activity Monitors Extension not implemented + * - Scalable Vector Extension not implemented. + * This is a temporary fix until RMM completely supports SVE. + * + * TODO: use and define: + * ID_AA64PFR0_EL1_AMU_MASK & ID_AA64PFR0_EL1_SVE_MASK + */ +#define ID_AA64PFR0_EL1_CLEAR \ + MASK(ID_AA64PFR0_EL1_AMU) | \ + MASK(ID_AA64PFR0_EL1_SVE) /* * Handle ID_AA64XXX<n>_EL1 instructions @@ -48,7 +107,7 @@ static bool handle_id_sysreg_trap(struct rec *rec, unsigned long esr) { unsigned int rt; - unsigned long idreg, mask; + unsigned long idreg, value; /* * We only set HCR_EL2.TID3 to trap ID registers at the moment and @@ -71,30 +130,54 @@ static bool handle_id_sysreg_trap(struct rec *rec, idreg = esr & ESR_EL2_SYSREG_MASK; - if (idreg == ESR_EL2_SYSREG_ID_AA64ISAR1_EL1) { - /* Clear Address and Generic Authentication bits */ - mask = (0xfUL << ESR_EL2_SYSREG_ID_AA64ISAR1_APA_SHIFT) | - (0xfUL << ESR_EL2_SYSREG_ID_AA64ISAR1_API_SHIFT) | - (0xfUL << ESR_EL2_SYSREG_ID_AA64ISAR1_GPA_SHIFT) | - (0xfUL << ESR_EL2_SYSREG_ID_AA64ISAR1_GPI_SHIFT); - /* - * Workaround for TF-A trapping AMU registers access - * to EL3 in Realm state - */ - } else if (idreg == ESR_EL2_SYSREG_ID_AA64PFR0_EL1) { - /* Clear support for Activity Monitors Extension */ - mask = MASK(ID_AA64PFR0_EL1_AMU); - + switch (idreg) { + SYSREG_CASE(AFR0) + value = SYSREG_READ(AFR0); + break; + SYSREG_CASE(AFR1) + value = SYSREG_READ(AFR1); + break; + SYSREG_CASE(DFR0) + value = SYSREG_READ_CLEAR_SET(DFR0); + break; + SYSREG_CASE(DFR1) + value = SYSREG_READ(DFR1); + break; + SYSREG_CASE(ISAR0) + value = SYSREG_READ(ISAR0); + break; + SYSREG_CASE(ISAR1) + value = SYSREG_READ_CLEAR(ISAR1); + break; + SYSREG_CASE(MMFR0) + value = SYSREG_READ(MMFR0); + break; + SYSREG_CASE(MMFR1) + value = SYSREG_READ(MMFR1); + break; + SYSREG_CASE(MMFR2) + value = SYSREG_READ(MMFR2); + break; + SYSREG_CASE(PFR0) /* - * Clear support for SVE. This is a temporary fix until RMM - * completely supports SVE. + * Workaround for TF-A trapping AMU registers access + * to EL3 in Realm state. */ - mask |= MASK(ID_AA64PFR0_EL1_SVE); - } else { - mask = 0UL; + value = SYSREG_READ_CLEAR(PFR0); + break; + SYSREG_CASE(PFR1) + value = SYSREG_READ(PFR1); + break; + /* + * TODO: not supported without SVE: + * SYSREG_CASE(ZFR0) + */ + default: + /* All other encodings are in the RES0 space */ + value = 0UL; } - rec->regs[rt] = read_idreg(idreg) & ~mask; + rec->regs[rt] = value; return true; } diff --git a/runtime/rmi/feature.c b/runtime/rmi/feature.c index 88bfbae3..a5da4131 100644 --- a/runtime/rmi/feature.c +++ b/runtime/rmi/feature.c @@ -24,8 +24,15 @@ static unsigned long get_feature_register_0(void) } /* Set support for SHA256 and SHA512 hash algorithms */ - feat_reg0 |= INPLACE(RMM_FEATURE_REGISTER_0_HASH_SHA_256, 1); - feat_reg0 |= INPLACE(RMM_FEATURE_REGISTER_0_HASH_SHA_512, 1); + feat_reg0 |= INPLACE(RMM_FEATURE_REGISTER_0_HASH_SHA_256, + RMI_SUPPORTED); + feat_reg0 |= INPLACE(RMM_FEATURE_REGISTER_0_HASH_SHA_512, + RMI_SUPPORTED); + + /* PMU is not supported */ + feat_reg0 |= INPLACE(RMM_FEATURE_REGISTER_0_PMU_EN, + RMI_NOT_SUPPORTED); + feat_reg0 |= INPLACE(RMM_FEATURE_REGISTER_0_PMU_NUM_CTRS, 0U); return feat_reg0; } @@ -60,6 +67,12 @@ static bool validate_feature_register_0(unsigned long value) return false; } + /* Validate PMU_EN flag */ + if ((EXTRACT(RMM_FEATURE_REGISTER_0_PMU_EN, value) == RMI_SUPPORTED) || + (EXTRACT(RMM_FEATURE_REGISTER_0_PMU_NUM_CTRS, value) != 0U)) { + return false; + } + return true; } |