diff options
Diffstat (limited to 'src/paging.zig')
-rw-r--r-- | src/paging.zig | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/src/paging.zig b/src/paging.zig index 1c7b49f..e066451 100644 --- a/src/paging.zig +++ b/src/paging.zig @@ -7,9 +7,6 @@ const fdt = @import("fdt.zig"); -pub const mmio_start: usize = 0x00000000; -pub const mmio_end: usize = 0x80000000; - // Defined by linker script. pub const text_start = @extern(*anyopaque, .{ .name = "_text_start" }); pub const text_end = @extern(*anyopaque, .{ .name = "_text_end" }); @@ -32,6 +29,8 @@ inline fn heapSize() usize { pub const page_size: usize = 0x1000; // 4096 bytes +pub var next_mmio_vaddr: usize = 0xff000000; + // Aligns an address with an offset to the next page. // Doesn't change addresses that are already aligned. fn pageAlign(addr: usize) usize { @@ -426,7 +425,6 @@ pub const Table = struct { } pub fn mapKernel(root: *Table) !void { - try root.identityMapRange(mmio_start, mmio_end, EntryFlags.readWrite); try root.identityMapRange(@intFromPtr(text_start), @intFromPtr(text_end), EntryFlags.readExec); try root.identityMapRange(@intFromPtr(rodata_start), @intFromPtr(rodata_end), EntryFlags.readOnly); try root.identityMapRange(@intFromPtr(data_start), @intFromPtr(data_end), EntryFlags.readWrite); @@ -440,6 +438,22 @@ pub const Table = struct { const fdt_blob = @intFromPtr(dt_header.raw_hdr); try root.identityMapRange(fdt_blob, fdt_blob + dt_header.total_size, EntryFlags.readOnly); } + + pub fn mapDevice(root: *Table, reg: fdt.Reg) !fdt.Reg { + const physical_start = reg.start & ~(page_size - 1); + const physical_end = (reg.start + reg.len - 1) & ~(page_size - 1); + + const offset = reg.start & (page_size - 1); + const vaddr = next_mmio_vaddr | offset; + + var paddr = physical_start; + while (paddr <= physical_end) : (paddr += page_size) { + try root.map(next_mmio_vaddr, paddr, EntryFlags.readWrite, 0); + next_mmio_vaddr += page_size; + } + + return .{ .start = vaddr, .len = reg.len }; + } }; pub fn init() void { |