aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHimbeer <himbeer@disroot.org>2024-05-11 16:28:02 +0200
committerHimbeer <himbeer@disroot.org>2024-05-11 16:28:02 +0200
commit2984574f714fafe6f99e4cb2ad6a22c735925fc6 (patch)
treef0a089f2bf0b7c2a728390936175b4c72020c614
parentf52900b6ed72b8ce4705c9ba8aa7353230a50eab (diff)
fdt: Fix compile errors
-rw-r--r--src/fdt.zig67
-rw-r--r--src/plic.zig2
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;