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_helpers.c b/plat/arm/common/arm_dyn_cfg_helpers.c
new file mode 100644
index 0000000..afe4453
--- /dev/null
+++ b/plat/arm/common/arm_dyn_cfg_helpers.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <desc_image_load.h>
+#include <fdt_wrappers.h>
+#include <libfdt.h>
+
+/*******************************************************************************
+ * Helper to read the `hw_config` property in config DTB. This function
+ * expects the following properties to be present in the config DTB.
+ * name : hw_config_addr size : 2 cells
+ * name : hw_config_max_size size : 1 cell
+ *
+ * Arguments:
+ * void *dtb - pointer to the TB_FW_CONFIG in memory
+ * int node - The node offset to appropriate node in the
+ * DTB.
+ * uint64_t *hw_config_addr - Returns the `hw_config` load address if read
+ * is successful.
+ * uint32_t *hw_config_size - Returns the `hw_config` size if read is
+ * successful.
+ *
+ * Returns 0 on success and -1 on error.
+ ******************************************************************************/
+int arm_dyn_get_hwconfig_info(void *dtb, int node,
+ uint64_t *hw_config_addr, uint32_t *hw_config_size)
+{
+ int err;
+
+ assert(dtb);
+ assert(hw_config_addr);
+ assert(hw_config_size);
+
+ /* Check if the pointer to DT is correct */
+ assert(fdt_check_header(dtb) == 0);
+
+ /* Assert the node offset point to "arm,tb_fw" compatible property */
+ assert(node == fdt_node_offset_by_compatible(dtb, -1, "arm,tb_fw"));
+
+ err = fdtw_read_cells(dtb, node, "hw_config_addr", 2,
+ (void *) hw_config_addr);
+ if (err < 0) {
+ WARN("Read cell failed for hw_config_addr\n");
+ return -1;
+ }
+
+ err = fdtw_read_cells(dtb, node, "hw_config_max_size", 1,
+ (void *) hw_config_size);
+ if (err < 0) {
+ WARN("Read cell failed for hw_config_max_size\n");
+ return -1;
+ }
+
+ VERBOSE("Dyn cfg: Read hw_config address from TB_FW_CONFIG 0x%p %p\n",
+ hw_config_addr, hw_config_size);
+
+ return 0;
+}
+
+/*******************************************************************************
+ * Validate the tb_fw_config is a valid DTB file and returns the node offset
+ * to "arm,tb_fw" property.
+ * Arguments:
+ * void *dtb - pointer to the TB_FW_CONFIG in memory
+ * int *node - Returns the node offset to "arm,tb_fw" property if found.
+ *
+ * Returns 0 on success and -1 on error.
+ ******************************************************************************/
+int arm_dyn_tb_fw_cfg_init(void *dtb, int *node)
+{
+ assert(dtb);
+ assert(node);
+
+ /* Check if the pointer to DT is correct */
+ if (fdt_check_header(dtb) != 0) {
+ WARN("Invalid DTB file passed as TB_FW_CONFIG\n");
+ return -1;
+ }
+
+ /* Assert the node offset point to "arm,tb_fw" compatible property */
+ *node = fdt_node_offset_by_compatible(dtb, -1, "arm,tb_fw");
+ if (*node < 0) {
+ WARN("The compatible property `arm,tb_fw` not found in the config\n");
+ return -1;
+ }
+
+ VERBOSE("Dyn cfg: Found \"arm,tb_fw\" in the config\n");
+ return 0;
+}