feat: tftf realm extension
This patch adds Realm payload management capabilities to TFTF
to act as a NS Host, it includes creation and destruction of a Realm,
mapping of protected data and creation of all needed RTT levels,
sharing of NS memory buffer from Host to Realm by mapping of
unprotected IPA, create REC and auxiliary granules, exit Realm
using RSI_HOST_CALL ABI.
Older realm_payload name is used now for only R-EL1 test cases,
RMI and SPM test cases have been moved to new file tests-rmi-spm.
New TFTF_MAX_IMAGE_SIZE argument added to FVP platform.mk,
as an offset from where R-EL1 payload memory resources start.
Signed-off-by: Nabil Kahlouche <nabil.kahlouche@arm.com>
Change-Id: Ida4cfd334795879d55924bb33b9b77182a3dcef7
diff --git a/tftf/tests/misc_tests/test_invalid_access.c b/tftf/tests/misc_tests/test_invalid_access.c
index 14be340..7e4a861 100644
--- a/tftf/tests/misc_tests/test_invalid_access.c
+++ b/tftf/tests/misc_tests/test_invalid_access.c
@@ -13,17 +13,15 @@
#ifdef __aarch64__
#include <sync.h>
#endif
-#include <test_helpers.h>
+#include <host_realm_helper.h>
#include <lib/aarch64/arch_features.h>
-#include <runtime_services/realm_payload/realm_payload_test.h>
+#include <test_helpers.h>
#include <tftf_lib.h>
#include <xlat_tables_v2.h>
-
#include <platform_def.h>
#include <cactus_test_cmds.h>
#include <ffa_endpoints.h>
-
/*
* Using "__aarch64__" here looks weird but its unavoidable because of following reason
* This test is part of standard test which runs on all platforms but pre-requisite
@@ -143,7 +141,7 @@
}
/* Delegate the shared page to Realm. */
- retmm = realm_granule_delegate((u_register_t)&share_page);
+ retmm = rmi_granule_delegate((u_register_t)&share_page);
if (retmm != 0UL) {
ERROR("Granule delegate failed!\n");
goto out_unregister;
@@ -161,7 +159,7 @@
out_undelegate:
/* Undelegate the shared page. */
- retmm = realm_granule_undelegate((u_register_t)&share_page);
+ retmm = rmi_granule_undelegate((u_register_t)&share_page);
if (retmm != 0UL) {
ERROR("Granule undelegate failed!\n");
}
@@ -233,7 +231,7 @@
return TEST_RESULT_SKIPPED;
}
- retrmm = realm_version();
+ retrmm = rmi_version();
VERBOSE("RMM version is: %lu.%lu\n",
RMI_ABI_VERSION_GET_MAJOR(retrmm),
@@ -247,17 +245,17 @@
return TEST_RESULT_SKIPPED;
}
- retrmm = realm_granule_delegate((u_register_t)&rd[0]);
+ retrmm = rmi_granule_delegate((u_register_t)&rd[0]);
if (retrmm != 0UL) {
ERROR("Delegate operation returns fail, %lx\n", retrmm);
return TEST_RESULT_FAIL;
}
/* Create a realm using a parameter in a secure physical address space should fail. */
- retrmm = realm_create((u_register_t)&rd[0], params);
+ retrmm = rmi_realm_create((u_register_t)&rd[0], params);
if (retrmm == 0UL) {
ERROR("Realm create operation should fail, %lx\n", retrmm);
- retrmm = realm_destroy((u_register_t)&rd[0]);
+ retrmm = rmi_realm_destroy((u_register_t)&rd[0]);
if (retrmm != 0UL) {
ERROR("Realm destroy operation returns fail, %lx\n", retrmm);
return TEST_RESULT_FAIL;
@@ -269,7 +267,7 @@
return TEST_RESULT_FAIL;
}
- retrmm = realm_granule_undelegate((u_register_t)&rd[0]);
+ retrmm = rmi_granule_undelegate((u_register_t)&rd[0]);
if (retrmm != 0UL) {
INFO("Undelegate operation returns fail, %lx\n", retrmm);
return TEST_RESULT_FAIL;
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
new file mode 100644
index 0000000..4b50b5a
--- /dev/null
+++ b/tftf/tests/runtime_services/host_realm_managment/host_realm_helper.c
@@ -0,0 +1,309 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <stdint.h>
+
+#include <arch_helpers.h>
+#include <debug.h>
+#include <events.h>
+#include <heap/page_alloc.h>
+#include <host_realm_helper.h>
+#include <host_realm_mem_layout.h>
+#include <host_realm_rmi.h>
+#include <host_shared_data.h>
+#include <plat_topology.h>
+#include <power_management.h>
+#include <realm_def.h>
+#include <test_helpers.h>
+#include <xlat_tables_v2.h>
+
+static struct realm realm;
+static bool realm_payload_created;
+static bool shared_mem_created;
+static bool realm_payload_mmaped;
+static u_register_t exit_reason = RMI_EXIT_INVALID;
+static unsigned int test_result = TEST_RESULT_FAIL;
+static volatile bool timer_enabled;
+
+/* From the TFTF_BASE offset, memory used by TFTF + Shared + Realm + POOL should
+ * not exceed DRAM_END offset
+ * NS_REALM_SHARED_MEM_BASE + NS_REALM_SHARED_MEM_SIZE is considered last offset
+ */
+CASSERT((((uint64_t)NS_REALM_SHARED_MEM_BASE + (uint64_t)NS_REALM_SHARED_MEM_SIZE)\
+ < ((uint64_t)DRAM_BASE + (uint64_t)DRAM_SIZE)),\
+ error_ns_memory_and_realm_payload_exceed_DRAM_SIZE);
+
+/*
+ * The function handler to print the Realm logged buffer,
+ * executed by the secondary core
+ */
+static inline test_result_t timer_handler(void)
+{
+ size_t str_len = 0UL;
+ host_shared_data_t *host_shared_data = host_get_shared_structure();
+ char *log_buffer = (char *)host_shared_data->log_buffer;
+
+ do {
+ spin_lock((spinlock_t *)&host_shared_data->printf_lock);
+ str_len = strlen((const char *)log_buffer);
+
+ /*
+ * Read Realm message from shared printf location and print
+ * them using uart
+ */
+ if (str_len != 0UL) {
+ /* Avoid memory overflow */
+ log_buffer[MAX_BUF_SIZE - 1] = 0U;
+
+ mp_printf("%s", log_buffer);
+ (void)memset((char *)log_buffer, 0, MAX_BUF_SIZE);
+ }
+ spin_unlock((spinlock_t *)&host_shared_data->printf_lock);
+
+ } while ((timer_enabled || (str_len != 0UL)));
+
+ return TEST_RESULT_SUCCESS;
+}
+
+/*
+ * Initialisation function which will clear the shared region,
+ * and try to find another CPU other than the lead one to
+ * handle the Realm message logging
+ */
+void host_init_realm_print_buffer(void)
+{
+ u_register_t other_mpidr, my_mpidr;
+ int ret;
+ host_shared_data_t *host_shared_data = host_get_shared_structure();
+
+ (void)memset((char *)host_shared_data, 0, sizeof(host_shared_data_t));
+ /* Program timer */
+ timer_enabled = false;
+
+ /* Find a valid CPU to power on */
+ my_mpidr = read_mpidr_el1() & MPID_MASK;
+ other_mpidr = tftf_find_any_cpu_other_than(my_mpidr);
+ if (other_mpidr == INVALID_MPID) {
+ ERROR("Couldn't find a valid other CPU\n");
+ return;
+ }
+
+ /* Power on the other CPU */
+ ret = tftf_cpu_on(other_mpidr, (uintptr_t)timer_handler, 0);
+ if (ret != PSCI_E_SUCCESS) {
+ ERROR("powering on %llx failed",
+ (unsigned long long)other_mpidr);
+ return;
+ }
+ timer_enabled = true;
+}
+
+/**
+ * @brief - Add regions assigned to Host into its translation table data
+ * structure.
+ **/
+static test_result_t host_mmap_realm_payload(u_register_t realm_payload_adr,
+ u_register_t plat_mem_pool_adr,
+ u_register_t plat_mem_pool_size)
+{
+ if (realm_payload_mmaped) {
+ return REALM_SUCCESS;
+ }
+
+ /* Memory Pool region */
+ int rc = mmap_add_dynamic_region(plat_mem_pool_adr,
+ plat_mem_pool_adr,
+ plat_mem_pool_size,
+ MT_RW_DATA | MT_NS);
+
+ if (rc != 0) {
+ ERROR("%d: mmap_add_dynamic_region() = %d\n", __LINE__, rc);
+ return TEST_RESULT_FAIL;
+ }
+
+ /* Realm Image region */
+ rc = mmap_add_dynamic_region(realm_payload_adr,
+ realm_payload_adr,
+ REALM_MAX_LOAD_IMG_SIZE,
+ MT_RW_DATA | MT_NS);
+
+ if (rc != 0) {
+ ERROR("%d: mmap_add_dynamic_region() = %d\n", __LINE__, rc);
+ return TEST_RESULT_FAIL;
+ }
+ realm_payload_mmaped = true;
+ return REALM_SUCCESS;
+}
+
+static bool host_enter_realm(u_register_t *exit_reason, unsigned int *test_result)
+{
+ u_register_t ret;
+
+ if (!realm_payload_created) {
+ ERROR("%s failed, Realm not created\n", __func__);
+ return false;
+ }
+ if (!shared_mem_created) {
+ ERROR("%s failed, shared memory not created\n", __func__);
+ return false;
+ }
+
+ /* Enter Realm */
+ ret = realm_rec_enter(&realm, exit_reason, test_result);
+ if (ret != REALM_SUCCESS) {
+ ERROR("Rec enter failed something went wrong, ret=%lx\n", ret);
+
+ /* Free test resources */
+ if (realm_destroy(&realm) != REALM_SUCCESS) {
+ ERROR("%s\n", "realm_destroy failed");
+ }
+ realm_payload_created = false;
+ return false;
+ }
+
+ return true;
+}
+
+bool host_create_realm_payload(u_register_t realm_payload_adr,
+ u_register_t plat_mem_pool_adr,
+ u_register_t plat_mem_pool_size,
+ u_register_t realm_pages_size)
+{
+ if (realm_payload_adr == TFTF_BASE) {
+ ERROR("realm_payload_adr should grater then TFTF_BASE\n");
+ return false;
+ }
+
+ if (plat_mem_pool_adr == 0UL ||
+ plat_mem_pool_size == 0UL ||
+ realm_pages_size == 0UL) {
+ ERROR("plat_mem_pool_size or "
+ "plat_mem_pool_size or realm_pages_size isNull\n");
+ return false;
+ }
+ /* Initialize Host NS heap memory to be used in Realm creation*/
+ if (page_pool_init(plat_mem_pool_adr, realm_pages_size)
+ != HEAP_INIT_SUCCESS) {
+ ERROR("page_pool_init() failed\n");
+ return false;
+ }
+
+ /* Mmap Realm payload region*/
+ if (host_mmap_realm_payload(realm_payload_adr,
+ plat_mem_pool_adr,
+ plat_mem_pool_size) != REALM_SUCCESS) {
+ ERROR("host_mmap_realm_payload() failed\n");
+ return false;
+ }
+
+ /* Read Realm feature Regs*/
+ if (rmi_features(0UL, &realm.rmm_feat_reg0) != REALM_SUCCESS) {
+ ERROR("rmi_features() Read Realm feature failed\n");
+ goto destroy_realm;
+ }
+
+ /* Create Realm */
+ if (realm_create(&realm) != REALM_SUCCESS) {
+ ERROR("realm_create() failed\n");
+ goto destroy_realm;
+ }
+
+ if (realm_init_ipa_state(&realm, 0U, 0U, 1ULL << 32)
+ != RMI_SUCCESS) {
+ ERROR("realm_init_ipa_state\n");
+ goto destroy_realm;
+ }
+ /* RTT map Realm image */
+ if (realm_map_payload_image(&realm, realm_payload_adr) !=
+ REALM_SUCCESS) {
+ ERROR("realm_map_payload_image() failed\n");
+ goto destroy_realm;
+ }
+
+ /* Create REC */
+ if (realm_rec_create(&realm) != REALM_SUCCESS) {
+ ERROR("REC create failed\n");
+ goto destroy_realm;
+ }
+
+ /* Activate Realm */
+ if (realm_activate(&realm) != REALM_SUCCESS) {
+ ERROR("Realm activate failed\n");
+ goto destroy_realm;
+ }
+
+ realm_payload_created = true;
+
+ return realm_payload_created;
+
+ /* Free test resources */
+destroy_realm:
+ if (realm_destroy(&realm) != REALM_SUCCESS) {
+ ERROR("%s\n", "realm_destroy failed");
+ }
+ realm_payload_created = false;
+
+ return realm_payload_created;
+}
+
+bool host_create_shared_mem(u_register_t ns_shared_mem_adr,
+ u_register_t ns_shared_mem_size)
+{
+ /* RTT map NS shared region */
+ if (realm_map_ns_shared(&realm, ns_shared_mem_adr, ns_shared_mem_size) !=
+ REALM_SUCCESS) {
+ ERROR("realm_map_ns_shared() failed\n");
+ shared_mem_created = false;
+ return false;
+ }
+
+ host_init_realm_print_buffer();
+ realm_shared_data_clear_realm_val();
+ shared_mem_created = true;
+
+ return shared_mem_created;
+}
+
+bool host_destroy_realm(void)
+{
+ /* Free test resources */
+ timer_enabled = false;
+ page_pool_reset();
+
+ if (!realm_payload_created) {
+ ERROR("realm_destroy failed, Realm not created\n");
+ return false;
+ }
+
+ realm_payload_created = false;
+ if (realm_destroy(&realm) != REALM_SUCCESS) {
+ ERROR("%s\n", "realm_destroy failed");
+ return false;
+ }
+
+ return true;
+}
+
+bool host_enter_realm_execute(uint8_t cmd)
+{
+ exit_reason = RMI_EXIT_INVALID;
+ test_result = TEST_RESULT_FAIL;
+
+ realm_shared_data_set_realm_cmd(cmd);
+ if (!host_enter_realm(&exit_reason, &test_result)) {
+ return false;
+ }
+
+ if (exit_reason == RMI_EXIT_HOST_CALL &&
+ test_result == TEST_RESULT_SUCCESS) {
+ return true;
+ }
+ ERROR("host_enter_realm_execute exit_reason:[0x%lx],test_result:[0x%x]\n",
+ exit_reason,
+ test_result);
+ return false;
+}
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
new file mode 100644
index 0000000..898e22a
--- /dev/null
+++ b/tftf/tests/runtime_services/host_realm_managment/host_realm_rmi.c
@@ -0,0 +1,1060 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <string.h>
+
+#include <debug.h>
+#include <heap/page_alloc.h>
+#include <host_realm_helper.h>
+#include <host_realm_mem_layout.h>
+#include <host_realm_rmi.h>
+#include <plat/common/platform.h>
+#include <realm_def.h>
+#include <tftf_lib.h>
+
+static inline u_register_t rmi_data_create(bool unknown, u_register_t data,
+ u_register_t rd, u_register_t map_addr, u_register_t src)
+{
+ if (unknown) {
+ return ((smc_ret_values)(tftf_smc(&(smc_args)
+ {RMI_DATA_CREATE_UNKNOWN, data, rd, map_addr,
+ 0UL, 0UL, 0UL, 0UL}))).ret0;
+ } else {
+ return ((smc_ret_values)(tftf_smc(&(smc_args) {RMI_DATA_CREATE,
+ data, rd, map_addr, src, 0UL, 0UL, 0UL}))).ret0;
+ }
+}
+
+static inline u_register_t rmi_realm_activate(u_register_t rd)
+{
+ return ((smc_ret_values)(tftf_smc(&(smc_args) {RMI_REALM_ACTIVATE,
+ rd, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL}))).ret0;
+}
+
+u_register_t rmi_realm_create(u_register_t rd, u_register_t params_ptr)
+{
+ return ((smc_ret_values)(tftf_smc(&(smc_args) {RMI_REALM_CREATE,
+ rd, params_ptr, 0UL, 0UL, 0UL, 0UL, 0UL}))).ret0;
+}
+
+u_register_t rmi_realm_destroy(u_register_t rd)
+{
+ return ((smc_ret_values)(tftf_smc(&(smc_args) {RMI_REALM_DESTROY,
+ rd, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL}))).ret0;
+}
+
+static inline u_register_t rmi_data_destroy(u_register_t rd,
+ u_register_t map_addr)
+{
+ return ((smc_ret_values)(tftf_smc(&(smc_args) {RMI_DATA_DESTROY,
+ rd, map_addr, 0UL, 0UL, 0UL, 0UL, 0UL}))).ret0;
+}
+
+static inline u_register_t rmi_rec_create(u_register_t rec, u_register_t rd,
+ u_register_t params_ptr)
+{
+ return ((smc_ret_values)(tftf_smc(&(smc_args) {RMI_REC_CREATE,
+ rec, rd, params_ptr, 0UL, 0UL, 0UL, 0UL}))).ret0;
+}
+
+static inline u_register_t rmi_rec_destroy(u_register_t rec)
+{
+ return ((smc_ret_values)(tftf_smc(&(smc_args) {RMI_REC_DESTROY,
+ rec, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL}))).ret0;
+}
+
+static inline u_register_t rmi_rtt_create(u_register_t rtt, u_register_t rd,
+ u_register_t map_addr, u_register_t level)
+{
+ return ((smc_ret_values)(tftf_smc(&(smc_args) {RMI_RTT_CREATE,
+ rtt, rd, map_addr, level, 0UL, 0UL, 0UL}))).ret0;
+}
+
+static inline u_register_t rmi_rtt_destroy(u_register_t rtt, u_register_t rd,
+ u_register_t map_addr, u_register_t level)
+{
+ return ((smc_ret_values)(tftf_smc(&(smc_args) {RMI_RTT_DESTROY,
+ rtt, rd, map_addr, level, 0UL, 0UL, 0UL}))).ret0;
+}
+
+u_register_t rmi_features(u_register_t index, u_register_t *features)
+{
+ smc_ret_values rets;
+
+ rets = tftf_smc(&(smc_args) {RMI_FEATURES, index, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL});
+ *features = rets.ret1;
+ return rets.ret0;
+}
+
+static inline u_register_t rmi_rtt_init_ripas(u_register_t rd,
+ u_register_t map_addr,
+ u_register_t level)
+{
+ return ((smc_ret_values)(tftf_smc(&(smc_args) {RMI_RTT_INIT_RIPAS,
+ rd, map_addr, level, 0UL, 0UL, 0UL, 0UL}))).ret0;
+}
+
+static inline u_register_t rmi_rtt_fold(u_register_t rtt, u_register_t rd,
+ u_register_t map_addr, u_register_t level)
+{
+ return ((smc_ret_values)(tftf_smc(&(smc_args) {RMI_RTT_FOLD,
+ rtt, rd, map_addr, level, 0UL, 0UL, 0UL}))).ret0;
+}
+
+static inline u_register_t rmi_rec_aux_count(u_register_t rd,
+ u_register_t *aux_count)
+{
+ smc_ret_values rets;
+
+ rets = tftf_smc(&(smc_args) {RMI_REC_AUX_COUNT, rd, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL});
+ *aux_count = rets.ret1;
+ return rets.ret0;
+}
+
+static inline u_register_t rmi_rtt_set_ripas(u_register_t rd, u_register_t rec,
+ u_register_t map_addr, u_register_t level,
+ u_register_t ripas)
+{
+ return ((smc_ret_values)(tftf_smc(&(smc_args) {RMI_RTT_SET_RIPAS,
+ rd, rec, map_addr, level, ripas, 0UL, 0UL}))).ret0;
+}
+
+static inline u_register_t rmi_rtt_mapunprotected(u_register_t rd,
+ u_register_t map_addr,
+ u_register_t level, u_register_t ns_pa)
+{
+ return ((smc_ret_values)(tftf_smc(&(smc_args) {RMI_RTT_MAP_UNPROTECTED,
+ rd, map_addr, level, ns_pa, 0UL, 0UL, 0UL}))).ret0;
+}
+
+static u_register_t rmi_rtt_readentry(u_register_t rd, u_register_t map_addr,
+ u_register_t level, struct rtt_entry *rtt)
+{
+ smc_ret_values rets;
+
+ rets = tftf_smc(&(smc_args) {RMI_RTT_READ_ENTRY,
+ rd, map_addr, level, 0UL, 0UL, 0UL, 0UL});
+
+ rtt->walk_level = rets.ret1;
+ rtt->state = rets.ret2 & 0xFF;
+ rtt->out_addr = rets.ret3;
+ return rets.ret0;
+}
+
+static inline u_register_t rmi_rtt_unmap_unprotected(u_register_t rd,
+ u_register_t map_addr,
+ u_register_t level, u_register_t ns_pa)
+{
+ return ((smc_ret_values)(tftf_smc(&(smc_args) {RMI_RTT_UNMAP_UNPROTECTED,
+ rd, map_addr, level, ns_pa, 0UL, 0UL, 0UL}))).ret0;
+}
+
+static inline u_register_t rtt_level_mapsize(u_register_t level)
+{
+ if (level > RTT_MAX_LEVEL) {
+ return PAGE_SIZE;
+ }
+
+ return (1UL << RTT_LEVEL_SHIFT(level));
+}
+
+static inline u_register_t realm_rtt_create(struct realm *realm,
+ u_register_t addr,
+ u_register_t level,
+ u_register_t phys)
+{
+ addr = ALIGN_DOWN(addr, rtt_level_mapsize(level - 1U));
+ return rmi_rtt_create(phys, realm->rd, addr, level);
+}
+
+static u_register_t rmi_create_rtt_levels(struct realm *realm,
+ u_register_t map_addr,
+ u_register_t level,
+ u_register_t max_level)
+{
+ u_register_t rtt, ret;
+
+ while (level++ < max_level) {
+ rtt = (u_register_t)page_alloc(PAGE_SIZE);
+ if (rtt == HEAP_NULL_PTR) {
+ ERROR("Failed to allocate memory for rtt\n");
+ return REALM_ERROR;
+ } else {
+ ret = rmi_granule_delegate(rtt);
+ if (ret != RMI_SUCCESS) {
+ ERROR("Rtt delegation failed,"
+ "rtt=0x%lx ret=0x%lx\n", rtt, ret);
+ return REALM_ERROR;
+ }
+ }
+ ret = realm_rtt_create(realm, map_addr, level, rtt);
+ if (ret != RMI_SUCCESS) {
+ ERROR("Rtt create failed,"
+ "rtt=0x%lx ret=0x%lx\n", rtt, ret);
+ rmi_granule_undelegate(rtt);
+ page_free(rtt);
+ return REALM_ERROR;
+ }
+ }
+
+ return REALM_SUCCESS;
+}
+
+static u_register_t realm_fold_rtt(u_register_t rd, u_register_t addr,
+ u_register_t level)
+{
+ struct rtt_entry rtt;
+ u_register_t ret;
+
+ ret = rmi_rtt_readentry(rd, addr, level, &rtt);
+ if (ret != RMI_SUCCESS) {
+ ERROR("Rtt readentry failed,"
+ "level=0x%lx addr=0x%lx ret=0x%lx\n",
+ level, addr, ret);
+ return REALM_ERROR;
+ }
+
+ if (rtt.state != RMI_TABLE) {
+ ERROR("Rtt readentry failed, rtt.state=0x%x\n", rtt.state);
+ return REALM_ERROR;
+ }
+
+ ret = rmi_rtt_fold(rtt.out_addr, rd, addr, level + 1U);
+ if (ret != RMI_SUCCESS) {
+ ERROR("Rtt destroy failed,"
+ "rtt.out_addr=0x%llx addr=0x%lx ret=0x%lx\n",
+ rtt.out_addr, addr, ret);
+ return REALM_ERROR;
+ }
+
+ page_free(rtt.out_addr);
+
+ return REALM_SUCCESS;
+
+}
+
+static u_register_t realm_map_protected_data(bool unknown, struct realm *realm,
+ u_register_t target_pa,
+ u_register_t map_size,
+ u_register_t src_pa)
+{
+ u_register_t rd = realm->rd;
+ u_register_t map_level, level;
+ u_register_t ret = 0UL;
+ u_register_t size;
+ u_register_t phys = target_pa;
+ u_register_t map_addr = target_pa;
+
+ if (!IS_ALIGNED(map_addr, map_size)) {
+ return REALM_ERROR;
+ }
+
+ switch (map_size) {
+ case PAGE_SIZE:
+ map_level = 3UL;
+ break;
+ case RTT_L2_BLOCK_SIZE:
+ map_level = 2UL;
+ break;
+ default:
+ ERROR("Unknown map_size=0x%lx\n", map_size);
+ return REALM_ERROR;
+ }
+
+ ret = rmi_rtt_init_ripas(rd, map_addr, map_level);
+ if (RMI_RETURN_STATUS(ret) == RMI_ERROR_RTT) {
+ ret = rmi_create_rtt_levels(realm, map_addr,
+ RMI_RETURN_INDEX(ret), map_level);
+ if (ret != RMI_SUCCESS) {
+ ERROR("rmi_create_rtt_levels failed,"
+ "ret=0x%lx line:%d\n",
+ ret, __LINE__);
+ goto err;
+ }
+ ret = rmi_rtt_init_ripas(rd, map_addr, map_level);
+ if (ret != RMI_SUCCESS) {
+ ERROR("rmi_create_rtt_levels failed,"
+ "ret=0x%lx line:%d\n",
+ ret, __LINE__);
+ goto err;
+ }
+ }
+ for (size = 0UL; size < map_size; size += PAGE_SIZE) {
+ ret = rmi_granule_delegate(phys);
+ if (ret != RMI_SUCCESS) {
+ ERROR("Granule delegation failed, PA=0x%lx ret=0x%lx\n",
+ phys, ret);
+ return REALM_ERROR;
+ }
+
+ ret = rmi_data_create(unknown, phys, rd, map_addr, src_pa);
+
+ if (RMI_RETURN_STATUS(ret) == RMI_ERROR_RTT) {
+ /* Create missing RTTs and retry */
+ level = RMI_RETURN_INDEX(ret);
+ ret = rmi_create_rtt_levels(realm, map_addr, level,
+ map_level);
+ if (ret != RMI_SUCCESS) {
+ ERROR("rmi_create_rtt_levels failed,"
+ "ret=0x%lx line:%d\n",
+ ret, __LINE__);
+ goto err;
+ }
+
+ ret = rmi_data_create(unknown, phys, rd, map_addr, src_pa);
+ }
+
+ if (ret != RMI_SUCCESS) {
+ ERROR("rmi_data_create failed, ret=0x%lx\n", ret);
+ goto err;
+ }
+
+ phys += PAGE_SIZE;
+ src_pa += PAGE_SIZE;
+ map_addr += PAGE_SIZE;
+ }
+
+ if (map_size == RTT_L2_BLOCK_SIZE) {
+ ret = realm_fold_rtt(rd, target_pa, map_level);
+ if (ret != RMI_SUCCESS) {
+ ERROR("fold_rtt failed, ret=0x%lx\n", ret);
+ goto err;
+ }
+ }
+
+ if (ret != RMI_SUCCESS) {
+ ERROR("rmi_rtt_mapprotected failed, ret=0x%lx\n", ret);
+ goto err;
+ }
+
+ return REALM_SUCCESS;
+
+err:
+ while (size >= PAGE_SIZE) {
+ ret = rmi_data_destroy(rd, map_addr);
+ if (ret != RMI_SUCCESS) {
+ ERROR("rmi_rtt_mapprotected failed, ret=0x%lx\n", ret);
+ }
+
+ ret = rmi_granule_undelegate(phys);
+ if (ret != RMI_SUCCESS) {
+ /* Page can't be returned to NS world so is lost */
+ ERROR("rmi_granule_undelegate failed\n");
+ }
+ phys -= PAGE_SIZE;
+ size -= PAGE_SIZE;
+ map_addr -= PAGE_SIZE;
+ }
+
+ return REALM_ERROR;
+}
+
+u_register_t realm_map_unprotected(struct realm *realm,
+ u_register_t ns_pa,
+ u_register_t map_size)
+{
+ u_register_t rd = realm->rd;
+ u_register_t map_level, level;
+ u_register_t ret = 0UL;
+ u_register_t phys = ns_pa;
+ u_register_t map_addr = ns_pa |
+ (1UL << (EXTRACT(RMM_FEATURE_REGISTER_0_S2SZ,
+ realm->rmm_feat_reg0) - 1UL)) ;
+
+
+ if (!IS_ALIGNED(map_addr, map_size)) {
+ return REALM_ERROR;
+ }
+
+ switch (map_size) {
+ case PAGE_SIZE:
+ map_level = 3UL;
+ break;
+ case RTT_L2_BLOCK_SIZE:
+ map_level = 2UL;
+ break;
+ default:
+ ERROR("Unknown map_size=0x%lx\n", map_size);
+ return REALM_ERROR;
+ }
+
+ u_register_t desc = phys | S2TTE_ATTR_FWB_WB_RW;
+
+ ret = rmi_rtt_mapunprotected(rd, map_addr, map_level, desc);
+
+ if (RMI_RETURN_STATUS(ret) == RMI_ERROR_RTT) {
+ /* Create missing RTTs and retry */
+ level = RMI_RETURN_INDEX(ret);
+ ret = rmi_create_rtt_levels(realm, map_addr, level, map_level);
+ if (ret != RMI_SUCCESS) {
+ ERROR("rmi_create_rtt_levels failed, ret=0x%lx line:%d\n",
+ ret, __LINE__);
+ return REALM_ERROR;
+ }
+
+ ret = rmi_rtt_mapunprotected(rd, map_addr, map_level, desc);
+ }
+ if (ret != RMI_SUCCESS) {
+ ERROR("al_rmi_rtt_mapunprotected failed, ret=0x%lx\n", ret);
+ return REALM_ERROR;
+ }
+
+ return REALM_SUCCESS;
+}
+
+static u_register_t realm_rtt_destroy(struct realm *realm, u_register_t addr,
+ u_register_t level,
+ u_register_t rtt_granule)
+{
+ addr = ALIGN_DOWN(addr, rtt_level_mapsize(level - 1U));
+ return rmi_rtt_destroy(rtt_granule, realm->rd, addr, level);
+}
+
+static u_register_t realm_destroy_free_rtt(struct realm *realm,
+ u_register_t addr,
+ u_register_t level, u_register_t rtt_granule)
+{
+ u_register_t ret;
+
+ ret = realm_rtt_destroy(realm, addr, level, rtt_granule);
+ if (ret != RMI_SUCCESS) {
+ ERROR("realm_rtt_destroy failed, rtt=0x%lx, ret=0x%lx\n",
+ rtt_granule, ret);
+ return REALM_ERROR;
+ }
+
+ ret = rmi_granule_undelegate(rtt_granule);
+ if (ret != RMI_SUCCESS) {
+ ERROR("rmi_granule_undelegate failed, rtt=0x%lx, ret=0x%lx\n",
+ rtt_granule, ret);
+ return REALM_ERROR;
+ }
+
+ page_free(rtt_granule);
+ return REALM_SUCCESS;
+}
+
+static void realm_destroy_undelegate_range(struct realm *realm,
+ u_register_t ipa,
+ u_register_t addr,
+ u_register_t size)
+{
+ u_register_t rd = realm->rd;
+ u_register_t ret;
+
+ while (size >= PAGE_SIZE) {
+ ret = rmi_data_destroy(rd, ipa);
+ if (ret != RMI_SUCCESS) {
+ ERROR("rmi_data_destroy failed, addr=0x%lx, ret=0x%lx\n",
+ ipa, ret);
+ }
+
+ ret = rmi_granule_undelegate(addr);
+ if (ret != RMI_SUCCESS) {
+ ERROR("al_rmi_granule_undelegate failed, addr=0x%lx,"
+ "ret=0x%lx\n",
+ ipa, ret);
+ }
+
+ page_free(addr);
+
+ addr += PAGE_SIZE;
+ ipa += PAGE_SIZE;
+ size -= PAGE_SIZE;
+ }
+}
+
+static u_register_t realm_tear_down_rtt_range(struct realm *realm,
+ u_register_t level,
+ u_register_t start,
+ u_register_t end)
+{
+ u_register_t rd = realm->rd, ret;
+ u_register_t map_size = rtt_level_mapsize(level);
+ u_register_t map_addr, next_addr, rtt_out_addr, end_addr;
+ struct rtt_entry rtt;
+
+ for (map_addr = start; map_addr < end; map_addr = next_addr) {
+ next_addr = ALIGN(map_addr + 1U, map_size);
+ end_addr = MIN(next_addr, end);
+
+ ret = rmi_rtt_readentry(rd, ALIGN_DOWN(map_addr, map_size),
+ level, &rtt);
+ if (ret != RMI_SUCCESS) {
+ continue;
+ }
+
+ rtt_out_addr = rtt.out_addr;
+
+ switch (rtt.state) {
+ case RMI_ASSIGNED:
+ realm_destroy_undelegate_range(realm, map_addr,
+ rtt_out_addr, map_size);
+ break;
+ case RMI_UNASSIGNED:
+ case RMI_DESTROYED:
+ break;
+ case RMI_TABLE:
+ ret = realm_tear_down_rtt_range(realm, level + 1U,
+ map_addr, end_addr);
+ if (ret != RMI_SUCCESS) {
+ ERROR("realm_tear_down_rtt_range failed, \
+ map_addr=0x%lx ret=0x%lx\n",
+ map_addr, ret);
+ return REALM_ERROR;
+ }
+
+ ret = realm_destroy_free_rtt(realm, map_addr, level + 1U,
+ rtt_out_addr);
+ if (ret != RMI_SUCCESS) {
+ ERROR("rrt destroy can't be performed failed, \
+ map_addr=0x%lx ret=0x%lx\n",
+ map_addr, ret);
+ return REALM_ERROR;
+ }
+ break;
+ case RMI_VALID_NS:
+ ret = rmi_rtt_unmap_unprotected(rd, map_addr, level,
+ rtt_out_addr);
+ if (ret != RMI_SUCCESS) {
+ ERROR("rmi_rtt_unmap_unprotected failed,"
+ "addr=0x%lx, ret=0x%lx\n",
+ map_addr, ret);
+ return REALM_ERROR;
+ }
+ break;
+ default:
+ return REALM_ERROR;
+ }
+ }
+
+ return REALM_SUCCESS;
+}
+
+u_register_t rmi_granule_delegate(u_register_t addr)
+{
+ return ((smc_ret_values)(tftf_smc(&(smc_args) {RMI_GRANULE_DELEGATE,
+ addr, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL}))).ret0;
+}
+
+u_register_t rmi_granule_undelegate(u_register_t addr)
+{
+ return ((smc_ret_values)(tftf_smc(&(smc_args) {RMI_GRANULE_UNDELEGATE,
+ addr, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL}))).ret0;
+}
+
+u_register_t rmi_version(void)
+{
+ return ((smc_ret_values)(tftf_smc(&(smc_args) {RMI_VERSION,
+ 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL}))).ret0;
+}
+
+u_register_t realm_create(struct realm *realm)
+{
+ struct rmi_realm_params *params;
+ u_register_t ret;
+
+ realm->par_size = REALM_MAX_LOAD_IMG_SIZE;
+
+ realm->state = REALM_STATE_NULL;
+ /*
+ * Allocate memory for PAR - Realm image. Granule delegation
+ * of PAR will be performed during rtt creation.
+ */
+ realm->par_base = (u_register_t)page_alloc(realm->par_size);
+ if (realm->par_base == HEAP_NULL_PTR) {
+ ERROR("page_alloc failed, base=0x%lx, size=0x%lx\n",
+ realm->par_base, realm->par_size);
+ return REALM_ERROR;
+ }
+
+ /* Allocate and delegate RD */
+ realm->rd = (u_register_t)page_alloc(PAGE_SIZE);
+ if (realm->rd == HEAP_NULL_PTR) {
+ ERROR("Failed to allocate memory for rd\n");
+ goto err_free_par;
+ } else {
+ ret = rmi_granule_delegate(realm->rd);
+ if (ret != RMI_SUCCESS) {
+ ERROR("rd delegation failed, rd=0x%lx, ret=0x%lx\n",
+ realm->rd, ret);
+ goto err_free_rd;
+ }
+ }
+
+ /* Allocate and delegate RTT */
+ realm->rtt_addr = (u_register_t)page_alloc(PAGE_SIZE);
+ if (realm->rtt_addr == HEAP_NULL_PTR) {
+ ERROR("Failed to allocate memory for rtt_addr\n");
+ goto err_undelegate_rd;
+ } else {
+ ret = rmi_granule_delegate(realm->rtt_addr);
+ if (ret != RMI_SUCCESS) {
+ ERROR("rtt delegation failed, rtt_addr=0x%lx, ret=0x%lx\n",
+ realm->rtt_addr, ret);
+ goto err_free_rtt;
+ }
+ }
+
+ /* Allocate memory for params */
+ params = (struct rmi_realm_params *)page_alloc(PAGE_SIZE);
+ if (params == NULL) {
+ ERROR("Failed to allocate memory for params\n");
+ goto err_undelegate_rtt;
+ }
+
+ /* Populate params */
+ params->features_0 = realm->rmm_feat_reg0;
+ params->rtt_level_start = 0L;
+ params->rtt_num_start = 1U;
+ params->rtt_base = realm->rtt_addr;
+ params->vmid = 1U;
+ params->hash_algo = RMI_HASH_SHA_256;
+
+ /* Create Realm */
+ ret = rmi_realm_create(realm->rd, (u_register_t)params);
+ if (ret != RMI_SUCCESS) {
+ ERROR("Realm create failed, rd=0x%lx, ret=0x%lx\n", realm->rd,
+ ret);
+ goto err_free_params;
+ }
+
+ ret = rmi_rec_aux_count(realm->rd, &realm->num_aux);
+ if (ret != RMI_SUCCESS) {
+ ERROR("rmi_rec_aux_count failed, rd=0x%lx, ret=0x%lx\n", realm->rd,
+ ret);
+ rmi_realm_destroy(realm->rd);
+ goto err_free_params;
+ }
+
+ realm->state = REALM_STATE_NEW;
+
+ /* Free params */
+ page_free((u_register_t)params);
+ return REALM_SUCCESS;
+
+err_free_params:
+ page_free((u_register_t)params);
+
+err_undelegate_rtt:
+ ret = rmi_granule_undelegate(realm->rtt_addr);
+ if (ret != RMI_SUCCESS) {
+ WARN("rtt undelegation failed, rtt_addr=0x%lx, ret=0x%lx\n",
+ realm->rtt_addr, ret);
+ }
+
+err_free_rtt:
+ page_free(realm->rtt_addr);
+
+err_undelegate_rd:
+ ret = rmi_granule_undelegate(realm->rd);
+ if (ret != RMI_SUCCESS) {
+ WARN("rd undelegation failed, rd=0x%lx, ret=0x%lx\n", realm->rd,
+ ret);
+ }
+err_free_rd:
+ page_free(realm->rd);
+
+err_free_par:
+ page_free(realm->par_base);
+
+ return REALM_ERROR;
+}
+
+u_register_t realm_map_payload_image(struct realm *realm,
+ u_register_t realm_payload_adr)
+{
+ u_register_t src_pa = realm_payload_adr;
+ u_register_t i = 0UL;
+ u_register_t ret;
+
+ /* MAP image regions */
+ while (i < (realm->par_size / PAGE_SIZE)) {
+ ret = realm_map_protected_data(false, realm,
+ realm->par_base + i * PAGE_SIZE,
+ PAGE_SIZE,
+ src_pa + i * PAGE_SIZE);
+ if (ret != RMI_SUCCESS) {
+ ERROR("realm_map_protected_data failed,"
+ "par_base=0x%lx ret=0x%lx\n",
+ realm->par_base, ret);
+ return REALM_ERROR;
+ }
+ i++;
+ }
+
+ return REALM_SUCCESS;
+}
+
+u_register_t realm_init_ipa_state(struct realm *realm,
+ u_register_t level,
+ u_register_t start,
+ uint64_t end)
+{
+ u_register_t rd = realm->rd, ret;
+ u_register_t map_size = rtt_level_mapsize(level);
+
+ while (start < end) {
+ ret = rmi_rtt_init_ripas(rd, start, level);
+
+ if (RMI_RETURN_STATUS(ret) == RMI_ERROR_RTT) {
+ int cur_level = RMI_RETURN_INDEX(ret);
+
+ if (cur_level < level) {
+ ret = rmi_create_rtt_levels(realm,
+ start,
+ cur_level,
+ level);
+ if (ret != RMI_SUCCESS) {
+ ERROR("rmi_create_rtt_levels failed,"
+ "ret=0x%lx line:%d\n",
+ ret, __LINE__);
+ return ret;
+ }
+ /* Retry with the RTT levels in place */
+ continue;
+ }
+
+ if (level >= RTT_MAX_LEVEL) {
+ return REALM_ERROR;
+ }
+
+ /* There's an entry at a lower level, recurse */
+ realm_init_ipa_state(realm, start, start + map_size,
+ level + 1);
+ } else if (ret != RMI_SUCCESS) {
+ return REALM_ERROR;
+ }
+
+ start += map_size;
+ }
+
+ return RMI_SUCCESS;
+}
+
+u_register_t realm_map_ns_shared(struct realm *realm,
+ u_register_t ns_shared_mem_adr,
+ u_register_t ns_shared_mem_size)
+{
+ u_register_t i = 0UL;
+ u_register_t ret;
+
+ realm->ipa_ns_buffer = ns_shared_mem_adr |
+ (1UL << (EXTRACT(RMM_FEATURE_REGISTER_0_S2SZ,
+ realm->rmm_feat_reg0) - 1));
+ realm->ns_buffer_size = ns_shared_mem_size;
+ /* MAP SHARED_NS region */
+ while (i < ns_shared_mem_size / PAGE_SIZE) {
+ ret = realm_map_unprotected(realm,
+ ns_shared_mem_adr + i * PAGE_SIZE, PAGE_SIZE);
+ if (ret != RMI_SUCCESS) {
+ ERROR("\trealm_map_unprotected failepar"
+ "base=0x%lx ret=0x%lx\n",
+ (ns_shared_mem_adr + i * PAGE_SIZE), ret);
+ return REALM_ERROR;
+ }
+ i++;
+ }
+ return REALM_SUCCESS;
+}
+
+static void realm_free_rec_aux(u_register_t *aux_pages, unsigned int num_aux)
+{
+ u_register_t ret;
+
+ for (unsigned int i = 0U; i < num_aux; i++) {
+ ret = rmi_granule_undelegate(aux_pages[i]);
+ if (ret != RMI_SUCCESS) {
+ WARN("realm_free_rec_aux undelegation failed,"
+ "index=%u, ret=0x%lx\n",
+ i, ret);
+ }
+ page_free(aux_pages[i]);
+ }
+}
+
+static u_register_t realm_alloc_rec_aux(struct realm *realm,
+ struct rmi_rec_params *params)
+{
+ u_register_t ret;
+ unsigned int i;
+
+ for (i = 0; i < realm->num_aux; i++) {
+ params->aux[i] = (u_register_t)page_alloc(PAGE_SIZE);
+ if (params->aux[i] == HEAP_NULL_PTR) {
+ ERROR("Failed to allocate memory for aux rec\n");
+ goto err_free_mem;
+ }
+ ret = rmi_granule_delegate(params->aux[i]);
+ if (ret != RMI_SUCCESS) {
+ ERROR("aux rec delegation failed at index=%d, ret=0x%lx\n",
+ i, ret);
+ goto err_free_mem;
+ }
+
+ /* We need a copy in Realm object for final destruction */
+ realm->aux_pages[i] = params->aux[i];
+ }
+ return RMI_SUCCESS;
+err_free_mem:
+ realm_free_rec_aux(params->aux, i);
+ return ret;
+}
+
+u_register_t realm_rec_create(struct realm *realm)
+{
+ struct rmi_rec_params *rec_params = HEAP_NULL_PTR;
+ u_register_t ret;
+
+ /* Allocate memory for run object */
+ realm->run = (u_register_t)page_alloc(PAGE_SIZE);
+ if (realm->run == HEAP_NULL_PTR) {
+ ERROR("Failed to allocate memory for run\n");
+ return REALM_ERROR;
+ }
+ (void)memset((void *)realm->run, 0x0, PAGE_SIZE);
+
+ /* Allocate and delegate REC */
+ realm->rec = (u_register_t)page_alloc(PAGE_SIZE);
+ if (realm->rec == HEAP_NULL_PTR) {
+ ERROR("Failed to allocate memory for REC\n");
+ goto err_free_mem;
+ } else {
+ ret = rmi_granule_delegate(realm->rec);
+ if (ret != RMI_SUCCESS) {
+ ERROR("rec delegation failed, rec=0x%lx, ret=0x%lx\n",
+ realm->rd, ret);
+ goto err_free_mem;
+ }
+ }
+
+ /* Allocate memory for rec_params */
+ rec_params = (struct rmi_rec_params *)page_alloc(PAGE_SIZE);
+ if (rec_params == NULL) {
+ ERROR("Failed to allocate memory for rec_params\n");
+ goto err_undelegate_rec;
+ }
+ (void)memset(rec_params, 0x0, PAGE_SIZE);
+
+ /* Populate rec_params */
+ for (unsigned int i = 0UL; i < (sizeof(rec_params->gprs) /
+ sizeof(rec_params->gprs[0]));
+ i++) {
+ rec_params->gprs[i] = 0x0UL;
+ }
+
+ /* Delegate the required number of auxiliary Granules */
+ ret = realm_alloc_rec_aux(realm, rec_params);
+ if (ret != RMI_SUCCESS) {
+ ERROR("REC realm_alloc_rec_aux, ret=0x%lx\n", ret);
+ goto err_free_mem;
+ }
+
+ rec_params->pc = realm->par_base;
+ rec_params->flags = RMI_RUNNABLE;
+ rec_params->mpidr = 0x0UL;
+ rec_params->num_aux = realm->num_aux;
+
+ /* Create REC */
+ ret = rmi_rec_create(realm->rec, realm->rd,
+ (u_register_t)rec_params);
+ if (ret != RMI_SUCCESS) {
+ ERROR("REC create failed, ret=0x%lx\n", ret);
+ goto err_free_rec_aux;
+ }
+
+ /* Free rec_params */
+ page_free((u_register_t)rec_params);
+ return REALM_SUCCESS;
+
+err_free_rec_aux:
+ realm_free_rec_aux(rec_params->aux, realm->num_aux);
+
+err_undelegate_rec:
+ ret = rmi_granule_undelegate(realm->rec);
+ if (ret != RMI_SUCCESS) {
+ WARN("rec undelegation failed, rec=0x%lx, ret=0x%lx\n",
+ realm->rec, ret);
+ }
+
+err_free_mem:
+ page_free(realm->run);
+ page_free(realm->rec);
+ page_free((u_register_t)rec_params);
+
+ return REALM_ERROR;
+}
+
+u_register_t realm_activate(struct realm *realm)
+{
+ u_register_t ret;
+
+ /* Activate Realm */
+ ret = rmi_realm_activate(realm->rd);
+ if (ret != RMI_SUCCESS) {
+ ERROR("Realm activate failed, ret=0x%lx\n", ret);
+ return REALM_ERROR;
+ }
+
+ realm->state = REALM_STATE_ACTIVE;
+
+ return REALM_SUCCESS;
+}
+
+u_register_t realm_destroy(struct realm *realm)
+{
+ u_register_t ret;
+
+ if (realm->state == REALM_STATE_NULL) {
+ return REALM_SUCCESS;
+ }
+
+ if (realm->state == REALM_STATE_NEW) {
+ goto undo_from_new_state;
+ }
+
+ if (realm->state != REALM_STATE_ACTIVE) {
+ ERROR("Invalid realm state found =0x%x\n", realm->state);
+ return REALM_ERROR;
+ }
+
+ /* For each REC - Destroy, undelegate and free */
+ ret = rmi_rec_destroy(realm->rec);
+ if (ret != RMI_SUCCESS) {
+ ERROR("REC destroy failed, rec=0x%lx, ret=0x%lx\n",
+ realm->rec, ret);
+ return REALM_ERROR;
+ }
+
+ ret = rmi_granule_undelegate(realm->rec);
+ if (ret != RMI_SUCCESS) {
+ ERROR("rec undelegation failed, rec=0x%lx, ret=0x%lx\n",
+ realm->rec, ret);
+ return REALM_ERROR;
+ }
+
+ realm_free_rec_aux(realm->aux_pages, realm->num_aux);
+ page_free(realm->rec);
+
+ /* Free run object */
+ page_free(realm->run);
+
+ /*
+ * For each data granule - Destroy, undelegate and free
+ * RTTs (level 1U and below) must be destroyed leaf-upwards,
+ * using RMI_DATA_DESTROY, RMI_RTT_DESTROY and RMI_GRANULE_UNDELEGATE
+ * commands.
+ */
+ if (realm_tear_down_rtt_range(realm, 0UL, 0UL,
+ (1UL << (EXTRACT(RMM_FEATURE_REGISTER_0_S2SZ,
+ realm->rmm_feat_reg0) - 1))) != RMI_SUCCESS) {
+ ERROR("realm_tear_down_rtt_range\n");
+ return REALM_ERROR;
+ }
+ if (realm_tear_down_rtt_range(realm, 0UL, realm->ipa_ns_buffer,
+ (realm->ipa_ns_buffer + realm->ns_buffer_size)) !=
+ RMI_SUCCESS) {
+ ERROR("realm_tear_down_rtt_range\n");
+ return REALM_ERROR;
+ }
+undo_from_new_state:
+
+ /*
+ * RD Destroy, undelegate and free
+ * RTT(L0) undelegate and free
+ * PAR free
+ */
+ ret = rmi_realm_destroy(realm->rd);
+ if (ret != RMI_SUCCESS) {
+ ERROR("Realm destroy failed, rd=0x%lx, ret=0x%lx\n",
+ realm->rd, ret);
+ return REALM_ERROR;
+ }
+
+ ret = rmi_granule_undelegate(realm->rd);
+ if (ret != RMI_SUCCESS) {
+ ERROR("rd undelegation failed, rd=0x%lx, ret=0x%lx\n",
+ realm->rd, ret);
+ return REALM_ERROR;
+ }
+
+ ret = rmi_granule_undelegate(realm->rtt_addr);
+ if (ret != RMI_SUCCESS) {
+ ERROR("rtt undelegation failed, rtt_addr=0x%lx, ret=0x%lx\n",
+ realm->rtt_addr, ret);
+ return REALM_ERROR;
+ }
+
+ page_free(realm->rd);
+ page_free(realm->rtt_addr);
+ page_free(realm->par_base);
+
+ return REALM_SUCCESS;
+}
+
+
+u_register_t realm_rec_enter(struct realm *realm, u_register_t *exit_reason,
+ unsigned int *test_result)
+{
+ struct rmi_rec_run *run = (struct rmi_rec_run *)realm->run;
+ u_register_t ret;
+ bool re_enter_rec;
+
+ do {
+ re_enter_rec = false;
+ ret = ((smc_ret_values)(tftf_smc(&(smc_args) {RMI_REC_ENTER,
+ realm->rec, realm->run,
+ 0UL, 0UL, 0UL, 0UL, 0UL}))).ret0;
+ VERBOSE("rmi_rec_enter, \
+ run->exit_reason=0x%lx, \
+ run->exit.esr=0x%llx, \
+ EC_BITS=%d, \
+ ISS_DFSC_MASK=0x%llx\n",
+ run->exit_reason,
+ run->exit.esr,
+ ((EC_BITS(run->exit.esr) == EC_DABORT_CUR_EL)),
+ (ISS_BITS(run->exit.esr) & ISS_DFSC_MASK));
+
+ /* If a data abort because of a GPF. */
+
+ if (EC_BITS(run->exit.esr) == EC_DABORT_CUR_EL) {
+ ERROR("EC_BITS(run->exit.esr) == EC_DABORT_CUR_EL\n");
+ if ((ISS_BITS(run->exit.esr) & ISS_DFSC_MASK) ==
+ DFSC_GPF_DABORT) {
+ ERROR("DFSC_GPF_DABORT\n");
+ }
+ }
+
+
+ if (ret != RMI_SUCCESS) {
+ return ret;
+ }
+
+ if (run->exit.exit_reason == RMI_EXIT_HOST_CALL) {
+ switch (run->exit.imm) {
+ case HOST_CALL_GET_SHARED_BUFF_CMD:
+ run->entry.gprs[0] = realm->ipa_ns_buffer;
+ re_enter_rec = true;
+ break;
+ case HOST_CALL_EXIT_SUCCESS_CMD:
+ *test_result = TEST_RESULT_SUCCESS;
+ break;
+ case HOST_CALL_EXIT_FAILED_CMD:
+ *test_result = TEST_RESULT_FAIL;
+ break;
+ default:
+ break;
+ }
+
+ }
+
+ } while (re_enter_rec);
+
+ *exit_reason = run->exit.exit_reason;
+
+ return ret;
+}
diff --git a/tftf/tests/runtime_services/host_realm_managment/host_shared_data.c b/tftf/tests/runtime_services/host_realm_managment/host_shared_data.c
new file mode 100644
index 0000000..bd571c7
--- /dev/null
+++ b/tftf/tests/runtime_services/host_realm_managment/host_shared_data.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <string.h>
+
+#include <host_realm_mem_layout.h>
+#include <host_shared_data.h>
+
+static host_shared_data_t *host_shared_data =
+ ((host_shared_data_t *)(NS_REALM_SHARED_MEM_BASE));
+static host_shared_data_t *guest_shared_data;
+/*
+ * Return shared buffer pointer mapped as host_shared_data_t structure
+ */
+host_shared_data_t *host_get_shared_structure(void)
+{
+ return host_shared_data;
+}
+
+/*
+ * Set guest mapped shared buffer pointer
+ */
+void realm_set_shared_structure(host_shared_data_t *ptr)
+{
+ guest_shared_data = ptr;
+}
+
+/*
+ * Get guest mapped shared buffer pointer
+ */
+host_shared_data_t *realm_get_shared_structure(void)
+{
+ return guest_shared_data;
+}
+
+/*
+ * Set data to be shared from Host to realm
+ */
+void realm_shared_data_set_host_val(uint8_t index, u_register_t val)
+{
+ host_shared_data->host_param_val[(index >= MAX_DATA_SIZE) ?
+ (MAX_DATA_SIZE - 1) : index] = val;
+}
+
+/*
+ * Set data to be shared from realm to Host
+ */
+void realm_shared_data_set_realm_val(uint8_t index, u_register_t val)
+{
+ host_shared_data->realm_out_val[(index >= MAX_DATA_SIZE) ?
+ (MAX_DATA_SIZE - 1) : index] = val;
+}
+
+/*
+ * Return Host's data at index
+ */
+u_register_t realm_shared_data_get_host_val(uint8_t index)
+{
+ return guest_shared_data->host_param_val[(index >= MAX_DATA_SIZE) ?
+ (MAX_DATA_SIZE - 1) : index];
+}
+
+/*
+ * Return Realm's data at index
+ */
+u_register_t realm_shared_data_get_realm_val(uint8_t index)
+{
+ return host_shared_data->realm_out_val[(index >= MAX_DATA_SIZE) ?
+ (MAX_DATA_SIZE - 1) : index];
+}
+
+/*
+ * Clear shared realm data
+ */
+void realm_shared_data_clear_realm_val(void)
+{
+ (void)memset((char *)host_shared_data->realm_out_val, 0,
+ MAX_DATA_SIZE * sizeof(host_shared_data->realm_out_val[0]));
+}
+
+/*
+ * Clear shared Host data
+ */
+void realm_shared_data_clear_host_val(void)
+{
+ (void)memset((char *)host_shared_data->host_param_val, 0,
+ MAX_DATA_SIZE * sizeof(host_shared_data->host_param_val[0]));
+}
+
+/*
+ * Get command sent from Host to realm
+ */
+uint8_t realm_shared_data_get_realm_cmd(void)
+{
+ return guest_shared_data->realm_cmd;
+}
+
+/*
+ * Set command to be send from Host to realm
+ */
+void realm_shared_data_set_realm_cmd(uint8_t cmd)
+{
+ host_shared_data->realm_cmd = cmd;
+}
diff --git a/tftf/tests/runtime_services/realm_payload/realm_payload_test.c b/tftf/tests/runtime_services/host_realm_managment/rmi_delegate_tests.c
similarity index 85%
rename from tftf/tests/runtime_services/realm_payload/realm_payload_test.c
rename to tftf/tests/runtime_services/host_realm_managment/rmi_delegate_tests.c
index 8bdc60a..17ff651 100644
--- a/tftf/tests/runtime_services/realm_payload/realm_payload_test.c
+++ b/tftf/tests/runtime_services/host_realm_managment/rmi_delegate_tests.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,17 +7,23 @@
#include <stdlib.h>
#include <arch_features.h>
+#include <host_realm_helper.h>
+#include <host_realm_mem_layout.h>
+#include <host_shared_data.h>
#include <plat_topology.h>
-#include <power_management.h>
#include <platform.h>
-#include <runtime_services/realm_payload/realm_payload_test.h>
+#include <power_management.h>
+#include "rmi_spm_tests.h"
#include <test_helpers.h>
+
+
static test_result_t realm_multi_cpu_payload_test(void);
static test_result_t realm_multi_cpu_payload_del_undel(void);
/* Buffer to delegate and undelegate */
-static char bufferdelegate[NUM_GRANULES * GRANULE_SIZE * PLATFORM_CORE_COUNT] __aligned(GRANULE_SIZE);
+static char bufferdelegate[NUM_GRANULES * GRANULE_SIZE * PLATFORM_CORE_COUNT]
+ __aligned(GRANULE_SIZE);
static char bufferstate[NUM_GRANULES * PLATFORM_CORE_COUNT];
/*
@@ -41,12 +47,14 @@
{
u_register_t retrmm;
- for (int i = 0; i < (NUM_GRANULES * PLATFORM_CORE_COUNT) ; i++) {
+ for (uint32_t i = 0; i < (NUM_GRANULES * PLATFORM_CORE_COUNT) ; i++) {
if ((rand() % 2) == 0) {
- retrmm = realm_granule_delegate((u_register_t)&bufferdelegate[i * GRANULE_SIZE]);
+ retrmm = rmi_granule_delegate(
+ (u_register_t)&bufferdelegate[i * GRANULE_SIZE]);
bufferstate[i] = B_DELEGATED;
if (retrmm != 0UL) {
- tftf_testcase_printf("Delegate operation returns fail, %lx\n", retrmm);
+ tftf_testcase_printf("Delegate operation returns fail, %lx\n",
+ retrmm);
return TEST_RESULT_FAIL;
}
} else {
@@ -67,7 +75,7 @@
return TEST_RESULT_SKIPPED;
}
- retrmm = realm_version();
+ retrmm = rmi_version();
tftf_testcase_printf("RMM version is: %lu.%lu\n",
RMI_ABI_VERSION_GET_MAJOR(retrmm),
@@ -138,12 +146,12 @@
return TEST_RESULT_SKIPPED;
}
- retrmm = realm_granule_delegate((u_register_t)bufferdelegate);
+ retrmm = rmi_granule_delegate((u_register_t)bufferdelegate);
if (retrmm != 0UL) {
tftf_testcase_printf("Delegate operation returns fail, %lx\n", retrmm);
return TEST_RESULT_FAIL;
}
- retrmm = realm_granule_undelegate((u_register_t)bufferdelegate);
+ retrmm = rmi_granule_undelegate((u_register_t)bufferdelegate);
if (retrmm != 0UL) {
tftf_testcase_printf("Undelegate operation returns fail, %lx\n", retrmm);
return TEST_RESULT_FAIL;
@@ -156,7 +164,7 @@
static test_result_t realm_multi_cpu_payload_test(void)
{
- u_register_t retrmm = realm_version();
+ u_register_t retrmm = rmi_version();
tftf_testcase_printf("Multi CPU RMM version on CPU %llx is: %lu.%lu\n",
(long long)read_mpidr_el1() & MPID_MASK, RMI_ABI_VERSION_GET_MAJOR(retrmm),
@@ -221,12 +229,14 @@
* Cleanup to set all granules back to undelegated
*/
- for (int i = 0; i < (NUM_GRANULES * PLATFORM_CORE_COUNT) ; i++) {
+ for (uint32_t i = 0; i < (NUM_GRANULES * PLATFORM_CORE_COUNT) ; i++) {
if (bufferstate[i] == B_DELEGATED) {
- retrmm = realm_granule_undelegate((u_register_t)&bufferdelegate[i * GRANULE_SIZE]);
+ retrmm = rmi_granule_undelegate(
+ (u_register_t)&bufferdelegate[i * GRANULE_SIZE]);
bufferstate[i] = B_UNDELEGATED;
if (retrmm != 0UL) {
- tftf_testcase_printf("Delegate operation returns fail, %lx\n", retrmm);
+ tftf_testcase_printf("Delegate operation returns fail, %lx\n",
+ retrmm);
return TEST_RESULT_FAIL;
}
}
@@ -250,13 +260,13 @@
cpu_node = platform_get_core_pos(read_mpidr_el1() & MPID_MASK);
- for (int i = 0; i < NUM_GRANULES; i++) {
+ for (uint32_t i = 0; i < NUM_GRANULES; i++) {
if (bufferstate[((cpu_node * NUM_GRANULES) + i)] == B_UNDELEGATED) {
- retrmm = realm_granule_delegate((u_register_t)
+ retrmm = rmi_granule_delegate((u_register_t)
&bufferdelegate[((cpu_node * NUM_GRANULES) + i) * GRANULE_SIZE]);
bufferstate[((cpu_node * NUM_GRANULES) + i)] = B_DELEGATED;
} else {
- retrmm = realm_granule_undelegate((u_register_t)
+ retrmm = rmi_granule_undelegate((u_register_t)
&bufferdelegate[((cpu_node * NUM_GRANULES) + i) * GRANULE_SIZE]);
bufferstate[((cpu_node * NUM_GRANULES) + i)] = B_UNDELEGATED;
}
@@ -281,7 +291,7 @@
u_register_t retrmm;
- retrmm = realm_granule_delegate((u_register_t)&bufferdelegate[0]);
+ retrmm = rmi_granule_delegate((u_register_t)&bufferdelegate[0]);
if (retrmm != 0UL) {
tftf_testcase_printf
@@ -289,7 +299,7 @@
return TEST_RESULT_FAIL;
}
- retrmm = realm_granule_delegate((u_register_t)&bufferdelegate[0]);
+ retrmm = rmi_granule_delegate((u_register_t)&bufferdelegate[0]);
if (retrmm == 0UL) {
tftf_testcase_printf
@@ -297,7 +307,7 @@
return TEST_RESULT_FAIL;
}
- retrmm = realm_granule_undelegate((u_register_t)&bufferdelegate[1]);
+ retrmm = rmi_granule_undelegate((u_register_t)&bufferdelegate[1]);
if (retrmm == 0UL) {
tftf_testcase_printf
@@ -305,7 +315,7 @@
return TEST_RESULT_FAIL;
}
- retrmm = realm_granule_undelegate((u_register_t)&bufferdelegate[0]);
+ retrmm = rmi_granule_undelegate((u_register_t)&bufferdelegate[0]);
if (retrmm != 0UL) {
tftf_testcase_printf
diff --git a/tftf/tests/runtime_services/realm_payload/realm_payload_spm_test.c b/tftf/tests/runtime_services/host_realm_managment/rmi_spm_tests.c
similarity index 93%
rename from tftf/tests/runtime_services/realm_payload/realm_payload_spm_test.c
rename to tftf/tests/runtime_services/host_realm_managment/rmi_spm_tests.c
index 1aaa12c..2a0e1e1 100644
--- a/tftf/tests/runtime_services/realm_payload/realm_payload_spm_test.c
+++ b/tftf/tests/runtime_services/host_realm_managment/rmi_spm_tests.c
@@ -6,20 +6,19 @@
#include <stdlib.h>
-#include <debug.h>
-#include <smccc.h>
-
#include <arch_helpers.h>
#include <cactus_test_cmds.h>
+#include <debug.h>
#include <ffa_endpoints.h>
#include <ffa_svc.h>
+#include <host_realm_helper.h>
#include <lib/events.h>
#include <lib/power_management.h>
-#include <platform.h>
-#include <test_helpers.h>
-
#include <plat_topology.h>
-#include <runtime_services/realm_payload/realm_payload_test.h>
+#include <platform.h>
+#include "rmi_spm_tests.h"
+#include <smccc.h>
+#include <test_helpers.h>
static test_result_t realm_multi_cpu_payload_del_undel(void);
@@ -29,7 +28,8 @@
#define MAX_REPEATED_TEST 3
/* Buffer to delegate and undelegate */
-static char bufferdelegate[NUM_GRANULES * GRANULE_SIZE * PLATFORM_CORE_COUNT] __aligned(GRANULE_SIZE);
+static char bufferdelegate[NUM_GRANULES * GRANULE_SIZE * PLATFORM_CORE_COUNT]
+ __aligned(GRANULE_SIZE);
static char bufferstate[NUM_GRANULES * PLATFORM_CORE_COUNT];
static int cpu_test_spm_rmi[PLATFORM_CORE_COUNT];
static event_t cpu_booted[PLATFORM_CORE_COUNT];
@@ -89,10 +89,12 @@
for (int i = 0; i < (NUM_GRANULES * PLATFORM_CORE_COUNT) ; i++) {
if ((rand() % 2) == 0) {
- retrmm = realm_granule_delegate((u_register_t)&bufferdelegate[i * GRANULE_SIZE]);
+ retrmm = rmi_granule_delegate(
+ (u_register_t)&bufferdelegate[i * GRANULE_SIZE]);
bufferstate[i] = B_DELEGATED;
if (retrmm != 0UL) {
- tftf_testcase_printf("Delegate operation returns fail, %lx\n", retrmm);
+ tftf_testcase_printf("Delegate operation\
+ returns fail, %lx\n", retrmm);
return TEST_RESULT_FAIL;
}
} else {
@@ -106,9 +108,9 @@
{
u_register_t retrmm;
- for (uint32_t i = 0; i < (NUM_GRANULES * PLATFORM_CORE_COUNT) ; i++) {
+ for (uint32_t i = 0U; i < (NUM_GRANULES * PLATFORM_CORE_COUNT) ; i++) {
if (bufferstate[i] == B_DELEGATED) {
- retrmm = realm_granule_undelegate(
+ retrmm = rmi_granule_undelegate(
(u_register_t)&bufferdelegate[i * GRANULE_SIZE]);
if (retrmm != 0UL) {
ERROR("Undelegate operation returns fail, %lx\n",
@@ -129,7 +131,9 @@
static test_result_t wait_then_call(test_result_t (*callback)(void))
{
unsigned int mpidr, this_mpidr = read_mpidr_el1() & MPID_MASK;
- unsigned int cpu_node, core_pos, this_core_pos = platform_get_core_pos(this_mpidr);
+ unsigned int cpu_node, core_pos;
+ unsigned int this_core_pos = platform_get_core_pos(this_mpidr);
+
tftf_send_event_to_all(&cpu_booted[this_core_pos]);
for_each_cpu(cpu_node) {
mpidr = tftf_get_mpidr_from_node(cpu_node);
@@ -252,7 +256,8 @@
ffa_ret = cactus_echo_send_cmd(HYP_ID, SP_ID(3), ECHO_VAL3);
if ((ffa_func_id(ffa_ret) == FFA_ERROR) &&
(ffa_error_code(ffa_ret) == FFA_ERROR_BUSY)) {
- VERBOSE("%s(%u) trial %u\n", __func__, core_pos, trial_loop);
+ VERBOSE("%s(%u) trial %u\n", __func__,
+ core_pos, trial_loop);
waitms(1);
continue;
}
@@ -277,7 +282,7 @@
/*
* Secondary core will perform sequentially a call to secure and realm worlds.
*/
-test_result_t non_secure_call_secure_and_realm(void)
+static test_result_t non_secure_call_secure_and_realm(void)
{
test_result_t result = run_spm_direct_message();
if (result != TEST_RESULT_SUCCESS)
@@ -310,18 +315,19 @@
for (int i = 0; i < NUM_GRANULES; i++) {
if (bufferstate[((cpu_node * NUM_GRANULES) + i)] == B_UNDELEGATED) {
- retrmm = realm_granule_delegate((u_register_t)
+ retrmm = rmi_granule_delegate((u_register_t)
&bufferdelegate[((cpu_node *
NUM_GRANULES) + i) * GRANULE_SIZE]);
bufferstate[((cpu_node * NUM_GRANULES) + i)] = B_DELEGATED;
} else {
- retrmm = realm_granule_undelegate((u_register_t)
+ retrmm = rmi_granule_undelegate((u_register_t)
&bufferdelegate[((cpu_node *
NUM_GRANULES) + i) * GRANULE_SIZE]);
bufferstate[((cpu_node * NUM_GRANULES) + i)] = B_UNDELEGATED;
}
if (retrmm != 0UL) {
- tftf_testcase_printf("Delegate operation returns fail, %lx\n", retrmm);
+ tftf_testcase_printf("Delegate operation returns fail, %lx\n",
+ retrmm);
return TEST_RESULT_FAIL;
}
}
@@ -423,7 +429,8 @@
* Main test to run both SPM and RMM or TRP together in parallel
*/
for (int i = 0; i < MAX_REPEATED_TEST; i++) {
- VERBOSE("Main test(%d) to run both SPM and RMM or TRP together in parallel...\n", i);
+ VERBOSE("Main test(%d) to run both SPM and RMM or\
+ TRP together in parallel...\n", i);
/* Reinitialize all CPUs event */
for (unsigned int i = 0U; i < PLATFORM_CORE_COUNT; i++) {
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
new file mode 100644
index 0000000..562e9b8
--- /dev/null
+++ b/tftf/tests/runtime_services/realm_payload/host_realm_payload_tests.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdlib.h>
+
+#include <arch_features.h>
+#include <debug.h>
+#include <host_realm_helper.h>
+#include <host_realm_mem_layout.h>
+#include <host_shared_data.h>
+
+#define SLEEP_TIME_MS 200U
+/*
+ * @Test_Aim@ Test realm payload creation and execution
+ */
+test_result_t test_realm_create_enter(void)
+{
+ bool ret1, ret2;
+ u_register_t retrmm;
+
+ if (get_armv9_2_feat_rme_support() == 0U) {
+ INFO("platform doesn't support RME\n");
+ return TEST_RESULT_SKIPPED;
+ }
+
+ retrmm = rmi_version();
+ VERBOSE("RMM version is: %lu.%lu\n",
+ RMI_ABI_VERSION_GET_MAJOR(retrmm),
+ RMI_ABI_VERSION_GET_MINOR(retrmm));
+ /*
+ * Skip the test if RMM is TRP, TRP version is always null.
+ */
+ if (retrmm == 0UL) {
+ INFO("Test case not supported for TRP as RMM\n");
+ return TEST_RESULT_SKIPPED;
+ }
+
+ 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)) {
+ return TEST_RESULT_FAIL;
+ }
+ if (!host_create_shared_mem(NS_REALM_SHARED_MEM_BASE,
+ NS_REALM_SHARED_MEM_SIZE)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ realm_shared_data_set_host_val(HOST_SLEEP_INDEX, SLEEP_TIME_MS);
+ ret1 = host_enter_realm_execute(REALM_SLEEP_CMD);
+ ret2 = host_destroy_realm();
+
+ if (!ret1 || !ret2) {
+ ERROR("test_realm_create_enter create:%d destroy:%d\n",
+ ret1, ret2);
+ return TEST_RESULT_FAIL;
+ }
+ return TEST_RESULT_SUCCESS;
+}
diff --git a/tftf/tests/runtime_services/realm_payload/realm_payload_test_helpers.c b/tftf/tests/runtime_services/realm_payload/realm_payload_test_helpers.c
deleted file mode 100644
index 49bf674..0000000
--- a/tftf/tests/runtime_services/realm_payload/realm_payload_test_helpers.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <runtime_services/realm_payload/realm_payload_test.h>
-
-u_register_t realm_version(void)
-{
- smc_args args = { RMI_RMM_REQ_VERSION };
- smc_ret_values ret;
-
- ret = tftf_smc(&args);
- return ret.ret0;
-}
-
-u_register_t realm_granule_delegate(u_register_t add)
-{
- smc_args args = { 0 };
- smc_ret_values ret;
-
- args.fid = SMC_RMM_GRANULE_DELEGATE;
- args.arg1 = add;
-
- ret = tftf_smc(&args);
- return ret.ret0;
-}
-
-u_register_t realm_granule_undelegate(u_register_t add)
-{
- smc_args args = { 0 };
- smc_ret_values ret;
-
- args.fid = SMC_RMM_GRANULE_UNDELEGATE;
- args.arg1 = add;
-
- ret = tftf_smc(&args);
- return ret.ret0;
-}
-
-u_register_t realm_create(u_register_t rd_addr, u_register_t realm_params_addr)
-{
- smc_args args = { 0 };
- smc_ret_values ret;
-
- args.fid = SMC_RMM_REALM_CREATE;
- args.arg1 = rd_addr;
- args.arg2 = realm_params_addr;
-
- ret = tftf_smc(&args);
- return ret.ret0;
-}
-
-u_register_t realm_destroy(u_register_t rd_addr)
-{
- smc_args args = { 0 };
- smc_ret_values ret;
-
- args.fid = SMC_RMM_REALM_DESTROY;
- args.arg1 = rd_addr;
-
- ret = tftf_smc(&args);
- return ret.ret0;
-}
\ No newline at end of file
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_exceptions.c b/tftf/tests/runtime_services/secure_service/test_ffa_exceptions.c
index 61cf2ad..e809885 100644
--- a/tftf/tests/runtime_services/secure_service/test_ffa_exceptions.c
+++ b/tftf/tests/runtime_services/secure_service/test_ffa_exceptions.c
@@ -9,9 +9,9 @@
#include <debug.h>
#include <ffa_endpoints.h>
#include <ffa_svc.h>
+#include <host_realm_helper.h>
#include <irq.h>
#include <platform.h>
-#include <runtime_services/realm_payload/realm_payload_test.h>
#include <smccc.h>
#include <spm_common.h>
#include <test_helpers.h>
@@ -71,7 +71,7 @@
handle, constituents[0].address);
/* Delegate the shared page to Realm. */
- retmm = realm_granule_delegate((u_register_t)&share_page);
+ retmm = rmi_granule_delegate((u_register_t)&share_page);
if (retmm != 0UL) {
ERROR("Granule delegate failed!\n");
return TEST_RESULT_FAIL;
@@ -82,7 +82,7 @@
handle, 0, true, 1);
/* Undelegate the shared page. */
- retmm = realm_granule_undelegate((u_register_t)&share_page);
+ retmm = rmi_granule_undelegate((u_register_t)&share_page);
if (retmm != 0UL) {
ERROR("Granule undelegate failed!\n");
return TEST_RESULT_FAIL;
diff --git a/tftf/tests/tests-invalid-access.mk b/tftf/tests/tests-invalid-access.mk
index ffca79e..8202c20 100644
--- a/tftf/tests/tests-invalid-access.mk
+++ b/tftf/tests/tests-invalid-access.mk
@@ -4,11 +4,14 @@
# SPDX-License-Identifier: BSD-3-Clause
#
+TFTF_INCLUDES += \
+ -Iinclude/runtime_services/host_realm_managment
+
TESTS_SOURCES += tftf/tests/misc_tests/test_invalid_access.c
TESTS_SOURCES += \
- $(addprefix tftf/tests/runtime_services/realm_payload/, \
- realm_payload_test_helpers.c \
+ $(addprefix tftf/tests/runtime_services/host_realm_managment/, \
+ host_realm_rmi.c \
)
TESTS_SOURCES += \
@@ -17,4 +20,4 @@
ffa_helpers.c \
spm_common.c \
test_ffa_setup_and_discovery.c \
-)
+)
\ No newline at end of file
diff --git a/tftf/tests/tests-realm-payload.mk b/tftf/tests/tests-realm-payload.mk
index a8642fa..6d23e38 100644
--- a/tftf/tests/tests-realm-payload.mk
+++ b/tftf/tests/tests-realm-payload.mk
@@ -1,24 +1,26 @@
#
-# Copyright (c) 2021, Arm Limited. All rights reserved.
+# Copyright (c) 2021-2022, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
+TFTF_INCLUDES += \
+ -Iinclude/runtime_services/host_realm_managment
+
TESTS_SOURCES += \
$(addprefix tftf/tests/runtime_services/realm_payload/, \
- realm_payload_test_helpers.c \
- realm_payload_test.c \
- realm_payload_spm_test.c \
+ host_realm_payload_tests.c \
)
TESTS_SOURCES += \
- $(addprefix tftf/tests/runtime_services/secure_service/, \
- ffa_helpers.c \
- spm_common.c \
- test_ffa_direct_messaging.c \
- test_ffa_interrupts.c \
- test_ffa_memory_sharing.c \
- test_ffa_setup_and_discovery.c \
- test_spm_cpu_features.c \
- test_spm_smmu.c \
+ $(addprefix tftf/tests/runtime_services/host_realm_managment/, \
+ host_realm_rmi.c \
+ host_realm_helper.c \
+ host_shared_data.c \
+ rmi_delegate_tests.c \
)
+
+TESTS_SOURCES += \
+ $(addprefix lib/heap/, \
+ page_alloc.c \
+ )
\ No newline at end of file
diff --git a/tftf/tests/tests-realm-payload.xml b/tftf/tests/tests-realm-payload.xml
index f80ead6..8438ea1 100644
--- a/tftf/tests/tests-realm-payload.xml
+++ b/tftf/tests/tests-realm-payload.xml
@@ -7,15 +7,18 @@
-->
<testsuites>
-
- <testsuite name="Realm payload tests" description="Tests for Realm management interface">
- <testcase name="Realm payload boot" function="realm_version_single_cpu" />
- <testcase name="Realm payload multi CPU request" function="realm_version_multi_cpu" />
- <testcase name="Realm payload Delegate and Undelegate" function="realm_delegate_undelegate" />
- <testcase name="Multi CPU Realm payload Delegate and Undelegate" function="realm_delundel_multi_cpu" />
- <testcase name="Testing delegation fails" function="realm_fail_del" />
- <testcase name="Test TFTF can call RMM/TRP and SPM serially on a single core" function="test_spm_rmm_serial_smc" />
- <testcase name="Test TFTF can call RMM/TRP and SPM parallelly on a multi core" function="test_spm_rmm_parallel_smc" />
+ <testsuite name="Realm payload at EL1" description="Test Realm EL1 framework capabilities" >
+ <testcase name="Realm EL1 creation and execution test"
+ function="test_realm_create_enter" />
+ <testcase name="Realm payload boot"
+ function="realm_version_single_cpu" />
+ <testcase name="Realm payload multi CPU request"
+ function="realm_version_multi_cpu" />
+ <testcase name="Realm payload Delegate and Undelegate"
+ function="realm_delegate_undelegate" />
+ <testcase name="Multi CPU Realm payload Delegate and Undelegate"
+ function="realm_delundel_multi_cpu" />
+ <testcase name="Testing delegation fails"
+ function="realm_fail_del" />
</testsuite>
-
</testsuites>
diff --git a/tftf/tests/tests-rmi-spm.mk b/tftf/tests/tests-rmi-spm.mk
new file mode 100644
index 0000000..960aa93
--- /dev/null
+++ b/tftf/tests/tests-rmi-spm.mk
@@ -0,0 +1,26 @@
+#
+# Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+TFTF_INCLUDES += \
+ -Iinclude/runtime_services/host_realm_managment
+
+TESTS_SOURCES += \
+ $(addprefix tftf/tests/runtime_services/host_realm_managment/, \
+ host_realm_rmi.c \
+ rmi_spm_tests.c \
+ )
+
+TESTS_SOURCES += \
+ $(addprefix tftf/tests/runtime_services/secure_service/, \
+ ${ARCH}/ffa_arch_helpers.S \
+ ffa_helpers.c \
+ spm_common.c \
+ )
+
+TESTS_SOURCES += \
+ $(addprefix lib/heap/, \
+ page_alloc.c \
+ )
\ No newline at end of file
diff --git a/tftf/tests/tests-rmi-spm.xml b/tftf/tests/tests-rmi-spm.xml
new file mode 100644
index 0000000..1d12b4a
--- /dev/null
+++ b/tftf/tests/tests-rmi-spm.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+
+ SPDX-License-Identifier: BSD-3-Clause
+-->
+
+<testsuites>
+
+ <testsuite name="RMI and SPM tests" description="Tests for SPM and RMI delegate/undelegate">
+ <testcase name="Test TFTF can call RMM/TRP and SPM serially on a single core"
+ function="test_spm_rmm_serial_smc" />
+ <testcase name="Test TFTF can call RMM/TRP and SPM parallelly on a multi core"
+ function="test_spm_rmm_parallel_smc" />
+ </testsuite>
+
+</testsuites>
\ No newline at end of file
diff --git a/tftf/tests/tests-spm.mk b/tftf/tests/tests-spm.mk
index 5d71aec..f2ad0e4 100644
--- a/tftf/tests/tests-spm.mk
+++ b/tftf/tests/tests-spm.mk
@@ -3,6 +3,10 @@
#
# SPDX-License-Identifier: BSD-3-Clause
#
+
+TFTF_INCLUDES += \
+ -Iinclude/runtime_services/host_realm_managment
+
TESTS_SOURCES += \
$(addprefix tftf/tests/runtime_services/secure_service/, \
${ARCH}/ffa_arch_helpers.S \
@@ -21,6 +25,6 @@
)
TESTS_SOURCES += \
- $(addprefix tftf/tests/runtime_services/realm_payload/, \
- realm_payload_test_helpers.c \
- )
+ $(addprefix tftf/tests/runtime_services/host_realm_managment/, \
+ host_realm_rmi.c \
+ )
\ No newline at end of file
diff --git a/tftf/tests/tests-standard.mk b/tftf/tests/tests-standard.mk
index a722077..d57c381 100644
--- a/tftf/tests/tests-standard.mk
+++ b/tftf/tests/tests-standard.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2018-2021, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2022, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -22,7 +22,8 @@
tests-trng.mk \
tests-tsp.mk \
tests-uncontainable.mk \
- tests-debugfs.mk \
+ tests-debugfs.mk \
+ tests-rmi-spm.mk \
tests-realm-payload.mk \
)
diff --git a/tftf/tests/tests-standard.xml b/tftf/tests/tests-standard.xml
index 384a5f4..1917bc9 100644
--- a/tftf/tests/tests-standard.xml
+++ b/tftf/tests/tests-standard.xml
@@ -24,6 +24,7 @@
<!ENTITY tests-spm SYSTEM "tests-spm.xml">
<!ENTITY tests-pmu-leakage SYSTEM "tests-pmu-leakage.xml">
<!ENTITY tests-debugfs SYSTEM "tests-debugfs.xml">
+ <!ENTITY tests-rmi-spm SYSTEM "tests-rmi-spm.xml">
<!ENTITY tests-realm-payload SYSTEM "tests-realm-payload.xml">
]>
@@ -44,6 +45,7 @@
&tests-spm;
&tests-pmu-leakage;
&tests-debugfs;
+ &tests-rmi-spm;
&tests-realm-payload;
</testsuites>