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", .{});
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", .{});

View file

@ -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 = &current_table.entries[index];