diff options
author | Himbeer <himbeer@disroot.org> | 2024-05-18 10:55:02 +0200 |
---|---|---|
committer | Himbeer <himbeer@disroot.org> | 2024-05-18 10:55:02 +0200 |
commit | 71a8c414d0ffcb6426f440542ea97e54133034f6 (patch) | |
tree | 99e47fd197c05a8bb67a5ae2403ad172489c7730 | |
parent | 41f2c18185484c5e4d3c28d869cd40eaba0ca37f (diff) |
fdt: Fix alignment + Add compatibility-based search + Add reg property slicer
-rw-r--r-- | src/fdt.zig | 59 |
1 files changed, 46 insertions, 13 deletions
diff --git a/src/fdt.zig b/src/fdt.zig index 5d2f333..9ea85d0 100644 --- a/src/fdt.zig +++ b/src/fdt.zig @@ -35,6 +35,11 @@ pub const MemReservation = struct { pub const Reg = struct { start: usize, len: usize, + + pub fn slice(self: Reg, comptime T: type) []volatile T { + const start_ptr: [*]volatile T = @ptrFromInt(self.start); + return start_ptr[0 .. self.len / @sizeOf(T)]; + } }; pub const Tree = struct { @@ -73,7 +78,7 @@ pub const Node = struct { return self.preferredDriver(&[_][]const u8{with}) != null; } - pub fn reg(self: Node, allocator: std.mem.Allocator) !std.ArrayList(Reg) { + pub fn reg(self: *const 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"); @@ -114,7 +119,7 @@ pub const PropertyDesc = struct { len: u32, name_offset: u32, - pub fn fromPtr(ptr: *PropertyDesc) PropertyDesc { + pub fn fromPtr(ptr: *align(1) PropertyDesc) PropertyDesc { return .{ .len = std.mem.bigToNative(u32, ptr.len), .name_offset = std.mem.bigToNative(u32, ptr.name_offset), @@ -157,7 +162,7 @@ pub const Header = struct { const token_nop = 0x00000004; const token_end = 0x00000009; - raw_hdr: *RawHeader, + raw_hdr: *align(1) RawHeader, magic: u32, total_size: u32, @@ -176,7 +181,7 @@ pub const Header = struct { // v17 size_dt_struct: u32, - pub fn parse(raw_hdr: *RawHeader) !Header { + pub fn parse(raw_hdr: *align(1) RawHeader) !Header { const hdr = .{ .raw_hdr = raw_hdr, @@ -225,10 +230,10 @@ pub const Header = struct { const dt_strings_addr = @intFromPtr(self.raw_hdr) + @as(usize, self.offset_dt_strings); const dt_strings: [*:0]const u8 = @ptrFromInt(dt_strings_addr); - while (std.mem.bigToNative(u32, @as(*u32, @ptrFromInt(dt_struct_addr)).*) != token_end) { + while (std.mem.bigToNative(u32, @as(*align(1) u32, @ptrFromInt(dt_struct_addr)).*) != token_end) { const parsed = try parseNode(allocator, dt_struct_addr, dt_strings); dt_struct_addr = parsed.addr; - try nodes.insert(0, parsed.value); + try nodes.append(parsed.value); } var tree = Tree{ .header = self, .nodes = nodes }; @@ -286,6 +291,34 @@ pub fn findPathExact(dt: *const Tree, path: []const u8) ?Node { return node; } +pub fn findCompatible(node: *Node, compatible: []const []const u8, max: comptime_int) []Node { + var results: [max]Node = undefined; + var n: usize = 0; + + for (node.subnodes.items) |subnode| { + var subnode_mut = subnode; + + const subresults = findCompatible(&subnode_mut, compatible, max); + for (subresults) |subresult| { + if (n >= max) break; + + results[n] = subresult; + n += 1; + } + + for (compatible) |driver| { + if (n >= max) break; + + if (subnode.isCompatible(driver)) { + results[n] = subnode; + n += 1; + } + } + } + + return results[0..n]; +} + fn nodeNameFilter(node: Node, name: []const u8) bool { var it = std.mem.splitScalar(u8, node.name, '@'); const trueName = it.first(); @@ -299,11 +332,11 @@ fn parseNode(allocator: std.mem.Allocator, dt_struct_addr: usize, dt_strings: [* var addr = dt_struct_addr; // Skip Nop tokens - while (std.mem.bigToNative(u32, @as(*u32, @ptrFromInt(addr)).*) == Header.token_nop) { + while (std.mem.bigToNative(u32, @as(*align(1) u32, @ptrFromInt(addr)).*) == Header.token_nop) { addr += @sizeOf(u32); } - if (std.mem.bigToNative(u32, @as(*u32, @ptrFromInt(addr)).*) != Header.token_begin_node) { + if (std.mem.bigToNative(u32, @as(*align(1) u32, @ptrFromInt(addr)).*) != Header.token_begin_node) { return ParseError.ExpectedBeginNodeToken; } @@ -316,8 +349,8 @@ fn parseNode(allocator: std.mem.Allocator, dt_struct_addr: usize, dt_strings: [* // Skip zeroed alignment padding addr += (4 - ((std.mem.len(name) + 1) % 4)) % 4; - while (std.mem.bigToNative(u32, @as(*u32, @ptrFromInt(addr)).*) != Header.token_end_node) { - switch (std.mem.bigToNative(u32, @as(*u32, @ptrFromInt(addr)).*)) { + while (std.mem.bigToNative(u32, @as(*align(1) u32, @ptrFromInt(addr)).*) != Header.token_end_node) { + switch (std.mem.bigToNative(u32, @as(*align(1) u32, @ptrFromInt(addr)).*)) { Header.token_prop => { const parsed = try parseProperty(addr, dt_strings); addr = parsed.addr; @@ -334,7 +367,7 @@ fn parseNode(allocator: std.mem.Allocator, dt_struct_addr: usize, dt_strings: [* Header.token_begin_node => { const parsed = try parseNode(allocator, addr, dt_strings); addr = parsed.addr; - try subnodes.insert(0, parsed.value); + try subnodes.append(parsed.value); }, else => return ParseError.BadToken, } @@ -357,11 +390,11 @@ fn parseProperty(dt_struct_addr: usize, dt_strings: [*:0]const u8) !ParseResult( var addr = dt_struct_addr; // Skip Nop tokens - while (std.mem.bigToNative(u32, @as(*u32, @ptrFromInt(addr)).*) == Header.token_nop) { + while (std.mem.bigToNative(u32, @as(*align(1) u32, @ptrFromInt(addr)).*) == Header.token_nop) { addr += @sizeOf(u32); } - if (std.mem.bigToNative(u32, @as(*u32, @ptrFromInt(addr)).*) != Header.token_prop) { + if (std.mem.bigToNative(u32, @as(*align(1) u32, @ptrFromInt(addr)).*) != Header.token_prop) { return ParseError.ExpectedPropToken; } |