summaryrefslogtreecommitdiff
path: root/introspect/src/freestanding_check.zig
diff options
context:
space:
mode:
Diffstat (limited to 'introspect/src/freestanding_check.zig')
-rw-r--r--introspect/src/freestanding_check.zig71
1 files changed, 71 insertions, 0 deletions
diff --git a/introspect/src/freestanding_check.zig b/introspect/src/freestanding_check.zig
new file mode 100644
index 0000000..ad88d0e
--- /dev/null
+++ b/introspect/src/freestanding_check.zig
@@ -0,0 +1,71 @@
+//! A tiny freestanding root proving that `core` and `vars` compile without an
+//! OS: `zig build introspect-check-freestanding` builds this for riscv32-freestanding-none.
+//! It instantiates `Server(cfg)` with static Storage/Shared, exposes one
+//! variable, and runs one push/step over a canned Tversion frame. It must not
+//! import scratch.zig (allocator) or anything OS-specific.
+const std = @import("std");
+const core = @import("core.zig");
+const Writer = std.Io.Writer;
+
+const Build = struct {
+ pub const zig_version: []const u8 = @import("builtin").zig_version_string;
+ pub const target: []const u8 = "riscv32-freestanding-none";
+ pub const optimize: []const u8 = "check";
+ pub const time: []const u8 = "1970-01-01T00:00:00Z";
+ pub const change: []const u8 = "none";
+};
+
+const State = struct { ticks: u32, phase: enum { idle, busy }, inner: struct { x: f32 } };
+
+const Fns = struct {
+ pub fn ticks(ctx: *anyopaque, w: *Writer) anyerror!void {
+ const s: *State = @ptrCast(@alignCast(ctx));
+ try w.print("{d}", .{s.ticks});
+ }
+};
+
+fn ctl(ctx: *anyopaque, cmd: []const u8, out: *Writer) anyerror!void {
+ const s: *State = @ptrCast(@alignCast(ctx));
+ if (std.mem.startsWith(u8, cmd, "reset")) s.ticks = 0;
+ try out.writeAll("ok");
+}
+
+const cfg: core.Config = .{
+ .name = "fw",
+ .build = Build,
+ .types = &.{ State, core.NodeStat },
+ .decls_of = Fns,
+ .fns = Fns,
+ .ctl = &ctl,
+ .msize = 2048,
+ .max_fids = 16,
+ .snapshot_slots = 2,
+ .snapshot_bytes = 1024,
+};
+
+const S = core.Server(cfg);
+
+var state: State = .{ .ticks = 0, .phase = .idle, .inner = .{ .x = 0 } };
+var storage: S.Storage = undefined;
+var shared: S.Shared = undefined;
+var conn: S.Conn = undefined;
+
+/// Tversion msize=2048 version="9P2000".
+const tversion = [_]u8{ 19, 0, 0, 0, 100, 0xFF, 0xFF, 0, 8, 0, 0, 6, 0, '9', 'P', '2', '0', '0', '0' };
+
+/// Runs one Tversion through the engine; returns the number of reply bytes.
+pub export fn introspect_check() u32 {
+ shared = .init(&state);
+ shared.expose("state", &state) catch unreachable;
+ conn = .init(&shared, &storage, cfg.msize);
+ _ = conn.push(&tversion);
+ _ = conn.step() catch return 0;
+ const out = conn.output();
+ conn.wrote(out.len);
+ return @intCast(out.len);
+}
+
+pub export fn _start() noreturn {
+ _ = introspect_check();
+ while (true) {}
+}