diff options
author | Himbeer <himbeer@disroot.org> | 2024-05-11 16:28:02 +0200 |
---|---|---|
committer | Himbeer <himbeer@disroot.org> | 2024-05-11 16:28:02 +0200 |
commit | 2984574f714fafe6f99e4cb2ad6a22c735925fc6 (patch) | |
tree | f0a089f2bf0b7c2a728390936175b4c72020c614 | |
parent | f52900b6ed72b8ce4705c9ba8aa7353230a50eab (diff) |
fdt: Fix compile errors
-rw-r--r-- | src/fdt.zig | 67 | ||||
-rw-r--r-- | src/plic.zig | 2 |
2 files changed, 45 insertions, 24 deletions
diff --git a/src/fdt.zig b/src/fdt.zig index d62e9fd..4fa47b3 100644 --- a/src/fdt.zig +++ b/src/fdt.zig @@ -14,6 +14,12 @@ pub const ParseError = error{ DuplicateProperty, }; +pub const NodeError = error{ + NoParent, + BadCellSize, + PropertyNotFound, +}; + pub const MemReservation = struct { const sentinel = .{ .addr = 0, @@ -36,6 +42,7 @@ pub const Tree = struct { pub const Node = struct { name: []const u8, props: std.StringHashMap([]const u8), + parent: ?*Node, subnodes: std.ArrayList(Node), pub fn unitAddr(self: Node) !?usize { @@ -49,40 +56,45 @@ pub const Node = struct { pub fn preferredDriver(self: Node, drivers: []const []const u8) ?[]const u8 { const compatible_prop = self.props.get("compatible") orelse return null; - for (std.mem.tokenizeScalar(u8, compatible_prop, '\x00')) |compatible| { - if (std.mem.containsAtLeast([]const u8, drivers, compatible)) return compatible; + var compatibles = std.mem.tokenizeScalar(u8, compatible_prop, '\x00'); + while (compatibles.next()) |compatible| { + for (drivers) |driver| { + if (std.mem.eql(u8, driver, compatible)) return compatible; + } } return null; } pub fn isCompatible(self: Node, with: []const u8) bool { - return self.preferredDriver([]const u8{with}) != null; + return self.preferredDriver(&[_][]const u8{with}) != null; } - pub fn reg(self: Node, allocator: std.mem.Allocator) ?std.ArrayList(Reg) { - const address_cells_bytes = self.parent.props.get("#address-cells"); - const size_cells_bytes = self.parent.props.get("#size-cells"); + pub fn reg(self: Node, allocator: std.mem.Allocator) !std.ArrayList(Reg) { + if (self.parent == null) return NodeError.NoParent; + + const address_cells_bytes = self.parent.?.props.get("#address-cells"); + const size_cells_bytes = self.parent.?.props.get("#size-cells"); const address_cells = if (address_cells_bytes) |bytes| std.mem.readInt(u32, bytes[0..4], .Big) else 2; const size_cells = if (size_cells_bytes) |bytes| std.mem.readInt(u32, bytes[0..4], .Big) else 1; - if (address_cells == 0 or size_cells == 0) return null; + if (address_cells == 0 or size_cells == 0) return NodeError.BadCellSize; - const reg_prop = self.props.get("reg") orelse return null; + const reg_prop = self.props.get("reg") orelse return NodeError.PropertyNotFound; const reg_elem_len = 4 * address_cells + 4 * size_cells; const n = reg_prop.len / reg_elem_len; - const regs = std.ArrayList(Reg).init(allocator); + var regs = std.ArrayList(Reg).init(allocator); for (0..n) |i| { const start_offset = i * reg_elem_len; const len_offset = start_offset + 4 * address_cells; - regs.append(.{ - .start = std.mem.readVarInt(usize, reg[start_offset .. start_offset + 4 * address_cells], .Big), - .len = std.mem.readVarInt(usize, reg[len_offset .. len_offset + 4 * size_cells], .Big), + try regs.append(.{ + .start = std.mem.readVarInt(usize, reg_prop[start_offset .. start_offset + 4 * address_cells], .Big), + .len = std.mem.readVarInt(usize, reg_prop[len_offset .. len_offset + 4 * size_cells], .Big), }); } @@ -211,7 +223,7 @@ pub const Header = struct { const dt_strings: [*:0]const u8 = @ptrFromInt(dt_strings_addr); while (std.mem.bigToNative(u32, @as(*u32, @ptrFromInt(dt_struct_addr)).*) != token_end) { - const parsed = try parseNode(allocator, dt_struct_addr, dt_strings); + const parsed = try parseNode(allocator, dt_struct_addr, dt_strings, null); dt_struct_addr = parsed.addr; try nodes.insert(0, parsed.value); } @@ -237,12 +249,14 @@ pub fn findNodeExact(nodes: []const Node, name: []const u8) ?struct { usize, Nod pub fn findPath(dt: *const Tree, path: []const u8) ?Node { if (dt.nodes.items.len < 1) return null; - path = std.mem.trim(u8, path, "/"); + const trimmed_path = std.mem.trim(u8, path, "/"); var node = dt.nodes.items[0]; - for (std.mem.tokenizeScalar(u8, path, '/')) |segment| { - if (findNode(node.subnodes.items, segment).next()) |result| { + var segments = std.mem.tokenizeScalar(u8, trimmed_path, '/'); + while (segments.next()) |segment| { + var nodes = findNode(node.subnodes.items, segment); + if (nodes.next()) |result| { node = result; } else return null; } @@ -272,7 +286,7 @@ fn nodeNameFilter(node: Node, name: []const u8) bool { return std.mem.eql(u8, trueName, name); } -fn parseNode(allocator: std.mem.Allocator, dt_struct_addr: usize, dt_strings: [*:0]const u8) !ParseResult(Node) { +fn parseNode(allocator: std.mem.Allocator, dt_struct_addr: usize, dt_strings: [*:0]const u8, parent: ?*Node) !ParseResult(Node) { var props = std.StringHashMap([]const u8).init(allocator); var subnodes = std.ArrayList(Node).init(allocator); @@ -312,7 +326,7 @@ fn parseNode(allocator: std.mem.Allocator, dt_struct_addr: usize, dt_strings: [* // Skip Nop tokens Header.token_nop => addr += @sizeOf(u32), Header.token_begin_node => { - const parsed = try parseNode(allocator, addr, dt_strings); + const parsed = try parseNode(allocator, addr, dt_strings, null); addr = parsed.addr; try subnodes.insert(0, parsed.value); }, @@ -322,13 +336,20 @@ fn parseNode(allocator: std.mem.Allocator, dt_struct_addr: usize, dt_strings: [* addr += @sizeOf(u32); + var self: Node = .{ + .name = std.mem.span(name), + .props = props, + .parent = parent, + .subnodes = subnodes, + }; + + for (0..self.subnodes.items.len) |i| { + self.subnodes.items[i].parent = &self; + } + return .{ .addr = addr, - .value = .{ - .name = std.mem.span(name), - .props = props, - .subnodes = subnodes, - }, + .value = self, }; } diff --git a/src/plic.zig b/src/plic.zig index db6a3d6..7ba6522 100644 --- a/src/plic.zig +++ b/src/plic.zig @@ -111,7 +111,7 @@ fn fromFdt(dt: *const fdt.Tree, allocator: std.mem.Allocator) !Plic { const plic_node = fdt.findPath(dt, "/soc/plic") orelse return Error.NoPlic; if (!plic_node.isCompatible("riscv,plic0")) return Error.PlicIncompatible; - const regs = plic_node.reg(allocator) orelse return Error.NoPlicReg; + const regs = try plic_node.reg(allocator); defer regs.deinit(); if (regs.items.len == 0) return Error.NoPlicReg; |