Xenon/src/paging/pdp.zig

100 lines
2.6 KiB
Zig

const std = @import("std");
const assert = std.debug.assert;
const PageDirectory = @import("pd.zig").PageDirectory;
pub const PageDirectoryPointer = packed struct {
const Self = @This();
entries: [512]Entry_,
pub fn getEntry(self: *Self, ptr: var) *Entry_ {
const address = @ptrToInt(ptr);
return &self.entries[address >> 30 & 0x1ff];
}
pub fn getEntryConst(self: *const Self, ptr: var) *const Entry_ {
const address = @ptrToInt(ptr);
return &self.entries[address >> 30 & 0x1ff];
}
pub fn toPhysical(self: *const Self, ptr: var) ?@TypeOf(ptr) {
const entry = self.getEntryConst(ptr);
if (!entry.present()) return null;
const address = @ptrToInt(ptr);
return if (entry.ps())
@intToPtr(@TypeOf(ptr), entry.pageStart() + (address & 0x3fffffff))
else
entry.ptr().toPhysical(ptr);
}
pub const Entry_ = packed struct {
comptime {
assert(@sizeOf(Entry) != 8); // zig #2627 might have been fixed, use Entry
}
value: u64,
usingnamespace @import("mixin.zig").PageEntryMixin();
const ptr_mask: u64 = 0xffffffffff000;
pub inline fn pageStart(self: @This()) usize {
return self.value & ptr_mask;
}
pub inline fn ptr(self: @This()) *PageDirectory {
const address = self.value & ptr_mask;
return @intToPtr(*PageDirectory, address);
}
pub inline fn ptrSet(self: *@This(), new_ptr: *PageDirectory) void {
self.value = (self.value & ~ptr_mask) | @ptrToInt(new_ptr);
}
pub inline fn ptrPsSet(self: *@This(), new_ptr: *allowzero u8) void {
self.value = (self.value & ~ptr_mask) | @ptrToInt(new_ptr);
}
};
pub const Entry = packed struct {
/// Table is loaded into physical memory
present: bool,
/// Allow writes to lower levels
read_write: bool,
/// Allow usermode access
user_supervisor: bool,
/// Table is writeback on false, otherwise writethrough
pwt: bool,
/// Table is cacheable
pcd: bool,
/// Table has been accessed
accessed: bool,
_ign6: u1,
/// Table uses 1GB page translation
ps: bool,
_ign8: u1,
avl: u3,
_ptr: u40,
available: u11,
/// Forbid execution of lower levels
no_execute: bool,
pub inline fn ptr(self: @This()) *PageDirectory {
const address = @bitCast(u64, self) & 0xffffffffff000;
return @intToPtr(*PageDirectory, address);
}
};
};