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
This commit is contained in:
Sandrine Bailleux 2020-02-11 16:15:45 +00:00 committed by TrustedFirmware Code Review
commit 21c4f56fa7
48 changed files with 1232 additions and 430 deletions

View File

@ -786,6 +786,7 @@ $(eval $(call assert_boolean,SPM_MM))
$(eval $(call assert_boolean,TRUSTED_BOARD_BOOT)) $(eval $(call assert_boolean,TRUSTED_BOARD_BOOT))
$(eval $(call assert_boolean,USE_COHERENT_MEM)) $(eval $(call assert_boolean,USE_COHERENT_MEM))
$(eval $(call assert_boolean,USE_DEBUGFS)) $(eval $(call assert_boolean,USE_DEBUGFS))
$(eval $(call assert_boolean,USE_FCONF_BASED_IO))
$(eval $(call assert_boolean,USE_ROMLIB)) $(eval $(call assert_boolean,USE_ROMLIB))
$(eval $(call assert_boolean,USE_TBBR_DEFS)) $(eval $(call assert_boolean,USE_TBBR_DEFS))
$(eval $(call assert_boolean,WARMBOOT_ENABLE_DCACHE_EARLY)) $(eval $(call assert_boolean,WARMBOOT_ENABLE_DCACHE_EARLY))
@ -854,6 +855,7 @@ $(eval $(call add_define,SPM_MM))
$(eval $(call add_define,TRUSTED_BOARD_BOOT)) $(eval $(call add_define,TRUSTED_BOARD_BOOT))
$(eval $(call add_define,USE_COHERENT_MEM)) $(eval $(call add_define,USE_COHERENT_MEM))
$(eval $(call add_define,USE_DEBUGFS)) $(eval $(call add_define,USE_DEBUGFS))
$(eval $(call add_define,USE_FCONF_BASED_IO))
$(eval $(call add_define,USE_ROMLIB)) $(eval $(call add_define,USE_ROMLIB))
$(eval $(call add_define,USE_TBBR_DEFS)) $(eval $(call add_define,USE_TBBR_DEFS))
$(eval $(call add_define,WARMBOOT_ENABLE_DCACHE_EARLY)) $(eval $(call add_define,WARMBOOT_ENABLE_DCACHE_EARLY))

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
@ -46,6 +46,11 @@ SECTIONS
__RODATA_START__ = .; __RODATA_START__ = .;
*(SORT_BY_ALIGNMENT(.rodata*)) *(SORT_BY_ALIGNMENT(.rodata*))
. = ALIGN(8);
__FCONF_POPULATOR_START__ = .;
KEEP(*(.fconf_populator))
__FCONF_POPULATOR_END__ = .;
/* Ensure 8-byte alignment for descriptors and ensure inclusion */ /* Ensure 8-byte alignment for descriptors and ensure inclusion */
. = ALIGN(8); . = ALIGN(8);
__PARSER_LIB_DESCS_START__ = .; __PARSER_LIB_DESCS_START__ = .;
@ -62,6 +67,11 @@ SECTIONS
*(SORT_BY_ALIGNMENT(.text*)) *(SORT_BY_ALIGNMENT(.text*))
*(SORT_BY_ALIGNMENT(.rodata*)) *(SORT_BY_ALIGNMENT(.rodata*))
. = ALIGN(8);
__FCONF_POPULATOR_START__ = .;
KEEP(*(.fconf_populator))
__FCONF_POPULATOR_END__ = .;
/* Ensure 8-byte alignment for descriptors and ensure inclusion */ /* Ensure 8-byte alignment for descriptors and ensure inclusion */
. = ALIGN(8); . = ALIGN(8);
__PARSER_LIB_DESCS_START__ = .; __PARSER_LIB_DESCS_START__ = .;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */

85
docs/components/fconf.rst Normal file
View File

@ -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

View File

@ -9,6 +9,7 @@ Components
spd/index spd/index
arm-sip-service arm-sip-service
exception-handling exception-handling
fconf
firmware-update firmware-update
platform-interrupt-controller-API platform-interrupt-controller-API
ras ras

View File

