Skip to content

Commit 599c226

Browse files
Workaround PSRAM cache invalid'n by reading flash (#2551)
* Workaround PSRAM cache invalid'n by reading flash Fixes #2537 While waiting for a working direct cache flush routine, try and force the cache to evict all PSRAM values by reading a bunch of flash addresses (which share the XIP cache). This hurts performance when PSRAM is not used, but is required for correctness until we have a working XIP flush. * Invalidate after cleaning the cache line gmx from the RPI forums came up with this hack and it seems to work! https://forums.raspberrypi.com/viewtopic.php?p=2262371#p2262371
1 parent e7419fb commit 599c226

File tree

1 file changed

+21
-1
lines changed

1 file changed

+21
-1
lines changed

cores/rp2040/flash_wrapper.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,35 @@
1717
License along with this library; if not, write to the Free Software
1818
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1919
*/
20-
20+
#include <Arduino.h>
2121
#include <hardware/flash.h>
2222

2323
#ifdef PICO_RP2350
2424
#include <hardware/structs/qmi.h>
2525
#endif
2626

27+
#if defined(PICO_RP2350) && defined(RP2350_PSRAM_CS)
28+
static void __no_inline_not_in_flash_func(flushcache)() {
29+
for (volatile uint8_t* cache = (volatile uint8_t*)0x18000001; cache < (volatile uint8_t*)(0x18000001 + 2048 * 8); cache += 8) {
30+
*cache = 0;
31+
__compiler_memory_barrier();
32+
*(cache - 1) = 0;
33+
__compiler_memory_barrier();
34+
}
35+
}
36+
#elif defined(PICO_RP2350)
37+
static void __no_inline_not_in_flash_func(flushcache)() {
38+
// Null
39+
}
40+
#endif
41+
42+
2743
extern "C" {
2844
extern void __real_flash_range_erase(uint32_t flash_offs, size_t count);
2945
void __wrap_flash_range_erase(uint32_t flash_offs, size_t count) {
3046
#ifdef PICO_RP2350
3147
auto s = qmi_hw->m[1];
48+
flushcache();
3249
#endif
3350
__real_flash_range_erase(flash_offs, count);
3451
#ifdef PICO_RP2350
@@ -41,6 +58,7 @@ extern "C" {
4158
void __wrap_flash_range_program(uint32_t flash_offs, const uint8_t *data, size_t count) {
4259
#ifdef PICO_RP2350
4360
auto s = qmi_hw->m[1];
61+
flushcache();
4462
#endif
4563
__real_flash_range_program(flash_offs, data, count);
4664
#ifdef PICO_RP2350
@@ -53,6 +71,7 @@ extern "C" {
5371
void __wrap_flash_get_unique_id(uint8_t *id_out) {
5472
#ifdef PICO_RP2350
5573
auto s = qmi_hw->m[1];
74+
flushcache();
5675
#endif
5776
__real_flash_get_unique_id(id_out);
5877
#ifdef PICO_RP2350
@@ -65,6 +84,7 @@ extern "C" {
6584
void __wrap_flash_do_cmd(const uint8_t *txbuf, uint8_t *rxbuf, size_t count) {
6685
#ifdef PICO_RP2350
6786
auto s = qmi_hw->m[1];
87+
flushcache();
6888
#endif
6989
__real_flash_do_cmd(txbuf, rxbuf, count);
7090
#ifdef PICO_RP2350

0 commit comments

Comments
 (0)