diff options
-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 { |