fconf: initial commit

Introduce the Firmware CONfiguration Framework (fconf).

The 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.

The default backing store used is C structure. If another backing store
has to be used, the platform integrator needs 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()". This ensures that the function would
be called inside the "fconf_populate()" function.

A two level macro is used as getter:
- the first macro takes 3 parameters and converts it to a function
  call: FCONF_GET_PROPERTY(a,b,c) -> a__b_getter(c).
- the second level defines a__b_getter(c) to the matching C structure,
  variable, array, function, etc..

Ex: Get a Chain of trust property:
    1) FCONF_GET_PROPERY(tbbr, cot, BL2_id) -> tbbr__cot_getter(BL2_id)
    2) tbbr__cot_getter(BL2_id) -> cot_desc_ptr[BL2_id]

Change-Id: Id394001353ed295bc680c3f543af0cf8da549469
Signed-off-by: Louis Mayencourt <louis.mayencourt@arm.com>
This commit is contained in:
Louis Mayencourt 2019-08-08 12:03:26 +01:00
parent d6b44b10e9
commit ab1981db9e
7 changed files with 132 additions and 6 deletions

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
*/
@ -46,6 +46,11 @@ SECTIONS
__RODATA_START__ = .;
*(SORT_BY_ALIGNMENT(.rodata*))
. = ALIGN(8);
__FCONF_POPULATOR_START__ = .;
KEEP(*(.fconf_populator))
__FCONF_POPULATOR_END__ = .;
/* Ensure 8-byte alignment for descriptors and ensure inclusion */
. = ALIGN(8);
__PARSER_LIB_DESCS_START__ = .;
@ -62,6 +67,11 @@ SECTIONS
*(SORT_BY_ALIGNMENT(.text*))
*(SORT_BY_ALIGNMENT(.rodata*))
. = ALIGN(8);
__FCONF_POPULATOR_START__ = .;
KEEP(*(.fconf_populator))
__FCONF_POPULATOR_END__ = .;
/* Ensure 8-byte alignment for descriptors and ensure inclusion */
. = ALIGN(8);
__PARSER_LIB_DESCS_START__ = .;

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
*/
@ -16,6 +16,7 @@
#include <drivers/auth/auth_mod.h>
#include <drivers/auth/crypto_mod.h>
#include <drivers/auth/img_parser_mod.h>
#include <lib/fconf/fconf_tbbr_getter.h>
#include <plat/common/platform.h>
/* 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;
assert(parent_id != NULL);
/* 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) */
if (img_desc->parent == NULL) {
@ -353,7 +353,7 @@ int auth_mod_verify_img(unsigned int img_id,
int rc, i;
/* 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 */
rc = img_parser_check_integrity(img_desc->img_type, img_ptr, img_len);

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

@ -0,0 +1,47 @@
/*
* 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);
};
/* 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);
#endif /* FCONF_H */

View File

@ -0,0 +1,15 @@
/*
* 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]
#endif /* FCONF_TBBR_GETTER_H */

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

@ -0,0 +1,40 @@
/*
* Copyright (c) 2019-2020, ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <common/debug.h>
#include <lib/fconf/fconf.h>
#include <libfdt.h>
#include <platform_def.h>
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();
}
}
}

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

@ -0,0 +1,11 @@
#
# 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
BL1_SOURCES += ${FCONF_SOURCES}
BL2_SOURCES += ${FCONF_SOURCES}

View File

@ -198,6 +198,9 @@ BL2_SOURCES += drivers/delay_timer/delay_timer.c \
plat/arm/common/arm_err.c \
plat/arm/common/arm_io_storage.c
# Firmware Configuration Framework sources
include lib/fconf/fconf.mk
# Add `libfdt` and Arm common helpers required for Dynamic Config
include lib/libfdt/libfdt.mk
@ -270,7 +273,7 @@ ifneq (${TRUSTED_BOARD_BOOT},0)
# Include common TBB sources
AUTH_SOURCES := drivers/auth/auth_mod.c \
drivers/auth/crypto_mod.c \
drivers/auth/img_parser_mod.c \
drivers/auth/img_parser_mod.c
# Include the selected chain of trust sources.
ifeq (${COT},tbbr)