@@ -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). */
375372static 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
410389static 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