wires

summary refs log tree commit diff
path: root/src/DtParser.zig
blob: 5ff3dfbc25fe3848280ee708ae6f5bbdc61c0500 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
const std = @import("std");
const bigToNative = std.mem.bigToNative;

const Self = @This();

const Header = struct {
    magic: u32,
    total_size: u32,
    off_dt_struct: u32,
    off_dt_strings: u32,
    off_mem_rsvmap: u32,
    version: u32,
    last_comp_version: u32,
    boot_cpuid_phys: u32,
    size_dt_strings: u32,
    size_dt_struct: u32,
};

base: [*]const u8,

pub fn new(base: [*]const u8) Self {
    return .{ .base = base };
}

fn getHeaderField(self: Self, comptime field_name: []const u8) u32 {
    const ptr: *const u32 = @ptrCast(
        @alignCast(self.base + @offsetOf(Header, field_name)),
    );
    return bigToNative(u32, ptr.*);
}

pub fn magic(self: Self) u32 {
    return self.getHeaderField("magic");
}

pub fn totalSize(self: Self) u32 {
    return self.getHeaderField("total_size");
}

pub fn version(self: Self) u32 {
    return self.getHeaderField("version");
}

pub const ReserveEntry = struct {
    address: u64,
    size: u64,
};

const MemRsvmapIter = struct {
    cur: [*]const u64,

    pub fn next(self: *@This()) ?ReserveEntry {
        const address = bigToNative(u64, self.cur[0]);
        const size = bigToNative(u64, self.cur[1]);

        if (address == 0 and size == 0) {
            return null;
        } else {
            self.cur += 2;
            return .{
                .address = address,
                .size = size,
            };
        }
    }
};

pub fn memRsvmap(self: Self) MemRsvmapIter {
    const offset = self.getHeaderField("off_mem_rsvmap");
    return .{
        .cur = @ptrCast(@alignCast(self.base + offset)),
    };
}