feat(pmu): add PMU support for Realms
This patch adds support for using PMU in Realms.
It adds 'bool pmu_enabled' and 'unsigned int pmu_num_cnts'
variables in 'struct rd' and 'struct rec.realm_info'.
Signed-off-by: AlexeiFedorov <Alexei.Fedorov@arm.com>
Change-Id: I13aad600a0215ba66d25be12ede5f4b86e6b018a
diff --git a/lib/arch/include/arch.h b/lib/arch/include/arch.h
index cc46639..6d898fe 100644
--- a/lib/arch/include/arch.h
+++ b/lib/arch/include/arch.h
@@ -395,6 +395,9 @@
#define ID_AA64DFR0_EL1_HPMN0_SHIFT UL(60)
#define ID_AA64DFR0_EL1_HPMN0_WIDTH UL(4)
+#define ID_AA64DFR0_EL1_ExtTrcBuff_SHIFT UL(56)
+#define ID_AA64DFR0_EL1_ExtTrcBuff_WIDTH UL(4)
+
#define ID_AA64DFR0_EL1_BRBE_SHIFT UL(52)
#define ID_AA64DFR0_EL1_BRBE_WIDTH UL(4)
@@ -416,15 +419,26 @@
#define ID_AA64DFR0_EL1_CTX_CMPS_SHIFT UL(28)
#define ID_AA64DFR0_EL1_CTX_CMPS_WIDTH UL(4)
+#define ID_AA64DFR0_EL1_SEBEP_SHIFT UL(24)
+#define ID_AA64DFR0_EL1_SEBEP_WIDTH UL(4)
+
#define ID_AA64DFR0_EL1_WRPs_SHIFT UL(20)
#define ID_AA64DFR0_EL1_WRPs_WIDTH UL(4)
+#define ID_AA64DFR0_EL1_PMSS_SHIFT UL(16)
+#define ID_AA64DFR0_EL1_PMSS_WIDTH UL(4)
+
#define ID_AA64DFR0_EL1_BRPs_SHIFT UL(12)
#define ID_AA64DFR0_EL1_BRPs_WIDTH UL(4)
#define ID_AA64DFR0_EL1_PMUVer_SHIFT UL(8)
#define ID_AA64DFR0_EL1_PMUVer_WIDTH UL(4)
+/* Performance Monitors Extension version */
+#define ID_AA64DFR0_EL1_PMUv3p7 UL(7)
+#define ID_AA64DFR0_EL1_PMUv3p8 UL(8)
+#define ID_AA64DFR0_EL1_PMUv3p9 UL(9)
+
#define ID_AA64DFR0_EL1_TraceVer_SHIFT UL(4)
#define ID_AA64DFR0_EL1_TraceVer_WIDTH UL(4)
@@ -432,11 +446,18 @@
#define ID_AA64DFR0_EL1_DebugVer_WIDTH UL(4)
/* 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)
+#define ID_AA64DFR0_EL1_Debugv8 UL(6)
+#define ID_AA64DFR0_EL1_DebugVHE UL(7)
+#define ID_AA64DFR0_EL1_Debugv8p2 UL(8)
+#define ID_AA64DFR0_EL1_Debugv8p4 UL(9)
+#define ID_AA64DFR0_EL1_Debugv8p8 UL(10)
+
+/* ID_AA64DFR1_EL1 definitions */
+#define ID_AA64DFR1_EL1_EBEP_SHIFT UL(48)
+#define ID_AA64DFR1_EL1_EBEP_WIDTH UL(4)
+
+#define ID_AA64DFR1_EL1_ICNTR_SHIFT UL(36)
+#define ID_AA64DFR1_EL1_ICNTR_WIDTH UL(4)
/* ID_AA64PFR0_EL1 definitions */
#define ID_AA64PFR0_EL1_SVE_SHIFT UL(32)
@@ -463,34 +484,35 @@
#define ID_AA64MMFR0_EL1_ECV_SHIFT UL(60)
#define ID_AA64MMFR0_EL1_ECV_WIDTH UL(4)
-#define ID_AA64MMFR0_EL1_ECV_NOT_SUPPORTED ULL(0x0)
-#define ID_AA64MMFR0_EL1_ECV_SUPPORTED ULL(0x1)
+#define ID_AA64MMFR0_EL1_ECV_NOT_SUPPORTED UL(0x0)
+#define ID_AA64MMFR0_EL1_ECV_SUPPORTED UL(0x1)
#define ID_AA64MMFR0_EL1_ECV_SELF_SYNCH ULL(0x2)
#define ID_AA64MMFR0_EL1_FGT_SHIFT UL(56)
#define ID_AA64MMFR0_EL1_FGT_WIDTH UL(4)
-#define ID_AA64MMFR0_EL1_FGT_SUPPORTED ULL(0x1)
-#define ID_AA64MMFR0_EL1_FGT_NOT_SUPPORTED ULL(0x0)
+#define ID_AA64MMFR0_EL1_FGT_NOT_SUPPORTED UL(0x0)
+#define ID_AA64MMFR0_EL1_FGT_SUPPORTED UL(0x1)
+#define ID_AA64MMFR0_EL1_FGT2_SUPPORTED UL(0x2)
#define ID_AA64MMFR0_EL1_TGRAN4_2_SHIFT U(40)
#define ID_AA64MMFR0_EL1_TGRAN4_2_WIDTH U(4)
-#define ID_AA64MMFR0_EL1_TGRAN4_2_TGRAN4 ULL(0x0)
-#define ID_AA64MMFR0_EL1_TGRAN4_2_NOT_SUPPORTED ULL(0x1)
-#define ID_AA64MMFR0_EL1_TGRAN4_2_SUPPORTED ULL(0x2)
-#define ID_AA64MMFR0_EL1_TGRAN4_2_LPA2 ULL(0x3)
+#define ID_AA64MMFR0_EL1_TGRAN4_2_TGRAN4 UL(0x0)
+#define ID_AA64MMFR0_EL1_TGRAN4_2_NOT_SUPPORTED UL(0x1)
+#define ID_AA64MMFR0_EL1_TGRAN4_2_SUPPORTED UL(0x2)
+#define ID_AA64MMFR0_EL1_TGRAN4_2_LPA2 UL(0x3)
#define ID_AA64MMFR0_EL1_TGRAN16_2_SHIFT UL(32)
#define ID_AA64MMFR0_EL1_TGRAN16_2_WIDTH UL(4)
-#define ID_AA64MMFR0_EL1_TGRAN16_2_TGRAN16 ULL(0x0)
-#define ID_AA64MMFR0_EL1_TGRAN16_2_NOT_SUPPORTED ULL(0x1)
-#define ID_AA64MMFR0_EL1_TGRAN16_2_SUPPORTED ULL(0x2)
-#define ID_AA64MMFR0_EL1_TGRAN16_2_LPA2 ULL(0x3)
+#define ID_AA64MMFR0_EL1_TGRAN16_2_TGRAN16 UL(0x0)
+#define ID_AA64MMFR0_EL1_TGRAN16_2_NOT_SUPPORTED UL(0x1)
+#define ID_AA64MMFR0_EL1_TGRAN16_2_SUPPORTED UL(0x2)
+#define ID_AA64MMFR0_EL1_TGRAN16_2_LPA2 UL(0x3)
#define ID_AA64MMFR0_EL1_TGRAN4_SHIFT UL(28)
#define ID_AA64MMFR0_EL1_TGRAN4_WIDTH UL(4)
-#define ID_AA64MMFR0_EL1_TGRAN4_SUPPORTED ULL(0x0)
-#define ID_AA64MMFR0_EL1_TGRAN4_LPA2 ULL(0x1)
-#define ID_AA64MMFR0_EL1_TGRAN4_NOT_SUPPORTED ULL(0xf)
+#define ID_AA64MMFR0_EL1_TGRAN4_SUPPORTED UL(0x0)
+#define ID_AA64MMFR0_EL1_TGRAN4_LPA2 UL(0x1)
+#define ID_AA64MMFR0_EL1_TGRAN4_NOT_SUPPORTED UL(0xf)
#define ID_AA64MMFR0_EL1_TGRAN64_SHIFT UL(24)
#define ID_AA64MMFR0_EL1_TGRAN64_WIDTH UL(4)
@@ -627,10 +649,17 @@
SCTLR_EL1_SA0 | SCTLR_EL1_SA)
/* PMCR_EL0 Definitions */
-#define PMCR_EL0_LC_BIT (UL(1) << 6)
+#define PMCR_EL0_N_SHIFT 11
+#define PMCR_EL0_N_WIDTH 5
+#define PMCR_EL0_LC_BIT (UL(1) << 6)
+#define PMCR_EL0_DP_BIT (UL(1) << 5)
+#define PMCR_EL0_C_BIT (UL(1) << 2)
+#define PMCR_EL0_P_BIT (UL(1) << 1)
+#define PMCR_EL0_E_BIT (UL(1) << 0)
-#define PMCR_EL0_RES1 PMCR_EL0_LC_BIT
-
+#define PMCR_EL0_INIT (PMCR_EL0_LC_BIT | PMCR_EL0_DP_BIT)
+#define PMCR_EL0_INIT_RESET (PMCR_EL0_INIT | PMCR_EL0_C_BIT | \
+ PMCR_EL0_P_BIT)
/* MDSCR_EL1 Definitions */
#define MDSCR_EL1_TDCC_BIT (UL(1) << 12)
@@ -721,6 +750,10 @@
CPTR_EL2_RES1)
/* MDCR_EL2 definitions */
+#define MDCR_EL2_HPMFZS (UL(1) << 36)
+#define MDCR_EL2_HPMFZO (UL(1) << 29)
+#define MDCR_EL2_MTPME (UL(1) << 28)
+#define MDCR_EL2_TDCC (UL(1) << 27)
#define MDCR_EL2_HLP (UL(1) << 26)
#define MDCR_EL2_HCCD (UL(1) << 23)
#define MDCR_EL2_TTRF (UL(1) << 19)
@@ -735,9 +768,16 @@
#define MDCR_EL2_HPME_BIT (UL(1) << 7)
#define MDCR_EL2_TPM_BIT (UL(1) << 6)
#define MDCR_EL2_TPMCR_BIT (UL(1) << 5)
-#define MDCR_EL2_INIT (MDCR_EL2_TPMCR_BIT \
- | MDCR_EL2_TPM_BIT \
- | MDCR_EL2_TDA_BIT)
+
+#define MDCR_EL2_HPMN_SHIFT UL(0)
+#define MDCR_EL2_HPMN_WIDTH UL(5)
+
+#define MDCR_EL2_INIT (MDCR_EL2_MTPME | \
+ MDCR_EL2_HCCD | \
+ MDCR_EL2_HPMD | \
+ MDCR_EL2_TDA_BIT | \
+ MDCR_EL2_TPM_BIT | \
+ MDCR_EL2_TPMCR_BIT)
/* MPIDR definitions */
#define MPIDR_EL1_AFF_MASK 0xFF
diff --git a/lib/arch/include/arch_features.h b/lib/arch/include/arch_features.h
index 23fe6c0..8efed1e 100644
--- a/lib/arch/include/arch_features.h
+++ b/lib/arch/include/arch_features.h
@@ -51,7 +51,7 @@
/*
* Check if FEAT_LPA2 is implemented.
- * 4KB granule at stage 2 supports 52-bit input and output addresses:
+ * 4KB granule at stage 2 supports 52-bit input and output addresses:
* ID_AA64MMFR0_EL1.TGran4_2 bits [43:40]: 0b0011
*/
static inline bool is_feat_lpa2_4k_present(void)
@@ -60,6 +60,16 @@
read_id_aa64mmfr0_el1()) == ID_AA64MMFR0_EL1_TGRAN4_2_LPA2);
}
+/*
+ * Returns Performance Monitors Extension version.
+ * ID_AA64DFR0_EL1.PMUVer, bits [11:8]:
+ * 0b0000: Performance Monitors Extension not implemented
+ */
+static inline unsigned int read_pmu_version(void)
+{
+ return EXTRACT(ID_AA64DFR0_EL1_PMUVer, read_id_aa64dfr0_el1());
+}
+
unsigned int arch_feat_get_pa_width(void);
#endif /* ARCH_FEATURES_H */
diff --git a/lib/arch/include/arch_helpers.h b/lib/arch/include/arch_helpers.h
index 805e488..2338604 100644
--- a/lib/arch/include/arch_helpers.h
+++ b/lib/arch/include/arch_helpers.h
@@ -186,7 +186,85 @@
DEFINE_SYSREG_RW_FUNCS(sp_el1)
DEFINE_SYSREG_RW_FUNCS(elr_el12)
DEFINE_SYSREG_RW_FUNCS(spsr_el12)
+
+DEFINE_SYSREG_RW_FUNCS(pmccfiltr_el0)
+DEFINE_SYSREG_RW_FUNCS(pmccntr_el0)
+DEFINE_SYSREG_RW_FUNCS(pmcntenclr_el0)
+DEFINE_SYSREG_RW_FUNCS(pmcntenset_el0)
+DEFINE_SYSREG_RW_FUNCS(pmcr_el0)
+DEFINE_SYSREG_RW_FUNCS(pmintenclr_el1)
+DEFINE_SYSREG_RW_FUNCS(pmintenset_el1)
+DEFINE_SYSREG_RW_FUNCS(pmovsclr_el0)
+DEFINE_SYSREG_RW_FUNCS(pmovsset_el0)
+DEFINE_SYSREG_RW_FUNCS(pmselr_el0)
DEFINE_SYSREG_RW_FUNCS(pmuserenr_el0)
+DEFINE_SYSREG_RW_FUNCS(pmxevcntr_el0)
+DEFINE_SYSREG_RW_FUNCS(pmxevtyper_el0)
+
+DEFINE_SYSREG_RW_FUNCS(pmevcntr0_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevcntr1_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevcntr2_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevcntr3_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevcntr4_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevcntr5_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevcntr6_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevcntr7_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevcntr8_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevcntr9_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevcntr10_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevcntr11_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevcntr12_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevcntr13_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevcntr14_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevcntr15_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevcntr16_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevcntr17_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevcntr18_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevcntr19_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevcntr20_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevcntr21_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevcntr22_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevcntr23_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevcntr24_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevcntr25_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevcntr26_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevcntr27_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevcntr28_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevcntr29_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevcntr30_el0)
+
+DEFINE_SYSREG_RW_FUNCS(pmevtyper0_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevtyper1_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevtyper2_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevtyper3_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevtyper4_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevtyper5_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevtyper6_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevtyper7_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevtyper8_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevtyper9_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevtyper10_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevtyper11_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevtyper12_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevtyper13_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevtyper14_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevtyper15_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevtyper16_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevtyper17_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevtyper18_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevtyper19_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevtyper20_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevtyper21_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevtyper22_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevtyper23_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevtyper24_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevtyper25_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevtyper26_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevtyper27_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevtyper28_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevtyper29_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevtyper30_el0)
+
DEFINE_SYSREG_RW_FUNCS(tpidrro_el0)
DEFINE_SYSREG_RW_FUNCS(tpidr_el0)
DEFINE_SYSREG_RW_FUNCS(tpidr_el2)
@@ -226,12 +304,17 @@
DEFINE_RENAME_SYSREG_READ_FUNC(ID_AA64MMFR2_EL1, id_aa64mmfr2_el1)
DEFINE_RENAME_SYSREG_READ_FUNC(ID_AA64PFR0_EL1, id_aa64pfr0_el1)
DEFINE_RENAME_SYSREG_READ_FUNC(ID_AA64PFR1_EL1, id_aa64pfr1_el1)
-DEFINE_RENAME_SYSREG_RW_FUNCS(icc_hppir1_el1, ICC_HPPIR1_EL1)
+DEFINE_SYSREG_READ_FUNC(id_aa64afr0_el1)
+DEFINE_SYSREG_READ_FUNC(id_aa64afr1_el1)
+DEFINE_SYSREG_READ_FUNC(id_aa64dfr0_el1)
+DEFINE_SYSREG_READ_FUNC(id_aa64dfr1_el1)
DEFINE_SYSREG_READ_FUNC(id_aa64isar0_el1)
+DEFINE_SYSREG_READ_FUNC(id_aa64isar1_el1)
DEFINE_SYSREG_READ_FUNC(id_aa64mmfr0_el1)
DEFINE_SYSREG_READ_FUNC(id_aa64mmfr1_el1)
DEFINE_SYSREG_READ_FUNC(id_aa64mmfr2_el1)
DEFINE_SYSREG_READ_FUNC(id_aa64pfr0_el1)
+DEFINE_SYSREG_READ_FUNC(id_aa64pfr1_el1)
DEFINE_RENAME_SYSREG_RW_FUNCS(mpam0_el1, MPAM0_EL1)
DEFINE_SYSREG_READ_FUNC(id_afr0_el1)
DEFINE_SYSREG_READ_FUNC(CurrentEl)
@@ -303,7 +386,6 @@
DEFINE_SYSREG_RW_FUNCS(mdcr_el2)
DEFINE_SYSREG_RW_FUNCS(hstr_el2)
-DEFINE_SYSREG_RW_FUNCS(pmcr_el0)
DEFINE_SYSREG_RW_FUNCS(mpam2_el2)
DEFINE_SYSREG_RW_FUNCS(mpamhcr_el2)
DEFINE_SYSREG_RW_FUNCS(pmscr_el2)
@@ -335,7 +417,7 @@
******************************************************************************/
DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sre_el2, ICC_SRE_EL2)
DEFINE_RENAME_SYSREG_RW_FUNCS(icc_ctrl_el1, ICC_CTLR_EL1)
-DEFINE_RENAME_SYSREG_READ_FUNC(icc_hppir1_el2, ICC_HPPIR1_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(icc_hppir1_el1, ICC_HPPIR1_EL1)
/*******************************************************************************
* Virtual GIC register accessor prototypes
diff --git a/lib/arch/include/pmu.h b/lib/arch/include/pmu.h
new file mode 100644
index 0000000..5d1588d
--- /dev/null
+++ b/lib/arch/include/pmu.h
@@ -0,0 +1,47 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
+ */
+
+#ifndef PMU_H
+#define PMU_H
+
+#include <arch_helpers.h>
+#include <utils_def.h>
+
+struct rmi_rec_exit;
+struct rec;
+
+struct pmev_regs {
+ unsigned long pmevcntr_el0;
+ unsigned long pmevtyper_el0;
+};
+
+/*
+ * PMU context structure.
+ * Align on cache writeback granule to minimise cache line
+ * thashing when allocated as an array for use by each CPU.
+ */
+struct pmu_state {
+ unsigned long pmccfiltr_el0;
+ unsigned long pmccntr_el0;
+ unsigned long pmcntenset_el0;
+ unsigned long pmcntenclr_el0;
+ unsigned long pmintenset_el1;
+ unsigned long pmintenclr_el1;
+ unsigned long pmovsset_el0;
+ unsigned long pmovsclr_el0;
+ unsigned long pmselr_el0;
+ unsigned long pmuserenr_el0;
+ unsigned long pmxevcntr_el0;
+ unsigned long pmxevtyper_el0;
+
+ struct pmev_regs pmev_regs[31];
+
+} __aligned(CACHE_WRITEBACK_GRANULE);
+
+void pmu_save_state(struct pmu_state *pmu, unsigned int num_cnts);
+void pmu_restore_state(struct pmu_state *pmu, unsigned int num_cnts);
+void pmu_update_rec_exit(struct rmi_rec_exit *rec_exit);
+
+#endif /* PMU_H */