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;
+ }
+ }
+}
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__ */
/*
- * 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
*/
--- /dev/null
+/*
+ * 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 <stdint.h>
+
+/* 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__ */
struct bl31_params;
struct meminfo;
struct image_info;
+struct bl_params;
#define ARM_CASSERT_MMAP \
CASSERT((ARRAY_SIZE(plat_arm_mmap) + ARM_BL_REGIONS) \
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);
/* 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
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();
#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"
.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,
*/
#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
/*
/*
- * 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
*/
.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,
/*
- * 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
*/
.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 */
{
* 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,
/* 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();
}
*/
void arm_bl2_platform_setup(void)
{
+#if LOAD_IMAGE_V2
+ arm_bl2_dyn_cfg_init();
+#endif
+
/* Initialize the secure environment */
plat_arm_security_setup();
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
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <arm_dyn_cfg_helpers.h>
#include <assert.h>
#include <debug.h>
#include <desc_image_load.h>
#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.
(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 */
--- /dev/null
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <desc_image_load.h>
+#include <fdt_wrappers.h>
+#include <libfdt.h>
+
+/*******************************************************************************
+ * 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;
+}
/*
- * 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
*/
#include <arm_def.h>
#include <bl_common.h>
#include <desc_image_load.h>
+#include <plat_arm.h>
#include <platform.h>
******************************************************************************/
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;
}
.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,
(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,