summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexeiFedorov <Alexei.Fedorov@arm.com>2023-06-07 17:30:10 +0100
committerSoby Mathew <soby.mathew@arm.com>2023-09-13 09:49:37 +0100
commitf81345ce2cd13d59cb6efa5847ec02baf54cd489 (patch)
treeca115e7029fc8f338a96f41ce044583aafa3bc2f
parentcd04e41b418decee80a03d25eb7598e7a6b8da95 (diff)
feat(rme): add Realm SVE tests for EAC1
This patch adds SVE tests for RMM EAC1. The 'feature_flag' parameter passed to 'host_create_realm_payload()' function is modified to contain 'sve_vl', 'num_bps', 'num_wps' and 'pmu_num_ctrs entries'. This allows to pass values which can exceed these fields in feature_register_0 for testing. It makes possible to pass 'Create SVE Realm with invalid VL' which was skipped originally, when SVE was configured with the maximum supported vector length value. Signed-off-by: AlexeiFedorov <Alexei.Fedorov@arm.com> Change-Id: Icd5e57c1bb0cb8dee27b7ace5643aec597e036c1
-rw-r--r--include/runtime_services/host_realm_managment/host_realm_rmi.h29
-rw-r--r--tftf/tests/runtime_services/host_realm_managment/host_realm_helper.c44
-rw-r--r--tftf/tests/runtime_services/host_realm_managment/host_realm_rmi.c46
-rw-r--r--tftf/tests/runtime_services/realm_payload/host_realm_payload_sve_tests.c51
-rw-r--r--tftf/tests/runtime_services/realm_payload/host_realm_payload_tests.c9
5 files changed, 109 insertions, 70 deletions
diff --git a/include/runtime_services/host_realm_managment/host_realm_rmi.h b/include/runtime_services/host_realm_managment/host_realm_rmi.h
index e25a30d..30caaac 100644
--- a/include/runtime_services/host_realm_managment/host_realm_rmi.h
+++ b/include/runtime_services/host_realm_managment/host_realm_rmi.h
@@ -218,14 +218,9 @@
#define RMI_FEATURE_TRUE 1U
/* RmiRealmFlags format */
-#define RMI_REALM_FLAGS_LPA2_SHIFT 0UL
-#define RMI_REALM_FLAGS_LPA2_WIDTH 1UL
-
-#define RMI_REALM_FLAGS_SVE_SHIFT 1UL
-#define RMI_REALM_FLAGS_SVE_WIDTH 1UL
-
-#define RMI_REALM_FLAGS_PMU_SHIFT 2UL
-#define RMI_REALM_FLAGS_PMU_WIDTH 1UL
+#define RMI_REALM_FLAGS_LPA2 BIT(0)
+#define RMI_REALM_FLAGS_SVE BIT(1)
+#define RMI_REALM_FLAGS_PMU BIT(2)
/* RmiInterfaceVersion type */
#define RMI_MAJOR_VERSION 0U
@@ -283,6 +278,20 @@
#define RMI_FEATURE_REGISTER_0_HASH_SHA_256 BIT(28)
#define RMI_FEATURE_REGISTER_0_HASH_SHA_512 BIT(29)
+/*
+ * Format of feature_flag[63:32].
+ * Value -1 indicates not set field, and parameter will be set
+ * from the corresponding field of feature register 0.
+ */
+#define FEATURE_SVE_VL_SHIFT 32UL
+#define FEATURE_SVE_VL_WIDTH 8UL
+#define FEATURE_NUM_BPS_SHIFT 40UL
+#define FEATURE_NUM_BPS_WIDTH 8UL
+#define FEATURE_NUM_WPS_SHIFT 48UL
+#define FEATURE_NUM_WPS_WIDTH 8UL
+#define FEATURE_PMU_NUM_CTRS_SHIFT 56UL
+#define FEATURE_PMU_NUM_CTRS_WIDTH 8UL
+
/* RmiStatusCode types */
/*
* Status codes which can be returned from RMM commands.
@@ -500,6 +509,10 @@ struct realm {
u_register_t ipa_ns_buffer;
u_register_t ns_buffer_size;
u_register_t aux_pages[REC_PARAMS_AUX_GRANULES];
+ uint8_t sve_vl;
+ uint8_t num_bps;
+ uint8_t num_wps;
+ uint8_t pmu_num_ctrs;
enum realm_state state;
};
diff --git a/tftf/tests/runtime_services/host_realm_managment/host_realm_helper.c b/tftf/tests/runtime_services/host_realm_managment/host_realm_helper.c
index 79020df..fc18a75 100644
--- a/tftf/tests/runtime_services/host_realm_managment/host_realm_helper.c
+++ b/tftf/tests/runtime_services/host_realm_managment/host_realm_helper.c
@@ -185,6 +185,8 @@ bool host_create_realm_payload(u_register_t realm_payload_adr,
u_register_t realm_pages_size,
u_register_t feature_flag)
{
+ int8_t value;
+
if (realm_payload_adr == TFTF_BASE) {
ERROR("realm_payload_adr should be grater then TFTF_BASE\n");
return false;
@@ -220,9 +222,43 @@ bool host_create_realm_payload(u_register_t realm_payload_adr,
/* Disable PMU if not required */
if ((feature_flag & RMI_FEATURE_REGISTER_0_PMU_EN) == 0UL) {
- realm.rmm_feat_reg0 &=
- ~(RMI_FEATURE_REGISTER_0_PMU_EN |
- MASK(RMI_FEATURE_REGISTER_0_PMU_NUM_CTRS));
+ realm.rmm_feat_reg0 &= ~RMI_FEATURE_REGISTER_0_PMU_EN;
+ realm.pmu_num_ctrs = 0U;
+ } else {
+ value = EXTRACT(FEATURE_PMU_NUM_CTRS, feature_flag);
+ if (value != -1) {
+ realm.pmu_num_ctrs = (unsigned int)value;
+ } else {
+ realm.pmu_num_ctrs =
+ EXTRACT(RMI_FEATURE_REGISTER_0_PMU_NUM_CTRS,
+ realm.rmm_feat_reg0);
+ }
+ }
+
+ /* Disable SVE if not required */
+ if ((feature_flag & RMI_FEATURE_REGISTER_0_SVE_EN) == 0UL) {
+ realm.rmm_feat_reg0 &= ~RMI_FEATURE_REGISTER_0_SVE_EN;
+ realm.sve_vl = 0U;
+ } else {
+ realm.sve_vl = EXTRACT(FEATURE_SVE_VL, feature_flag);
+ }
+
+ /* Requested number of breakpoints */
+ value = EXTRACT(FEATURE_NUM_BPS, feature_flag);
+ if (value != -1) {
+ realm.num_bps = (unsigned int)value;
+ } else {
+ realm.num_bps = EXTRACT(RMI_FEATURE_REGISTER_0_NUM_BPS,
+ realm.rmm_feat_reg0);
+ }
+
+ /* Requested number of watchpoints */
+ value = EXTRACT(FEATURE_NUM_WPS, feature_flag);
+ if (value != -1) {
+ realm.num_wps = (unsigned int)value;
+ } else {
+ realm.num_wps = EXTRACT(RMI_FEATURE_REGISTER_0_NUM_WPS,
+ realm.rmm_feat_reg0);
}
/* Set SVE bits from feature_flag */
@@ -238,7 +274,7 @@ bool host_create_realm_payload(u_register_t realm_payload_adr,
/* Create Realm */
if (host_realm_create(&realm) != REALM_SUCCESS) {
ERROR("%s() failed\n", "host_realm_create");
- goto destroy_realm;
+ return false;
}
if (host_realm_init_ipa_state(&realm, 0U, 0U, 1ULL << 32)
diff --git a/tftf/tests/runtime_services/host_realm_managment/host_realm_rmi.c b/tftf/tests/runtime_services/host_realm_managment/host_realm_rmi.c
index 012c331..3983a34 100644
--- a/tftf/tests/runtime_services/host_realm_managment/host_realm_rmi.c
+++ b/tftf/tests/runtime_services/host_realm_managment/host_realm_rmi.c
@@ -126,8 +126,8 @@ static inline u_register_t host_rmi_realm_activate(u_register_t rd)
u_register_t host_rmi_realm_create(u_register_t rd, u_register_t params_ptr)
{
- return host_rmi_handler(&(smc_args) {RMI_REALM_CREATE,
- rd, params_ptr}, 3U).ret0;
+ return host_rmi_handler(&(smc_args) {RMI_REALM_CREATE, rd, params_ptr},
+ 3U).ret0;
}
u_register_t host_rmi_realm_destroy(u_register_t rd)
@@ -142,8 +142,9 @@ static inline u_register_t host_rmi_data_destroy(u_register_t rd,
{
smc_ret_values rets;
- rets = host_rmi_handler(&(smc_args) {RMI_DATA_DESTROY,
- rd, map_addr, (u_register_t)&rets}, 4U);
+ rets = host_rmi_handler(&(smc_args) {RMI_DATA_DESTROY, rd, map_addr,
+ (u_register_t)&rets}, 4U);
+
*data = rets.ret1;
*top = rets.ret2;
return rets.ret0;
@@ -153,9 +154,8 @@ static inline u_register_t host_rmi_rec_create(u_register_t rd,
u_register_t rec,
u_register_t params_ptr)
{
-
- return host_rmi_handler(&(smc_args) {RMI_REC_CREATE, rd, rec, params_ptr},
- 4U).ret0;
+ return host_rmi_handler(&(smc_args) {RMI_REC_CREATE,
+ rd, rec, params_ptr}, 4U).ret0;
}
static inline u_register_t host_rmi_rec_destroy(u_register_t rec)
@@ -693,17 +693,17 @@ static u_register_t host_realm_tear_down_rtt_range(struct realm *realm,
u_register_t host_rmi_granule_delegate(u_register_t addr)
{
- return host_rmi_handler(&(smc_args){RMI_GRANULE_DELEGATE, addr}, 2U).ret0;
+ return host_rmi_handler(&(smc_args) {RMI_GRANULE_DELEGATE, addr}, 2U).ret0;
}
u_register_t host_rmi_granule_undelegate(u_register_t addr)
{
- return host_rmi_handler(&(smc_args){RMI_GRANULE_UNDELEGATE, addr}, 2U).ret0;
+ return host_rmi_handler(&(smc_args) {RMI_GRANULE_UNDELEGATE, addr}, 2U).ret0;
}
u_register_t host_rmi_version(void)
{
- return host_rmi_handler(&(smc_args){RMI_VERSION}, 1U).ret0;
+ return host_rmi_handler(&(smc_args) {RMI_VERSION}, 1U).ret0;
}
u_register_t host_realm_create(struct realm *realm)
@@ -763,21 +763,23 @@ u_register_t host_realm_create(struct realm *realm)
/* Populate params */
params->s2sz = EXTRACT(RMI_FEATURE_REGISTER_0_S2SZ,
realm->rmm_feat_reg0);
- params->sve_vl = EXTRACT(RMI_FEATURE_REGISTER_0_SVE_VL,
- realm->rmm_feat_reg0);
- params->num_bps = EXTRACT(RMI_FEATURE_REGISTER_0_NUM_BPS,
- realm->rmm_feat_reg0);
- params->num_wps = EXTRACT(RMI_FEATURE_REGISTER_0_NUM_WPS,
- realm->rmm_feat_reg0);
+ params->num_bps = realm->num_bps;
+ params->num_wps = realm->num_wps;
+
+ /* SVE enable and vector length */
+ if ((realm->rmm_feat_reg0 & RMI_FEATURE_REGISTER_0_SVE_EN) != 0UL) {
+ params->flags = RMI_REALM_FLAGS_SVE;
+ params->sve_vl = realm->sve_vl;
+ } else {
+ params->flags = 0UL;
+ params->sve_vl = 0U;
+ }
/* PMU enable and number of event counters */
if ((realm->rmm_feat_reg0 & RMI_FEATURE_REGISTER_0_PMU_EN) != 0UL) {
- params->flags = INPLACE(RMI_REALM_FLAGS_PMU, RMI_FEATURE_TRUE);
- params->pmu_num_ctrs = EXTRACT(
- RMI_FEATURE_REGISTER_0_PMU_NUM_CTRS,
- realm->rmm_feat_reg0);
+ params->flags |= RMI_REALM_FLAGS_PMU;
+ params->pmu_num_ctrs = realm->pmu_num_ctrs;
} else {
- params->flags = INPLACE(RMI_REALM_FLAGS_PMU, RMI_FEATURE_FALSE);
params->pmu_num_ctrs = 0U;
}
@@ -1177,7 +1179,7 @@ u_register_t host_realm_rec_enter(struct realm *realm,
do {
re_enter_rec = false;
- ret = host_rmi_handler(&(smc_args){RMI_REC_ENTER,
+ ret = host_rmi_handler(&(smc_args) {RMI_REC_ENTER,
realm->rec, realm->run}, 3U).ret0;
VERBOSE("%s() run->exit.exit_reason=%lu "
"run->exit.esr=0x%lx EC_BITS=%u ISS_DFSC_MASK=0x%lx\n",
diff --git a/tftf/tests/runtime_services/realm_payload/host_realm_payload_sve_tests.c b/tftf/tests/runtime_services/realm_payload/host_realm_payload_sve_tests.c
index 3bde128..8782c9e 100644
--- a/tftf/tests/runtime_services/realm_payload/host_realm_payload_sve_tests.c
+++ b/tftf/tests/runtime_services/realm_payload/host_realm_payload_sve_tests.c
@@ -45,13 +45,13 @@ static sve_vector_t ns_sve_vectors_read[SVE_NUM_VECTORS] __aligned(16);
static test_result_t host_create_sve_realm_payload(bool sve_en, uint8_t sve_vq)
{
- u_register_t rmi_feat_reg0;
+ u_register_t feature_flag;
if (sve_en) {
- rmi_feat_reg0 = RMI_FEATURE_REGISTER_0_SVE_EN |
- INPLACE(RMI_FEATURE_REGISTER_0_SVE_VL, sve_vq);
+ feature_flag = RMI_FEATURE_REGISTER_0_SVE_EN |
+ INPLACE(FEATURE_SVE_VL, sve_vq);
} else {
- rmi_feat_reg0 = 0UL;
+ feature_flag = 0UL;
}
/* Initialise Realm payload */
@@ -60,7 +60,7 @@ static test_result_t host_create_sve_realm_payload(bool sve_en, uint8_t sve_vq)
(u_register_t)(PAGE_POOL_MAX_SIZE +
NS_REALM_SHARED_MEM_SIZE),
(u_register_t)PAGE_POOL_MAX_SIZE,
- rmi_feat_reg0)) {
+ feature_flag)) {
return TEST_RESULT_FAIL;
}
@@ -90,14 +90,14 @@ test_result_t host_check_rmi_reports_proper_sve_vl(void)
rmi_sve_vq = EXTRACT(RMI_FEATURE_REGISTER_0_SVE_VL, rmi_feat_reg0);
/*
- * configure NS to arch supported max VL and get the value reported
+ * Configure NS to arch supported max VL and get the value reported
* by rdvl
*/
sve_config_vq(SVE_VQ_ARCH_MAX);
ns_sve_vq = SVE_VL_TO_VQ(sve_vector_length_get());
if (rmi_sve_vq != ns_sve_vq) {
- ERROR("RMI max SVE VL %u bits doesn't matches NS max "
+ ERROR("RMI max SVE VL %u bits don't match NS max "
"SVE VL %u bits\n", SVE_VQ_TO_BITS(rmi_sve_vq),
SVE_VQ_TO_BITS(ns_sve_vq));
return TEST_RESULT_FAIL;
@@ -135,7 +135,7 @@ test_result_t host_sve_realm_cmd_rdvl(void)
goto rm_realm;
}
- /* check if rdvl matches the SVE VL created */
+ /* Check if rdvl matches the SVE VL created */
sd = host_get_shared_structure();
rl_output = (struct sve_cmd_rdvl *)sd->realm_cmd_output_buffer;
rl_max_sve_vq = SVE_VL_TO_VQ(rl_output->rdvl);
@@ -170,19 +170,12 @@ test_result_t host_sve_realm_test_invalid_vl(void)
sve_vq = EXTRACT(RMI_FEATURE_REGISTER_0_SVE_VL, rmi_feat_reg0);
/*
- * If RMM supports MAX SVE VQ, we can't pass in an invalid sve_vq to
- * create a realm, so skip the test. Else pass a sve_vq that is greater
- * than the value supported by RMM and check whether creating Realm fails
+ * Pass a sve_vq that is greater than the value supported by RMM
+ * and check whether creating Realm fails
*/
- if (sve_vq == SVE_VQ_ARCH_MAX) {
- INFO("RMI supports arch max SVE VL, skipping\n");
- return TEST_RESULT_SKIPPED;
- }
-
rc = host_create_sve_realm_payload(true, (sve_vq + 1));
-
if (rc == TEST_RESULT_SUCCESS) {
- ERROR("Error: Realm created with invalid SVE VL\n");
+ ERROR("Error: Realm created with invalid SVE VL %u\n", (sve_vq + 1));
host_destroy_realm();
return TEST_RESULT_FAIL;
}
@@ -263,9 +256,7 @@ test_result_t host_non_sve_realm_cmd_id_registers(void)
static void print_sve_vl_bitmap(uint32_t vl_bitmap)
{
- uint8_t vq;
-
- for (vq = 0U; vq <= SVE_VQ_ARCH_MAX; vq++) {
+ for (uint8_t vq = 0U; vq <= SVE_VQ_ARCH_MAX; vq++) {
if ((vl_bitmap & BIT_32(vq)) != 0U) {
INFO("\t%u\n", SVE_VQ_TO_BITS(vq));
}
@@ -393,17 +384,10 @@ test_result_t host_sve_realm_check_config_register(void)
*/
static bool callback_enter_realm(void)
{
- bool realm_rc;
-
- realm_rc = host_enter_realm_execute(REALM_SVE_OPS, NULL,
+ return !host_enter_realm_execute(REALM_SVE_OPS, NULL,
RMI_EXIT_HOST_CALL);
- if (realm_rc != true) {
- return true;
}
- return false;
-}
-
/* Intermittently switch to Realm while doing NS SVE ops */
test_result_t host_sve_realm_check_vectors_operations(void)
{
@@ -425,7 +409,7 @@ test_result_t host_sve_realm_check_vectors_operations(void)
return rc;
}
- /* get at random value to do sve_subtract */
+ /* Get at random value to do sve_subtract */
val = rand();
for (i = 0U; i < NS_SVE_OP_ARRAYSIZE; i++) {
ns_sve_op_1[i] = val - i;
@@ -451,6 +435,7 @@ test_result_t host_sve_realm_check_vectors_operations(void)
/* Check result of SVE operations. */
rc = TEST_RESULT_SUCCESS;
+
for (i = 0U; i < NS_SVE_OP_ARRAYSIZE; i++) {
if (ns_sve_op_1[i] != (val - i - SVE_TEST_ITERATIONS)) {
ERROR("SVE op failed at idx: %u, expected: 0x%x "
@@ -503,14 +488,14 @@ test_result_t host_sve_realm_check_vectors_leaked(void)
/* 1. Set NS SVE VQ to max and write known pattern */
sve_config_vq(sve_vq);
- (void)memset((void *)&ns_sve_vectors_write, 0xaa,
+ (void)memset((void *)&ns_sve_vectors_write, 0xAA,
SVE_VQ_TO_BYTES(sve_vq) * SVE_NUM_VECTORS);
sve_fill_vector_regs(ns_sve_vectors_write);
- /* 2. NS programs ZCR_EL2 with VQ as 0 */
+ /* 2. NS programs ZCR_EL2 with VQ as 0 */
sve_config_vq(SVE_VQ_ARCH_MIN);
- /* 3. Create Realm with max VQ (higher than NS SVE VQ). */
+ /* 3. Create Realm with max VQ (higher than NS SVE VQ) */
rc = host_create_sve_realm_payload(true, sve_vq);
if (rc != TEST_RESULT_SUCCESS) {
return rc;
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 43747b1..e6afd57 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
@@ -37,8 +37,7 @@ test_result_t host_test_realm_create_enter(void)
(u_register_t)PAGE_POOL_BASE,
(u_register_t)(PAGE_POOL_MAX_SIZE +
NS_REALM_SHARED_MEM_SIZE),
- (u_register_t)PAGE_POOL_MAX_SIZE,
- 0UL)) {
+ (u_register_t)PAGE_POOL_MAX_SIZE, 0UL)) {
return TEST_RESULT_FAIL;
}
if (!host_create_shared_mem(NS_REALM_SHARED_MEM_BASE,
@@ -210,18 +209,22 @@ static bool host_realm_handle_irq_exit(struct realm *realm_ptr)
static test_result_t host_test_realm_pmuv3(uint8_t cmd)
{
struct realm *realm_ptr;
+ u_register_t feature_flag;
bool ret1, ret2;
SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
host_set_pmu_state();
+ feature_flag = RMI_FEATURE_REGISTER_0_PMU_EN |
+ INPLACE(FEATURE_PMU_NUM_CTRS, (unsigned long long)(-1));
+
if (!host_create_realm_payload((u_register_t)REALM_IMAGE_BASE,
(u_register_t)PAGE_POOL_BASE,
(u_register_t)(PAGE_POOL_MAX_SIZE +
NS_REALM_SHARED_MEM_SIZE),
(u_register_t)PAGE_POOL_MAX_SIZE,
- RMI_FEATURE_REGISTER_0_PMU_EN)) {
+ feature_flag)) {
return TEST_RESULT_FAIL;
}
if (!host_create_shared_mem(NS_REALM_SHARED_MEM_BASE,