mm: pmap overhaul

This commit is contained in:
Loïc Grégoire
2026-07-01 13:02:39 -04:00
parent 88d6fd10de
commit efe5df1567
9 changed files with 447 additions and 446 deletions
+86 -67
View File
@@ -17,41 +17,45 @@ pub const hhdm_base = 0xffff800000000000;
pub const kernel_heap_base = 0xffffe00000000000;
pub const pfndb_base = 0xffffff0000000000;
pub const PagingImpl = struct {
const Self = @This();
pub const levels = [_]mi.PMapLevel{
.{ .shift = 12, .mask = 0x1ff, .leaf = true }, // 4K
.{ .shift = 21, .mask = 0x1ff, .leaf = true }, // 2M
.{ .shift = 30, .mask = 0x1ff, .leaf = true }, // 1G
.{ .shift = 39, .mask = 0x1ff, .leaf = false }, // root
};
pub const levels = [_]mi.radix_pmap.Level{
.{ .shift = 12, .leaf = true }, // 4K
.{ .shift = 21, .leaf = true }, // 2M
.{ .shift = 30, .leaf = true }, // 1G
.{ .shift = 39, .leaf = false }, // root
};
pub const Pte = packed struct(u64) {
present: bool,
writable: bool,
user: bool,
write_through: bool,
cache_disable: bool,
accessed: bool,
dirty: bool,
huge_page: bool,
global: bool,
available: u3,
addr: u40,
ignored_2: u11,
nx: bool,
pub const Pte = packed struct(u64) {
present: bool,
writable: bool,
user: bool,
write_through: bool,
cache_disable: bool,
accessed: bool,
dirty: bool,
huge_page: bool,
global: bool,
available: u3,
addr: u40,
ignored_2: u11,
nx: bool,
pub fn address(self: Pte) r.PAddr {
return @as(r.PAddr, self.addr) << 12;
}
pub fn address(self: Pte) r.PAddr {
return @as(r.PAddr, self.addr) << 12;
}
};
pub fn is_present(self: Pte) bool {
return self.present;
}
pub inline fn make_table_pte(pa: r.PAddr) Pte {
pub fn load(table: *Pte) Pte {
return @atomicLoad(Pte, table, .monotonic);
}
pub fn zero() Pte {
return Pte{
.present = true,
.writable = true,
.user = true,
.present = false,
.writable = false,
.user = false,
.write_through = false,
.cache_disable = false,
.accessed = false,
@@ -59,50 +63,65 @@ pub const PagingImpl = struct {
.huge_page = false,
.global = false,
.available = 0,
.addr = @truncate(pa >> 12),
.addr = 0,
.ignored_2 = 0,
.nx = false,
};
}
pub inline fn make_leaf_pte(pa: r.PAddr, flags: mm.MapFlags, level: usize) Pte {
return Pte{
.present = true,
.writable = flags.write,
.user = flags.user,
.write_through = flags.write_through,
.cache_disable = flags.cache_disable,
.accessed = false,
.dirty = false,
.huge_page = (level > 0),
.global = flags.global,
.available = 0,
.addr = @truncate(pa >> 12),
.ignored_2 = 0,
.nx = !flags.execute,
};
}
pub inline fn activate(root_pa: r.PAddr) void {
amd64.write_cr(3, root_pa);
}
pub fn is_leaf_level_enabled(level: usize) bool {
if (!levels[level].leaf) return false;
if (level == 2) return amd64.cpu_features.gib_pages;
return true;
}
};
pub const PMap = mi.radix_pmap.RadixPmap(PagingImpl);
pub inline fn make_table_pte(pa: r.PAddr) Pte {
return Pte{
.present = true,
.writable = true,
.user = true,
.write_through = false,
.cache_disable = false,
.accessed = false,
.dirty = false,
.huge_page = false,
.global = false,
.available = 0,
.addr = @truncate(pa >> 12),
.ignored_2 = 0,
.nx = false,
};
}
pub inline fn make_leaf_pte(pa: r.PAddr, flags: mm.MapFlags, level: usize) Pte {
return Pte{
.present = true,
.writable = flags.write,
.user = flags.user,
.write_through = flags.write_through,
.cache_disable = flags.cache_disable,
.accessed = false,
.dirty = false,
.huge_page = (level > 0),
.global = flags.global,
.available = 0,
.addr = @truncate(pa >> 12),
.ignored_2 = 0,
.nx = !flags.execute,
};
}
pub inline fn activate(root_pa: r.PAddr) void {
amd64.write_cr(3, root_pa);
}
pub fn is_leaf_level_enabled(level: usize) bool {
if (!levels[level].leaf) return false;
if (level == 2) return amd64.cpu_features.gib_pages;
return true;
}
pub fn init_kernel() void {
const higher_half_start = phys_to_virt(0);
const higher_half_size: usize = 256 * (1 << 39);
mi.kernel_space.pmap.root_pa = mi.phys.early_alloc();
const table_ptr: [*]Pte = @ptrFromInt(mm.p2v(mi.kernel_space.pmap.root_pa));
@memset(table_ptr[0..512], Pte.zero());
mi.kernel_space.pmap.impl.root_pa = mi.phys.alloc();
const table_ptr: [*]u64 = @ptrFromInt(mm.p2v(mi.kernel_space.pmap.impl.root_pa));
@memset(table_ptr[0..512], 0);
mi.kernel_space.pmap.impl.preallocate(higher_half_start, higher_half_size, 2);
for (256..512) |i| {
table_ptr[i] = make_table_pte(mi.phys.early_alloc());
}
}