test(pmu): check if PMUv3 is functional

The PMU is tested for secure world leakage but there are no checks
whether it works in the first place.

The counter and event counters are exercised separately. This is because
the functionality of one does not imply the functionality of the other
(EL3 has separate controls for both). This additionally catches a corner
case with FEAT_HPMN0 missing without failing all tests.

Signed-off-by: Boyan Karatotev <boyan.karatotev@arm.com>
Change-Id: I966d3155cdd6edfde01af32f7c50c3bb3644274a
diff --git a/include/lib/aarch64/arch_helpers.h b/include/lib/aarch64/arch_helpers.h
index e10ddab..f79174e 100644
--- a/include/lib/aarch64/arch_helpers.h
+++ b/include/lib/aarch64/arch_helpers.h
@@ -416,6 +416,34 @@
 
 DEFINE_SYSREG_RW_FUNCS(pmevtyper0_el0)
 DEFINE_SYSREG_READ_FUNC(pmevcntr0_el0)
+DEFINE_SYSREG_RW_FUNCS(pmselr_el0)
+DEFINE_SYSREG_RW_FUNCS(pmxevtyper_el0)
+DEFINE_SYSREG_RW_FUNCS(pmxevcntr_el0)
+
+/* parameterised event counter accessors */
+static inline u_register_t read_pmevcntrn_el0(int ctr_num)
+{
+	write_pmselr_el0(ctr_num & PMSELR_EL0_SEL_MASK);
+	return read_pmxevcntr_el0();
+}
+
+static inline void write_pmevcntrn_el0(int ctr_num, u_register_t val)
+{
+	write_pmselr_el0(ctr_num & PMSELR_EL0_SEL_MASK);
+	write_pmxevcntr_el0(val);
+}
+
+static inline u_register_t read_pmevtypern_el0(int ctr_num)
+{
+	write_pmselr_el0(ctr_num & PMSELR_EL0_SEL_MASK);
+	return read_pmxevtyper_el0();
+}
+
+static inline void write_pmevtypern_el0(int ctr_num, u_register_t val)
+{
+	write_pmselr_el0(ctr_num & PMSELR_EL0_SEL_MASK);
+	write_pmxevtyper_el0(val);
+}
 
 /* Armv8.5 FEAT_RNG Registers */
 DEFINE_SYSREG_READ_FUNC(rndr)