aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHimbeer <himbeer@disroot.org>2024-05-18 10:55:02 +0200
committerHimbeer <himbeer@disroot.org>2024-05-18 10:55:02 +0200
commit71a8c414d0ffcb6426f440542ea97e54133034f6 (patch)
tree99e47fd197c05a8bb67a5ae2403ad172489c7730
parent41f2c18185484c5e4d3c28d869cd40eaba0ca37f (diff)
fdt: Fix alignment + Add compatibility-based search + Add reg property slicer
-rw-r--r--src/fdt.zig59
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;
}