F-7051: return the hal_status_t unmodified from FRAM_Erase

FRAM_Erase() already negated its failure status (return -(int)status),
and its only caller ext_flash_erase() applied the same conversion a
second time (return -(int)status). The two negations cancelled, so a
failed FRAM erase made ext_flash_erase() return +1/+2 - a
success-looking value to callers that test ret < 0, e.g. diag_erase()
in src/libwolfboot.c which maps ret < 0 to failure.

FRAM_Erase() now returns the hal_status_t unmodified (and
hal_status_ok on success); ext_flash_erase() is the single negation
point, matching the already-correct ext_flash_write()/ext_flash_read()
pair (FRAM_Write/FRAM_Read return un-negated statuses).

Added to unit-va416x0-fram: a successful 64 byte erase (two 32 byte
FRAM chunks, six SPI transfers) returning 0 with the shadow IRAM
filled 0xFF, and a failed erase returning a negative code with the
shadow IRAM untouched. Pre-fix the failure case returned +2.

Verified: unit-va416x0-fram 5/5 green post-fix (failure case returned
+2 pre-fix), tools/unit-tests suite green (112 binaries).
pull/862/head
Daniele Lacamera 2026-08-18 03:32:21 +02:00
parent cc8564ae75
commit 9b1d962fa4
2 changed files with 54 additions and 2 deletions

View File

@ -333,12 +333,14 @@ hal_status_t FRAM_Erase(uint8_t spiBank, uint32_t addr, uint32_t len)
uint32_t erase_len = (len > sizeof(data)) ? sizeof(data) : len;
status = FRAM_Write(ROM_SPI_BANK, addr, data, erase_len);
if (status != hal_status_ok) {
return -(int)status; /* convert to negative error code */
/* Return the hal_status_t unmodified; ext_flash_erase() is
* the single negation point to a negative error code. */
return status;
}
addr += erase_len;
len -= erase_len;
}
return 0;
return hal_status_ok;
}
#ifndef WOLFBOOT_UNIT_TEST_VA416X0_FRAM

View File

@ -227,6 +227,54 @@ START_TEST(test_iram_fill_unaligned_64bit_addr)
}
END_TEST
/* A successful erase returns 0 and fills the shadow IRAM with 0xFF.
* The 64 byte erase spans two 32 byte FRAM chunks (six SPI transfers).
*/
START_TEST(test_ext_flash_erase_success_fills_iram)
{
hal_status_t ok_script[] = {
hal_status_ok, hal_status_ok, hal_status_ok,
hal_status_ok, hal_status_ok, hal_status_ok
};
int i;
reset_spi_mocks();
memset(g_iram, 0xA5, sizeof(g_iram));
set_transmit_script(ok_script, 6);
ck_assert_int_eq(ext_flash_erase((uintptr_t)g_iram, 64), 0);
ck_assert_int_eq(transmit_call_count, 6);
for (i = 0; i < 64; i++)
ck_assert_uint_eq(g_iram[i], 0xFF);
}
END_TEST
/* A failed FRAM erase must make ext_flash_erase() return a negative
* error code. Pre-fix, FRAM_Erase() negated the hal_status_t and
* ext_flash_erase() negated it a second time, so a failure returned
* +1/+2 - a success-looking value to callers testing ret < 0 (e.g.
* diag_erase in src/libwolfboot.c). */
START_TEST(test_ext_flash_erase_failure_returns_negative)
{
hal_status_t fail_script[] = {
hal_status_ok, hal_status_ok, hal_status_err
};
int i;
int ret;
reset_spi_mocks();
memset(g_iram, 0xA5, sizeof(g_iram));
set_transmit_script(fail_script, 3);
ret = ext_flash_erase((uintptr_t)g_iram, 32);
ck_assert_int_lt(ret, 0);
/* The shadow IRAM must be left untouched on failure. */
for (i = 0; i < 32; i++)
ck_assert_uint_eq(g_iram[i], 0xA5);
}
END_TEST
Suite *va416x0_fram_suite(void)
{
Suite *s = suite_create("va416x0-fram");
@ -235,6 +283,8 @@ Suite *va416x0_fram_suite(void)
tcase_add_test(tc, test_fram_write_command_failure_aborts_split_transaction);
tcase_add_test(tc, test_iram_write_unaligned_64bit_addr);
tcase_add_test(tc, test_iram_fill_unaligned_64bit_addr);
tcase_add_test(tc, test_ext_flash_erase_success_fills_iram);
tcase_add_test(tc, test_ext_flash_erase_failure_returns_negative);
suite_add_tcase(s, tc);
return s;