feat(arm): load tos_fw_cfg using xferlist in SPMC_AT_EL3

Load tos_fw_cfg when SPMC_AT_EL3 enabled and deliver its manifest
via transfer list and set its address in entrypoint's arg0 to load it
properly by spmc_setup().

Change-Id: I43490d0bbe8288701efcce93313838395d41f330
Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c
index 78ab862..668e34d 100644
--- a/plat/arm/common/arm_bl2_setup.c
+++ b/plat/arm/common/arm_bl2_setup.c
@@ -308,8 +308,11 @@
 #endif
 
 #if TRANSFER_LIST
-	if (image_id == HW_CONFIG_ID) {
-		/* Refresh the now stale checksum following loading of HW_CONFIG into the TL. */
+	if (image_id == HW_CONFIG_ID || image_id == TOS_FW_CONFIG_ID) {
+		/*
+		 * Refresh the now stale checksum following loading of
+		 * HW_CONFIG or TOS_FW_CONFIG into the TL.
+		 */
 		transfer_list_update_checksum(secure_tl);
 	}
 #endif /* TRANSFER_LIST */
diff --git a/plat/arm/common/arm_transfer_list.c b/plat/arm/common/arm_transfer_list.c
index 5a480b6..effa8cd 100644
--- a/plat/arm/common/arm_transfer_list.c
+++ b/plat/arm/common/arm_transfer_list.c
@@ -65,6 +65,20 @@
 	next_param_node->image_info.image_max_size = PLAT_ARM_HW_CONFIG_SIZE;
 	next_param_node->image_info.image_base =
 		(uintptr_t)transfer_list_entry_data(te);
+
+#if SPMC_AT_EL3 && defined(PLAT_ARM_SPMC_SP_MANIFEST_SIZE)
+	next_param_node = get_bl_mem_params_node(TOS_FW_CONFIG_ID);
+	assert(next_param_node != NULL);
+
+	te = transfer_list_add(tl, TL_TAG_DT_FFA_MANIFEST,
+			PLAT_ARM_SPMC_SP_MANIFEST_SIZE, NULL);
+	assert(te != NULL);
+
+	next_param_node->image_info.h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING;
+	next_param_node->image_info.image_max_size = PLAT_ARM_SPMC_SP_MANIFEST_SIZE;
+	next_param_node->image_info.image_base =
+		(uintptr_t)transfer_list_entry_data(te);
+#endif /* SPMC_AT_EL3 */
 }
 
 void arm_transfer_list_populate_ep_info(bl_mem_params_node_t *next_param_node,