]> git.baikalelectronics.ru Git - arm-tf.git/commitdiff
fconf: necessary modifications to support fconf in BL31 & SP_MIN
authorMadhukar Pappireddy <madhukar.pappireddy@arm.com>
Mon, 27 Jan 2020 19:37:51 +0000 (13:37 -0600)
committerMadhukar Pappireddy <madhukar.pappireddy@arm.com>
Wed, 11 Mar 2020 16:24:55 +0000 (11:24 -0500)
Necessary infrastructure added to integrate fconf framework in BL31 & SP_MIN.
Created few populator() functions which parse HW_CONFIG device tree
and registered them with fconf framework. Many of the changes are
only applicable for fvp platform.

This patch:
1. Adds necessary symbols and sections in BL31, SP_MIN linker script
2. Adds necessary memory map entry for translation in BL31, SP_MIN
3. Creates an abstraction layer for hardware configuration based on
   fconf framework
4. Adds necessary changes to build flow (makefiles)
5. Minimal callback to read hw_config dtb for capturing properties
   related to GIC(interrupt-controller node)
6. updates the fconf documentation

Change-Id: Ib6292071f674ef093962b9e8ba0d322b7bf919af
Signed-off-by: Madhukar Pappireddy <madhukar.pappireddy@arm.com>
14 files changed:
Makefile
bl31/bl31.ld.S
bl32/sp_min/sp_min.ld.S
docs/components/fconf.rst
include/plat/arm/common/plat_arm.h
plat/arm/board/fvp/fconf/fconf_hw_config_getter.c [new file with mode: 0644]
plat/arm/board/fvp/fvp_bl31_setup.c
plat/arm/board/fvp/fvp_common.c
plat/arm/board/fvp/include/fconf_hw_config_getter.h [new file with mode: 0644]
plat/arm/board/fvp/include/platform_def.h
plat/arm/board/fvp/platform.mk
plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c
plat/arm/board/fvp/sp_min/sp_min-fvp.mk
plat/arm/common/sp_min/arm_sp_min_setup.c

index 3d5b395022f54def1fd5b63377dd0d57813034af..47a544dcfa5587ac6103fd5e2f263ebb63923fe4 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1000,6 +1000,8 @@ endif
 
 ifeq (${NEED_BL31},yes)
 BL31_SOURCES += ${SPD_SOURCES}
+# Sort BL31 source files to remove duplicates
+BL31_SOURCES := $(sort ${BL31_SOURCES})
 ifneq (${DECRYPTION_SUPPORT},none)
 $(if ${BL31}, $(eval $(call TOOL_ADD_IMG,bl31,--soc-fw,,$(ENCRYPT_BL31))),\
        $(eval $(call MAKE_BL,31,soc-fw,,$(ENCRYPT_BL31))))
@@ -1013,7 +1015,8 @@ endif
 # build system will call TOOL_ADD_IMG to print a warning message and abort the
 # process. Note that the dependency on BL32 applies to the FIP only.
 ifeq (${NEED_BL32},yes)
-
+# Sort BL32 source files to remove duplicates
+BL32_SOURCES := $(sort ${BL32_SOURCES})
 BUILD_BL32 := $(if $(BL32),,$(if $(BL32_SOURCES),1))
 
 ifneq (${DECRYPTION_SUPPORT},none)
index 4a1c5f31017591c3956c0221876878bc7eba74f5..fce9eb266d4b15f595a36b46f86065a15f6c1ebd 100644 (file)
@@ -54,6 +54,11 @@ SECTIONS
         KEEP(*(rt_svc_descs))
         __RT_SVC_DESCS_END__ = .;
 
+        . = ALIGN(8);
+         __FCONF_POPULATOR_START__ = .;
+        KEEP(*(.fconf_populator))
+         __FCONF_POPULATOR_END__ = .;
+
 #if ENABLE_PMF
         /* Ensure 8-byte alignment for descriptors and ensure inclusion */
         . = ALIGN(8);
@@ -101,6 +106,11 @@ SECTIONS
         KEEP(*(rt_svc_descs))
         __RT_SVC_DESCS_END__ = .;
 
+        . = ALIGN(8);
+         __FCONF_POPULATOR_START__ = .;
+        KEEP(*(.fconf_populator))
+         __FCONF_POPULATOR_END__ = .;
+
 #if ENABLE_PMF
         /* Ensure 8-byte alignment for descriptors and ensure inclusion */
         . = ALIGN(8);
index 6997a7fdbd6678b6600c461be58376f344268407..3231f9aec7977f02cc8da878aaf1da1a77bafc6f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -55,6 +55,11 @@ SECTIONS
         KEEP(*(rt_svc_descs))
         __RT_SVC_DESCS_END__ = .;
 
