commit 1441f5976f96cf2dc1f6e1390fd1b4b0cd4c4565
parent dd7daaeae78b52f9355f0442629ff0920695896f
Author: Sylvia Ivory <git@sivory.net>
Date: Wed, 14 Jan 2026 22:43:50 -0800
Enable fake-pi on labs
Diffstat:
4 files changed, 35 insertions(+), 43 deletions(-)
diff --git a/build.zig b/build.zig
@@ -1,6 +1,8 @@
const std = @import("std");
const config = @import("build.zig.zon");
+const add_exe_ty = *const fn (exe_name: []const u8, path: std.Build.LazyPath, b: *std.Build) anyerror!*std.Build.Step.Compile;
+
fn add_exe_fake_pi(exe_name: []const u8, path: std.Build.LazyPath, b: *std.Build) !*std.Build.Step.Compile {
const pi = b.createModule(.{
.root_source_file = path,
@@ -30,7 +32,7 @@ fn add_exe_fake_pi(exe_name: []const u8, path: std.Build.LazyPath, b: *std.Build
return exe;
}
-fn add_exe(exe_name: []const u8, path: std.Build.LazyPath, b: *std.Build) !*std.Build.Step.Compile {
+fn add_exe_real(exe_name: []const u8, path: std.Build.LazyPath, b: *std.Build) !*std.Build.Step.Compile {
var cpu_features = std.Target.arm.cpu.arm1176jzf_s.features;
cpu_features.addFeatureSet(std.Target.arm.featureSet(&[_]std.Target.arm.Feature{.strict_align}));
@@ -44,22 +46,24 @@ fn add_exe(exe_name: []const u8, path: std.Build.LazyPath, b: *std.Build) !*std.
// BCM2835 is **very specifically** the ARM1176JZF-S
// https://www.raspberrypi.com/documentation/computers/processors.html
+ const pi = b.createModule(.{
+ .root_source_file = path,
+ .target = b.resolveTargetQuery(target),
+ .optimize = .ReleaseSafe,
+ .unwind_tables = .none,
+ .single_threaded = true,
+ .error_tracing = false,
+ .link_libc = false,
+ .no_builtin = true,
+ });
+ pi.addAssemblyFile(b.path("start.s"));
+
const exe = b.addExecutable(.{
.name = exe_name,
.linkage = .static,
- .root_module = b.createModule(.{
- .root_source_file = path,
- .target = b.resolveTargetQuery(target),
- .optimize = .ReleaseSafe,
- .unwind_tables = .none,
- .single_threaded = true,
- .error_tracing = false,
- .link_libc = false,
- .no_builtin = true,
- }),
+ .root_module = pi,
});
exe.setLinkerScript(b.path("linker.ld"));
- exe.addAssemblyFile(b.path("start.s"));
const asm_name = try std.fmt.allocPrint(b.allocator, "{s}.s", .{exe_name});
defer b.allocator.free(asm_name);
@@ -72,7 +76,7 @@ fn add_exe(exe_name: []const u8, path: std.Build.LazyPath, b: *std.Build) !*std.
return exe;
}
-fn lab(name: []const u8, units: []const []const u8, b: *std.Build) !void {
+fn lab(name: []const u8, units: []const []const u8, b: *std.Build, add_exe: add_exe_ty) !void {
for (units) |unit| {
const exe_name = try std.fmt.allocPrint(b.allocator, "{s}_{s}.elf", .{ name, unit });
defer b.allocator.free(exe_name);
@@ -83,7 +87,10 @@ fn lab(name: []const u8, units: []const []const u8, b: *std.Build) !void {
const template =
\\ const lab = @import("{s}");
\\ export fn abort() void {{ while(true) {{}} }}
- \\ pub export fn kmain() void {{ _ = lab.{s}() catch {{}}; }}
+ \\ pub export fn kmain() void {{
+ \\ @import("devices/gpio.zig").initialize(0x2000_0000);
+ \\ _ = lab.{s}() catch {{}};
+ \\ }}
;
const root_src = try std.fmt.allocPrint(b.allocator, template, .{ lab_path, unit });
@@ -116,9 +123,9 @@ fn lab(name: []const u8, units: []const []const u8, b: *std.Build) !void {
}
}
-fn handle_lab(name: []const u8, b: *std.Build) !void {
+fn handle_lab(name: []const u8, b: *std.Build, add_exe: add_exe_ty) !void {
if (std.mem.eql(u8, name, "2-gpio")) {
- try lab(name, &.{ "blink_1", "blink_2", "loopback", "act_blink", "all" }, b);
+ try lab(name, &.{ "blink_1", "blink_2", "loopback", "act_blink", "all" }, b, add_exe);
} else {
@panic("invalid lab name");
}
@@ -126,15 +133,13 @@ fn handle_lab(name: []const u8, b: *std.Build) !void {
pub fn build(b: *std.Build) !void {
const fake_pi = b.option(bool, "fake-pi", "build with fake-pi");
+ const add_exe = if (fake_pi orelse false) &add_exe_fake_pi else &add_exe_real;
+
const lab_opt = b.option([]const u8, "lab", "compile specific lab");
if (lab_opt) |lab_name| {
- try handle_lab(lab_name, b);
+ try handle_lab(lab_name, b, add_exe);
}
- if (fake_pi orelse false) {
- _ = try add_exe_fake_pi(@tagName(config.name), b.path("src/root.zig"), b);
- } else {
- _ = try add_exe(@tagName(config.name), b.path("src/root.zig"), b);
- }
+ _ = try add_exe(@tagName(config.name), b.path("src/root.zig"), b);
}
diff --git a/fake-pi/root.zig b/fake-pi/root.zig
@@ -40,3 +40,5 @@ export fn put_u32(address: *u32, value: u32) void {
},
}
}
+
+export fn nop() void {}
diff --git a/src/util.zig b/src/util.zig
@@ -2,21 +2,6 @@ pub extern fn nop() void;
pub extern fn get_u32(address: *u32) u32;
pub extern fn put_u32(address: *u32, value: u32) void;
-// pub inline fn get_u32(address: *u32) u32 {
-// return asm volatile ("ldr %[result], [%[address]]"
-// : [result] "=r" (-> u32),
-// : [address] "r" (address),
-// );
-// }
-
-// pub inline fn put_u32(address: *u32, value: u32) void {
-// asm volatile ("str %[value], [%[address]]"
-// :
-// : [address] "r" (address),
-// [value] "r" (value),
-// );
-// }
-
pub noinline fn delay_cycles(ticks: usize) void {
var counter = ticks;
while (counter > 0) {
diff --git a/start.s b/start.s
@@ -12,16 +12,16 @@ _start:
nop:
bx lr
-.global put_32
-.type _start, function
+.global put_u32
+.type put_u32, function
.align 8
-put_32:
+put_u32:
str r1,[r0]
bx lr
-.global get_32
-.type _start, function
+.global get_u32
+.type get_u32, function
.align 8
-get_32:
+get_u32:
ldr r0,[r0]
bx lr