diff --git a/common/desc_image_load.c b/common/desc_image_load.c index 47c80aa..30b97e0 100644 --- a/common/desc_image_load.c +++ b/common/desc_image_load.c @@ -214,9 +214,6 @@ { 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 @@ 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 @@ 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 946a3b8..b8ba14c 100644 --- a/include/plat/common/platform.h +++ b/include/plat/common/platform.h @@ -290,8 +290,7 @@ 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 a3e30e8..109b001 100644 --- a/plat/common/plat_spmd_manifest.c +++ b/plat/common/plat_spmd_manifest.c @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -110,28 +111,75 @@ * 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); - INFO("Reading SPM Core manifest at address %p\n", ptr); + /* + * 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; - rc = fdt_check_header(ptr); + /* 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; + } + + /* 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("Wrong format for SPM Core manifest (%d).\n", rc); + ERROR("Error while mapping SPM Core manifest (%d).\n", rc); return rc; } - rc = fdt_node_offset_by_compatible(ptr, -1, + rc = fdt_check_header(pm_addr); + if (rc != 0) { + ERROR("Wrong format for SPM Core manifest (%d).\n", rc); + goto exit_unmap; + } + + /* 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; } - return manifest_parse_root(manifest, ptr, rc); + 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 rc; } diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c index f6dbb97..501782f 100644 --- a/services/std_svc/spmd/spmd_main.c +++ b/services/std_svc/spmd/spmd_main.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -56,8 +55,7 @@ * 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 @@ /******************************************************************************* * 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 @@ 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 @@ /* 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 @@ ******************************************************************************/ 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 @@ * 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; } /*******************************************************************************