+        . = ALIGN(8);
+         __FCONF_POPULATOR_START__ = .;
+        KEEP(*(.fconf_populator))
+         __FCONF_POPULATOR_END__ = .;
+
 #if ENABLE_PMF
         /* Ensure 4-byte alignment for descriptors and ensure inclusion */
         . = ALIGN(4);
@@ -92,6 +97,11 @@ SECTIONS
         KEEP(*(rt_svc_descs))
         __RT_SVC_DESCS_END__ = .;
 
+        . = ALIGN(8);
+         __FCONF_POPULATOR_START__ = .;
+        KEEP(*(.fconf_populator))
+         __FCONF_POPULATOR_END__ = .;
+
         /*
          * Ensure 4-byte alignment for cpu_ops so that its fields are also
          * aligned. Also ensure cpu_ops inclusion.
index cec3cebe4a96e3096543053eb3a4e6ab7ce376a2..4ea1f5ba063dfc4a55ddec429c153a1457d8cc3d 100644 (file)
@@ -28,29 +28,45 @@ 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 another
-backing store is wanted to be used, the platform has to provide a ``populate()``
-function to fill the corresponding C structure.
-
-The ``populate()`` function 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
+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:
+ - TB_FW: properties related to trusted firmware such as IO policies,
+   base address of other DTBs, 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_tbbr_dyn_config(uintptr_t config)
+    int fconf_populate_topology(uintptr_t config)
     {
-        /* read dtb and fill tbbr_dyn_config struct */
+        /* read hw config dtb and fill soc_topology struct */
     }
 
-    FCONF_REGISTER_POPULATOR(fconf_populate_tbbr_dyn_config);
+    FCONF_REGISTER_POPULATOR(HW_CONFIG, topology, fconf_populate_topology);
 
 Then, a wrapper has to be provided to match the ``FCONF_GET_PROPERTY()`` macro:
 
@@ -60,7 +76,7 @@ Then, a wrapper has to be provided to match the ``FCONF_GET_PROPERTY()`` macro:
     #define FCONF_GET_PROPERTY(a,b,property)   a##__##b##_getter(property)
 
     /* my specific getter */
-    #define tbbr__dyn_config_getter(id)        tbbr_dyn_config.id
+    #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..
@@ -80,6 +96,6 @@ 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()``.
+registered with ``FCONF_REGISTER_POPULATOR()`` as described above.
 
 .. uml:: ../resources/diagrams/plantuml/fconf_bl2_populate.puml
index babde41feb6c60b648b0c463bd10cdcf6e9ad3fc..6c2925afa802bcc26744b7580bfb72a6561553f5 100644 (file)
@@ -222,6 +222,7 @@ void arm_tsp_early_platform_setup(void);
 void arm_sp_min_early_platform_setup(void *from_bl2, uintptr_t tos_fw_config,
                                uintptr_t hw_config, void *plat_params_from_bl2);
 void arm_sp_min_plat_runtime_setup(void);
+void arm_sp_min_plat_arch_setup(void);
 
 /* FIP TOC validity check */
 bool arm_io_is_toc_valid(void);
