Remove NO_DIRECT_READ_OF_ERASED_SECTOR option; write after erase instead

pull/714/head
Mattia Moffa 2026-03-16 17:25:31 +01:00 committed by Daniele Lacamera
parent 3ef8c60242
commit fcf72e008c
8 changed files with 91 additions and 170 deletions

View File

@ -28,7 +28,6 @@ RAM_CODE?=1
DUALBANK_SWAP?=0
PKA?=1
FLASH_MULTI_SECTOR_ERASE?=1
NO_DIRECT_READ_OF_ERASED_SECTOR?=1
WOLFCRYPT_TZ?=1
WOLFCRYPT_TZ_PKCS11?=1

View File

@ -28,7 +28,6 @@ RAM_CODE?=1
DUALBANK_SWAP?=0
PKA?=1
FLASH_MULTI_SECTOR_ERASE?=1
NO_DIRECT_READ_OF_ERASED_SECTOR?=1
# 512-byte pages erasable/writeable
WOLFBOOT_SECTOR_SIZE?=0x200

View File

@ -76,6 +76,23 @@ static void periph_unsecure(void)
}
#endif
static void hal_flash_fix_ecc(void)
{
uint8_t page_buf[512];
uint32_t addr;
uint32_t start = WOLFBOOT_PARTITION_BOOT_ADDRESS;
uint32_t end = WOLFBOOT_PARTITION_SWAP_ADDRESS + WOLFBOOT_SECTOR_SIZE;
memset(page_buf, 0xFF, sizeof(page_buf));
for (addr = start; addr < end; addr += pflash_page_size) {
if (FLASH_VerifyErase(&pflash, addr, pflash_page_size)
== kStatus_FLASH_Success) {
FLASH_Program(&pflash, addr, page_buf, pflash_page_size);
}
}
}
void hal_init(void)
{
#ifdef __WOLFBOOT
@ -91,6 +108,7 @@ void hal_init(void)
#if defined(__WOLFBOOT) || !defined(TZEN)
memset(&pflash, 0, sizeof(pflash));
FLASH_Init(&pflash);
hal_flash_fix_ecc();
#endif
#if defined(TZEN) && !defined(NONSECURE_APP)
@ -120,16 +138,41 @@ void hal_prepare_boot(void)
int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len)
{
if (
address % pflash_page_size == 0 &&
len % pflash_page_size == 0 &&
FLASH_Program(&pflash, address, data, len) == kStatus_FLASH_Success
)
{
return 0;
uint8_t page_buf[512];
uint32_t page_addr;
uint32_t offset;
uint32_t chunk;
while (len > 0) {
page_addr = address & ~(pflash_page_size - 1);
offset = address - page_addr;
chunk = pflash_page_size - offset;
if ((uint32_t)len < chunk)
chunk = (uint32_t)len;
if (FLASH_VerifyErase(&pflash, page_addr, pflash_page_size)
== kStatus_FLASH_Success) {
memset(page_buf, 0xFF, pflash_page_size);
} else {
memcpy(page_buf, (void *)page_addr, pflash_page_size);
if (FLASH_Erase(&pflash, page_addr, pflash_page_size,
kFLASH_ApiEraseKey) != kStatus_FLASH_Success)
return -1;
}
memcpy(page_buf + offset, data, chunk);
if (FLASH_Program(&pflash, page_addr, page_buf, pflash_page_size)
!= kStatus_FLASH_Success)
return -1;
address += chunk;
data += chunk;
len -= (int)chunk;
}
return -1;
return 0;
}
void RAMFUNCTION hal_flash_unlock(void)
@ -142,27 +185,27 @@ void RAMFUNCTION hal_flash_lock(void)
int RAMFUNCTION hal_flash_erase(uint32_t address, int len)
{
if (
address % pflash_page_size == 0 &&
len % pflash_page_size == 0 &&
FLASH_Erase(&pflash, address, len, kFLASH_ApiEraseKey)
== kStatus_FLASH_Success
)
{
return 0;
uint8_t page_buf[512];
uint32_t pos;
if (address % pflash_page_size != 0 || len % pflash_page_size != 0)
return -1;
memset(page_buf, 0xFF, sizeof(page_buf));
for (pos = address; pos < address + (uint32_t)len; pos += pflash_page_size) {
if (FLASH_Erase(&pflash, pos, pflash_page_size, kFLASH_ApiEraseKey)
!= kStatus_FLASH_Success)
return -1;
if (FLASH_Program(&pflash, pos, page_buf, pflash_page_size)
!= kStatus_FLASH_Success)
return -1;
}
return -1;
return 0;
}
#ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
int RAMFUNCTION hal_flash_is_erased_at(uint32_t address)
{
address &= ~(WOLFBOOT_SECTOR_SIZE - 1);
return FLASH_VerifyErase(&pflash, address, WOLFBOOT_SECTOR_SIZE) == kStatus_FLASH_Success;
}
#endif
#ifdef WOLFCRYPT_SECURE_MODE
void hal_trng_init(void)
{
@ -262,4 +305,4 @@ void uart_write(const char *buf, unsigned int sz)
sz -= line_sz + 1U;
}
}
#endif
#endif

View File

@ -88,9 +88,6 @@ uint64_t hal_get_timer_us(void);
void hal_flash_unlock(void);
void hal_flash_lock(void);
void hal_prepare_boot(void);
#ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
int hal_flash_is_erased_at(uint32_t address);
#endif
#ifdef DUALBANK_SWAP
void hal_flash_dualbank_swap(void);

View File

@ -713,10 +713,6 @@ ifeq ($(NVM_FLASH_WRITEONCE),1)
CFLAGS+= -D"NVM_FLASH_WRITEONCE"
endif
ifeq ($(NO_DIRECT_READ_OF_ERASED_SECTOR),1)
CFLAGS+= -D"NO_DIRECT_READ_OF_ERASED_SECTOR"
endif
ifeq ($(DISABLE_BACKUP),1)
CFLAGS+= -D"DISABLE_BACKUP"
endif

View File

@ -1298,17 +1298,10 @@ uint32_t wolfBoot_image_size(uint8_t *image)
*/
int wolfBoot_open_image_address(struct wolfBoot_image *img, uint8_t *image)
{
uint32_t *pmagic = (uint32_t *)(image);
uint32_t magic = FLASH_WORD_ERASED;
if (
#ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
hal_flash_is_erased_at((uintptr_t)pmagic) ||
#endif
(magic = *pmagic) != WOLFBOOT_MAGIC
)
{
uint32_t *magic = (uint32_t *)(image);
if (*magic != WOLFBOOT_MAGIC) {
wolfBoot_printf("Partition %d header magic 0x%08x invalid at %p\n",
img->part, (unsigned int)magic, img->hdr);
img->part, (unsigned int)*magic, img->hdr);
return -1;
}
img->fw_size = wolfBoot_image_size(image);

View File

@ -228,7 +228,6 @@ static int RAMFUNCTION nvm_select_fresh_sector(int part)
uint8_t* addrErase = 0;
uint32_t word_0;
uint32_t word_1;
uint32_t *ptr_word_0, *ptr_word_1;
#if defined(EXT_FLASH) && !defined(FLAGS_HOME)
if ((part == PART_UPDATE) && FLAGS_UPDATE_EXT()) {
@ -255,28 +254,8 @@ static int RAMFUNCTION nvm_select_fresh_sector(int part)
}
/* check magic in case the sector is corrupt */
ptr_word_0 = (uint32_t*)((uintptr_t)base - sizeof(uint32_t));
ptr_word_1 = (uint32_t*)((uintptr_t)base - (WOLFBOOT_SECTOR_SIZE + sizeof(uint32_t)));
#ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
if (hal_flash_is_erased_at((uintptr_t)ptr_word_0))
{
word_0 = FLASH_WORD_ERASED;
}
else
#endif
{
word_0 = *ptr_word_0;
}
#ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
if (hal_flash_is_erased_at((uintptr_t)ptr_word_1))
{
word_1 = FLASH_WORD_ERASED;
}
else
#endif
{
word_1 = *ptr_word_1;
}
word_0 = *((uint32_t*)((uintptr_t)base - sizeof(uint32_t)));
word_1 = *((uint32_t*)((uintptr_t)base - (WOLFBOOT_SECTOR_SIZE + sizeof(uint32_t))));
if (word_0 == WOLFBOOT_MAGIC_TRAIL && word_1 != WOLFBOOT_MAGIC_TRAIL) {
sel = 0;
@ -322,15 +301,8 @@ static int RAMFUNCTION nvm_select_fresh_sector(int part)
finish:
/* Erase the non-selected partition, requires unlocked flash */
addrErase -= WOLFBOOT_SECTOR_SIZE * (!sel);
if (
#ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
! hal_flash_is_erased_at((uintptr_t)addrErase)
#else
*((uint32_t*)(addrErase + WOLFBOOT_SECTOR_SIZE - sizeof(uint32_t)))
!= FLASH_WORD_ERASED
#endif
)
{
if (*((uint32_t*)(addrErase + WOLFBOOT_SECTOR_SIZE - sizeof(uint32_t)))
!= FLASH_WORD_ERASED) {
hal_flash_erase((uintptr_t)addrErase, WOLFBOOT_SECTOR_SIZE);
}
return sel;
@ -355,12 +327,7 @@ static int RAMFUNCTION trailer_write(uint8_t part, uintptr_t addr, uint8_t val)
nvm_cached_sector = nvm_select_fresh_sector(part);
addr_read = addr_align - (nvm_cached_sector * NVM_CACHE_SIZE);
#ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
if (hal_flash_is_erased_at((uintptr_t)addr_read))
XMEMSET(NVM_CACHE, FLASH_BYTE_ERASED, NVM_CACHE_SIZE);
else
#endif
XMEMCPY(NVM_CACHE, (void*)addr_read, NVM_CACHE_SIZE);
XMEMCPY(NVM_CACHE, (void*)addr_read, NVM_CACHE_SIZE);
NVM_CACHE[addr_off] = val;
/* Calculate write address */
@ -404,12 +371,7 @@ static int RAMFUNCTION partition_magic_write(uint8_t part, uintptr_t addr)
nvm_cached_sector = nvm_select_fresh_sector(part);
addr_read = base - (nvm_cached_sector * NVM_CACHE_SIZE);
addr_write = base - (!nvm_cached_sector * NVM_CACHE_SIZE);
#ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
if (hal_flash_is_erased_at((uintptr_t)addr_read))
XMEMSET(NVM_CACHE, FLASH_BYTE_ERASED, NVM_CACHE_SIZE);
else
#endif
XMEMCPY(NVM_CACHE, (void*)addr_read, NVM_CACHE_SIZE);
XMEMCPY(NVM_CACHE, (void*)addr_read, NVM_CACHE_SIZE);
XMEMCPY(NVM_CACHE + off, &wolfboot_magic_trail, sizeof(uint32_t));
ret = hal_flash_write(addr_write, NVM_CACHE, WOLFBOOT_SECTOR_SIZE);
if (ret != 0)
@ -664,20 +626,11 @@ int RAMFUNCTION wolfBoot_set_partition_state(uint8_t part, uint8_t newst)
if (part == PART_NONE)
return -1;
magic = get_partition_magic(part);
if (
#ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
hal_flash_is_erased_at((uintptr_t)magic) ||
#endif
*magic != WOLFBOOT_MAGIC_TRAIL
)
{
if (*magic != WOLFBOOT_MAGIC_TRAIL)
set_partition_magic(part);
}
state = get_partition_state(part);
if (*state != newst)
{
set_partition_state(part, newst);
}
return 0;
}
@ -699,15 +652,8 @@ int RAMFUNCTION wolfBoot_set_update_sector_flag(uint16_t sector,
uint8_t pos = sector >> 1;
magic = get_partition_magic(PART_UPDATE);
if (
#ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
hal_flash_is_erased_at((uintptr_t)magic) ||
#endif
*magic != wolfboot_magic_trail
)
{
if (*magic != wolfboot_magic_trail)
set_partition_magic(PART_UPDATE);
}
flags = get_update_sector_flags(pos);
if (sector == (pos << 1))
@ -735,15 +681,8 @@ int RAMFUNCTION wolfBoot_get_partition_state(uint8_t part, uint8_t *st)
if (part == PART_NONE)
return -1;
magic = get_partition_magic(part);
if (
#ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
hal_flash_is_erased_at((uintptr_t)magic) ||
#endif
*magic != WOLFBOOT_MAGIC_TRAIL
)
{
if (*magic != WOLFBOOT_MAGIC_TRAIL)
return -1;
}
state = get_partition_state(part);
*st = *state;
return 0;
@ -767,15 +706,8 @@ int wolfBoot_get_update_sector_flag(uint16_t sector, uint8_t *flag)
uint8_t *flags;
uint8_t pos = sector >> 1;
magic = get_partition_magic(PART_UPDATE);
if (
#ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
hal_flash_is_erased_at((uintptr_t)magic) ||
#endif
*magic != WOLFBOOT_MAGIC_TRAIL
)
{
if (*magic != WOLFBOOT_MAGIC_TRAIL)
return -1;
}
flags = get_update_sector_flags(pos);
if (sector == (pos << 1))
*flag = *flags & 0x0F;
@ -862,17 +794,12 @@ void RAMFUNCTION wolfBoot_update_trigger(void)
#else
uint32_t magic = WOLFBOOT_MAGIC_TRAIL;
uint32_t offset = SECTOR_FLAGS_SIZE;
# ifdef FLAGS_HOME
#ifdef FLAGS_HOME
offset -= (PART_BOOT_ENDFLAGS - PART_UPDATE_ENDFLAGS);
# endif
#endif
selSec = nvm_select_fresh_sector(PART_UPDATE);
# ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
if (hal_flash_is_erased_at((uintptr_t)lastSector - WOLFBOOT_SECTOR_SIZE * selSec))
XMEMSET(NVM_CACHE, FLASH_BYTE_ERASED, WOLFBOOT_SECTOR_SIZE);
else
# endif
XMEMCPY(NVM_CACHE, (uint8_t*)lastSector - WOLFBOOT_SECTOR_SIZE * selSec,
WOLFBOOT_SECTOR_SIZE);
XMEMCPY(NVM_CACHE, (uint8_t*)lastSector - WOLFBOOT_SECTOR_SIZE * selSec,
WOLFBOOT_SECTOR_SIZE);
/* write to the non selected sector */
hal_flash_erase(lastSector - WOLFBOOT_SECTOR_SIZE * !selSec,
WOLFBOOT_SECTOR_SIZE);
@ -1081,15 +1008,8 @@ int wolfBoot_get_delta_info(uint8_t part, int inverse, uint32_t **img_offset,
/* Don't check image against NULL to allow using address 0x00000000 */
magic = (uint32_t *)image;
if (
#ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
hal_flash_is_erased_at((uintptr_t)magic) ||
#endif
*magic != WOLFBOOT_MAGIC
)
{
if (*magic != WOLFBOOT_MAGIC)
return -1;
}
if (inverse) {
if (wolfBoot_find_header((uint8_t *)(image + IMAGE_HEADER_OFFSET),
HDR_IMG_DELTA_INVERSE, (uint8_t **)img_offset)
@ -1162,15 +1082,8 @@ uint32_t wolfBoot_get_blob_version(uint8_t *blob)
img_bin = dec_hdr;
#endif
magic = (uint32_t *)img_bin;
if (
#ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
hal_flash_is_erased_at((uintptr_t)magic) ||
#endif
*magic != WOLFBOOT_MAGIC
)
{
if (*magic != WOLFBOOT_MAGIC)
return 0;
}
if (wolfBoot_find_header(img_bin + IMAGE_HEADER_OFFSET, HDR_VERSION,
(void *)&version_field) == 0)
return 0;
@ -1202,15 +1115,8 @@ uint16_t wolfBoot_get_blob_type(uint8_t *blob)
img_bin = dec_hdr;
#endif
magic = (uint32_t *)img_bin;
if (
#ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
hal_flash_is_erased_at((uintptr_t)magic) ||
#endif
*magic != WOLFBOOT_MAGIC
)
{
if (*magic != WOLFBOOT_MAGIC)
return 0;
}
if (wolfBoot_find_header(img_bin + IMAGE_HEADER_OFFSET, HDR_IMG_TYPE,
(void *)&type_field) == 0)
return 0;
@ -1246,15 +1152,8 @@ uint32_t wolfBoot_get_blob_diffbase_version(uint8_t *blob)
img_bin = dec_hdr;
#endif
magic = (uint32_t *)img_bin;
if (
#ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
hal_flash_is_erased_at((uintptr_t)magic) ||
#endif
*magic != WOLFBOOT_MAGIC
)
{
if (*magic != WOLFBOOT_MAGIC)
return 0;
}
if (wolfBoot_find_header(img_bin + IMAGE_HEADER_OFFSET, HDR_IMG_DELTA_BASE,
(void *)&delta_base) == 0)
return 0;

View File

@ -447,12 +447,7 @@ static int RAMFUNCTION wolfBoot_swap_and_final_erase(int resume)
ext_flash_read((uintptr_t)(boot->hdr + tmpBootPos), (void*)tmpBuffer,
sizeof(tmpBuffer));
#else
# ifdef NO_DIRECT_READ_OF_ERASED_SECTOR
if (hal_flash_is_erased_at((uintptr_t)(boot->hdr + tmpBootPos)))
memset(tmpBuffer, FLASH_BYTE_ERASED, sizeof(tmpBuffer));
else
# endif
memcpy(tmpBuffer, boot->hdr + tmpBootPos, sizeof(tmpBuffer));
memcpy(tmpBuffer, boot->hdr + tmpBootPos, sizeof(tmpBuffer));
#endif
/* Check if the magic trailer exists - indicates an interrupted swap