plat/arm: Load and populate fw_config and tb_fw_config

Modified the code to do below changes:

1. Load tb_fw_config along with fw_config by BL1.
2. Populate fw_config device tree information in the
   BL1 to load tb_fw_config.
3. In BL2, populate fw_config information to retrieve
   the address of tb_fw_config and then tb_fw_config
   gets populated using retrieved address.
4. Avoid processing of configuration file in case of error
   value returned from "fw_config_load" function.
5. Updated entrypoint information for BL2 image so
   that it's arg0 should point to fw_config address.

Signed-off-by: Manish V Badarkhe <Manish.Badarkhe@arm.com>
Signed-off-by: Louis Mayencourt <louis.mayencourt@arm.com>
Change-Id: Ife6f7b673a074e7f544ee3d1bda7645fd5b2886c
This commit is contained in:
Manish V Badarkhe 2020-06-11 22:32:11 +01:00
parent f17ae7b0a9
commit 8286967552
6 changed files with 106 additions and 28 deletions

View File

@ -21,4 +21,7 @@ struct dyn_cfg_dtb_info_t {
struct dyn_cfg_dtb_info_t *dyn_cfg_dtb_info_getter(unsigned int config_id);
int fconf_populate_dtb_registry(uintptr_t config);
/* Set fw_config information in global DTB array */
void set_fw_config_info(uintptr_t config_addr, uint32_t config_max_size);
#endif /* FCONF_DYN_CFG_GETTER_H */

View File

@ -190,7 +190,7 @@ void arm_bl1_platform_setup(void);
void arm_bl1_plat_arch_setup(void);
/* BL2 utility functions */
void arm_bl2_early_platform_setup(uintptr_t tb_fw_config, struct meminfo *mem_layout);
void arm_bl2_early_platform_setup(uintptr_t 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);

View File

@ -29,8 +29,11 @@ int fconf_load_config(unsigned int image_id)
};
config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, image_id);
assert(config_info != NULL);
config_image_info.image_base = config_info->config_addr;
config_image_info.image_max_size = (uint32_t)config_info->config_max_size;
config_image_info.image_max_size =
(uint32_t)config_info->config_max_size;
VERBOSE("FCONF: Loading config with image ID: %d\n", image_id);
err = load_auth_image(image_id, &config_image_info);

View File