@ -578,6 +578,11 @@ Common build options
exposing a virtual filesystem interface through BL31 as a SiP SMC function. exposing a virtual filesystem interface through BL31 as a SiP SMC function.
Default is 0. Default is 0.
- ``USE_FCONF_BASED_IO``: This flag determines whether to use IO based on the
firmware configuration framework. This allows moving the io_policies into a
configuration device tree, instead of static structure in the code base.
- ``USE_ROMLIB``: This flag determines whether library at ROM will be used. - ``USE_ROMLIB``: This flag determines whether library at ROM will be used.
This feature creates a library of functions to be placed in ROM and thus This feature creates a library of functions to be placed in ROM and thus
reduces SRAM usage. Refer to :ref:`Library at ROM` for further details. Default reduces SRAM usage. Refer to :ref:`Library at ROM` for further details. Default

View File

@ -6,11 +6,13 @@
.. |COT| replace:: :term:`COT` .. |COT| replace:: :term:`COT`
.. |CSS| replace:: :term:`CSS` .. |CSS| replace:: :term:`CSS`
.. |CVE| replace:: :term:`CVE` .. |CVE| replace:: :term:`CVE`
.. |DTB| replace:: :term:`DTB`
.. |DS-5| replace:: :term:`DS-5` .. |DS-5| replace:: :term:`DS-5`
.. |DSU| replace:: :term:`DSU` .. |DSU| replace:: :term:`DSU`
.. |DT| replace:: :term:`DT` .. |DT| replace:: :term:`DT`
.. |EL| replace:: :term:`EL` .. |EL| replace:: :term:`EL`
.. |EHF| replace:: :term:`EHF` .. |EHF| replace:: :term:`EHF`
.. |FCONF| replace:: :term:`FCONF`
.. |FDT| replace:: :term:`FDT` .. |FDT| replace:: :term:`FDT`
.. |FIP| replace:: :term:`FIP` .. |FIP| replace:: :term:`FIP`
.. |FVP| replace:: :term:`FVP` .. |FVP| replace:: :term:`FVP`

View File

@ -42,12 +42,18 @@ You can find additional definitions in the `Arm Glossary`_.
DT DT
Device Tree Device Tree
DTB
Device Tree Blob
EL EL
Exception Level Exception Level
EHF EHF
Exception Handling Framework Exception Handling Framework
FCONF
Firmware Configuration Framework
FDT FDT
Flattened Device Tree Flattened Device Tree

View File

@ -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

View File

