summaryrefslogtreecommitdiffstats
path: root/docs/components/fconf
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--docs/components/fconf/amu-bindings.rst142
-rw-r--r--docs/components/fconf/fconf_properties.rst39
-rw-r--r--docs/components/fconf/index.rst149
-rw-r--r--docs/components/fconf/mpmm-bindings.rst48
4 files changed, 378 insertions, 0 deletions
diff --git a/docs/components/fconf/amu-bindings.rst b/docs/components/fconf/amu-bindings.rst
new file mode 100644
index 0000000..047f75e
--- /dev/null
+++ b/docs/components/fconf/amu-bindings.rst
@@ -0,0 +1,142 @@
+Activity Monitor Unit (AMU) Bindings
+====================================
+
+To support platform-defined Activity Monitor Unit (|AMU|) auxiliary counters
+through FCONF, the ``HW_CONFIG`` device tree accepts several |AMU|-specific
+nodes and properties.
+
+Bindings
+^^^^^^^^
+
+.. contents::
+ :local:
+
+``/cpus/cpus/cpu*`` node properties
+"""""""""""""""""""""""""""""""""""
+
+The ``cpu`` node has been augmented to support a handle to an associated |AMU|
+view, which should describe the counters offered by the core.
+
++---------------+-------+---------------+-------------------------------------+
+| Property name | Usage | Value type | Description |
++===============+=======+===============+=====================================+
+| ``amu`` | O | ``<phandle>`` | If present, indicates that an |AMU| |
+| | | | is available and its counters are |
+| | | | described by the node provided. |
++---------------+-------+---------------+-------------------------------------+
+
+``/cpus/amus`` node properties
+""""""""""""""""""""""""""""""
+
+The ``amus`` node describes the |AMUs| implemented by the cores in the system.
+This node does not have any properties.
+
+``/cpus/amus/amu*`` node properties
+"""""""""""""""""""""""""""""""""""
+
+An ``amu`` node describes the layout and meaning of the auxiliary counter
+registers of one or more |AMUs|, and may be shared by multiple cores.
+
++--------------------+-------+------------+------------------------------------+
+| Property name | Usage | Value type | Description |
++====================+=======+============+====================================+
+| ``#address-cells`` | R | ``<u32>`` | Value shall be 1. Specifies that |
+| | | | the ``reg`` property array of |
+| | | | children of this node uses a |
+| | | | single cell. |
++--------------------+-------+------------+------------------------------------+
+| ``#size-cells`` | R | ``<u32>`` | Value shall be 0. Specifies that |
+| | | | no size is required in the ``reg`` |
+| | | | property in children of this node. |
++--------------------+-------+------------+------------------------------------+
+
+``/cpus/amus/amu*/counter*`` node properties
+""""""""""""""""""""""""""""""""""""""""""""
+
+A ``counter`` node describes an auxiliary counter belonging to the parent |AMU|
+view.
+
++-------------------+-------+-------------+------------------------------------+
+| Property name | Usage | Value type | Description |
++===================+=======+=============+====================================+
+| ``reg`` | R | array | Represents the counter register |
+| | | | index, and must be a single cell. |
++-------------------+-------+-------------+------------------------------------+
+| ``enable-at-el3`` | O | ``<empty>`` | The presence of this property |
+| | | | indicates that this counter should |
+| | | | be enabled prior to EL3 exit. |
++-------------------+-------+-------------+------------------------------------+
+
+Example
+^^^^^^^
+
+An example system offering four cores made up of two clusters, where the cores
+of each cluster share different |AMUs|, may use something like the following:
+
+.. code-block::
+
+ cpus {
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ amus {
+ amu0: amu-0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ counterX: counter@0 {
+ reg = <0>;
+
+ enable-at-el3;
+ };
+
+ counterY: counter@1 {
+ reg = <1>;
+
+ enable-at-el3;
+ };
+ };
+
+ amu1: amu-1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ counterZ: counter@0 {
+ reg = <0>;
+
+ enable-at-el3;
+ };
+ };
+ };
+
+ cpu0@00000 {
+ ...
+
+ amu = <&amu0>;
+ };
+
+ cpu1@00100 {
+ ...
+
+ amu = <&amu0>;
+ };
+
+ cpu2@10000 {
+ ...
+
+ amu = <&amu1>;
+ };
+
+ cpu3@10100 {
+ ...
+
+ amu = <&amu1>;
+ };
+ }
+
+In this situation, ``cpu0`` and ``cpu1`` (the two cores in the first cluster),
+share the view of their AMUs defined by ``amu0``. Likewise, ``cpu2`` and
+``cpu3`` (the two cores in the second cluster), share the view of their |AMUs|
+defined by ``amu1``. This will cause ``counterX`` and ``counterY`` to be enabled
+for both ``cpu0`` and ``cpu1``, and ``counterZ`` to be enabled for both ``cpu2``
+and ``cpu3``.
diff --git a/docs/components/fconf/fconf_properties.rst b/docs/components/fconf/fconf_properties.rst
new file mode 100644
index 0000000..20cc758
--- /dev/null
+++ b/docs/components/fconf/fconf_properties.rst
@@ -0,0 +1,39 @@
+DTB binding for FCONF properties
+================================
+
+This document describes the device tree format of |FCONF| properties. These
+properties are not related to a specific platform and can be queried from
+common code.
+
+Dynamic configuration
+~~~~~~~~~~~~~~~~~~~~~
+
+The |FCONF| framework expects a *dtb-registry* node with the following field:
+
+- compatible [mandatory]
+ - value type: <string>
+ - Must be the string "fconf,dyn_cfg-dtb_registry".
+
+Then a list of subnodes representing a configuration |DTB|, which can be used
+by |FCONF|. Each subnode should be named according to the information it
+contains, and must be formed with the following fields:
+
+- load-address [mandatory]
+ - value type: <u64>
+ - Physical loading base address of the configuration.
+
+- max-size [mandatory]
+ - value type: <u32>
+ - Maximum size of the configuration.
+
+- id [mandatory]
+ - value type: <u32>
+ - Image ID of the configuration.
+
+- ns-load-address [optional]
+ - value type: <u64>
+ - Physical loading base address of the configuration in the non-secure
+ memory.
+ Only needed by those configuration files which require being loaded
+ in secure memory (at load-address) as well as in non-secure memory
+ e.g. HW_CONFIG
diff --git a/docs/components/fconf/index.rst b/docs/components/fconf/index.rst
new file mode 100644
index 0000000..029f324
--- /dev/null
+++ b/docs/components/fconf/index.rst
@@ -0,0 +1,149 @@
+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
+- GICv3 properties: hw_config.gicv3_config.gicr_base
+
+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
+properties originate from a different backend source such as a device tree,
+then the platform has to provide a ``populate()`` function which essentially
+captures the property and stores them into a corresponding |FCONF| based C
+structure.
+
+Such a ``populate()`` function is usually platform specific and is associated
+with a specific backend source. For example, a populator function which
+captures the hardware topology of the platform from the HW_CONFIG device tree.
+Hence each ``populate()`` function must be registered with a specific
+``config_type`` identifier. It broadly represents a logical grouping of
+configuration properties which is usually a device tree file.
+
+Example:
+ - FW_CONFIG: properties related to base address, maximum size and image id
+ of other DTBs etc.
+ - TB_FW: properties related to trusted firmware such as IO policies,
+ mbedtls heap info etc.
+ - HW_CONFIG: properties related to hardware configuration of the SoC
+ such as topology, GIC controller, PSCI hooks, CPU ID etc.
+
+Hence the ``populate()`` callback 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_topology(uintptr_t config)
+ {
+ /* read hw config dtb and fill soc_topology struct */
+ }
+
+ FCONF_REGISTER_POPULATOR(HW_CONFIG, topology, fconf_populate_topology);
+
+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 hw_config__topology_getter(prop) soc_topology.prop
+
+This second level wrapper can be used to remap the ``FCONF_GET_PROPERTY()`` to
+anything appropriate: structure, array, function, etc..
+
+To ensure a good interpretation of the properties, this documentation must
+explain how the properties are described for a specific backend. Refer to the
+:ref:`binding-document` section for more information and example.
+
+Loading the property device tree
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The ``fconf_load_config(image_id)`` must be called to load fw_config and
+tb_fw_config devices 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()`` as described above.
+
+.. uml:: ../../resources/diagrams/plantuml/fconf_bl2_populate.puml
+
+Namespace guidance
+~~~~~~~~~~~~~~~~~~
+
+As mentioned above, properties are logically grouped around namespaces and
+sub-namespaces. The following concepts should be considered when adding new
+properties/namespaces.
+The framework differentiates two types of properties:
+
+ - Properties used inside common code.
+ - Properties used inside platform specific code.
+
+The first category applies to properties being part of the firmware and shared
+across multiple platforms. They should be globally accessible and defined
+inside the ``lib/fconf`` directory. The namespace must be chosen to reflect the
+feature/data abstracted.
+
+Example:
+ - |TBBR| related properties: tbbr.cot.bl2_id
+ - Dynamic configuration information: dyn_cfg.dtb_info.hw_config_id
+
+The second category should represent the majority of the properties defined
+within the framework: Platform specific properties. They must be accessed only
+within the platform API and are defined only inside the platform scope. The
+namespace must contain the platform name under which the properties defined
+belong.
+
+Example:
+ - Arm io framework: arm.io_policies.bl31_id
+
+.. _binding-document:
+
+Properties binding information
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. toctree::
+ :maxdepth: 1
+
+ fconf_properties
+ amu-bindings
+ mpmm-bindings
diff --git a/docs/components/fconf/mpmm-bindings.rst b/docs/components/fconf/mpmm-bindings.rst
new file mode 100644
index 0000000..d3cc857
--- /dev/null
+++ b/docs/components/fconf/mpmm-bindings.rst
@@ -0,0 +1,48 @@
+Maximum Power Mitigation Mechanism (MPMM) Bindings
+==================================================
+
+|MPMM| support cannot be determined at runtime by the firmware. Instead, these
+DTB bindings allow the platform to communicate per-core support for |MPMM| via
+the ``HW_CONFIG`` device tree blob.
+
+Bindings
+^^^^^^^^
+
+.. contents::
+ :local:
+
+``/cpus/cpus/cpu*`` node properties
+"""""""""""""""""""""""""""""""""""
+
+The ``cpu`` node has been augmented to allow the platform to indicate support
+for |MPMM| on a given core.
+
++-------------------+-------+-------------+------------------------------------+
+| Property name | Usage | Value type | Description |
++===================+=======+=============+====================================+
+| ``supports-mpmm`` | O | ``<empty>`` | If present, indicates that |MPMM| |
+| | | | is available on this core. |
++-------------------+-------+-------------+------------------------------------+
+
+Example
+^^^^^^^
+
+An example system offering two cores, one with support for |MPMM| and one
+without, can be described as follows:
+
+.. code-block::
+
+ cpus {
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ cpu0@00000 {
+ ...
+
+ supports-mpmm;
+ };
+
+ cpu1@00100 {
+ ...
+ };
+ }