diff --git a/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c b/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c
new file mode 100644 (file)
index 0000000..1a1d056
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <common/debug.h>
+#include <common/fdt_wrappers.h>
+#include <fconf_hw_config_getter.h>
+#include <libfdt.h>
+#include <plat/common/platform.h>
+
+struct gicv3_config_t gicv3_config;
+
+int fconf_populate_gicv3_config(uintptr_t config)
+{
+       int err;
+       int node;
+       int addr[20];
+
+       /* Necessary to work with libfdt APIs */
+       const void *hw_config_dtb = (const void *)config;
+
+       /*
+        * Find the offset of the node containing "arm,gic-v3" compatible property.
+        * Populating fconf strucutures dynamically is not supported for legacy
+        * systems which use GICv2 IP. Simply skip extracting GIC properties.
+        */
+       node = fdt_node_offset_by_compatible(hw_config_dtb, -1, "arm,gic-v3");
+       if (node < 0) {
+               WARN("FCONF: Unable to locate node with arm,gic-v3 compatible property\n");
+               return 0;
+       }
+       /* Read the reg cell holding base address of GIC controller modules
+       A sample reg cell array is shown here:
+               reg = <0x0 0x2f000000 0 0x10000>,       // GICD
+                     <0x0 0x2f100000 0 0x200000>,      // GICR
+                     <0x0 0x2c000000 0 0x2000>,        // GICC
+                     <0x0 0x2c010000 0 0x2000>,        // GICH
+                     <0x0 0x2c02f000 0 0x2000>;        // GICV
+       */
+
+       err = fdtw_read_array(hw_config_dtb, node, "reg", 20, &addr);
+       if (err < 0) {
+               ERROR("FCONF: Failed to read reg property of GIC node\n");
+       }
+       return err;
+}
+
+
+FCONF_REGISTER_POPULATOR(HW_CONFIG, gicv3_config, fconf_populate_gicv3_config);
index 8627c5ef0101fbf22607cd9f9e7b2c09b6451599..dc7bfa2dc14bb4411e305aa8a1cdb9c8076b57d7 100644 (file)
@@ -1,16 +1,21 @@
 /*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <assert.h>
+#include <common/debug.h>
 #include <drivers/arm/smmu_v3.h>
+#include <lib/fconf/fconf.h>
 #include <plat/arm/common/arm_config.h>
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
 #include "fvp_private.h"
 
+uintptr_t hw_config_dtb;
+
 void __init bl31_early_platform_setup2(u_register_t arg0,
                u_register_t arg1, u_register_t arg2, u_register_t arg3)
 {
@@ -40,4 +45,23 @@ void __init bl31_early_platform_setup2(u_register_t arg0,
        /* On FVP RevC, initialize SMMUv3 */
        if ((arm_config.flags & ARM_CONFIG_FVP_HAS_SMMUV3) != 0U)
                smmuv3_init(PLAT_FVP_SMMUV3_BASE);
+
+       hw_config_dtb = arg2;
+}
+
+void __init bl31_plat_arch_setup(void)
+{
+       arm_bl31_plat_arch_setup();
+
+       /*
+        * For RESET_TO_BL31 systems, BL31 is the first bootloader to run.
+        * So there is no BL2 to load the HW_CONFIG dtb into memory before
+        * control is passed to BL31.
+        */
+#if !RESET_TO_BL31 && !BL2_AT_EL3
+       assert(hw_config_dtb != 0U);
+
+       INFO("BL31 FCONF: HW_CONFIG address = %p\n", (void *)hw_config_dtb);
+       fconf_populate("HW_CONFIG", hw_config_dtb);
+#endif
 }
index 2c880fc3069efe2f943fe429a364168ad6381fe6..33f3067f302cf587667d40e8b32a7d64c93dae31 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -134,6 +134,8 @@ const mmap_region_t plat_arm_mmap[] = {
 #if SPM_MM
        ARM_SPM_BUF_EL3_MMAP,
 #endif
+       /* Required by fconf APIs to read HW_CONFIG dtb loaded into DRAM */
+       ARM_MAP_NS_DRAM1,
        {0}
 };
 
@@ -160,6 +162,8 @@ const mmap_region_t plat_arm_mmap[] = {
        V2M_MAP_IOFPGA,
        MAP_DEVICE0,
        MAP_DEVICE1,
+       /* Required by fconf APIs to read HW_CONFIG dtb loaded into DRAM */
+       ARM_MAP_NS_DRAM1,
        {0}
 };
 #endif
diff --git a/plat/arm/board/fvp/include/fconf_hw_config_getter.h b/plat/arm/board/fvp/include/fconf_hw_config_getter.h
new file mode 100644 (file)
index 0000000..cc1576e
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FCONF_HW_CONFIG_GETTER_H
+#define FCONF_HW_CONFIG_GETTER_H
+
+#include <lib/fconf/fconf.h>
+
+/* Hardware Config related getter */
+#define hw_config__gicv3_config_getter(prop) gicv3_config.prop
+
+struct gicv3_config_t {
+       void *gicd_base;
+       void *gicr_base;
+};
+
+int fconf_populate_gicv3_config(uintptr_t config);
+
+extern struct gicv3_config_t gicv3_config;
+
+#endif /* FCONF_HW_CONFIG_GETTER_H */
index bfe207a29bc45069fa61afa0412a9f2e40293c5b..69d49bab4df437936414788ffcd3da60320e5346 100644 (file)
  */
 #if defined(IMAGE_BL31)
 # if SPM_MM
-#  define PLAT_ARM_MMAP_ENTRIES                9
+#  define PLAT_ARM_MMAP_ENTRIES                10
 #  define MAX_XLAT_TABLES              9
 #  define PLAT_SP_IMAGE_MMAP_REGIONS   30
 #  define PLAT_SP_IMAGE_MAX_XLAT_TABLES        10
 # else
-#  define PLAT_ARM_MMAP_ENTRIES                8
+#  define PLAT_ARM_MMAP_ENTRIES                9
 #  if USE_DEBUGFS
 #   define MAX_XLAT_TABLES             6
 #  else
