Use hulk.pagetable from hello

This commit is contained in:
Josh Holtrop 2022-10-26 00:05:49 -04:00
parent 555ec9b627
commit 4a431f7d93
2 changed files with 19 additions and 57 deletions

View File

@ -8,7 +8,7 @@ import hello.console;
import hello.scratch; import hello.scratch;
import hulk.bootinfo; import hulk.bootinfo;
import hulk.header; import hulk.header;
import hos.page_table; import hulk.pagetable;
import hos.cpu; import hos.cpu;
import hos.memory; import hos.memory;
import ldc.llvmasm; import ldc.llvmasm;
@ -238,9 +238,9 @@ private void get_memory_map(ulong * bss_phys, ulong * stack_phys, ulong * physic
/** /**
* Allocate a new page table. * Allocate a new page table.
*/ */
private PageTableEntry * new_page_table() private PageTable * new_page_table()
{ {
PageTableEntry * pt = cast(PageTableEntry *)scratch.alloc(1u); PageTable * pt = cast(PageTable *)scratch.alloc(1u);
memset64(pt, 0u, 512); memset64(pt, 0u, 512);
return pt; return pt;
} }
@ -252,19 +252,18 @@ private PageTableEntry * new_page_table()
* @param dest_page Destination page address. * @param dest_page Destination page address.
* @param pt_base Page table base address. * @param pt_base Page table base address.
*/ */
private void map4k(ulong source_page, ulong dest_page, PageTableEntry * pt_base) private void map4k(ulong source_page, ulong dest_page, PageTable * pt_base)
{ {
PageTableEntry * pt = pt_base; PageTable * pt = pt_base;
PageTableEntry * next_pt;
for (size_t level = 0; level < 4u; level++) for (size_t level = 0; level < 4u; level++)
{ {
size_t pt_index = PageTableEntry.page_table_index(source_page, level); if ((*pt)[source_page, level].present)
if (pt[pt_index].present())
{ {
pt = pt[pt_index].next(); pt = (*pt)[source_page, level].follow();
} }
else else
{ {
PageTable * next_pt;
ulong addr; ulong addr;
if (level < 3u) if (level < 3u)
{ {
@ -275,8 +274,7 @@ private void map4k(ulong source_page, ulong dest_page, PageTableEntry * pt_base)
{ {
addr = dest_page; addr = dest_page;
} }
pt[pt_index] = PageTableEntry(addr, (*pt)[source_page, level] = PageTableEntry(addr, PT_WRITABLE | PT_PRESENT);
0u, 0u, 0u, 0u, 0u, 0u, 1u, 1u);
pt = next_pt; pt = next_pt;
} }
} }
@ -290,7 +288,7 @@ private void map4k(ulong source_page, ulong dest_page, PageTableEntry * pt_base)
* @param size Region size. * @param size Region size.
* @param pt_base Page table base address. * @param pt_base Page table base address.
*/ */
private void map4kregion(ulong source, ulong dest, size_t size, PageTableEntry * pt_base) private void map4kregion(ulong source, ulong dest, size_t size, PageTable * pt_base)
{ {
ulong end = source + size; ulong end = source + size;
while (source < end) while (source < end)
@ -308,29 +306,26 @@ private void map4kregion(ulong source, ulong dest, size_t size, PageTableEntry *
* @param dest_page Destination page address. * @param dest_page Destination page address.
* @param pt_base Page table base address. * @param pt_base Page table base address.
*/ */
private void map2m(ulong source_page, ulong dest_page, PageTableEntry * pt_base) private void map2m(ulong source_page, ulong dest_page, PageTable * pt_base)
{ {
PageTableEntry * pt = pt_base; PageTable * pt = pt_base;
PageTableEntry * next_pt;
for (size_t level = 0; level < 3u; level++) for (size_t level = 0; level < 3u; level++)
{ {
size_t pt_index = PageTableEntry.page_table_index(source_page, level); if ((*pt)[source_page, level].present)
if (pt[pt_index].present())
{ {
pt = pt[pt_index].next(); pt = (*pt)[source_page, level].follow();
} }
else else
{ {
PageTable * next_pt;
if (level < 2u) if (level < 2u)
{ {
next_pt = new_page_table(); next_pt = new_page_table();
pt[pt_index] = PageTableEntry(cast(ulong)next_pt, (*pt)[source_page, level] = PageTableEntry(next_pt, PT_WRITABLE | PT_PRESENT);
0u, 0u, 0u, 0u, 0u, 0u, 1u, 1u);
} }
else else
{ {
pt[pt_index] = PageTableEntry(dest_page, (*pt)[source_page, level] = PageTableEntry(dest_page, PT_HUGE_PAGE | PT_WRITABLE | PT_PRESENT);
0u, 0u, 1u, 0u, 0u, 0u, 1u, 1u);
} }
pt = next_pt; pt = next_pt;
} }
@ -342,7 +337,7 @@ private void map2m(ulong source_page, ulong dest_page, PageTableEntry * pt_base)
* *
* @param pt_base Page table base address. * @param pt_base Page table base address.
*/ */
private void map_hulk(PageTableEntry * pt_base, ulong bss_phys, ulong stack_phys) private void map_hulk(PageTable * pt_base, ulong bss_phys, ulong stack_phys)
{ {
/* Map HULK bin region. */ /* Map HULK bin region. */
ulong virt = hulk_virt_base_address(); ulong virt = hulk_virt_base_address();
@ -362,7 +357,7 @@ private void map_hulk(PageTableEntry * pt_base, ulong bss_phys, ulong stack_phys
*/ */
private void build_page_tables(ulong physical_address_limit, ulong bss_phys, ulong stack_phys) private void build_page_tables(ulong physical_address_limit, ulong bss_phys, ulong stack_phys)
{ {
PageTableEntry * pt_base = new_page_table(); PageTable * pt_base = new_page_table();
/* Map physical RAM. */ /* Map physical RAM. */
for (size_t addr = 0u; addr < physical_address_limit; addr += (2u * 1024u * 1024u)) for (size_t addr = 0u; addr < physical_address_limit; addr += (2u * 1024u * 1024u))
{ {

View File

@ -1,33 +0,0 @@
struct PageTableEntry
{
ulong entry;
this(ulong address, ulong no_execute, ulong global,
ulong huge, ulong disable_cache, ulong write_through, ulong user,
ulong writable, ulong present)
{
entry = (present |
(writable << 1) |
(user << 2) |
(write_through << 3) |
(disable_cache << 4) |
(huge << 7) |
(global << 8) |
(no_execute << 63)) | address;
}
bool present()
{
return (entry & 0x1u) != 0u;
}
PageTableEntry * next()
{
return cast(PageTableEntry *)(entry & 0x7FFF_FFFF_FFFF_F000u);
}
static ulong page_table_index(ulong address, size_t level)
{
return ((address >> (39u - 9u * level)) & 0x1FFu);
}
}