fconf: Add documentation
Change-Id: I606f9491fb6deebc6845c5b9d7db88fc5c895bd9
Signed-off-by: Louis Mayencourt <louis.mayencourt@arm.com>
diff --git a/docs/components/fconf.rst b/docs/components/fconf.rst
new file mode 100644
index 0000000..cec3ceb
--- /dev/null
+++ b/docs/components/fconf.rst
@@ -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
diff --git a/docs/components/index.rst b/docs/components/index.rst
index f1904c0..6a6b1b0 100644
--- a/docs/components/index.rst
+++ b/docs/components/index.rst
@@ -9,6 +9,7 @@
spd/index
arm-sip-service
exception-handling
+ fconf
firmware-update
platform-interrupt-controller-API
ras
diff --git a/docs/global_substitutions.txt b/docs/global_substitutions.txt
index 491b160..4dda1dc 100644
--- a/docs/global_substitutions.txt
+++ b/docs/global_substitutions.txt
@@ -6,11 +6,13 @@
.. |COT| replace:: :term:`COT`
.. |CSS| replace:: :term:`CSS`
.. |CVE| replace:: :term:`CVE`
+.. |DTB| replace:: :term:`DTB`
.. |DS-5| replace:: :term:`DS-5`
.. |DSU| replace:: :term:`DSU`
.. |DT| replace:: :term:`DT`
.. |EL| replace:: :term:`EL`
.. |EHF| replace:: :term:`EHF`
+.. |FCONF| replace:: :term:`FCONF`
.. |FDT| replace:: :term:`FDT`
.. |FIP| replace:: :term:`FIP`
.. |FVP| replace:: :term:`FVP`
diff --git a/docs/glossary.rst b/docs/glossary.rst
index 2f19df5..3da30b0 100644
--- a/docs/glossary.rst
+++ b/docs/glossary.rst
@@ -42,12 +42,18 @@
DT
Device Tree
+ DTB
+ Device Tree Blob
+
EL
Exception Level
EHF
Exception Handling Framework
+ FCONF
+ Firmware Configuration Framework
+
FDT
Flattened Device Tree
diff --git a/docs/resources/diagrams/plantuml/fconf_bl1_load_config.puml b/docs/resources/diagrams/plantuml/fconf_bl1_load_config.puml
new file mode 100644
index 0000000..c36e544
--- /dev/null
+++ b/docs/resources/diagrams/plantuml/fconf_bl1_load_config.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
diff --git a/docs/resources/diagrams/plantuml/fconf_bl2_populate.puml b/docs/resources/diagrams/plantuml/fconf_bl2_populate.puml
new file mode 100644
index 0000000..98a3ff1
--- /dev/null
+++ b/docs/resources/diagrams/plantuml/fconf_bl2_populate.puml
@@ -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