diff --git a/common/desc_image_load.c b/common/desc_image_load.c index f2e8f60..c8dd403 100644 --- a/common/desc_image_load.c +++ b/common/desc_image_load.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -215,6 +215,9 @@ bl_params_node_t *params_node; unsigned int fw_config_id; uintptr_t hw_config_base = 0, fw_config_base; +#if defined(SPD_spmd) + uint32_t fw_config_size = 0; +#endif bl_mem_params_node_t *mem_params; assert(bl2_to_next_bl_params != NULL); @@ -249,10 +252,14 @@ if (fw_config_id != INVALID_IMAGE_ID) { mem_params = get_bl_mem_params_node(fw_config_id); - if (mem_params != NULL) + if (mem_params != NULL) { fw_config_base = mem_params->image_info.image_base; +#if defined(SPD_spmd) + fw_config_size = + mem_params->image_info.image_size; +#endif + } } - /* * Pass hw and tb_fw config addresses to next images. NOTE - for * EL3 runtime images (BL31 for AArch64 and BL32 for AArch32), @@ -273,6 +280,11 @@ if (params_node->ep_info->args.arg1 == 0U) params_node->ep_info->args.arg1 = hw_config_base; +#if defined(SPD_spmd) + if (params_node->ep_info->args.arg2 == 0U) + params_node->ep_info->args.arg2 = + fw_config_size; +#endif } } } diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h index 332cfca..f5bd298 100644 --- a/include/plat/common/platform.h +++ b/include/plat/common/platform.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -10,6 +10,9 @@ #include #include +#if defined(SPD_spmd) + #include +#endif /******************************************************************************* * Forward declarations @@ -272,7 +275,11 @@ int plat_spm_sp_rd_load(struct sp_res_desc *rd, const void *ptr, size_t size); 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_sect_attribute_t *manifest, + const void *ptr, + size_t size); +#endif /******************************************************************************* * Mandatory BL image load functions(may be overridden). ******************************************************************************/ diff --git a/include/services/spm_core_manifest.h b/include/services/spm_core_manifest.h new file mode 100644 index 0000000..06ecc13 --- /dev/null +++ b/include/services/spm_core_manifest.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SPMC_MANIFEST_H +#define SPMC_MANIFEST_H + +#include + +/******************************************************************************* + * Attribute Section + ******************************************************************************/ + +typedef struct spm_core_manifest_sect_attribute { + /* + * SPCI version (mandatory). + */ + uint32_t major_version; + uint32_t minor_version; + + /* + * Run-Time Exception Level (mandatory): + * - 1: SEL1 + * - 2: SEL2 + */ + uint32_t runtime_el; + + /* + * Run-Time Execution state (optional): + * - 0: AArch64 (default) + * - 1: AArch32 + */ + uint32_t exec_state; + + /* + * Address of binary image containing SPM core in bytes (optional). + */ + uint64_t load_address; + + /* + * Offset from the base of the partition's binary image to the entry + * point of the partition. + */ + uint64_t entrypoint; + + /* + * Size of binary image containing SPM core in bytes (mandatory). + */ + uint32_t binary_size; + +} spmc_manifest_sect_attribute_t; + +#endif /* SPMC_MANIFEST_H */ diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts new file mode 100644 index 0000000..e1c106f --- /dev/null +++ b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +/dts-v1/; + +/ { + compatible = "spci-core-manifest-1.0"; + + attribute { + maj_ver = <0x0>; + min_ver = <0x9>; + runtime_el = <0x1>; + exec_state = <0x0>; + load_address = <0x0 0x6000000>; + entrypoint = <0x0 0x6000000>; + }; +}; diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 97a326c..dcc55d8 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -224,6 +224,14 @@ $(eval $(call TOOL_ADD_PAYLOAD,${FVP_TOS_FW_CONFIG},--tos-fw-config)) endif +ifeq (${SPD},spmd) +FDT_SOURCES += plat/arm/board/fvp/fdts/${PLAT}_spmc_manifest.dts +FVP_TOS_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_spmc_manifest.dtb + +# Add the TOS_FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TOS_FW_CONFIG},--tos-fw-config)) +endif + # Add the TB_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config)) # Add the SOC_FW_CONFIG to FIP and specify the same to certtool diff --git a/plat/arm/common/arm_dyn_cfg.c b/plat/arm/common/arm_dyn_cfg.c index e6c5a73..fdc3ef3 100644 --- a/plat/arm/common/arm_dyn_cfg.c +++ b/plat/arm/common/arm_dyn_cfg.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -197,8 +197,8 @@ HW_CONFIG_ID, SOC_FW_CONFIG_ID, NT_FW_CONFIG_ID, -#ifdef SPD_tspd - /* Currently tos_fw_config is only present for TSP */ +#if defined(SPD_tspd) || defined(SPD_spmd) + /* tos_fw_config is only present for TSPD/SPMD */ TOS_FW_CONFIG_ID #endif }; diff --git a/plat/common/plat_spmd_manifest.c b/plat/common/plat_spmd_manifest.c new file mode 100644 index 0000000..4c78979 --- /dev/null +++ b/plat/common/plat_spmd_manifest.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +/******************************************************************************* + * Attribute section handler + ******************************************************************************/ +static int manifest_parse_attribute(spmc_manifest_sect_attribute_t *attr, + const void *fdt, + int node) +{ + int rc = 0; + + assert(attr && fdt); + + rc = fdtw_read_cells(fdt, node, "maj_ver", 1, &attr->major_version); + if (rc) { + ERROR("Missing SPCI major version in SPM core manifest.\n"); + return -ENOENT; + } + + rc = fdtw_read_cells(fdt, node, "min_ver", 1, &attr->minor_version); + if (rc) { + ERROR("Missing SPCI minor version in SPM core manifest.\n"); + return -ENOENT; + } + + rc = fdtw_read_cells(fdt, node, "runtime_el", 1, &attr->runtime_el); + if (rc) { + ERROR("Missing SPM core runtime EL in manifest.\n"); + return -ENOENT; + } + + rc = fdtw_read_cells(fdt, node, "exec_state", 1, &attr->exec_state); + if (rc) + NOTICE("Execution state not specified in SPM core manifest.\n"); + + rc = fdtw_read_cells(fdt, node, "binary_size", 1, &attr->binary_size); + if (rc) + NOTICE("Binary size not specified in SPM core manifest.\n"); + + rc = fdtw_read_cells(fdt, node, "load_address", 2, &attr->load_address); + if (rc) + NOTICE("Load address not specified in SPM core manifest.\n"); + + rc = fdtw_read_cells(fdt, node, "entrypoint", 2, &attr->entrypoint); + if (rc) + NOTICE("Entrypoint not specified in SPM core manifest.\n"); + + VERBOSE("SPM core manifest attribute section:\n"); + VERBOSE(" version: %x.%x\n", attr->major_version, attr->minor_version); + VERBOSE(" runtime_el: 0x%x\n", attr->runtime_el); + VERBOSE(" binary_size: 0x%x\n", attr->binary_size); + VERBOSE(" load_address: 0x%llx\n", attr->load_address); + VERBOSE(" entrypoint: 0x%llx\n", attr->entrypoint); + + return 0; +} + +/******************************************************************************* + * Root node handler + ******************************************************************************/ +static int manifest_parse_root(spmc_manifest_sect_attribute_t *manifest, + const void *fdt, + int root) +{ + int node; + char *str; + + str = "attribute"; + node = fdt_subnode_offset_namelen(fdt, root, str, strlen(str)); + if (node < 0) { + ERROR("Root node doesn't contain subnode '%s'\n", str); + return -ENOENT; + } + + return manifest_parse_attribute(manifest, fdt, node); +} + +/******************************************************************************* + * Platform handler to parse a SPM core manifest. + ******************************************************************************/ +int plat_spm_core_manifest_load(spmc_manifest_sect_attribute_t *manifest, + const void *ptr, + size_t size) +{ + int rc; + int root_node; + + assert(manifest != NULL); + assert(ptr != NULL); + + INFO("Reading SPM core manifest at address %p\n", ptr); + + rc = fdt_check_header(ptr); + if (rc != 0) { + ERROR("Wrong format for SPM core manifest (%d).\n", rc); + return -EINVAL; + } + + INFO("Reading SPM core manifest at address %p\n", ptr); + + root_node = fdt_node_offset_by_compatible(ptr, -1, + "arm,spci-core-manifest-1.0"); + if (root_node < 0) { + ERROR("Unrecognized SPM core manifest\n"); + return -ENOENT; + } + + INFO("Reading SPM core manifest at address %p\n", ptr); + return manifest_parse_root(manifest, ptr, root_node); +}