@ -15,22 +15,23 @@
/* We currently use FW, TB_FW, SOC_FW, TOS_FW, NS_fw and HW configs */
#define MAX_DTB_INFO U(6)
#ifdef IMAGE_BL1
static struct dyn_cfg_dtb_info_t dtb_infos[MAX_DTB_INFO] = {
[0] = {
.config_addr = ARM_FW_CONFIG_BASE,
.config_max_size = (uint32_t)
(ARM_FW_CONFIG_LIMIT - ARM_FW_CONFIG_BASE),
.config_id = FW_CONFIG_ID
},
};
/* Create an object pool starting at the second element */
static OBJECT_POOL(dtb_info_pool, &dtb_infos[1],
sizeof(struct dyn_cfg_dtb_info_t), MAX_DTB_INFO-1);
#else
static struct dyn_cfg_dtb_info_t dtb_infos[MAX_DTB_INFO];
static OBJECT_POOL_ARRAY(dtb_info_pool, dtb_infos);
#endif
/*
* This function is used to alloc memory for fw config information from
* global pool and set fw configuration information.
* Specifically used by BL1 to set fw_config information in global array
*/
void set_fw_config_info(uintptr_t config_addr, uint32_t config_max_size)
{
struct dyn_cfg_dtb_info_t *dtb_info;
dtb_info = pool_alloc(&dtb_info_pool);
dtb_info->config_addr = config_addr;
dtb_info->config_max_size = config_max_size;
dtb_info->config_id = FW_CONFIG_ID;
}
struct dyn_cfg_dtb_info_t *dyn_cfg_dtb_info_getter(unsigned int config_id)
{
@ -62,6 +63,30 @@ int fconf_populate_dtb_registry(uintptr_t config)
/* As libfdt use void *, we can't avoid this cast */
const void *dtb = (void *)config;
/*
* Compile time assert if FW_CONFIG_ID is 0 which is more
* unlikely as 0 is a valid image id for FIP as per the current
* code but still to avoid code breakage in case of unlikely
* event when image ids gets changed.
*/
CASSERT(FW_CONFIG_ID != 0, assert_invalid_fw_config_id);
/*
* In case of BL1, fw_config dtb information is already
* populated in global dtb_infos array by 'set_fw_config_info'
* function, Below check is present to avoid re-population of
* fw_config information.
*
* Other BLs, satisfy below check and populate fw_config information
* in global dtb_infos array.
*/
if (dtb_infos[0].config_id == 0) {
dtb_info = pool_alloc(&dtb_info_pool);
dtb_info->config_addr = config;
dtb_info->config_max_size = fdt_totalsize(dtb);
dtb_info->config_id = FW_CONFIG_ID;
}
/* Find the node offset point to "fconf,dyn_cfg-dtb_registry" compatible property */
const char *compatible_str = "fconf,dyn_cfg-dtb_registry";
node = fdt_node_offset_by_compatible(dtb, -1, compatible_str);
@ -70,15 +95,6 @@ int fconf_populate_dtb_registry(uintptr_t config)
return node;
}
#ifndef IMAGE_BL1
/* Save config dtb information */
dtb_info = pool_alloc(&dtb_info_pool);
dtb_info->config_addr = config;
dtb_info->config_max_size = fdt_totalsize(dtb);
dtb_info->config_id = FW_CONFIG_ID;
#endif
fdt_for_each_subnode(child, dtb, node) {
uint32_t val32;
uint64_t val64;

View File

@ -12,6 +12,7 @@
#include <bl1/bl1.h>
#include <common/bl_common.h>
#include <lib/fconf/fconf.h>
#include <lib/fconf/fconf_dyn_cfg_getter.h>
#include <lib/utils.h>
#include <lib/xlat_tables/xlat_tables_compat.h>
#include <plat/arm/common/plat_arm.h>
@ -142,11 +143,58 @@ void bl1_plat_arch_setup(void)
*/
void arm_bl1_platform_setup(void)
{
const struct dyn_cfg_dtb_info_t *fw_config_info;
image_desc_t *desc;
uint32_t fw_config_max_size;
int err = -1;
/* Initialise the IO layer and register platform IO devices */
plat_arm_io_setup();
/* Fill the properties struct with the info from the config dtb */
fconf_load_config(FW_CONFIG_ID);
/* Check if we need FWU before further processing */
err = plat_arm_bl1_fwu_needed();
if (err) {
ERROR("Skip platform setup as FWU detected\n");
return;
}
/* Set global DTB info for fixed fw_config information */
fw_config_max_size = ARM_FW_CONFIG_LIMIT - ARM_FW_CONFIG_BASE;
set_fw_config_info(ARM_FW_CONFIG_BASE, fw_config_max_size);
/* Fill the device tree information struct with the info from the config dtb */
err = fconf_load_config(FW_CONFIG_ID);
if (err < 0) {
ERROR("Loading of FW_CONFIG failed %d\n", err);
plat_error_handler(err);
}
/*
* FW_CONFIG loaded successfully. If FW_CONFIG device tree parsing
* is successful then load TB_FW_CONFIG device tree.
*/
fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, FW_CONFIG_ID);
if (fw_config_info != NULL) {
err = fconf_populate_dtb_registry(fw_config_info->config_addr);
if (err < 0) {
ERROR("Parsing of FW_CONFIG failed %d\n", err);
plat_error_handler(err);
}
/* load TB_FW_CONFIG */
err = fconf_load_config(TB_FW_CONFIG_ID);
if (err < 0) {
ERROR("Loading of TB_FW_CONFIG failed %d\n", err);
plat_error_handler(err);
}
} else {
ERROR("Invalid FW_CONFIG address\n");
plat_error_handler(err);
}
/* 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 = fw_config_info->config_addr;
#if TRUSTED_BOARD_BOOT
/* Share the Mbed TLS heap info with other images */

View File

@ -15,6 +15,7 @@
#include <common/desc_image_load.h>
#include <drivers/generic_delay_timer.h>
#include <lib/fconf/fconf.h>
#include <lib/fconf/fconf_dyn_cfg_getter.h>
#ifdef SPD_opteed
#include <lib/optee_utils.h>
#endif
@ -53,6 +54,7 @@ CASSERT(BL2_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl2_base_overflows);
void arm_bl2_early_platform_setup(uintptr_t fw_config,
struct meminfo *mem_layout)
{
const struct dyn_cfg_dtb_info_t *tb_fw_config_info;
/* Initialize the console to provide early debug support */
arm_console_boot_init();
@ -61,7 +63,13 @@ void arm_bl2_early_platform_setup(uintptr_t fw_config,
/* Fill the properties struct with the info from the config dtb */
if (fw_config != 0U) {
fconf_populate("TB_FW", fw_config);
fconf_populate("FW_CONFIG", fw_config);
}
/* TB_FW_CONFIG was also loaded by BL1 */
tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID);
if (tb_fw_config_info != NULL) {
fconf_populate("TB_FW", tb_fw_config_info->config_addr);
}
/* Initialise the IO layer and register platform IO devices */