@ -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

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015-2019, 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
*/ */
@ -16,6 +16,7 @@
#include <drivers/auth/auth_mod.h> #include <drivers/auth/auth_mod.h>
#include <drivers/auth/crypto_mod.h> #include <drivers/auth/crypto_mod.h>
#include <drivers/auth/img_parser_mod.h> #include <drivers/auth/img_parser_mod.h>
#include <lib/fconf/fconf_tbbr_getter.h>
#include <plat/common/platform.h> #include <plat/common/platform.h>
/* ASN.1 tags */ /* ASN.1 tags */
@ -302,9 +303,8 @@ int auth_mod_get_parent_id(unsigned int img_id, unsigned int *parent_id)
const auth_img_desc_t *img_desc = NULL; const auth_img_desc_t *img_desc = NULL;
assert(parent_id != NULL); assert(parent_id != NULL);
/* Get the image descriptor */ /* Get the image descriptor */
img_desc = cot_desc_ptr[img_id]; img_desc = FCONF_GET_PROPERTY(tbbr, cot, img_id);
/* Check if the image has no parent (ROT) */ /* Check if the image has no parent (ROT) */
if (img_desc->parent == NULL) { if (img_desc->parent == NULL) {
@ -353,7 +353,7 @@ int auth_mod_verify_img(unsigned int img_id,
int rc, i; int rc, i;
/* Get the image descriptor from the chain of trust */ /* Get the image descriptor from the chain of trust */
img_desc = cot_desc_ptr[img_id]; img_desc = FCONF_GET_PROPERTY(tbbr, cot, img_id);
/* Ask the parser to check the image integrity */ /* Ask the parser to check the image integrity */
rc = img_parser_check_integrity(img_desc->img_type, img_ptr, img_len); rc = img_parser_check_integrity(img_desc->img_type, img_ptr, img_len);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
@ -53,7 +53,7 @@ typedef struct io_file_spec {
/* UUID specification - used to refer to data accessed using UUIDs (i.e. FIP /* UUID specification - used to refer to data accessed using UUIDs (i.e. FIP
* images) */ * images) */
typedef struct io_uuid_spec { typedef struct io_uuid_spec {
const uuid_t uuid; uuid_t uuid;
} io_uuid_spec_t; } io_uuid_spec_t;
/* Block specification - used to refer to data on a device supporting /* Block specification - used to refer to data on a device supporting

61
include/lib/fconf/fconf.h Normal file
View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
@ -10,12 +10,7 @@
#include <stdint.h> #include <stdint.h>
/* Function declarations */ /* Function declarations */
int arm_dyn_get_config_load_info(void *dtb, int node, unsigned int config_id,
uint64_t *config_addr, uint32_t *config_size);
int arm_dyn_tb_fw_cfg_init(void *dtb, int *node); int arm_dyn_tb_fw_cfg_init(void *dtb, int *node);
int arm_dyn_get_disable_auth(void *dtb, int node, uint32_t *disable_auth);
int arm_get_dtb_mbedtls_heap_info(void *dtb, void **heap_addr,
size_t *heap_size);
int arm_set_dtb_mbedtls_heap_info(void *dtb, void *heap_addr, int arm_set_dtb_mbedtls_heap_info(void *dtb, void *heap_addr,
size_t heap_size); size_t heap_size);

View File

@ -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 */

View File

@ -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 */

View File

@ -6,6 +6,7 @@
#ifndef PLAT_ARM_H #ifndef PLAT_ARM_H
#define PLAT_ARM_H #define PLAT_ARM_H
#include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <drivers/arm/tzc_common.h> #include <drivers/arm/tzc_common.h>
@ -148,7 +149,7 @@ void arm_setup_romlib(void);
#define ARM_ROTPK_DEVEL_ECDSA_ID 3 #define ARM_ROTPK_DEVEL_ECDSA_ID 3
/* IO storage utility functions */ /* IO storage utility functions */
void arm_io_setup(void); int arm_io_setup(void);
/* Security utility functions */ /* Security utility functions */
void arm_tzc400_setup(const arm_tzc_regions_info_t *tzc_regions); void arm_tzc400_setup(const arm_tzc_regions_info_t *tzc_regions);
@ -222,11 +223,9 @@ void arm_sp_min_early_platform_setup(void *from_bl2, uintptr_t tos_fw_config,
void arm_sp_min_plat_runtime_setup(void); void arm_sp_min_plat_runtime_setup(void);
/* FIP TOC validity check */ /* FIP TOC validity check */
int arm_io_is_toc_valid(void); bool arm_io_is_toc_valid(void);
/* Utility functions for Dynamic Config */ /* 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); void arm_bl2_dyn_cfg_init(void);
void arm_bl1_set_mbedtls_heap(void); void arm_bl1_set_mbedtls_heap(void);
int arm_get_mbedtls_heap(void **heap_addr, size_t *heap_size); int arm_get_mbedtls_heap(void **heap_addr, size_t *heap_size);
@ -256,7 +255,7 @@ void plat_arm_interconnect_init(void);
void plat_arm_interconnect_enter_coherency(void); void plat_arm_interconnect_enter_coherency(void);
void plat_arm_interconnect_exit_coherency(void); void plat_arm_interconnect_exit_coherency(void);
void plat_arm_program_trusted_mailbox(uintptr_t address); void plat_arm_program_trusted_mailbox(uintptr_t address);
int plat_arm_bl1_fwu_needed(void); bool plat_arm_bl1_fwu_needed(void);
__dead2 void plat_arm_error_handler(int err); __dead2 void plat_arm_error_handler(int err);
/* /*

View File

@ -27,7 +27,7 @@
*/ */
/* /*
* Portions copyright (c) 2014, ARM Limited and Contributors. * Portions copyright (c) 2014-2020, ARM Limited and Contributors.
* All rights reserved. * All rights reserved.
*/ */
@ -56,6 +56,11 @@ struct uuid {
uint8_t node[_UUID_NODE_LEN]; uint8_t node[_UUID_NODE_LEN];
}; };
union uuid_helper_t {
struct uuid uuid_struct;
uint32_t word[4];
};
/* XXX namespace pollution? */ /* XXX namespace pollution? */
typedef struct uuid uuid_t; typedef struct uuid uuid_t;

85
lib/fconf/fconf.c Normal file
View File

@ -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;
}

12
lib/fconf/fconf.mk Normal file
View File

@ -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}

View File

@ -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);

