Skip to content

Commit c3d255d

Browse files
dgarskedanielinux
authored andcommitted
Vorago VA416x0: harden iram_write/iram_fill per review
Two follow-ups to the IRAM shadow update fix (da96f5a): 1. Mark the bulk-copy destination as volatile uint32_t * so the compiler cannot lower a 32-bit assignment into byte/halfword stores. Sub-word stores are silently dropped by the IRAM ECC, so a future codegen change could have broken the workaround. 2. Use (uintptr_t)3u / ~(uintptr_t)3u for alignment masking. On targets where uintptr_t is wider than unsigned int the bare ~3u would zero the high half of the address; harmless on Cortex-M4 today, but the helper pattern is easy to copy elsewhere. The int len type is kept to match the wolfBoot ext_flash_* HAL signature convention across all ports. Verified with arm-none-eabi-objdump: aligned bulk path emits only 32-bit str instructions (no strb/strh).
1 parent 08c6673 commit c3d255d

1 file changed

Lines changed: 14 additions & 11 deletions

File tree

hal/va416x0.c

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -376,23 +376,25 @@ static void iram_write(void *dst, const void *src, int len)
376376
{
377377
uintptr_t d = (uintptr_t)dst;
378378
uintptr_t s = (uintptr_t)src;
379-
/* Word-aligned bulk copy */
380-
if (((d | s) & 3u) == 0u) {
381-
uint32_t *wd = (uint32_t *)dst;
379+
/* Word-aligned bulk copy. The destination is marked volatile so the
380+
* compiler cannot lower a 32-bit assignment into byte/halfword stores
381+
* (which would be silently dropped by the IRAM ECC machinery). */
382+
if (((d | s) & (uintptr_t)3u) == 0u) {
383+
volatile uint32_t *wd = (volatile uint32_t *)dst;
382384
const uint32_t *ws = (const uint32_t *)src;
383385
while (len >= 4) {
384386
*wd++ = *ws++;
385387
len -= 4;
386388
}
387389
/* Fall through with byte tail (typically zero on this target) */
388-
dst = wd;
390+
dst = (void *)wd;
389391
src = ws;
390392
}
391393
/* Byte tail/unaligned: do read-modify-write of the containing word
392394
* (sub-word stores are dropped by the hardware). */
393395
while (len > 0) {
394-
uintptr_t addr = (uintptr_t)dst & ~3u;
395-
uint32_t off = (uintptr_t)dst & 3u;
396+
uintptr_t addr = (uintptr_t)dst & ~(uintptr_t)3u;
397+
uint32_t off = (uint32_t)((uintptr_t)dst & (uintptr_t)3u);
396398
uint32_t word = *(volatile uint32_t *)addr;
397399
uint8_t *wp = (uint8_t *)&word;
398400
while (len > 0 && off < 4u) {
@@ -410,17 +412,18 @@ static void iram_fill(void *dst, uint8_t val, int len)
410412
uint32_t pattern = ((uint32_t)val << 24) | ((uint32_t)val << 16) |
411413
((uint32_t)val << 8) | (uint32_t)val;
412414
uintptr_t d = (uintptr_t)dst;
413-
if ((d & 3u) == 0u) {
414-
uint32_t *wd = (uint32_t *)dst;
415+
/* Word-aligned bulk fill via volatile to guarantee 32-bit stores. */
416+
if ((d & (uintptr_t)3u) == 0u) {
417+
volatile uint32_t *wd = (volatile uint32_t *)dst;
415418
while (len >= 4) {
416419
*wd++ = pattern;
417420
len -= 4;
418421
}
419-
dst = wd;
422+
dst = (void *)wd;
420423
}
421424
while (len > 0) {
422-
uintptr_t addr = (uintptr_t)dst & ~3u;
423-
uint32_t off = (uintptr_t)dst & 3u;
425+
uintptr_t addr = (uintptr_t)dst & ~(uintptr_t)3u;
426+
uint32_t off = (uint32_t)((uintptr_t)dst & (uintptr_t)3u);
424427
uint32_t word = *(volatile uint32_t *)addr;
425428
uint8_t *wp = (uint8_t *)&word;
426429
while (len > 0 && off < 4u) {

0 commit comments

Comments
 (0)