From ab1981db9ea793accf1279446b9f7666a3be04ca Mon Sep 17 00:00:00 2001 From: Louis Mayencourt Date: Thu, 8 Aug 2019 12:03:26 +0100 Subject: 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 --- lib/fconf/fconf.c | 40 ++++++++++++++++++++++++++++++++++++++++ lib/fconf/fconf.mk | 11 +++++++++++ 2 files changed, 51 insertions(+) create mode 100644 lib/fconf/fconf.c create mode 100644 lib/fconf/fconf.mk (limited to 'lib') 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} -- cgit v1.2.3 From 3b5ea741fd92088c9e005d3508b73e50f1d5daf7 Mon Sep 17 00:00:00 2001 From: Louis Mayencourt Date: Thu, 17 Oct 2019 14:46:51 +0100 Subject: 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 --- lib/fconf/fconf.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'lib') 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); -- cgit v1.2.3 From 9814bfc1bfc4868a8505d3756aceea5ad41a8c64 Mon Sep 17 00:00:00 2001 From: Louis Mayencourt Date: Thu, 17 Oct 2019 15:14:25 +0100 Subject: 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 --- lib/fconf/fconf.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'lib') 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; } -- cgit v1.2.3 From 25ac87940cd3db8036f967d01653c0db64e4c136 Mon Sep 17 00:00:00 2001 From: Louis Mayencourt Date: Tue, 17 Dec 2019 13:17:25 +0000 Subject: 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 --- lib/fconf/fconf.c | 2 +- lib/fconf/fconf.mk | 3 +- lib/fconf/fconf_dyn_cfg_getter.c | 95 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 lib/fconf/fconf_dyn_cfg_getter.c (limited to 'lib') 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); -- cgit v1.2.3 From ce8528411a95d4e988844d5d16b5af2828f9f407 Mon Sep 17 00:00:00 2001 From: Louis Mayencourt Date: Mon, 30 Sep 2019 10:57:24 +0100 Subject: 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 --- lib/fconf/fconf_tbbr_getter.c | 56 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 lib/fconf/fconf_tbbr_getter.c (limited to 'lib') 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); -- cgit v1.2.3 From 6c9723176019cb5327d5be0e952583809b714f5f Mon Sep 17 00:00:00 2001 From: Louis Mayencourt Date: Tue, 1 Oct 2019 10:45:14 +0100 Subject: 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 --- lib/fconf/fconf_tbbr_getter.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'lib') 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; } -- cgit v1.2.3