Split PageTable struct out from hulk.hurl to hulk.pagetable
This commit is contained in:
1 parent
c11361d40f
commit
555ec9b627
3 files changed
+174
-77
No files matched your search
@@ -0,0 +1,164 @@
|
||||
/**
|
||||
* Page table structures.
|
||||
*/
|
||||
module hulk.pagetable;
|
||||
|
||||
/** Page table entry attributes. @{ */
|
||||
enum ulong PT_PRESENT = 0x1u;
|
||||
enum ulong PT_WRITABLE = 0x2u;
|
||||
enum ulong PT_USER = 0x4u;
|
||||
enum ulong PT_WRITE_THROUGH = 0x8u;
|
||||
enum ulong PT_DISABLE_CACHE = 0x10u;
|
||||
enum ulong PT_HUGE_PAGE = 0x80u;
|
||||
enum ulong PT_GLOBAL = 0x100u;
|
||||
enum ulong PT_NO_EXECUTE = 0x8000_0000_0000_0000u;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* Structure that represents a page table entry.
|
||||
*/
|
||||
struct PageTableEntry
|
||||
{
|
||||
/** The raw page table entry is a 64-bit ulong. */
|
||||
private ulong entry;
|
||||
alias entry this;
|
||||
|
||||
/**
|
||||
* Construct a page table entry.
|
||||
*
|
||||
* @param address
|
||||
* Address pointed to by the page table entry (ulong or pointer).
|
||||
* @param flags
|
||||
* Page table flags (ORed set of PT_*).
|
||||
*/
|
||||
this(T)(T address, ulong flags = 0u)
|
||||
{
|
||||
entry = cast(ulong)address | flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the page is present.
|
||||
*/
|
||||
public @property bool present() const
|
||||
{
|
||||
return (entry & PT_PRESENT) != 0u;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the page is writable.
|
||||
*/
|
||||
public @property bool writable() const
|
||||
{
|
||||
return (entry & PT_WRITABLE) != 0u;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the page is a user page.
|
||||
*/
|
||||
public @property bool user() const
|
||||
{
|
||||
return (entry & PT_USER) != 0u;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the page is write-through.
|
||||
*/
|
||||
public @property bool write_through() const
|
||||
{
|
||||
return (entry & PT_WRITE_THROUGH) != 0u;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the page has disable cache set.
|
||||
*/
|
||||
public @property bool disable_cache() const
|
||||
{
|
||||
return (entry & PT_DISABLE_CACHE) != 0u;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the page is huge.
|
||||
*/
|
||||
public @property bool huge() const
|
||||
{
|
||||
return (entry & PT_HUGE_PAGE) != 0u;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the page is global.
|
||||
*/
|
||||
public @property bool global() const
|
||||
{
|
||||
return (entry & PT_GLOBAL) != 0u;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the page is no-execute.
|
||||
*/
|
||||
public @property bool no_execute() const
|
||||
{
|
||||
return (entry & PT_NO_EXECUTE) != 0u;
|
||||
}
|
||||
|
||||
/**
|
||||
* Follow the page table entry to the next page table it points to.
|
||||
*/
|
||||
public PageTable * follow() const
|
||||
{
|
||||
return cast(PageTable *)(entry & 0x7FFF_FFFF_FFFF_F000u);
|
||||
}
|
||||
}
|
||||
static assert(PageTableEntry.sizeof == 8u);
|
||||
|
||||
/**
|
||||
* Structure that represents a page table.
|
||||
*/
|
||||
struct PageTable
|
||||
{
|
||||
/** Page table entries. */
|
||||
private PageTableEntry[512] entries;
|
||||
|
||||
/**
|
||||
* Access the PageTableEntry for the given address and page table level.
|
||||
*
|
||||
* @param address
|
||||
* Address to look up the page table entry (ulong or pointer).
|
||||
* @param level
|
||||
* Page table level (0-4).
|
||||
*/
|
||||
public PageTableEntry opIndex(T)(T address, ulong level)
|
||||
{
|
||||
return entries[pt_index(cast(ulong)address, level)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign the PageTableEntry for the given address and page table level.
|
||||
*
|
||||
* @param pte
|
||||
* PageTableEntry value to assign.
|
||||
* @param address
|
||||
* Address to look up the page table entry (ulong or pointer).
|
||||
* @param level
|
||||
* Page table level (0-4).
|
||||
*/
|
||||
public PageTableEntry opIndexAssign(T)(PageTableEntry pte, T address, ulong level)
|
||||
{
|
||||
entries[pt_index(cast(ulong)address, level)] = pte;
|
||||
return pte;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the index into the page table for the given address and page
|
||||
* table level.
|
||||
*
|
||||
* @param address
|
||||
* Address to look up the page table entry (ulong or pointer).
|
||||
* @param level
|
||||
* Page table level (0-4).
|
||||
*/
|
||||
public ulong pt_index(T)(T address, ulong level)
|
||||
{
|
||||
return (cast(ulong)address >> (39u - (9u * level))) & 0x1FFu;
|
||||
}
|
||||
}
|
||||
static assert(PageTable.sizeof == 4096u);
|
||||
Reference in new issue
Block a user