test(realm): add test for RSI_PLANE_REG_READ/WRITE command
test for RSI_PLANE_REG_READ/WRITE command
Signed-off-by: Shruti Gupta <shruti.gupta@arm.com>
Change-Id: I92e0aeef48c9b2abe26e5d3b2ea62669a22d4f8b
diff --git a/include/lib/aarch64/arch.h b/include/lib/aarch64/arch.h
index f4c1d87..90d4706 100644
--- a/include/lib/aarch64/arch.h
+++ b/include/lib/aarch64/arch.h
@@ -1705,4 +1705,72 @@
******************************************************************************/
#define FPMR S3_3_C4_C4_2
+/******************************************************************************
+ * Definitions of system register identifiers
+ *****************************************************************************/
+
+#define ESR_EL2_SYSREG_TRAP_OP0_SHIFT 20
+#define ESR_EL2_SYSREG_TRAP_OP0_WIDTH U(2)
+
+#define ESR_EL2_SYSREG_TRAP_OP2_SHIFT 17
+#define ESR_EL2_SYSREG_TRAP_OP2_WIDTH U(3)
+
+#define ESR_EL2_SYSREG_TRAP_OP1_SHIFT 14
+#define ESR_EL2_SYSREG_TRAP_OP1_WIDTH U(3)
+
+#define ESR_EL2_SYSREG_TRAP_CRN_SHIFT 10
+#define ESR_EL2_SYSREG_TRAP_CRN_WIDTH U(4)
+
+#define ESR_EL2_SYSREG_TRAP_CRM_SHIFT 1
+#define ESR_EL2_SYSREG_TRAP_CRM_WIDTH U(4)
+
+#define SYSREG_ESR(op0, op1, crn, crm, op2) \
+ ((UL(op0) << ESR_EL2_SYSREG_TRAP_OP0_SHIFT) | \
+ (UL(op1) << ESR_EL2_SYSREG_TRAP_OP1_SHIFT) | \
+ (UL(crn) << ESR_EL2_SYSREG_TRAP_CRN_SHIFT) | \
+ (UL(crm) << ESR_EL2_SYSREG_TRAP_CRM_SHIFT) | \
+ (UL(op2) << ESR_EL2_SYSREG_TRAP_OP2_SHIFT))
+
+#define SYSREG_ID_sp_el0 SYSREG_ESR(3, 0, 4, 1, 0)
+#define SYSREG_ID_sp_el1 SYSREG_ESR(3, 4, 4, 1, 0)
+#define SYSREG_ID_elr_el1 SYSREG_ESR(3, 0, 4, 0, 1)
+#define SYSREG_ID_spsr_el1 SYSREG_ESR(3, 0, 4, 0, 0)
+#define SYSREG_ID_pmcr_el0 SYSREG_ESR(3, 3, 9, 12, 0)
+#define SYSREG_ID_tpidrro_el0 SYSREG_ESR(3, 3, 13, 0, 3)
+#define SYSREG_ID_tpidr_el0 SYSREG_ESR(3, 3, 13, 0, 2)
+#define SYSREG_ID_csselr_el1 SYSREG_ESR(3, 2, 0, 0, 0)
+#define SYSREG_ID_sctlr_el1 SYSREG_ESR(3, 0, 1, 0, 0)
+#define SYSREG_ID_actlr_el1 SYSREG_ESR(3, 0, 1, 0, 1)
+#define SYSREG_ID_cpacr_el1 SYSREG_ESR(3, 0, 1, 0, 2)
+#define SYSREG_ID_zcr_el1 SYSREG_ESR(3, 0, 1, 2, 0)
+#define SYSREG_ID_ttbr0_el1 SYSREG_ESR(3, 0, 2, 0, 0)
+#define SYSREG_ID_ttbr1_el1 SYSREG_ESR(3, 0, 2, 0, 1)
+#define SYSREG_ID_tcr_el1 SYSREG_ESR(3, 0, 2, 0, 2)
+#define SYSREG_ID_esr_el1 SYSREG_ESR(3, 0, 5, 2, 0)
+#define SYSREG_ID_afsr0_el1 SYSREG_ESR(3, 0, 5, 1, 0)
+#define SYSREG_ID_afsr1_el1 SYSREG_ESR(3, 0, 5, 1, 1)
+#define SYSREG_ID_far_el1 SYSREG_ESR(3, 0, 6, 0, 0)
+#define SYSREG_ID_mair_el1 SYSREG_ESR(3, 0, 10, 2, 0)
+#define SYSREG_ID_vbar_el1 SYSREG_ESR(3, 0, 12, 0, 0)
+#define SYSREG_ID_contextidr_el1 SYSREG_ESR(3, 0, 13, 0, 1)
+#define SYSREG_ID_tpidr_el1 SYSREG_ESR(3, 0, 13, 0, 4)
+#define SYSREG_ID_amair_el1 SYSREG_ESR(3, 0, 10, 3, 0)
+#define SYSREG_ID_cntkctl_el1 SYSREG_ESR(3, 0, 14, 1, 0)
+#define SYSREG_ID_par_el1 SYSREG_ESR(3, 0, 7, 4, 0)
+#define SYSREG_ID_mdscr_el1 SYSREG_ESR(2, 0, 0, 2, 2)
+#define SYSREG_ID_mdccint_el1 SYSREG_ESR(2, 0, 0, 2, 0)
+#define SYSREG_ID_disr_el1 SYSREG_ESR(3, 0, 12, 1, 1)
+#define SYSREG_ID_mpam0_el1 SYSREG_ESR(3, 0, 10, 5, 1)
+#define SYSREG_ID_apiakeylo_el1 SYSREG_ESR(3, 0, 2, 1, 0)
+#define SYSREG_ID_apiakeyhi_el1 SYSREG_ESR(3, 0, 2, 1, 1)
+#define SYSREG_ID_apibkeylo_el1 SYSREG_ESR(3, 0, 2, 1, 2)
+#define SYSREG_ID_apibkeyhi_el1 SYSREG_ESR(3, 0, 2, 1, 3)
+#define SYSREG_ID_apdakeylo_el1 SYSREG_ESR(3, 0, 2, 2, 0)
+#define SYSREG_ID_apdakeyhi_el1 SYSREG_ESR(3, 0, 2, 2, 1)
+#define SYSREG_ID_apdbkeylo_el1 SYSREG_ESR(3, 0, 2, 2, 2)
+#define SYSREG_ID_apdbkeyhi_el1 SYSREG_ESR(3, 0, 2, 2, 3)
+#define SYSREG_ID_apgakeylo_el1 SYSREG_ESR(3, 0, 2, 3, 0)
+#define SYSREG_ID_apgakeyhi_el1 SYSREG_ESR(3, 0, 2, 3, 1)
+#define SYSREG_ID_mpamidr_el1 SYSREG_ESR(3, 0, 10, 4, 4)
+
#endif /* ARCH_H */
diff --git a/include/runtime_services/host_realm_managment/host_shared_data.h b/include/runtime_services/host_realm_managment/host_shared_data.h
index 05d22da..fecb27b 100644
--- a/include/runtime_services/host_realm_managment/host_shared_data.h
+++ b/include/runtime_services/host_realm_managment/host_shared_data.h
@@ -75,7 +75,8 @@
REALM_FEAT_DOUBLEFAULT2_TEST,
REALM_ATTESTATION,
REALM_ATTESTATION_FAULT,
- REALM_ENTER_PLANE_N_CMD
+ REALM_ENTER_PLANE_N_CMD,
+ REALM_PLANE_N_REG_RW_CMD
};
/*
diff --git a/realm/include/realm_helpers.h b/realm/include/realm_helpers.h
index 9214564..7ed8f9b 100644
--- a/realm/include/realm_helpers.h
+++ b/realm/include/realm_helpers.h
@@ -34,6 +34,8 @@
/* Function for initializing planes, called at Boot */
void realm_plane_init(void);
+bool plane_common_init(u_register_t plane_index, u_register_t perm_index,
+ u_register_t base, rsi_plane_run *run);
#endif /* REALM_HELPERS_H */
diff --git a/realm/include/realm_rsi.h b/realm/include/realm_rsi.h
index e72a769..06f857f 100644
--- a/realm/include/realm_rsi.h
+++ b/realm/include/realm_rsi.h
@@ -270,6 +270,12 @@
*/
#define RSI_PLANE_REG_READ SMC_RSI_FID(0x1EU)
+u_register_t rsi_plane_reg_read(u_register_t plane_index, u_register_t register_encoding,
+ u_register_t *value);
+
+u_register_t rsi_plane_reg_write(u_register_t plane_index, u_register_t register_encoding,
+ u_register_t value);
+
/*
* arg1 == plane index
* arg2 == register encoding
diff --git a/realm/realm_payload_main.c b/realm/realm_payload_main.c
index 4ad1b6c..aeadb9e 100644
--- a/realm/realm_payload_main.c
+++ b/realm/realm_payload_main.c
@@ -48,15 +48,102 @@
static bool test_realm_enter_plane_n(void)
{
u_register_t base, plane_index, perm_index, flags = 0U;
+ bool ret1;
plane_index = realm_shared_data_get_my_host_val(HOST_ARG1_INDEX);
base = realm_shared_data_get_my_host_val(HOST_ARG2_INDEX);
perm_index = plane_index + 1U;
+ ret1 = plane_common_init(plane_index, perm_index, base, &run);
+ if (!ret1) {
+ return ret1;
+ }
+
realm_printf("Entering plane %ld, ep=0x%lx run=0x%lx\n", plane_index, base, &run);
return realm_plane_enter(plane_index, perm_index, base, flags, &run);
}
+static bool test_realm_enter_plane_n_reg_rw(void)
+{
+ u_register_t base, plane_index, perm_index, flags = 0U;
+ u_register_t reg1, reg2, reg3, reg4, ret;
+ bool ret1;
+
+ if (realm_is_plane0()) {
+ plane_index = realm_shared_data_get_my_host_val(HOST_ARG1_INDEX);
+ base = realm_shared_data_get_my_host_val(HOST_ARG2_INDEX);
+ perm_index = plane_index + 1U;
+
+ ret1 = plane_common_init(plane_index, perm_index, base, &run);
+ if (!ret1) {
+ return ret1;
+ }
+
+ realm_printf("Entering plane %ld, ep=0x%lx run=0x%lx\n", plane_index, base, &run);
+ ret = realm_plane_enter(plane_index, perm_index, base, flags, &run);
+ if (ret) {
+ /* get return value from plane1 */
+ reg1 = realm_shared_data_get_plane_n_val(plane_index,
+ REC_IDX(read_mpidr_el1()), HOST_ARG1_INDEX);
+
+ reg2 = realm_shared_data_get_plane_n_val(plane_index,
+ REC_IDX(read_mpidr_el1()), HOST_ARG2_INDEX);
+
+ realm_printf("P0 read 0x%lx 0x%lx\n", reg1, reg2);
+
+ /* read pauth register for plane1 */
+ ret = rsi_plane_reg_read(plane_index, SYSREG_ID_apiakeylo_el1, ®3);
+ if ((ret != RSI_SUCCESS) || (reg1 != reg3)) {
+ realm_printf("pauth register mismatch 0x%lx 0x%lx\n", reg1, reg3);
+ return false;
+ }
+
+ /* read sctlr register for plane1 */
+ ret = rsi_plane_reg_read(plane_index, SYSREG_ID_sctlr_el1, ®4);
+ if ((ret != RSI_SUCCESS) || (reg2 != reg4)) {
+ realm_printf("sctlr register mismatch 0x%lx 0x%lx\n", reg2, reg4);
+ return false;
+ }
+
+ /* write pauth register and verify it is same after exiting plane n */
+ ret = rsi_plane_reg_write(plane_index, SYSREG_ID_apibkeylo_el1, 0xABCD);
+ if (ret != RSI_SUCCESS) {
+ realm_printf("pauth register write failed\n");
+ return false;
+ }
+
+ /* enter plane n */
+ ret = realm_plane_enter(plane_index, perm_index, base, flags, &run);
+ if (ret) {
+ /* read pauth register for plane1 */
+ ret = rsi_plane_reg_read(plane_index, SYSREG_ID_apibkeylo_el1,
+ ®3);
+
+ if ((ret != RSI_SUCCESS) || (reg3 != 0xABCD)) {
+ realm_printf("reg mismatch after write 0x%lx\n", reg3);
+ return false;
+ }
+ }
+
+ /* read sysreg not supported by rmm, expect error */
+ ret = rsi_plane_reg_read(plane_index, SYSREG_ID_mpamidr_el1, ®3);
+ if (ret == RSI_SUCCESS) {
+ realm_printf("reg read should have failed\n");
+ return false;
+ }
+ return true;
+ }
+ return false;
+ } else {
+ realm_printf("PN set 0x%lx 0x%lx\n", read_apiakeylo_el1(), read_sctlr_el1());
+
+ /* return pauth and sctlr back to p0 */
+ realm_shared_data_set_my_realm_val(HOST_ARG1_INDEX, read_apiakeylo_el1());
+ realm_shared_data_set_my_realm_val(HOST_ARG2_INDEX, read_sctlr_el1());
+ return true;
+ }
+}
+
/*
* This function requests RSI/ABI version from RMM.
*/
@@ -300,6 +387,9 @@
case REALM_ENTER_PLANE_N_CMD:
test_succeed = test_realm_enter_plane_n();
break;
+ case REALM_PLANE_N_REG_RW_CMD:
+ test_succeed = test_realm_enter_plane_n_reg_rw();
+ break;
case REALM_MULTIPLE_REC_PSCI_DENIED_CMD:
test_succeed = test_realm_multiple_rec_psci_denied_cmd();
break;
diff --git a/realm/realm_plane.c b/realm/realm_plane.c
index 9a604c6..c7225ed 100644
--- a/realm/realm_plane.c
+++ b/realm/realm_plane.c
@@ -135,7 +135,7 @@
return PSI_RETURN_TO_P0;
}
-static bool plane_common_init(u_register_t plane_index,
+bool plane_common_init(u_register_t plane_index,
u_register_t perm_index,
u_register_t base,
rsi_plane_run *run)
@@ -161,12 +161,6 @@
rsi_plane_run *run)
{
u_register_t ret;
- bool ret1;
-
- ret1 = plane_common_init(plane_index, perm_index, base, run);
- if (!ret1) {
- return ret1;
- }
run->enter.flags = flags;
diff --git a/realm/realm_rsi.c b/realm/realm_rsi.c
index b2505cc..4e223ca 100644
--- a/realm/realm_rsi.c
+++ b/realm/realm_rsi.c
@@ -199,3 +199,28 @@
{RSI_PLANE_ENTER, plane_index, plane_run});
return res.ret0;
}
+
+u_register_t rsi_plane_reg_read(u_register_t plane_index,
+ u_register_t register_encoding,
+ u_register_t *value)
+{
+ smc_ret_values res = {};
+
+ res = tftf_smc(&(smc_args)
+ {RSI_PLANE_REG_READ, plane_index, register_encoding});
+ if (res.ret0 == RSI_SUCCESS) {
+ *value = res.ret1;
+ }
+ return res.ret0;
+}
+
+u_register_t rsi_plane_reg_write(u_register_t plane_index,
+ u_register_t register_encoding,
+ u_register_t value)
+{
+ smc_ret_values res = {};
+
+ res = tftf_smc(&(smc_args)
+ {RSI_PLANE_REG_WRITE, plane_index, register_encoding, value});
+ return res.ret0;
+}
diff --git a/tftf/tests/runtime_services/realm_payload/host_realm_payload_tests.c b/tftf/tests/runtime_services/realm_payload/host_realm_payload_tests.c
index f1ea9ef..0c7289a 100644
--- a/tftf/tests/runtime_services/realm_payload/host_realm_payload_tests.c
+++ b/tftf/tests/runtime_services/realm_payload/host_realm_payload_tests.c
@@ -50,6 +50,63 @@
}
/*
+ * @Test_Aim@ Test RSI_PLANE_REG_READ/WRITE
+ */
+test_result_t host_test_realm_create_planes_register_rw(void)
+{
+ bool ret1, ret2;
+ u_register_t rec_flag[MAX_REC_COUNT];
+ struct realm realm;
+ u_register_t feature_flag = 0UL;
+ long sl = RTT_MIN_LEVEL;
+ struct rmi_rec_run *run;
+
+ SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
+
+ if (!are_planes_supported()) {
+ return TEST_RESULT_SKIPPED;
+ }
+
+ if (is_feat_52b_on_4k_2_supported() == true) {
+ feature_flag = RMI_FEATURE_REGISTER_0_LPA2;
+ sl = RTT_MIN_LEVEL_LPA2;
+ }
+
+ for (unsigned int i = 0U; i < MAX_REC_COUNT; i++) {
+ rec_flag[i] = RMI_RUNNABLE;
+ }
+
+ if (!host_create_activate_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
+ feature_flag, sl, rec_flag, 1U, 1U)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ /* CMD for Plane N */
+ host_shared_data_set_realm_cmd(&realm, REALM_PLANE_N_REG_RW_CMD, 1U, 0U);
+
+ run = (struct rmi_rec_run *)realm.run[0U];
+
+ host_realm_set_aux_plane_args(&realm, 1U);
+ ret1 = host_enter_realm_execute(&realm, REALM_PLANE_N_REG_RW_CMD,
+ RMI_EXIT_HOST_CALL, 0U);
+
+ if (run->exit.exit_reason != RMI_EXIT_HOST_CALL) {
+ ERROR("Rec0 error exit=0x%lx ret1=%d HPFAR=0x%lx \
+ esr=0x%lx far=0x%lx\n",
+ run->exit.exit_reason, ret1,
+ run->exit.hpfar,
+ run->exit.esr, run->exit.far);
+ }
+ ret2 = host_destroy_realm(&realm);
+
+ if (!ret1 || !ret2) {
+ ERROR("%s(): enter=%d destroy=%d\n",
+ __func__, ret1, ret2);
+ return TEST_RESULT_FAIL;
+ }
+ return host_cmp_result();
+}
+/*
* @Test_Aim@ Test realm payload creation with 3 Aux Planes, enter all Planes
* Host cannot enter Aux Planes directly,
* Host will enter P0, P0 will enter aux plane
diff --git a/tftf/tests/tests-realm-payload.xml b/tftf/tests/tests-realm-payload.xml
index ea0d27c..7cc7866 100644
--- a/tftf/tests/tests-realm-payload.xml
+++ b/tftf/tests/tests-realm-payload.xml
@@ -10,6 +10,8 @@
<testsuite name="Realm payload at EL1" description="Test Realm EL1 framework capabilities" >
<testcase name="Realm Planes execution test"
function="host_test_realm_create_planes_enter" />
+ <testcase name="Realm Planes register read/write test"
+ function="host_test_realm_create_planes_register_rw" />
<testcase name="Realm EL1 creation and execution test"
function="host_test_realm_create_enter" />
<testcase name="Realm RTT fold unfold test Unassigned Empty"