add support for multiple types of MMU

This commit is contained in:
Lorenzo Torres 2026-02-02 18:11:44 +01:00
parent 7cb116229f
commit 8e160782ec
2 changed files with 17 additions and 7 deletions

View file

@ -54,13 +54,16 @@ export fn kmain(hartid: u64, fdt_ptr: *const anyopaque) callconv(.c) noreturn {
debug.print("memory allocator initialized.\n", .{}); debug.print("memory allocator initialized.\n", .{});
const allocator = buddy.allocator(); const allocator = buddy.allocator();
const mmu_type = fdt.mmuType();
var table = isa.PageTable.init(allocator) catch { @panic("Unable to create page table.\n"); }; var table = isa.PageTable.init(allocator) catch { @panic("Unable to create page table.\n"); };
table.identityMap(allocator, memory_end) catch {}; table.identityMap(allocator, memory_end, mmu_type) catch {};
table.map(allocator, @intFromPtr(console.mmio), @intFromPtr(console.mmio), .{.read = 1, .write = 1, .execute = 1}) catch {}; table.map(allocator, @intFromPtr(console.mmio), @intFromPtr(console.mmio), .{.read = 1, .write = 1, .execute = 1}, mmu_type) catch {
};
isa.write_satp(.{ isa.write_satp(.{
.ppn = @as(u44, @intCast(@intFromPtr(table) >> 12)), .ppn = @as(u44, @intCast(@intFromPtr(table) >> 12)),
.mode = .sv57, .mode = mmu_type,
}); });
debug.print("loaded kernel page table.\n", .{}); debug.print("loaded kernel page table.\n", .{});

View file

@ -2,6 +2,7 @@ const std = @import("std");
const Allocator = std.mem.Allocator; const Allocator = std.mem.Allocator;
const PageTable = @This(); const PageTable = @This();
const debug = @import("../debug.zig"); const debug = @import("../debug.zig");
const isa = @import("isa.zig");
const MEMORY_START = @extern([*]u8, .{.name = "__memory_start"}); const MEMORY_START = @extern([*]u8, .{.name = "__memory_start"});
@ -34,7 +35,7 @@ pub fn init(allocator: Allocator) !*PageTable {
return table; 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{ const flags = EntryFlags{
.valid = 1, .valid = 1,
.read = 1, .read = 1,
@ -45,17 +46,24 @@ pub fn identityMap(self: *PageTable, allocator: Allocator, memory_end: u64) !voi
var addr: u64 = 0x0; var addr: u64 = 0x0;
while (addr < memory_end) : (addr += 0x1000) { 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; const PAGE_SIZE = 4096;
if (virtual % PAGE_SIZE != 0 or physical % PAGE_SIZE != 0) { if (virtual % PAGE_SIZE != 0 or physical % PAGE_SIZE != 0) {
return error.AddressNotAligned; return error.AddressNotAligned;
} }
var level: usize = switch (mode) {
.sv39 => 2,
.sv48 => 3,
.sv57 => 4,
else => return error.UnsupportedMode,
};
const vpn = [5]u64{ const vpn = [5]u64{
(virtual >> 12) & 0x1ff, (virtual >> 12) & 0x1ff,
(virtual >> 21) & 0x1ff, (virtual >> 21) & 0x1ff,
@ -66,7 +74,6 @@ pub fn map(self: *PageTable, allocator: Allocator, virtual: u64, physical: u64,
var current_table = self; var current_table = self;
var level: usize = 4;
while (level > 0) : (level -= 1) { while (level > 0) : (level -= 1) {
const index = vpn[level]; const index = vpn[level];
var entry = &current_table.entries[index]; var entry = &current_table.entries[index];