Compare commits
No commits in common. "89f7d2120f0b3efc55249c7cb86f627701a87f7e" and "b0e59b3e26482d681e187b962a4d87c25187a230" have entirely different histories.
89f7d2120f
...
b0e59b3e26
@ -65,7 +65,7 @@ struct hippo
|
|||||||
ulong phys = header.bootinfo.memory_map[bii].base;
|
ulong phys = header.bootinfo.memory_map[bii].base;
|
||||||
ulong phys_end = phys + header.bootinfo.memory_map[bii].size;
|
ulong phys_end = phys + header.bootinfo.memory_map[bii].size;
|
||||||
usable_memory += header.bootinfo.memory_map[bii].size;
|
usable_memory += header.bootinfo.memory_map[bii].size;
|
||||||
while (phys < phys_end)
|
phys_loop: while (phys < phys_end)
|
||||||
{
|
{
|
||||||
bool is_reserved = false;
|
bool is_reserved = false;
|
||||||
for (size_t ri = 0u; ri < reserved.length; ri++)
|
for (size_t ri = 0u; ri < reserved.length; ri++)
|
||||||
@ -111,7 +111,7 @@ struct hippo
|
|||||||
public static void * allocate_page()
|
public static void * allocate_page()
|
||||||
{
|
{
|
||||||
PhysicalPage * pp;
|
PhysicalPage * pp;
|
||||||
if (free_pages != null)
|
if (pp != null)
|
||||||
{
|
{
|
||||||
pp = free_pages;
|
pp = free_pages;
|
||||||
free_pages = free_pages.next;
|
free_pages = free_pages.next;
|
||||||
|
109
src/hulk/hurl.d
109
src/hulk/hurl.d
@ -5,10 +5,6 @@
|
|||||||
*/
|
*/
|
||||||
module hulk.hurl;
|
module hulk.hurl;
|
||||||
|
|
||||||
import hos.cpu;
|
|
||||||
import hulk.hippo;
|
|
||||||
import hos.memory;
|
|
||||||
|
|
||||||
/** HULK virtual base address. */
|
/** HULK virtual base address. */
|
||||||
enum ulong HULK_VIRTUAL_BASE_ADDRESS = 0xFFFF_8000_0000_0000u;
|
enum ulong HULK_VIRTUAL_BASE_ADDRESS = 0xFFFF_8000_0000_0000u;
|
||||||
|
|
||||||
@ -17,108 +13,3 @@ enum ulong HULK_VIRTUAL_STACK_TOP_ADDRESS = 0xFFFF_A000_0000_0000u;
|
|||||||
|
|
||||||
/** HULK virtual framebuffer address. */
|
/** HULK virtual framebuffer address. */
|
||||||
enum ulong HULK_VIRTUAL_FRAMEBUFFER_ADDRESS = 0xFFFF_A000_0000_0000u;
|
enum ulong HULK_VIRTUAL_FRAMEBUFFER_ADDRESS = 0xFFFF_A000_0000_0000u;
|
||||||
|
|
||||||
/** Page table entry attributes. @{ */
|
|
||||||
enum ulong MAP_PRESENT = 0x1u;
|
|
||||||
enum ulong MAP_WRITABLE = 0x2u;
|
|
||||||
enum ulong MAP_USER = 0x4u;
|
|
||||||
enum ulong MAP_WRITE_THROUGH = 0x8u;
|
|
||||||
enum ulong MAP_DISABLE_CACHE = 0x10u;
|
|
||||||
enum ulong MAP_HUGE_PAGE = 0x20u;
|
|
||||||
enum ulong MAP_GLOBAL = 0x40u;
|
|
||||||
enum ulong MAP_NO_EXECUTE = 0x8000_0000_0000_0000u;
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
struct Hurl
|
|
||||||
{
|
|
||||||
private struct PageTableEntry
|
|
||||||
{
|
|
||||||
private ulong m_entry;
|
|
||||||
|
|
||||||
this(ulong address, ulong flags)
|
|
||||||
{
|
|
||||||
m_entry = address | flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
this(void * address, ulong flags)
|
|
||||||
{
|
|
||||||
m_entry = cast(ulong)address | flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
public @property bool present()
|
|
||||||
{
|
|
||||||
return (m_entry & MAP_PRESENT) != 0u;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PageTable * follow()
|
|
||||||
{
|
|
||||||
return cast(PageTable *)(m_entry & 0x7FFF_FFFF_FFFF_F000u);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private struct PageTable
|
|
||||||
{
|
|
||||||
public PageTableEntry opIndex(ulong address, ulong level)
|
|
||||||
{
|
|
||||||
PageTableEntry * entries = cast(PageTableEntry *)&this;
|
|
||||||
return entries[pt_index(address, level)];
|
|
||||||
}
|
|
||||||
|
|
||||||
public PageTableEntry opIndex(void * address, ulong level)
|
|
||||||
{
|
|
||||||
return opIndex(cast(ulong)address, level);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PageTableEntry opIndexAssign(PageTableEntry pte, ulong address, ulong level)
|
|
||||||
{
|
|
||||||
PageTableEntry * entries = cast(PageTableEntry *)&this;
|
|
||||||
entries[pt_index(address, level)] = pte;
|
|
||||||
return pte;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PageTableEntry opIndexAssign(PageTableEntry pte, void * address, ulong level)
|
|
||||||
{
|
|
||||||
return opIndexAssign(pte, cast(ulong)address, level);
|
|
||||||
}
|
|
||||||
|
|
||||||
private ulong pt_index(ulong address, ulong level)
|
|
||||||
{
|
|
||||||
return (address >> (39u - (9u * level))) & 0x1FFu;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static __gshared PageTable * m_pt_base;
|
|
||||||
|
|
||||||
public static void initialize()
|
|
||||||
{
|
|
||||||
m_pt_base = cast(PageTable *)read_cr3();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void map(ulong virtual, ulong physical, ulong flags)
|
|
||||||
{
|
|
||||||
size_t last_level = ((flags & MAP_HUGE_PAGE) != 0u) ? 2u : 3u;
|
|
||||||
PageTable * pt = m_pt_base;
|
|
||||||
for (size_t level = 0; level <= last_level; level++)
|
|
||||||
{
|
|
||||||
if (level < last_level)
|
|
||||||
{
|
|
||||||
PageTableEntry entry = (*pt)[virtual, level];
|
|
||||||
if (entry.present)
|
|
||||||
{
|
|
||||||
pt = entry.follow();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PageTable * next_pt = cast(PageTable *)hippo.allocate_page();
|
|
||||||
memset32(next_pt, 0, 4096u / 4u);
|
|
||||||
(*pt)[virtual, level] = PageTableEntry(next_pt, MAP_WRITABLE | MAP_PRESENT);
|
|
||||||
pt = next_pt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
(*pt)[virtual, level] = PageTableEntry(physical, flags | MAP_PRESENT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user