diff --git a/core/src/utilities.zig b/core/src/utilities.zig index 9bcad56bf..bc43c6aa5 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 (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}) }); + 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/build.zig b/port/raspberrypi/rp2xxx/build.zig index 581169e83..00909a0bd 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"), @@ -196,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); +} diff --git a/port/raspberrypi/rp2xxx/ld/rp2040/sections.ld b/port/raspberrypi/rp2xxx/ld/rp2040/sections.ld index 436f923e6..edebbc5f0 100644 --- a/port/raspberrypi/rp2xxx/ld/rp2040/sections.ld +++ b/port/raspberrypi/rp2xxx/ld/rp2040/sections.ld @@ -4,10 +4,27 @@ 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 + 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); +} 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..341a5bf16 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,24 @@ 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 + 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); +} diff --git a/port/raspberrypi/rp2xxx/ld/rp2350/arm_sections.ld b/port/raspberrypi/rp2xxx/ld/rp2350/arm_sections.ld index 3007ad8f3..e8d7fa889 100644 --- a/port/raspberrypi/rp2xxx/ld/rp2350/arm_sections.ld +++ b/port/raspberrypi/rp2xxx/ld/rp2350/arm_sections.ld @@ -4,6 +4,24 @@ 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 + 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); +} 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..341a5bf16 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,24 @@ 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 + 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); +} diff --git a/port/raspberrypi/rp2xxx/ld/rp2350/riscv_sections.ld b/port/raspberrypi/rp2xxx/ld/rp2350/riscv_sections.ld index 3007ad8f3..e8d7fa889 100644 --- a/port/raspberrypi/rp2xxx/ld/rp2350/riscv_sections.ld +++ b/port/raspberrypi/rp2xxx/ld/rp2350/riscv_sections.ld @@ -4,6 +4,24 @@ 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 + 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); +} diff --git a/port/raspberrypi/rp2xxx/src/hal.zig b/port/raspberrypi/rp2xxx/src/hal.zig index 853cdb94d..94957f98f 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. @@ -144,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; 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";