Skip to content

Commit 978e15c

Browse files
author
steffen.yount
committed
Facilitate RP2040 XIP-cache-as-RAM feature (#2653)
The pico-sdk and RP2040 hardware provide a few facilities that improve performance by moving runtime code and data into SRAM: 1. "pico/platform/sections.h" currently provides the "__not_in_flash", "__not_in_flash_func", and "__time_critical_func" macros for placing runtime code and data into SRAM by assigning them linker section names in the source code. 2. The pico-sdk CMake scripts allow any of four binary types to be selected with similarly named project properties for the RP2040: "default", "blocked_ram", "copy_to_ram", or "no_flash" 3. The RP2040's eXecute-In-Place (XIP) cache has its own connection to the main AHB bus and provides SRAM speeds on cache hits when retrieving runtime code and data from flash But this regime isn't perfect. The 16kB of XIP cache and its connection to the main AHB bus go mostly unused for PICO_COPY_TO_RAM and PICO_NO_FLASH binary type builds, leaving some performance opportunities unrealized in their implementations. The RP2040's eXecute-In-Place (XIP) cache can be disabled by clearing its CTRL.EN bit which allows its 16kB of memory to be used as SRAM directly. These changes are aiming to update the pico-sdk to support the following: 1. Use the "__time_critical_func" macro to place runtime code into XIP RAM for PICO_COPY_TO_RAM and PICO_NO_FLASH binary type builds 2. Add a couple new "copy_to_ram_using_xip_ram" and "no_flash_using_xip_ram" binary type builds for the RP2040 3. Add a new "PICO_USE_XIP_CACHE_AS_RAM" CMake property to enable the XIP cache's use as RAM for time critical instructions in PICO_COPY_TO_RAM and PICO_NO_FLASH binary type builds 4. Add a couple new CMake functions "pico_sections_not_in_flash(TARGET [list_of_sources])" and "pico_sections_time_critical(TARGET [list_of_sources])" that target selected source files or a whole CMake build target's list of source files for placement into RAM and/or XIP RAM I believe I've achieved these 4 goals, but note: I've only tested them manually with CMake based builds on the RP2040 hardware that I have. Though I have made an effort to fail fast when configuration properties are incompatible, and I've also made an effort to stay compatible with the preexisting section names and the preexisting linker scripts.
1 parent 36f1df6 commit 978e15c

File tree

17 files changed

+823
-29
lines changed

17 files changed

+823
-29
lines changed

src/cmake/rp2_common.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
include(cmake/on_device.cmake)
44

55
# PICO_CMAKE_CONFIG: PICO_NO_FLASH, Option to default all binaries to not use flash i.e. run from SRAM, type=bool, default=0, group=build, docref=cmake-binary-type-config
6-
option(PICO_NO_FLASH "Default binaries to not not use flash")
6+
option(PICO_NO_FLASH "Default binaries to not use flash")
77
# PICO_CMAKE_CONFIG: PICO_COPY_TO_RAM, Option to default all binaries to copy code from flash to SRAM before running, type=bool, default=0, group=build, docref=cmake-binary-type-config
88
option(PICO_COPY_TO_RAM "Default binaries to copy code to RAM when booting from flash")
99

src/rp2040/boot_stage2/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ BOOT2_CHOICE_DEFINE_MAP["compile_time_choice"] = []
3535
cc_library(
3636
name = "config",
3737
hdrs = [
38+
"asminclude/embedded_xip_cache_enable_block.inc.S",
3839
"asminclude/boot2_helpers/exit_from_boot2.S",
3940
"asminclude/boot2_helpers/read_flash_sreg.S",
4041
"asminclude/boot2_helpers/wait_ssi_ready.S",
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#include "hardware/regs/addressmap.h"
2+
#include "hardware/regs/xip.h"
3+
4+
#if defined(PICO_USE_XIP_CACHE_AS_RAM) && PICO_USE_XIP_CACHE_AS_RAM
5+
// Disable the XIP cache making its 16k of XIP RAM available for storage
6+
_b2_disable_xip_cache:
7+
ldr r0, =(REG_ALIAS_CLR_BITS + XIP_CTRL_BASE + XIP_CTRL_OFFSET)
8+
movs r1, #XIP_CTRL_EN_BITS
9+
str r1, [r0]
10+
#else
11+
// Enable the XIP cache (hardware default)
12+
_b2_enable_xip_cache:
13+
ldr r0, =(REG_ALIAS_SET_BITS + XIP_CTRL_BASE + XIP_CTRL_OFFSET)
14+
movs r1, #XIP_CTRL_EN_BITS
15+
str r1, [r0]
16+
#endif

src/rp2040/boot_stage2/boot2_at25sf128a.S

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,8 @@ configure_ssi:
266266
// Bus accesses to the XIP window will now be transparently serviced by the
267267
// external flash on cache miss. We are ready to run code from flash.
268268

269+
#include "embedded_xip_cache_enable_block.inc.S"
270+
269271
// Pull in standard exit routine
270272
#include "boot2_helpers/exit_from_boot2.S"
271273

src/rp2040/boot_stage2/boot2_generic_03h.S

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ regular_func _stage2_boot
9696
// translated by the SSI into 03h read commands to the external flash (if cache is missed),
9797
// and the data will be returned to the bus.
9898

99+
#include "embedded_xip_cache_enable_block.inc.S"
100+
99101
// Pull in standard exit routine
100102
#include "boot2_helpers/exit_from_boot2.S"
101103

src/rp2040/boot_stage2/boot2_is25lp080.S

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,8 @@ configure_ssi:
248248
// We are now in XIP mode, with all transactions using Dual I/O and only
249249
// needing to send 24-bit addresses (plus mode bits) for each read transaction.
250250

251+
#include "embedded_xip_cache_enable_block.inc.S"
252+
251253
// Pull in standard exit routine
252254
#include "boot2_helpers/exit_from_boot2.S"
253255

src/rp2040/boot_stage2/boot2_w25q080.S

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,8 @@ configure_ssi:
268268
// Bus accesses to the XIP window will now be transparently serviced by the
269269
// external flash on cache miss. We are ready to run code from flash.
270270

271+
#include "embedded_xip_cache_enable_block.inc.S"
272+
271273
// Pull in standard exit routine
272274
#include "boot2_helpers/exit_from_boot2.S"
273275

src/rp2040/boot_stage2/boot2_w25x10cl.S

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,8 @@ regular_func _stage2_boot
187187
// We are now in XIP mode, with all transactions using Dual I/O and only
188188
// needing to send 24-bit addresses (plus mode bits) for each read transaction.
189189

190+
#include "embedded_xip_cache_enable_block.inc.S"
191+
190192
// Pull in standard exit routine
191193
#include "boot2_helpers/exit_from_boot2.S"
192194

src/rp2_common/pico_crt0/BUILD.bazel

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@ alias(
2828
}),
2929
)
3030

31+
alias(
32+
name = "copy_to_ram_using_xip_ram_linker_script",
33+
actual = select({
34+
"//bazel/constraint:rp2040": "//src/rp2_common/pico_crt0/rp2040:copy_to_ram_using_xip_ram_linker_script",
35+
"//conditions:default": "//bazel:incompatible_cc_lib",
36+
}),
37+
)
38+
3139
alias(
3240
name = "no_flash_linker_script",
3341
actual = select({
@@ -37,6 +45,14 @@ alias(
3745
}),
3846
)
3947

48+
alias(
49+
name = "no_flash_using_xip_ram_linker_script",
50+
actual = select({
51+
"//bazel/constraint:rp2040": "//src/rp2_common/pico_crt0/rp2040:no_flash_using_xip_ram_linker_script",
52+
"//conditions:default": "//bazel:incompatible_cc_lib",
53+
}),
54+
)
55+
4056
cc_library(
4157
name = "no_warn_rwx_flag",
4258
linkopts = select({

src/rp2_common/pico_crt0/crt0.S

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include "hardware/regs/addressmap.h"
1313
#include "hardware/regs/sio.h"
14+
#include "hardware/regs/xip.h"
1415
#include "pico/binary_info/defs.h"
1516
#include "boot/picobin.h"
1617
#include "pico/bootrom.h"
@@ -457,6 +458,22 @@ hold_non_core0_in_bootrom:
457458
b _enter_vtable_in_r0
458459
1:
459460

461+
#if PICO_RP2040 && PICO_NO_FLASH
462+
#if PICO_USE_XIP_CACHE_AS_RAM
463+
// Disable the XIP cache making its 16k of XIP RAM available for storage
464+
_disable_xip_cache:
465+
ldr r0, =(REG_ALIAS_CLR_BITS + XIP_CTRL_BASE + XIP_CTRL_OFFSET)
466+
movs r1, #XIP_CTRL_EN_BITS
467+
str r1, [r0]
468+
#else
469+
// Enable the XIP cache (hardware default)
470+
_enable_xip_cache:
471+
ldr r0, =(REG_ALIAS_SET_BITS + XIP_CTRL_BASE + XIP_CTRL_OFFSET)
472+
movs r1, #XIP_CTRL_EN_BITS
473+
str r1, [r0]
474+
#endif
475+
#endif
476+
460477
#if !PICO_RP2040 && PICO_EMBED_XIP_SETUP && !PICO_NO_FLASH
461478
// Execute boot2 on the core 0 stack (it also gets copied into BOOTRAM due
462479
// to inclusion in the data copy table below). Note the reference
@@ -552,6 +569,12 @@ data_cpy_table:
552569
.word __data_start__
553570
.word __data_end__
554571

572+
#if PICO_RP2040 && PICO_USE_XIP_CACHE_AS_RAM
573+
.word __xip_ram_text_source__
574+
.word __xip_ram_text_start__
575+
.word __xip_ram_text_end__
576+
#endif
577+
555578
.word __scratch_x_source__
556579
.word __scratch_x_start__
557580
.word __scratch_x_end__

0 commit comments

Comments
 (0)