diff --git a/src/main.zig b/src/main.zig index 80296da..1e9fc1f 100644 --- a/src/main.zig +++ b/src/main.zig @@ -54,13 +54,16 @@ export fn kmain(hartid: u64, fdt_ptr: *const anyopaque) callconv(.c) noreturn { debug.print("memory allocator initialized.\n", .{}); const allocator = buddy.allocator(); + const mmu_type = fdt.mmuType(); var table = isa.PageTable.init(allocator) catch { @panic("Unable to create page table.\n"); }; - table.identityMap(allocator, memory_end) catch {}; - table.map(allocator, @intFromPtr(console.mmio), @intFromPtr(console.mmio), .{.read = 1, .write = 1, .execute = 1}) catch {}; + table.identityMap(allocator, memory_end, mmu_type) catch {}; + table.map(allocator, @intFromPtr(console.mmio), @intFromPtr(console.mmio), .{.read = 1, .write = 1, .execute = 1}, mmu_type) catch { + + }; isa.write_satp(.{ .ppn = @as(u44, @intCast(@intFromPtr(table) >> 12)), - .mode = .sv57, + .mode = mmu_type, }); debug.print("loaded kernel page table.\n", .{}); diff --git a/src/riscv/PageTable.zig b/src/riscv/PageTable.zig index 0b70704..d702eae 100644 --- a/src/riscv/PageTable.zig +++ b/src/riscv/PageTable.zig @@ -2,6 +2,7 @@ const std = @import("std"); const Allocator = std.mem.Allocator; const PageTable = @This(); const debug = @import("../debug.zig"); +const isa = @import("isa.zig"); const MEMORY_START = @extern([*]u8, .{.name = "__memory_start"}); @@ -34,7 +35,7 @@ pub fn init(allocator: Allocator) !*PageTable { return table; } -pub fn identityMap(self: *PageTable, allocator: Allocator, memory_end: u64) !void { +pub fn identityMap(self: *PageTable, allocator: Allocator, memory_end: u64, mode: isa.Satp.Mode) !void { const flags = EntryFlags{ .valid = 1, .read = 1, @@ -45,17 +46,24 @@ pub fn identityMap(self: *PageTable, allocator: Allocator, memory_end: u64) !voi var addr: u64 = 0x0; while (addr < memory_end) : (addr += 0x1000) { - try self.map(allocator, addr, addr, flags); + try self.map(allocator, addr, addr, flags, mode); } } -pub fn map(self: *PageTable, allocator: Allocator, virtual: u64, physical: u64, flags: EntryFlags) !void { +pub fn map(self: *PageTable, allocator: Allocator, virtual: u64, physical: u64, flags: EntryFlags, mode: isa.Satp.Mode) !void { const PAGE_SIZE = 4096; if (virtual % PAGE_SIZE != 0 or physical % PAGE_SIZE != 0) { return error.AddressNotAligned; } + var level: usize = switch (mode) { + .sv39 => 2, + .sv48 => 3, + .sv57 => 4, + else => return error.UnsupportedMode, + }; + const vpn = [5]u64{ (virtual >> 12) & 0x1ff, (virtual >> 21) & 0x1ff, @@ -66,7 +74,6 @@ pub fn map(self: *PageTable, allocator: Allocator, virtual: u64, physical: u64, var current_table = self; - var level: usize = 4; while (level > 0) : (level -= 1) { const index = vpn[level]; var entry = ¤t_table.entries[index];