Commit 326150b9 authored by Louis Mayencourt's avatar Louis Mayencourt
Browse files

fconf: Add documentation



Change-Id: I606f9491fb6deebc6845c5b9d7db88fc5c895bd9
Signed-off-by: default avatarLouis Mayencourt <louis.mayencourt@arm.com>
parent 0a6e7e3b
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
...@@ -9,6 +9,7 @@ Components ...@@ -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
......
...@@ -6,11 +6,13 @@ ...@@ -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`
......
...@@ -42,12 +42,18 @@ You can find additional definitions in the `Arm Glossary`_. ...@@ -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
......
@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
@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
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment