fconf: necessary modifications to support fconf in BL31 & SP_MIN

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>
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
index 0000000..1a1d056
--- /dev/null
+++ b/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c
@@ -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);
diff --git a/plat/arm/board/fvp/fvp_bl31_setup.c b/plat/arm/board/fvp/fvp_bl31_setup.c
index 8627c5e..dc7bfa2 100644
--- a/plat/arm/board/fvp/fvp_bl31_setup.c
+++ b/plat/arm/board/fvp/fvp_bl31_setup.c
@@ -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 @@
 	/* 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
 }
diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c
index 2c880fc..33f3067 100644
--- a/plat/arm/board/fvp/fvp_common.c
+++ b/plat/arm/board/fvp/fvp_common.c
@@ -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 @@
 #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 @@
 	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
index 0000000..cc1576e
--- /dev/null
+++ b/plat/arm/board/fvp/include/fconf_hw_config_getter.h
@@ -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 */
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index bfe207a..69d49ba 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -63,12 +63,12 @@
  */
 #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
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 05c11ce..fc64430 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -202,6 +202,12 @@
 				${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
diff --git a/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c b/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c
index 88c91e6..763b42a 100644
--- a/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c
+++ b/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c
@@ -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 @@
 	 * 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
 }
diff --git a/plat/arm/board/fvp/sp_min/sp_min-fvp.mk b/plat/arm/board/fvp/sp_min/sp_min-fvp.mk
index 0250a5f..520a70f 100644
--- a/plat/arm/board/fvp/sp_min/sp_min-fvp.mk
+++ b/plat/arm/board/fvp/sp_min/sp_min-fvp.mk
@@ -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 @@
 				${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
diff --git a/plat/arm/common/sp_min/arm_sp_min_setup.c b/plat/arm/common/sp_min/arm_sp_min_setup.c
index cbbdfa2..2904ad9 100644
--- a/plat/arm/common/sp_min/arm_sp_min_setup.c
+++ b/plat/arm/common/sp_min/arm_sp_min_setup.c
@@ -217,7 +217,7 @@
  * 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 @@
 
 	enable_mmu_svc_mon(0);
 }
+
+void sp_min_plat_arch_setup(void)
+{
+	arm_sp_min_plat_arch_setup();
+}