From 8247719b65bc6841aabe56c3b210939690e31c8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20=27vesim=27=20Kuli=C5=84ski?= Date: Mon, 2 Feb 2026 01:46:30 +0100 Subject: [PATCH 1/4] rp2xxx: Add scratch sections --- port/raspberrypi/rp2xxx/build.zig | 29 +++++++++---------- port/raspberrypi/rp2xxx/ld/rp2040/sections.ld | 17 ++++++++++- .../ld/rp2350/arm_ram_image_sections.ld | 18 +++++++++++- .../rp2xxx/ld/rp2350/arm_sections.ld | 18 +++++++++++- .../ld/rp2350/riscv_ram_image_sections.ld | 18 +++++++++++- .../rp2xxx/ld/rp2350/riscv_sections.ld | 18 +++++++++++- port/raspberrypi/rp2xxx/src/hal.zig | 1 + port/raspberrypi/rp2xxx/src/hal/sections.zig | 2 ++ 8 files changed, 100 insertions(+), 21 deletions(-) create mode 100644 port/raspberrypi/rp2xxx/src/hal/sections.zig diff --git a/port/raspberrypi/rp2xxx/build.zig b/port/raspberrypi/rp2xxx/build.zig index 581169e83..5cf808c12 100644 --- a/port/raspberrypi/rp2xxx/build.zig +++ b/port/raspberrypi/rp2xxx/build.zig @@ -60,8 +60,10 @@ pub fn init(dep: *std.Build.Dependency) Self { .name = "RP2040", .register_definition = .{ .svd = pico_sdk.path("src/rp2040/hardware_regs/RP2040.svd") }, .memory_regions = &.{ - .{ .tag = .flash, .offset = 0x10000000, .length = 2048 * 1024, .access = .rx }, - .{ .tag = .ram, .offset = 0x20000000, .length = 256 * 1024, .access = .rwx }, + .{ .name = "FLASH", .tag = .flash, .offset = 0x10000000, .length = 2048 * 1024, .access = .rx }, + .{ .name = "RAM", .tag = .ram, .offset = 0x20000000, .length = 256 * 1024, .access = .rwx }, + .{ .name = "SCRATCH_X", .tag = .ram, .offset = 0x20040000, .length = 4 * 1024, .access = .rwx }, + .{ .name = "SCRATCH_Y", .tag = .ram, .offset = 0x20041000, .length = 4 * 1024, .access = .rwx }, }, .patch_files = &.{b.path("patches/rp2040.zon")}, }, @@ -71,6 +73,13 @@ pub fn init(dep: *std.Build.Dependency) Self { }, }; + const chip_rp2350_memory_regions = [_]microzig.MemoryRegion{ + .{ .name = "FLASH", .tag = .flash, .offset = 0x10000000, .length = 2048 * 1024, .access = .rx }, + .{ .name = "RAM", .tag = .ram, .offset = 0x20000000, .length = 512 * 1024, .access = .rwx }, + .{ .name = "SCRATCH_X", .tag = .ram, .offset = 0x20080000, .length = 4 * 1024, .access = .rwx }, + .{ .name = "SCRATCH_Y", .tag = .ram, .offset = 0x20081000, .length = 4 * 1024, .access = .rwx }, + }; + const chip_rp2350_arm: microzig.Target = .{ .dep = dep, .preferred_binary_format = .{ .uf2 = .{ @@ -86,13 +95,7 @@ pub fn init(dep: *std.Build.Dependency) Self { .chip = .{ .name = "RP2350", .register_definition = .{ .svd = pico_sdk.path("src/rp2350/hardware_regs/RP2350.svd") }, - .memory_regions = &.{ - .{ .tag = .flash, .offset = 0x10000000, .length = 2048 * 1024, .access = .rx }, - .{ .tag = .ram, .offset = 0x20000000, .length = 512 * 1024, .access = .rwx }, - // TODO: maybe these can be used for stacks - .{ .tag = .ram, .offset = 0x20080000, .length = 4 * 1024, .access = .rwx }, - .{ .tag = .ram, .offset = 0x20081000, .length = 4 * 1024, .access = .rwx }, - }, + .memory_regions = &chip_rp2350_memory_regions, .patch_files = &.{b.path("patches/rp2350.zon")}, }, .hal = hal, @@ -138,13 +141,7 @@ pub fn init(dep: *std.Build.Dependency) Self { .chip = .{ .name = "RP2350", .register_definition = .{ .svd = pico_sdk.path("src/rp2350/hardware_regs/RP2350.svd") }, - .memory_regions = &.{ - .{ .tag = .flash, .offset = 0x10000000, .length = 2048 * 1024, .access = .rx }, - .{ .tag = .ram, .offset = 0x20000000, .length = 512 * 1024, .access = .rwx }, - // TODO: maybe these can be used for stacks - .{ .tag = .ram, .offset = 0x20080000, .length = 4 * 1024, .access = .rwx }, - .{ .tag = .ram, .offset = 0x20081000, .length = 4 * 1024, .access = .rwx }, - }, + .memory_regions = &chip_rp2350_memory_regions, .patch_files = &.{ b.path("patches/rp2350.zon"), b.path("patches/rp2350_hazard3.zon"), diff --git a/port/raspberrypi/rp2xxx/ld/rp2040/sections.ld b/port/raspberrypi/rp2xxx/ld/rp2040/sections.ld index 436f923e6..6639ec9c5 100644 --- a/port/raspberrypi/rp2xxx/ld/rp2040/sections.ld +++ b/port/raspberrypi/rp2xxx/ld/rp2040/sections.ld @@ -4,10 +4,25 @@ SECTIONS __boot2_start__ = .; KEEP (*(.boot2)) __boot2_end__ = .; - } > flash0 + } > FLASH ASSERT(__boot2_end__ - __boot2_start__ == 256, "ERROR: Pico second stage bootloader must be 256 bytes in size") } INSERT BEFORE .flash_start; +SECTIONS { + .scratch_x : { + microzig_scratch_x_start = .; + *(.scratch_x.*) + . = ALIGN(4); + microzig_scratch_x_end = .; + } > SCRATCH_X AT > FLASH + + .scratch_y : { + microzig_scratch_y_start = .; + *(.scratch_y.*) + . = ALIGN(4); + microzig_scratch_y_end = .; + } > SCRATCH_Y AT > FLASH +} diff --git a/port/raspberrypi/rp2xxx/ld/rp2350/arm_ram_image_sections.ld b/port/raspberrypi/rp2xxx/ld/rp2350/arm_ram_image_sections.ld index 4513ada28..66b5aace5 100644 --- a/port/raspberrypi/rp2xxx/ld/rp2350/arm_ram_image_sections.ld +++ b/port/raspberrypi/rp2xxx/ld/rp2350/arm_ram_image_sections.ld @@ -4,6 +4,22 @@ SECTIONS { __bootmeta_start__ = .; KEEP(*(.bootmeta)) __bootmeta_end__ = .; - } > ram0 + } > RAM } INSERT AFTER .ram_start; + +SECTIONS { + .scratch_x : { + microzig_scratch_x_start = .; + *(.scratch_x.*) + . = ALIGN(4); + microzig_scratch_x_end = .; + } > SCRATCH_X AT > FLASH + + .scratch_y : { + microzig_scratch_y_start = .; + *(.scratch_y.*) + . = ALIGN(4); + microzig_scratch_y_end = .; + } > SCRATCH_Y AT > FLASH +} diff --git a/port/raspberrypi/rp2xxx/ld/rp2350/arm_sections.ld b/port/raspberrypi/rp2xxx/ld/rp2350/arm_sections.ld index 3007ad8f3..eaef93374 100644 --- a/port/raspberrypi/rp2xxx/ld/rp2350/arm_sections.ld +++ b/port/raspberrypi/rp2xxx/ld/rp2350/arm_sections.ld @@ -4,6 +4,22 @@ SECTIONS { __bootmeta_start__ = .; KEEP(*(.bootmeta)) __bootmeta_end__ = .; - } > flash0 + } > FLASH } INSERT AFTER .flash_start; + +SECTIONS { + .scratch_x : { + microzig_scratch_x_start = .; + *(.scratch_x.*) + . = ALIGN(4); + microzig_scratch_x_end = .; + } > SCRATCH_X AT > FLASH + + .scratch_y : { + microzig_scratch_y_start = .; + *(.scratch_y.*) + . = ALIGN(4); + microzig_scratch_y_end = .; + } > SCRATCH_Y AT > FLASH +} diff --git a/port/raspberrypi/rp2xxx/ld/rp2350/riscv_ram_image_sections.ld b/port/raspberrypi/rp2xxx/ld/rp2350/riscv_ram_image_sections.ld index 4513ada28..66b5aace5 100644 --- a/port/raspberrypi/rp2xxx/ld/rp2350/riscv_ram_image_sections.ld +++ b/port/raspberrypi/rp2xxx/ld/rp2350/riscv_ram_image_sections.ld @@ -4,6 +4,22 @@ SECTIONS { __bootmeta_start__ = .; KEEP(*(.bootmeta)) __bootmeta_end__ = .; - } > ram0 + } > RAM } INSERT AFTER .ram_start; + +SECTIONS { + .scratch_x : { + microzig_scratch_x_start = .; + *(.scratch_x.*) + . = ALIGN(4); + microzig_scratch_x_end = .; + } > SCRATCH_X AT > FLASH + + .scratch_y : { + microzig_scratch_y_start = .; + *(.scratch_y.*) + . = ALIGN(4); + microzig_scratch_y_end = .; + } > SCRATCH_Y AT > FLASH +} diff --git a/port/raspberrypi/rp2xxx/ld/rp2350/riscv_sections.ld b/port/raspberrypi/rp2xxx/ld/rp2350/riscv_sections.ld index 3007ad8f3..eaef93374 100644 --- a/port/raspberrypi/rp2xxx/ld/rp2350/riscv_sections.ld +++ b/port/raspberrypi/rp2xxx/ld/rp2350/riscv_sections.ld @@ -4,6 +4,22 @@ SECTIONS { __bootmeta_start__ = .; KEEP(*(.bootmeta)) __bootmeta_end__ = .; - } > flash0 + } > FLASH } INSERT AFTER .flash_start; + +SECTIONS { + .scratch_x : { + microzig_scratch_x_start = .; + *(.scratch_x.*) + . = ALIGN(4); + microzig_scratch_x_end = .; + } > SCRATCH_X AT > FLASH + + .scratch_y : { + microzig_scratch_y_start = .; + *(.scratch_y.*) + . = ALIGN(4); + microzig_scratch_y_end = .; + } > SCRATCH_Y AT > FLASH +} diff --git a/port/raspberrypi/rp2xxx/src/hal.zig b/port/raspberrypi/rp2xxx/src/hal.zig index 853cdb94d..fb2f84242 100644 --- a/port/raspberrypi/rp2xxx/src/hal.zig +++ b/port/raspberrypi/rp2xxx/src/hal.zig @@ -39,6 +39,7 @@ pub const time = @import("hal/time.zig"); pub const uart = @import("hal/uart.zig"); pub const usb = @import("hal/usb.zig"); pub const watchdog = @import("hal/watchdog.zig"); +pub const sections = @import("hal/sections.zig"); comptime { // HACK: tests can't access microzig. maybe there's a better way to do this. diff --git a/port/raspberrypi/rp2xxx/src/hal/sections.zig b/port/raspberrypi/rp2xxx/src/hal/sections.zig new file mode 100644 index 000000000..caae3d5d7 --- /dev/null +++ b/port/raspberrypi/rp2xxx/src/hal/sections.zig @@ -0,0 +1,2 @@ +pub const scratch_x = ".scratch_x"; +pub const scratch_y = ".scratch_y"; From 2d988ba3bfdfe124f0cb59ed3d2b3136be0de1e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20=27vesim=27=20Kuli=C5=84ski?= Date: Mon, 2 Feb 2026 02:27:22 +0100 Subject: [PATCH 2/4] rp2xxx: copy data to scratch sections --- core/src/utilities.zig | 16 ++++++++++++++++ port/raspberrypi/rp2xxx/ld/rp2040/sections.ld | 2 ++ .../rp2xxx/ld/rp2350/arm_ram_image_sections.ld | 2 ++ .../raspberrypi/rp2xxx/ld/rp2350/arm_sections.ld | 2 ++ .../rp2xxx/ld/rp2350/riscv_ram_image_sections.ld | 2 ++ .../rp2xxx/ld/rp2350/riscv_sections.ld | 2 ++ port/raspberrypi/rp2xxx/src/hal.zig | 2 ++ 7 files changed, 28 insertions(+) diff --git a/core/src/utilities.zig b/core/src/utilities.zig index 9bcad56bf..eec8ed3fa 100644 --- a/core/src/utilities.zig +++ b/core/src/utilities.zig @@ -40,6 +40,22 @@ pub inline fn initialize_system_memories(which: enum { @memset(bss_start[0..bss_len], 0); } + if (@hasDecl(microzig.hal, "extra_ram_load_sections")) { + inline for (microzig.hal.extra_ram_load_sections) |section_name| { + const section = struct { + const start = @extern(*anyopaque, .{ .name = std.fmt.comptimePrint("microzig_{s}_start", .{section_name}) }); + const end = @extern(*anyopaque, .{ .name = std.fmt.comptimePrint("microzig_{s}_end", .{section_name}) }); + const load_start = @extern(*anyopaque, .{ .name = std.fmt.comptimePrint("microzig_{s}_load_start", .{section_name}) }); + }; + const start: [*]u8 = @ptrCast(section.start); + const end: [*]u8 = @ptrCast(section.end); + const len = @intFromPtr(end) - @intFromPtr(start); + const src: [*]const u8 = @ptrCast(§ion.load_start); + + @memcpy(start[0..len], src[0..len]); + } + } + // load .data from flash if (which != .bss_only) { const data_start: [*]u8 = @ptrCast(§ions.microzig_data_start); diff --git a/port/raspberrypi/rp2xxx/ld/rp2040/sections.ld b/port/raspberrypi/rp2xxx/ld/rp2040/sections.ld index 6639ec9c5..edebbc5f0 100644 --- a/port/raspberrypi/rp2xxx/ld/rp2040/sections.ld +++ b/port/raspberrypi/rp2xxx/ld/rp2040/sections.ld @@ -18,6 +18,7 @@ SECTIONS { . = ALIGN(4); microzig_scratch_x_end = .; } > SCRATCH_X AT > FLASH + microzig_scratch_x_load_start = LOADADDR(.scratch_x); .scratch_y : { microzig_scratch_y_start = .; @@ -25,4 +26,5 @@ SECTIONS { . = ALIGN(4); microzig_scratch_y_end = .; } > SCRATCH_Y AT > FLASH + microzig_scratch_y_load_start = LOADADDR(.scratch_y); } diff --git a/port/raspberrypi/rp2xxx/ld/rp2350/arm_ram_image_sections.ld b/port/raspberrypi/rp2xxx/ld/rp2350/arm_ram_image_sections.ld index 66b5aace5..341a5bf16 100644 --- a/port/raspberrypi/rp2xxx/ld/rp2350/arm_ram_image_sections.ld +++ b/port/raspberrypi/rp2xxx/ld/rp2350/arm_ram_image_sections.ld @@ -15,6 +15,7 @@ SECTIONS { . = ALIGN(4); microzig_scratch_x_end = .; } > SCRATCH_X AT > FLASH + microzig_scratch_x_load_start = LOADADDR(.scratch_x); .scratch_y : { microzig_scratch_y_start = .; @@ -22,4 +23,5 @@ SECTIONS { . = ALIGN(4); microzig_scratch_y_end = .; } > SCRATCH_Y AT > FLASH + microzig_scratch_y_load_start = LOADADDR(.scratch_y); } diff --git a/port/raspberrypi/rp2xxx/ld/rp2350/arm_sections.ld b/port/raspberrypi/rp2xxx/ld/rp2350/arm_sections.ld index eaef93374..e8d7fa889 100644 --- a/port/raspberrypi/rp2xxx/ld/rp2350/arm_sections.ld +++ b/port/raspberrypi/rp2xxx/ld/rp2350/arm_sections.ld @@ -15,6 +15,7 @@ SECTIONS { . = ALIGN(4); microzig_scratch_x_end = .; } > SCRATCH_X AT > FLASH + microzig_scratch_x_load_start = LOADADDR(.scratch_x); .scratch_y : { microzig_scratch_y_start = .; @@ -22,4 +23,5 @@ SECTIONS { . = ALIGN(4); microzig_scratch_y_end = .; } > SCRATCH_Y AT > FLASH + microzig_scratch_y_load_start = LOADADDR(.scratch_y); } diff --git a/port/raspberrypi/rp2xxx/ld/rp2350/riscv_ram_image_sections.ld b/port/raspberrypi/rp2xxx/ld/rp2350/riscv_ram_image_sections.ld index 66b5aace5..341a5bf16 100644 --- a/port/raspberrypi/rp2xxx/ld/rp2350/riscv_ram_image_sections.ld +++ b/port/raspberrypi/rp2xxx/ld/rp2350/riscv_ram_image_sections.ld @@ -15,6 +15,7 @@ SECTIONS { . = ALIGN(4); microzig_scratch_x_end = .; } > SCRATCH_X AT > FLASH + microzig_scratch_x_load_start = LOADADDR(.scratch_x); .scratch_y : { microzig_scratch_y_start = .; @@ -22,4 +23,5 @@ SECTIONS { . = ALIGN(4); microzig_scratch_y_end = .; } > SCRATCH_Y AT > FLASH + microzig_scratch_y_load_start = LOADADDR(.scratch_y); } diff --git a/port/raspberrypi/rp2xxx/ld/rp2350/riscv_sections.ld b/port/raspberrypi/rp2xxx/ld/rp2350/riscv_sections.ld index eaef93374..e8d7fa889 100644 --- a/port/raspberrypi/rp2xxx/ld/rp2350/riscv_sections.ld +++ b/port/raspberrypi/rp2xxx/ld/rp2350/riscv_sections.ld @@ -15,6 +15,7 @@ SECTIONS { . = ALIGN(4); microzig_scratch_x_end = .; } > SCRATCH_X AT > FLASH + microzig_scratch_x_load_start = LOADADDR(.scratch_x); .scratch_y : { microzig_scratch_y_start = .; @@ -22,4 +23,5 @@ SECTIONS { . = ALIGN(4); microzig_scratch_y_end = .; } > SCRATCH_Y AT > FLASH + microzig_scratch_y_load_start = LOADADDR(.scratch_y); } diff --git a/port/raspberrypi/rp2xxx/src/hal.zig b/port/raspberrypi/rp2xxx/src/hal.zig index fb2f84242..94957f98f 100644 --- a/port/raspberrypi/rp2xxx/src/hal.zig +++ b/port/raspberrypi/rp2xxx/src/hal.zig @@ -145,6 +145,8 @@ pub fn get_cpu_id() u32 { return SIO.CPUID.read().CPUID; } +pub const extra_ram_load_sections = .{ "scratch_x", "scratch_y" }; + test "hal tests" { _ = pio; _ = usb; From e15a0c7b570e3882f0772236501e715359ebe88c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20=27vesim=27=20Kuli=C5=84ski?= Date: Mon, 2 Feb 2026 02:33:04 +0100 Subject: [PATCH 3/4] rp2xxx: fix rp2040 flashless scratch sections --- port/raspberrypi/rp2xxx/build.zig | 4 +++- .../rp2xxx/ld/rp2040/ram_sections.ld | 17 +++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 port/raspberrypi/rp2xxx/ld/rp2040/ram_sections.ld diff --git a/port/raspberrypi/rp2xxx/build.zig b/port/raspberrypi/rp2xxx/build.zig index 5cf808c12..00909a0bd 100644 --- a/port/raspberrypi/rp2xxx/build.zig +++ b/port/raspberrypi/rp2xxx/build.zig @@ -193,7 +193,9 @@ pub fn init(dep: *std.Build.Dependency) Self { .pico_flashless = chip_rp2040.derive(.{ .ram_image = true, // we can use the default generated linker script - .linker_script = .{}, + .linker_script = .{ + .file = b.path("ld/rp2040/ram_sections.ld"), + }, .entry = .{ .symbol_name = "_entry_point" }, .board = .{ .name = "RaspberryPi Pico (ram image)", diff --git a/port/raspberrypi/rp2xxx/ld/rp2040/ram_sections.ld b/port/raspberrypi/rp2xxx/ld/rp2040/ram_sections.ld new file mode 100644 index 000000000..344018d88 --- /dev/null +++ b/port/raspberrypi/rp2xxx/ld/rp2040/ram_sections.ld @@ -0,0 +1,17 @@ +SECTIONS { + .scratch_x : { + microzig_scratch_x_start = .; + *(.scratch_x.*) + . = ALIGN(4); + microzig_scratch_x_end = .; + } > SCRATCH_X AT > FLASH + microzig_scratch_x_load_start = LOADADDR(.scratch_x); + + .scratch_y : { + microzig_scratch_y_start = .; + *(.scratch_y.*) + . = ALIGN(4); + microzig_scratch_y_end = .; + } > SCRATCH_Y AT > FLASH + microzig_scratch_y_load_start = LOADADDR(.scratch_y); +} From d5599bdc658ef1b367311036093bad37c3685582 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20=27vesim=27=20Kuli=C5=84ski?= Date: Mon, 2 Feb 2026 02:40:13 +0100 Subject: [PATCH 4/4] core: fix no_hal builds --- core/src/utilities.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/utilities.zig b/core/src/utilities.zig index eec8ed3fa..bc43c6aa5 100644 --- a/core/src/utilities.zig +++ b/core/src/utilities.zig @@ -40,7 +40,7 @@ pub inline fn initialize_system_memories(which: enum { @memset(bss_start[0..bss_len], 0); } - if (@hasDecl(microzig.hal, "extra_ram_load_sections")) { + if (microzig.hal != void and @hasDecl(microzig.hal, "extra_ram_load_sections")) { inline for (microzig.hal.extra_ram_load_sections) |section_name| { const section = struct { const start = @extern(*anyopaque, .{ .name = std.fmt.comptimePrint("microzig_{s}_start", .{section_name}) });