From ab1981db9ea793accf1279446b9f7666a3be04ca Mon Sep 17 00:00:00 2001 From: Louis Mayencourt Date: Thu, 8 Aug 2019 12:03:26 +0100 Subject: [PATCH 01/10] fconf: initial commit Introduce the Firmware CONfiguration Framework (fconf). The fconf is an abstraction layer for platform specific data, allowing a "property" to be queried and a value retrieved without the requesting entity knowing what backing store is being used to hold the data. The default backing store used is C structure. If another backing store has to be used, the platform integrator needs to provide a "populate()" function to fill the corresponding C structure. The "populate()" function must be registered to the fconf framework with the "FCONF_REGISTER_POPULATOR()". This ensures that the function would be called inside the "fconf_populate()" function. A two level macro is used as getter: - the first macro takes 3 parameters and converts it to a function call: FCONF_GET_PROPERTY(a,b,c) -> a__b_getter(c). - the second level defines a__b_getter(c) to the matching C structure, variable, array, function, etc.. Ex: Get a Chain of trust property: 1) FCONF_GET_PROPERY(tbbr, cot, BL2_id) -> tbbr__cot_getter(BL2_id) 2) tbbr__cot_getter(BL2_id) -> cot_desc_ptr[BL2_id] Change-Id: Id394001353ed295bc680c3f543af0cf8da549469 Signed-off-by: Louis Mayencourt --- bl2/bl2.ld.S | 12 ++++++- drivers/auth/auth_mod.c | 8 ++--- include/lib/fconf/fconf.h | 47 +++++++++++++++++++++++++++ include/lib/fconf/fconf_tbbr_getter.h | 15 +++++++++ lib/fconf/fconf.c | 40 +++++++++++++++++++++++ lib/fconf/fconf.mk | 11 +++++++ plat/arm/common/arm_common.mk | 5 ++- 7 files changed, 132 insertions(+), 6 deletions(-) create mode 100644 include/lib/fconf/fconf.h create mode 100644 include/lib/fconf/fconf_tbbr_getter.h create mode 100644 lib/fconf/fconf.c create mode 100644 lib/fconf/fconf.mk diff --git a/bl2/bl2.ld.S b/bl2/bl2.ld.S index 6230562ed..c1338e22d 100644 --- a/bl2/bl2.ld.S +++ b/bl2/bl2.ld.S @@ -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 */ @@ -46,6 +46,11 @@ SECTIONS __RODATA_START__ = .; *(SORT_BY_ALIGNMENT(.rodata*)) + . = ALIGN(8); + __FCONF_POPULATOR_START__ = .; + KEEP(*(.fconf_populator)) + __FCONF_POPULATOR_END__ = .; + /* Ensure 8-byte alignment for descriptors and ensure inclusion */ . = ALIGN(8); __PARSER_LIB_DESCS_START__ = .; @@ -62,6 +67,11 @@ SECTIONS *(SORT_BY_ALIGNMENT(.text*)) *(SORT_BY_ALIGNMENT(.rodata*)) + . = ALIGN(8); + __FCONF_POPULATOR_START__ = .; + KEEP(*(.fconf_populator)) + __FCONF_POPULATOR_END__ = .; + /* Ensure 8-byte alignment for descriptors and ensure inclusion */ . = ALIGN(8); __PARSER_LIB_DESCS_START__ = .; diff --git a/drivers/auth/auth_mod.c b/drivers/auth/auth_mod.c index 3fb2d1a48..91ee1bea9 100644 --- a/drivers/auth/auth_mod.c +++ b/drivers/auth/auth_mod.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -16,6 +16,7 @@ #include #include #include +#include #include /* ASN.1 tags */ @@ -302,9 +303,8 @@ int auth_mod_get_parent_id(unsigned int img_id, unsigned int *parent_id) const auth_img_desc_t *img_desc = NULL; assert(parent_id != NULL); - /* Get the image descriptor */ - img_desc = cot_desc_ptr[img_id]; + img_desc = FCONF_GET_PROPERTY(tbbr, cot, img_id); /* Check if the image has no parent (ROT) */ if (img_desc->parent == NULL) { @@ -353,7 +353,7 @@ int auth_mod_verify_img(unsigned int img_id, int rc, i; /* Get the image descriptor from the chain of trust */ - img_desc = cot_desc_ptr[img_id]; + img_desc = FCONF_GET_PROPERTY(tbbr, cot, img_id); /* Ask the parser to check the image integrity */ rc = img_parser_check_integrity(img_desc->img_type, img_ptr, img_len); diff --git a/include/lib/fconf/fconf.h b/include/lib/fconf/fconf.h new file mode 100644 index 000000000..c5f10d267 --- /dev/null +++ b/include/lib/fconf/fconf.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2019-2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef FCONF_H +#define FCONF_H + +#include + +/* Public API */ +#define FCONF_GET_PROPERTY(a, b, c) a##__##b##_getter(c) + +#define FCONF_REGISTER_POPULATOR(name, callback) \ + __attribute__((used, section(".fconf_populator"))) \ + const struct fconf_populator name##__populator = { \ + .info = #name, \ + .populate = callback \ + }; + +/* + * Populator callback + * + * This structure are used by the fconf_populate function and should only be + * defined by the FCONF_REGISTER_POPULATOR macro. + */ +struct fconf_populator { + /* Description of the data loaded by the callback */ + const char *info; + + /* Callback used by fconf_populate function with a provided config dtb. + * Return 0 on success, err_code < 0 otherwise. + */ + int (*populate)(uintptr_t config); +}; + +/* Top level populate function + * + * This function takes a configuration dtb and calls all the registered + * populator callback with it. + * + * Panic on error. + */ +void fconf_populate(uintptr_t config); + +#endif /* FCONF_H */ diff --git a/include/lib/fconf/fconf_tbbr_getter.h b/include/lib/fconf/fconf_tbbr_getter.h new file mode 100644 index 000000000..fb81e7bea --- /dev/null +++ b/include/lib/fconf/fconf_tbbr_getter.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2019-2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef FCONF_TBBR_GETTER_H +#define FCONF_TBBR_GETTER_H + +#include + +/* TBBR related getter */ +#define tbbr__cot_getter(id) cot_desc_ptr[id] + +#endif /* FCONF_TBBR_GETTER_H */ diff --git a/lib/fconf/fconf.c b/lib/fconf/fconf.c new file mode 100644 index 000000000..387e758d2 --- /dev/null +++ b/lib/fconf/fconf.c @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2019-2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include + +void fconf_populate(uintptr_t config) +{ + assert(config != 0UL); + + /* Check if the pointer to DTB is correct */ + if (fdt_check_header((void *)config) != 0) { + ERROR("FCONF: Invalid DTB file passed for FW_CONFIG\n"); + panic(); + } + + INFO("FCONF: Reading firmware configuration file from: 0x%lx\n", config); + + /* Go through all registered populate functions */ + IMPORT_SYM(struct fconf_populator *, __FCONF_POPULATOR_START__, start); + IMPORT_SYM(struct fconf_populator *, __FCONF_POPULATOR_END__, end); + const struct fconf_populator *populator; + + for (populator = start; populator != end; populator++) { + assert((populator->info != NULL) && (populator->populate != NULL)); + + INFO("FCONF: Reading firmware configuration information for: %s\n", populator->info); + if (populator->populate(config) != 0) { + /* TODO: handle property miss */ + panic(); + } + } +} diff --git a/lib/fconf/fconf.mk b/lib/fconf/fconf.mk new file mode 100644 index 000000000..0813c73cc --- /dev/null +++ b/lib/fconf/fconf.mk @@ -0,0 +1,11 @@ +# +# Copyright (c) 2019-2020, ARM Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# Add Firmware Configuration files +FCONF_SOURCES := lib/fconf/fconf.c + +BL1_SOURCES += ${FCONF_SOURCES} +BL2_SOURCES += ${FCONF_SOURCES} diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index 9f4bc2107..abf2f914e 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -198,6 +198,9 @@ BL2_SOURCES += drivers/delay_timer/delay_timer.c \ plat/arm/common/arm_err.c \ plat/arm/common/arm_io_storage.c +# Firmware Configuration Framework sources +include lib/fconf/fconf.mk + # Add `libfdt` and Arm common helpers required for Dynamic Config include lib/libfdt/libfdt.mk @@ -270,7 +273,7 @@ ifneq (${TRUSTED_BOARD_BOOT},0) # Include common TBB sources AUTH_SOURCES := drivers/auth/auth_mod.c \ drivers/auth/crypto_mod.c \ - drivers/auth/img_parser_mod.c \ + drivers/auth/img_parser_mod.c # Include the selected chain of trust sources. ifeq (${COT},tbbr) From 3b5ea741fd92088c9e005d3508b73e50f1d5daf7 Mon Sep 17 00:00:00 2001 From: Louis Mayencourt Date: Thu, 17 Oct 2019 14:46:51 +0100 Subject: [PATCH 02/10] fconf: Load config dtb from bl1 Move the loading of the dtb from arm_dym_cfg to fconf. The new loading function is not associated to arm platform anymore, and can be moved to bl_main if wanted. Change-Id: I847d07eaba36d31d9d3ed9eba8e58666ea1ba563 Signed-off-by: Louis Mayencourt --- include/lib/fconf/fconf.h | 3 ++ include/plat/arm/common/plat_arm.h | 1 - lib/fconf/fconf.c | 39 ++++++++++++++++++++ plat/arm/board/a5ds/platform.mk | 5 ++- plat/arm/board/fvp_ve/platform.mk | 5 ++- plat/arm/common/arm_bl1_setup.c | 8 +++- plat/arm/common/arm_dyn_cfg.c | 59 +----------------------------- 7 files changed, 57 insertions(+), 63 deletions(-) diff --git a/include/lib/fconf/fconf.h b/include/lib/fconf/fconf.h index c5f10d267..5a5837f45 100644 --- a/include/lib/fconf/fconf.h +++ b/include/lib/fconf/fconf.h @@ -35,6 +35,9 @@ struct fconf_populator { int (*populate)(uintptr_t config); }; +/* Load firmware configuration dtb */ +void fconf_load_config(void); + /* Top level populate function * * This function takes a configuration dtb and calls all the registered diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index 32dc9f93d..ec0f37988 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -225,7 +225,6 @@ void arm_sp_min_plat_runtime_setup(void); int arm_io_is_toc_valid(void); /* Utility functions for Dynamic Config */ -void arm_load_tb_fw_config(void); void arm_bl2_set_tb_cfg_addr(void *dtb); void arm_bl2_dyn_cfg_init(void); void arm_bl1_set_mbedtls_heap(void); diff --git a/lib/fconf/fconf.c b/lib/fconf/fconf.c index 387e758d2..7e0b00b08 100644 --- a/lib/fconf/fconf.c +++ b/lib/fconf/fconf.c @@ -9,8 +9,47 @@ #include #include #include +#include #include +static uintptr_t tb_fw_cfg_dtb; +static size_t tb_fw_cfg_dtb_size; + +void fconf_load_config(void) +{ + int err; + image_desc_t *desc; + + image_info_t arm_tb_fw_info = { + .h.type = (uint8_t)PARAM_IMAGE_BINARY, + .h.version = (uint8_t)VERSION_2, + .h.size = (uint16_t)sizeof(image_info_t), + .h.attr = 0, + .image_base = ARM_TB_FW_CONFIG_BASE, + .image_max_size = (uint32_t) + (ARM_TB_FW_CONFIG_LIMIT - ARM_TB_FW_CONFIG_BASE) + }; + + VERBOSE("FCONF: Loading FW_CONFIG\n"); + err = load_auth_image(TB_FW_CONFIG_ID, &arm_tb_fw_info); + if (err != 0) { + /* Return if FW_CONFIG is not loaded */ + VERBOSE("Failed to load FW_CONFIG\n"); + return; + } + + /* At this point we know that a DTB is indeed available */ + tb_fw_cfg_dtb = arm_tb_fw_info.image_base; + tb_fw_cfg_dtb_size = (size_t)arm_tb_fw_info.image_size; + + /* The BL2 ep_info arg0 is modified to point to FW_CONFIG */ + desc = bl1_plat_get_image_desc(BL2_IMAGE_ID); + assert(desc != NULL); + desc->ep_info.args.arg0 = tb_fw_cfg_dtb; + + INFO("FCONF: FW_CONFIG loaded at address = 0x%lx\n", tb_fw_cfg_dtb); +} + void fconf_populate(uintptr_t config) { assert(config != 0UL); diff --git a/plat/arm/board/a5ds/platform.mk b/plat/arm/board/a5ds/platform.mk index d42b2bfa8..ac3973ae0 100644 --- a/plat/arm/board/a5ds/platform.mk +++ b/plat/arm/board/a5ds/platform.mk @@ -1,9 +1,12 @@ # -# Copyright (c) 2019, Arm Limited. All rights reserved. +# Copyright (c) 2019-2020, Arm Limited. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # +# Firmware Configuration Framework sources +include lib/fconf/fconf.mk + # Add `libfdt` and Arm common helpers required for Dynamic Config include lib/libfdt/libfdt.mk diff --git a/plat/arm/board/fvp_ve/platform.mk b/plat/arm/board/fvp_ve/platform.mk index 4d21f4ba0..51c03151d 100644 --- a/plat/arm/board/fvp_ve/platform.mk +++ b/plat/arm/board/fvp_ve/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2019, Arm Limited. All rights reserved. +# Copyright (c) 2019-2020, Arm Limited. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -116,6 +116,9 @@ else PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS} endif +# Firmware Configuration Framework sources +include lib/fconf/fconf.mk + # Add `libfdt` and Arm common helpers required for Dynamic Config include lib/libfdt/libfdt.mk diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c index b19a7c39c..bf4d7bd5c 100644 --- a/plat/arm/common/arm_bl1_setup.c +++ b/plat/arm/common/arm_bl1_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -143,7 +144,10 @@ void arm_bl1_platform_setup(void) { /* Initialise the IO layer and register platform IO devices */ plat_arm_io_setup(); - arm_load_tb_fw_config(); + + /* Load fw config */ + fconf_load_config(); + #if TRUSTED_BOARD_BOOT /* Share the Mbed TLS heap info with other images */ arm_bl1_set_mbedtls_heap(); diff --git a/plat/arm/common/arm_dyn_cfg.c b/plat/arm/common/arm_dyn_cfg.c index e6c5a7361..fa251c8ce 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 */ @@ -115,63 +115,6 @@ void arm_bl1_set_mbedtls_heap(void) #endif /* TRUSTED_BOARD_BOOT */ -/* - * Helper function to load TB_FW_CONFIG and populate the load information to - * arg0 of BL2 entrypoint info. - */ -void arm_load_tb_fw_config(void) -{ - int err; - uintptr_t config_base = 0UL; - image_desc_t *desc; - - image_desc_t arm_tb_fw_info = { - .image_id = TB_FW_CONFIG_ID, - SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY, - VERSION_2, image_info_t, 0), - .image_info.image_base = ARM_TB_FW_CONFIG_BASE, - .image_info.image_max_size = - ARM_TB_FW_CONFIG_LIMIT - ARM_TB_FW_CONFIG_BASE - }; - - VERBOSE("BL1: Loading TB_FW_CONFIG\n"); - err = load_auth_image(TB_FW_CONFIG_ID, &arm_tb_fw_info.image_info); - if (err != 0) { - /* Return if TB_FW_CONFIG is not loaded */ - VERBOSE("Failed to load TB_FW_CONFIG\n"); - return; - } - - /* At this point we know that a DTB is indeed available */ - config_base = arm_tb_fw_info.image_info.image_base; - tb_fw_cfg_dtb = (void *)config_base; - - /* The BL2 ep_info arg0 is modified to point to TB_FW_CONFIG */ - desc = bl1_plat_get_image_desc(BL2_IMAGE_ID); - assert(desc != NULL); - desc->ep_info.args.arg0 = config_base; - - INFO("BL1: TB_FW_CONFIG loaded at address = 0x%lx\n", config_base); - -#if TRUSTED_BOARD_BOOT && defined(DYN_DISABLE_AUTH) - int tb_fw_node; - uint32_t disable_auth = 0; - - err = arm_dyn_tb_fw_cfg_init((void *)config_base, &tb_fw_node); - if (err < 0) { - ERROR("Invalid TB_FW_CONFIG loaded\n"); - panic(); - } - - err = arm_dyn_get_disable_auth((void *)config_base, tb_fw_node, &disable_auth); - if (err < 0) - return; - - if (disable_auth == 1) - dyn_disable_auth(); -#endif -} - /* * BL2 utility function to set the address of TB_FW_CONFIG passed from BL1. */ From 9814bfc1bfc4868a8505d3756aceea5ad41a8c64 Mon Sep 17 00:00:00 2001 From: Louis Mayencourt Date: Thu, 17 Oct 2019 15:14:25 +0100 Subject: [PATCH 03/10] fconf: Populate properties from dtb during bl2 setup Use the dtb provided by bl1 as configuration file for fconf. Change-Id: I3f466ad9b7047e1a361d94e71ac6d693e31496d9 Signed-off-by: Louis Mayencourt --- include/lib/fconf/fconf.h | 11 +++++++++++ lib/fconf/fconf.c | 22 ++++++++++++++-------- plat/arm/common/arm_bl2_setup.c | 11 +++++++---- 3 files changed, 32 insertions(+), 12 deletions(-) diff --git a/include/lib/fconf/fconf.h b/include/lib/fconf/fconf.h index 5a5837f45..f58ff5710 100644 --- a/include/lib/fconf/fconf.h +++ b/include/lib/fconf/fconf.h @@ -47,4 +47,15 @@ void fconf_load_config(void); */ void fconf_populate(uintptr_t config); +/* FCONF specific getter */ +#define fconf__dtb_getter(prop) fconf_dtb_info.prop + +/* Structure used to locally keep a reference to the config dtb. */ +struct fconf_dtb_info_t { + uintptr_t base_addr; + size_t size; +}; + +extern struct fconf_dtb_info_t fconf_dtb_info; + #endif /* FCONF_H */ diff --git a/lib/fconf/fconf.c b/lib/fconf/fconf.c index 7e0b00b08..2ca1bdc77 100644 --- a/lib/fconf/fconf.c +++ b/lib/fconf/fconf.c @@ -7,18 +7,17 @@ #include #include +#include #include #include #include #include -static uintptr_t tb_fw_cfg_dtb; -static size_t tb_fw_cfg_dtb_size; +struct fconf_dtb_info_t fconf_dtb_info; void fconf_load_config(void) { int err; - image_desc_t *desc; image_info_t arm_tb_fw_info = { .h.type = (uint8_t)PARAM_IMAGE_BINARY, @@ -27,7 +26,7 @@ void fconf_load_config(void) .h.attr = 0, .image_base = ARM_TB_FW_CONFIG_BASE, .image_max_size = (uint32_t) - (ARM_TB_FW_CONFIG_LIMIT - ARM_TB_FW_CONFIG_BASE) + (ARM_TB_FW_CONFIG_LIMIT - ARM_TB_FW_CONFIG_BASE) }; VERBOSE("FCONF: Loading FW_CONFIG\n"); @@ -39,15 +38,19 @@ void fconf_load_config(void) } /* At this point we know that a DTB is indeed available */ - tb_fw_cfg_dtb = arm_tb_fw_info.image_base; - tb_fw_cfg_dtb_size = (size_t)arm_tb_fw_info.image_size; + fconf_dtb_info.base_addr = arm_tb_fw_info.image_base; + fconf_dtb_info.size = (size_t)arm_tb_fw_info.image_size; + +#if !BL2_AT_EL3 + image_desc_t *desc; /* The BL2 ep_info arg0 is modified to point to FW_CONFIG */ desc = bl1_plat_get_image_desc(BL2_IMAGE_ID); assert(desc != NULL); - desc->ep_info.args.arg0 = tb_fw_cfg_dtb; + desc->ep_info.args.arg0 = arm_tb_fw_info.image_base; +#endif - INFO("FCONF: FW_CONFIG loaded at address = 0x%lx\n", tb_fw_cfg_dtb); + INFO("FCONF: FW_CONFIG loaded at address = 0x%lx\n", arm_tb_fw_info.image_base); } void fconf_populate(uintptr_t config) @@ -76,4 +79,7 @@ void fconf_populate(uintptr_t config) panic(); } } + + /* save local pointer to the config dtb */ + fconf_dtb_info.base_addr = config; } diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c index cdf87ca55..5f83bccde 100644 --- a/plat/arm/common/arm_bl2_setup.c +++ b/plat/arm/common/arm_bl2_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -14,6 +14,7 @@ #include #include #include +#include #ifdef SPD_opteed #include #endif @@ -58,11 +59,13 @@ void arm_bl2_early_platform_setup(uintptr_t tb_fw_config, /* Setup the BL2 memory layout */ bl2_tzram_layout = *mem_layout; + /* Fill the properties struct with the info from the config dtb */ + if (tb_fw_config != 0U) { + fconf_populate(tb_fw_config); + } + /* Initialise the IO layer and register platform IO devices */ plat_arm_io_setup(); - - if (tb_fw_config != 0U) - arm_bl2_set_tb_cfg_addr((void *)tb_fw_config); } void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) From 25ac87940cd3db8036f967d01653c0db64e4c136 Mon Sep 17 00:00:00 2001 From: Louis Mayencourt Date: Tue, 17 Dec 2019 13:17:25 +0000 Subject: [PATCH 04/10] fconf: Add dynamic config DTBs info as property This patch introduces a better separation between the trusted-boot related properties, and the dynamic configuration DTBs loading information. The dynamic configuration DTBs properties are moved to a new node: `dtb-registry`. All the sub-nodes present will be provided to the dynamic config framework to be loaded. The node currently only contains the already defined configuration DTBs, but can be extended for future features if necessary. The dynamic config framework is modified to use the abstraction provided by the fconf framework, instead of directly accessing the DTBs. The trusted-boot properties are kept under the "arm,tb_fw" compatible string, but in a separate `tb_fw-config` node. The `tb_fw-config` property of the `dtb-registry` node simply points to the load address of `fw_config`, as the `tb_fw-config` is currently part of the same DTB. Change-Id: Iceb6c4c2cb92b692b6e28dbdc9fb060f1c46de82 Signed-off-by: Louis Mayencourt --- include/lib/fconf/fconf_dyn_cfg_getter.h | 24 +++++ include/plat/arm/common/arm_dyn_cfg_helpers.h | 4 +- include/plat/arm/common/plat_arm.h | 1 - lib/fconf/fconf.c | 2 +- lib/fconf/fconf.mk | 3 +- lib/fconf/fconf_dyn_cfg_getter.c | 95 +++++++++++++++++++ plat/arm/board/a5ds/fdts/a5ds_fw_config.dts | 35 +++++++ .../arm/board/a5ds/fdts/a5ds_tb_fw_config.dts | 18 ---- plat/arm/board/a5ds/platform.mk | 4 +- ...fvp_tb_fw_config.dts => fvp_fw_config.dts} | 58 ++++++++--- plat/arm/board/fvp/jmptbl.i | 2 + plat/arm/board/fvp/platform.mk | 4 +- .../board/fvp_ve/fdts/fvp_ve_fw_config.dts | 35 +++++++ .../board/fvp_ve/fdts/fvp_ve_tb_fw_config.dts | 18 ---- plat/arm/board/fvp_ve/platform.mk | 4 +- plat/arm/board/juno/fdts/juno_fw_config.dts | 40 ++++++++ .../arm/board/juno/fdts/juno_tb_fw_config.dts | 25 ----- plat/arm/board/juno/jmptbl.i | 2 + plat/arm/board/juno/platform.mk | 4 +- plat/arm/common/arm_dyn_cfg.c | 72 +++++++------- plat/arm/common/arm_dyn_cfg_helpers.c | 77 --------------- 21 files changed, 327 insertions(+), 200 deletions(-) create mode 100644 include/lib/fconf/fconf_dyn_cfg_getter.h create mode 100644 lib/fconf/fconf_dyn_cfg_getter.c create mode 100644 plat/arm/board/a5ds/fdts/a5ds_fw_config.dts delete mode 100644 plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts rename plat/arm/board/fvp/fdts/{fvp_tb_fw_config.dts => fvp_fw_config.dts} (51%) create mode 100644 plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts delete mode 100644 plat/arm/board/fvp_ve/fdts/fvp_ve_tb_fw_config.dts create mode 100644 plat/arm/board/juno/fdts/juno_fw_config.dts delete mode 100644 plat/arm/board/juno/fdts/juno_tb_fw_config.dts diff --git a/include/lib/fconf/fconf_dyn_cfg_getter.h b/include/lib/fconf/fconf_dyn_cfg_getter.h new file mode 100644 index 000000000..0fda8c9b2 --- /dev/null +++ b/include/lib/fconf/fconf_dyn_cfg_getter.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2019-2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef FCONF_DYN_CFG_GETTER_H +#define FCONF_DYN_CFG_GETTER_H + +#include + +/* Dynamic configuration related getter */ +#define dyn_cfg__dtb_getter(id) dyn_cfg_dtb_info_getter(id) + +struct dyn_cfg_dtb_info_t { + uintptr_t config_addr; + size_t config_max_size; + unsigned int config_id; +}; + +struct dyn_cfg_dtb_info_t *dyn_cfg_dtb_info_getter(unsigned int config_id); +int fconf_populate_dtb_registry(uintptr_t config); + +#endif /* FCONF_DYN_CFG_GETTER_H */ diff --git a/include/plat/arm/common/arm_dyn_cfg_helpers.h b/include/plat/arm/common/arm_dyn_cfg_helpers.h index 3ad6d5468..9fb31317c 100644 --- a/include/plat/arm/common/arm_dyn_cfg_helpers.h +++ b/include/plat/arm/common/arm_dyn_cfg_helpers.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -10,8 +10,6 @@ #include /* Function declarations */ -int arm_dyn_get_config_load_info(void *dtb, int node, unsigned int config_id, - uint64_t *config_addr, uint32_t *config_size); int arm_dyn_tb_fw_cfg_init(void *dtb, int *node); int arm_dyn_get_disable_auth(void *dtb, int node, uint32_t *disable_auth); int arm_get_dtb_mbedtls_heap_info(void *dtb, void **heap_addr, diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index ec0f37988..129ceca66 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -225,7 +225,6 @@ void arm_sp_min_plat_runtime_setup(void); int arm_io_is_toc_valid(void); /* Utility functions for Dynamic Config */ -void arm_bl2_set_tb_cfg_addr(void *dtb); void arm_bl2_dyn_cfg_init(void); void arm_bl1_set_mbedtls_heap(void); int arm_get_mbedtls_heap(void **heap_addr, size_t *heap_size); diff --git a/lib/fconf/fconf.c b/lib/fconf/fconf.c index 2ca1bdc77..a6da56b00 100644 --- a/lib/fconf/fconf.c +++ b/lib/fconf/fconf.c @@ -18,7 +18,7 @@ struct fconf_dtb_info_t fconf_dtb_info; void fconf_load_config(void) { int err; - + /* fconf FW_CONFIG and TB_FW_CONFIG are currently the same DTB */ image_info_t arm_tb_fw_info = { .h.type = (uint8_t)PARAM_IMAGE_BINARY, .h.version = (uint8_t)VERSION_2, diff --git a/lib/fconf/fconf.mk b/lib/fconf/fconf.mk index 0813c73cc..703196949 100644 --- a/lib/fconf/fconf.mk +++ b/lib/fconf/fconf.mk @@ -5,7 +5,8 @@ # # Add Firmware Configuration files -FCONF_SOURCES := lib/fconf/fconf.c +FCONF_SOURCES := lib/fconf/fconf.c \ + lib/fconf/fconf_dyn_cfg_getter.c BL1_SOURCES += ${FCONF_SOURCES} BL2_SOURCES += ${FCONF_SOURCES} diff --git a/lib/fconf/fconf_dyn_cfg_getter.c b/lib/fconf/fconf_dyn_cfg_getter.c new file mode 100644 index 000000000..d313a5618 --- /dev/null +++ b/lib/fconf/fconf_dyn_cfg_getter.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2019-2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include +#include + +/* We currently use TB_FW, SOC_FW, TOS_FW, NS_fw and HW configs */ +#define MAX_DTB_INFO U(5) + +static struct dyn_cfg_dtb_info_t dtb_infos[MAX_DTB_INFO]; +static OBJECT_POOL_ARRAY(dtb_info_pool, dtb_infos); + +struct dyn_cfg_dtb_info_t *dyn_cfg_dtb_info_getter(unsigned int config_id) +{ + unsigned int index; + struct dyn_cfg_dtb_info_t *info; + + /* Positions index to the proper config-id */ + for (index = 0; index < MAX_DTB_INFO; index++) { + if (dtb_infos[index].config_id == config_id) { + info = &dtb_infos[index]; + break; + } + } + + if (index == MAX_DTB_INFO) { + WARN("FCONF: Invalid config id %u\n", config_id); + info = NULL; + } + + return info; +} + +int fconf_populate_dtb_registry(uintptr_t config) +{ + int rc; + int node, child; + struct dyn_cfg_dtb_info_t *dtb_info; + + /* As libfdt use void *, we can't avoid this cast */ + const void *dtb = (void *)config; + + /* Find the node offset point to "arm,dyn_cfg-dtb_registry" compatible property */ + const char *compatible_str = "arm,dyn_cfg-dtb_registry"; + node = fdt_node_offset_by_compatible(dtb, -1, compatible_str); + if (node < 0) { + ERROR("FCONF: Can't find %s compatible in dtb\n", compatible_str); + return node; + } + + fdt_for_each_subnode(child, dtb, node) { + dtb_info = pool_alloc(&dtb_info_pool); + + /* Read configuration dtb information */ + rc = fdtw_read_cells(dtb, child, "load-address", 2, &dtb_info->config_addr); + if (rc < 0) { + ERROR("FCONF: Incomplete configuration property in dtb-registry.\n"); + return rc; + } + + rc = fdtw_read_cells(dtb, child, "max-size", 1, &dtb_info->config_max_size); + if (rc < 0) { + ERROR("FCONF: Incomplete configuration property in dtb-registry.\n"); + return rc; + } + + rc = fdtw_read_cells(dtb, child, "id", 1, &dtb_info->config_id); + if (rc < 0) { + ERROR("FCONF: Incomplete configuration property in dtb-registry.\n"); + return rc; + } + + VERBOSE("FCONF: dyn_cfg.dtb_registry cell found with:\n"); + VERBOSE("\tload-address = %lx\n", dtb_info->config_addr); + VERBOSE("\tmax-size = 0x%zx\n", dtb_info->config_max_size); + VERBOSE("\tconfig-id = %u\n", dtb_info->config_id); + } + + if ((child < 0) && (child != -FDT_ERR_NOTFOUND)) { + ERROR("%d: fdt_for_each_subnode(): %d\n", __LINE__, node); + return child; + } + + return 0; +} + +FCONF_REGISTER_POPULATOR(dyn_cfg, fconf_populate_dtb_registry); diff --git a/plat/arm/board/a5ds/fdts/a5ds_fw_config.dts b/plat/arm/board/a5ds/fdts/a5ds_fw_config.dts new file mode 100644 index 000000000..2f2d265c5 --- /dev/null +++ b/plat/arm/board/a5ds/fdts/a5ds_fw_config.dts @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2019-2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +/dts-v1/; + +/ { + dtb-registry { + compatible = "arm,dyn_cfg-dtb_registry"; + + /* tb_fw_config is temporarily contained in this dtb */ + tb_fw-config { + load-address = <0x0 0x2001010>; + max-size = <0x200>; + id = ; + }; + + hw-config { + load-address = <0x0 0x83000000>; + max-size = <0x01000000>; + id = ; + }; + }; + + tb_fw-config { + compatible = "arm,tb_fw"; + + /* Disable authentication for development */ + disable_auth = <0x0>; + }; +}; diff --git a/plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts b/plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts deleted file mode 100644 index 7b3aa1144..000000000 --- a/plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (c) 2019-2020, Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/dts-v1/; - -/ { - /* Platform Config */ - plat_arm_bl2 { - compatible = "arm,tb_fw"; - hw_config_addr = <0x0 0x83000000>; - hw_config_max_size = <0x01000000>; - /* Disable authentication for development */ - disable_auth = <0x0>; - }; -}; diff --git a/plat/arm/board/a5ds/platform.mk b/plat/arm/board/a5ds/platform.mk index ac3973ae0..719884217 100644 --- a/plat/arm/board/a5ds/platform.mk +++ b/plat/arm/board/a5ds/platform.mk @@ -70,7 +70,7 @@ BL2_SOURCES += lib/aarch32/arm32_aeabi_divmod.c \ # Add the FDT_SOURCES and options for Dynamic Config (only for Unix env) ifdef UNIX_MK -FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/a5ds_tb_fw_config.dtb +FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/a5ds_fw_config.dtb # 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)) @@ -80,7 +80,7 @@ $(eval FVP_HW_CONFIG := ${BUILD_PLAT}/$(patsubst %.dts,%.dtb, \ # Add the HW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${FVP_HW_CONFIG},--hw-config)) -FDT_SOURCES += plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts \ +FDT_SOURCES += plat/arm/board/a5ds/fdts/a5ds_fw_config.dts \ ${FVP_HW_CONFIG_DTS} endif diff --git a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_fw_config.dts similarity index 51% rename from plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts rename to plat/arm/board/fvp/fdts/fvp_fw_config.dts index ce589385c..ff83db361 100644 --- a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts +++ b/plat/arm/board/fvp/fdts/fvp_fw_config.dts @@ -1,31 +1,61 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, ARM Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ +#include + /dts-v1/; / { - /* Platform Config */ - plat_arm_bl2 { - compatible = "arm,tb_fw"; - hw_config_addr = <0x0 0x82000000>; - hw_config_max_size = <0x01000000>; - /* Disable authentication for development */ - disable_auth = <0x0>; + dtb-registry { + compatible = "arm,dyn_cfg-dtb_registry"; + + /* tb_fw_config is temporarily contained on this dtb */ + tb_fw-config { + load-address = <0x0 0x4001010>; + max-size = <0x200>; + id = ; + }; + + hw-config { + load-address = <0x0 0x82000000>; + max-size = <0x01000000>; + id = ; + }; + /* * Load SoC and TOS firmware configs at the base of * non shared SRAM. The runtime checks ensure we don't * overlap BL2, BL31 or BL32. The NT firmware config * is loaded at base of DRAM. */ - soc_fw_config_addr = <0x0 0x04001000>; - soc_fw_config_max_size = <0x200>; - tos_fw_config_addr = <0x0 0x04001200>; - tos_fw_config_max_size = <0x200>; - nt_fw_config_addr = <0x0 0x80000000>; - nt_fw_config_max_size = <0x200>; + soc_fw-config { + load-address = <0x0 0x04001000>; + max-size = <0x200>; + id = ; + }; + + tos_fw-config { + load-address = <0x0 0x04001200>; + max-size = <0x200>; + id = ; + }; + + nt_fw-config { + load-address = <0x0 0x80000000>; + max-size = <0x200>; + id = ; + }; + }; + + tb_fw-config { + compatible = "arm,tb_fw"; + + /* Disable authentication for development */ + disable_auth = <0x0>; + /* * The following two entries are placeholders for Mbed TLS * heap information. The default values don't matter since diff --git a/plat/arm/board/fvp/jmptbl.i b/plat/arm/board/fvp/jmptbl.i index 6ccdd283f..b1b9ed463 100644 --- a/plat/arm/board/fvp/jmptbl.i +++ b/plat/arm/board/fvp/jmptbl.i @@ -20,6 +20,8 @@ fdt fdt_setprop_inplace fdt fdt_check_header fdt fdt_node_offset_by_compatible fdt fdt_setprop_inplace_namelen_partial +fdt fdt_first_subnode +fdt fdt_next_subnode mbedtls mbedtls_asn1_get_alg mbedtls mbedtls_asn1_get_alg_null mbedtls mbedtls_asn1_get_bitstring_null diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 6fb34c48a..f46f8e211 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -205,12 +205,12 @@ endif ifdef UNIX_MK FVP_HW_CONFIG_DTS := fdts/${FVP_DT_PREFIX}.dts FDT_SOURCES += $(addprefix plat/arm/board/fvp/fdts/, \ - ${PLAT}_tb_fw_config.dts \ + ${PLAT}_fw_config.dts \ ${PLAT}_soc_fw_config.dts \ ${PLAT}_nt_fw_config.dts \ ) -FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb +FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb FVP_SOC_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_soc_fw_config.dtb FVP_NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb diff --git a/plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts b/plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts new file mode 100644 index 000000000..147c8f366 --- /dev/null +++ b/plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2019-2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +/dts-v1/; + +/ { + dtb-registry { + compatible = "arm,dyn_cfg-dtb_registry"; + + /* tb_fw_config is temporarily contained on this dtb */ + tb_fw-config { + load-address = <0x0 0x80001010>; + max-size = <0x200>; + id = ; + }; + + hw-config { + load-address = <0x0 0x82000000>; + max-size = <0x01000000>; + id = ; + }; + }; + + tb_fw-config { + compatible = "arm,tb_fw"; + + /* Disable authentication for development */ + disable_auth = <0x0>; + }; +}; diff --git a/plat/arm/board/fvp_ve/fdts/fvp_ve_tb_fw_config.dts b/plat/arm/board/fvp_ve/fdts/fvp_ve_tb_fw_config.dts deleted file mode 100644 index 9ab2d9656..000000000 --- a/plat/arm/board/fvp_ve/fdts/fvp_ve_tb_fw_config.dts +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (c) 2019, Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/dts-v1/; - -/ { - /* Platform Config */ - plat_arm_bl2 { - compatible = "arm,tb_fw"; - hw_config_addr = <0x0 0x82000000>; - hw_config_max_size = <0x01000000>; - /* Disable authentication for development */ - disable_auth = <0x0>; - }; -}; diff --git a/plat/arm/board/fvp_ve/platform.mk b/plat/arm/board/fvp_ve/platform.mk index 51c03151d..7883719b0 100644 --- a/plat/arm/board/fvp_ve/platform.mk +++ b/plat/arm/board/fvp_ve/platform.mk @@ -72,9 +72,9 @@ BL2_SOURCES += plat/arm/board/fvp_ve/fvp_ve_bl2_setup.c \ # Add the FDT_SOURCES and options for Dynamic Config (only for Unix env) ifdef UNIX_MK -FDT_SOURCES += plat/arm/board/fvp_ve/fdts/fvp_ve_tb_fw_config.dts +FDT_SOURCES += plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts -FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/fvp_ve_tb_fw_config.dtb +FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/fvp_ve_fw_config.dtb # 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)) diff --git a/plat/arm/board/juno/fdts/juno_fw_config.dts b/plat/arm/board/juno/fdts/juno_fw_config.dts new file mode 100644 index 000000000..cab6f2bf4 --- /dev/null +++ b/plat/arm/board/juno/fdts/juno_fw_config.dts @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2019-2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +/dts-v1/; + +/ { + dtb-registry { + compatible = "arm,dyn_cfg-dtb_registry"; + + /* tb_fw_config is temporarily contained on this dtb */ + tb_fw-config { + load-address = <0x0 0x4001010>; + max-size = <0x200>; + id = ; + }; + }; + + tb_fw-config { + /* Platform Config */ + compatible = "arm,tb_fw"; + /* Disable authentication for development */ + disable_auth = <0x0>; + /* + * The following two entries are placeholders for Mbed TLS + * heap information. The default values don't matter since + * they will be overwritten by BL1. + * In case of having shared Mbed TLS heap between BL1 and BL2, + * BL1 will populate these two properties with the respective + * info about the shared heap. This info will be available for + * BL2 in order to locate and re-use the heap. + */ + mbedtls_heap_addr = <0x0 0x0>; + mbedtls_heap_size = <0x0>; + }; +}; diff --git a/plat/arm/board/juno/fdts/juno_tb_fw_config.dts b/plat/arm/board/juno/fdts/juno_tb_fw_config.dts deleted file mode 100644 index a8ab6c5f9..000000000 --- a/plat/arm/board/juno/fdts/juno_tb_fw_config.dts +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/dts-v1/; - -/ { - /* Platform Config */ - compatible = "arm,tb_fw"; - /* Disable authentication for development */ - disable_auth = <0x0>; - /* - * The following two entries are placeholders for Mbed TLS - * heap information. The default values don't matter since - * they will be overwritten by BL1. - * In case of having shared Mbed TLS heap between BL1 and BL2, - * BL1 will populate these two properties with the respective - * info about the shared heap. This info will be available for - * BL2 in order to locate and re-use the heap. - */ - mbedtls_heap_addr = <0x0 0x0>; - mbedtls_heap_size = <0x0>; -}; diff --git a/plat/arm/board/juno/jmptbl.i b/plat/arm/board/juno/jmptbl.i index 6ccdd283f..b1b9ed463 100644 --- a/plat/arm/board/juno/jmptbl.i +++ b/plat/arm/board/juno/jmptbl.i @@ -20,6 +20,8 @@ fdt fdt_setprop_inplace fdt fdt_check_header fdt fdt_node_offset_by_compatible fdt fdt_setprop_inplace_namelen_partial +fdt fdt_first_subnode +fdt fdt_next_subnode mbedtls mbedtls_asn1_get_alg mbedtls mbedtls_asn1_get_alg_null mbedtls mbedtls_asn1_get_bitstring_null diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk index a85ad5376..27650d266 100644 --- a/plat/arm/board/juno/platform.mk +++ b/plat/arm/board/juno/platform.mk @@ -156,8 +156,8 @@ else endif # Add the FDT_SOURCES and options for Dynamic Config -FDT_SOURCES += plat/arm/board/juno/fdts/${PLAT}_tb_fw_config.dts -TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb +FDT_SOURCES += plat/arm/board/juno/fdts/${PLAT}_fw_config.dts +TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb # Add the TB_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config)) diff --git a/plat/arm/common/arm_dyn_cfg.c b/plat/arm/common/arm_dyn_cfg.c index fa251c8ce..402fd93da 100644 --- a/plat/arm/common/arm_dyn_cfg.c +++ b/plat/arm/common/arm_dyn_cfg.c @@ -16,13 +16,12 @@ #if TRUSTED_BOARD_BOOT #include #endif +#include +#include #include #include #include -/* Variable to store the address to TB_FW_CONFIG passed from BL1 */ -static void *tb_fw_cfg_dtb; - #if TRUSTED_BOARD_BOOT static void *mbedtls_heap_addr; @@ -58,6 +57,10 @@ int arm_get_mbedtls_heap(void **heap_addr, size_t *heap_size) #elif defined(IMAGE_BL2) int err; + void *tb_fw_cfg_dtb; + + /* fconf FW_CONFIG and TB_FW_CONFIG are currently the same DTB*/ + tb_fw_cfg_dtb = (void *)FCONF_GET_PROPERTY(fconf, dtb, base_addr); /* If in BL2, retrieve the already allocated heap's info from DTB */ if (tb_fw_cfg_dtb != NULL) { @@ -83,6 +86,7 @@ int arm_get_mbedtls_heap(void **heap_addr, size_t *heap_size) void arm_bl1_set_mbedtls_heap(void) { int err; + uintptr_t tb_fw_cfg_dtb; /* * If tb_fw_cfg_dtb==NULL then DTB is not present for the current @@ -96,8 +100,15 @@ void arm_bl1_set_mbedtls_heap(void) * information, we would need to call plat_get_mbedtls_heap to retrieve * the default heap's address and size. */ - if ((tb_fw_cfg_dtb != NULL) && (mbedtls_heap_addr != NULL)) { - err = arm_set_dtb_mbedtls_heap_info(tb_fw_cfg_dtb, + + /* fconf FW_CONFIG and TB_FW_CONFIG are currently the same DTB*/ + tb_fw_cfg_dtb = FCONF_GET_PROPERTY(fconf, dtb, base_addr); + + if ((tb_fw_cfg_dtb != 0UL) && (mbedtls_heap_addr != NULL)) { + /* As libfdt use void *, we can't avoid this cast */ + void *dtb = (void *)tb_fw_cfg_dtb; + + err = arm_set_dtb_mbedtls_heap_info(dtb, mbedtls_heap_addr, mbedtls_heap_size); if (err < 0) { ERROR("BL1: unable to write shared Mbed TLS heap information to DTB\n"); @@ -108,22 +119,12 @@ void arm_bl1_set_mbedtls_heap(void) * images. It's critical because BL2 won't be able to proceed * without the heap info. */ - flush_dcache_range((uintptr_t)tb_fw_cfg_dtb, - fdt_totalsize(tb_fw_cfg_dtb)); + flush_dcache_range(tb_fw_cfg_dtb, fdt_totalsize(dtb)); } } #endif /* TRUSTED_BOARD_BOOT */ -/* - * BL2 utility function to set the address of TB_FW_CONFIG passed from BL1. - */ -void arm_bl2_set_tb_cfg_addr(void *dtb) -{ - assert(dtb != NULL); - tb_fw_cfg_dtb = dtb; -} - /* * BL2 utility function to initialize dynamic configuration specified by * TB_FW_CONFIG. Populate the bl_mem_params_node_t of other FW_CONFIGs if @@ -131,11 +132,10 @@ void arm_bl2_set_tb_cfg_addr(void *dtb) */ void arm_bl2_dyn_cfg_init(void) { - int err = 0, tb_fw_node; unsigned int i; bl_mem_params_node_t *cfg_mem_params = NULL; - uint64_t image_base; - uint32_t image_size; + uintptr_t image_base; + size_t image_size; const unsigned int config_ids[] = { HW_CONFIG_ID, SOC_FW_CONFIG_ID, @@ -146,16 +146,7 @@ void arm_bl2_dyn_cfg_init(void) #endif }; - if (tb_fw_cfg_dtb == NULL) { - VERBOSE("No TB_FW_CONFIG specified\n"); - return; - } - - err = arm_dyn_tb_fw_cfg_init(tb_fw_cfg_dtb, &tb_fw_node); - if (err < 0) { - ERROR("Invalid TB_FW_CONFIG passed from BL1\n"); - panic(); - } + const struct dyn_cfg_dtb_info_t *dtb_info; /* Iterate through all the fw config IDs */ for (i = 0; i < ARRAY_SIZE(config_ids); i++) { @@ -166,14 +157,16 @@ void arm_bl2_dyn_cfg_init(void) continue; } - err = arm_dyn_get_config_load_info(tb_fw_cfg_dtb, tb_fw_node, - config_ids[i], &image_base, &image_size); - if (err < 0) { + dtb_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, config_ids[i]); + if (dtb_info == NULL) { VERBOSE("Couldn't find config_id %d load info in TB_FW_CONFIG\n", config_ids[i]); continue; } + image_base = dtb_info->config_addr; + image_size = dtb_info->config_max_size; + /* * Do some runtime checks on the load addresses of soc_fw_config, * tos_fw_config, nt_fw_config. This is not a comprehensive check @@ -205,8 +198,8 @@ void arm_bl2_dyn_cfg_init(void) } - cfg_mem_params->image_info.image_base = (uintptr_t)image_base; - cfg_mem_params->image_info.image_max_size = image_size; + cfg_mem_params->image_info.image_base = image_base; + cfg_mem_params->image_info.image_max_size = (uint32_t)image_size; /* * Remove the IMAGE_ATTRIB_SKIP_LOADING attribute from @@ -217,6 +210,17 @@ void arm_bl2_dyn_cfg_init(void) #if TRUSTED_BOARD_BOOT && defined(DYN_DISABLE_AUTH) uint32_t disable_auth = 0; + void *tb_fw_cfg_dtb; + int err, tb_fw_node; + + dtb_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID); + tb_fw_cfg_dtb = (void *)dtb_info->config_addr; + + err = arm_dyn_tb_fw_cfg_init(tb_fw_cfg_dtb, &tb_fw_node); + if (err < 0) { + ERROR("Invalid TB_FW_CONFIG passed from BL1\n"); + panic(); + } err = arm_dyn_get_disable_auth(tb_fw_cfg_dtb, tb_fw_node, &disable_auth); diff --git a/plat/arm/common/arm_dyn_cfg_helpers.c b/plat/arm/common/arm_dyn_cfg_helpers.c index daf0f0a63..ac6c99d2b 100644 --- a/plat/arm/common/arm_dyn_cfg_helpers.c +++ b/plat/arm/common/arm_dyn_cfg_helpers.c @@ -15,83 +15,6 @@ #define DTB_PROP_MBEDTLS_HEAP_ADDR "mbedtls_heap_addr" #define DTB_PROP_MBEDTLS_HEAP_SIZE "mbedtls_heap_size" -typedef struct config_load_info_prop { - unsigned int config_id; - const char *config_addr; - const char *config_max_size; -} config_load_info_prop_t; - -static const config_load_info_prop_t prop_names[] = { - {HW_CONFIG_ID, "hw_config_addr", "hw_config_max_size"}, - {SOC_FW_CONFIG_ID, "soc_fw_config_addr", "soc_fw_config_max_size"}, - {TOS_FW_CONFIG_ID, "tos_fw_config_addr", "tos_fw_config_max_size"}, - {NT_FW_CONFIG_ID, "nt_fw_config_addr", "nt_fw_config_max_size"} -}; - -/******************************************************************************* - * Helper to read the load information corresponding to the `config_id` in - * TB_FW_CONFIG. This function expects the following properties to be defined : - * _addr size : 2 cells - * _max_size size : 1 cell - * - * Arguments: - * void *dtb - pointer to the TB_FW_CONFIG in memory - * int node - The node offset to appropriate node in the - * DTB. - * unsigned int config_id - The configuration id - * uint64_t *config_addr - Returns the `config` load address if read - * is successful. - * uint32_t *config_size - Returns the `config` size if read is - * successful. - * - * Returns 0 on success and -1 on error. - ******************************************************************************/ -int arm_dyn_get_config_load_info(void *dtb, int node, unsigned int config_id, - uint64_t *config_addr, uint32_t *config_size) -{ - int err; - unsigned int i; - - assert(dtb != NULL); - assert(config_addr != NULL); - assert(config_size != NULL); - - for (i = 0; i < ARRAY_SIZE(prop_names); i++) { - if (prop_names[i].config_id == config_id) - break; - } - - if (i == ARRAY_SIZE(prop_names)) { - WARN("Invalid config id %d\n", config_id); - return -1; - } - - /* Check if the pointer to DT is correct */ - assert(fdt_check_header(dtb) == 0); - - /* Assert the node offset point to "arm,tb_fw" compatible property */ - assert(node == fdt_node_offset_by_compatible(dtb, -1, "arm,tb_fw")); - - err = fdtw_read_cells(dtb, node, prop_names[i].config_addr, 2, - (void *) config_addr); - if (err < 0) { - WARN("Read cell failed for %s\n", prop_names[i].config_addr); - return -1; - } - - err = fdtw_read_cells(dtb, node, prop_names[i].config_max_size, 1, - (void *) config_size); - if (err < 0) { - WARN("Read cell failed for %s\n", prop_names[i].config_max_size); - return -1; - } - - VERBOSE("Dyn cfg: Read config_id %d load info from TB_FW_CONFIG 0x%llx 0x%x\n", - config_id, (unsigned long long)*config_addr, *config_size); - - return 0; -} - /******************************************************************************* * Helper to read the `disable_auth` property in config DTB. This function * expects the following properties to be present in the config DTB. From ce8528411a95d4e988844d5d16b5af2828f9f407 Mon Sep 17 00:00:00 2001 From: Louis Mayencourt Date: Mon, 30 Sep 2019 10:57:24 +0100 Subject: [PATCH 05/10] fconf: Add TBBR disable_authentication property Use fconf to retrieve the `disable_authentication` property. Move this access from arm dynamic configuration to bl common. Change-Id: Ibf184a5c6245d04839222f5457cf5e651f252b86 Signed-off-by: Louis Mayencourt --- common/bl_common.c | 2 +- include/lib/fconf/fconf_tbbr_getter.h | 10 ++++ include/plat/arm/common/arm_dyn_cfg_helpers.h | 1 - lib/fconf/fconf_tbbr_getter.c | 56 +++++++++++++++++++ plat/arm/common/arm_common.mk | 3 +- plat/arm/common/arm_dyn_cfg.c | 23 -------- plat/arm/common/arm_dyn_cfg_helpers.c | 45 --------------- 7 files changed, 69 insertions(+), 71 deletions(-) create mode 100644 lib/fconf/fconf_tbbr_getter.c diff --git a/common/bl_common.c b/common/bl_common.c index b74225b13..2fcb5385d 100644 --- a/common/bl_common.c +++ b/common/bl_common.c @@ -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 */ diff --git a/include/lib/fconf/fconf_tbbr_getter.h b/include/lib/fconf/fconf_tbbr_getter.h index fb81e7bea..32e1b6594 100644 --- a/include/lib/fconf/fconf_tbbr_getter.h +++ b/include/lib/fconf/fconf_tbbr_getter.h @@ -12,4 +12,14 @@ /* TBBR related getter */ #define tbbr__cot_getter(id) cot_desc_ptr[id] +#define tbbr__dyn_config_getter(id) tbbr_dyn_config.id + +struct tbbr_dyn_config_t { + uint32_t disable_auth; +}; + +extern struct tbbr_dyn_config_t tbbr_dyn_config; + +int fconf_populate_tbbr_dyn_config(uintptr_t config); + #endif /* FCONF_TBBR_GETTER_H */ diff --git a/include/plat/arm/common/arm_dyn_cfg_helpers.h b/include/plat/arm/common/arm_dyn_cfg_helpers.h index 9fb31317c..61f876f82 100644 --- a/include/plat/arm/common/arm_dyn_cfg_helpers.h +++ b/include/plat/arm/common/arm_dyn_cfg_helpers.h @@ -11,7 +11,6 @@ /* Function declarations */ int arm_dyn_tb_fw_cfg_init(void *dtb, int *node); -int arm_dyn_get_disable_auth(void *dtb, int node, uint32_t *disable_auth); int arm_get_dtb_mbedtls_heap_info(void *dtb, void **heap_addr, size_t *heap_size); int arm_set_dtb_mbedtls_heap_info(void *dtb, void *heap_addr, diff --git a/lib/fconf/fconf_tbbr_getter.c b/lib/fconf/fconf_tbbr_getter.c new file mode 100644 index 000000000..29f67caec --- /dev/null +++ b/lib/fconf/fconf_tbbr_getter.c @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2019-2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include + +#include +#include +#include +#include +#include + +struct tbbr_dyn_config_t tbbr_dyn_config; + +int fconf_populate_tbbr_dyn_config(uintptr_t config) +{ + int err; + int node; + + /* As libfdt use void *, we can't avoid this cast */ + const void *dtb = (void *)config; + + /* Assert the node offset point to "arm,tb_fw" compatible property */ + const char *compatible_str = "arm,tb_fw"; + node = fdt_node_offset_by_compatible(dtb, -1, compatible_str); + if (node < 0) { + ERROR("FCONF: Can't find %s compatible in dtb\n", compatible_str); + return node; + } + + /* Locate the disable_auth cell and read the value */ + err = fdtw_read_cells(dtb, node, "disable_auth", 1, &tbbr_dyn_config.disable_auth); + if (err < 0) { + WARN("FCONF: Read cell failed for `disable_auth`\n"); + return err; + } + + /* Check if the value is boolean */ + if ((tbbr_dyn_config.disable_auth != 0U) && (tbbr_dyn_config.disable_auth != 1U)) { + WARN("Invalid value for `disable_auth` cell %d\n", tbbr_dyn_config.disable_auth); + return -1; + } + +#if defined(DYN_DISABLE_AUTH) + if (tbbr_dyn_config.disable_auth == 1) + dyn_disable_auth(); +#endif + + VERBOSE("FCONF:tbbr.disable_auth cell found with value = %d\n", + tbbr_dyn_config.disable_auth); + + return 0; +} + +FCONF_REGISTER_POPULATOR(tbbr, fconf_populate_tbbr_dyn_config); diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index abf2f914e..ceff6e2bb 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -273,7 +273,8 @@ ifneq (${TRUSTED_BOARD_BOOT},0) # Include common TBB sources AUTH_SOURCES := drivers/auth/auth_mod.c \ drivers/auth/crypto_mod.c \ - drivers/auth/img_parser_mod.c + drivers/auth/img_parser_mod.c \ + lib/fconf/fconf_tbbr_getter.c # Include the selected chain of trust sources. ifeq (${COT},tbbr) diff --git a/plat/arm/common/arm_dyn_cfg.c b/plat/arm/common/arm_dyn_cfg.c index 402fd93da..d373dedc8 100644 --- a/plat/arm/common/arm_dyn_cfg.c +++ b/plat/arm/common/arm_dyn_cfg.c @@ -207,27 +207,4 @@ void arm_bl2_dyn_cfg_init(void) */ cfg_mem_params->image_info.h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING; } - -#if TRUSTED_BOARD_BOOT && defined(DYN_DISABLE_AUTH) - uint32_t disable_auth = 0; - void *tb_fw_cfg_dtb; - int err, tb_fw_node; - - dtb_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID); - tb_fw_cfg_dtb = (void *)dtb_info->config_addr; - - err = arm_dyn_tb_fw_cfg_init(tb_fw_cfg_dtb, &tb_fw_node); - if (err < 0) { - ERROR("Invalid TB_FW_CONFIG passed from BL1\n"); - panic(); - } - - err = arm_dyn_get_disable_auth(tb_fw_cfg_dtb, tb_fw_node, - &disable_auth); - if (err < 0) - return; - - if (disable_auth == 1) - dyn_disable_auth(); -#endif } diff --git a/plat/arm/common/arm_dyn_cfg_helpers.c b/plat/arm/common/arm_dyn_cfg_helpers.c index ac6c99d2b..db6f26073 100644 --- a/plat/arm/common/arm_dyn_cfg_helpers.c +++ b/plat/arm/common/arm_dyn_cfg_helpers.c @@ -15,51 +15,6 @@ #define DTB_PROP_MBEDTLS_HEAP_ADDR "mbedtls_heap_addr" #define DTB_PROP_MBEDTLS_HEAP_SIZE "mbedtls_heap_size" -/******************************************************************************* - * Helper to read the `disable_auth` property in config DTB. This function - * expects the following properties to be present in the config DTB. - * name : disable_auth size : 1 cell - * - * Arguments: - * void *dtb - pointer to the TB_FW_CONFIG in memory - * int node - The node offset to appropriate node in the - * DTB. - * uint64_t *disable_auth - The value of `disable_auth` property on - * successful read. Must be 0 or 1. - * - * Returns 0 on success and -1 on error. - ******************************************************************************/ -int arm_dyn_get_disable_auth(void *dtb, int node, uint32_t *disable_auth) -{ - int err; - - assert(dtb != NULL); - assert(disable_auth != NULL); - - /* Check if the pointer to DT is correct */ - assert(fdt_check_header(dtb) == 0); - - /* Assert the node offset point to "arm,tb_fw" compatible property */ - assert(node == fdt_node_offset_by_compatible(dtb, -1, "arm,tb_fw")); - - /* Locate the disable_auth cell and read the value */ - err = fdtw_read_cells(dtb, node, "disable_auth", 1, disable_auth); - if (err < 0) { - WARN("Read cell failed for `disable_auth`\n"); - return -1; - } - - /* Check if the value is boolean */ - if ((*disable_auth != 0U) && (*disable_auth != 1U)) { - WARN("Invalid value for `disable_auth` cell %d\n", *disable_auth); - return -1; - } - - VERBOSE("Dyn cfg: `disable_auth` cell found with value = %d\n", - *disable_auth); - return 0; -} - /******************************************************************************* * Validate the tb_fw_config is a valid DTB file and returns the node offset * to "arm,tb_fw" property. From 6c9723176019cb5327d5be0e952583809b714f5f Mon Sep 17 00:00:00 2001 From: Louis Mayencourt Date: Tue, 1 Oct 2019 10:45:14 +0100 Subject: [PATCH 06/10] fconf: Add mbedtls shared heap as property Use the firmware configuration framework in arm dynamic configuration to retrieve mbedtls heap information between bl1 and bl2. For this, a new fconf getter is added to expose the device tree base address and size. Change-Id: Ifa5ac9366ae100e2cdd1f4c8e85fc591b170f4b6 Signed-off-by: Louis Mayencourt --- include/lib/fconf/fconf_tbbr_getter.h | 2 + include/plat/arm/common/arm_dyn_cfg_helpers.h | 2 - lib/fconf/fconf_tbbr_getter.c | 19 +++++++++ plat/arm/common/arm_dyn_cfg.c | 21 ++-------- plat/arm/common/arm_dyn_cfg_helpers.c | 41 ------------------- 5 files changed, 25 insertions(+), 60 deletions(-) diff --git a/include/lib/fconf/fconf_tbbr_getter.h b/include/lib/fconf/fconf_tbbr_getter.h index 32e1b6594..eddc0c4b5 100644 --- a/include/lib/fconf/fconf_tbbr_getter.h +++ b/include/lib/fconf/fconf_tbbr_getter.h @@ -16,6 +16,8 @@ struct tbbr_dyn_config_t { uint32_t disable_auth; + void *mbedtls_heap_addr; + size_t mbedtls_heap_size; }; extern struct tbbr_dyn_config_t tbbr_dyn_config; diff --git a/include/plat/arm/common/arm_dyn_cfg_helpers.h b/include/plat/arm/common/arm_dyn_cfg_helpers.h index 61f876f82..2dc94abe3 100644 --- a/include/plat/arm/common/arm_dyn_cfg_helpers.h +++ b/include/plat/arm/common/arm_dyn_cfg_helpers.h @@ -11,8 +11,6 @@ /* Function declarations */ int arm_dyn_tb_fw_cfg_init(void *dtb, int *node); -int arm_get_dtb_mbedtls_heap_info(void *dtb, void **heap_addr, - size_t *heap_size); int arm_set_dtb_mbedtls_heap_info(void *dtb, void *heap_addr, size_t heap_size); diff --git a/lib/fconf/fconf_tbbr_getter.c b/lib/fconf/fconf_tbbr_getter.c index 29f67caec..c6df9c876 100644 --- a/lib/fconf/fconf_tbbr_getter.c +++ b/lib/fconf/fconf_tbbr_getter.c @@ -47,8 +47,27 @@ int fconf_populate_tbbr_dyn_config(uintptr_t config) dyn_disable_auth(); #endif + /* Retrieve the Mbed TLS heap details from the DTB */ + err = fdtw_read_cells(dtb, node, + "mbedtls_heap_addr", 2, &tbbr_dyn_config.mbedtls_heap_addr); + if (err < 0) { + ERROR("FCONF: Read cell failed for mbedtls_heap\n"); + return err; + } + + err = fdtw_read_cells(dtb, node, + "mbedtls_heap_size", 1, &tbbr_dyn_config.mbedtls_heap_size); + if (err < 0) { + ERROR("FCONF: Read cell failed for mbedtls_heap\n"); + return err; + } + VERBOSE("FCONF:tbbr.disable_auth cell found with value = %d\n", tbbr_dyn_config.disable_auth); + VERBOSE("FCONF:tbbr.mbedtls_heap_addr cell found with value = %p\n", + tbbr_dyn_config.mbedtls_heap_addr); + VERBOSE("FCONF:tbbr.mbedtls_heap_size cell found with value = %zu\n", + tbbr_dyn_config.mbedtls_heap_size); return 0; } diff --git a/plat/arm/common/arm_dyn_cfg.c b/plat/arm/common/arm_dyn_cfg.c index d373dedc8..b9361a479 100644 --- a/plat/arm/common/arm_dyn_cfg.c +++ b/plat/arm/common/arm_dyn_cfg.c @@ -18,6 +18,7 @@ #endif #include #include +#include #include #include #include @@ -56,24 +57,10 @@ int arm_get_mbedtls_heap(void **heap_addr, size_t *heap_size) #elif defined(IMAGE_BL2) - int err; - void *tb_fw_cfg_dtb; - - /* fconf FW_CONFIG and TB_FW_CONFIG are currently the same DTB*/ - tb_fw_cfg_dtb = (void *)FCONF_GET_PROPERTY(fconf, dtb, base_addr); - /* If in BL2, retrieve the already allocated heap's info from DTB */ - if (tb_fw_cfg_dtb != NULL) { - err = arm_get_dtb_mbedtls_heap_info(tb_fw_cfg_dtb, heap_addr, - heap_size); - if (err < 0) { - ERROR("BL2: unable to retrieve shared Mbed TLS heap information from DTB\n"); - panic(); - } - } else { - ERROR("BL2: DTB missing, cannot get Mbed TLS heap\n"); - panic(); - } + *heap_addr = FCONF_GET_PROPERTY(tbbr, dyn_config, mbedtls_heap_addr); + *heap_size = FCONF_GET_PROPERTY(tbbr, dyn_config, mbedtls_heap_size); + #endif return 0; diff --git a/plat/arm/common/arm_dyn_cfg_helpers.c b/plat/arm/common/arm_dyn_cfg_helpers.c index db6f26073..909c4a671 100644 --- a/plat/arm/common/arm_dyn_cfg_helpers.c +++ b/plat/arm/common/arm_dyn_cfg_helpers.c @@ -46,47 +46,6 @@ int arm_dyn_tb_fw_cfg_init(void *dtb, int *node) return 0; } -/* - * Reads and returns the Mbed TLS shared heap information from the DTB. - * This function is supposed to be called *only* when a DTB is present. - * This function is supposed to be called only by BL2. - * - * Returns: - * 0 = success - * -1 = error. In this case the values of heap_addr, heap_size should be - * considered as garbage by the caller. - */ -int arm_get_dtb_mbedtls_heap_info(void *dtb, void **heap_addr, - size_t *heap_size) -{ - int err, dtb_root; - - /* Verify the DTB is valid and get the root node */ - err = arm_dyn_tb_fw_cfg_init(dtb, &dtb_root); - if (err < 0) { - ERROR("Invalid TB_FW_CONFIG. Cannot retrieve Mbed TLS heap information from DTB\n"); - return -1; - } - - /* Retrieve the Mbed TLS heap details from the DTB */ - err = fdtw_read_cells(dtb, dtb_root, - DTB_PROP_MBEDTLS_HEAP_ADDR, 2, heap_addr); - if (err < 0) { - ERROR("Error while reading %s from DTB\n", - DTB_PROP_MBEDTLS_HEAP_ADDR); - return -1; - } - err = fdtw_read_cells(dtb, dtb_root, - DTB_PROP_MBEDTLS_HEAP_SIZE, 1, heap_size); - if (err < 0) { - ERROR("Error while reading %s from DTB\n", - DTB_PROP_MBEDTLS_HEAP_SIZE); - return -1; - } - return 0; -} - - /* * This function writes the Mbed TLS heap address and size in the DTB. When it * is called, it is guaranteed that a DTB is available. However it is not From 0a6e7e3b76fa0e6aea6a40c69ad7d4ea8be720d8 Mon Sep 17 00:00:00 2001 From: Louis Mayencourt Date: Thu, 24 Oct 2019 15:18:46 +0100 Subject: [PATCH 07/10] fconf: Move platform io policies into fconf Use the firmware configuration framework to store the io_policies information inside the configuration device tree instead of the static structure in the code base. The io_policies required by BL1 can't be inside the dtb, as this one is loaded by BL1, and only available at BL2. This change currently only applies to FVP platform. Change-Id: Ic9c1ac3931a4a136aa36f7f58f66d3764c1bfca1 Signed-off-by: Louis Mayencourt --- Makefile | 2 + docs/getting_started/build-options.rst | 5 + include/drivers/io/io_storage.h | 4 +- include/plat/arm/common/arm_fconf_getter.h | 24 +++ .../plat/arm/common/arm_fconf_io_storage.h | 19 +++ include/tools_share/uuid.h | 7 +- make_helpers/defaults.mk | 3 + plat/arm/board/fvp/fdts/fvp_fw_config.dts | 25 +++ plat/arm/board/fvp/platform.mk | 5 + plat/arm/common/arm_common.mk | 12 +- plat/arm/common/arm_fconf_io_storage.c | 142 +++++++++++++++++ plat/arm/common/fconf/arm_fconf_io.c | 143 ++++++++++++++++++ 12 files changed, 386 insertions(+), 5 deletions(-) create mode 100644 include/plat/arm/common/arm_fconf_getter.h create mode 100644 include/plat/arm/common/arm_fconf_io_storage.h create mode 100644 plat/arm/common/arm_fconf_io_storage.c create mode 100644 plat/arm/common/fconf/arm_fconf_io.c diff --git a/Makefile b/Makefile index 5167d2e53..42921edc5 100644 --- a/Makefile +++ b/Makefile @@ -777,6 +777,7 @@ $(eval $(call assert_boolean,SPM_MM)) $(eval $(call assert_boolean,TRUSTED_BOARD_BOOT)) $(eval $(call assert_boolean,USE_COHERENT_MEM)) $(eval $(call assert_boolean,USE_DEBUGFS)) +$(eval $(call assert_boolean,USE_FCONF_BASED_IO)) $(eval $(call assert_boolean,USE_ROMLIB)) $(eval $(call assert_boolean,USE_TBBR_DEFS)) $(eval $(call assert_boolean,WARMBOOT_ENABLE_DCACHE_EARLY)) @@ -845,6 +846,7 @@ $(eval $(call add_define,SPM_MM)) $(eval $(call add_define,TRUSTED_BOARD_BOOT)) $(eval $(call add_define,USE_COHERENT_MEM)) $(eval $(call add_define,USE_DEBUGFS)) +$(eval $(call add_define,USE_FCONF_BASED_IO)) $(eval $(call add_define,USE_ROMLIB)) $(eval $(call add_define,USE_TBBR_DEFS)) $(eval $(call add_define,WARMBOOT_ENABLE_DCACHE_EARLY)) diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index ca305355b..c1787a802 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -578,6 +578,11 @@ Common build options exposing a virtual filesystem interface through BL31 as a SiP SMC function. Default is 0. +- ``USE_FCONF_BASED_IO``: This flag determines whether to use IO based on the + firmware configuration framework. This allows moving the io_policies into a + configuration device tree, instead of static structure in the code base. + + - ``USE_ROMLIB``: This flag determines whether library at ROM will be used. This feature creates a library of functions to be placed in ROM and thus reduces SRAM usage. Refer to :ref:`Library at ROM` for further details. Default diff --git a/include/drivers/io/io_storage.h b/include/drivers/io/io_storage.h index 0e6ffd619..a301ad563 100644 --- a/include/drivers/io/io_storage.h +++ b/include/drivers/io/io_storage.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -53,7 +53,7 @@ typedef struct io_file_spec { /* UUID specification - used to refer to data accessed using UUIDs (i.e. FIP * images) */ typedef struct io_uuid_spec { - const uuid_t uuid; + uuid_t uuid; } io_uuid_spec_t; /* Block specification - used to refer to data on a device supporting diff --git a/include/plat/arm/common/arm_fconf_getter.h b/include/plat/arm/common/arm_fconf_getter.h new file mode 100644 index 000000000..28913a43f --- /dev/null +++ b/include/plat/arm/common/arm_fconf_getter.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2019-2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef ARM_FCONF_GETTER +#define ARM_FCONF_GETTER + +#include + +/* ARM io policies */ +#define arm__io_policies_getter(id) &policies[id] + +struct plat_io_policy { + uintptr_t *dev_handle; + uintptr_t image_spec; + int (*check)(const uintptr_t spec); +}; + +extern struct plat_io_policy policies[]; +int fconf_populate_arm_io_policies(uintptr_t config); + +#endif /* ARM_FCONF_GETTER */ diff --git a/include/plat/arm/common/arm_fconf_io_storage.h b/include/plat/arm/common/arm_fconf_io_storage.h new file mode 100644 index 000000000..02ee66c35 --- /dev/null +++ b/include/plat/arm/common/arm_fconf_io_storage.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef ARM_FCONF_IO_STORAGE_H +#define ARM_FCONF_IO_STORAGE_H + +#include + +/* IO devices handle */ +extern uintptr_t memmap_dev_handle; +extern uintptr_t fip_dev_handle; + +/* Function declarations */ +int open_fip(const uintptr_t spec); +int open_memmap(const uintptr_t spec); + +#endif /* ARM_FCONF_IO_STORAGE_H */ diff --git a/include/tools_share/uuid.h b/include/tools_share/uuid.h index 7d0043206..36be9ed37 100644 --- a/include/tools_share/uuid.h +++ b/include/tools_share/uuid.h @@ -27,7 +27,7 @@ */ /* - * Portions copyright (c) 2014, ARM Limited and Contributors. + * Portions copyright (c) 2014-2020, ARM Limited and Contributors. * All rights reserved. */ @@ -56,6 +56,11 @@ struct uuid { uint8_t node[_UUID_NODE_LEN]; }; +union uuid_helper_t { + struct uuid uuid_struct; + uint32_t word[4]; +}; + /* XXX namespace pollution? */ typedef struct uuid uuid_t; diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index fff336cd2..e8e990d45 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -201,6 +201,9 @@ USE_COHERENT_MEM := 1 # Build option to add debugfs support USE_DEBUGFS := 0 +# Build option to fconf based io +USE_FCONF_BASED_IO := 0 + # Build option to choose whether Trusted Firmware uses library at ROM USE_ROMLIB := 0 diff --git a/plat/arm/board/fvp/fdts/fvp_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_fw_config.dts index ff83db361..d0f60331d 100644 --- a/plat/arm/board/fvp/fdts/fvp_fw_config.dts +++ b/plat/arm/board/fvp/fdts/fvp_fw_config.dts @@ -68,4 +68,29 @@ mbedtls_heap_addr = <0x0 0x0>; mbedtls_heap_size = <0x0>; }; + + arm-io_policies { + fip-handles { + compatible = "arm,io-fip-handle"; + scp_bl2_uuid = <0x3dfd6697 0x49e8be89 0xa1785dae 0x13826040>; + bl31_uuid = <0x6d08d447 0x4698fe4c 0x5029959b 0x005abdcb>; + bl32_uuid = <0x89e1d005 0x4713dc53 0xa502b8d 0x383e7a4b>; + bl32_extra1_uuid = <0x9bc2700b 0x40785a2a 0x560a659f 0x88827382>; + bl32_extra2_uuid = <0xb17ba88e 0x4d3fa2cf 0xbbe7fd85 0xd92002a5>; + bl33_uuid = <0xa7eed0d6 0x4bd5eafc 0x34998297 0xe4b634f2>; + hw_cfg_uuid = <0xd9f1b808 0x4993cfc9 0xbc6f62a9 0xcc65726b>; + soc_fw_cfg_uuid = <0x4b817999 0x46fb7603 0x268d8e8c 0xe059787f>; + tos_fw_cfg_uuid = <0x1a7c2526 0x477fc6db 0xc4c4968d 0x218024b0>; + nt_fw_cfg_uuid = <0x1598da28 0x447ee893 0xaf1a66ac 0xf9501580>; + t_key_cert_uuid = <0x90e87e82 0x11e460f8 0x7a77b4a1 0x4cf9b421>; + scp_fw_key_uuid = <0xa1214202 0x11e460f8 0x3cf39b8d 0x14a0150e>; + soc_fw_key_uuid = <0xccbeb88a 0x11e460f9 0x48ebd09a 0xf8dcd822>; + tos_fw_key_cert_uuid = <0x3d67794 0x11e460fb 0x10b7dd85 0x4ee8c5b>; + nt_fw_key_cert_uuid = <0x2a83d58a 0x11e460fb 0x30dfaf8a 0x5998c4bb>; + scp_fw_content_cert_uuid = <0x046fbe44 0x11e4635e 0xd8738bb2 0x5696aeea>; + soc_fw_content_cert_uuid = <0x200cb2e2 0x11e4635e 0xccabe89c 0x66b62bf9>; + tos_fw_content_cert_uuid = <0x11449fa4 0x11e4635e 0x53f2887 0x3df32a72>; + nt_fw_content_cert_uuid = <0xf3c1c48e 0x11e4635d 0xee87a9a7 0xa73fb240>; + }; + }; }; diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index f46f8e211..9d7d768ce 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -10,6 +10,11 @@ FVP_USE_GIC_DRIVER := FVP_GICV3 # Use the SP804 timer instead of the generic one FVP_USE_SP804_TIMER := 0 +# Use fconf based io for FVP +ifeq ($(BL2_AT_EL3), 0) +USE_FCONF_BASED_IO := 1 +endif + # Default cluster count for FVP FVP_CLUSTER_COUNT := 2 diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index ceff6e2bb..a4d365e9a 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -177,12 +177,20 @@ include lib/xlat_tables_v2/xlat_tables.mk PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS} endif +ifeq (${USE_FCONF_BASED_IO}, 0) +ARM_IO_SOURCES += plat/arm/common/arm_io_storage.c +else +ARM_IO_SOURCES += plat/arm/common/arm_fconf_io_storage.c \ + plat/arm/common/fconf/arm_fconf_io.c +endif + BL1_SOURCES += drivers/io/io_fip.c \ drivers/io/io_memmap.c \ drivers/io/io_storage.c \ plat/arm/common/arm_bl1_setup.c \ plat/arm/common/arm_err.c \ - plat/arm/common/arm_io_storage.c + ${ARM_IO_SOURCES} + ifdef EL3_PAYLOAD_BASE # Need the plat_arm_program_trusted_mailbox() function to release secondary CPUs from # their holding pen @@ -196,7 +204,7 @@ BL2_SOURCES += drivers/delay_timer/delay_timer.c \ drivers/io/io_storage.c \ plat/arm/common/arm_bl2_setup.c \ plat/arm/common/arm_err.c \ - plat/arm/common/arm_io_storage.c + ${ARM_IO_SOURCES} # Firmware Configuration Framework sources include lib/fconf/fconf.mk diff --git a/plat/arm/common/arm_fconf_io_storage.c b/plat/arm/common/arm_fconf_io_storage.c new file mode 100644 index 000000000..afc8dbe47 --- /dev/null +++ b/plat/arm/common/arm_fconf_io_storage.c @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2015-2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/* IO devices */ +static const io_dev_connector_t *fip_dev_con; +uintptr_t fip_dev_handle; +static const io_dev_connector_t *memmap_dev_con; +uintptr_t memmap_dev_handle; + +/* Weak definitions may be overridden in specific ARM standard platform */ +#pragma weak plat_arm_io_setup +#pragma weak plat_arm_get_alt_image_source + +int open_fip(const uintptr_t spec) +{ + int result; + uintptr_t local_image_handle; + + /* See if a Firmware Image Package is available */ + result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); + if (result == 0) { + result = io_open(fip_dev_handle, spec, &local_image_handle); + if (result == 0) { + VERBOSE("Using FIP\n"); + io_close(local_image_handle); + } + } + return result; +} + +int open_memmap(const uintptr_t spec) +{ + int result; + uintptr_t local_image_handle; + + result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL); + if (result == 0) { + result = io_open(memmap_dev_handle, spec, &local_image_handle); + if (result == 0) { + VERBOSE("Using Memmap\n"); + io_close(local_image_handle); + } + } + return result; +} + +void arm_io_setup(void) +{ + int io_result; + + io_result = register_io_dev_fip(&fip_dev_con); + assert(io_result == 0); + + io_result = register_io_dev_memmap(&memmap_dev_con); + assert(io_result == 0); + + /* Open connections to devices and cache the handles */ + io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL, + &fip_dev_handle); + assert(io_result == 0); + + io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, + &memmap_dev_handle); + assert(io_result == 0); + + /* Ignore improbable errors in release builds */ + (void)io_result; +} + +void plat_arm_io_setup(void) +{ + arm_io_setup(); +} + +int plat_arm_get_alt_image_source( + unsigned int image_id __unused, + uintptr_t *dev_handle __unused, + uintptr_t *image_spec __unused) +{ + /* By default do not try an alternative */ + return -ENOENT; +} + +/* Return an IO device handle and specification which can be used to access + * an image. Use this to enforce platform load policy */ +int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, + uintptr_t *image_spec) +{ + int result; + const struct plat_io_policy *policy; + + assert(image_id < MAX_NUMBER_IDS); + + policy = FCONF_GET_PROPERTY(arm, io_policies, image_id); + result = policy->check(policy->image_spec); + if (result == 0) { + *image_spec = policy->image_spec; + *dev_handle = *(policy->dev_handle); + } else { + VERBOSE("Trying alternative IO\n"); + result = plat_arm_get_alt_image_source(image_id, dev_handle, + image_spec); + } + + return result; +} + +/* + * See if a Firmware Image Package is available, + * by checking if TOC is valid or not. + */ +int arm_io_is_toc_valid(void) +{ + int result; + + result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); + + if (result == 0) { + return 1UL; + } else { + return 0UL; + } +} diff --git a/plat/arm/common/fconf/arm_fconf_io.c b/plat/arm/common/fconf/arm_fconf_io.c new file mode 100644 index 000000000..3c0586fd0 --- /dev/null +++ b/plat/arm/common/fconf/arm_fconf_io.c @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2019-2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +const io_block_spec_t fip_block_spec = { + .offset = PLAT_ARM_FIP_BASE, + .length = PLAT_ARM_FIP_MAX_SIZE +}; + +const io_uuid_spec_t arm_uuid_spec[MAX_NUMBER_IDS] = { + [BL2_IMAGE_ID] = {UUID_TRUSTED_BOOT_FIRMWARE_BL2}, + [TB_FW_CONFIG_ID] = {UUID_TB_FW_CONFIG}, +#if TRUSTED_BOARD_BOOT + [TRUSTED_BOOT_FW_CERT_ID] = {UUID_TRUSTED_BOOT_FW_CERT}, +#endif /* TRUSTED_BOARD_BOOT */ +}; + +/* By default, ARM platforms load images from the FIP */ +struct plat_io_policy policies[MAX_NUMBER_IDS] = { + [FIP_IMAGE_ID] = { + &memmap_dev_handle, + (uintptr_t)&fip_block_spec, + open_memmap + }, + [BL2_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[BL2_IMAGE_ID], + open_fip + }, + [TB_FW_CONFIG_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[TB_FW_CONFIG_ID], + open_fip + }, +#if TRUSTED_BOARD_BOOT + [TRUSTED_BOOT_FW_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[TRUSTED_BOOT_FW_CERT_ID], + open_fip + }, +#endif /* TRUSTED_BOARD_BOOT */ +}; + +#ifdef IMAGE_BL2 + +#if TRUSTED_BOARD_BOOT +#define FCONF_ARM_IO_UUID_NUMBER 19 +#else +#define FCONF_ARM_IO_UUID_NUMBER 10 +#endif + +static io_uuid_spec_t fconf_arm_uuids[FCONF_ARM_IO_UUID_NUMBER]; +static OBJECT_POOL_ARRAY(fconf_arm_uuids_pool, fconf_arm_uuids); + +struct policies_load_info { + unsigned int image_id; + const char *name; +}; + +/* image id to property name table */ +static const struct policies_load_info load_info[FCONF_ARM_IO_UUID_NUMBER] = { + {SCP_BL2_IMAGE_ID, "scp_bl2_uuid"}, + {BL31_IMAGE_ID, "bl31_uuid"}, + {BL32_IMAGE_ID, "bl32_uuid"}, + {BL32_EXTRA1_IMAGE_ID, "bl32_extra1_uuid"}, + {BL32_EXTRA2_IMAGE_ID, "bl32_extra2_uuid"}, + {BL33_IMAGE_ID, "bl33_uuid"}, + {HW_CONFIG_ID, "hw_cfg_uuid"}, + {SOC_FW_CONFIG_ID, "soc_fw_cfg_uuid"}, + {TOS_FW_CONFIG_ID, "tos_fw_cfg_uuid"}, + {NT_FW_CONFIG_ID, "nt_fw_cfg_uuid"}, +#if TRUSTED_BOARD_BOOT + {TRUSTED_KEY_CERT_ID, "t_key_cert_uuid"}, + {SCP_FW_KEY_CERT_ID, "scp_fw_key_uuid"}, + {SOC_FW_KEY_CERT_ID, "soc_fw_key_uuid"}, + {TRUSTED_OS_FW_KEY_CERT_ID, "tos_fw_key_cert_uuid"}, + {NON_TRUSTED_FW_KEY_CERT_ID, "nt_fw_key_cert_uuid"}, + {SCP_FW_CONTENT_CERT_ID, "scp_fw_content_cert_uuid"}, + {SOC_FW_CONTENT_CERT_ID, "soc_fw_content_cert_uuid"}, + {TRUSTED_OS_FW_CONTENT_CERT_ID, "tos_fw_content_cert_uuid"}, + {NON_TRUSTED_FW_CONTENT_CERT_ID, "nt_fw_content_cert_uuid"}, +#endif /* TRUSTED_BOARD_BOOT */ +}; + +int fconf_populate_arm_io_policies(uintptr_t config) +{ + int err, node; + unsigned int i; + + union uuid_helper_t uuid_helper; + io_uuid_spec_t *uuid_ptr; + + /* As libfdt uses void *, we can't avoid this cast */ + const void *dtb = (void *)config; + + /* Assert the node offset point to "arm,io-fip-handle" compatible property */ + const char *compatible_str = "arm,io-fip-handle"; + node = fdt_node_offset_by_compatible(dtb, -1, compatible_str); + if (node < 0) { + ERROR("FCONF: Can't find %s compatible in dtb\n", compatible_str); + return node; + } + + /* Locate the uuid cells and read the value for all the load info uuid */ + for (i = 0; i < FCONF_ARM_IO_UUID_NUMBER; i++) { + uuid_ptr = pool_alloc(&fconf_arm_uuids_pool); + err = fdtw_read_array(dtb, node, load_info[i].name, 4, &uuid_helper.word); + if (err < 0) { + WARN("FCONF: Read cell failed for %s\n", load_info[i].name); + return err; + } + + VERBOSE("FCONF: arm-io_policies.%s cell found with value = 0x%x 0x%x 0x%x 0x%x\n", + load_info[i].name, + uuid_helper.word[0], uuid_helper.word[1], + uuid_helper.word[2], uuid_helper.word[3]); + + uuid_ptr->uuid = uuid_helper.uuid_struct; + policies[load_info[i].image_id].image_spec = (uintptr_t)uuid_ptr; + policies[load_info[i].image_id].dev_handle = &fip_dev_handle; + policies[load_info[i].image_id].check = open_fip; + } + return 0; +} + +FCONF_REGISTER_POPULATOR(arm_io, fconf_populate_arm_io_policies); + +#endif /* IMAGE_BL2 */ From 326150b9862c7ee359dd5c189c8c6e10622551d6 Mon Sep 17 00:00:00 2001 From: Louis Mayencourt Date: Fri, 8 Nov 2019 15:09:15 +0000 Subject: [PATCH 08/10] fconf: Add documentation Change-Id: I606f9491fb6deebc6845c5b9d7db88fc5c895bd9 Signed-off-by: Louis Mayencourt --- docs/components/fconf.rst | 85 +++++++++++++++++++ docs/components/index.rst | 1 + docs/global_substitutions.txt | 2 + docs/glossary.rst | 6 ++ .../plantuml/fconf_bl1_load_config.puml | 52 ++++++++++++ .../diagrams/plantuml/fconf_bl2_populate.puml | 41 +++++++++ 6 files changed, 187 insertions(+) create mode 100644 docs/components/fconf.rst create mode 100644 docs/resources/diagrams/plantuml/fconf_bl1_load_config.puml create mode 100644 docs/resources/diagrams/plantuml/fconf_bl2_populate.puml diff --git a/docs/components/fconf.rst b/docs/components/fconf.rst new file mode 100644 index 000000000..cec3cebe4 --- /dev/null +++ b/docs/components/fconf.rst @@ -0,0 +1,85 @@ +Firmware Configuration Framework +================================ + +This document provides an overview of the |FCONF| framework. + +Introduction +~~~~~~~~~~~~ + +The Firmware CONfiguration Framework (|FCONF|) is an abstraction layer for +platform specific data, allowing a "property" to be queried and a value +retrieved without the requesting entity knowing what backing store is being used +to hold the data. + +It is used to bridge new and old ways of providing platform-specific data. +Today, information like the Chain of Trust is held within several, nested +platform-defined tables. In the future, it may be provided as part of a device +blob, along with the rest of the information about images to load. +Introducing this abstraction layer will make migration easier and will preserve +functionality for platforms that cannot / don't want to use device tree. + +Accessing properties +~~~~~~~~~~~~~~~~~~~~ + +Properties defined in the |FCONF| are grouped around namespaces and +sub-namespaces: a.b.property. +Examples namespace can be: + +- (|TBBR|) Chain of Trust data: tbbr.cot.trusted_boot_fw_cert +- (|TBBR|) dynamic configuration info: tbbr.dyn_config.disable_auth +- Arm io policies: arm.io_policies.bl2_image + +Properties can be accessed with the ``FCONF_GET_PROPERTY(a,b,property)`` macro. + +Defining properties +~~~~~~~~~~~~~~~~~~~ + +Properties composing the |FCONF| have to be stored in C structures. If another +backing store is wanted to be used, the platform has to provide a ``populate()`` +function to fill the corresponding C structure. + +The ``populate()`` function must be registered to the |FCONF| framework with +the ``FCONF_REGISTER_POPULATOR()`` macro. This ensures that the function would +be called inside the generic ``fconf_populate()`` function during +initialization. + +:: + + int fconf_populate_tbbr_dyn_config(uintptr_t config) + { + /* read dtb and fill tbbr_dyn_config struct */ + } + + FCONF_REGISTER_POPULATOR(fconf_populate_tbbr_dyn_config); + +Then, a wrapper has to be provided to match the ``FCONF_GET_PROPERTY()`` macro: + +:: + + /* generic getter */ + #define FCONF_GET_PROPERTY(a,b,property) a##__##b##_getter(property) + + /* my specific getter */ + #define tbbr__dyn_config_getter(id) tbbr_dyn_config.id + +This second level wrapper can be used to remap the ``FCONF_GET_PROPERTY()`` to +anything appropriate: structure, array, function, etc.. + +Loading the property device tree +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ``fconf_load_config()`` must be called to load the device tree containing +the properties' values. This must be done after the io layer is initialized, as +the |DTB| is stored on an external device (FIP). + +.. uml:: ../resources/diagrams/plantuml/fconf_bl1_load_config.puml + +Populating the properties +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Once a valid device tree is available, the ``fconf_populate(config)`` function +can be used to fill the C data structure with the data from the config |DTB|. +This function will call all the ``populate()`` callbacks which have been +registered with ``FCONF_REGISTER_POPULATOR()``. + +.. uml:: ../resources/diagrams/plantuml/fconf_bl2_populate.puml diff --git a/docs/components/index.rst b/docs/components/index.rst index f1904c004..6a6b1b0d5 100644 --- a/docs/components/index.rst +++ b/docs/components/index.rst @@ -9,6 +9,7 @@ Components spd/index arm-sip-service exception-handling + fconf firmware-update platform-interrupt-controller-API ras diff --git a/docs/global_substitutions.txt b/docs/global_substitutions.txt index 491b160e6..4dda1dcd4 100644 --- a/docs/global_substitutions.txt +++ b/docs/global_substitutions.txt @@ -6,11 +6,13 @@ .. |COT| replace:: :term:`COT` .. |CSS| replace:: :term:`CSS` .. |CVE| replace:: :term:`CVE` +.. |DTB| replace:: :term:`DTB` .. |DS-5| replace:: :term:`DS-5` .. |DSU| replace:: :term:`DSU` .. |DT| replace:: :term:`DT` .. |EL| replace:: :term:`EL` .. |EHF| replace:: :term:`EHF` +.. |FCONF| replace:: :term:`FCONF` .. |FDT| replace:: :term:`FDT` .. |FIP| replace:: :term:`FIP` .. |FVP| replace:: :term:`FVP` diff --git a/docs/glossary.rst b/docs/glossary.rst index 2f19df59c..3da30b02a 100644 --- a/docs/glossary.rst +++ b/docs/glossary.rst @@ -42,12 +42,18 @@ You can find additional definitions in the `Arm Glossary`_. DT Device Tree + DTB + Device Tree Blob + EL Exception Level EHF Exception Handling Framework + FCONF + Firmware Configuration Framework + FDT Flattened Device Tree diff --git a/docs/resources/diagrams/plantuml/fconf_bl1_load_config.puml b/docs/resources/diagrams/plantuml/fconf_bl1_load_config.puml new file mode 100644 index 000000000..c36e54423 --- /dev/null +++ b/docs/resources/diagrams/plantuml/fconf_bl1_load_config.puml @@ -0,0 +1,52 @@ +@startuml + +box "BL1 common code" + participant bl1_main + participant bl_common +end box + +box "arm platform code" #LightBlue + participant fvp_bl1_setup + participant arm_bl1_setup + participant arm_io_storage +end box + +box "platform common code" + participant plat_bl1_common + participant fconf +end box + +bl1_main -> fvp_bl1_setup : bl1_platform_setup() +fvp_bl1_setup -> arm_bl1_setup : arm_bl1_platform_setup() +arm_bl1_setup -> arm_io_storage : plat_arm_io_setup() +note over arm_io_storage : register and setup fip +arm_bl1_setup -> fconf : fconf_load_config() +activate fconf + note over fconf + create and populate an + image_desc_t for TB_FW_CONFIG + end note + fconf -> bl_common : load_auth_image(TB_FW_CONFIG_ID, &image_info) + activate bl_common + note over bl_common + load and auth image from fip + with info from plat_io_policy + end note + bl_common -> arm_io_storage + arm_io_storage -> fconf: FCONF_GET_PROPERTY(arm, arm_io_policies, tb_fw_cfg) + note over fconf: use staticaly defined policies in bl1 + fconf <- bl_common : image_info + deactivate bl_common + note over fconf : get tb_fw_config_dtb from image_info + fconf -> plat_bl1_common : bl1_plat_get_image_desc(BL2_IMAGE_ID) + fconf <- plat_bl1_common : BL2_IMAGE_DESC + note over fconf + set ep_info.args.arg0 of BL2_IMAGE_DESC + to TB_FW_CONFIG base address + end note +arm_bl1_setup <- fconf +deactivate fconf + +== load & auth, prepare and jump to BL2 == + +@enduml diff --git a/docs/resources/diagrams/plantuml/fconf_bl2_populate.puml b/docs/resources/diagrams/plantuml/fconf_bl2_populate.puml new file mode 100644 index 000000000..98a3ff19b --- /dev/null +++ b/docs/resources/diagrams/plantuml/fconf_bl2_populate.puml @@ -0,0 +1,41 @@ +@startuml + +box "BL2 common code" + participant bl2_entrypoint + participant bl2_main +end box + +box "platform common code" + participant fconf + participant fconf_tbbr_getter +end box + +box "arm platform code" #LightBlue + participant arm_bl2_setup + participant arm_io_storage + participant arm_fconf_io +end box + +== bl2 setup == +bl2_entrypoint -> bl2_main : bl2_setup() +bl2_main -> arm_bl2_setup : bl2_early_platform_setup2(\n\t arg0, arg1, arg2, arg3) +note over arm_bl2_setup + arg0 = tb_fw_config + arg1 = mem_layout +end note +arm_bl2_setup -> arm_bl2_setup : arm_bl2_early_platform_setup(\n\t tb_fw_config, mem_layout) +activate arm_bl2_setup + arm_bl2_setup -> fconf: fconf_polulate(tb_fw_config) + activate fconf + fconf -> fconf_tbbr_getter: fconf_populate_tbbr_dyn_config(uintptr_t dtb) + note over fconf_tbbr_getter: read tbbr propeties from dtb + fconf -> arm_fconf_io: fconf_populate_arm_io_policies(uintptr_t dtb) + note over arm_fconf_io: read arm io propeties from dtb + deactivate fconf + arm_bl2_setup -> arm_io_storage : plat_arm_io_setup() + note over arm_io_storage: use populated properties +deactivate arm_bl2_setup + +== bl2 main == + +@enduml From d6dcbcad1897fcb2ca3c6c56c034f44f0274a5bf Mon Sep 17 00:00:00 2001 From: Louis Mayencourt Date: Wed, 29 Jan 2020 11:42:31 +0000 Subject: [PATCH 09/10] MISRA fix: Use boolean essential type Change the return type of "arm_io_is_toc_valid()" and "plat_arm_bl1_fwu_needed()" to bool, to match function behavior. Change-Id: I503fba211219a241cb263149ef36ca14e3362a1c Signed-off-by: Louis Mayencourt --- include/plat/arm/common/plat_arm.h | 5 +++-- plat/arm/board/juno/juno_bl1_setup.c | 12 ++++-------- plat/arm/common/arm_bl1_setup.c | 9 +++------ plat/arm/common/arm_fconf_io_storage.c | 12 ++---------- plat/arm/common/arm_io_storage.c | 10 +++------- 5 files changed, 15 insertions(+), 33 deletions(-) diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index 129ceca66..4751314f2 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -6,6 +6,7 @@ #ifndef PLAT_ARM_H #define PLAT_ARM_H +#include #include #include @@ -222,7 +223,7 @@ void arm_sp_min_early_platform_setup(void *from_bl2, uintptr_t tos_fw_config, void arm_sp_min_plat_runtime_setup(void); /* FIP TOC validity check */ -int arm_io_is_toc_valid(void); +bool arm_io_is_toc_valid(void); /* Utility functions for Dynamic Config */ void arm_bl2_dyn_cfg_init(void); @@ -254,7 +255,7 @@ void plat_arm_interconnect_init(void); void plat_arm_interconnect_enter_coherency(void); void plat_arm_interconnect_exit_coherency(void); void plat_arm_program_trusted_mailbox(uintptr_t address); -int plat_arm_bl1_fwu_needed(void); +bool plat_arm_bl1_fwu_needed(void); __dead2 void plat_arm_error_handler(int err); /* diff --git a/plat/arm/board/juno/juno_bl1_setup.c b/plat/arm/board/juno/juno_bl1_setup.c index 89398d686..25a27da07 100644 --- a/plat/arm/board/juno/juno_bl1_setup.c +++ b/plat/arm/board/juno/juno_bl1_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -60,17 +60,13 @@ static int is_watchdog_reset(void) * The following function checks if Firmware update is needed, * by checking if TOC in FIP image is valid or watchdog reset happened. ******************************************************************************/ -int plat_arm_bl1_fwu_needed(void) +bool plat_arm_bl1_fwu_needed(void) { const int32_t *nv_flags_ptr = (const int32_t *)V2M_SYS_NVFLAGS_ADDR; /* Check if TOC is invalid or watchdog reset happened. */ - if ((arm_io_is_toc_valid() != 1) || - (((*nv_flags_ptr == -EAUTH) || (*nv_flags_ptr == -ENOENT)) - && is_watchdog_reset())) - return 1; - - return 0; + return (!arm_io_is_toc_valid() || (((*nv_flags_ptr == -EAUTH) || + (*nv_flags_ptr == -ENOENT)) && is_watchdog_reset())); } /******************************************************************************* diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c index bf4d7bd5c..c2f49c211 100644 --- a/plat/arm/common/arm_bl1_setup.c +++ b/plat/arm/common/arm_bl1_setup.c @@ -188,9 +188,9 @@ void bl1_plat_prepare_exit(entry_point_info_t *ep_info) * On Arm platforms, the FWU process is triggered when the FIP image has * been tampered with. */ -int plat_arm_bl1_fwu_needed(void) +bool plat_arm_bl1_fwu_needed(void) { - return (arm_io_is_toc_valid() != 1); + return !arm_io_is_toc_valid(); } /******************************************************************************* @@ -199,8 +199,5 @@ int plat_arm_bl1_fwu_needed(void) ******************************************************************************/ unsigned int bl1_plat_get_next_image_id(void) { - if (plat_arm_bl1_fwu_needed() != 0) - return NS_BL1U_IMAGE_ID; - - return BL2_IMAGE_ID; + return plat_arm_bl1_fwu_needed() ? NS_BL1U_IMAGE_ID : BL2_IMAGE_ID; } diff --git a/plat/arm/common/arm_fconf_io_storage.c b/plat/arm/common/arm_fconf_io_storage.c index afc8dbe47..6bbdb3cf2 100644 --- a/plat/arm/common/arm_fconf_io_storage.c +++ b/plat/arm/common/arm_fconf_io_storage.c @@ -128,15 +128,7 @@ int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, * See if a Firmware Image Package is available, * by checking if TOC is valid or not. */ -int arm_io_is_toc_valid(void) +bool arm_io_is_toc_valid(void) { - int result; - - result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); - - if (result == 0) { - return 1UL; - } else { - return 0UL; - } + return (io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID) == 0); } diff --git a/plat/arm/common/arm_io_storage.c b/plat/arm/common/arm_io_storage.c index fc1eb490e..60d19b24e 100644 --- a/plat/arm/common/arm_io_storage.c +++ b/plat/arm/common/arm_io_storage.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -357,12 +357,8 @@ int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, * See if a Firmware Image Package is available, * by checking if TOC is valid or not. */ -int arm_io_is_toc_valid(void) +bool arm_io_is_toc_valid(void) { - int result; - - result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); - - return (result == 0); + return (io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID) == 0); } From 97399821256653115c9d6b5d3233934aa7689c0c Mon Sep 17 00:00:00 2001 From: Louis Mayencourt Date: Wed, 29 Jan 2020 14:43:06 +0000 Subject: [PATCH 10/10] arm-io: Panic in case of io setup failure Currently, an IO setup failure will be ignored on arm platform release build. Change this to panic instead. Change-Id: I027a045bce2422b0a0fc4ff9e9d4c6e7bf5d2f98 Signed-off-by: Louis Mayencourt --- include/plat/arm/common/plat_arm.h | 2 +- plat/arm/board/fvp/fvp_io_storage.c | 18 +++++++++++------- plat/arm/common/arm_fconf_io_storage.c | 25 +++++++++++++++++-------- plat/arm/common/arm_io_storage.c | 25 +++++++++++++++++-------- 4 files changed, 46 insertions(+), 24 deletions(-) diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index 4751314f2..025a64fa2 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -149,7 +149,7 @@ void arm_setup_romlib(void); #define ARM_ROTPK_DEVEL_ECDSA_ID 3 /* IO storage utility functions */ -void arm_io_setup(void); +int arm_io_setup(void); /* Security utility functions */ void arm_tzc400_setup(const arm_tzc_regions_info_t *tzc_regions); diff --git a/plat/arm/board/fvp/fvp_io_storage.c b/plat/arm/board/fvp/fvp_io_storage.c index 9c4c1d574..109d32150 100644 --- a/plat/arm/board/fvp/fvp_io_storage.c +++ b/plat/arm/board/fvp/fvp_io_storage.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -120,18 +120,22 @@ void plat_arm_io_setup(void) { int io_result; - arm_io_setup(); + io_result = arm_io_setup(); + if (io_result < 0) { + panic(); + } /* Register the additional IO devices on this platform */ io_result = register_io_dev_sh(&sh_dev_con); - assert(io_result == 0); + if (io_result < 0) { + panic(); + } /* Open connections to devices and cache the handles */ io_result = io_dev_open(sh_dev_con, (uintptr_t)NULL, &sh_dev_handle); - assert(io_result == 0); - - /* Ignore improbable errors in release builds */ - (void)io_result; + if (io_result < 0) { + panic(); + } } /* diff --git a/plat/arm/common/arm_fconf_io_storage.c b/plat/arm/common/arm_fconf_io_storage.c index 6bbdb3cf2..341622a0b 100644 --- a/plat/arm/common/arm_fconf_io_storage.c +++ b/plat/arm/common/arm_fconf_io_storage.c @@ -63,32 +63,41 @@ int open_memmap(const uintptr_t spec) return result; } -void arm_io_setup(void) +int arm_io_setup(void) { int io_result; io_result = register_io_dev_fip(&fip_dev_con); - assert(io_result == 0); + if (io_result < 0) { + return io_result; + } io_result = register_io_dev_memmap(&memmap_dev_con); - assert(io_result == 0); + if (io_result < 0) { + return io_result; + } /* Open connections to devices and cache the handles */ io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL, &fip_dev_handle); - assert(io_result == 0); + if (io_result < 0) { + return io_result; + } io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, &memmap_dev_handle); - assert(io_result == 0); - /* Ignore improbable errors in release builds */ - (void)io_result; + return io_result; } void plat_arm_io_setup(void) { - arm_io_setup(); + int err; + + err = arm_io_setup(); + if (err < 0) { + panic(); + } } int plat_arm_get_alt_image_source( diff --git a/plat/arm/common/arm_io_storage.c b/plat/arm/common/arm_io_storage.c index 60d19b24e..f5d8a414d 100644 --- a/plat/arm/common/arm_io_storage.c +++ b/plat/arm/common/arm_io_storage.c @@ -292,32 +292,41 @@ static int open_memmap(const uintptr_t spec) } -void arm_io_setup(void) +int arm_io_setup(void) { int io_result; io_result = register_io_dev_fip(&fip_dev_con); - assert(io_result == 0); + if (io_result < 0) { + return io_result; + } io_result = register_io_dev_memmap(&memmap_dev_con); - assert(io_result == 0); + if (io_result < 0) { + return io_result; + } /* Open connections to devices and cache the handles */ io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL, &fip_dev_handle); - assert(io_result == 0); + if (io_result < 0) { + return io_result; + } io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, &memmap_dev_handle); - assert(io_result == 0); - /* Ignore improbable errors in release builds */ - (void)io_result; + return io_result; } void plat_arm_io_setup(void) { - arm_io_setup(); + int err; + + err = arm_io_setup(); + if (err < 0) { + panic(); + } } int plat_arm_get_alt_image_source(