View File

@ -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);

View File

@ -201,6 +201,9 @@ USE_COHERENT_MEM := 1
# Build option to add debugfs support # Build option to add debugfs support
USE_DEBUGFS := 0 USE_DEBUGFS := 0
# Build option to fconf based io
USE_FCONF_BASED_IO := 0
# Build option to choose whether Trusted Firmware uses library at ROM # Build option to choose whether Trusted Firmware uses library at ROM
USE_ROMLIB := 0 USE_ROMLIB := 0

View File

@ -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>;
};
};

View File

@ -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>;
};
};

View File

@ -1,9 +1,12 @@
# #
# Copyright (c) 2019, Arm Limited. All rights reserved. # Copyright (c) 2019-2020, Arm Limited. All rights reserved.
# #
# SPDX-License-Identifier: BSD-3-Clause # SPDX-License-Identifier: BSD-3-Clause
# #
# 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
@ -67,7 +70,7 @@ BL2_SOURCES += lib/aarch32/arm32_aeabi_divmod.c \
# Add the FDT_SOURCES and options for Dynamic Config (only for Unix env) # Add the FDT_SOURCES and options for Dynamic Config (only for Unix env)
ifdef UNIX_MK ifdef UNIX_MK
FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/a5ds_tb_fw_config.dtb FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/a5ds_fw_config.dtb
# Add the TB_FW_CONFIG to FIP and specify the same to certtool # Add the TB_FW_CONFIG to FIP and specify the same to certtool
$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config)) $(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config))
@ -77,7 +80,7 @@ $(eval FVP_HW_CONFIG := ${BUILD_PLAT}/$(patsubst %.dts,%.dtb, \
# Add the HW_CONFIG to FIP and specify the same to certtool # Add the HW_CONFIG to FIP and specify the same to certtool
$(eval $(call TOOL_ADD_PAYLOAD,${FVP_HW_CONFIG},--hw-config)) $(eval $(call TOOL_ADD_PAYLOAD,${FVP_HW_CONFIG},--hw-config))
FDT_SOURCES += plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts \ FDT_SOURCES += plat/arm/board/a5ds/fdts/a5ds_fw_config.dts \
${FVP_HW_CONFIG_DTS} ${FVP_HW_CONFIG_DTS}
endif endif

View File

@ -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>;
};
};
};

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
@ -120,18 +120,22 @@ void plat_arm_io_setup(void)
{ {
int io_result; int io_result;
arm_io_setup(); io_result = arm_io_setup();
if (io_result < 0) {
panic();
}
/* Register the additional IO devices on this platform */ /* Register the additional IO devices on this platform */
io_result = register_io_dev_sh(&sh_dev_con); io_result = register_io_dev_sh(&sh_dev_con);
assert(io_result == 0); if (io_result < 0) {
panic();
}
/* Open connections to devices and cache the handles */ /* Open connections to devices and cache the handles */
io_result = io_dev_open(sh_dev_con, (uintptr_t)NULL, &sh_dev_handle); io_result = io_dev_open(sh_dev_con, (uintptr_t)NULL, &sh_dev_handle);
assert(io_result == 0); if (io_result < 0) {
panic();
/* Ignore improbable errors in release builds */ }
(void)io_result;
} }
/* /*

View File

@ -20,6 +20,8 @@ fdt fdt_setprop_inplace
fdt fdt_check_header fdt fdt_check_header
fdt fdt_node_offset_by_compatible fdt fdt_node_offset_by_compatible
fdt fdt_setprop_inplace_namelen_partial fdt fdt_setprop_inplace_namelen_partial
fdt fdt_first_subnode
fdt fdt_next_subnode
mbedtls mbedtls_asn1_get_alg mbedtls mbedtls_asn1_get_alg
mbedtls mbedtls_asn1_get_alg_null mbedtls mbedtls_asn1_get_alg_null
mbedtls mbedtls_asn1_get_bitstring_null mbedtls mbedtls_asn1_get_bitstring_null

View File

@ -10,6 +10,11 @@ FVP_USE_GIC_DRIVER := FVP_GICV3
# Use the SP804 timer instead of the generic one # Use the SP804 timer instead of the generic one
FVP_USE_SP804_TIMER := 0 FVP_USE_SP804_TIMER := 0
# Use fconf based io for FVP
ifeq ($(BL2_AT_EL3), 0)
USE_FCONF_BASED_IO := 1
endif
# Default cluster count for FVP # Default cluster count for FVP
FVP_CLUSTER_COUNT := 2 FVP_CLUSTER_COUNT := 2
@ -205,12 +210,12 @@ endif
ifdef UNIX_MK ifdef UNIX_MK
FVP_HW_CONFIG_DTS := fdts/${FVP_DT_PREFIX}.dts FVP_HW_CONFIG_DTS := fdts/${FVP_DT_PREFIX}.dts
FDT_SOURCES += $(addprefix plat/arm/board/fvp/fdts/, \ FDT_SOURCES += $(addprefix plat/arm/board/fvp/fdts/, \
${PLAT}_tb_fw_config.dts \ ${PLAT}_fw_config.dts \
${PLAT}_soc_fw_config.dts \ ${PLAT}_soc_fw_config.dts \
${PLAT}_nt_fw_config.dts \ ${PLAT}_nt_fw_config.dts \
) )
FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb
FVP_SOC_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_soc_fw_config.dtb FVP_SOC_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_soc_fw_config.dtb
FVP_NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb FVP_NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb

View File

@ -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>;
};
};

View File

@ -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>;
};
};

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 2019, Arm Limited. All rights reserved. # Copyright (c) 2019-2020, Arm Limited. All rights reserved.
# #
# SPDX-License-Identifier: BSD-3-Clause # SPDX-License-Identifier: BSD-3-Clause
# #
@ -72,9 +72,9 @@ BL2_SOURCES += plat/arm/board/fvp_ve/fvp_ve_bl2_setup.c \
# Add the FDT_SOURCES and options for Dynamic Config (only for Unix env) # Add the FDT_SOURCES and options for Dynamic Config (only for Unix env)
ifdef UNIX_MK ifdef UNIX_MK
FDT_SOURCES += plat/arm/board/fvp_ve/fdts/fvp_ve_tb_fw_config.dts FDT_SOURCES += plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts
FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/fvp_ve_tb_fw_config.dtb FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/fvp_ve_fw_config.dtb
# Add the TB_FW_CONFIG to FIP and specify the same to certtool # Add the TB_FW_CONFIG to FIP and specify the same to certtool
$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config)) $(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config))
@ -116,6 +116,9 @@ else
PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS} PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS}
endif endif
# 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

View File

@ -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 * SPDX-License-Identifier: BSD-3-Clause
*/ */
#include <export/common/tbbr/tbbr_img_def_exp.h>
/dts-v1/; /dts-v1/;
/ { / {
/* Platform Config */ dtb-registry {
plat_arm_bl2 { 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"; compatible = "arm,tb_fw";
hw_config_addr = <0x0 0x82000000>;
hw_config_max_size = <0x01000000>;
/* Disable authentication for development */ /* Disable authentication for development */
disable_auth = <0x0>; 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 * The following two entries are placeholders for Mbed TLS
* heap information. The default values don't matter since * heap information. The default values don't matter since

View File

@ -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>;
};

View File

@ -20,6 +20,8 @@ fdt fdt_setprop_inplace
fdt fdt_check_header fdt fdt_check_header
fdt fdt_node_offset_by_compatible fdt fdt_node_offset_by_compatible
fdt fdt_setprop_inplace_namelen_partial fdt fdt_setprop_inplace_namelen_partial
fdt fdt_first_subnode
fdt fdt_next_subnode
mbedtls mbedtls_asn1_get_alg mbedtls mbedtls_asn1_get_alg
mbedtls mbedtls_asn1_get_alg_null mbedtls mbedtls_asn1_get_alg_null
mbedtls mbedtls_asn1_get_bitstring_null mbedtls mbedtls_asn1_get_bitstring_null

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015-2016, 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
*/ */
@ -60,17 +60,13 @@ static int is_watchdog_reset(void)
* The following function checks if Firmware update is needed, * The following function checks if Firmware update is needed,
* by checking if TOC in FIP image is valid or watchdog reset happened. * by checking if TOC in FIP image is valid or watchdog reset happened.
******************************************************************************/ ******************************************************************************/
int plat_arm_bl1_fwu_needed(void) bool plat_arm_bl1_fwu_needed(void)
{ {
const int32_t *nv_flags_ptr = (const int32_t *)V2M_SYS_NVFLAGS_ADDR; const int32_t *nv_flags_ptr = (const int32_t *)V2M_SYS_NVFLAGS_ADDR;
/* Check if TOC is invalid or watchdog reset happened. */ /* Check if TOC is invalid or watchdog reset happened. */
if ((arm_io_is_toc_valid() != 1) || return (!arm_io_is_toc_valid() || (((*nv_flags_ptr == -EAUTH) ||
(((*nv_flags_ptr == -EAUTH) || (*nv_flags_ptr == -ENOENT)) (*nv_flags_ptr == -ENOENT)) && is_watchdog_reset()));
&& is_watchdog_reset()))
return 1;
return 0;
} }
/******************************************************************************* /*******************************************************************************

View File

@ -156,8 +156,8 @@ else
endif endif
# Add the FDT_SOURCES and options for Dynamic Config # Add the FDT_SOURCES and options for Dynamic Config
FDT_SOURCES += plat/arm/board/juno/fdts/${PLAT}_tb_fw_config.dts FDT_SOURCES += plat/arm/board/juno/fdts/${PLAT}_fw_config.dts
TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb
# Add the TB_FW_CONFIG to FIP and specify the same to certtool # Add the TB_FW_CONFIG to FIP and specify the same to certtool
$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config)) $(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config))

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015-2019, 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
*/ */
@ -11,6 +11,7 @@
#include <arch.h> #include <arch.h>
#include <bl1/bl1.h> #include <bl1/bl1.h>
#include <common/bl_common.h> #include <common/bl_common.h>
#include <lib/fconf/fconf.h>
#include <lib/utils.h> #include <lib/utils.h>
#include <lib/xlat_tables/xlat_tables_compat.h> #include <lib/xlat_tables/xlat_tables_compat.h>
#include <plat/arm/common/plat_arm.h> #include <plat/arm/common/plat_arm.h>
@ -143,7 +144,10 @@ void arm_bl1_platform_setup(void)
{ {
/* 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();
arm_load_tb_fw_config();
/* Load fw config */
fconf_load_config();
#if TRUSTED_BOARD_BOOT #if TRUSTED_BOARD_BOOT
/* Share the Mbed TLS heap info with other images */ /* Share the Mbed TLS heap info with other images */
arm_bl1_set_mbedtls_heap(); arm_bl1_set_mbedtls_heap();
@ -184,9 +188,9 @@ void bl1_plat_prepare_exit(entry_point_info_t *ep_info)
* On Arm platforms, the FWU process is triggered when the FIP image has * On Arm platforms, the FWU process is triggered when the FIP image has
* been tampered with. * been tampered with.
*/ */
int plat_arm_bl1_fwu_needed(void) bool plat_arm_bl1_fwu_needed(void)
{ {
return (arm_io_is_toc_valid() != 1); return !arm_io_is_toc_valid();
} }
/******************************************************************************* /*******************************************************************************
@ -195,8 +199,5 @@ int plat_arm_bl1_fwu_needed(void)
******************************************************************************/ ******************************************************************************/
unsigned int bl1_plat_get_next_image_id(void) unsigned int bl1_plat_get_next_image_id(void)
{ {
if (plat_arm_bl1_fwu_needed() != 0) return plat_arm_bl1_fwu_needed() ? NS_BL1U_IMAGE_ID : BL2_IMAGE_ID;
return NS_BL1U_IMAGE_ID;
return BL2_IMAGE_ID;
} }

View File

@ -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,
/* 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)

View File

@ -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 \
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)
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)

View File

@ -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)
#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)
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)
* 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)
* 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)
*/ */
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)
#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)
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)
} }
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)
*/ */
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
} }

View File

@ -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)
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

View File

@ -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);
}

View File

@ -1,5 +1,5 @@
/* /*
* 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)
} }
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,
* 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);
} }

View File

@ -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 */