Skip to content

Commit 2d25c5a

Browse files
committed
Vorago VA416x0: simplify iram_write/iram_fill (single RMW path)
1 parent c3d255d commit 2d25c5a

1 file changed

Lines changed: 14 additions & 47 deletions

File tree

hal/va416x0.c

Lines changed: 14 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -362,41 +362,20 @@ void ext_flash_unlock(void)
362362
}
363363

364364
/* The VA416xx code RAM (IRAM, 0x00000000-0x0003FFFF) silently drops 8/16-bit
365-
* stores when WREN=1 - only word-aligned 32-bit stores stick (the ECC
365+
* stores when WREN=1 -- only word-aligned 32-bit stores stick (the ECC
366366
* machinery computes parity per word and rejects sub-word writes without
367-
* fault). A generic byte-wise memcpy/memset on the IRAM shadow appears
368-
* to succeed but leaves the destination unchanged. These helpers copy/fill
369-
* with 32-bit stores so the IRAM shadow update actually takes effect.
370-
*
371-
* Partition addresses (boot/update/swap) are sector-aligned (0x800) and the
372-
* swap engine moves whole sector-sized blocks, so in practice the IRAM
373-
* shadow path is always word-aligned. The unaligned head/tail fallbacks
374-
* exist for defense-in-depth. */
367+
* fault). A generic byte-wise memcpy/memset on the IRAM shadow appears to
368+
* succeed but leaves the destination unchanged. These helpers do a
369+
* read-modify-write of the containing word for each up-to-4-byte group, so
370+
* the only stores emitted are 32-bit STR through a volatile pointer (which
371+
* the compiler is required to emit verbatim, i.e. exactly one STR). */
375372
static void iram_write(void *dst, const void *src, int len)
376373
{
377-
uintptr_t d = (uintptr_t)dst;
378-
uintptr_t s = (uintptr_t)src;
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;
384-
const uint32_t *ws = (const uint32_t *)src;
385-
while (len >= 4) {
386-
*wd++ = *ws++;
387-
len -= 4;
388-
}
389-
/* Fall through with byte tail (typically zero on this target) */
390-
dst = (void *)wd;
391-
src = ws;
392-
}
393-
/* Byte tail/unaligned: do read-modify-write of the containing word
394-
* (sub-word stores are dropped by the hardware). */
395374
while (len > 0) {
396-
uintptr_t addr = (uintptr_t)dst & ~(uintptr_t)3u;
397-
uint32_t off = (uint32_t)((uintptr_t)dst & (uintptr_t)3u);
398-
uint32_t word = *(volatile uint32_t *)addr;
399-
uint8_t *wp = (uint8_t *)&word;
375+
uintptr_t addr = (uintptr_t)dst & ~3u;
376+
uint32_t off = (uintptr_t)dst & 3u;
377+
uint32_t word = *(volatile uint32_t *)addr;
378+
uint8_t *wp = (uint8_t *)&word;
400379
while (len > 0 && off < 4u) {
401380
wp[off++] = *(const uint8_t *)src;
402381
src = (const uint8_t *)src + 1;
@@ -409,23 +388,11 @@ static void iram_write(void *dst, const void *src, int len)
409388

410389
static void iram_fill(void *dst, uint8_t val, int len)
411390
{
412-
uint32_t pattern = ((uint32_t)val << 24) | ((uint32_t)val << 16) |
413-
((uint32_t)val << 8) | (uint32_t)val;
414-
uintptr_t d = (uintptr_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;
418-
while (len >= 4) {
419-
*wd++ = pattern;
420-
len -= 4;
421-
}
422-
dst = (void *)wd;
423-
}
424391
while (len > 0) {
425-
uintptr_t addr = (uintptr_t)dst & ~(uintptr_t)3u;
426-
uint32_t off = (uint32_t)((uintptr_t)dst & (uintptr_t)3u);
427-
uint32_t word = *(volatile uint32_t *)addr;
428-
uint8_t *wp = (uint8_t *)&word;
392+
uintptr_t addr = (uintptr_t)dst & ~3u;
393+
uint32_t off = (uintptr_t)dst & 3u;
394+
uint32_t word = *(volatile uint32_t *)addr;
395+
uint8_t *wp = (uint8_t *)&word;
429396
while (len > 0 && off < 4u) {
430397
wp[off++] = val;
431398
dst = (uint8_t *)dst + 1;

0 commit comments

Comments
 (0)