Browse Source
* 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 commitpull/1938/head
Sandrine Bailleux
5 years ago
committed by
TrustedFirmware Code Review
48 changed files with 1232 additions and 430 deletions
@ -0,0 +1,85 @@ |
|||
Firmware Configuration Framework |
|||
================================ |
|||
|
|||
This document provides an overview of the |FCONF| framework. |
|||
|
|||
Introduction |
|||
~~~~~~~~~~~~ |
|||
|
|||
The Firmware CONfiguration Framework (|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. |
|||
|
|||
It is used to bridge new and old ways of providing platform-specific data. |
|||
Today, information like the Chain of Trust is held within several, nested |
|||
platform-defined tables. In the future, it may be provided as part of a device |
|||
blob, along with the rest of the information about images to load. |
|||
Introducing this abstraction layer will make migration easier and will preserve |
|||
functionality for platforms that cannot / don't want to use device tree. |
|||
|
|||
Accessing properties |
|||
~~~~~~~~~~~~~~~~~~~~ |
|||
|
|||
Properties defined in the |FCONF| are grouped around namespaces and |
|||
sub-namespaces: a.b.property. |
|||
Examples namespace can be: |
|||
|
|||
- (|TBBR|) Chain of Trust data: tbbr.cot.trusted_boot_fw_cert |
|||
- (|TBBR|) dynamic configuration info: tbbr.dyn_config.disable_auth |
|||
- Arm io policies: arm.io_policies.bl2_image |
|||
|
|||
Properties can be accessed with the ``FCONF_GET_PROPERTY(a,b,property)`` macro. |
|||
|
|||
Defining properties |
|||
~~~~~~~~~~~~~~~~~~~ |
|||
|
|||
Properties composing the |FCONF| have to be stored in C structures. If another |
|||
backing store is wanted to be used, the platform has 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()`` macro. This ensures that the function would |
|||
be called inside the generic ``fconf_populate()`` function during |
|||
initialization. |
|||
|
|||
:: |
|||
|
|||
int fconf_populate_tbbr_dyn_config(uintptr_t config) |
|||
{ |
|||
/* read dtb and fill tbbr_dyn_config struct */ |
|||
} |
|||
|
|||
FCONF_REGISTER_POPULATOR(fconf_populate_tbbr_dyn_config); |
|||
|
|||
Then, a wrapper has to be provided to match the ``FCONF_GET_PROPERTY()`` macro: |
|||
|
|||
:: |
|||
|
|||
/* generic getter */ |
|||
#define FCONF_GET_PROPERTY(a,b,property) a##__##b##_getter(property) |
|||
|
|||
/* my specific getter */ |
|||
#define tbbr__dyn_config_getter(id) tbbr_dyn_config.id |
|||
|
|||
This second level wrapper can be used to remap the ``FCONF_GET_PROPERTY()`` to |
|||
anything appropriate: structure, array, function, etc.. |
|||
|
|||
Loading the property device tree |
|||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|||
|
|||
The ``fconf_load_config()`` must be called to load the device tree containing |
|||
the properties' values. This must be done after the io layer is initialized, as |
|||
the |DTB| is stored on an external device (FIP). |
|||
|
|||
.. uml:: ../resources/diagrams/plantuml/fconf_bl1_load_config.puml |
|||
|
|||
Populating the properties |
|||
~~~~~~~~~~~~~~~~~~~~~~~~~ |
|||
|
|||
Once a valid device tree is available, the ``fconf_populate(config)`` function |
|||
can be used to fill the C data structure with the data from the config |DTB|. |
|||
This function will call all the ``populate()`` callbacks which have been |
|||
registered with ``FCONF_REGISTER_POPULATOR()``. |
|||
|
|||
.. uml:: ../resources/diagrams/plantuml/fconf_bl2_populate.puml |
@ -0,0 +1,52 @@ |
|||
@startuml |
|||
|
|||
box "BL1 common code" |
|||
participant bl1_main |
|||
participant bl_common |
|||
end box |
|||
|
|||
box "arm platform code" #LightBlue |
|||
participant fvp_bl1_setup |
|||
participant arm_bl1_setup |
|||
participant arm_io_storage |
|||
end box |
|||
|
|||
box "platform common code" |
|||
participant plat_bl1_common |
|||
participant fconf |
|||
end box |
|||
|
|||
bl1_main -> fvp_bl1_setup : bl1_platform_setup() |
|||
fvp_bl1_setup -> arm_bl1_setup : arm_bl1_platform_setup() |
|||
arm_bl1_setup -> arm_io_storage : plat_arm_io_setup() |
|||
note over arm_io_storage : register and setup fip |
|||
arm_bl1_setup -> fconf : fconf_load_config() |
|||
activate fconf |
|||
note over fconf |
|||
create and populate an |
|||
image_desc_t for TB_FW_CONFIG |
|||
end note |
|||
fconf -> bl_common : load_auth_image(TB_FW_CONFIG_ID, &image_info) |
|||
activate bl_common |
|||
note over bl_common |
|||
load and auth image from fip |
|||
with info from plat_io_policy |
|||
end note |
|||
bl_common -> arm_io_storage |
|||
arm_io_storage -> fconf: FCONF_GET_PROPERTY(arm, arm_io_policies, tb_fw_cfg) |
|||
note over fconf: use staticaly defined policies in bl1 |
|||
fconf <- bl_common : image_info |
|||
deactivate bl_common |
|||
note over fconf : get tb_fw_config_dtb from image_info |
|||
fconf -> plat_bl1_common : bl1_plat_get_image_desc(BL2_IMAGE_ID) |
|||
fconf <- plat_bl1_common : BL2_IMAGE_DESC |
|||
note over fconf |
|||
set ep_info.args.arg0 of BL2_IMAGE_DESC |
|||
to TB_FW_CONFIG base address |
|||
end note |
|||
arm_bl1_setup <- fconf |
|||
deactivate fconf |
|||
|
|||
== load & auth, prepare and jump to BL2 == |
|||
|
|||
@enduml |
@ -0,0 +1,41 @@ |
|||
@startuml |
|||
|
|||
box "BL2 common code" |
|||
participant bl2_entrypoint |
|||
participant bl2_main |
|||
end box |
|||
|
|||
box "platform common code" |
|||
participant fconf |
|||
participant fconf_tbbr_getter |
|||
end box |
|||
|
|||
box "arm platform code" #LightBlue |
|||
participant arm_bl2_setup |
|||
participant arm_io_storage |
|||
participant arm_fconf_io |
|||
end box |
|||
|
|||
== bl2 setup == |
|||
bl2_entrypoint -> bl2_main : bl2_setup() |
|||
bl2_main -> arm_bl2_setup : bl2_early_platform_setup2(\n\t arg0, arg1, arg2, arg3) |
|||
note over arm_bl2_setup |
|||
arg0 = tb_fw_config |
|||
arg1 = mem_layout |
|||
end note |
|||
arm_bl2_setup -> arm_bl2_setup : arm_bl2_early_platform_setup(\n\t tb_fw_config, mem_layout) |
|||
activate arm_bl2_setup |
|||
arm_bl2_setup -> fconf: fconf_polulate(tb_fw_config) |
|||
activate fconf |
|||
fconf -> fconf_tbbr_getter: fconf_populate_tbbr_dyn_config(uintptr_t dtb) |
|||
note over fconf_tbbr_getter: read tbbr propeties from dtb |
|||
fconf -> arm_fconf_io: fconf_populate_arm_io_policies(uintptr_t dtb) |
|||
note over arm_fconf_io: read arm io propeties from dtb |
|||
deactivate fconf |
|||
arm_bl2_setup -> arm_io_storage : plat_arm_io_setup() |
|||
note over arm_io_storage: use populated properties |
|||
deactivate arm_bl2_setup |
|||
|
|||
== bl2 main == |
|||
|
|||
@enduml |
@ -0,0 +1,61 @@ |
|||
/*
|
|||
* Copyright (c) 2019-2020, ARM Limited. All rights reserved. |
|||
* |
|||
* SPDX-License-Identifier: BSD-3-Clause |
|||
*/ |
|||
|
|||
#ifndef FCONF_H |
|||
#define FCONF_H |
|||
|
|||
#include <stdint.h> |
|||
|
|||
/* Public API */ |
|||
#define FCONF_GET_PROPERTY(a, b, c) a##__##b##_getter(c) |
|||
|
|||
#define FCONF_REGISTER_POPULATOR(name, callback) \ |
|||
__attribute__((used, section(".fconf_populator"))) \ |
|||
const struct fconf_populator name##__populator = { \ |
|||
.info = #name, \ |
|||
.populate = callback \ |
|||
}; |
|||
|
|||
/*
|
|||
* Populator callback |
|||
* |
|||
* This structure are used by the fconf_populate function and should only be |
|||
* defined by the FCONF_REGISTER_POPULATOR macro. |
|||
*/ |
|||
struct fconf_populator { |
|||
/* Description of the data loaded by the callback */ |
|||
const char *info; |
|||
|
|||
/* Callback used by fconf_populate function with a provided config dtb.
|
|||
* Return 0 on success, err_code < 0 otherwise. |
|||
*/ |
|||
int (*populate)(uintptr_t config); |
|||
}; |
|||
|
|||
/* Load firmware configuration dtb */ |
|||
void fconf_load_config(void); |
|||
|
|||
/* Top level populate function
|
|||
* |
|||
* This function takes a configuration dtb and calls all the registered |
|||
* populator callback with it. |
|||
* |
|||
* Panic on error. |
|||
*/ |
|||
void fconf_populate(uintptr_t config); |
|||
|
|||
/* FCONF specific getter */ |
|||
#define fconf__dtb_getter(prop) fconf_dtb_info.prop |
|||
|
|||
/* Structure used to locally keep a reference to the config dtb. */ |
|||
struct fconf_dtb_info_t { |
|||
uintptr_t base_addr; |
|||
size_t size; |
|||
}; |
|||
|
|||
extern struct fconf_dtb_info_t fconf_dtb_info; |
|||
|
|||
#endif /* FCONF_H */ |
@ -0,0 +1,24 @@ |
|||
/*
|
|||
* Copyright (c) 2019-2020, Arm Limited. All rights reserved. |
|||
* |
|||
* SPDX-License-Identifier: BSD-3-Clause |
|||
*/ |
|||
|
|||
#ifndef FCONF_DYN_CFG_GETTER_H |
|||
#define FCONF_DYN_CFG_GETTER_H |
|||
|
|||
#include <lib/fconf/fconf.h> |
|||
|
|||
/* Dynamic configuration related getter */ |
|||
#define dyn_cfg__dtb_getter(id) dyn_cfg_dtb_info_getter(id) |
|||
|
|||
struct dyn_cfg_dtb_info_t { |
|||
uintptr_t config_addr; |
|||
size_t config_max_size; |
|||
unsigned int config_id; |
|||
}; |
|||
|
|||
struct dyn_cfg_dtb_info_t *dyn_cfg_dtb_info_getter(unsigned int config_id); |
|||
int fconf_populate_dtb_registry(uintptr_t config); |
|||
|
|||
#endif /* FCONF_DYN_CFG_GETTER_H */ |
@ -0,0 +1,27 @@ |
|||
/*
|
|||
* Copyright (c) 2019-2020, ARM Limited. All rights reserved. |
|||
* |
|||
* SPDX-License-Identifier: BSD-3-Clause |
|||
*/ |
|||
|
|||
#ifndef FCONF_TBBR_GETTER_H |
|||
#define FCONF_TBBR_GETTER_H |
|||
|
|||
#include <lib/fconf/fconf.h> |
|||
|
|||
/* TBBR related getter */ |
|||
#define tbbr__cot_getter(id) cot_desc_ptr[id] |
|||
|
|||
#define tbbr__dyn_config_getter(id) tbbr_dyn_config.id |
|||
|
|||
struct tbbr_dyn_config_t { |
|||
uint32_t disable_auth; |
|||
void *mbedtls_heap_addr; |
|||
size_t mbedtls_heap_size; |
|||
}; |
|||
|
|||
extern struct tbbr_dyn_config_t tbbr_dyn_config; |
|||
|
|||
int fconf_populate_tbbr_dyn_config(uintptr_t config); |
|||
|
|||
#endif /* FCONF_TBBR_GETTER_H */ |
@ -0,0 +1,24 @@ |
|||
/*
|
|||
* Copyright (c) 2019-2020, ARM Limited. All rights reserved. |
|||
* |
|||
* SPDX-License-Identifier: BSD-3-Clause |
|||
*/ |
|||
|
|||
#ifndef ARM_FCONF_GETTER |
|||
#define ARM_FCONF_GETTER |
|||
|
|||
#include <lib/fconf/fconf.h> |
|||
|
|||
/* ARM io policies */ |
|||
#define arm__io_policies_getter(id) &policies[id] |
|||
|
|||
struct plat_io_policy { |
|||
uintptr_t *dev_handle; |
|||
uintptr_t image_spec; |
|||
int (*check)(const uintptr_t spec); |
|||
}; |
|||
|
|||
extern struct plat_io_policy policies[]; |
|||
int fconf_populate_arm_io_policies(uintptr_t config); |
|||
|
|||
#endif /* ARM_FCONF_GETTER */ |
@ -0,0 +1,19 @@ |
|||
/*
|
|||
* Copyright (c) 2020, ARM Limited. All rights reserved. |
|||
* |
|||
* SPDX-License-Identifier: BSD-3-Clause |
|||
*/ |
|||
#ifndef ARM_FCONF_IO_STORAGE_H |
|||
#define ARM_FCONF_IO_STORAGE_H |
|||
|
|||
#include <stdint.h> |
|||
|
|||
/* IO devices handle */ |
|||
extern uintptr_t memmap_dev_handle; |
|||
extern uintptr_t fip_dev_handle; |
|||
|
|||
/* Function declarations */ |
|||
int open_fip(const uintptr_t spec); |
|||
int open_memmap(const uintptr_t spec); |
|||
|
|||
#endif /* ARM_FCONF_IO_STORAGE_H */ |
@ -0,0 +1,85 @@ |
|||
/*
|
|||
* 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 <lib/fconf/fconf.h> |
|||
#include <libfdt.h> |
|||
#include <plat/common/platform.h> |
|||
#include <platform_def.h> |
|||
|
|||
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, |
|||
.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 */ |
|||
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 = arm_tb_fw_info.image_base; |
|||
#endif |
|||
|
|||
INFO("FCONF: FW_CONFIG loaded at address = 0x%lx\n", arm_tb_fw_info.image_base); |
|||
} |
|||
|
|||
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(); |
|||
} |
|||
} |
|||
|
|||
/* save local pointer to the config dtb */ |
|||
fconf_dtb_info.base_addr = config; |
|||
} |
@ -0,0 +1,12 @@ |
|||
#
|
|||
# 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 \
|
|||
lib/fconf/fconf_dyn_cfg_getter.c |
|||
|
|||
BL1_SOURCES += ${FCONF_SOURCES} |
|||
BL2_SOURCES += ${FCONF_SOURCES} |
@ -0,0 +1,95 @@ |
|||
/*
|
|||
* 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 <lib/fconf/fconf_dyn_cfg_getter.h> |
|||
#include <lib/object_pool.h> |
|||
#include <libfdt.h> |
|||
|
|||
/* 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); |
@ -0,0 +1,75 @@ |
|||
/*
|
|||
* Copyright (c) 2019-2020, ARM Limited. All rights reserved. |
|||
* |
|||
* SPDX-License-Identifier: BSD-3-Clause |
|||
*/ |
|||
#include <assert.h> |
|||
|
|||
#include <common/bl_common.h> |
|||
#include <common/debug.h> |
|||
#include <common/fdt_wrappers.h> |
|||
#include <lib/fconf/fconf_tbbr_getter.h> |
|||
#include <libfdt.h> |
|||
|
|||
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 |
|||
|
|||
/* 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; |
|||
} |
|||
|
|||
FCONF_REGISTER_POPULATOR(tbbr, fconf_populate_tbbr_dyn_config); |
@ -0,0 +1,35 @@ |
|||
/* |
|||
* Copyright (c) 2019-2020, Arm Limited. All rights reserved. |
|||
* |
|||
* SPDX-License-Identifier: BSD-3-Clause |
|||
*/ |
|||
|
|||
#include <export/common/tbbr/tbbr_img_def_exp.h> |
|||
|
|||
/dts-v1/; |
|||
|
|||
/ { |
|||
dtb-registry { |
|||
compatible = "arm,dyn_cfg-dtb_registry"; |
|||
|
|||
/* tb_fw_config is temporarily contained in this dtb */ |
|||
tb_fw-config { |
|||
load-address = <0x0 0x2001010>; |
|||
max-size = <0x200>; |
|||
id = <TB_FW_CONFIG_ID>; |
|||
}; |
|||
|
|||
hw-config { |
|||
load-address = <0x0 0x83000000>; |
|||
max-size = <0x01000000>; |
|||
id = <HW_CONFIG_ID>; |
|||
}; |
|||
}; |
|||
|
|||
tb_fw-config { |
|||
compatible = "arm,tb_fw"; |
|||
|
|||
/* Disable authentication for development */ |
|||
disable_auth = <0x0>; |
|||
}; |
|||
}; |
@ -1,18 +0,0 @@ |
|||
/* |
|||
* Copyright (c) 2019-2020, Arm Limited. All rights reserved. |
|||
* |
|||
* SPDX-License-Identifier: BSD-3-Clause |
|||
*/ |
|||
|
|||
/dts-v1/; |
|||
|
|||
/ { |
|||
/* Platform Config */ |
|||
plat_arm_bl2 { |
|||
compatible = "arm,tb_fw"; |
|||
hw_config_addr = <0x0 0x83000000>; |
|||
hw_config_max_size = <0x01000000>; |
|||
/* Disable authentication for development */ |
|||
disable_auth = <0x0>; |
|||
}; |
|||
}; |
@ -0,0 +1,96 @@ |
|||
/* |
|||
* Copyright (c) 2019-2020, ARM Limited. All rights reserved. |
|||
* |
|||
* SPDX-License-Identifier: BSD-3-Clause |
|||
*/ |
|||
|
|||
#include <export/common/tbbr/tbbr_img_def_exp.h> |
|||
|
|||
/dts-v1/; |
|||
|
|||
/ { |
|||
dtb-registry { |
|||
compatible = "arm,dyn_cfg-dtb_registry"; |
|||
|
|||
/* tb_fw_config is temporarily contained on this dtb */ |
|||
tb_fw-config { |
|||
load-address = <0x0 0x4001010>; |
|||
max-size = <0x200>; |
|||
id = <TB_FW_CONFIG_ID>; |
|||
}; |
|||
|
|||
hw-config { |
|||
load-address = <0x0 0x82000000>; |
|||
max-size = <0x01000000>; |
|||
id = <HW_CONFIG_ID>; |
|||
}; |
|||
|
|||
/* |
|||
* Load SoC and TOS firmware configs at the base of |
|||
* non shared SRAM. The runtime checks ensure we don't |
|||
* overlap BL2, BL31 or BL32. The NT firmware config |
|||
* is loaded at base of DRAM. |
|||
*/ |
|||
soc_fw-config { |
|||
load-address = <0x0 0x04001000>; |
|||
max-size = <0x200>; |
|||
id = <SOC_FW_CONFIG_ID>; |
|||
}; |
|||
|
|||
tos_fw-config { |
|||
load-address = <0x0 0x04001200>; |
|||
max-size = <0x200>; |
|||
id = <TOS_FW_CONFIG_ID>; |
|||
}; |
|||
|
|||
nt_fw-config { |
|||
load-address = <0x0 0x80000000>; |
|||
max-size = <0x200>; |
|||
id = <NT_FW_CONFIG_ID>; |
|||
}; |
|||
}; |
|||
|
|||
tb_fw-config { |
|||
compatible = "arm,tb_fw"; |
|||
|
|||
/* Disable authentication for development */ |
|||
disable_auth = <0x0>; |
|||
|
|||
/* |
|||
* The following two entries are placeholders for Mbed TLS |
|||
* heap information. The default values don't matter since |
|||
* they will be overwritten by BL1. |
|||
* In case of having shared Mbed TLS heap between BL1 and BL2, |
|||
* BL1 will populate these two properties with the respective |
|||
* info about the shared heap. This info will be available for |
|||
* BL2 in order to locate and re-use the heap. |
|||
*/ |
|||
mbedtls_heap_addr = <0x0 0x0>; |
|||
mbedtls_heap_size = <0x0>; |
|||
}; |
|||
|
|||
arm-io_policies { |
|||
fip-handles { |
|||
compatible = "arm,io-fip-handle"; |
|||
scp_bl2_uuid = <0x3dfd6697 0x49e8be89 0xa1785dae 0x13826040>; |
|||
bl31_uuid = <0x6d08d447 0x4698fe4c 0x5029959b 0x005abdcb>; |
|||
bl32_uuid = <0x89e1d005 0x4713dc53 0xa502b8d 0x383e7a4b>; |
|||
bl32_extra1_uuid = <0x9bc2700b 0x40785a2a 0x560a659f 0x88827382>; |
|||
bl32_extra2_uuid = <0xb17ba88e 0x4d3fa2cf 0xbbe7fd85 0xd92002a5>; |
|||
bl33_uuid = <0xa7eed0d6 0x4bd5eafc 0x34998297 0xe4b634f2>; |
|||
hw_cfg_uuid = <0xd9f1b808 0x4993cfc9 0xbc6f62a9 0xcc65726b>; |
|||
soc_fw_cfg_uuid = <0x4b817999 0x46fb7603 0x268d8e8c 0xe059787f>; |
|||
tos_fw_cfg_uuid = <0x1a7c2526 0x477fc6db 0xc4c4968d 0x218024b0>; |
|||
nt_fw_cfg_uuid = <0x1598da28 0x447ee893 0xaf1a66ac 0xf9501580>; |
|||
t_key_cert_uuid = <0x90e87e82 0x11e460f8 0x7a77b4a1 0x4cf9b421>; |
|||
scp_fw_key_uuid = <0xa1214202 0x11e460f8 0x3cf39b8d 0x14a0150e>; |
|||
soc_fw_key_uuid = <0xccbeb88a 0x11e460f9 0x48ebd09a 0xf8dcd822>; |
|||
tos_fw_key_cert_uuid = <0x3d67794 0x11e460fb 0x10b7dd85 0x4ee8c5b>; |
|||
nt_fw_key_cert_uuid = <0x2a83d58a 0x11e460fb 0x30dfaf8a 0x5998c4bb>; |
|||
scp_fw_content_cert_uuid = <0x046fbe44 0x11e4635e 0xd8738bb2 0x5696aeea>; |
|||
soc_fw_content_cert_uuid = <0x200cb2e2 0x11e4635e 0xccabe89c 0x66b62bf9>; |
|||
tos_fw_content_cert_uuid = <0x11449fa4 0x11e4635e 0x53f2887 0x3df32a72>; |
|||
nt_fw_content_cert_uuid = <0xf3c1c48e 0x11e4635d 0xee87a9a7 0xa73fb240>; |
|||
}; |
|||
}; |
|||
}; |
@ -0,0 +1,35 @@ |
|||
/* |
|||
* Copyright (c) 2019-2020, Arm Limited. All rights reserved. |
|||
* |
|||
* SPDX-License-Identifier: BSD-3-Clause |
|||
*/ |
|||
|
|||
#include <export/common/tbbr/tbbr_img_def_exp.h> |
|||
|
|||
/dts-v1/; |
|||
|
|||
/ { |
|||
dtb-registry { |
|||
compatible = "arm,dyn_cfg-dtb_registry"; |
|||
|
|||
/* tb_fw_config is temporarily contained on this dtb */ |
|||
tb_fw-config { |
|||
load-address = <0x0 0x80001010>; |
|||
max-size = <0x200>; |
|||
id = <TB_FW_CONFIG_ID>; |
|||
}; |
|||
|
|||
hw-config { |
|||
load-address = <0x0 0x82000000>; |
|||
max-size = <0x01000000>; |
|||
id = <HW_CONFIG_ID>; |
|||
}; |
|||
}; |
|||
|
|||
tb_fw-config { |
|||
compatible = "arm,tb_fw"; |
|||
|
|||
/* Disable authentication for development */ |
|||
disable_auth = <0x0>; |
|||
}; |
|||
}; |
@ -1,18 +0,0 @@ |
|||
/* |
|||
* Copyright (c) 2019, Arm Limited. All rights reserved. |
|||
* |
|||
* SPDX-License-Identifier: BSD-3-Clause |
|||
*/ |
|||
|
|||
/dts-v1/; |
|||
|
|||
/ { |
|||
/* Platform Config */ |
|||
plat_arm_bl2 { |
|||
compatible = "arm,tb_fw"; |
|||
hw_config_addr = <0x0 0x82000000>; |
|||
hw_config_max_size = <0x01000000>; |
|||
/* Disable authentication for development */ |
|||
disable_auth = <0x0>; |
|||
}; |
|||
}; |
@ -1,31 +1,30 @@ |
|||
/* |
|||
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. |
|||
* Copyright (c) 2019-2020, ARM Limited. All rights reserved. |
|||
* |
|||
* SPDX-License-Identifier: BSD-3-Clause |
|||
*/ |
|||
|
|||
#include <export/common/tbbr/tbbr_img_def_exp.h> |
|||
|
|||
/dts-v1/; |
|||
|
|||
/ { |
|||
/* Platform Config */ |
|||
plat_arm_bl2 { |
|||
dtb-registry { |
|||
compatible = "arm,dyn_cfg-dtb_registry"; |
|||
|
|||
/* tb_fw_config is temporarily contained on this dtb */ |
|||
tb_fw-config { |
|||
load-address = <0x0 0x4001010>; |
|||
max-size = <0x200>; |
|||
id = <TB_FW_CONFIG_ID>; |
|||
}; |
|||
}; |
|||
|
|||
tb_fw-config { |
|||
/* Platform Config */ |
|||
compatible = "arm,tb_fw"; |
|||
hw_config_addr = <0x0 0x82000000>; |
|||
hw_config_max_size = <0x01000000>; |
|||
/* Disable authentication for development */ |
|||
disable_auth = <0x0>; |
|||
/* |
|||
* Load SoC and TOS firmware configs at the base of |
|||
* non shared SRAM. The runtime checks ensure we don't |
|||
* overlap BL2, BL31 or BL32. The NT firmware config |
|||
* is loaded at base of DRAM. |
|||
*/ |
|||
soc_fw_config_addr = <0x0 0x04001000>; |
|||
soc_fw_config_max_size = <0x200>; |
|||
tos_fw_config_addr = <0x0 0x04001200>; |
|||
tos_fw_config_max_size = <0x200>; |
|||
nt_fw_config_addr = <0x0 0x80000000>; |
|||
nt_fw_config_max_size = <0x200>; |
|||
/* |
|||
* The following two entries are placeholders for Mbed TLS |
|||
* heap information. The default values don't matter since |
@ -1,25 +0,0 @@ |
|||
/* |
|||
* Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. |
|||
* |
|||
* SPDX-License-Identifier: BSD-3-Clause |
|||
*/ |
|||
|
|||
/dts-v1/; |
|||
|
|||
/ { |
|||
/* Platform Config */ |
|||
compatible = "arm,tb_fw"; |
|||
/* Disable authentication for development */ |
|||
disable_auth = <0x0>; |
|||
/* |
|||
* The following two entries are placeholders for Mbed TLS |
|||
* heap information. The default values don't matter since |
|||
* they will be overwritten by BL1. |
|||
* In case of having shared Mbed TLS heap between BL1 and BL2, |
|||
* BL1 will populate these two properties with the respective |
|||
* info about the shared heap. This info will be available for |
|||
* BL2 in order to locate and re-use the heap. |
|||
*/ |
|||
mbedtls_heap_addr = <0x0 0x0>; |
|||
mbedtls_heap_size = <0x0>; |
|||
}; |
@ -0,0 +1,143 @@ |
|||
/*
|
|||
* 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); |
|||
} |
@ -0,0 +1,143 @@ |
|||
/*
|
|||
* 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 */ |
Loading…
Reference in new issue