Merge changes from topic "hm/handoff-aarch32" into integration

* changes:
  feat(fvp): support AArch32 booting with handoff
  feat(arm): support AArch32 booting with handoff
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index 396bd14..ae2e96f 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -147,6 +147,14 @@
 
 #endif /* defined(IMAGE_BL31) || (!defined(__aarch64__) && defined(IMAGE_BL32)) */
 
+#ifdef __aarch64__
+#define TL_TAG_EXEC_EP_INFO	TL_TAG_EXEC_EP_INFO64
+#define TL_TAG_SRAM_LAYOUT	TL_TAG_SRAM_LAYOUT64
+#else
+#define TL_TAG_EXEC_EP_INFO	TL_TAG_EXEC_EP_INFO32
+#define TL_TAG_SRAM_LAYOUT	TL_TAG_SRAM_LAYOUT32
+#endif
+
 #if ARM_RECOM_STATE_ID_ENC
 /*
  * Macros used to parse state information from State-ID if it is using the
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index f5be8f2..854e48a 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -307,9 +307,15 @@
  * calculated using the current SP_MIN PROGBITS debug size plus the sizes of
  * BL2 and BL1-RW
  */
+#if TRANSFER_LIST
+# define PLAT_ARM_MAX_BL32_SIZE		(PLAT_ARM_TRUSTED_SRAM_SIZE - \
+					 ARM_SHARED_RAM_SIZE - \
+					 PLAT_ARM_FW_HANDOFF_SIZE)
+#else
 # define PLAT_ARM_MAX_BL32_SIZE		(PLAT_ARM_TRUSTED_SRAM_SIZE - \
 					 ARM_SHARED_RAM_SIZE - \
 					 ARM_FW_CONFIGS_SIZE)
+#endif /* TRANSFER_LIST */
 #endif /* RESET_TO_SP_MIN */
 #endif
 
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 76ca5b5..8c193fa 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
@@ -14,16 +14,34 @@
 
 #include "../fvp_private.h"
 
+static uintptr_t hw_config __unused;
+
 void plat_arm_sp_min_early_platform_setup(u_register_t arg0, u_register_t arg1,
 			u_register_t arg2, u_register_t arg3)
 {
 	const struct dyn_cfg_dtb_info_t *tos_fw_config_info __unused;
+	struct transfer_list_header *tl __unused;
 
 	/* Initialize the console to provide early debug support */
 	arm_console_boot_init();
 
-#if !RESET_TO_SP_MIN && !RESET_TO_BL2
+#if TRANSFER_LIST
+	/*
+	 * Register usage at function entry:
+	 *   r0 - Reserved (must be zero)
+	 *   r1 - Register convention and TL signature
+	 *   r2 - Pointer to the FDT located within the TL
+	 *   r3 - Base address of the TL
+	 *
+	 * Initialize TL pointer from r3 and validate that the FDT pointer (arg2)
+	 * lies within the bounds of the Transfer List memory region.
+	 */
+	tl = (struct transfer_list_header *)arg3;
 
+	assert(arg2 > (uintptr_t)tl && arg2 < (uintptr_t)tl + tl->size);
+	hw_config = (uintptr_t)arg2;
+#else
+#if !RESET_TO_SP_MIN && !RESET_TO_BL2
 	INFO("SP_MIN FCONF: FW_CONFIG address = %lx\n", (uintptr_t)arg1);
 	/* Fill the properties struct with the info from the config dtb */
 	fconf_populate("FW_CONFIG", arg1);
@@ -33,6 +51,7 @@
 		arg1 = tos_fw_config_info->config_addr;
 	}
 #endif /* !RESET_TO_SP_MIN && !RESET_TO_BL2 */
+#endif /* TRANSFER_LIST */
 
 	arm_sp_min_early_platform_setup(arg0, arg1, arg2, arg3);
 
@@ -75,7 +94,10 @@
 	 * TODO: remove the ARM_XLAT_TABLES_LIB_V1 check when its support
 	 * gets deprecated.
 	 */
-#if !RESET_TO_SP_MIN && !RESET_TO_BL2 && !ARM_XLAT_TABLES_LIB_V1
+#if TRANSFER_LIST
+	INFO("SP_MIN FCONF: HW_CONFIG address = %p\n", (void *)hw_config);
+	fconf_populate("HW_CONFIG", hw_config);
+#elif !RESET_TO_SP_MIN && !RESET_TO_BL2 && !ARM_XLAT_TABLES_LIB_V1
 	hw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, HW_CONFIG_ID);
 	assert(hw_config_info != NULL);
 	assert(hw_config_info->config_addr != 0UL);
