aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier Deprez <olivier.deprez@arm.com>2020-02-07 15:44:43 +0100
committerjmarinho <jose.marinho@arm.com>2020-12-17 17:09:22 +0000
commit4516270294b1c9f4bb859127013f66d104d51995 (patch)
treed8a9ce4bd6129fd4df9b342decc76e4166a67911
parente37a30fa71407b37f246f438206c0c269fedc1e6 (diff)
downloadtrusted-firmware-a-4516270294b1c9f4bb859127013f66d104d51995.tar.gz
SPMD: extract SPMC DTB header size from SPMD
Currently BL2 passes TOS_FW_CONFIG address and size through registers to BL31. This corresponds to SPMC manifest load address and size. The SPMC manifest is mapped in BL31 by dynamic mapping. This patch removes BL2 changes from generic code (which were enclosed by SPD=spmd) and retrieves SPMC manifest size directly from within SPMD. The SPMC manifest load address is still passed through a register by generic code. Signed-off-by: Olivier Deprez <olivier.deprez@arm.com> Change-Id: I35c5abd95c616ae25677302f0b1d0c45c51c042f
-rw-r--r--common/desc_image_load.c12
-rw-r--r--include/plat/common/platform.h3
-rw-r--r--plat/common/plat_spmd_manifest.c68
-rw-r--r--services/std_svc/spmd/spmd_main.c62
4 files changed, 73 insertions, 72 deletions
diff --git a/common/desc_image_load.c b/common/desc_image_load.c
index 47c80aa86e..30b97e0509 100644
--- a/common/desc_image_load.c
+++ b/common/desc_image_load.c
@@ -214,9 +214,6 @@ void populate_next_bl_params_config(bl_params_t *bl2_to_next_bl_params)
{
bl_params_node_t *params_node;
unsigned int fw_config_id;
-#ifdef SPD_spmd
- uint32_t fw_config_size = 0;
-#endif
uintptr_t fw_config_base;
bl_mem_params_node_t *mem_params;
uintptr_t hw_config_base = 0;
@@ -264,10 +261,6 @@ void populate_next_bl_params_config(bl_params_t *bl2_to_next_bl_params)
mem_params = get_bl_mem_params_node(fw_config_id);
if (mem_params != NULL) {
fw_config_base = mem_params->image_info.image_base;
-#ifdef SPD_spmd
- fw_config_size =
- mem_params->image_info.image_size;
-#endif
}
}
@@ -306,11 +299,6 @@ void populate_next_bl_params_config(bl_params_t *bl2_to_next_bl_params)
if (params_node->ep_info->args.arg1 == 0U)
params_node->ep_info->args.arg1 =
hw_config_base;
-#ifdef SPD_spmd
- if (params_node->ep_info->args.arg2 == 0U)
- params_node->ep_info->args.arg2 =
- fw_config_size;
-#endif
}
#ifdef SPD_opteed
}
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index 946a3b8b83..b8ba14c572 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -290,8 +290,7 @@ int plat_spm_sp_get_next_address(void **sp_base, size_t *sp_size,
void **rd_base, size_t *rd_size);
#if defined(SPD_spmd)
int plat_spm_core_manifest_load(spmc_manifest_attribute_t *manifest,
- const void *ptr,
- size_t size);
+ const void *pm_addr);
#endif
/*******************************************************************************
* Mandatory BL image load functions(may be overridden).
diff --git a/plat/common/plat_spmd_manifest.c b/plat/common/plat_spmd_manifest.c
index a3e30e89cc..109b001f0b 100644
--- a/plat/common/plat_spmd_manifest.c
+++ b/plat/common/plat_spmd_manifest.c
@@ -11,6 +11,7 @@
#include <common/debug.h>
#include <common/fdt_wrappers.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
#include <platform_def.h>
#include <services/spm_core_manifest.h>
@@ -110,28 +111,75 @@ static int manifest_parse_root(spmc_manifest_attribute_t *manifest,
* Platform handler to parse a SPM Core manifest.
******************************************************************************/
int plat_spm_core_manifest_load(spmc_manifest_attribute_t *manifest,
- const void *ptr,
- size_t size)
+ const void *pm_addr)
{
- int rc;
+ int rc, unmap_ret;
+ uintptr_t pm_base, pm_base_align;
+ size_t mapped_size;
assert(manifest != NULL);
- assert(ptr != NULL);
+ assert(pm_addr != NULL);
+
+ /*
+ * Assume TOS_FW_CONFIG is not necessarily aligned to a page
+ * boundary, thus calculate the remaining space between SPMC
+ * manifest start address and upper page limit.
+ *
+ */
+ pm_base = (uintptr_t)pm_addr;
+ pm_base_align = page_align(pm_base, UP);
+ mapped_size = pm_base_align - pm_base;
+
+ /* Check space within the page at least maps the FDT header */
+ if (mapped_size < sizeof(struct fdt_header)) {
+ ERROR("Error while mapping SPM Core manifest.\n");
+ return -EINVAL;
+ }
- INFO("Reading SPM Core manifest at address %p\n", ptr);
+ /* Map first SPMC manifest page in the SPMD translation regime */
+ pm_base_align = page_align(pm_base, DOWN);
+ rc = mmap_add_dynamic_region((unsigned long long)pm_base_align,
+ pm_base_align,
+ PAGE_SIZE,
+ MT_RO_DATA);
+ if (rc != 0) {
+ ERROR("Error while mapping SPM Core manifest (%d).\n", rc);
+ return rc;
+ }
- rc = fdt_check_header(ptr);
+ rc = fdt_check_header(pm_addr);
if (rc != 0) {
ERROR("Wrong format for SPM Core manifest (%d).\n", rc);
- return rc;
+ goto exit_unmap;
}
- rc = fdt_node_offset_by_compatible(ptr, -1,
+ /* Check SPMC manifest fits within the upper mapped page boundary */
+ if (mapped_size < fdt_totalsize(pm_addr)) {
+ ERROR("SPM Core manifest too large.\n");
+ rc = -EINVAL;
+ goto exit_unmap;
+ }
+
+ VERBOSE("Reading SPM Core manifest at address %p\n", pm_addr);
+
+ rc = fdt_node_offset_by_compatible(pm_addr, -1,
"arm,spci-core-manifest-1.0");
if (rc < 0) {
ERROR("Unrecognized SPM Core manifest\n");
- return rc;
+ goto exit_unmap;
+ }
+
+ rc = manifest_parse_root(manifest, pm_addr, rc);
+
+exit_unmap:
+ unmap_ret = mmap_remove_dynamic_region(pm_base_align, PAGE_SIZE);
+ if (unmap_ret != 0) {
+ ERROR("Error while unmapping SPM Core manifest (%d).\n",
+ unmap_ret);
+ if (rc == 0) {
+ rc = unmap_ret;
+ }
}
- return manifest_parse_root(manifest, ptr, rc);
+ return rc;
}
diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c
index f6dbb97e37..501782ffbe 100644
--- a/services/std_svc/spmd/spmd_main.c
+++ b/services/std_svc/spmd/spmd_main.c
@@ -17,7 +17,6 @@
#include <lib/smccc.h>
#include <lib/spinlock.h>
#include <lib/utils.h>
-#include <lib/xlat_tables/xlat_tables_v2.h>
#include <plat/common/common_def.h>
#include <plat/common/platform.h>
#include <platform_def.h>
@@ -56,8 +55,7 @@ spmd_spm_core_context_t *spmd_get_context(void)
* Static function declaration.
******************************************************************************/
static int32_t spmd_init(void);
-static int spmd_spmc_init(void *rd_base,
- size_t rd_size);
+static int spmd_spmc_init(void *pm_addr);
static uint64_t spmd_spci_error_return(void *handle,
int error_code);
static uint64_t spmd_smc_forward(uint32_t smc_fid,
@@ -146,14 +144,14 @@ static int32_t spmd_init(void)
/*******************************************************************************
* Loads SPMC manifest and inits SPMC.
******************************************************************************/
-static int spmd_spmc_init(void *rd_base, size_t rd_size)
+static int spmd_spmc_init(void *pm_addr)
{
spmd_spm_core_context_t *spm_ctx = spmd_get_context();
uint32_t ep_attr;
int rc;
/* Load the SPM Core manifest */
- rc = plat_spm_core_manifest_load(&spmc_attrs, rd_base, rd_size);
+ rc = plat_spm_core_manifest_load(&spmc_attrs, pm_addr);
if (rc != 0) {
WARN("No or invalid SPM Core manifest image provided by BL2\n");
return rc;
@@ -170,7 +168,7 @@ static int spmd_spmc_init(void *rd_base, size_t rd_size)
return -EINVAL;
}
- VERBOSE("SPCI version (%u.%u).\n", spmc_attrs.major_version,
+ VERBOSE("SPCI version (%u.%u)\n", spmc_attrs.major_version,
spmc_attrs.minor_version);
VERBOSE("SPM Core run time EL%x.\n",
@@ -186,12 +184,13 @@ static int spmd_spmc_init(void *rd_base, size_t rd_size)
/* Validate the SPM Core execution state */
if ((spmc_attrs.exec_state != MODE_RW_64) &&
(spmc_attrs.exec_state != MODE_RW_32)) {
- WARN("Unsupported SPM Core execution state 0x%x.\n",
+ WARN("Unsupported %s%x.\n", "SPM Core execution state 0x",
spmc_attrs.exec_state);
return -EINVAL;
}
- VERBOSE("SPM Core execution state 0x%x.\n", spmc_attrs.exec_state);
+ VERBOSE("%s%x.\n", "SPM Core execution state 0x",
+ spmc_attrs.exec_state);
#if SPMD_SPM_AT_SEL2
/* Ensure manifest has not requested AArch32 state in S-EL2 */
@@ -260,11 +259,8 @@ static int spmd_spmc_init(void *rd_base, size_t rd_size)
******************************************************************************/
int spmd_setup(void)
{
+ void *spmc_manifest;
int rc;
- void *rd_base;
- size_t rd_size;
- uintptr_t rd_base_align;
- uintptr_t rd_size_align;
spmc_ep_info = bl31_plat_get_next_image_ep_info(SECURE);
if (spmc_ep_info == NULL) {
@@ -279,49 +275,19 @@ int spmd_setup(void)
* Check if BL32 ep_info has a reference to 'tos_fw_config'. This will
* be used as a manifest for the SPM Core at the next lower EL/mode.
*/
- if (spmc_ep_info->args.arg0 == 0U || spmc_ep_info->args.arg2 == 0U) {
- ERROR("Invalid or absent SPM core manifest\n");
- panic();
- }
-
- /* Obtain whereabouts of SPM Core manifest */
- rd_base = (void *) spmc_ep_info->args.arg0;
- rd_size = spmc_ep_info->args.arg2;
-
- rd_base_align = page_align((uintptr_t) rd_base, DOWN);
- rd_size_align = page_align((uintptr_t) rd_size, UP);
-
- /* Map the manifest in the SPMD translation regime first */
- VERBOSE("SPM core manifest base : 0x%lx\n", rd_base_align);
- VERBOSE("SPM core manifest size : 0x%lx\n", rd_size_align);
- rc = mmap_add_dynamic_region((unsigned long long) rd_base_align,
- (uintptr_t) rd_base_align,
- rd_size_align,
- MT_RO_DATA);
- if (rc != 0) {
- ERROR("Error while mapping SPM core manifest (%d).\n", rc);
- panic();
+ spmc_manifest = (void *)spmc_ep_info->args.arg0;
+ if (spmc_manifest == NULL) {
+ ERROR("Invalid or absent SPM Core manifest.\n");
+ return -EINVAL;
}
/* Load manifest, init SPMC */
- rc = spmd_spmc_init(rd_base, rd_size);
+ rc = spmd_spmc_init(spmc_manifest);
if (rc != 0) {
- int mmap_rc;
-
WARN("Booting device without SPM initialization.\n");
-
- mmap_rc = mmap_remove_dynamic_region(rd_base_align,
- rd_size_align);
- if (mmap_rc != 0) {
- ERROR("Error while unmapping SPM core manifest (%d).\n",
- mmap_rc);
- panic();
- }
-
- return rc;
}
- return 0;
+ return rc;
}
/*******************************************************************************