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;
+}