@@ -118,5 +140,6 @@
 		      rc);
 		panic();
 	}
-#endif /*!RESET_TO_SP_MIN && !RESET_TO_BL2 && !ARM_XLAT_TABLES_LIB_V1*/
+
+#endif /* TRANSFER_LIST */
 }
diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c
index 75d6a53..06a919c 100644
--- a/plat/arm/common/arm_bl1_setup.c
+++ b/plat/arm/common/arm_bl1_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -289,18 +289,17 @@
 	return  is_fwu_needed ? NS_BL1U_IMAGE_ID : BL2_IMAGE_ID;
 }
 
-// Use the default implementation of this function when Firmware Handoff is
-// disabled to avoid duplicating its logic.
 #if TRANSFER_LIST
 int bl1_plat_handle_post_image_load(unsigned int image_id)
 {
-	image_desc_t *image_desc __unused;
-
-	assert(image_id == BL2_IMAGE_ID);
 	struct transfer_list_entry *te;
 
+	if (image_id != BL2_IMAGE_ID) {
+		return 0;
+	}
+
 	/* Convey this information to BL2 via its TL. */
-	te = transfer_list_add(secure_tl, TL_TAG_SRAM_LAYOUT64,
+	te = transfer_list_add(secure_tl, TL_TAG_SRAM_LAYOUT,
 			       sizeof(meminfo_t), NULL);
 	assert(te != NULL);
 
diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c
index 6418628..bd3946c 100644
--- a/plat/arm/common/arm_bl2_setup.c
+++ b/plat/arm/common/arm_bl2_setup.c
@@ -78,7 +78,7 @@
 #if TRANSFER_LIST
 	secure_tl = (struct transfer_list_header *)arg3;
 
-	te = transfer_list_find(secure_tl, TL_TAG_SRAM_LAYOUT64);
+	te = transfer_list_find(secure_tl, TL_TAG_SRAM_LAYOUT);
 	assert(te != NULL);
 
 	bl2_tzram_layout = *(meminfo_t *)transfer_list_entry_data(te);
diff --git a/plat/arm/common/arm_transfer_list.c b/plat/arm/common/arm_transfer_list.c
index 6847591..5a480b6 100644
--- a/plat/arm/common/arm_transfer_list.c
+++ b/plat/arm/common/arm_transfer_list.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2024-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -71,9 +71,8 @@
 					struct transfer_list_header *tl)
 {
 	uint32_t next_exe_img_id;
-	entry_point_info_t *ep;
+	entry_point_info_t *ep __unused;
 	struct transfer_list_entry *te;
-
 	assert(next_param_node != NULL);
 
 	while ((next_exe_img_id = next_param_node->next_handoff_image_id) !=
@@ -83,14 +82,16 @@
 				next_exe_img_id)];
 		assert(next_param_node != NULL);
 
-		te = transfer_list_add(tl, TL_TAG_EXEC_EP_INFO64,
+		te = transfer_list_add(tl, TL_TAG_EXEC_EP_INFO,
 				       sizeof(entry_point_info_t),
 				       &next_param_node->ep_info);
 		assert(te != NULL);
 
 		ep = transfer_list_entry_data(te);
+		assert(ep != NULL);
 
-		if ((next_exe_img_id == BL32_IMAGE_ID) && SPMC_AT_EL3) {
+#if SPMC_AT_EL3
+		if (next_exe_img_id == BL32_IMAGE_ID) {
 			/*
 			 * Populate the BL32 image base, size and max limit in
 			 * the entry point information, since there is no
@@ -106,6 +107,7 @@
 				next_param_node->image_info.image_base +
 				next_param_node->image_info.image_max_size;
 		}
+#endif /* SPMC_AT_EL3 */
 
 		next_exe_img_id = next_param_node->next_handoff_image_id;
 	}
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 78fc88e..cc4ae59 100644
--- a/plat/arm/common/sp_min/arm_sp_min_setup.c
+++ b/plat/arm/common/sp_min/arm_sp_min_setup.c
@@ -16,6 +16,9 @@
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
+struct transfer_list_header *secure_tl;
+struct transfer_list_header *ns_tl __unused;
+
 static entry_point_info_t bl33_image_ep_info;
 
 /* Weak definitions may be overridden in specific ARM standard platform */
@@ -28,13 +31,25 @@
 					BL32_END - BL32_BASE,		\
 					MT_MEMORY | MT_RW | MT_SECURE)
 
+#define MAP_EL3_FW_HANDOFF                            \
+	MAP_REGION_FLAT(PLAT_ARM_EL3_FW_HANDOFF_BASE, \
+			PLAT_ARM_FW_HANDOFF_SIZE, MT_MEMORY | MT_RW | EL3_PAS)
+
+#define MAP_FW_NS_HANDOFF                                             \
+	MAP_REGION_FLAT(FW_NS_HANDOFF_BASE, PLAT_ARM_FW_HANDOFF_SIZE, \
+			MT_MEMORY | MT_RW | MT_NS)
+
 /*
  * Check that BL32_BASE is above ARM_FW_CONFIG_LIMIT. The reserved page
  * is required for SOC_FW_CONFIG/TOS_FW_CONFIG passed from BL2.
  */
 #if !RESET_TO_SP_MIN
+#if TRANSFER_LIST
+CASSERT(BL32_BASE >= PLAT_ARM_EL3_FW_HANDOFF_LIMIT, assert_bl32_base_overflows);
+#else
 CASSERT(BL32_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl32_base_overflows);
 #endif
+#endif
 
 /*******************************************************************************
  * Return a pointer to the 'entry_point_info' structure of the next image for the
@@ -64,9 +79,22 @@
 void arm_sp_min_early_platform_setup(u_register_t arg0, u_register_t arg1,
 			u_register_t arg2, u_register_t arg3)
 {
+	struct transfer_list_entry *te __unused;
+
 	/* Initialize the console to provide early debug support */
 	arm_console_boot_init();
 
+#if TRANSFER_LIST
+	secure_tl = (struct transfer_list_header *)arg3;
+
+	te = transfer_list_find(secure_tl, TL_TAG_EXEC_EP_INFO32);
+	assert(te != NULL);
+
+	bl33_image_ep_info =
+		*(struct entry_point_info *)transfer_list_entry_data(te);
+	return;
+#endif /* TRANSFER_LIST */
+
 #if RESET_TO_SP_MIN
 	/* Populate entry point information for BL33 */
 	SET_PARAM_HEAD(&bl33_image_ep_info,
@@ -81,7 +109,7 @@
 	bl33_image_ep_info.spsr = arm_get_spsr_for_bl33_entry();
 	SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
 
-# if ARM_LINUX_KERNEL_AS_BL33
+#if ARM_LINUX_KERNEL_AS_BL33
 	/*
 	 * According to the file ``Documentation/arm/Booting`` of the Linux
 	 * kernel tree, Linux expects:
@@ -176,10 +204,33 @@
  ******************************************************************************/
 void sp_min_platform_setup(void)
 {
+	struct transfer_list_entry *te __unused;
+
 	/* Initialize the GIC driver, cpu and distributor interfaces */
 	plat_arm_gic_driver_init();
 	plat_arm_gic_init();
 
+#if TRANSFER_LIST
+	ns_tl = transfer_list_ensure((void *)FW_NS_HANDOFF_BASE,
+				       PLAT_ARM_FW_HANDOFF_SIZE);
+	if (ns_tl == NULL) {
+		ERROR("Non-secure transfer list initialisation failed!\n");
+		panic();
+	}
+
+	te = transfer_list_find(secure_tl, TL_TAG_FDT);
+	if (te != NULL) {
+		te = transfer_list_add(ns_tl, TL_TAG_FDT, te->data_size,
+				  (void *)transfer_list_entry_data(te));
+		if (te == NULL) {
+			ERROR("Failed to relocate device tree into non-secure memory.\n");
+			panic();
+		}
+	}
+
+	transfer_list_set_handoff_args(ns_tl, &bl33_image_ep_info);
+#endif
+
 	/*
 	 * Do initial security configuration to allow DRAM/device access
 	 * (if earlier BL has not already done so).
@@ -223,6 +274,10 @@
 #if USE_COHERENT_MEM
 		ARM_MAP_BL_COHERENT_RAM,
 #endif
+#if TRANSFER_LIST
+		MAP_EL3_FW_HANDOFF,
+		MAP_FW_NS_HANDOFF,
+#endif
 		{0}
 	};