From 89611203f0b8e513c0787be78057f6cac7e4a8ab Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 1 Nov 2025 18:23:09 +0100 Subject: [PATCH] efi: Use EVT_RESERVE_BOARD to reserve memory for efi_priv Use the EVT_RESERVE_BOARD event handler to allocate the efi_priv struct in the normal memory area. This avoids the caller needing to keep it on the stack. Copy the struct to the new place and start using it there. Co-developed-by: Claude Signed-off-by: Simon Glass --- include/efi.h | 10 ++++++++++ lib/efi_client/efi.c | 6 ++++++ lib/efi_client/efi_app.c | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/include/efi.h b/include/efi.h index d2513d14e8d..f5e8d632d47 100644 --- a/include/efi.h +++ b/include/efi.h @@ -621,6 +621,16 @@ struct efi_priv *efi_get_priv(void); */ void efi_set_priv(struct efi_priv *priv); +/** + * efi_move_priv() - Move EFI-private information to a new location + * + * Copies the existing EFI-private data to a new location and updates the + * global pointer. If there is no existing data, just sets the pointer. + * + * @new_priv: New location for private data + */ +void efi_move_priv(struct efi_priv *new_priv); + /** * efi_get_sys_table() - Get access to the main EFI system table * diff --git a/lib/efi_client/efi.c b/lib/efi_client/efi.c index 083ad1f423c..c4b1a24d6be 100644 --- a/lib/efi_client/efi.c +++ b/lib/efi_client/efi.c @@ -57,6 +57,12 @@ void efi_set_priv(struct efi_priv *priv) global_priv = priv; } +void efi_move_priv(struct efi_priv *new_priv) +{ + *new_priv = *global_priv; + global_priv = new_priv; +} + struct efi_system_table *efi_get_sys_table(void) { return global_priv->sys_table; diff --git a/lib/efi_client/efi_app.c b/lib/efi_client/efi_app.c index 878994a5763..0a817839f26 100644 --- a/lib/efi_client/efi_app.c +++ b/lib/efi_client/efi_app.c @@ -33,6 +33,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -389,6 +390,39 @@ U_BOOT_DRIVER(efi_sysreset) = { .ops = &efi_sysreset_ops, }; +/** + * efi_reserve_priv() - Event handler to reserve memory for struct efi_priv + * + * This handler is called during EVT_RESERVE_BOARD event to reserve memory + * for the efi_priv structure before other reservations. + * + * @ctx: Event context (unused) + * @event: Event information containing reserve_board data + * Return: 0 on success + */ +static int efi_reserve_priv(void *ctx, struct event *event) +{ + struct event_reserve_board *reserve = &event->data.reserve_board; + struct efi_priv *priv; + ulong addr; + + /* Reserve memory for efi_priv using the provided stack pointer */ + addr = ALIGN_DOWN(reserve->start_addr_sp - sizeof(struct efi_priv), 16); + priv = map_sysmem(addr, sizeof(struct efi_priv)); + + /* Update stack pointer for next reservation */ + reserve->start_addr_sp = addr; + + /* Move existing priv data (from stack) to reserved location */ + efi_move_priv(priv); + + log_debug("Reserving %zu bytes for EFI priv at: %08lx\n", + sizeof(struct efi_priv), addr); + + return 0; +} +EVENT_SPY_FULL(EVT_RESERVE_BOARD, efi_reserve_priv); + efi_status_t efi_startup(efi_handle_t image, struct efi_system_table *systab) { struct efi_priv local_priv, *priv = &local_priv;