blob: 4ea1f5ba063dfc4a55ddec429c153a1457d8cc3d [file] [log] [blame]
Louis Mayencourt326150b2019-11-08 15:09:15 +00001Firmware Configuration Framework
2================================
3
4This document provides an overview of the |FCONF| framework.
5
6Introduction
7~~~~~~~~~~~~
8
9The Firmware CONfiguration Framework (|FCONF|) is an abstraction layer for
10platform specific data, allowing a "property" to be queried and a value
11retrieved without the requesting entity knowing what backing store is being used
12to hold the data.
13
14It is used to bridge new and old ways of providing platform-specific data.
15Today, information like the Chain of Trust is held within several, nested
16platform-defined tables. In the future, it may be provided as part of a device
17blob, along with the rest of the information about images to load.
18Introducing this abstraction layer will make migration easier and will preserve
19functionality for platforms that cannot / don't want to use device tree.
20
21Accessing properties
22~~~~~~~~~~~~~~~~~~~~
23
24Properties defined in the |FCONF| are grouped around namespaces and
25sub-namespaces: a.b.property.
26Examples namespace can be:
27
28- (|TBBR|) Chain of Trust data: tbbr.cot.trusted_boot_fw_cert
29- (|TBBR|) dynamic configuration info: tbbr.dyn_config.disable_auth
30- Arm io policies: arm.io_policies.bl2_image
Madhukar Pappireddy26d1e0c2020-01-27 13:37:51 -060031- GICv3 properties: hw_config.gicv3_config.gicr_base
Louis Mayencourt326150b2019-11-08 15:09:15 +000032
33Properties can be accessed with the ``FCONF_GET_PROPERTY(a,b,property)`` macro.
34
35Defining properties
36~~~~~~~~~~~~~~~~~~~
37
Madhukar Pappireddy26d1e0c2020-01-27 13:37:51 -060038Properties composing the |FCONF| have to be stored in C structures. If
39properties originate from a different backend source such as a device tree,
40then the platform has to provide a ``populate()`` function which essentially
41captures the property and stores them into a corresponding |FCONF| based C
42structure.
Louis Mayencourt326150b2019-11-08 15:09:15 +000043
Madhukar Pappireddy26d1e0c2020-01-27 13:37:51 -060044Such a ``populate()`` function is usually platform specific and is associated
45with a specific backend source. For example, a populator function which
46captures the hardware topology of the platform from the HW_CONFIG device tree.
47Hence each ``populate()`` function must be registered with a specific
48``config_type`` identifier. It broadly represents a logical grouping of
49configuration properties which is usually a device tree file.
50
51Example:
52 - TB_FW: properties related to trusted firmware such as IO policies,
53 base address of other DTBs, mbedtls heap info etc.
54 - HW_CONFIG: properties related to hardware configuration of the SoC
55 such as topology, GIC controller, PSCI hooks, CPU ID etc.
56
57Hence the ``populate()`` callback must be registered to the (|FCONF|) framework
58with the ``FCONF_REGISTER_POPULATOR()`` macro. This ensures that the function
59would be called inside the generic ``fconf_populate()`` function during
Louis Mayencourt326150b2019-11-08 15:09:15 +000060initialization.
61
62::
63
Madhukar Pappireddy26d1e0c2020-01-27 13:37:51 -060064 int fconf_populate_topology(uintptr_t config)
Louis Mayencourt326150b2019-11-08 15:09:15 +000065 {
Madhukar Pappireddy26d1e0c2020-01-27 13:37:51 -060066 /* read hw config dtb and fill soc_topology struct */
Louis Mayencourt326150b2019-11-08 15:09:15 +000067 }
68
Madhukar Pappireddy26d1e0c2020-01-27 13:37:51 -060069 FCONF_REGISTER_POPULATOR(HW_CONFIG, topology, fconf_populate_topology);
Louis Mayencourt326150b2019-11-08 15:09:15 +000070
71Then, a wrapper has to be provided to match the ``FCONF_GET_PROPERTY()`` macro:
72
73::
74
75 /* generic getter */
76 #define FCONF_GET_PROPERTY(a,b,property) a##__##b##_getter(property)
77
78 /* my specific getter */
Madhukar Pappireddy26d1e0c2020-01-27 13:37:51 -060079 #define hw_config__topology_getter(prop) soc_topology.prop
Louis Mayencourt326150b2019-11-08 15:09:15 +000080
81This second level wrapper can be used to remap the ``FCONF_GET_PROPERTY()`` to
82anything appropriate: structure, array, function, etc..
83
84Loading the property device tree
85~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
86
87The ``fconf_load_config()`` must be called to load the device tree containing
88the properties' values. This must be done after the io layer is initialized, as
89the |DTB| is stored on an external device (FIP).
90
91.. uml:: ../resources/diagrams/plantuml/fconf_bl1_load_config.puml
92
93Populating the properties
94~~~~~~~~~~~~~~~~~~~~~~~~~
95
96Once a valid device tree is available, the ``fconf_populate(config)`` function
97can be used to fill the C data structure with the data from the config |DTB|.
98This function will call all the ``populate()`` callbacks which have been
Madhukar Pappireddy26d1e0c2020-01-27 13:37:51 -060099registered with ``FCONF_REGISTER_POPULATOR()`` as described above.
Louis Mayencourt326150b2019-11-08 15:09:15 +0000100
101.. uml:: ../resources/diagrams/plantuml/fconf_bl2_populate.puml