blob: 029f324dc762f49d6508f0c926c6d297acab817f [file] [log] [blame]
Louis Mayencourt8ac387c2019-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 Pappireddyae9677b2020-01-27 13:37:51 -060031- GICv3 properties: hw_config.gicv3_config.gicr_base
Louis Mayencourt8ac387c2019-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 Pappireddyae9677b2020-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 Mayencourt8ac387c2019-11-08 15:09:15 +000043
Madhukar Pappireddyae9677b2020-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:
Manish V Badarkhe824cb5c2020-06-21 05:41:11 +010052 - FW_CONFIG: properties related to base address, maximum size and image id
53 of other DTBs etc.
Madhukar Pappireddyae9677b2020-01-27 13:37:51 -060054 - TB_FW: properties related to trusted firmware such as IO policies,
Manish V Badarkhe824cb5c2020-06-21 05:41:11 +010055 mbedtls heap info etc.
Madhukar Pappireddyae9677b2020-01-27 13:37:51 -060056 - HW_CONFIG: properties related to hardware configuration of the SoC
57 such as topology, GIC controller, PSCI hooks, CPU ID etc.
58
59Hence the ``populate()`` callback must be registered to the (|FCONF|) framework
60with the ``FCONF_REGISTER_POPULATOR()`` macro. This ensures that the function
61would be called inside the generic ``fconf_populate()`` function during
Louis Mayencourt8ac387c2019-11-08 15:09:15 +000062initialization.
63
64::
65
Madhukar Pappireddyae9677b2020-01-27 13:37:51 -060066 int fconf_populate_topology(uintptr_t config)
Louis Mayencourt8ac387c2019-11-08 15:09:15 +000067 {
Madhukar Pappireddyae9677b2020-01-27 13:37:51 -060068 /* read hw config dtb and fill soc_topology struct */
Louis Mayencourt8ac387c2019-11-08 15:09:15 +000069 }
70
Madhukar Pappireddyae9677b2020-01-27 13:37:51 -060071 FCONF_REGISTER_POPULATOR(HW_CONFIG, topology, fconf_populate_topology);
Louis Mayencourt8ac387c2019-11-08 15:09:15 +000072
73Then, a wrapper has to be provided to match the ``FCONF_GET_PROPERTY()`` macro:
74
75::
76
77 /* generic getter */
78 #define FCONF_GET_PROPERTY(a,b,property) a##__##b##_getter(property)
79
80 /* my specific getter */
Madhukar Pappireddyae9677b2020-01-27 13:37:51 -060081 #define hw_config__topology_getter(prop) soc_topology.prop
Louis Mayencourt8ac387c2019-11-08 15:09:15 +000082
83This second level wrapper can be used to remap the ``FCONF_GET_PROPERTY()`` to
84anything appropriate: structure, array, function, etc..
85
Louis Mayencourta458dfa2020-04-20 14:14:10 +010086To ensure a good interpretation of the properties, this documentation must
87explain how the properties are described for a specific backend. Refer to the
88:ref:`binding-document` section for more information and example.
89
Louis Mayencourt8ac387c2019-11-08 15:09:15 +000090Loading the property device tree
91~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
92
Manish V Badarkhe824cb5c2020-06-21 05:41:11 +010093The ``fconf_load_config(image_id)`` must be called to load fw_config and
94tb_fw_config devices tree containing the properties' values. This must be done
95after the io layer is initialized, as the |DTB| is stored on an external
96device (FIP).
Louis Mayencourt8ac387c2019-11-08 15:09:15 +000097
Louis Mayencourta458dfa2020-04-20 14:14:10 +010098.. uml:: ../../resources/diagrams/plantuml/fconf_bl1_load_config.puml
Louis Mayencourt8ac387c2019-11-08 15:09:15 +000099
100Populating the properties
101~~~~~~~~~~~~~~~~~~~~~~~~~
102
103Once a valid device tree is available, the ``fconf_populate(config)`` function
104can be used to fill the C data structure with the data from the config |DTB|.
105This function will call all the ``populate()`` callbacks which have been
Madhukar Pappireddyae9677b2020-01-27 13:37:51 -0600106registered with ``FCONF_REGISTER_POPULATOR()`` as described above.
Louis Mayencourt8ac387c2019-11-08 15:09:15 +0000107
Louis Mayencourta458dfa2020-04-20 14:14:10 +0100108.. uml:: ../../resources/diagrams/plantuml/fconf_bl2_populate.puml
Louis Mayencourt29792242020-03-09 16:43:25 +0000109
110Namespace guidance
111~~~~~~~~~~~~~~~~~~
112
113As mentioned above, properties are logically grouped around namespaces and
114sub-namespaces. The following concepts should be considered when adding new
115properties/namespaces.
116The framework differentiates two types of properties:
Louis Mayencourt950ef2f2020-03-27 11:49:20 +0000117
Louis Mayencourt29792242020-03-09 16:43:25 +0000118 - Properties used inside common code.
119 - Properties used inside platform specific code.
120
121The first category applies to properties being part of the firmware and shared
122across multiple platforms. They should be globally accessible and defined
123inside the ``lib/fconf`` directory. The namespace must be chosen to reflect the
124feature/data abstracted.
Louis Mayencourt950ef2f2020-03-27 11:49:20 +0000125
Louis Mayencourt29792242020-03-09 16:43:25 +0000126Example:
127 - |TBBR| related properties: tbbr.cot.bl2_id
128 - Dynamic configuration information: dyn_cfg.dtb_info.hw_config_id
129
130The second category should represent the majority of the properties defined
131within the framework: Platform specific properties. They must be accessed only
132within the platform API and are defined only inside the platform scope. The
133namespace must contain the platform name under which the properties defined
134belong.
Louis Mayencourt950ef2f2020-03-27 11:49:20 +0000135
Louis Mayencourt29792242020-03-09 16:43:25 +0000136Example:
137 - Arm io framework: arm.io_policies.bl31_id
138
Louis Mayencourta458dfa2020-04-20 14:14:10 +0100139.. _binding-document:
140
141Properties binding information
142~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
143
144.. toctree::
145 :maxdepth: 1
146
147 fconf_properties
Chris Kayf11909f2021-08-19 11:21:52 +0100148 amu-bindings
Chris Kay03be39d2021-05-05 13:38:30 +0100149 mpmm-bindings