diff --git a/common/desc_image_load.c b/common/desc_image_load.c index e68e69ca0..147dfbff4 100644 --- a/common/desc_image_load.c +++ b/common/desc_image_load.c @@ -190,3 +190,65 @@ bl_params_t *get_next_bl_params_from_mem_params_desc(void) return &next_bl_params; } + +/******************************************************************************* + * This function populates the entry point information with the corresponding + * config file for all executable BL images described in bl_params. + ******************************************************************************/ +void populate_next_bl_params_config(bl_params_t *bl2_to_next_bl_params) +{ + bl_params_node_t *params_node; + unsigned int fw_config_id; + uintptr_t hw_config_base = 0, fw_config_base; + bl_mem_params_node_t *mem_params; + + assert(bl2_to_next_bl_params); + + /* + * Get the `bl_mem_params_node_t` corresponding to HW_CONFIG + * if available. + */ + mem_params = get_bl_mem_params_node(HW_CONFIG_ID); + if (mem_params != NULL) + hw_config_base = mem_params->image_info.image_base; + + for (params_node = bl2_to_next_bl_params->head; params_node != NULL; + params_node = params_node->next_params_info) { + + fw_config_base = 0; + + switch (params_node->image_id) { + case BL31_IMAGE_ID: + fw_config_id = SOC_FW_CONFIG_ID; + break; + case BL32_IMAGE_ID: + fw_config_id = TOS_FW_CONFIG_ID; + break; + case BL33_IMAGE_ID: + fw_config_id = NT_FW_CONFIG_ID; + break; + default: + fw_config_id = INVALID_IMAGE_ID; + break; + } + + if (fw_config_id != INVALID_IMAGE_ID) { + mem_params = get_bl_mem_params_node(fw_config_id); + if (mem_params != NULL) + fw_config_base = mem_params->image_info.image_base; + } + + /* + * Pass hw and tb_fw config addresses to next images. NOTE - for + * EL3 runtime images (BL31 for AArch64 and BL32 for AArch32), + * arg0 is already used by generic code. + */ + if (params_node == bl2_to_next_bl_params->head) { + params_node->ep_info->args.arg1 = fw_config_base; + params_node->ep_info->args.arg2 = hw_config_base; + } else { + params_node->ep_info->args.arg0 = fw_config_base; + params_node->ep_info->args.arg1 = hw_config_base; + } + } +} diff --git a/include/common/desc_image_load.h b/include/common/desc_image_load.h index 79f2bd7b8..f183db50d 100644 --- a/include/common/desc_image_load.h +++ b/include/common/desc_image_load.h @@ -33,7 +33,7 @@ int get_bl_params_node_index(unsigned int image_id); bl_mem_params_node_t *get_bl_mem_params_node(unsigned int image_id); bl_load_info_t *get_bl_load_info_from_mem_params_desc(void); bl_params_t *get_next_bl_params_from_mem_params_desc(void); - +void populate_next_bl_params_config(bl_params_t *bl2_to_next_bl_params); #endif /* LOAD_IMAGE_V2 */ #endif /* __DESC_IMAGE_LOAD_H__ */ diff --git a/include/plat/arm/board/common/board_arm_def.h b/include/plat/arm/board/common/board_arm_def.h index 888629e32..12a21fb73 100644 --- a/include/plat/arm/board/common/board_arm_def.h +++ b/include/plat/arm/board/common/board_arm_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ diff --git a/include/plat/arm/common/arm_dyn_cfg_helpers.h b/include/plat/arm/common/arm_dyn_cfg_helpers.h new file mode 100644 index 000000000..4a0f6397d --- /dev/null +++ b/include/plat/arm/common/arm_dyn_cfg_helpers.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef __ARM_DYN_CFG_HELPERS_H__ +#define __ARM_DYN_CFG_HELPERS_H__ + +#include + +/* Function declaration */ +int arm_dyn_get_hwconfig_info(void *dtb, int node, + uint64_t *hw_config_addr, uint32_t *hw_config_size); +int arm_dyn_tb_fw_cfg_init(void *dtb, int *node); + +#endif /* __ARM_DYN_CFG_HELPERS_H__ */ diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index 933caeeda..b2c7bd276 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -19,6 +19,7 @@ struct bl31_params; struct meminfo; struct image_info; +struct bl_params; #define ARM_CASSERT_MMAP \ CASSERT((ARRAY_SIZE(plat_arm_mmap) + ARM_BL_REGIONS) \ @@ -138,7 +139,7 @@ void arm_bl1_platform_setup(void); void arm_bl1_plat_arch_setup(void); /* BL2 utility functions */ -void arm_bl2_early_platform_setup(struct meminfo *mem_layout); +void arm_bl2_early_platform_setup(uintptr_t tb_fw_config, struct meminfo *mem_layout); void arm_bl2_platform_setup(void); void arm_bl2_plat_arch_setup(void); uint32_t arm_get_spsr_for_bl32_entry(void); @@ -180,6 +181,8 @@ 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); /* * Mandatory functions required in ARM standard platforms diff --git a/plat/arm/board/fvp/fvp_bl2_setup.c b/plat/arm/board/fvp/fvp_bl2_setup.c index 4315c1f37..415de052c 100644 --- a/plat/arm/board/fvp/fvp_bl2_setup.c +++ b/plat/arm/board/fvp/fvp_bl2_setup.c @@ -14,7 +14,7 @@ void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) { - arm_bl2_early_platform_setup((meminfo_t *)arg1); + arm_bl2_early_platform_setup((uintptr_t)arg0, (meminfo_t *)arg1); /* Initialize the platform config for future decision making */ fvp_config_setup(); diff --git a/plat/arm/board/fvp/fvp_io_storage.c b/plat/arm/board/fvp/fvp_io_storage.c index f18303ffa..11c7c3bcd 100644 --- a/plat/arm/board/fvp/fvp_io_storage.c +++ b/plat/arm/board/fvp/fvp_io_storage.c @@ -19,6 +19,7 @@ #define BL32_IMAGE_NAME "bl32.bin" #define BL33_IMAGE_NAME "bl33.bin" #define TB_FW_CONFIG_NAME "fvp_tb_fw_config.dtb" +#define HW_CONFIG_NAME "hw_config.dtb" #if TRUSTED_BOARD_BOOT #define TRUSTED_BOOT_FW_CERT_NAME "tb_fw.crt" @@ -56,6 +57,10 @@ static const io_file_spec_t sh_file_spec[] = { .path = TB_FW_CONFIG_NAME, .mode = FOPEN_MODE_RB }, + [HW_CONFIG_ID] = { + .path = HW_CONFIG_NAME, + .mode = FOPEN_MODE_RB + }, #if TRUSTED_BOARD_BOOT [TRUSTED_BOOT_FW_CERT_ID] = { .path = TRUSTED_BOOT_FW_CERT_NAME, diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h index cac47f72f..2e2fdd7ad 100644 --- a/plat/arm/board/juno/include/platform_def.h +++ b/plat/arm/board/juno/include/platform_def.h @@ -110,12 +110,12 @@ */ #if TRUSTED_BOARD_BOOT #if TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA -# define PLAT_ARM_MAX_BL2_SIZE 0x1E000 +# define PLAT_ARM_MAX_BL2_SIZE 0x1F000 #else -# define PLAT_ARM_MAX_BL2_SIZE 0x1A000 +# define PLAT_ARM_MAX_BL2_SIZE 0x1B000 #endif #else -# define PLAT_ARM_MAX_BL2_SIZE 0xC000 +# define PLAT_ARM_MAX_BL2_SIZE 0xD000 #endif /* diff --git a/plat/arm/common/aarch32/arm_bl2_mem_params_desc.c b/plat/arm/common/aarch32/arm_bl2_mem_params_desc.c index 7fd42aa1e..890f2c960 100644 --- a/plat/arm/common/aarch32/arm_bl2_mem_params_desc.c +++ b/plat/arm/common/aarch32/arm_bl2_mem_params_desc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -54,7 +54,15 @@ static bl_mem_params_node_t bl2_mem_params_descs[] = { .next_handoff_image_id = BL33_IMAGE_ID, }, - + /* Fill HW_CONFIG related information if it exists */ + { + .image_id = HW_CONFIG_ID, + SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY, + VERSION_2, entry_point_info_t, NON_SECURE | NON_EXECUTABLE), + SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY, + VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING), + .next_handoff_image_id = INVALID_IMAGE_ID, + }, /* Fill BL33 related information */ { .image_id = BL33_IMAGE_ID, diff --git a/plat/arm/common/aarch64/arm_bl2_mem_params_desc.c b/plat/arm/common/aarch64/arm_bl2_mem_params_desc.c index d3490eb5c..fef01c9d2 100644 --- a/plat/arm/common/aarch64/arm_bl2_mem_params_desc.c +++ b/plat/arm/common/aarch64/arm_bl2_mem_params_desc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -82,7 +82,15 @@ static bl_mem_params_node_t bl2_mem_params_descs[] = { .next_handoff_image_id = BL33_IMAGE_ID, # endif }, - + /* Fill HW_CONFIG related information */ + { + .image_id = HW_CONFIG_ID, + SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY, + VERSION_2, entry_point_info_t, NON_SECURE | NON_EXECUTABLE), + SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY, + VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING), + .next_handoff_image_id = INVALID_IMAGE_ID, + }, # ifdef BL32_BASE /* Fill BL32 related information */ { diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c index 14da1fd69..9a5101275 100644 --- a/plat/arm/common/arm_bl2_setup.c +++ b/plat/arm/common/arm_bl2_setup.c @@ -181,7 +181,7 @@ struct entry_point_info *bl2_plat_get_bl31_ep_info(void) * in x0. This memory layout is sitting at the base of the free trusted SRAM. * Copy it to a safe location before its reclaimed by later BL2 functionality. ******************************************************************************/ -void arm_bl2_early_platform_setup(meminfo_t *mem_layout) +void arm_bl2_early_platform_setup(uintptr_t tb_fw_config, meminfo_t *mem_layout) { /* Initialize the console to provide early debug support */ console_init(PLAT_ARM_BOOT_UART_BASE, PLAT_ARM_BOOT_UART_CLK_IN_HZ, @@ -192,11 +192,17 @@ void arm_bl2_early_platform_setup(meminfo_t *mem_layout) /* Initialise the IO layer and register platform IO devices */ plat_arm_io_setup(); + +#if LOAD_IMAGE_V2 + if (tb_fw_config != 0) + arm_bl2_set_tb_cfg_addr((void *)tb_fw_config); +#endif } void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) { - arm_bl2_early_platform_setup((meminfo_t *)arg1); + arm_bl2_early_platform_setup((uintptr_t)arg0, (meminfo_t *)arg1); + generic_delay_timer_init(); } @@ -205,6 +211,10 @@ void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_ */ void arm_bl2_platform_setup(void) { +#if LOAD_IMAGE_V2 + arm_bl2_dyn_cfg_init(); +#endif + /* Initialize the secure environment */ plat_arm_security_setup(); diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index 903b1e1df..b3462ab8a 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -152,6 +152,13 @@ BL2_SOURCES += drivers/delay_timer/delay_timer.c \ plat/arm/common/arm_bl2_setup.c \ plat/arm/common/arm_io_storage.c +# Add `libfdt` and Arm common helpers required for Dynamic Config +include lib/libfdt/libfdt.mk +BL2_SOURCES += plat/arm/common/arm_dyn_cfg.c \ + plat/arm/common/arm_dyn_cfg_helpers.c \ + common/fdt_wrappers.c \ + ${LIBFDT_SRCS} + ifeq (${BL2_AT_EL3},1) BL2_SOURCES += plat/arm/common/arm_bl2_el3_setup.c endif diff --git a/plat/arm/common/arm_dyn_cfg.c b/plat/arm/common/arm_dyn_cfg.c index 432576427..a6fafb831 100644 --- a/plat/arm/common/arm_dyn_cfg.c +++ b/plat/arm/common/arm_dyn_cfg.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include #include #include #include @@ -14,6 +15,9 @@ #if LOAD_IMAGE_V2 +/* Variable to store the address to TB_FW_CONFIG passed from BL1 */ +static void *tb_fw_cfg_dtb; + /* * Helper function to load TB_FW_CONFIG and populate the load information to * arg0 of BL2 entrypoint info. @@ -51,4 +55,54 @@ void arm_load_tb_fw_config(void) (void *) config_base); } +/* + * 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); + tb_fw_cfg_dtb = dtb; +} + +/* + * BL2 utility function to initialize dynamic configuration specified by + * TB_FW_CONFIG. Return early if TB_FW_CONFIG is not found or HW_CONFIG is + * not specified in TB_FW_CONFIG. + */ +void arm_bl2_dyn_cfg_init(void) +{ + int err = 0; + int tb_fw_node; + bl_mem_params_node_t *hw_cfg_mem_params = NULL; + + if (tb_fw_cfg_dtb == NULL) { + VERBOSE("No TB_FW_CONFIG specified\n"); + return; + } + + err = arm_dyn_tb_fw_cfg_init((void *)tb_fw_cfg_dtb, &tb_fw_node); + if (err < 0) { + ERROR("Invalid TB_FW_CONFIG passed from BL1\n"); + panic(); + } + + /* Get the hw_config load address and size from TB_FW_CONFIG */ + hw_cfg_mem_params = get_bl_mem_params_node(HW_CONFIG_ID); + if (hw_cfg_mem_params == NULL) { + VERBOSE("Couldn't find HW_CONFIG in bl_mem_params_node\n"); + return; + } + + err = arm_dyn_get_hwconfig_info((void *)tb_fw_cfg_dtb, tb_fw_node, + (uint64_t *) &hw_cfg_mem_params->image_info.image_base, + &hw_cfg_mem_params->image_info.image_max_size); + if (err < 0) { + VERBOSE("Couldn't find HW_CONFIG load info in TB_FW_CONFIG\n"); + return; + } + + /* Remove the IMAGE_ATTRIB_SKIP_LOADING attribute from HW_CONFIG node */ + hw_cfg_mem_params->image_info.h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING; +} + #endif /* LOAD_IMAGE_V2 */ diff --git a/plat/arm/common/arm_dyn_cfg_helpers.c b/plat/arm/common/arm_dyn_cfg_helpers.c new file mode 100644 index 000000000..afe44537d --- /dev/null +++ b/plat/arm/common/arm_dyn_cfg_helpers.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + +/******************************************************************************* + * Helper to read the `hw_config` property in config DTB. This function + * expects the following properties to be present in the config DTB. + * name : hw_config_addr size : 2 cells + * name : hw_config_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. + * uint64_t *hw_config_addr - Returns the `hw_config` load address if read + * is successful. + * uint32_t *hw_config_size - Returns the `hw_config` size if read is + * successful. + * + * Returns 0 on success and -1 on error. + ******************************************************************************/ +int arm_dyn_get_hwconfig_info(void *dtb, int node, + uint64_t *hw_config_addr, uint32_t *hw_config_size) +{ + int err; + + assert(dtb); + assert(hw_config_addr); + assert(hw_config_size); + + /* 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, "hw_config_addr", 2, + (void *) hw_config_addr); + if (err < 0) { + WARN("Read cell failed for hw_config_addr\n"); + return -1; + } + + err = fdtw_read_cells(dtb, node, "hw_config_max_size", 1, + (void *) hw_config_size); + if (err < 0) { + WARN("Read cell failed for hw_config_max_size\n"); + return -1; + } + + VERBOSE("Dyn cfg: Read hw_config address from TB_FW_CONFIG 0x%p %p\n", + hw_config_addr, hw_config_size); + + return 0; +} + +/******************************************************************************* + * Validate the tb_fw_config is a valid DTB file and returns the node offset + * to "arm,tb_fw" property. + * Arguments: + * void *dtb - pointer to the TB_FW_CONFIG in memory + * int *node - Returns the node offset to "arm,tb_fw" property if found. + * + * Returns 0 on success and -1 on error. + ******************************************************************************/ +int arm_dyn_tb_fw_cfg_init(void *dtb, int *node) +{ + assert(dtb); + assert(node); + + /* Check if the pointer to DT is correct */ + if (fdt_check_header(dtb) != 0) { + WARN("Invalid DTB file passed as TB_FW_CONFIG\n"); + return -1; + } + + /* Assert the node offset point to "arm,tb_fw" compatible property */ + *node = fdt_node_offset_by_compatible(dtb, -1, "arm,tb_fw"); + if (*node < 0) { + WARN("The compatible property `arm,tb_fw` not found in the config\n"); + return -1; + } + + VERBOSE("Dyn cfg: Found \"arm,tb_fw\" in the config\n"); + return 0; +} diff --git a/plat/arm/common/arm_image_load.c b/plat/arm/common/arm_image_load.c index 03e4b4f4d..916fa8dc8 100644 --- a/plat/arm/common/arm_image_load.c +++ b/plat/arm/common/arm_image_load.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,6 +7,7 @@ #include #include #include +#include #include @@ -37,5 +38,8 @@ bl_load_info_t *plat_get_bl_image_load_info(void) ******************************************************************************/ bl_params_t *plat_get_next_bl_params(void) { - return get_next_bl_params_from_mem_params_desc(); + bl_params_t *next_bl_params = get_next_bl_params_from_mem_params_desc(); + + populate_next_bl_params_config(next_bl_params); + return next_bl_params; } diff --git a/plat/arm/common/arm_io_storage.c b/plat/arm/common/arm_io_storage.c index 6d8f20953..5cabc5465 100644 --- a/plat/arm/common/arm_io_storage.c +++ b/plat/arm/common/arm_io_storage.c @@ -57,6 +57,10 @@ static const io_uuid_spec_t tb_fw_config_uuid_spec = { .uuid = UUID_TB_FW_CONFIG, }; +static const io_uuid_spec_t hw_config_uuid_spec = { + .uuid = UUID_HW_CONFIG, +}; + #if TRUSTED_BOARD_BOOT static const io_uuid_spec_t tb_fw_cert_uuid_spec = { .uuid = UUID_TRUSTED_BOOT_FW_CERT, @@ -156,6 +160,11 @@ static const struct plat_io_policy policies[] = { (uintptr_t)&tb_fw_config_uuid_spec, open_fip }, + [HW_CONFIG_ID] = { + &fip_dev_handle, + (uintptr_t)&hw_config_uuid_spec, + open_fip + }, #if TRUSTED_BOARD_BOOT [TRUSTED_BOOT_FW_CERT_ID] = { &fip_dev_handle,