From 396ab268df8a0b52e25108e41370ec6ab64fd337 Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 19 Mar 2025 15:59:22 +1100 Subject: [PATCH] stm32/qspi: Implement MP_QSPI_IOCTL_MEMORY_MODIFIED ioctl. stm32's QSPI driver supports memory-mapped mode. The memory-mapped flash can also be erased/written to. To support both these modes, it switches in and out of memory-mapped mode during an erase/write. If the flash is erased/written and then switched back to memory mapped mode, the cache related to the memory-mapped region that changed must be invalidated. Otherwise subsequent code may end up reading old data. That cache invalidation is currently not being done, and this commit fixes that. This bug has been around ever since QSPI memory-mapped mode existed, but it's never really been observed because it's not common to use flash in memory-mapped mode and also erase/write it. Eg PYBD_SF2 uses the memory-mapped flash in read-only mode to store additional firmware. But since the introduction of ROMFS, things changed. The `vfs.rom_ioctl()` command can erase/write memory-mapped flash. Signed-off-by: Damien George --- ports/stm32/qspi.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ports/stm32/qspi.c b/ports/stm32/qspi.c index 1d3239b0d2..1311c27d1d 100644 --- a/ports/stm32/qspi.c +++ b/ports/stm32/qspi.c @@ -190,6 +190,14 @@ static int qspi_ioctl(void *self_in, uint32_t cmd, uintptr_t arg) { // Switch to memory-map mode when bus is idle qspi_memory_map(); break; + case MP_QSPI_IOCTL_MEMORY_MODIFIED: { + uintptr_t *addr_len = (uintptr_t *)arg; + volatile void *addr = (volatile void *)(QSPI_MAP_ADDR + addr_len[0]); + size_t len = addr_len[1]; + SCB_InvalidateICache_by_Addr(addr, len); + SCB_InvalidateDCache_by_Addr(addr, len); + break; + } } return 0; // success }