feat(rme): add SVE Realm tests

Verifies Realm with SVE support. Below tests are added
- Check whether RMI features reports proper SVE VL
- Create SVE Realm and check rdvl result
- Create SVE Realm with invalid VL and check if it fails
- Create SVE Realm and test ID registers
- Create non SVE Realm and test ID registers
- Create SVE Realm and probe all supported VLs
- Check RMM preserves NS ZCR_EL2 register

Signed-off-by: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
Change-Id: I98a20f34ce72c7c1a353ed13678870168fa27c48
diff --git a/realm/aarch64/realm_entrypoint.S b/realm/aarch64/realm_entrypoint.S
index 97c4ff5..0fd4f9b 100644
--- a/realm/aarch64/realm_entrypoint.S
+++ b/realm/aarch64/realm_entrypoint.S
@@ -72,6 +72,8 @@
 	mov	x1, CPACR_EL1_FPEN(CPACR_EL1_FP_TRAP_NONE)
 	mrs	x0, cpacr_el1
 	orr	x0, x0, x1
+	mov	x1, CPACR_EL1_ZEN(CPACR_EL1_ZEN_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 0e653ba..c1c780b 100644
--- a/realm/include/realm_tests.h
+++ b/realm/include/realm_tests.h
@@ -12,6 +12,9 @@
 bool test_pmuv3_event_works_realm(void);
 bool test_pmuv3_rmm_preserves(void);
 bool test_pmuv3_overflow_interrupt(void);
+bool test_realm_sve_rdvl(void);
+bool test_realm_sve_read_id_registers(void);
+bool test_realm_sve_probe_vl(void);
 
 #endif /* REALM_TESTS_H */
 
diff --git a/realm/realm.mk b/realm/realm.mk
index 923a687..e12f3e1 100644
--- a/realm/realm.mk
+++ b/realm/realm.mk
@@ -32,6 +32,7 @@
 	realm_pmuv3.c							\
 	realm_rsi.c							\
 	realm_shared_data.c						\
+	realm_sve.c							\
 	)
 
 REALM_SOURCES += lib/${ARCH}/cache_helpers.S				\
@@ -41,7 +42,8 @@
 	lib/exceptions/${ARCH}/sync.c					\
 	lib/locks/${ARCH}/spinlock.S					\
 	lib/delay/delay.c						\
-	lib/extensions/fpu/fpu.c
+	lib/extensions/fpu/fpu.c					\
+	lib/extensions/sve/aarch64/sve.c
 
 # TODO: Remove dependency on TFTF files.
 REALM_SOURCES	+=							\
diff --git a/realm/realm_payload_main.c b/realm/realm_payload_main.c
index c6665b4..f19dd3e 100644
--- a/realm/realm_payload_main.c
+++ b/realm/realm_payload_main.c
@@ -93,6 +93,14 @@
 			break;
 		case REALM_REQ_FPU_CMP_CMD:
 			test_succeed = fpu_state_compare_template(&fpu_temp_rl);
+		case REALM_SVE_RDVL:
+			test_succeed = test_realm_sve_rdvl();
+			break;
+		case REALM_SVE_ID_REGISTERS:
+			test_succeed = test_realm_sve_read_id_registers();
+			break;
+		case REALM_SVE_PROBE_VL:
+			test_succeed = test_realm_sve_probe_vl();
 			break;
 		default:
 			realm_printf("%s() invalid cmd %u\n", __func__, cmd);
diff --git a/realm/realm_sve.c b/realm/realm_sve.c
new file mode 100644
index 0000000..349b8d7
--- /dev/null
+++ b/realm/realm_sve.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <arch_features.h>
+#include <arch_helpers.h>
+#include <assert.h>
+#include <debug.h>
+#include <lib/extensions/sve.h>
+
+#include <host_realm_sve.h>
+#include <host_shared_data.h>
+
+/* Returns the maximum supported VL. This test is called only by sve Realm */
+bool test_realm_sve_rdvl(void)
+{
+	host_shared_data_t *sd = realm_get_shared_structure();
+	struct sve_cmd_rdvl *output;
+
+	assert(is_armv8_2_sve_present());
+
+	output = (struct sve_cmd_rdvl *)sd->realm_cmd_output_buffer;
+	memset((void *)output, 0, sizeof(struct sve_cmd_rdvl));
+
+	sve_config_vq(SVE_VQ_ARCH_MAX);
+	output->rdvl = sve_vector_length_get();
+
+	return true;
+}
+
+/*
+ * Reads and returns the ID_AA64PFR0_EL1 and ID_AA64ZFR0_EL1 registers
+ * This test could be called from sve or non-sve Realm
+ */
+bool test_realm_sve_read_id_registers(void)
+{
+	host_shared_data_t *sd = realm_get_shared_structure();
+	struct sve_cmd_id_regs *output;
+
+	output = (struct sve_cmd_id_regs *)sd->realm_cmd_output_buffer;
+	memset((void *)output, 0, sizeof(struct sve_cmd_id_regs));
+
+	realm_printf("Realm: reading ID registers: ID_AA64PFR0_EL1, "
+		    " ID_AA64ZFR0_EL1\n");
+	output->id_aa64pfr0_el1 = read_id_aa64pfr0_el1();
+	output->id_aa64zfr0_el1 = read_id_aa64zfr0_el1();
+
+	return true;
+}
+
+/*
+ * Probes all VLs and return the bitmap with the bit set for each corresponding
+ * valid VQ. This test is called only by sve Realm
+ */
+bool test_realm_sve_probe_vl(void)
+{
+	host_shared_data_t *sd = realm_get_shared_structure();
+	struct sve_cmd_probe_vl *output;
+
+	assert(is_armv8_2_sve_present());
+
+	output = (struct sve_cmd_probe_vl *)&sd->realm_cmd_output_buffer;
+	memset((void *)output, 0, sizeof(struct sve_cmd_probe_vl));
+
+	/* Probe all VLs */
+	output->vl_bitmap = sve_probe_vl(SVE_VQ_ARCH_MAX);
+
+	return true;
+}