xref: /rk3399_ARM-atf/docs/components/fconf/index.rst (revision 4874793d2ba048b15322aed651bcede35d9dfe33)
1*4874793dSLouis MayencourtFirmware Configuration Framework
2*4874793dSLouis Mayencourt================================
3*4874793dSLouis Mayencourt
4*4874793dSLouis MayencourtThis document provides an overview of the |FCONF| framework.
5*4874793dSLouis Mayencourt
6*4874793dSLouis MayencourtIntroduction
7*4874793dSLouis Mayencourt~~~~~~~~~~~~
8*4874793dSLouis Mayencourt
9*4874793dSLouis MayencourtThe Firmware CONfiguration Framework (|FCONF|) is an abstraction layer for
10*4874793dSLouis Mayencourtplatform specific data, allowing a "property" to be queried and a value
11*4874793dSLouis Mayencourtretrieved without the requesting entity knowing what backing store is being used
12*4874793dSLouis Mayencourtto hold the data.
13*4874793dSLouis Mayencourt
14*4874793dSLouis MayencourtIt is used to bridge new and old ways of providing platform-specific data.
15*4874793dSLouis MayencourtToday, information like the Chain of Trust is held within several, nested
16*4874793dSLouis Mayencourtplatform-defined tables. In the future, it may be provided as part of a device
17*4874793dSLouis Mayencourtblob, along with the rest of the information about images to load.
18*4874793dSLouis MayencourtIntroducing this abstraction layer will make migration easier and will preserve
19*4874793dSLouis Mayencourtfunctionality for platforms that cannot / don't want to use device tree.
20*4874793dSLouis Mayencourt
21*4874793dSLouis MayencourtAccessing properties
22*4874793dSLouis Mayencourt~~~~~~~~~~~~~~~~~~~~
23*4874793dSLouis Mayencourt
24*4874793dSLouis MayencourtProperties defined in the |FCONF| are grouped around namespaces and
25*4874793dSLouis Mayencourtsub-namespaces: a.b.property.
26*4874793dSLouis MayencourtExamples namespace can be:
27*4874793dSLouis Mayencourt
28*4874793dSLouis Mayencourt- (|TBBR|) Chain of Trust data: tbbr.cot.trusted_boot_fw_cert
29*4874793dSLouis Mayencourt- (|TBBR|) dynamic configuration info: tbbr.dyn_config.disable_auth
30*4874793dSLouis Mayencourt- Arm io policies: arm.io_policies.bl2_image
31*4874793dSLouis Mayencourt- GICv3 properties: hw_config.gicv3_config.gicr_base
32*4874793dSLouis Mayencourt
33*4874793dSLouis MayencourtProperties can be accessed with the ``FCONF_GET_PROPERTY(a,b,property)`` macro.
34*4874793dSLouis Mayencourt
35*4874793dSLouis MayencourtDefining properties
36*4874793dSLouis Mayencourt~~~~~~~~~~~~~~~~~~~
37*4874793dSLouis Mayencourt
38*4874793dSLouis MayencourtProperties composing the |FCONF| have to be stored in C structures. If
39*4874793dSLouis Mayencourtproperties originate from a different backend source such as a device tree,
40*4874793dSLouis Mayencourtthen the platform has to provide a ``populate()`` function which essentially
41*4874793dSLouis Mayencourtcaptures the property and stores them into a corresponding |FCONF| based C
42*4874793dSLouis Mayencourtstructure.
43*4874793dSLouis Mayencourt
44*4874793dSLouis MayencourtSuch a ``populate()`` function is usually platform specific and is associated
45*4874793dSLouis Mayencourtwith a specific backend source. For example, a populator function which
46*4874793dSLouis Mayencourtcaptures the hardware topology of the platform from the HW_CONFIG device tree.
47*4874793dSLouis MayencourtHence each ``populate()`` function must be registered with a specific
48*4874793dSLouis Mayencourt``config_type`` identifier. It broadly represents a logical grouping of
49*4874793dSLouis Mayencourtconfiguration properties which is usually a device tree file.
50*4874793dSLouis Mayencourt
51*4874793dSLouis MayencourtExample:
52*4874793dSLouis Mayencourt - TB_FW: properties related to trusted firmware such as IO policies,
53*4874793dSLouis Mayencourt   base address of other DTBs, mbedtls heap info etc.
54*4874793dSLouis Mayencourt - HW_CONFIG: properties related to hardware configuration of the SoC
55*4874793dSLouis Mayencourt   such as topology, GIC controller, PSCI hooks, CPU ID etc.
56*4874793dSLouis Mayencourt
57*4874793dSLouis MayencourtHence the ``populate()`` callback must be registered to the (|FCONF|) framework
58*4874793dSLouis Mayencourtwith the ``FCONF_REGISTER_POPULATOR()`` macro. This ensures that the function
59*4874793dSLouis Mayencourtwould be called inside the generic ``fconf_populate()`` function during
60*4874793dSLouis Mayencourtinitialization.
61*4874793dSLouis Mayencourt
62*4874793dSLouis Mayencourt::
63*4874793dSLouis Mayencourt
64*4874793dSLouis Mayencourt    int fconf_populate_topology(uintptr_t config)
65*4874793dSLouis Mayencourt    {
66*4874793dSLouis Mayencourt        /* read hw config dtb and fill soc_topology struct */
67*4874793dSLouis Mayencourt    }
68*4874793dSLouis Mayencourt
69*4874793dSLouis Mayencourt    FCONF_REGISTER_POPULATOR(HW_CONFIG, topology, fconf_populate_topology);
70*4874793dSLouis Mayencourt
71*4874793dSLouis MayencourtThen, a wrapper has to be provided to match the ``FCONF_GET_PROPERTY()`` macro:
72*4874793dSLouis Mayencourt
73*4874793dSLouis Mayencourt::
74*4874793dSLouis Mayencourt
75*4874793dSLouis Mayencourt    /* generic getter */
76*4874793dSLouis Mayencourt    #define FCONF_GET_PROPERTY(a,b,property)	a##__##b##_getter(property)
77*4874793dSLouis Mayencourt
78*4874793dSLouis Mayencourt    /* my specific getter */
79*4874793dSLouis Mayencourt    #define hw_config__topology_getter(prop) soc_topology.prop
80*4874793dSLouis Mayencourt
81*4874793dSLouis MayencourtThis second level wrapper can be used to remap the ``FCONF_GET_PROPERTY()`` to
82*4874793dSLouis Mayencourtanything appropriate: structure, array, function, etc..
83*4874793dSLouis Mayencourt
84*4874793dSLouis MayencourtTo ensure a good interpretation of the properties, this documentation must
85*4874793dSLouis Mayencourtexplain how the properties are described for a specific backend. Refer to the
86*4874793dSLouis Mayencourt:ref:`binding-document` section for more information and example.
87*4874793dSLouis Mayencourt
88*4874793dSLouis MayencourtLoading the property device tree
89*4874793dSLouis Mayencourt~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
90*4874793dSLouis Mayencourt
91*4874793dSLouis MayencourtThe ``fconf_load_config()`` must be called to load the device tree containing
92*4874793dSLouis Mayencourtthe properties' values. This must be done after the io layer is initialized, as
93*4874793dSLouis Mayencourtthe |DTB| is stored on an external device (FIP).
94*4874793dSLouis Mayencourt
95*4874793dSLouis Mayencourt.. uml:: ../../resources/diagrams/plantuml/fconf_bl1_load_config.puml
96*4874793dSLouis Mayencourt
97*4874793dSLouis MayencourtPopulating the properties
98*4874793dSLouis Mayencourt~~~~~~~~~~~~~~~~~~~~~~~~~
99*4874793dSLouis Mayencourt
100*4874793dSLouis MayencourtOnce a valid device tree is available, the ``fconf_populate(config)`` function
101*4874793dSLouis Mayencourtcan be used to fill the C data structure with the data from the config |DTB|.
102*4874793dSLouis MayencourtThis function will call all the ``populate()`` callbacks which have been
103*4874793dSLouis Mayencourtregistered with ``FCONF_REGISTER_POPULATOR()`` as described above.
104*4874793dSLouis Mayencourt
105*4874793dSLouis Mayencourt.. uml:: ../../resources/diagrams/plantuml/fconf_bl2_populate.puml
106*4874793dSLouis Mayencourt
107*4874793dSLouis MayencourtNamespace guidance
108*4874793dSLouis Mayencourt~~~~~~~~~~~~~~~~~~
109*4874793dSLouis Mayencourt
110*4874793dSLouis MayencourtAs mentioned above, properties are logically grouped around namespaces and
111*4874793dSLouis Mayencourtsub-namespaces. The following concepts should be considered when adding new
112*4874793dSLouis Mayencourtproperties/namespaces.
113*4874793dSLouis MayencourtThe framework differentiates two types of properties:
114*4874793dSLouis Mayencourt
115*4874793dSLouis Mayencourt - Properties used inside common code.
116*4874793dSLouis Mayencourt - Properties used inside platform specific code.
117*4874793dSLouis Mayencourt
118*4874793dSLouis MayencourtThe first category applies to properties being part of the firmware and shared
119*4874793dSLouis Mayencourtacross multiple platforms. They should be globally accessible and defined
120*4874793dSLouis Mayencourtinside the ``lib/fconf`` directory. The namespace must be chosen to reflect the
121*4874793dSLouis Mayencourtfeature/data abstracted.
122*4874793dSLouis Mayencourt
123*4874793dSLouis MayencourtExample:
124*4874793dSLouis Mayencourt - |TBBR| related properties: tbbr.cot.bl2_id
125*4874793dSLouis Mayencourt - Dynamic configuration information: dyn_cfg.dtb_info.hw_config_id
126*4874793dSLouis Mayencourt
127*4874793dSLouis MayencourtThe second category should represent the majority of the properties defined
128*4874793dSLouis Mayencourtwithin the framework: Platform specific properties. They must be accessed only
129*4874793dSLouis Mayencourtwithin the platform API and are defined only inside the platform scope. The
130*4874793dSLouis Mayencourtnamespace must contain the platform name under which the properties defined
131*4874793dSLouis Mayencourtbelong.
132*4874793dSLouis Mayencourt
133*4874793dSLouis MayencourtExample:
134*4874793dSLouis Mayencourt - Arm io framework: arm.io_policies.bl31_id
135*4874793dSLouis Mayencourt
136*4874793dSLouis Mayencourt.. _binding-document:
137*4874793dSLouis Mayencourt
138*4874793dSLouis MayencourtProperties binding information
139*4874793dSLouis Mayencourt~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
140*4874793dSLouis Mayencourt
141*4874793dSLouis Mayencourt.. toctree::
142*4874793dSLouis Mayencourt  :maxdepth: 1
143*4874793dSLouis Mayencourt
144*4874793dSLouis Mayencourt  fconf_properties
145