Support shared Mbed TLS heap for FVP

This patch introduces the shared Mbed TLS heap optimisation for Arm
platforms. The objective is the Mbed TLS heap to be shared between BL1
and BL2 so as to not allocate the heap memory twice. To achieve that,
the patch introduces all the necessary helpers for implementing this
optimisation. It also applies it for FVP.

Change-Id: I6d85eaa1361517b7490956b2ac50f5fa0d0bb008
Signed-off-by: John Tsichritzis <john.tsichritzis@arm.com>
diff --git a/plat/arm/common/arm_dyn_cfg_helpers.c b/plat/arm/common/arm_dyn_cfg_helpers.c
index 5a7e20a..e610903 100644
--- a/plat/arm/common/arm_dyn_cfg_helpers.c
+++ b/plat/arm/common/arm_dyn_cfg_helpers.c
@@ -11,6 +11,8 @@
 #include <libfdt.h>
 #include <plat_arm.h>
 
+#define DTB_PROP_MBEDTLS_HEAP_ADDR "mbedtls_heap_addr"
+#define DTB_PROP_MBEDTLS_HEAP_SIZE "mbedtls_heap_size"
 
 typedef struct config_load_info_prop {
 	unsigned int config_id;
@@ -164,3 +166,102 @@
 	VERBOSE("Dyn cfg: Found \"arm,tb_fw\" in the config\n");
 	return 0;
 }
+
+
+#if TRUSTED_BOARD_BOOT && LOAD_IMAGE_V2
+/*
+ * Reads and returns the Mbed TLS shared heap information from the DTB.
+ * This function is supposed to be called *only* when a DTB is present.
+ * This function is supposed to be called only by BL2.
+ *
+ * Returns:
+ *	0 = success
+ *	-1 = error. In this case the values of heap_addr, heap_size should be
+ *	    considered as garbage by the caller.
+ */
+int arm_get_dtb_mbedtls_heap_info(void *dtb, void **heap_addr,
+	size_t *heap_size)
+{
+	int err, dtb_root;
+
+	/* Verify the DTB is valid and get the root node */
+	err = arm_dyn_tb_fw_cfg_init(dtb, &dtb_root);
+	if (err < 0) {
+		ERROR("%s: Invalid TB_FW_CONFIG. Cannot retrieve Mbed TLS "
+			"heap information from DTB\n", __func__);
+		return -1;
+	}
+
+	/* Retrieve the Mbed TLS heap details from the DTB */
+	err = fdtw_read_cells(dtb, dtb_root,
+		DTB_PROP_MBEDTLS_HEAP_ADDR, 2, heap_addr);
+	if (err < 0) {
+		ERROR("%s: error while reading %s from DTB\n", __func__,
+			DTB_PROP_MBEDTLS_HEAP_ADDR);
+		return -1;
+	}
+	err = fdtw_read_cells(dtb, dtb_root,
+		DTB_PROP_MBEDTLS_HEAP_SIZE, 1, heap_size);
+	if (err < 0) {
+		ERROR("%s: error while reading %s from DTB\n", __func__,
+			DTB_PROP_MBEDTLS_HEAP_SIZE);
+		return -1;
+	}
+	return 0;
+}
+
+
+/*
+ * This function writes the Mbed TLS heap address and size in the DTB. When it
+ * is called, it is guaranteed that a DTB is available. However it is not
+ * guaranteed that the shared Mbed TLS heap implementation is used. Thus we
+ * return error code from here and it's the responsibility of the caller to
+ * determine the action upon error.
+ *
+ * This function is supposed to be called only by BL1.
+ *
+ * Returns:
+ *	0 = success
+ *	1 = error
+ */
+int arm_set_dtb_mbedtls_heap_info(void *dtb, void *heap_addr, size_t heap_size)
+{
+	int err, dtb_root;
+
+	/*
+	 * Verify that the DTB is valid, before attempting to write to it,
+	 * and get the DTB root node.
+	 */
+	err = arm_dyn_tb_fw_cfg_init(dtb, &dtb_root);
+	if (err < 0) {
+		ERROR("%s: Invalid TB_FW_CONFIG loaded. Unable to get "
+			"root node\n", __func__);
+		return -1;
+	}
+
+	/*
+	 * Write the heap address and size in the DTB.
+	 *
+	 * NOTE: The variables heap_addr and heap_size are corrupted
+	 * by the "fdtw_write_inplace_cells" function. After the
+	 * function calls they must NOT be reused.
+	 */
+	err = fdtw_write_inplace_cells(dtb, dtb_root,
+		DTB_PROP_MBEDTLS_HEAP_ADDR, 2, &heap_addr);
+	if (err < 0) {
+		ERROR("%s: unable to write DTB property %s\n",
+			__func__, DTB_PROP_MBEDTLS_HEAP_ADDR);
+		return -1;
+	}
+
+	err = fdtw_write_inplace_cells(dtb, dtb_root,
+		DTB_PROP_MBEDTLS_HEAP_SIZE, 1, &heap_size);
+	if (err < 0) {
+		ERROR("%s: unable to write DTB property %s\n",
+			__func__, DTB_PROP_MBEDTLS_HEAP_SIZE);
+		return -1;
+	}
+
+	return 0;
+}
+#endif /* TRUSTED_BOARD_BOOT && LOAD_IMAGE_V2 */