From 0c5e5b3b1b74959c9dc71f8a32da1c23e081efab Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Tue, 18 Aug 2026 09:19:13 +0200 Subject: [PATCH] efi/p1021: honor the documented failure contract, align FCM access open_kernel_image() left *sz set on the read-failure path though it documents both outputs as 0 on failure. The p1021 FCM helpers used 32-bit accesses from flash_idx, which starts at the page column, so an odd column made every access misaligned -- an alignment interrupt on the guarded eLBC window on e500. --- hal/nxp_p1021.c | 15 +++++++++++---- hal/x86_64_efi.c | 1 + 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/hal/nxp_p1021.c b/hal/nxp_p1021.c index aa5e0f25..90d5f95b 100644 --- a/hal/nxp_p1021.c +++ b/hal/nxp_p1021.c @@ -692,7 +692,11 @@ static int hal_flash_command(uint8_t iswrite) return ret; } -/* assume input/output buffers are 32-bit aligned */ +/* Uses 32-bit accesses only when both the FCM window offset and the + * caller's buffer are 4-byte aligned: flash_idx starts at the page + * column and the chunk lengths need not be multiples of 4, so either + * side can be odd. A misaligned 32-bit access to the cache-inhibited, + * guarded eLBC window raises an alignment interrupt on e500. */ static void hal_flash_read_bytes(uint8_t* data, size_t len) { uint32_t end = flash_idx + (uint32_t)len; @@ -705,7 +709,8 @@ static void hal_flash_read_bytes(uint8_t* data, size_t len) * page column (see hal_flash_set_addr), so len is a relative count and * the end must be flash_idx + len, not len. */ while (flash_idx < end) { - if (end - flash_idx >= 4) { + if (end - flash_idx >= 4 && + ((flash_idx | (uintptr_t)data) & 3) == 0) { *((volatile uint32_t*)data) = *(volatile uint32_t*)(&flash_buf[flash_idx]); flash_idx += 4; @@ -718,7 +723,8 @@ static void hal_flash_read_bytes(uint8_t* data, size_t len) } } } -/* assume input/output buffers are 32-bit aligned */ +/* 32-bit accesses only when both sides are aligned; see + * hal_flash_read_bytes() above. */ static void hal_flash_write_bytes(const uint8_t* data, size_t len) { uint32_t end = flash_idx + (uint32_t)len; @@ -731,7 +737,8 @@ static void hal_flash_write_bytes(const uint8_t* data, size_t len) * page column (see hal_flash_set_addr), so len is a relative count and * the end must be flash_idx + len, not len. */ while (flash_idx < end) { - if (end - flash_idx >= 4) { + if (end - flash_idx >= 4 && + ((flash_idx | (uintptr_t)data) & 3) == 0) { *(volatile uint32_t*)(&flash_buf[flash_idx]) = *((volatile uint32_t*)data); flash_idx += 4; diff --git a/hal/x86_64_efi.c b/hal/x86_64_efi.c index c94c7329..59d3afcd 100644 --- a/hal/x86_64_efi.c +++ b/hal/x86_64_efi.c @@ -288,6 +288,7 @@ static int open_kernel_image(EFI_FILE_HANDLE vol, CHAR16 *filename, wolfBoot_printf("can't read kernel image %d\n", status); uefi_call_wrapper(BS->FreePages, 2, *_addr, pages); *_addr = 0; + *sz = 0; /* both outputs are 0 on failure, as documented */ return -1; }