ARM Platforms: Load HW_CONFIG in BL2

The patch adds the necessary changes to load HW_CONFIG in BL2 for
ARM Platforms :

1. The load address of HW_CONFIG is specified via the `hw_config_addr`
property in TB_FW_CONFIG is loaded by BL1. The `hw_config_max_size`
property defines the maximum size to be expected for the HW_CONFIG.
The `arm_dyn_cfg_helpers.c` and corresponding header implements
utility functions to parse these DT properties defined.
The `arm_dyn_cfg.c` implements wrappers to these helpers to enable
them to be invoked from ARM platform layer.

2. `HW_CONFIG` is added to the `bl2_mem_params_descs[]` array which is
the list of images to be loaded by BL2.

3. The `libfdt` sources are now included when BL2 is built

4. A new helper `populate_next_bl_params_config()` is introduced in
desc_image_load.c to populate the subsequent executable BL images
with the `hw_config` and the corresponding `fw_config` if available.
The `plat_get_next_bl_params()` API for ARM platforms is modified to
invoke this new helper.

5. The implementation of `bl2_early_platform_setup2()` is modified to
consider `arg0` as well in addition to `arg1` passed from BL1.

6. Bump up the BL2 size for Juno to accommodate the inclusion of libfdt.

Change-Id: I80f1554adec41753e0d179a5237364f04fe13a3f
Signed-off-by: Soby Mathew <soby.mathew@arm.com>
diff --git a/plat/arm/common/arm_dyn_cfg.c b/plat/arm/common/arm_dyn_cfg.c
index 4325764..a6fafb8 100644
--- a/plat/arm/common/arm_dyn_cfg.c
+++ b/plat/arm/common/arm_dyn_cfg.c
@@ -4,6 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <arm_dyn_cfg_helpers.h>
 #include <assert.h>
 #include <debug.h>
 #include <desc_image_load.h>
@@ -14,6 +15,9 @@
 
 #if LOAD_IMAGE_V2
 
+/* Variable to store the address to TB_FW_CONFIG passed from BL1 */
+static void *tb_fw_cfg_dtb;
+
 /*
  * Helper function to load TB_FW_CONFIG and populate the load information to
  * arg0 of BL2 entrypoint info.
@@ -51,4 +55,54 @@
 			(void *) config_base);
 }
 
+/*
+ * BL2 utility function to set the address of TB_FW_CONFIG passed from BL1.
+ */
+void arm_bl2_set_tb_cfg_addr(void *dtb)
+{
+	assert(dtb);
+	tb_fw_cfg_dtb = dtb;
+}
+
+/*
+ * BL2 utility function to initialize dynamic configuration specified by
+ * TB_FW_CONFIG. Return early if TB_FW_CONFIG is not found or HW_CONFIG is
+ * not specified in TB_FW_CONFIG.
+ */
+void arm_bl2_dyn_cfg_init(void)
+{
+	int err = 0;
+	int tb_fw_node;
+	bl_mem_params_node_t *hw_cfg_mem_params = NULL;
+
+	if (tb_fw_cfg_dtb == NULL) {
+		VERBOSE("No TB_FW_CONFIG specified\n");
+		return;
+	}
+
+	err = arm_dyn_tb_fw_cfg_init((void *)tb_fw_cfg_dtb, &tb_fw_node);
+	if (err < 0) {
+		ERROR("Invalid TB_FW_CONFIG passed from BL1\n");
+		panic();
+	}
+
+	/* Get the hw_config load address and size from TB_FW_CONFIG */
+	hw_cfg_mem_params = get_bl_mem_params_node(HW_CONFIG_ID);
+	if (hw_cfg_mem_params == NULL) {
+		VERBOSE("Couldn't find HW_CONFIG in bl_mem_params_node\n");
+		return;
+	}
+
+	err = arm_dyn_get_hwconfig_info((void *)tb_fw_cfg_dtb, tb_fw_node,
+		(uint64_t *) &hw_cfg_mem_params->image_info.image_base,
+		&hw_cfg_mem_params->image_info.image_max_size);
+	if (err < 0) {
+		VERBOSE("Couldn't find HW_CONFIG load info in TB_FW_CONFIG\n");
+		return;
+	}
+
+	/* Remove the IMAGE_ATTRIB_SKIP_LOADING attribute from HW_CONFIG node */
+	hw_cfg_mem_params->image_info.h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING;
+}
+
 #endif /* LOAD_IMAGE_V2 */