Datasheet

Table Of Contents
2.6.3.2. Cache Flushing and Maintenance
The FLUSH register allows the entire cache contents to be flushed. This is necessary if software has reprogrammed the
flash contents, and needs to clear out stale data and code, without performing a reboot. Cache flushes are triggered
either manually by writing 1 to FLUSH, or automatically when the XIP block is brought out of reset. The flush is
implemented by zeroing the cache tag memory using an internal counter, which takes just over 1024 clock cycles (16 kB
total size / 8 bytes per line / 2 ways per set).
Flushing the cache whilst accessing flash data (perhaps initiating the flush on one core whilst another core may be
executing code from flash) is a safe operation, but any master accessing flash data while the flush is in progress will be
stalled until completion.
CAUTION
The cache-as-SRAM alias (0x15…) must not be written whilst a cache flush is in progress. Before writing for the first
time, if a cache flush has recently been initiated (e.g. via a watchdog reset), a dummy read from FLUSH is
recommended to ensure the cache flush has completed. Writing to cache-as-SRAM whilst a flush is in progress can
corrupt the data memory contents.
A complete cache flush dramatically slows subsequent code execution, until the cache "warms up" again. There is an
alternative, which allows cache contents corresponding to only a certain address range to be invalidated. A write to the
0x10… mirror will look up the addressed location in the cache, and delete any matching entry found. Writing to all word-
aligned locations in an address range (e.g. a flash sector that has just been erased and reprogrammed) therefore
eliminates the possibility of stale cached data in this range, without suffering the effects of a complete cache flush.
Pico Examples: https://github.com/raspberrypi/pico-examples/tree/master/flash/cache_perfctr/flash_cache_perfctr.c Lines 30 - 55
30 // Flush cache to make sure we miss the first time we access test_data
31 xip_ctrl_hw->flush = 1;
32 while (!(xip_ctrl_hw->stat & XIP_STAT_FLUSH_READY_BITS))
33 tight_loop_contents();
34
35 // Clear counters (write any value to clear)
36 xip_ctrl_hw->ctr_acc = 1;
37 xip_ctrl_hw->ctr_hit = 1;
38
39 (void) *test_data_ptr;
40 check(xip_ctrl_hw->ctr_hit == 0 && xip_ctrl_hw->ctr_acc == 1,
41 "First access to data should miss");
42
43 (void) *test_data_ptr;
44 check(xip_ctrl_hw->ctr_hit == 1 && xip_ctrl_hw->ctr_acc == 2,
45 "Second access to data should hit");
46
47 // Write to invalidate individual cache lines (64 bits)
48 // Writes must be directed to the cacheable, allocatable alias (address 0x10.._....)
49 *test_data_ptr = 0;
50 (void) *test_data_ptr;
51 check(xip_ctrl_hw->ctr_hit == 1 && xip_ctrl_hw->ctr_acc == 3,
52 "Should miss after invalidation");
53 (void) *test_data_ptr;
54 check(xip_ctrl_hw->ctr_hit == 2 && xip_ctrl_hw->ctr_acc == 4,
55 "Second access after invalidation should hit again");
2.6.3.3. SSI
The execute-in-place functionality is provided by the SSI interface, documented in Section 4.10. It supports 1, 2 or 4-bit
SPI flash interfaces (SPI, DSPI and QSPI), and can insert either an instruction prefix or mode continuation bits on each
RP2040 Datasheet
2.6. Memory 151