Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,7 @@ pub fn MicroBuild(port_select: PortSelect) type {
.chip_name = target.chip.name,
.memory_regions = target.chip.memory_regions,
.generate = linker_script_options.generate,
.ram_image = target.ram_image,
};

const args_str = std.json.stringifyAlloc(
Expand Down
14 changes: 7 additions & 7 deletions core/src/cpus/cortex_m.zig
Original file line number Diff line number Diff line change
Expand Up @@ -591,7 +591,7 @@ pub const startup_logic = struct {
extern var microzig_bss_end: u8;
extern const microzig_data_load_start: u8;

pub fn ram_image_entrypoint() linksection(".entry") callconv(.naked) void {
pub fn ram_image_entrypoint() linksection("microzig_ram_start") callconv(.naked) void {
asm volatile (
\\
// Set VTOR to point to ram table
Expand Down Expand Up @@ -687,17 +687,17 @@ pub fn export_startup_logic() void {
@export(&startup_logic.ram_image_entrypoint, .{
.name = "_entry_point",
.linkage = .strong,
})
else
@export(&startup_logic._vector_table, .{
.name = "_vector_table",
.section = "microzig_flash_start",
.linkage = .strong,
});

@export(&startup_logic._start, .{
.name = "_start",
});

@export(&startup_logic._vector_table, .{
.name = "_vector_table",
.section = "microzig_flash_start",
.linkage = .strong,
});
}

const scs_base = 0xE000E000;
Expand Down
2 changes: 2 additions & 0 deletions examples/raspberrypi/rp2xxx/build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ pub fn build(b: *std.Build) void {
.{ .target = raspberrypi.pico, .name = "pico_pcf8574", .file = "src/rp2040_only/pcf8574.zig" },
.{ .target = raspberrypi.pico, .name = "pico_i2c_slave", .file = "src/rp2040_only/i2c_slave.zig" },
.{ .target = raspberrypi.pico_flashless, .name = "pico_flashless_blinky", .file = "src/blinky.zig" },
.{ .target = raspberrypi.pico2_arm_flashless, .name = "pico2_arm_flashless_blinky", .file = "src/blinky.zig" },
.{ .target = raspberrypi.pico2_riscv_flashless, .name = "pico2_riscv_flashless_blinky", .file = "src/blinky.zig" },

.{ .target = raspberrypi.pico2_arm, .name = "pico2_arm_random_data", .file = "src/rp2350_only/random_data.zig" },
.{ .target = raspberrypi.pico2_riscv, .name = "pico2_riscv_random_data", .file = "src/rp2350_only/random_data.zig" },
Expand Down
30 changes: 27 additions & 3 deletions port/raspberrypi/rp2xxx/build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ boards: struct {
pico: *const microzig.Target,
pico_flashless: *const microzig.Target,
pico2_arm: *const microzig.Target,
pico2_arm_flashless: *const microzig.Target,
pico2_riscv: *const microzig.Target,
pico2_riscv_flashless: *const microzig.Target,
},
waveshare: struct {
rp2040_plus_4m: *const microzig.Target,
Expand Down Expand Up @@ -175,13 +177,13 @@ pub fn init(dep: *std.Build.Dependency) Self {
},
}),
.pico_flashless = chip_rp2040.derive(.{
.entry = .{ .symbol_name = "_entry_point" },
.linker_script = .{ .generate = .none, .file = b.path("ld/rp2040/ram_image_linker.ld") },
.ram_image = true,
// we can use the default generated linker script
.linker_script = .{},
.board = .{
.name = "RaspberryPi Pico (ram image)",
.url = "https://www.raspberrypi.com/products/raspberry-pi-pico/",
.root_source_file = b.path("src/boards/raspberry_pi_pico2.zig"),
.root_source_file = b.path("src/boards/raspberry_pi_pico_flashless.zig"),
},
}),
.pico2_arm = chip_rp2350_arm.derive(.{
Expand All @@ -191,13 +193,35 @@ pub fn init(dep: *std.Build.Dependency) Self {
.root_source_file = b.path("src/boards/raspberry_pi_pico2.zig"),
},
}),
.pico2_arm_flashless = chip_rp2350_arm.derive(.{
.ram_image = true,
.linker_script = .{
.file = b.path("ld/rp2350/arm_ram_image_sections.ld"),
},
.board = .{
.name = "RaspberryPi Pico 2 (ram image)",
.url = "https://www.raspberrypi.com/products/raspberry-pi-pico2/",
.root_source_file = b.path("src/boards/raspberry_pi_pico2.zig"),
},
}),
.pico2_riscv = chip_rp2350_riscv.derive(.{
.board = .{
.name = "RaspberryPi Pico 2",
.url = "https://www.raspberrypi.com/products/raspberry-pi-pico2/",
.root_source_file = b.path("src/boards/raspberry_pi_pico2.zig"),
},
}),
.pico2_riscv_flashless = chip_rp2350_riscv.derive(.{
.ram_image = true,
.linker_script = .{
.file = b.path("ld/rp2350/riscv_ram_image_sections.ld"),
},
.board = .{
.name = "RaspberryPi Pico 2 (ram image)",
.url = "https://www.raspberrypi.com/products/raspberry-pi-pico2/",
.root_source_file = b.path("src/boards/raspberry_pi_pico2.zig"),
},
}),
},
.waveshare = .{
.rp2040_plus_4m = chip_rp2040.derive(.{
Expand Down
47 changes: 0 additions & 47 deletions port/raspberrypi/rp2xxx/ld/rp2040/ram_image_linker.ld

This file was deleted.

18 changes: 18 additions & 0 deletions port/raspberrypi/rp2xxx/ld/rp2350/arm_ram_image_sections.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
SECTIONS {
.bootmeta :
{
__bootmeta_start__ = .;
KEEP(*(.bootmeta))
__bootmeta_end__ = .;
} > ram0
}
INSERT AFTER .ram_start;

SECTIONS {
.ram_vectors (NOLOAD) :
{
KEEP(*(ram_vectors))
} > ram0
}
INSERT AFTER .bss;

23 changes: 23 additions & 0 deletions port/raspberrypi/rp2xxx/ld/rp2350/riscv_ram_image_sections.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
SECTIONS {
.bootmeta :
{
__bootmeta_start__ = .;
KEEP(*(.bootmeta))
__bootmeta_end__ = .;
} > ram0

.vectors :
{
KEEP(*(core_vectors))
} > ram0
}
INSERT AFTER .ram_start;

SECTIONS {
.ram_vectors (NOLOAD) :
{
KEEP(*(ram_vectors))
} > ram0
}
INSERT AFTER .bss;

2 changes: 1 addition & 1 deletion port/raspberrypi/rp2xxx/ld/rp2350/riscv_sections.ld
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ SECTIONS {
INSERT AFTER .flash_start;

SECTIONS {
.ram_vectors (NOLOAD) :
.ram_vectors (NOLOAD) :
{
KEEP(*(ram_vectors))
} > ram0
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub const xosc_freq = 12_000_000;
11 changes: 8 additions & 3 deletions port/raspberrypi/rp2xxx/src/cpus/hazard3.zig
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,10 @@ var ram_vectors: [vector_count]Handler = undefined;
pub const startup_logic = struct {
extern fn microzig_main() noreturn;

pub export fn _start() linksection("microzig_flash_start") callconv(.naked) noreturn {
pub export fn _start() linksection(if (microzig.config.ram_image)
"microzig_ram_start"
else
"microzig_flash_start") callconv(.naked) noreturn {
asm volatile (
\\.option push
\\.option norelax
Expand Down Expand Up @@ -199,7 +202,9 @@ pub const startup_logic = struct {
}

pub export fn _start_c() callconv(.c) noreturn {
root.initialize_system_memories();
if (!microzig.config.ram_image) {
root.initialize_system_memories();
}

// Move vector table to RAM if requested
if (interrupt.has_ram_vectors()) {
Expand Down Expand Up @@ -316,7 +321,7 @@ pub fn export_startup_logic() void {

@export(&startup_logic.external_interrupt_table, .{
.name = "_external_interrupt_table",
.section = "flash_vectors",
.section = if (!microzig.config.ram_image) "flash_vectors" else null,
.linkage = .strong,
});
}
Expand Down
16 changes: 12 additions & 4 deletions port/raspberrypi/rp2xxx/src/hal.zig
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ pub const watchdog = @import("hal/watchdog.zig");
pub const cyw49_pio_spi = @import("hal/cyw43_pio_spi.zig");
pub const drivers = @import("hal/drivers.zig");
pub const compatibility = @import("hal/compatibility.zig");
pub const image_def = @import("hal/image_def.zig");
pub const bootmeta = @import("hal/bootmeta.zig");

comptime {
// HACK: tests can't access microzig. maybe there's a better way to do this.
if (!builtin.is_test and compatibility.chip == .RP2350) {
_ = image_def;
_ = bootmeta;
}

// On the RP2040, we need to import the `atomic.zig` file to export some global
Expand All @@ -46,8 +46,16 @@ comptime {
}
}

pub const HAL_Options = struct {
image_def_security: image_def.Security = .secure,
pub const HAL_Options = switch (compatibility.chip) {
.RP2040 => struct {},
.RP2350 => struct {
image_def_exe_security: bootmeta.ImageDef.ImageTypeFlags.ExeSecurity = .secure,

/// Next metadata block to link after image_def. **Last block in the
/// chain must link back to the first one** (to
/// `bootmeta.image_def_block`).
next_metadata_block: ?*const anyopaque = null,
},
};

/// A default clock configuration with sensible defaults that will work
Expand Down
111 changes: 111 additions & 0 deletions port/raspberrypi/rp2xxx/src/hal/bootmeta.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/// Documentation taken from section 5.9.5.1 of the rp2350 datasheet.
const std = @import("std");
const root = @import("root");
const microzig = @import("microzig");
const arch = @import("compatibility.zig").arch;

pub const image_def_block: Block(extern struct {
image_def: ImageDef,
entry_point: EntryPoint(false),
}) = .{
.items = .{
.image_def = .{
.image_type_flags = .{
.image_type = .exe,
.exe_security = root.microzig_options.hal.image_def_exe_security,
.cpu = std.meta.stringToEnum(ImageDef.ImageTypeFlags.Cpu, @tagName(arch)).?,
.chip = .RP2350,
.try_before_you_buy = false,
},
},
.entry_point = .{
.entry = if (microzig.config.ram_image and arch == .arm)
&microzig.cpu.startup_logic.ram_image_entrypoint
else
&microzig.cpu.startup_logic._start,
.sp = microzig.config.end_of_stack,
},
},
.link = root.microzig_options.hal.next_metadata_block,
};

comptime {
@export(&image_def_block, .{
.name = "_image_def_block",
.section = ".bootmeta",
.linkage = .strong,
});
}

pub fn Block(Items: type) type {
return extern struct {
header: u32 = 0xffffded3,
items: Items,
last_item: u32 = 0x000000ff | ((@sizeOf(Items) / 4) << 8),
link: ?*const anyopaque = null,
footer: u32 = 0xab123579,
};
}

pub const ImageDef = packed struct {
item_type: u8 = 0x42,
block_size: u8 = 0x01,
image_type_flags: ImageTypeFlags,

pub const ImageTypeFlags = packed struct {
image_type: ImageType,
exe_security: ExeSecurity,
reserved0: u2 = 0,
cpu: Cpu,
reserved1: u1 = 0,
chip: Chip,
try_before_you_buy: bool,

pub const ImageType = enum(u4) {
invalid = 0,
exe = 1,
data = 2,
};

pub const ExeSecurity = enum(u2) {
unspecified = 0,
non_secure = 1,
secure = 2,
};

pub const Cpu = enum(u3) {
arm = 0,
riscv = 1,
};

pub const Chip = enum(u3) {
RP2040 = 0,
RP2350 = 1,
};
};
};

pub fn EntryPoint(with_stack_limit: bool) type {
if (with_stack_limit) {
return extern struct {
header: packed struct {
item_type: u8 = 0x44,
block_size: u8 = 0x04,
padding: u16 = 0,
} = .{},
entry: *const anyopaque,
sp: u32,
sp_limit: u32,
};
} else {
return extern struct {
header: packed struct {
item_type: u8 = 0x44,
block_size: u8 = 0x03,
padding: u16 = 0,
} = .{},
entry: *const anyopaque,
sp: u32,
};
}
}
Loading
Loading