feat(arm): support AArch32 booting with handoff
Configre SP-MIN to receive information via the firmare handoff
framework. In BL1 and BL2, select the 32-bit variants of the SRAM layout
and entry point info to enable booting in aarch32 mode. In SP-MIN
process expected data directly from the transfer list in secure memory.
Change-Id: If0417cdd4c47b772332eb6fd4b71ef0ea474f0fa
Signed-off-by: Harrison Mutai <harrison.mutai@arm.com>
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/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}
};