100 lines
2.6 KiB
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);
|
|
}
|
|
};
|
|
};
|