diff options
author | Himbeer <himbeer@disroot.org> | 2024-05-11 12:58:12 +0200 |
---|---|---|
committer | Himbeer <himbeer@disroot.org> | 2024-05-11 12:58:12 +0200 |
commit | d0a577d2383fd752e21bb9dfe7650060b2fced0a (patch) | |
tree | 62289da2f6c9133a839be85a314ba171b2c5e74e | |
parent | 6e55affa04b227a2c529652cb0ac098b59e52dff (diff) |
fdt: Add reg property parsing helper
-rw-r--r-- | src/fdt.zig | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/src/fdt.zig b/src/fdt.zig index b97e890..3ec3fda 100644 --- a/src/fdt.zig +++ b/src/fdt.zig @@ -24,6 +24,11 @@ pub const MemReservation = struct { size: u64, }; +pub const Reg = struct { + start: usize, + len: usize, +}; + pub const Tree = union { nodes: std.ArrayList(Node), }; @@ -54,6 +59,33 @@ pub const Node = struct { pub fn isCompatible(self: Node, with: []const u8) bool { 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"); + + 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; + + const reg_prop = self.props.get("reg") orelse return null; + 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); + + 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), + }); + } + + return regs; + } }; pub const Property = struct { |