diff --git a/include/export/common/tbbr/tbbr_img_def_exp.h b/include/export/common/tbbr/tbbr_img_def_exp.h index ff0d16c..3602554 100644 --- a/include/export/common/tbbr/tbbr_img_def_exp.h +++ b/include/export/common/tbbr/tbbr_img_def_exp.h @@ -86,6 +86,11 @@ #define STM32_IMAGE_ID U(29) /* Define size of the array */ +#if defined(SPD_spmd) +#define MAX_SP_IDS U(8) +#define MAX_NUMBER_IDS MAX_SP_IDS + U(30) +#else #define MAX_NUMBER_IDS U(30) +#endif #endif /* ARM_TRUSTED_FIRMWARE_EXPORT_COMMON_TBBR_TBBR_IMG_DEF_EXP_H */ diff --git a/include/plat/arm/common/fconf_arm_sp_getter.h b/include/plat/arm/common/fconf_arm_sp_getter.h new file mode 100644 index 0000000..38c30fb --- /dev/null +++ b/include/plat/arm/common/fconf_arm_sp_getter.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef FCONF_ARM_SP_GETTER_H +#define FCONF_ARM_SP_GETTER_H + +#include +#include + +/* arm_sp getter */ +#define arm__sp_getter(prop) arm_sp.prop + +#define ARM_SP_MAX_SIZE U(0x10000) + +struct arm_sp_t { + unsigned int number_of_sp; + union uuid_helper_t uuids[MAX_SP_IDS]; + uintptr_t load_addr[MAX_SP_IDS]; +}; + +int fconf_populate_arm_sp(uintptr_t config); + +extern struct arm_sp_t arm_sp; + +extern bl_mem_params_node_t sp_mem_params_descs[MAX_SP_IDS]; + +#endif /* FCONF_ARM_SP_GETTER_H */ diff --git a/plat/arm/board/fvp/fdts/fvp_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_fw_config.dts index d0f6033..9a4a057 100644 --- a/plat/arm/board/fvp/fdts/fvp_fw_config.dts +++ b/plat/arm/board/fvp/fdts/fvp_fw_config.dts @@ -69,6 +69,12 @@ mbedtls_heap_size = <0x0>; }; + /* + * Though TF-A is UUID RFC 4122 compliant meaning fields are stored in + * network order (big endian), UUID's mentioned in this file are are + * stored in machine order (little endian). + * This will be fixed in future. + */ arm-io_policies { fip-handles { compatible = "arm,io-fip-handle"; @@ -93,4 +99,17 @@ nt_fw_content_cert_uuid = <0xf3c1c48e 0x11e4635d 0xee87a9a7 0xa73fb240>; }; }; + + secure-partitions { + compatible = "arm,sp"; + cactus { + uuid = <0x1e67b5b4 0xe14f904a 0x13fb1fb8 0xcbdae1da>; + load-address = <0x7000000>; + }; + + ivy { + uuid = <0x092358d1 0xb94723f0 0x64447c82 0xc88f57f5>; + load-address = <0x7100000>; + }; + }; }; diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c index dd39208..136e65a 100644 --- a/plat/arm/common/arm_bl2_setup.c +++ b/plat/arm/common/arm_bl2_setup.c @@ -205,6 +205,13 @@ ******************************************************************************/ int arm_bl2_plat_handle_post_image_load(unsigned int image_id) { +#if defined(SPD_spmd) + /* For Secure Partitions we don't need post processing */ + if ((image_id >= (MAX_NUMBER_IDS - MAX_SP_IDS)) && + (image_id < MAX_NUMBER_IDS)) { + return 0; + } +#endif return arm_bl2_handle_post_image_load(image_id); } diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index 17058d1..4fb85fb 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -182,6 +182,9 @@ else ARM_IO_SOURCES += plat/arm/common/arm_fconf_io_storage.c \ plat/arm/common/fconf/arm_fconf_io.c +ifeq (${SPD},spmd) +ARM_IO_SOURCES += plat/arm/common/fconf/arm_fconf_sp.c +endif endif BL1_SOURCES += drivers/io/io_fip.c \ diff --git a/plat/arm/common/arm_image_load.c b/plat/arm/common/arm_image_load.c index 2faaa76..593199d 100644 --- a/plat/arm/common/arm_image_load.c +++ b/plat/arm/common/arm_image_load.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,6 +7,9 @@ #include #include #include +#if defined(SPD_spmd) +#include +#endif #include #include @@ -29,12 +32,62 @@ next_bl_params_cpy_ptr); } +#if defined(SPD_spmd) +/******************************************************************************* + * This function appends Secure Partitions to list of loadable images. + ******************************************************************************/ +void plat_add_sp_images_load_info(struct bl_load_info *load_info) +{ + bl_load_info_node_t *node_info = load_info->head; + unsigned int index = 0; + + if (sp_mem_params_descs[index].image_id == 0) { + ERROR("No Secure Partition Image available\n"); + return; + } + + /* Traverse through the bl images list */ + do { + node_info = node_info->next_load_info; + } while (node_info->next_load_info != NULL); + + for (; index < MAX_SP_IDS; index++) { + /* Populate the image information */ + node_info->image_id = sp_mem_params_descs[index].image_id; + node_info->image_info = &sp_mem_params_descs[index].image_info; + + if ((index + 1U) == MAX_SP_IDS) { + INFO("Reached Max number of SPs\n"); + return; + } + + if (sp_mem_params_descs[index + 1U].image_id == 0) { + return; + } + + node_info->next_load_info = + &sp_mem_params_descs[index + 1U].load_node_mem; + node_info = node_info->next_load_info; + + } +} +#endif + /******************************************************************************* * This function returns the list of loadable images. ******************************************************************************/ struct bl_load_info *plat_get_bl_image_load_info(void) { +#if defined(SPD_spmd) + bl_load_info_t *bl_load_info; + + bl_load_info = get_bl_load_info_from_mem_params_desc(); + plat_add_sp_images_load_info(bl_load_info); + + return bl_load_info; +#else return get_bl_load_info_from_mem_params_desc(); +#endif } /******************************************************************************* diff --git a/plat/arm/common/fconf/arm_fconf_sp.c b/plat/arm/common/fconf/arm_fconf_sp.c new file mode 100644 index 0000000..bb88aff --- /dev/null +++ b/plat/arm/common/fconf/arm_fconf_sp.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef IMAGE_BL2 + +bl_mem_params_node_t sp_mem_params_descs[MAX_SP_IDS]; + +struct arm_sp_t arm_sp; + +int fconf_populate_arm_sp(uintptr_t config) +{ + int sp_node, node, err; + union uuid_helper_t uuid_helper; + unsigned int index = 0; + const unsigned int sp_start_index = MAX_NUMBER_IDS - MAX_SP_IDS; + + /* As libfdt use void *, we can't avoid this cast */ + const void *dtb = (void *)config; + + /* Assert the node offset point to "arm,sp" compatible property */ + const char *compatible_str = "arm,sp"; + + node = fdt_node_offset_by_compatible(dtb, -1, compatible_str); + if (node < 0) { + ERROR("FCONF: Can't find %s in dtb\n", compatible_str); + return node; + } + + fdt_for_each_subnode(sp_node, dtb, node) { + err = fdtw_read_array(dtb, sp_node, "uuid", 4, + &uuid_helper.word); + if (err < 0) { + ERROR("FCONF: cannot read SP uuid\n"); + return -1; + } + + arm_sp.uuids[index] = uuid_helper; + + err = fdtw_read_cells(dtb, sp_node, "load-address", 1, + &arm_sp.load_addr[index]); + if (err < 0) { + ERROR("FCONF: cannot read SP load address\n"); + return -1; + } + + VERBOSE("FCONF: %s UUID %x-%x-%x-%x load_addr=%lx\n", + __func__, + uuid_helper.word[0], + uuid_helper.word[1], + uuid_helper.word[2], + uuid_helper.word[3], + arm_sp.load_addr[index]); + + /* Add SP information in mem param descriptor */ + sp_mem_params_descs[index].image_id = sp_start_index + index; + SET_PARAM_HEAD(&sp_mem_params_descs[index].image_info, + PARAM_IMAGE_BINARY, VERSION_2, 0); + sp_mem_params_descs[index].image_info.image_max_size = + ARM_SP_MAX_SIZE; + sp_mem_params_descs[index].next_handoff_image_id = + INVALID_IMAGE_ID; + sp_mem_params_descs[index].image_info.image_base = + arm_sp.load_addr[index]; + + /* Add SP information in IO policies structure */ + policies[sp_start_index + index].image_spec = + (uintptr_t)&arm_sp.uuids[index]; + policies[sp_start_index + index].dev_handle = &fip_dev_handle; + policies[sp_start_index + index].check = open_fip; + + index++; + + if (index >= MAX_SP_IDS) { + ERROR("FCONF: reached max number of SPs\n"); + return -1; + } + } + + if ((sp_node < 0) && (sp_node != -FDT_ERR_NOTFOUND)) { + ERROR("%d: fdt_for_each_subnode(): %d\n", __LINE__, node); + return sp_node; + } + + arm_sp.number_of_sp = index; + return 0; +} + +FCONF_REGISTER_POPULATOR(arm_sp, fconf_populate_arm_sp); + +#endif /* IMAGE_BL2 */