feat(rme): add tests to check NS SME ID registers and configurations
These tests checks the functionality of RMM for NS SME support.
- Create Realm and test ID registers specific to SME
- Check if Realm gets undefined abort when it accesses SME
- Check whether RMM preserves NS SMCR_EL2 register
Signed-off-by: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
Change-Id: Ia8ffd0188297a74c095dbadfb389add50c548e10
diff --git a/realm/aarch64/realm_entrypoint.S b/realm/aarch64/realm_entrypoint.S
index ab00989..016689f 100644
--- a/realm/aarch64/realm_entrypoint.S
+++ b/realm/aarch64/realm_entrypoint.S
@@ -111,6 +111,8 @@
orr x0, x0, x1
mov x1, CPACR_EL1_ZEN(CPACR_EL1_ZEN_TRAP_NONE)
orr x0, x0, x1
+ mov x1, CPACR_EL1_SMEN(CPACR_EL1_SMEN_TRAP_NONE)
+ orr x0, x0, x1
msr cpacr_el1, x0
isb
diff --git a/realm/include/realm_tests.h b/realm/include/realm_tests.h
index ac839ac..5caea8c 100644
--- a/realm/include/realm_tests.h
+++ b/realm/include/realm_tests.h
@@ -23,6 +23,8 @@
bool test_realm_sve_cmp_regs(void);
bool test_realm_sve_undef_abort(void);
bool test_realm_multiple_rec_psci_denied_cmd(void);
+bool test_realm_sme_read_id_registers(void);
+bool test_realm_sme_undef_abort(void);
#endif /* REALM_TESTS_H */
diff --git a/realm/realm_payload_main.c b/realm/realm_payload_main.c
index aaf7479..e1f78c5 100644
--- a/realm/realm_payload_main.c
+++ b/realm/realm_payload_main.c
@@ -143,6 +143,12 @@
case REALM_SVE_UNDEF_ABORT:
test_succeed = test_realm_sve_undef_abort();
break;
+ case REALM_SME_ID_REGISTERS:
+ test_succeed = test_realm_sme_read_id_registers();
+ break;
+ case REALM_SME_UNDEF_ABORT:
+ test_succeed = test_realm_sme_undef_abort();
+ break;
default:
realm_printf("%s() invalid cmd %u\n", __func__, cmd);
break;
diff --git a/realm/realm_simd.c b/realm/realm_simd.c
index 273696b..106a849 100644
--- a/realm/realm_simd.c
+++ b/realm/realm_simd.c
@@ -13,7 +13,7 @@
#include <lib/extensions/fpu.h>
#include <lib/extensions/sve.h>
-#include <host_realm_sve.h>
+#include <host_realm_simd.h>
#include <host_shared_data.h>
#define RL_SVE_OP_ARRAYSIZE 512U
@@ -218,3 +218,38 @@
return true;
}
+
+/* Reads and returns the ID_AA64PFR1_EL1 and ID_AA64SMFR0_EL1 registers */
+bool test_realm_sme_read_id_registers(void)
+{
+ host_shared_data_t *sd = realm_get_my_shared_structure();
+ struct sme_cmd_id_regs *output;
+
+ output = (struct sme_cmd_id_regs *)sd->realm_cmd_output_buffer;
+ memset((void *)output, 0, sizeof(struct sme_cmd_id_regs));
+
+ realm_printf("Realm: reading ID registers: ID_AA64PFR1_EL1, "
+ " ID_AA64SMFR0_EL1\n");
+
+ output->id_aa64pfr1_el1 = read_id_aa64pfr1_el1();
+ output->id_aa64smfr0_el1 = read_id_aa64smfr0_el1();
+
+ return true;
+}
+
+/* Check if Realm gets undefined abort when it access SME functionality */
+bool test_realm_sme_undef_abort(void)
+{
+ realm_got_undef_abort = 0UL;
+
+ /* install exception handler to catch undef abort */
+ register_custom_sync_exception_handler(&realm_sync_exception_handler);
+ (void)read_svcr();
+ unregister_custom_sync_exception_handler();
+
+ if (realm_got_undef_abort == 0UL) {
+ return false;
+ }
+
+ return true;
+}