feat(spe): add simple SPE test
Added simple SPE test that reads static profiling system registers
of available SPE version i.e. FEAT_SPE/FEAT_SPEv1p1/FEAT_SPEv1p2
Signed-off-by: Manish V Badarkhe <Manish.Badarkhe@arm.com>
Change-Id: I6fe02914b0ad5e8b702654dab27aee449b3b7b9f
diff --git a/tftf/tests/extensions/spe/test_spe.c b/tftf/tests/extensions/spe/test_spe.c
new file mode 100644
index 0000000..8b18654
--- /dev/null
+++ b/tftf/tests/extensions/spe/test_spe.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <test_helpers.h>
+
+#ifdef __aarch64__
+/*
+ * Get SPE version value from id_aa64dfr0_el1.
+ * Return values
+ * ID_AA64DFR0_SPE_NOT_SUPPORTED: not supported
+ * ID_AA64DFR0_SPE: FEAT_SPE supported (introduced in ARM v8.2)
+ * ID_AA64DFR0_SPE_V1P1: FEAT_SPEv1p1 supported (introduced in ARM v8.5)
+ * ID_AA64DFR0_SPE_V1P2: FEAT_SPEv1p2 supported (introduced in ARM v8.7)
+ */
+
+typedef enum {
+ ID_AA64DFR0_SPE_NOT_SUPPORTED = 0,
+ ID_AA64DFR0_SPE,
+ ID_AA64DFR0_SPE_V1P1,
+ ID_AA64DFR0_SPE_V1P2
+} spe_ver_t;
+
+static spe_ver_t spe_get_version(void)
+{
+ return (spe_ver_t)((read_id_aa64dfr0_el1() >> ID_AA64DFR0_PMS_SHIFT) &
+ ID_AA64DFR0_PMS_MASK);
+}
+#endif /* __aarch64__ */
+
+test_result_t test_spe_support(void)
+{
+ /* SPE is an AArch64-only feature.*/
+ SKIP_TEST_IF_AARCH32();
+
+#ifdef __aarch64__
+ spe_ver_t spe_ver = spe_get_version();
+
+ assert(spe_ver <= ID_AA64DFR0_SPE_V1P2);
+
+ if (spe_ver == ID_AA64DFR0_SPE_NOT_SUPPORTED) {
+ return TEST_RESULT_SKIPPED;
+ }
+
+ /*
+ * If runtime-EL3 does not enable access to SPE system
+ * registers from NS-EL2/NS-EL1 then read of these
+ * registers traps in EL3
+ */
+ read_pmscr_el1();
+ read_pmsfcr_el1();
+ read_pmsicr_el1();
+ read_pmsidr_el1();
+ read_pmsirr_el1();
+ read_pmslatfr_el1();
+ read_pmblimitr_el1();
+ read_pmbptr_el1();
+ read_pmbsr_el1();
+ read_pmsevfr_el1();
+ if (IS_IN_EL2()) {
+ read_pmscr_el2();
+ }
+ if (spe_ver == ID_AA64DFR0_SPE_V1P2) {
+ read_pmsnevfr_el1();
+ }
+
+ return TEST_RESULT_SUCCESS;
+#endif /* __aarch64__ */
+}