aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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;
}
/*******************************************************************************