Commit 21c4f56f authored by Sandrine Bailleux's avatar Sandrine Bailleux Committed by TrustedFirmware Code Review
Browse files

Merge changes from topic "lm/fconf" into integration

* changes:
  arm-io: Panic in case of io setup failure
  MISRA fix: Use boolean essential type
  fconf: Add documentation
  fconf: Move platform io policies into fconf
  fconf: Add mbedtls shared heap as property
  fconf: Add TBBR disable_authentication property
  fconf: Add dynamic config DTBs info as property
  fconf: Populate properties from dtb during bl2 setup
  fconf: Load config dtb from bl1
  fconf: initial commit
parents 63aa4094 97399821
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <common/debug.h> #include <common/debug.h>
#include <common/desc_image_load.h> #include <common/desc_image_load.h>
#include <drivers/generic_delay_timer.h> #include <drivers/generic_delay_timer.h>
#include <lib/fconf/fconf.h>
#ifdef SPD_opteed #ifdef SPD_opteed
#include <lib/optee_utils.h> #include <lib/optee_utils.h>
#endif #endif
...@@ -58,11 +59,13 @@ void arm_bl2_early_platform_setup(uintptr_t tb_fw_config, ...@@ -58,11 +59,13 @@ void arm_bl2_early_platform_setup(uintptr_t tb_fw_config,
/* Setup the BL2 memory layout */ /* Setup the BL2 memory layout */
bl2_tzram_layout = *mem_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 */ /* Initialise the IO layer and register platform IO devices */
plat_arm_io_setup(); 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) void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3)
......
...@@ -177,12 +177,20 @@ include lib/xlat_tables_v2/xlat_tables.mk ...@@ -177,12 +177,20 @@ include lib/xlat_tables_v2/xlat_tables.mk
PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS} PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS}
endif 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 \ BL1_SOURCES += drivers/io/io_fip.c \
drivers/io/io_memmap.c \ drivers/io/io_memmap.c \
drivers/io/io_storage.c \ drivers/io/io_storage.c \
plat/arm/common/arm_bl1_setup.c \ plat/arm/common/arm_bl1_setup.c \
plat/arm/common/arm_err.c \ plat/arm/common/arm_err.c \
plat/arm/common/arm_io_storage.c ${ARM_IO_SOURCES}
ifdef EL3_PAYLOAD_BASE ifdef EL3_PAYLOAD_BASE
# Need the plat_arm_program_trusted_mailbox() function to release secondary CPUs from # Need the plat_arm_program_trusted_mailbox() function to release secondary CPUs from
# their holding pen # their holding pen
...@@ -196,7 +204,10 @@ BL2_SOURCES += drivers/delay_timer/delay_timer.c \ ...@@ -196,7 +204,10 @@ BL2_SOURCES += drivers/delay_timer/delay_timer.c \
drivers/io/io_storage.c \ drivers/io/io_storage.c \
plat/arm/common/arm_bl2_setup.c \ plat/arm/common/arm_bl2_setup.c \
plat/arm/common/arm_err.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
# Add `libfdt` and Arm common helpers required for Dynamic Config # Add `libfdt` and Arm common helpers required for Dynamic Config
include lib/libfdt/libfdt.mk include lib/libfdt/libfdt.mk
...@@ -278,6 +289,7 @@ ifneq (${TRUSTED_BOARD_BOOT},0) ...@@ -278,6 +289,7 @@ ifneq (${TRUSTED_BOARD_BOOT},0)
AUTH_SOURCES := drivers/auth/auth_mod.c \ AUTH_SOURCES := drivers/auth/auth_mod.c \
drivers/auth/crypto_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. # Include the selected chain of trust sources.
ifeq (${COT},tbbr) ifeq (${COT},tbbr)
......
...@@ -16,13 +16,13 @@ ...@@ -16,13 +16,13 @@
#if TRUSTED_BOARD_BOOT #if TRUSTED_BOARD_BOOT
#include <drivers/auth/mbedtls/mbedtls_config.h> #include <drivers/auth/mbedtls/mbedtls_config.h>
#endif #endif
#include <lib/fconf/fconf.h>
#include <lib/fconf/fconf_dyn_cfg_getter.h>
#include <lib/fconf/fconf_tbbr_getter.h>
#include <plat/arm/common/arm_dyn_cfg_helpers.h> #include <plat/arm/common/arm_dyn_cfg_helpers.h>
#include <plat/arm/common/plat_arm.h> #include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h> #include <plat/common/platform.h>
/* Variable to store the address to TB_FW_CONFIG passed from BL1 */
static void *tb_fw_cfg_dtb;
#if TRUSTED_BOARD_BOOT #if TRUSTED_BOARD_BOOT
static void *mbedtls_heap_addr; static void *mbedtls_heap_addr;
...@@ -57,20 +57,10 @@ int arm_get_mbedtls_heap(void **heap_addr, size_t *heap_size) ...@@ -57,20 +57,10 @@ int arm_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
#elif defined(IMAGE_BL2) #elif defined(IMAGE_BL2)
int err;
/* If in BL2, retrieve the already allocated heap's info from DTB */ /* If in BL2, retrieve the already allocated heap's info from DTB */
if (tb_fw_cfg_dtb != NULL) { *heap_addr = FCONF_GET_PROPERTY(tbbr, dyn_config, mbedtls_heap_addr);
err = arm_get_dtb_mbedtls_heap_info(tb_fw_cfg_dtb, heap_addr, *heap_size = FCONF_GET_PROPERTY(tbbr, dyn_config, mbedtls_heap_size);
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();
}
#endif #endif
return 0; return 0;
...@@ -83,6 +73,7 @@ int arm_get_mbedtls_heap(void **heap_addr, size_t *heap_size) ...@@ -83,6 +73,7 @@ int arm_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
void arm_bl1_set_mbedtls_heap(void) void arm_bl1_set_mbedtls_heap(void)
{ {
int err; int err;
uintptr_t tb_fw_cfg_dtb;
/* /*
* If tb_fw_cfg_dtb==NULL then DTB is not present for the current * If tb_fw_cfg_dtb==NULL then DTB is not present for the current
...@@ -96,8 +87,15 @@ void arm_bl1_set_mbedtls_heap(void) ...@@ -96,8 +87,15 @@ void arm_bl1_set_mbedtls_heap(void)
* information, we would need to call plat_get_mbedtls_heap to retrieve * information, we would need to call plat_get_mbedtls_heap to retrieve
* the default heap's address and size. * 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); mbedtls_heap_addr, mbedtls_heap_size);
if (err < 0) { if (err < 0) {
ERROR("BL1: unable to write shared Mbed TLS heap information to DTB\n"); ERROR("BL1: unable to write shared Mbed TLS heap information to DTB\n");
...@@ -108,79 +106,12 @@ void arm_bl1_set_mbedtls_heap(void) ...@@ -108,79 +106,12 @@ void arm_bl1_set_mbedtls_heap(void)
* images. It's critical because BL2 won't be able to proceed * images. It's critical because BL2 won't be able to proceed
* without the heap info. * without the heap info.
*/ */
flush_dcache_range((uintptr_t)tb_fw_cfg_dtb, flush_dcache_range(tb_fw_cfg_dtb, fdt_totalsize(dtb));
fdt_totalsize(tb_fw_cfg_dtb));
} }
} }
#endif /* TRUSTED_BOARD_BOOT */ #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.
*/
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 * BL2 utility function to initialize dynamic configuration specified by
* TB_FW_CONFIG. Populate the bl_mem_params_node_t of other FW_CONFIGs if * TB_FW_CONFIG. Populate the bl_mem_params_node_t of other FW_CONFIGs if
...@@ -188,11 +119,10 @@ void arm_bl2_set_tb_cfg_addr(void *dtb) ...@@ -188,11 +119,10 @@ void arm_bl2_set_tb_cfg_addr(void *dtb)
*/ */
void arm_bl2_dyn_cfg_init(void) void arm_bl2_dyn_cfg_init(void)
{ {
int err = 0, tb_fw_node;
unsigned int i; unsigned int i;
bl_mem_params_node_t *cfg_mem_params = NULL; bl_mem_params_node_t *cfg_mem_params = NULL;
uint64_t image_base; uintptr_t image_base;
uint32_t image_size; size_t image_size;
const unsigned int config_ids[] = { const unsigned int config_ids[] = {
HW_CONFIG_ID, HW_CONFIG_ID,
SOC_FW_CONFIG_ID, SOC_FW_CONFIG_ID,
...@@ -203,16 +133,7 @@ void arm_bl2_dyn_cfg_init(void) ...@@ -203,16 +133,7 @@ void arm_bl2_dyn_cfg_init(void)
#endif #endif
}; };
if (tb_fw_cfg_dtb == NULL) { const struct dyn_cfg_dtb_info_t *dtb_info;
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();
}
/* Iterate through all the fw config IDs */ /* Iterate through all the fw config IDs */
for (i = 0; i < ARRAY_SIZE(config_ids); i++) { for (i = 0; i < ARRAY_SIZE(config_ids); i++) {
...@@ -223,14 +144,16 @@ void arm_bl2_dyn_cfg_init(void) ...@@ -223,14 +144,16 @@ void arm_bl2_dyn_cfg_init(void)
continue; continue;
} }
err = arm_dyn_get_config_load_info(tb_fw_cfg_dtb, tb_fw_node, dtb_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, config_ids[i]);
config_ids[i], &image_base, &image_size); if (dtb_info == NULL) {
if (err < 0) {
VERBOSE("Couldn't find config_id %d load info in TB_FW_CONFIG\n", VERBOSE("Couldn't find config_id %d load info in TB_FW_CONFIG\n",
config_ids[i]); config_ids[i]);
continue; 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, * Do some runtime checks on the load addresses of soc_fw_config,
* tos_fw_config, nt_fw_config. This is not a comprehensive check * tos_fw_config, nt_fw_config. This is not a comprehensive check
...@@ -262,8 +185,8 @@ void arm_bl2_dyn_cfg_init(void) ...@@ -262,8 +185,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_base = image_base;
cfg_mem_params->image_info.image_max_size = image_size; cfg_mem_params->image_info.image_max_size = (uint32_t)image_size;
/* /*
* Remove the IMAGE_ATTRIB_SKIP_LOADING attribute from * Remove the IMAGE_ATTRIB_SKIP_LOADING attribute from
...@@ -271,16 +194,4 @@ void arm_bl2_dyn_cfg_init(void) ...@@ -271,16 +194,4 @@ void arm_bl2_dyn_cfg_init(void)
*/ */
cfg_mem_params->image_info.h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING; cfg_mem_params->image_info.h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING;
} }
#if TRUSTED_BOARD_BOOT && defined(DYN_DISABLE_AUTH)
uint32_t disable_auth = 0;
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
} }
...@@ -15,128 +15,6 @@ ...@@ -15,128 +15,6 @@
#define DTB_PROP_MBEDTLS_HEAP_ADDR "mbedtls_heap_addr" #define DTB_PROP_MBEDTLS_HEAP_ADDR "mbedtls_heap_addr"
#define DTB_PROP_MBEDTLS_HEAP_SIZE "mbedtls_heap_size" #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 :
* <config>_addr size : 2 cells
* <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.
* 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.
* 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 * Validate the tb_fw_config is a valid DTB file and returns the node offset
* to "arm,tb_fw" property. * to "arm,tb_fw" property.
...@@ -168,47 +46,6 @@ int arm_dyn_tb_fw_cfg_init(void *dtb, int *node) ...@@ -168,47 +46,6 @@ int arm_dyn_tb_fw_cfg_init(void *dtb, int *node)
return 0; 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 * 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 * is called, it is guaranteed that a DTB is available. However it is not
......
/*
* Copyright (c) 2015-2020, ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <common/debug.h>
#include <drivers/io/io_driver.h>
#include <drivers/io/io_fip.h>
#include <drivers/io/io_memmap.h>
#include <drivers/io/io_storage.h>
#include <lib/utils.h>
#include <tools_share/firmware_image_package.h>
#include <plat/arm/common/arm_fconf_getter.h>
#include <plat/arm/common/arm_fconf_io_storage.h>
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
#include <platform_def.h>
/* 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;
}
int arm_io_setup(void)
{
int io_result;
io_result = register_io_dev_fip(&fip_dev_con);
if (io_result < 0) {
return io_result;
}
io_result = register_io_dev_memmap(&memmap_dev_con);
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);
if (io_result < 0) {
return io_result;
}
io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL,
&memmap_dev_handle);
return io_result;
}
void plat_arm_io_setup(void)
{
int err;
err = arm_io_setup();
if (err < 0) {
panic();
}
}
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.
*/
bool arm_io_is_toc_valid(void)
{
return (io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID) == 0);
}
/* /*
* 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 * SPDX-License-Identifier: BSD-3-Clause
*/ */
...@@ -292,32 +292,41 @@ static int open_memmap(const uintptr_t spec) ...@@ -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; int io_result;
io_result = register_io_dev_fip(&fip_dev_con); 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); 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 */ /* Open connections to devices and cache the handles */
io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL, io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
&fip_dev_handle); &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, io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL,
&memmap_dev_handle); &memmap_dev_handle);
assert(io_result == 0);
/* Ignore improbable errors in release builds */ return io_result;
(void)io_result;
} }
void plat_arm_io_setup(void) 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( int plat_arm_get_alt_image_source(
...@@ -357,12 +366,8 @@ int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, ...@@ -357,12 +366,8 @@ int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
* See if a Firmware Image Package is available, * See if a Firmware Image Package is available,
* by checking if TOC is valid or not. * by checking if TOC is valid or not.
*/ */
int arm_io_is_toc_valid(void) bool arm_io_is_toc_valid(void)
{ {
int result; return (io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID) == 0);
result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
return (result == 0);
} }
/*
* Copyright (c) 2019-2020, ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <common/debug.h>
#include <common/fdt_wrappers.h>
#include <drivers/io/io_storage.h>
#include <lib/object_pool.h>
#include <libfdt.h>
#include <tools_share/firmware_image_package.h>
#include <plat/arm/common/arm_fconf_getter.h>
#include <plat/arm/common/arm_fconf_io_storage.h>
#include <platform_def.h>
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 */
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment