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/runtime/rmi/feature.c b/runtime/rmi/feature.c
index a5da413..a5c4a6a 100644
--- a/runtime/rmi/feature.c
+++ b/runtime/rmi/feature.c
@@ -9,8 +9,9 @@
 #include <smc-handler.h>
 #include <smc-rmi.h>
 #include <status.h>
+#include <utils_def.h>
 
-#define RMM_FEATURE_MIN_IPA_SIZE		PARANGE_0000_WIDTH
+#define RMM_FEATURE_MIN_IPA_SIZE	PARANGE_0000_WIDTH
 
 static unsigned long get_feature_register_0(void)
 {
@@ -29,10 +30,16 @@
 	feat_reg0 |= INPLACE(RMM_FEATURE_REGISTER_0_HASH_SHA_512,
 				RMI_SUPPORTED);
 
-	/* PMU is not supported */
+	/* RMM supports PMUv3p7+ */
+	assert(read_pmu_version() >= ID_AA64DFR0_EL1_PMUv3p7);
+
+	/* Set support for PMUv3 */
 	feat_reg0 |= INPLACE(RMM_FEATURE_REGISTER_0_PMU_EN,
-				RMI_NOT_SUPPORTED);
-	feat_reg0 |= INPLACE(RMM_FEATURE_REGISTER_0_PMU_NUM_CTRS, 0U);
+				RMI_SUPPORTED);
+
+	/* Set number of PMU counters available */
+	feat_reg0 |= INPLACE(RMM_FEATURE_REGISTER_0_PMU_NUM_CTRS,
+				EXTRACT(PMCR_EL0_N, read_pmcr_el0()));
 
 	return feat_reg0;
 }
@@ -63,13 +70,19 @@
 
 	/* Validate LPA2 flag */
 	if ((EXTRACT(RMM_FEATURE_REGISTER_0_LPA2, value) == RMI_LPA2) &&
-	    !is_feat_lpa2_4k_present()) {
+	    (EXTRACT(RMM_FEATURE_REGISTER_0_LPA2, feat_reg0) == RMI_NO_LPA2)) {
 		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)) {
+	/*
+	 * Skip validation of RMM_FEATURE_REGISTER_0_PMU_EN flag
+	 * as RMM always assumes that PMUv3p7+ is present.
+	 */
+
+	/* Validate number of PMU counters if PMUv3 is enabled */
+	if ((EXTRACT(RMM_FEATURE_REGISTER_0_PMU_EN, value) == RMI_SUPPORTED) &&
+	    (EXTRACT(RMM_FEATURE_REGISTER_0_PMU_NUM_CTRS, value) !=
+	     EXTRACT(RMM_FEATURE_REGISTER_0_PMU_NUM_CTRS, feat_reg0))) {
 		return false;
 	}