@@ -76,7 +76,7 @@
 #  endif
 # endif
 #elif defined(IMAGE_BL32)
-# define PLAT_ARM_MMAP_ENTRIES         8
+# define PLAT_ARM_MMAP_ENTRIES         9
 # define MAX_XLAT_TABLES               5
 #elif !USE_ROMLIB
 # define PLAT_ARM_MMAP_ENTRIES         11
index 05c11ce52219829ccda316ae71c357090e89e7bc..fc644302de5233bc38f4178e948e8bd1aabbfbf1 100644 (file)
@@ -202,6 +202,12 @@ BL31_SOURCES               +=      drivers/arm/fvp/fvp_pwrc.c                      \
                                ${FVP_INTERCONNECT_SOURCES}                     \
                                ${FVP_SECURITY_SOURCES}
 
+# Support for fconf in BL31
+# Added separately from the above list for better readability
+BL31_SOURCES           +=      common/fdt_wrappers.c                           \
+                               lib/fconf/fconf.c                               \
+                               plat/arm/board/fvp/fconf/fconf_hw_config_getter.c
+
 ifeq (${FVP_USE_SP804_TIMER},1)
 BL31_SOURCES           +=      drivers/arm/sp804/sp804_delay_timer.c
 else
index 88c91e6feb183a31ee61d57c6523f2b96caf09ff..763b42afbd2d9ea910769bd363f08b83bc315af1 100644 (file)
@@ -1,13 +1,20 @@
 /*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <assert.h>
+
+#include <bl32/sp_min/platform_sp_min.h>
+#include <common/debug.h>
+#include <lib/fconf/fconf.h>
 #include <plat/arm/common/plat_arm.h>
 
 #include "../fvp_private.h"
 
+uintptr_t hw_config_dtb;
+
 void plat_arm_sp_min_early_platform_setup(u_register_t arg0, u_register_t arg1,
                        u_register_t arg2, u_register_t arg3)
 {
@@ -30,4 +37,24 @@ void plat_arm_sp_min_early_platform_setup(u_register_t arg0, u_register_t arg1,
         * FVP PSCI code will enable coherency for other clusters.
         */
        fvp_interconnect_enable();
+
+       hw_config_dtb = arg2;
+}
+
+void sp_min_plat_arch_setup(void)
+{
+       arm_sp_min_plat_arch_setup();
+
+       /*
+        * For RESET_TO_SP_MIN systems, SP_MIN(BL32) is the first bootloader
+        * to run. So there is no BL2 to load the HW_CONFIG dtb into memory
+        * before control is passed to SP_MIN.
+        * Also, BL2 skips loading HW_CONFIG dtb for BL2_AT_EL3 builds.
+        */
+#if !RESET_TO_SP_MIN && !BL2_AT_EL3
+       assert(hw_config_dtb != 0U);
+
+       INFO("SP_MIN FCONF: HW_CONFIG address = %p\n", (void *)hw_config_dtb);
+       fconf_populate("HW_CONFIG", hw_config_dtb);
+#endif
 }
index 0250a5f1a2096e1f2cfe810e574aa88e9bc1e45d..520a70f992837fd9775c04f89c2be85f31290dec 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -18,4 +18,10 @@ BL32_SOURCES         +=      drivers/arm/fvp/fvp_pwrc.c                      \
                                ${FVP_INTERCONNECT_SOURCES}                     \
                                ${FVP_SECURITY_SOURCES}
 
+# Support for fconf in SP_MIN(BL32)
+# Added separately from the above list for better readability
+BL32_SOURCES           +=      common/fdt_wrappers.c                           \
+                               lib/fconf/fconf.c                               \
+                               plat/arm/board/fvp/fconf/fconf_hw_config_getter.c
+
 include plat/arm/common/sp_min/arm_sp_min.mk
index cbbdfa21b917b757aad533c4b757de994b7f9864..2904ad942a58af02deb29208957b303ca960d191 100644 (file)
@@ -217,7 +217,7 @@ void sp_min_plat_runtime_setup(void)
  * Perform the very early platform specific architectural setup here. At the
  * moment this only initializes the MMU
  ******************************************************************************/
-void sp_min_plat_arch_setup(void)
+void arm_sp_min_plat_arch_setup(void)
 {
        const mmap_region_t bl_regions[] = {
                MAP_BL_SP_MIN_TOTAL,
@@ -232,3 +232,8 @@ void sp_min_plat_arch_setup(void)
 
        enable_mmu_svc_mon(0);
 }
+
+void sp_min_plat_arch_setup(void)
+{
+       arm_sp_min_plat_arch_setup();
+}