From 0cdb6d555d966aadac98bb968961c6258cd7ffb7 Mon Sep 17 00:00:00 2001 From: Theo Paris Date: Mon, 5 Oct 2026 16:00:47 -0700 Subject: [PATCH] feat: use zig 0.17 --- build.zig | 6 +-- build.zig.zon | 8 ++-- flake.lock | 6 +-- flake.nix | 5 ++- pkgs/weir/default.nix | 10 ++--- src/acpi/acpi.zig | 2 +- src/acpi/qemu.zig | 2 +- src/block/block.zig | 2 +- src/boot/manager.zig | 2 +- src/fs/fat.zig | 2 +- src/fsbl/ddr_train.zig | 12 +++--- src/loader/pe.zig | 6 +-- src/sbi/ipi.zig | 2 +- src/tpm/tcg2.zig | 14 +++---- src/tpm/tpm.zig | 2 +- src/uefi/blockio.zig | 12 +++--- src/uefi/simplefs.zig | 24 +++++------ src/uefi/uefi.zig | 93 +++++++++++++++++++++--------------------- tools/fdt_bases.zig | 2 +- 19 files changed, 108 insertions(+), 104 deletions(-) diff --git a/build.zig b/build.zig index 8433262..054c0ee 100644 --- a/build.zig +++ b/build.zig @@ -169,7 +169,7 @@ pub fn build(b: *std.Build) void { b.getInstallStep().dependOn(&install_elf.step); // Flat image for `-bios`. - const bin = exe.addObjCopy(.{ .format = .bin }); + const bin = exe.addObjCopy(.{ .format = .binary }); const install_bin = b.addInstallBinFile(bin.getOutput(), "weir-firmware.bin"); b.getInstallStep().dependOn(&install_bin.step); @@ -239,7 +239,7 @@ pub fn build(b: *std.Build) void { "-bios", }); run.addFileArg(bin.getOutput()); - if (b.args) |args| run.addArgs(args); + run.addPassthruArgs(); const qemu_step = b.step("qemu", "Boot Weir under qemu-system-riscv64 -machine virt"); qemu_step.dependOn(&run.step); @@ -281,7 +281,7 @@ pub fn build(b: *std.Build) void { fexe.entry = .{ .symbol_name = "_start" }; fexe.setLinkerScript(genLd(b, ld_gen, dtb_path, "fsbl", null)); - const fbin = fexe.addObjCopy(.{ .format = .bin }); + const fbin = fexe.addObjCopy(.{ .format = .binary }); const finstall = b.addInstallBinFile(fbin.getOutput(), "weir-fsbl.bin"); b.getInstallStep().dependOn(&finstall.step); diff --git a/build.zig.zon b/build.zig.zon index b7eb76f..eec8c6d 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -5,12 +5,12 @@ .minimum_zig_version = "0.16.0", .dependencies = .{ .conduit = .{ - .url = "git+https://git.lilithsemi.com/LilithSemi/conduit.git#cb9b7130b72b71001cb4347e11b0b383c0fbcdc4", - .hash = "conduit-0.1.0-R_mFrINUBQDxhZBhJcDJ9Jxw0Wsxo3iTZl6rKdR-o7QF", + .url = "git+https://git.lilithsemi.com/LilithSemi/conduit#ee4577536650baccafef031bfd6805df2a396f3f", + .hash = "conduit-0.1.0-R_mFrINSBQDBumznUsVwExYHXxmSKd_o7ensGtl0UwEI", }, .dtree = .{ - .url = "git+https://git.lilithsemi.com/LilithSemi/dtree.git#1a37e566bb82194acfd7d7d5514615fe4fe13c68", - .hash = "dtree-0.1.0-76to8Fy8AADLnQuIRRFtYugky-X4UAtcO74DyS_9Tmp3", + .url = "git+https://git.lilithsemi.com/LilithSemi/dtree#63fe0a7292ca2df829bc3d66d86291416c657cd7", + .hash = "dtree-0.1.0-76to8F7kAAD-G7jPybrgZuWwvRQV8SmMXQilS86JCIpA", }, }, .paths = .{""}, diff --git a/flake.lock b/flake.lock index 0e19b9b..434bc15 100644 --- a/flake.lock +++ b/flake.lock @@ -35,11 +35,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1780867909, - "narHash": "sha256-+oY3E1qhi9Ar7xH8bBZevKwVP53aWWkE4ao5uRyKdaE=", + "lastModified": 1791242001, + "narHash": "sha256-GtmV90UcEWX9ieqpJqjM9NpT9kudYYh1XVwZZy+23Ns=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "7ca07f132f8b88d8fe5a427b7959964a893ba17e", + "rev": "950252d741a894b87d3891ecea7bff97b7834c54", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 3804648..74eea81 100644 --- a/flake.nix +++ b/flake.nix @@ -58,7 +58,10 @@ treefmt.programs = { nixfmt.enable = true; - zig.enable = true; + zig = { + enable = true; + package = pkgs.zig_0_17; + }; }; overlayAttrs = { diff --git a/pkgs/weir/default.nix b/pkgs/weir/default.nix index 146542e..8c46bde 100644 --- a/pkgs/weir/default.nix +++ b/pkgs/weir/default.nix @@ -2,7 +2,7 @@ lib, stdenv, mkShell, - zig, + zig_0_17, qemu, flakever, }: @@ -12,13 +12,13 @@ stdenv.mkDerivation (finalAttrs: { src = lib.cleanSource ../../.; - zigDeps = zig.fetchDeps { + zigDeps = zig_0_17.fetchDeps { inherit (finalAttrs) src pname version; - hash = "sha256-YY+Uyg3qUQ4Rdf68/Ur7FkDd6DIBEAJ0IlRKQazNFEk="; + hash = "sha256-lS//HnBMruyFPHLm6AsOViLbwhfV42ABIyF1yNZw8ls="; }; nativeBuildInputs = [ - zig + zig_0_17 ]; postConfigure = '' @@ -29,7 +29,7 @@ stdenv.mkDerivation (finalAttrs: { name = "weir-dev-shell"; packages = [ - zig + zig_0_17 qemu ]; }; diff --git a/src/acpi/acpi.zig b/src/acpi/acpi.zig index 71102e1..03c1e2a 100644 --- a/src/acpi/acpi.zig +++ b/src/acpi/acpi.zig @@ -27,7 +27,7 @@ pub fn setup(dsdt: ?[]const u8) void { /// SPCR body (after the 36-byte SDT header): a full-16550 console at `uart_base`, /// byte-wide registers, 115200 8N1, polled. fn spcrBody(uart_base: u64) [44]u8 { - var b = [_]u8{0} ** 44; + var b: [44]u8 = @splat(0); b[0] = 0x00; // interface type: full 16550 b[4] = 0x00; // base address GAS: system memory b[5] = 8; // register bit width diff --git a/src/acpi/qemu.zig b/src/acpi/qemu.zig index 8f7ef11..7679a36 100644 --- a/src/acpi/qemu.zig +++ b/src/acpi/qemu.zig @@ -23,7 +23,7 @@ var pool_next: usize = POOL_BASE; var rsdp_addr: usize = 0; const Blob = struct { - name: [56]u8 = [_]u8{0} ** 56, + name: [56]u8 = @splat(0), name_len: usize = 0, buf: []u8 = &.{}, }; diff --git a/src/block/block.zig b/src/block/block.zig index 16a76a0..8598788 100644 --- a/src/block/block.zig +++ b/src/block/block.zig @@ -18,7 +18,7 @@ pub const Partition = struct { /// 1-based partition number and the GPT unique partition GUID, used to build /// the Hard Drive device path node so a bootloader can match its boot volume. number: u32 = 1, - signature: [16]u8 = .{0} ** 16, + signature: [16]u8 = @splat(0), pub fn blockSize(self: *const Partition) u32 { return self.dev.block_size; diff --git a/src/boot/manager.zig b/src/boot/manager.zig index a071e90..611ad66 100644 --- a/src/boot/manager.zig +++ b/src/boot/manager.zig @@ -91,7 +91,7 @@ fn tryDevice(sd: storage.Device, i: usize, buf: []u8) ?pe.Loaded { // boot media (controller kind + MMIO base), so the ESP handle carries a // distinct path a bootloader can match, then publish the ESP via Simple File // System so the loaded bootloader reads its config, kernel, and initrd. - blockio.setBootMedia(@intFromEnum(sd.kind), sd.base); + blockio.setBootMedia(@backingInt(sd.kind), sd.base); if (handledb.create()) |h| { if (simplefs.install(h, part)) console.out.writeAll("[boot] ESP published via Simple File System\n") catch {}; diff --git a/src/fs/fat.zig b/src/fs/fat.zig index 1072619..508e830 100644 --- a/src/fs/fat.zig +++ b/src/fs/fat.zig @@ -275,7 +275,7 @@ fn readChain(s: *State, start_cluster: u32, size: u32, buf: []u8) ?usize { pub const Loc = struct { root16: bool, cluster: u32 }; pub const DirEnt = struct { - name: [256]u16 = [_]u16{0} ** 256, // UTF-16, null-terminated + name: [256]u16 = @splat(0), // UTF-16, null-terminated name_units: usize = 0, // including the null cluster: u32 = 0, size: u32 = 0, diff --git a/src/fsbl/ddr_train.zig b/src/fsbl/ddr_train.zig index e06d8b0..4601b40 100644 --- a/src/fsbl/ddr_train.zig +++ b/src/fsbl/ddr_train.zig @@ -80,7 +80,7 @@ pub const KnobFeedback = enum { /// One tunable PHY delay, taken from a `knob@N` node in the device tree. pub const Knob = struct { - name_buf: [NAME_CAP]u8 = [_]u8{0} ** NAME_CAP, + name_buf: [NAME_CAP]u8 = @splat(0), name_len: usize = 0, /// Register byte offset inside the window. reg: u32 = 0, @@ -103,7 +103,7 @@ pub const TrainDesc = struct { train_base: u64 = 0, stride: u32 = 8, lanes: u32 = 0, - knobs: [MAX_KNOBS]Knob = [_]Knob{.{}} ** MAX_KNOBS, + knobs: [MAX_KNOBS]Knob = @splat(.{}), knob_count: usize = 0, rows: u32 = 0, cols: u32 = 0, @@ -396,7 +396,7 @@ fn widestCenter(pass: []const bool, min: u32, max: u32) SweepResult { /// so the engine can set any tap directly. Return the centre of the widest passing /// window. fn sweepAbsolute(a: SweepArgs) SweepResult { - var pass = [_]bool{false} ** 33; // taps 0..31 plus a guard slot + var pass: [33]bool = @splat(false); // taps 0..31 plus a guard slot const mask = sliceMask(a.d, a.knob, a.slice); var tap = a.knob.min; var pass_count: u32 = 0; @@ -423,7 +423,7 @@ fn advanceOne(d: *const TrainDesc, knob: *const Knob, lane: u32) void { /// absolute count, so the engine steps it forward and checks each count. The count /// range wraps at max+1. The sweep assumes the level starts at 0. fn sweepAdvance(a: SweepArgs) SweepResult { - var pass = [_]bool{false} ** 9; // counts 0..7 plus a guard slot + var pass: [9]bool = @splat(false); // counts 0..7 plus a guard slot const mask = sliceMask(a.d, a.knob, a.slice); const span = a.knob.max + 1; // the wrap period, e.g. 8 for a 3-bit slip var pass_count: u32 = 0; @@ -585,7 +585,7 @@ test "parseTrainingNode reads the creek runtime training node" { test "widestCenter picks the centre of the widest run" { // Two runs: 1..2 (width 2) and 5..8 (width 4). The wider run wins. - var pass = [_]bool{false} ** 33; + var pass: [33]bool = @splat(false); pass[1] = true; pass[2] = true; pass[5] = true; @@ -598,7 +598,7 @@ test "widestCenter picks the centre of the widest run" { } test "widestCenter reports no window when nothing passes" { - const pass = [_]bool{false} ** 33; + const pass: [33]bool = @splat(false); const res = widestCenter(pass[0..], 0, 31); try std.testing.expect(!res.found); } diff --git a/src/loader/pe.zig b/src/loader/pe.zig index 17029bd..6c95a0f 100644 --- a/src/loader/pe.zig +++ b/src/loader/pe.zig @@ -42,7 +42,7 @@ pub fn sizeOf(image: []const u8) Error!usize { var pe = coff.Coff.init(image, false) catch return error.BadPe; if (!pe.is_image) return error.NotImage; if (pe.getHeader().machine != .RISCV64) return error.NotRiscv64; - if (@intFromEnum(pe.getOptionalHeader().magic) != coff.IMAGE_NT_OPTIONAL_HDR64_MAGIC) { + if (@backingInt(pe.getOptionalHeader().magic) != coff.IMAGE_NT_OPTIONAL_HDR64_MAGIC) { return error.NotPe32Plus; } return pe.getOptionalHeader64().size_of_image; @@ -56,7 +56,7 @@ pub fn loadAt(image: []const u8, load_base: usize, max_image: usize) Error!Loade if (!pe.is_image) return error.NotImage; if (pe.getHeader().machine != .RISCV64) return error.NotRiscv64; - if (@intFromEnum(pe.getOptionalHeader().magic) != coff.IMAGE_NT_OPTIONAL_HDR64_MAGIC) { + if (@backingInt(pe.getOptionalHeader().magic) != coff.IMAGE_NT_OPTIONAL_HDR64_MAGIC) { return error.NotPe32Plus; } @@ -155,7 +155,7 @@ fn relocate( if (delta == 0) return; // loaded at its preferred base, nothing to fix up const dirs = pe.getDataDirectories(); - const idx = @intFromEnum(coff.IMAGE.DIRECTORY_ENTRY.BASERELOC); + const idx = @backingInt(coff.IMAGE.DIRECTORY_ENTRY.BASERELOC); if (idx >= dirs.len) return; const reloc = dirs[idx]; // No relocation table: the image is position-independent and relocates diff --git a/src/sbi/ipi.zig b/src/sbi/ipi.zig index 2700a53..54c1f72 100644 --- a/src/sbi/ipi.zig +++ b/src/sbi/ipi.zig @@ -15,7 +15,7 @@ pub const SOFT: u32 = 1 << 0; // relay to S-mode as SSIP pub const FENCE_I: u32 = 1 << 1; // execute FENCE.I locally pub const SFENCE_VMA: u32 = 1 << 2; // execute SFENCE.VMA locally (full flush) -var pending: [MAX_HARTS]u32 = [_]u32{0} ** MAX_HARTS; +var pending: [MAX_HARTS]u32 = @splat(0); /// Queue `ops` on `target` and signal it. Fire-and-forget (used for SOFT relays). pub fn send(target: usize, ops: u32) void { diff --git a/src/tpm/tcg2.zig b/src/tpm/tcg2.zig index f93df20..c88618d 100644 --- a/src/tpm/tcg2.zig +++ b/src/tpm/tcg2.zig @@ -9,7 +9,7 @@ const tpm2 = @import("tpm2.zig"); const handledb = @import("../uefi/handledb.zig"); const Status = uefi.Status; -const ok = @intFromEnum(Status.success); +const ok = @backingInt(Status.success); // EFI_TCG2_PROTOCOL_GUID 607f766c-7455-42be-930b-e4d76db2720f. pub const TCG2_GUID = uefi.Guid{ @@ -74,7 +74,7 @@ fn getEventLog( last_entry: *u64, truncated: *bool, ) callconv(.c) usize { - if (format != EVENT_LOG_FORMAT_TCG_2) return @intFromEnum(Status.invalid_parameter); + if (format != EVENT_LOG_FORMAT_TCG_2) return @backingInt(Status.invalid_parameter); log_loc.* = tpm.eventLogStart(); last_entry.* = tpm.eventLogLastEntry(); truncated.* = tpm.logTruncated(); @@ -93,9 +93,9 @@ fn hashLogExtendEvent( data_len: u64, event: [*]u8, ) callconv(.c) usize { - if (!tpm.isAvailable()) return @intFromEnum(Status.device_error); + if (!tpm.isAvailable()) return @backingInt(Status.device_error); const size = std.mem.readInt(u32, event[0..4], .little); - if (size < 18) return @intFromEnum(Status.invalid_parameter); + if (size < 18) return @backingInt(Status.invalid_parameter); const pcr = std.mem.readInt(u32, event[10..14], .little); const event_type = std.mem.readInt(u32, event[14..18], .little); const event_data = event[18..size]; @@ -107,9 +107,9 @@ fn hashLogExtendEvent( const want_log = flags & HLEE_EXTEND_ONLY == 0; if (want_log) { if (!tpm.logExtend(pcr, event_type, &digest, event_data)) - return @intFromEnum(Status.device_error); + return @backingInt(Status.device_error); } else { - if (!tpm.extendOnly(pcr, &digest)) return @intFromEnum(Status.device_error); + if (!tpm.extendOnly(pcr, &digest)) return @backingInt(Status.device_error); } return ok; } @@ -122,7 +122,7 @@ fn submitCommand( out_block: [*]u8, ) callconv(.c) usize { if (tpm2.submit(in_block[0..in_size], out_block[0..out_size]) == null) - return @intFromEnum(Status.device_error); + return @backingInt(Status.device_error); return ok; } diff --git a/src/tpm/tpm.zig b/src/tpm/tpm.zig index a825ece..1d5112e 100644 --- a/src/tpm/tpm.zig +++ b/src/tpm/tpm.zig @@ -60,7 +60,7 @@ fn initLog() void { log_truncated = false; logU32(0); // pcrIndex logU32(EV_NO_ACTION); // eventType - logBytes(&[_]u8{0} ** 20); // SHA1 digest field (zero) + logBytes(&@as([20]u8, @splat(0))); // SHA1 digest field (zero) // eventSize + TCG_EfiSpecIdEvent const spec_size: u32 = 16 + 4 + 4 + 4 + (2 + 2) + 1; // sig+class+ver+count+1 alg+vendorlen logU32(spec_size); diff --git a/src/uefi/blockio.zig b/src/uefi/blockio.zig index 8063482..292015f 100644 --- a/src/uefi/blockio.zig +++ b/src/uefi/blockio.zig @@ -10,7 +10,7 @@ const blk = @import("../virtio/blk.zig"); const handledb = @import("handledb.zig"); const Status = uefi.Status; -const ok = @intFromEnum(Status.success); +const ok = @backingInt(Status.success); const BlockIo = uefi.protocol.BlockIo; const Media = BlockIo.BlockMedia; @@ -74,9 +74,9 @@ fn readBlocks( ) callconv(.c) usize { _ = self; _ = media_id; - if (buffer_size % dev.block_size != 0) return @intFromEnum(Status.bad_buffer_size); + if (buffer_size % dev.block_size != 0) return @backingInt(Status.bad_buffer_size); const count: u32 = @intCast(buffer_size / dev.block_size); - if (!dev.readBlocks(lba, count, buf[0..buffer_size])) return @intFromEnum(Status.device_error); + if (!dev.readBlocks(lba, count, buf[0..buffer_size])) return @backingInt(Status.device_error); return ok; } @@ -92,7 +92,7 @@ fn writeBlocks( _ = lba; _ = buffer_size; _ = buf; - return @intFromEnum(Status.write_protected); + return @backingInt(Status.write_protected); } fn flushBlocks(self: *BlockIo) callconv(.c) usize { @@ -161,10 +161,10 @@ fn partRead( _ = self; _ = media_id; const bs = part_dev.dev.block_size; - if (buffer_size % bs != 0) return @intFromEnum(Status.bad_buffer_size); + if (buffer_size % bs != 0) return @backingInt(Status.bad_buffer_size); const count: u32 = @intCast(buffer_size / bs); if (!part_dev.readBlocks(lba, count, buf[0..buffer_size])) { - return @intFromEnum(Status.device_error); + return @backingInt(Status.device_error); } return ok; } diff --git a/src/uefi/simplefs.zig b/src/uefi/simplefs.zig index 3aced5f..3180444 100644 --- a/src/uefi/simplefs.zig +++ b/src/uefi/simplefs.zig @@ -13,7 +13,7 @@ const block = @import("../block/block.zig"); const console = @import("../console/console.zig"); const Status = uefi.Status; -const ok = @intFromEnum(Status.success); +const ok = @backingInt(Status.success); const File = uefi.protocol.File; const SimpleFileSystem = uefi.protocol.SimpleFileSystem; @@ -79,7 +79,7 @@ fn alloc() ?*Handle { fn openVolume(self: *const SimpleFileSystem, out: **File) callconv(.c) usize { _ = self; - const h = alloc() orelse return @intFromEnum(Status.out_of_resources); + const h = alloc() orelse return @backingInt(Status.out_of_resources); h.is_dir = true; h.loc = fat.rootLoc(); h.name[0] = '\\'; @@ -101,7 +101,7 @@ fn fileOpen( _ = mode; _ = attr; const h: *Handle = @ptrCast(self); - if (!h.is_dir) return @intFromEnum(Status.not_found); + if (!h.is_dir) return @backingInt(Status.not_found); // Start at root for an absolute path, else at this directory. var loc = h.loc; @@ -128,16 +128,16 @@ fn fileOpen( if (c == 0) continue; if (c == 1 and comp[0] == '.') continue; - if (!fat.lookupComponent(loc, comp[0..c], &last)) return @intFromEnum(Status.not_found); + if (!fat.lookupComponent(loc, comp[0..c], &last)) return @backingInt(Status.not_found); resolved = true; is_dir = last.is_dir; if (name[i] != 0) { - if (!last.is_dir) return @intFromEnum(Status.not_found); + if (!last.is_dir) return @backingInt(Status.not_found); loc = .{ .root16 = false, .cluster = last.cluster }; } } - const nh = alloc() orelse return @intFromEnum(Status.out_of_resources); + const nh = alloc() orelse return @backingInt(Status.out_of_resources); if (!resolved) { // Opened the directory itself (e.g. trailing separators). nh.is_dir = true; @@ -165,7 +165,7 @@ fn fileClose(self: *File) callconv(.c) usize { fn fileDelete(self: *File) callconv(.c) usize { _ = self; - return @intFromEnum(Status.unsupported); + return @backingInt(Status.unsupported); } fn fileRead(self: *File, buffer_size: *usize, buffer: [*]u8) callconv(.c) usize { @@ -199,7 +199,7 @@ fn fileWrite(self: *File, buffer_size: *usize, buffer: [*]const u8) callconv(.c) _ = self; _ = buffer_size; _ = buffer; - return @intFromEnum(Status.write_protected); + return @backingInt(Status.write_protected); } fn fileGetPosition(self: *const File, pos: *u64) callconv(.c) usize { @@ -223,11 +223,11 @@ fn fileGetInfo( ) callconv(.c) usize { const h: *const Handle = @ptrCast(self); if (!std.mem.eql(u8, std.mem.asBytes(guid), std.mem.asBytes(&File.Info.File.guid))) { - return @intFromEnum(Status.unsupported); + return @backingInt(Status.unsupported); } const buf = if (buffer) |b| b[0..size.*] else { size.* = 80 + h.name_units * 2; - return @intFromEnum(Status.buffer_too_small); + return @backingInt(Status.buffer_too_small); }; return writeFileInfo(buf, size, h.name[0..h.name_units], h.size, h.is_dir); } @@ -242,7 +242,7 @@ fn fileSetInfo( _ = guid; _ = size; _ = buffer; - return @intFromEnum(Status.write_protected); + return @backingInt(Status.write_protected); } fn fileFlush(self: *File) callconv(.c) usize { @@ -255,7 +255,7 @@ fn writeFileInfo(buf: []u8, size: *usize, name: []const u16, file_size: u32, is_ const needed = 80 + name.len * 2; if (buf.len < needed) { size.* = needed; - return @intFromEnum(Status.buffer_too_small); + return @backingInt(Status.buffer_too_small); } @memset(buf[0..needed], 0); std.mem.writeInt(u64, buf[0..8], needed, .little); // Size diff --git a/src/uefi/uefi.zig b/src/uefi/uefi.zig index 515d9cd..d5f5dfb 100644 --- a/src/uefi/uefi.zig +++ b/src/uefi/uefi.zig @@ -175,7 +175,7 @@ fn bumpAlloc(size: usize, alignment: usize) ?usize { return null; } -const ok = @intFromEnum(Status.success); +const ok = @backingInt(Status.success); // Images loaded through the LoadImage boot service (the bootloader loading a // kernel). Each keeps its entry point and a LoadedImage protocol the app reads @@ -212,10 +212,10 @@ fn tr(comptime name: []const u8) void { /// Generic stub for unimplemented services: returns unsupported. fn stub() callconv(.c) usize { tr(""); - return @intFromEnum(Status.unsupported); + return @backingInt(Status.unsupported); } -const not_found = @intFromEnum(Status.not_found); +const not_found = @backingInt(Status.not_found); fn guidEql(a: *const uefi.Guid, b: *const uefi.Guid) bool { return std.mem.eql(u8, std.mem.asBytes(a), std.mem.asBytes(b)); @@ -283,13 +283,13 @@ fn locateHandle( ) callconv(.c) usize { _ = search_type; _ = key; - const g = guid orelse return @intFromEnum(Status.invalid_parameter); + const g = guid orelse return @backingInt(Status.invalid_parameter); var tmp: [32]*handledb.Handle = undefined; const n = handledb.locateHandles(g, &tmp); const needed = n * @sizeOf(uefi.Handle); if (buffer == null or buffer_size.* < needed) { buffer_size.* = needed; - return @intFromEnum(Status.buffer_too_small); + return @backingInt(Status.buffer_too_small); } var i: usize = 0; while (i < n) : (i += 1) buffer.?[i] = @ptrCast(tmp[i]); @@ -307,13 +307,13 @@ fn locateHandleBuffer( ) callconv(.c) usize { _ = search_type; _ = key; - const g = guid orelse return @intFromEnum(Status.invalid_parameter); + const g = guid orelse return @backingInt(Status.invalid_parameter); var tmp: [32]*handledb.Handle = undefined; const n = handledb.locateHandles(g, &tmp); if (n == 0) return not_found; var out: ?*anyopaque = null; if (allocatePool(0, n * @sizeOf(uefi.Handle), &out) != ok) { - return @intFromEnum(Status.out_of_resources); + return @backingInt(Status.out_of_resources); } const handles: [*]uefi.Handle = @ptrCast(@alignCast(out.?)); var i: usize = 0; @@ -344,7 +344,7 @@ fn installProtocolInterface( _ = itype; const existing: ?*handledb.Handle = if (handle.*) |hp| @ptrCast(@alignCast(hp)) else null; const h = handledb.install(existing, guid, interface) orelse - return @intFromEnum(Status.out_of_resources); + return @backingInt(Status.out_of_resources); handle.* = @ptrCast(h); return ok; } @@ -361,7 +361,7 @@ fn installMultipleProtocolInterfaces(handle: *?*anyopaque, ...) callconv(.c) usi const interface = @cVaArg(&va, *anyopaque); const existing: ?*handledb.Handle = if (handle.*) |hp| @ptrCast(@alignCast(hp)) else null; const h = handledb.install(existing, guid, interface) orelse - return @intFromEnum(Status.out_of_resources); + return @backingInt(Status.out_of_resources); handle.* = @ptrCast(h); } return ok; @@ -384,7 +384,7 @@ fn installConfigurationTable(guid: *const uefi.Guid, table: ?*anyopaque) callcon return ok; } if (table) |t| { - if (config_count >= config_table.len) return @intFromEnum(Status.out_of_resources); + if (config_count >= config_table.len) return @backingInt(Status.out_of_resources); config_table[config_count] = .{ .vendor_guid = guid.*, .vendor_table = t }; config_count += 1; system_table.number_of_table_entries = config_count; @@ -400,10 +400,11 @@ fn textOk() callconv(.c) usize { /// Point every pointer field of a table at a stub, leaving `hdr` alone. fn stubAll(comptime T: type, table: *T) void { - inline for (std.meta.fields(T)) |f| { - if (comptime std.mem.eql(u8, f.name, "hdr")) continue; - if (comptime @typeInfo(f.type) == .pointer) { - @field(table.*, f.name) = @ptrFromInt(@intFromPtr(&stub)); + const info = @typeInfo(T).@"struct"; + inline for (info.field_names, info.field_types) |name, field_type| { + if (comptime std.mem.eql(u8, name, "hdr")) continue; + if (comptime @typeInfo(field_type) == .pointer) { + @field(table.*, name) = @ptrFromInt(@intFromPtr(&stub)); } } } @@ -505,7 +506,7 @@ fn decodeKey(buf: []const u8) KeyDecode { fn inReadKey(self: *uefi.protocol.SimpleTextInput, key: *anyopaque) callconv(.c) usize { _ = self; fillKeys(); - if (key_len == 0) return @intFromEnum(Status.not_ready); + if (key_len == 0) return @backingInt(Status.not_ready); // Give a partial escape sequence a short window to finish arriving. A // terminal sends the whole sequence back to back, so a few milliseconds is @@ -525,7 +526,7 @@ fn inReadKey(self: *uefi.protocol.SimpleTextInput, key: *anyopaque) callconv(.c) const k: *InputKey = @ptrCast(@alignCast(key)); k.* = .{ .scan_code = dec.scan, .unicode_char = dec.char }; // A consumed-but-unmapped sequence (scan and char both zero) is not a key. - if (dec.scan == 0 and dec.char == 0) return @intFromEnum(Status.not_ready); + if (dec.scan == 0 and dec.char == 0) return @backingInt(Status.not_ready); return ok; } @@ -544,7 +545,7 @@ fn outString(self: *uefi.protocol.SimpleTextOutput, str: [*:0]const u16) callcon fn allocatePool(pool_type: u32, size: usize, buffer: *?*anyopaque) callconv(.c) usize { tr("allocatePool"); _ = pool_type; - const addr = bumpAlloc(size, 8) orelse return @intFromEnum(Status.out_of_resources); + const addr = bumpAlloc(size, 8) orelse return @backingInt(Status.out_of_resources); buffer.* = @ptrFromInt(addr); return ok; } @@ -567,12 +568,12 @@ fn allocatePages(alloc_type: u32, mem_type: u32, pages: usize, memory: *usize) c if (alloc_type == 2) { const req = memory.*; if (req < FW_RESERVED_END or req +% size < req or req + size > RAM_END) { - return @intFromEnum(Status.out_of_resources); + return @backingInt(Status.out_of_resources); } reserveRegion(req, req + size); return ok; } - const addr = bumpAlloc(size, 4096) orelse return @intFromEnum(Status.out_of_resources); + const addr = bumpAlloc(size, 4096) orelse return @backingInt(Status.out_of_resources); memory.* = addr; if (trace) console.out.print("[uefi] -> pages at {x}\n", .{addr}) catch {}; return ok; @@ -625,7 +626,7 @@ fn getMemoryMap( desc_ver.* = 1; if (mmap == null or mmap_size.* < needed) { mmap_size.* = needed; - return @intFromEnum(Status.buffer_too_small); + return @backingInt(Status.buffer_too_small); } // EFI_MEMORY_WB: ordinary writeback-cacheable RAM. @@ -801,31 +802,31 @@ fn loadImage( // zippy:ignore too_many_params UEFI LoadImage ABI is fixed // The image bytes: an explicit buffer, or the file the device path names. const src: []const u8 = if (source_buffer) |sb| blk: { - if (source_size == 0) return @intFromEnum(Status.invalid_parameter); + if (source_size == 0) return @backingInt(Status.invalid_parameter); break :blk sb[0..source_size]; } else blk: { - const dp = device_path orelse return @intFromEnum(Status.invalid_parameter); + const dp = device_path orelse return @backingInt(Status.invalid_parameter); var name_buf: [256]u8 = undefined; const path = devicePathFile(@ptrCast(dp), &name_buf) orelse return not_found; const fsize = fat.fileSize(path) orelse return not_found; - const scratch = bumpAlloc(fsize, 8) orelse return @intFromEnum(Status.out_of_resources); + const scratch = bumpAlloc(fsize, 8) orelse return @backingInt(Status.out_of_resources); const sbuf = @as([*]u8, @ptrFromInt(scratch))[0..fsize]; // A multi-MiB image over polled SPI takes many seconds. Announce the read // so a slow load reads as progress, not a hang. - const got = fat.readFile(path, sbuf) orelse return @intFromEnum(Status.device_error); - if (got != fsize) return @intFromEnum(Status.device_error); + const got = fat.readFile(path, sbuf) orelse return @backingInt(Status.device_error); + if (got != fsize) return @backingInt(Status.device_error); break :blk sbuf; }; // Place the image in a fresh page-aligned region above the loaded bootloader, // and reserve it so no later allocation aliases the loaded image. - const image_size = pe.sizeOf(src) catch return @intFromEnum(Status.load_error); - const base = bumpAlloc(image_size, 4096) orelse return @intFromEnum(Status.out_of_resources); + const image_size = pe.sizeOf(src) catch return @backingInt(Status.load_error); + const base = bumpAlloc(image_size, 4096) orelse return @backingInt(Status.out_of_resources); reserveRegion(base, base + image_size); - const loaded = pe.loadAt(src, base, image_size) catch return @intFromEnum(Status.load_error); + const loaded = pe.loadAt(src, base, image_size) catch return @backingInt(Status.load_error); - const slot = loadedImageSlot() orelse return @intFromEnum(Status.out_of_resources); - const h = handledb.create() orelse return @intFromEnum(Status.out_of_resources); + const slot = loadedImageSlot() orelse return @backingInt(Status.out_of_resources); + const h = handledb.create() orelse return @backingInt(Status.out_of_resources); slot.used = true; slot.handle = h; slot.entry = loaded.entry; @@ -859,10 +860,10 @@ fn startImage(image: uefi.Handle, exit_data_size: ?*usize, exit_data: ?*[*]u16) _ = exit_data; if (exit_data_size) |s| s.* = 0; const h: *handledb.Handle = @ptrCast(@alignCast(image)); - const slot = findLoadedImage(h) orelse return @intFromEnum(Status.invalid_parameter); + const slot = findLoadedImage(h) orelse return @backingInt(Status.invalid_parameter); const EntryFn = *const fn (uefi.Handle, *tables.SystemTable) callconv(.c) Status; const entry: EntryFn = @ptrFromInt(slot.entry); - return @intFromEnum(entry(image, &system_table)); + return @backingInt(entry(image, &system_table)); } /// UnloadImage: drop a loaded image the app chose not to start. The bump @@ -984,7 +985,7 @@ fn createEvent( out: *?*anyopaque, ) callconv(.c) usize { _ = notify_tpl; - const e = eventAlloc() orelse return @intFromEnum(Status.out_of_resources); + const e = eventAlloc() orelse return @backingInt(Status.out_of_resources); e.is_timer = (etype & EVT_TIMER) != 0; e.notify_fn = notify_fn; e.notify_ctx = notify_ctx; @@ -1005,7 +1006,7 @@ fn createEventEx( // zippy:ignore too_many_params UEFI CreateEventEx ABI is fixe } fn setTimer(event: ?*anyopaque, delay: u32, trigger_time: u64) callconv(.c) usize { - const e = eventOf(event) orelse return @intFromEnum(Status.invalid_parameter); + const e = eventOf(event) orelse return @backingInt(Status.invalid_parameter); switch (delay) { 0 => { // cancel e.timer_armed = false; @@ -1022,18 +1023,18 @@ fn setTimer(event: ?*anyopaque, delay: u32, trigger_time: u64) callconv(.c) usiz e.periodic = false; e.deadline = clint.time() + timerTicks(trigger_time); }, - else => return @intFromEnum(Status.invalid_parameter), + else => return @backingInt(Status.invalid_parameter), } return ok; } fn waitForEvent(event_len: usize, evs: [*]const ?*anyopaque, index: *usize) callconv(.c) usize { - if (event_len == 0) return @intFromEnum(Status.invalid_parameter); + if (event_len == 0) return @backingInt(Status.invalid_parameter); var i: usize = 0; while (i < event_len) : (i += 1) { if (eventOf(evs[i]) == null) { index.* = i; - return @intFromEnum(Status.invalid_parameter); + return @backingInt(Status.invalid_parameter); } } // Poll the events until one is ready. This blocks, as WaitForEvent must. @@ -1051,23 +1052,23 @@ fn waitForEvent(event_len: usize, evs: [*]const ?*anyopaque, index: *usize) call } fn checkEvent(event: ?*anyopaque) callconv(.c) usize { - const e = eventOf(event) orelse return @intFromEnum(Status.invalid_parameter); + const e = eventOf(event) orelse return @backingInt(Status.invalid_parameter); if (eventReady(e)) { e.signaled = false; return ok; } - return @intFromEnum(Status.not_ready); + return @backingInt(Status.not_ready); } fn signalEvent(event: ?*anyopaque) callconv(.c) usize { - const e = eventOf(event) orelse return @intFromEnum(Status.invalid_parameter); + const e = eventOf(event) orelse return @backingInt(Status.invalid_parameter); e.signaled = true; if (e.notify_fn) |f| f(@ptrCast(e), e.notify_ctx); return ok; } fn closeEvent(event: ?*anyopaque) callconv(.c) usize { - const e = eventOf(event) orelse return @intFromEnum(Status.invalid_parameter); + const e = eventOf(event) orelse return @backingInt(Status.invalid_parameter); // The key event belongs to ConIn, not the app: keep it alive. if (e != wait_key_event) e.used = false; return ok; @@ -1092,7 +1093,7 @@ fn setVirtualAddressMap( // --- EFI variable runtime services (flash-backed) --------------------------- fn statusOf(r: varstore.Result) usize { - return @intFromEnum(switch (r) { + return @backingInt(switch (r) { .success => Status.success, .not_found => Status.not_found, .buffer_too_small => Status.buffer_too_small, @@ -1133,7 +1134,7 @@ fn queryVariableInfo( max_var: *u64, ) callconv(.c) usize { _ = attributes; - if (!varstore.available()) return @intFromEnum(Status.unsupported); + if (!varstore.available()) return @backingInt(Status.unsupported); varstore.queryInfo(max_storage, remaining, max_var); return ok; } @@ -1169,7 +1170,7 @@ fn setTime(t: *const uefi.Time) callconv(.c) usize { .second = t.second, }); // A present but read-only RTC cannot take the write. - return if (written) ok else @intFromEnum(Status.device_error); + return if (written) ok else @backingInt(Status.device_error); } fn resetSystem( @@ -1197,7 +1198,7 @@ pub fn imageHandle() uefi.Handle { fn fixCrc(comptime T: type, hdr: *tables.TableHeader, table: *const T) void { hdr.crc32 = 0; const bytes = @as([*]const u8, @ptrCast(table))[0..@sizeOf(T)]; - hdr.crc32 = std.hash.crc.Crc32.hash(bytes); + hdr.crc32 = std.hash.Crc32.hash(bytes); } // The handle DB has spare capacity during table construction, so install never @@ -1323,7 +1324,7 @@ pub fn prepare(dtb: usize, hartid: usize, image_base: usize, image_size: usize) }; // A bare End-of-Hardware device path for the loaded image. - end_path = .{ .type = @enumFromInt(0x7f), .subtype = 0xff, .length = 4 }; + end_path = .{ .type = @fromBackingInt(@intCast(0x7f)), .subtype = 0xff, .length = 4 }; // Loaded Image protocol: where the app sits and its command line. loaded_image = .{ diff --git a/tools/fdt_bases.zig b/tools/fdt_bases.zig index 2041079..037cc12 100644 --- a/tools/fdt_bases.zig +++ b/tools/fdt_bases.zig @@ -74,7 +74,7 @@ pub fn parse(fdt: *const dtree.Reader, out: *Bases) void { // One entry per open node. stack[0] is the implicit root parent (holding the // DT default cells); sp indexes the current node. 24 levels is far more than // any real tree nests; deeper nodes reuse the deepest slot. - var stack = [_]Node{.{}} ** 24; + var stack: [24]Node = @splat(.{}); var sp: usize = 0; while (iter.next() catch return) |node| {