The binman-appended DDR firmware grows towards its fixed execution address at 0xc082d000 as SPL gains code and device-tree data. On the current R2S image the source starts at 0xc0825c80 and its 36248 bytes overlap the execution region by 6680 bytes. The RV2 image overlaps by 7704 bytes.
memcpy() copies forwards on RISC-V and corrupts the end of the firmware when the destination overlaps a later part of the source. Use memmove() so both overlapping and disjoint image layouts preserve the firmware. Keep the DDR configuration, execution address and instruction fence intact. Signed-off-by: Dave Klotz <[email protected]> --- Validation: checkpatch has zero errors/warnings. The previous packaged RISC-V copy instructions reproduce firmware corruption; the corrected instructions pass five full-SRAM copy cases per board in each tested build, including disjoint/overlap cases and unchanged bytes outside the destination. An integration containing this fix, the clock-mux rename and the MMC corrections passed warm-boot tests on a 2 GiB OrangePi R2S and a 4 GiB OrangePi RV2. Both reached DDR/SPL, FIT verification and automatic EFI boot to their existing FreeBSD 16 installation, with the expected memory and eight CPUs. These are combined integration results, not isolated tests of this single patch. Cold boot of the corrected firmware has not been tested. board/spacemit/k1/spl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/board/spacemit/k1/spl.c b/board/spacemit/k1/spl.c index 157e1bf5b442..4e9f66f60909 100644 --- a/board/spacemit/k1/spl.c +++ b/board/spacemit/k1/spl.c @@ -421,7 +421,8 @@ src = (void __iomem *)pos; dst = (void __iomem *)(DDR_FIRMWARE_BASE); log_info("DDR firmware: [0x%lx]:0x%x, size:0x%lx\n", pos, readl(src), size); - memcpy((u8 *)dst, (u8 *)src, size); + /* The appended firmware may overlap its fixed execution address. */ + memmove((u8 *)dst, (u8 *)src, size); size = round_up(size, 64); /* * Ensure the just-written DDR firmware bytes are observable in the -- 2.50.0
