blob: cec3cebe4a96e3096543053eb3a4e6ab7ce376a2 [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
31
32Properties can be accessed with the ``FCONF_GET_PROPERTY(a,b,property)`` macro.
33
34Defining properties
35~~~~~~~~~~~~~~~~~~~
36
37Properties composing the |FCONF| have to be stored in C structures. If another
38backing store is wanted to be used, the platform has to provide a ``populate()``
39function to fill the corresponding C structure.
40
41The ``populate()`` function must be registered to the |FCONF| framework with
42the ``FCONF_REGISTER_POPULATOR()`` macro. This ensures that the function would
43be called inside the generic ``fconf_populate()`` function during
44initialization.
45
46::
47
48 int fconf_populate_tbbr_dyn_config(uintptr_t config)
49 {
50 /* read dtb and fill tbbr_dyn_config struct */
51 }
52
53 FCONF_REGISTER_POPULATOR(fconf_populate_tbbr_dyn_config);
54
55Then, a wrapper has to be provided to match the ``FCONF_GET_PROPERTY()`` macro:
56
57::
58
59 /* generic getter */
60 #define FCONF_GET_PROPERTY(a,b,property) a##__##b##_getter(property)
61
62 /* my specific getter */
63 #define tbbr__dyn_config_getter(id) tbbr_dyn_config.id
64
65This second level wrapper can be used to remap the ``FCONF_GET_PROPERTY()`` to
66anything appropriate: structure, array, function, etc..
67
68Loading the property device tree
69~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
70
71The ``fconf_load_config()`` must be called to load the device tree containing
72the properties' values. This must be done after the io layer is initialized, as
73the |DTB| is stored on an external device (FIP).
74
75.. uml:: ../resources/diagrams/plantuml/fconf_bl1_load_config.puml
76
77Populating the properties
78~~~~~~~~~~~~~~~~~~~~~~~~~
79
80Once a valid device tree is available, the ``fconf_populate(config)`` function
81can be used to fill the C data structure with the data from the config |DTB|.
82This function will call all the ``populate()`` callbacks which have been
83registered with ``FCONF_REGISTER_POPULATOR()``.
84
85.. uml:: ../resources/diagrams/plantuml/fconf_bl2_populate.puml