Skip to content

Instantly share code, notes, and snippets.

@punzik
Created August 18, 2023 15:32
Show Gist options
  • Save punzik/bda5ee814b39e876e14405b63d9770d6 to your computer and use it in GitHub Desktop.
Save punzik/bda5ee814b39e876e14405b63d9770d6 to your computer and use it in GitHub Desktop.
Minimal bare-metal PicoRV32 Zig example
const std = @import("std");
const CrossTarget = @import("std").zig.CrossTarget;
const Target = @import("std").Target;
const Feature = @import("std").Target.Cpu.Feature;
pub fn build(b: *std.Build) void {
const features = Target.riscv.Feature;
var disabled_features = Feature.Set.empty;
var enabled_features = Feature.Set.empty;
// Not allowed in PicoRV32
disabled_features.addFeature(@intFromEnum(features.a));
disabled_features.addFeature(@intFromEnum(features.d));
disabled_features.addFeature(@intFromEnum(features.f));
// Embedded. Not supported by llvm
disabled_features.addFeature(@intFromEnum(features.e));
// Compressed Instructions
disabled_features.addFeature(@intFromEnum(features.c));
// Integer Multiplication and Division
disabled_features.addFeature(@intFromEnum(features.m));
const target = CrossTarget{
.cpu_arch = Target.Cpu.Arch.riscv32,
.os_tag = Target.Os.Tag.freestanding,
.abi = Target.Abi.none,
.cpu_features_sub = disabled_features,
.cpu_features_add = enabled_features,
};
// const optimize = b.standardOptimizeOption(.{});
const optimize = std.builtin.OptimizeMode.ReleaseSmall;
const exe = b.addExecutable(.{
.name = "main",
.root_source_file = .{ .path = "src/main.zig" },
.target = target,
.optimize = optimize,
});
exe.setLinkerScriptPath(.{ .path = "picorv32-minimal.ld" });
b.default_step.dependOn(&exe.step);
b.installArtifact(exe);
}
export fn _start() callconv(.Naked) noreturn {
const main_ptr: fn () callconv(.C) noreturn = main;
asm volatile (
\\la sp, __stack_top
\\add s0, sp, zero
\\jal zero, %[main_func]
:
: [main_func] "i" (main_ptr),
);
}
const vptr: *volatile u32 = @ptrFromInt(0x12345670);
export fn main() noreturn {
for (0..99) |i| {
vptr.* = double(i);
}
while (true) {}
unreachable;
}
fn double(x: u32) u32 {
return x * 2;
}
MEMORY { ram (rx) : ORIGIN = 0, LENGTH = 2048 }
SECTIONS
{
. = 0x00;
.text : {
*(.init*)
*(.text*)
} > ram
.bss (NOLOAD) :
{
*(.bss*)
*(COMMON)
} > ram
.data :
{
*(.data*)
} > ram
.stack (NOLOAD) :
{
. = ORIGIN(ram) + LENGTH(ram) - 4;
. = ALIGN(4);
__stack_top = .;
} > ram
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment