@@ -46,30 +46,37 @@ static uint32_t m1_rfmt;
46
46
static uint32_t m1_timing ;
47
47
#endif
48
48
49
- static void save_psram_settings (void ) {
49
+ static void __no_inline_not_in_flash_func ( save_psram_settings ) (void ) {
50
50
#ifdef PICO_RP2350
51
51
// We're about to invalidate the XIP cache, clean it first to commit any dirty writes to PSRAM
52
- volatile uint8_t * maintenance_ptr = (uint8_t * )XIP_MAINTENANCE_BASE ;
53
- for (int i = 1 ; i < 16 * 1024 ; i += 8 ) {
54
- // Background info: https://forums.raspberrypi.com/viewtopic.php?t=378249
55
- maintenance_ptr [i ] = 0 ; // Clean
56
- __compiler_memory_barrier ();
57
- maintenance_ptr [i - 1 ] = 0 ; // Explicitly invalidate
58
- __compiler_memory_barrier ();
52
+ // From https://forums.raspberrypi.com/viewtopic.php?t=378249#p2263677
53
+ // Perform clean-by-set/way on all lines
54
+ for (uint32_t i = 0 ; i < 2048 ; ++ i ) {
55
+ // Use the upper 16k of the maintenance space (0x1bffc000 through 0x1bffffff):
56
+ * (volatile uint8_t * )(XIP_SRAM_BASE + (XIP_MAINTENANCE_BASE - XIP_BASE ) + i * 8u + 0x1u ) = 0 ;
59
57
}
60
58
61
59
m1_timing = qmi_hw -> m [1 ].timing ;
62
60
m1_rfmt = qmi_hw -> m [1 ].rfmt ;
63
61
#endif
64
62
}
65
63
66
- static void restore_psram_settings (void ) {
64
+ static void __no_inline_not_in_flash_func ( restore_psram_settings ) (void ) {
67
65
#ifdef PICO_RP2350
68
66
qmi_hw -> m [1 ].timing = m1_timing ;
69
67
qmi_hw -> m [1 ].rfmt = m1_rfmt ;
68
+ __compiler_memory_barrier ();
70
69
#endif
71
70
}
72
71
72
+ void supervisor_flash_pre_write (void ) {
73
+ save_psram_settings ();
74
+ }
75
+
76
+ void supervisor_flash_post_write (void ) {
77
+ restore_psram_settings ();
78
+ }
79
+
73
80
void supervisor_flash_init (void ) {
74
81
bi_decl_if_func_used (bi_block_device (
75
82
BINARY_INFO_MAKE_TAG ('C' , 'P' ),
@@ -84,9 +91,9 @@ void supervisor_flash_init(void) {
84
91
// Read the RDID register to get the flash capacity.
85
92
uint8_t cmd [] = {0x9f , 0 , 0 , 0 };
86
93
uint8_t data [4 ];
87
- save_psram_settings ();
94
+ supervisor_flash_pre_write ();
88
95
flash_do_cmd (cmd , data , 4 );
89
- restore_psram_settings ();
96
+ supervisor_flash_post_write ();
90
97
uint8_t power_of_two = FLASH_DEFAULT_POWER_OF_TWO ;
91
98
// Flash must be at least 2MB (1 << 21) because we use the first 1MB for the
92
99
// CircuitPython core. We validate the range because Adesto Tech flash chips
@@ -116,10 +123,10 @@ void port_internal_flash_flush(void) {
116
123
#if CIRCUITPY_AUDIOCORE
117
124
uint32_t channel_mask = audio_dma_pause_all ();
118
125
#endif
119
- save_psram_settings ();
126
+ supervisor_flash_pre_write ();
120
127
flash_range_erase (CIRCUITPY_CIRCUITPY_DRIVE_START_ADDR + _cache_lba , SECTOR_SIZE );
121
128
flash_range_program (CIRCUITPY_CIRCUITPY_DRIVE_START_ADDR + _cache_lba , _cache , SECTOR_SIZE );
122
- restore_psram_settings ();
129
+ supervisor_flash_post_write ();
123
130
_cache_lba = NO_CACHE ;
124
131
#if CIRCUITPY_AUDIOCORE
125
132
audio_dma_unpause_mask (channel_mask );
0 commit comments