summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSoby Mathew <soby.mathew@arm.com>2023-01-27 15:08:00 +0100
committerTrustedFirmware Code Review <review@review.trustedfirmware.org>2023-01-27 15:08:00 +0100
commit708eb9d6ef16700c38aa89232e63e8bdea18c486 (patch)
treeb0410ef564c79b848fb5506cf0441267fa7cfc84
parentf56d37aa8a6d7c029d1650e67fe915cb4bbb3384 (diff)
parent7bb7a70a8d22f4db7fbda6f9520e588a5e5d67e0 (diff)
downloadtf-rmm-708eb9d6ef16700c38aa89232e63e8bdea18c486.tar.gz
Merge "feat(rmm): report PMU not supported" into integration
-rw-r--r--lib/arch/include/arch.h85
-rw-r--r--lib/arch/include/arch_features.h4
-rw-r--r--lib/smc/include/smc-rmi.h10
-rw-r--r--runtime/core/sysregs.c175
-rw-r--r--runtime/rmi/feature.c17
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;
}