diff options
Diffstat (limited to 'src/lib/hwinfo.zig')
-rw-r--r-- | src/lib/hwinfo.zig | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/src/lib/hwinfo.zig b/src/lib/hwinfo.zig new file mode 100644 index 0000000..a2d6a5e --- /dev/null +++ b/src/lib/hwinfo.zig @@ -0,0 +1,96 @@ +// SPDX-FileCopyrightText: 2024 Himbeer <himbeer@disroot.org> +// +// SPDX-License-Identifier: AGPL-3.0-or-later + +const config = @import("config"); +const std = @import("std"); + +const hw_info = @embedFile("cfg/platform/" ++ config.platform ++ ".hwi"); +//const devices: *[hw_info.len / @sizeOf(Dev)]Dev = @ptrCast(hw_info); +const devices = std.io.FixedBufferStream([]const u8){ .buffer = hw_info, .pos = 0 }; + +pub const ParseError = error{ + MissingKind, + MissingRegAddr, + MissingRegLen, + + UnknownDevKind, +}; + +pub const DevKind = enum(u32) { + cpus, + plic, + pcie, + pci, + + pub fn parse(buf: []const u8) !DevKind { + if (std.mem.eql(u8, buf, "cpus")) { + return .cpus; + } else if (std.mem.eql(u8, buf, "plic")) { + return .plic; + } else if (std.mem.eql(u8, buf, "pcie")) { + return .pcie; + } else if (std.mem.eql(u8, buf, "pci")) { + return .pci; + } + + return ParseError.UnknownDevKind; + } +}; + +pub const Dev = extern struct { + kind: DevKind, + reg: Reg, + value: u64, + + pub fn parse(buf: []const u8) !Dev { + var columns = std.mem.tokenizeScalar(u8, buf, ' '); + const kind_buf = columns.next() orelse return ParseError.MissingKind; + const reg_addr_buf = columns.next() orelse return ParseError.MissingRegAddr; + const reg_len_buf = columns.next() orelse return ParseError.MissingRegLen; + const value_buf = columns.next() orelse "0"; + + return .{ + .kind = try DevKind.parse(kind_buf), + .reg = .{ + .addr = try std.fmt.parseUnsigned(u64, reg_addr_buf, 0), + .len = try std.fmt.parseUnsigned(u64, reg_len_buf, 0), + }, + .value = try std.fmt.parseUnsigned(u64, value_buf, 0), + }; + } +}; + +pub const Reg = extern struct { + addr: u64, + len: u64, + + pub fn slice(self: Reg, comptime T: type) []volatile T { + const ptr: [*]volatile T = @ptrFromInt(self.addr); + return ptr[0 .. self.len / @sizeOf(T)]; + } +}; + +pub const ByKind = struct { + kind: DevKind, + fbs: std.io.FixedBufferStream([]const u8), + + pub fn next(it: *ByKind) !?Dev { + const reader = it.fbs.reader(); + while (reader.readStruct(Dev)) |device| { + if (device.kind == it.kind) { + return device; + } + } else |_| {} + + return null; + } + + pub fn reset(it: *ByKind) !void { + try it.fbs.seekTo(0); + } +}; + +pub fn byKind(kind: DevKind) ByKind { + return .{ .kind = kind, .fbs = devices }; +} |