Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
25 changes: 24 additions & 1 deletion core/src/cpus/cortex_m/m33.zig
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,30 @@ pub const SystemControlBlock = extern struct {
_AFSR: u32,
reserved1: [18]u32,
/// Coprocessor Access Control Register.
CPACR: u32,
CPACR: mmio.Mmio(packed struct(u32) {
CP0: Privilege,
CP1: Privilege,
CP2: Privilege,
CP3: Privilege,
CP4: Privilege,
CP5: Privilege,
CP6: Privilege,
CP7: Privilege,
reserved16: u4,
CP10: Privilege,
CP11: Privilege,
reserved24: u8,

pub const Privilege = enum(u2) {
/// Access denied. Any attempted access generates a NOCP UsageFault.
access_denied = 0b00,
/// Privileged access only. An unprivileged access generates a NOCP UsageFault.
priviledged_access_only = 0b01,
reserved = 0b10,
/// Full access.
full_access = 0b11,
};
}),
/// Non-secure Access Control Register.
NSACR: u32,
};
Expand Down
62 changes: 35 additions & 27 deletions port/raspberrypi/rp2xxx/src/hal.zig
Original file line number Diff line number Diff line change
Expand Up @@ -99,33 +99,7 @@ const is_fpu_used: bool = builtin.abi.float() == .hard;
/// Allows user to easily swap in their own clock config while still
/// using the recommended initialization sequence
pub fn init_sequence(comptime clock_cfg: clocks.config.Global) void {
if (compatibility.chip == .RP2350 and
compatibility.arch == .arm)
{
var cpacr: u32 = microzig.cpu.peripherals.scb.CPACR;

if (microzig.options.hal.enable_fpu) {
if (is_fpu_used) {
// enable lazy state preservation
microzig.cpu.peripherals.fpu.FPCCR.modify(.{
.ASPEN = 1,
.LSPEN = 1,
});

// enable the FPU
cpacr |= 0xF << 20;
} else {
@compileError("target doesn't have FPU features enabled");
}
}

if (microzig.options.hal.use_dcp) {
// enable the DCP
cpacr |= 0b11 << 8;
}

microzig.cpu.peripherals.scb.CPACR = cpacr;
}
maybe_enable_fpu_and_dcp();

// Disable the watchdog as a soft reset doesn't disable the WD automatically!
watchdog.disable();
Expand Down Expand Up @@ -155,6 +129,40 @@ pub fn init_sequence(comptime clock_cfg: clocks.config.Global) void {
resets.unreset_block_wait(resets.masks.all);
}

/// Enables fpu and/or dcp on RP2350 arm if requested in HAL options. On RP2350
/// riscv and RP2040 this is a noop. Called in init_sequence and on core1
/// startup.
pub fn maybe_enable_fpu_and_dcp() void {
if (compatibility.chip == .RP2350 and
compatibility.arch == .arm)
{
if (microzig.options.hal.enable_fpu) {
if (is_fpu_used) {
// enable lazy state preservation
microzig.cpu.peripherals.fpu.FPCCR.modify(.{
.ASPEN = 1,
.LSPEN = 1,
});

// enable the FPU for the current core
microzig.cpu.peripherals.scb.CPACR.modify(.{
.CP10 = .full_access,
.CP11 = .full_access,
});
} else {
@compileError("target doesn't have FPU features enabled");
}
}

if (microzig.options.hal.use_dcp) {
// enable the DCP for the current core
microzig.cpu.peripherals.scb.CPACR.modify(.{
.CP4 = .full_access,
});
}
}
}

pub fn get_cpu_id() u32 {
return SIO.CPUID.read().CPUID;
}
Expand Down
1 change: 1 addition & 0 deletions port/raspberrypi/rp2xxx/src/hal/multicore.zig
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ pub fn launch_core1_with_stack(entrypoint: *const fn () void, stack: []u32) void
fn _wrapper(_: u32, _: u32, _: u32, _: u32, entry: u32, stack_base: [*]u32) callconv(.c) void {
// TODO: protect stack using MPU
_ = stack_base;
microzig.hal.maybe_enable_fpu_and_dcp();
@as(*const fn () void, @ptrFromInt(entry))();
}
}._wrapper;
Expand Down
Loading