Adapt new vmm to 5-level paging as well
This commit is contained in:
parent
0c7e08d3c7
commit
1ccf8e34bc
|
@ -23,19 +23,35 @@ static pt_entry_t *get_next_level(pt_entry_t *current_level, size_t entry) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
pagemap_t new_pagemap(void) {
|
pagemap_t new_pagemap(int lv) {
|
||||||
return (pagemap_t)(size_t)balloc_aligned(PT_SIZE, PT_SIZE);
|
pagemap_t pagemap;
|
||||||
|
pagemap.levels = lv;
|
||||||
|
pagemap.top_level = balloc_aligned(PT_SIZE, PT_SIZE);
|
||||||
|
return pagemap;
|
||||||
}
|
}
|
||||||
|
|
||||||
void map_page(pagemap_t pagemap, uint64_t virt_addr, uint64_t phys_addr, uint64_t flags) {
|
void map_page(pagemap_t pagemap, uint64_t virt_addr, uint64_t phys_addr, uint64_t flags) {
|
||||||
// Calculate the indices in the various tables using the virtual address
|
// Calculate the indices in the various tables using the virtual address
|
||||||
|
size_t pml5_entry = (virt_addr & ((uint64_t)0x1ff << 48)) >> 48;
|
||||||
size_t pml4_entry = (virt_addr & ((uint64_t)0x1ff << 39)) >> 39;
|
size_t pml4_entry = (virt_addr & ((uint64_t)0x1ff << 39)) >> 39;
|
||||||
size_t pml3_entry = (virt_addr & ((uint64_t)0x1ff << 30)) >> 30;
|
size_t pml3_entry = (virt_addr & ((uint64_t)0x1ff << 30)) >> 30;
|
||||||
size_t pml2_entry = (virt_addr & ((uint64_t)0x1ff << 21)) >> 21;
|
size_t pml2_entry = (virt_addr & ((uint64_t)0x1ff << 21)) >> 21;
|
||||||
|
|
||||||
pt_entry_t *pml4 = (pt_entry_t *)(size_t)pagemap;
|
pt_entry_t *pml5, *pml4, *pml3, *pml2;
|
||||||
pt_entry_t *pml3 = get_next_level(pml4, pml4_entry);
|
|
||||||
pt_entry_t *pml2 = get_next_level(pml3, pml3_entry);
|
// Paging levels
|
||||||
|
switch (pagemap.levels) {
|
||||||
|
case 5:
|
||||||
|
pml5 = pagemap.top_level;
|
||||||
|
pml4 = get_next_level(pml5, pml5_entry);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
pml4 = pagemap.top_level;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
pml3 = get_next_level(pml4, pml4_entry);
|
||||||
|
pml2 = get_next_level(pml3, pml3_entry);
|
||||||
|
|
||||||
// Set the entry as present and point it to the passed physical address
|
// Set the entry as present and point it to the passed physical address
|
||||||
// Also set the specified flags
|
// Also set the specified flags
|
||||||
|
|
|
@ -5,9 +5,12 @@
|
||||||
|
|
||||||
#define PAGE_SIZE ((uint64_t)0x200000)
|
#define PAGE_SIZE ((uint64_t)0x200000)
|
||||||
|
|
||||||
typedef uint64_t pagemap_t;
|
typedef struct {
|
||||||
|
int levels;
|
||||||
|
void *top_level;
|
||||||
|
} pagemap_t;
|
||||||
|
|
||||||
pagemap_t new_pagemap(void);
|
pagemap_t new_pagemap(int lv);
|
||||||
void map_page(pagemap_t pagemap, uint64_t virt_addr, uint64_t phys_addr, uint64_t flags);
|
void map_page(pagemap_t pagemap, uint64_t virt_addr, uint64_t phys_addr, uint64_t flags);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -262,7 +262,6 @@ __attribute__((noreturn)) void stivale_spinup(int bits, bool level5pg,
|
||||||
pic_flush();
|
pic_flush();
|
||||||
|
|
||||||
if (bits == 64) {
|
if (bits == 64) {
|
||||||
void *pagemap_ptr;
|
|
||||||
if (level5pg) {
|
if (level5pg) {
|
||||||
// Enable CR4.LA57
|
// Enable CR4.LA57
|
||||||
ASM(
|
ASM(
|
||||||
|
@ -270,55 +269,19 @@ __attribute__((noreturn)) void stivale_spinup(int bits, bool level5pg,
|
||||||
"bts eax, 12\n\t"
|
"bts eax, 12\n\t"
|
||||||
"mov cr4, eax\n\t", :: "eax", "memory"
|
"mov cr4, eax\n\t", :: "eax", "memory"
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
struct pagemap {
|
pagemap_t pagemap = new_pagemap(level5pg ? 5 : 4);
|
||||||
uint64_t pml5[512];
|
|
||||||
uint64_t pml4_lo[512];
|
|
||||||
uint64_t pml4_hi[512];
|
|
||||||
uint64_t pml3_lo[512];
|
|
||||||
uint64_t pml3_hi[512];
|
|
||||||
uint64_t pml2_0gb[512];
|
|
||||||
uint64_t pml2_1gb[512];
|
|
||||||
uint64_t pml2_2gb[512];
|
|
||||||
uint64_t pml2_3gb[512];
|
|
||||||
};
|
|
||||||
struct pagemap *pagemap = balloc_aligned(sizeof(struct pagemap), 0x1000);
|
|
||||||
pagemap_ptr = (void *)pagemap;
|
|
||||||
|
|
||||||
// zero out the pagemap
|
// Map 0 to 2GiB at 0xffffffff80000000
|
||||||
for (uint64_t *p = (uint64_t *)pagemap; p < &pagemap->pml3_hi[512]; p++)
|
for (uint64_t i = 0; i < 0x80000000; i += PAGE_SIZE) {
|
||||||
*p = 0;
|
map_page(pagemap, i + 0xffffffff80000000, i, 0x03);
|
||||||
|
}
|
||||||
|
|
||||||
pagemap->pml5[511] = (uint64_t)(size_t)pagemap->pml4_hi | 0x03;
|
// Map 0 to 4GiB at 0xffff800000000000 and 0
|
||||||
pagemap->pml5[0] = (uint64_t)(size_t)pagemap->pml4_lo | 0x03;
|
for (uint64_t i = 0; i < 0x100000000; i += PAGE_SIZE) {
|
||||||
pagemap->pml4_hi[511] = (uint64_t)(size_t)pagemap->pml3_hi | 0x03;
|
map_page(pagemap, i, i, 0x03);
|
||||||
pagemap->pml4_hi[256] = (uint64_t)(size_t)pagemap->pml3_lo | 0x03;
|
map_page(pagemap, i + 0xffff800000000000, i, 0x03);
|
||||||
pagemap->pml4_lo[0] = (uint64_t)(size_t)pagemap->pml3_lo | 0x03;
|
|
||||||
pagemap->pml3_hi[510] = (uint64_t)(size_t)pagemap->pml2_0gb | 0x03;
|
|
||||||
pagemap->pml3_hi[511] = (uint64_t)(size_t)pagemap->pml2_1gb | 0x03;
|
|
||||||
pagemap->pml3_lo[0] = (uint64_t)(size_t)pagemap->pml2_0gb | 0x03;
|
|
||||||
pagemap->pml3_lo[1] = (uint64_t)(size_t)pagemap->pml2_1gb | 0x03;
|
|
||||||
pagemap->pml3_lo[2] = (uint64_t)(size_t)pagemap->pml2_2gb | 0x03;
|
|
||||||
pagemap->pml3_lo[3] = (uint64_t)(size_t)pagemap->pml2_3gb | 0x03;
|
|
||||||
|
|
||||||
// populate the page directories
|
|
||||||
for (size_t i = 0; i < 512 * 4; i++)
|
|
||||||
(&pagemap->pml2_0gb[0])[i] = (i * 0x200000) | 0x03 | (1 << 7);
|
|
||||||
} else {
|
|
||||||
pagemap_t pagemap = new_pagemap();
|
|
||||||
|
|
||||||
// Map 0 to 2GiB at 0xffffffff80000000
|
|
||||||
for (uint64_t i = 0; i < 0x80000000; i += PAGE_SIZE) {
|
|
||||||
map_page(pagemap, i + 0xffffffff80000000, i, 0x03);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Map 0 to 4GiB at 0xffff800000000000 and 0
|
|
||||||
for (uint64_t i = 0; i < 0x100000000; i += PAGE_SIZE) {
|
|
||||||
map_page(pagemap, i, i, 0x03);
|
|
||||||
map_page(pagemap, i + 0xffff800000000000, i, 0x03);
|
|
||||||
}
|
|
||||||
|
|
||||||
pagemap_ptr = (void *)pagemap;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ASM(
|
ASM(
|
||||||
|
@ -367,7 +330,7 @@ __attribute__((noreturn)) void stivale_spinup(int bits, bool level5pg,
|
||||||
|
|
||||||
"iretq\n\t"
|
"iretq\n\t"
|
||||||
".code32\n\t",
|
".code32\n\t",
|
||||||
: "a" (pagemap_ptr), "b" (&entry_point),
|
: "a" (pagemap.top_level), "b" (&entry_point),
|
||||||
"D" (stivale_struct), "S" (&stack)
|
"D" (stivale_struct), "S" (&stack)
|
||||||
: "memory"
|
: "memory"
|
||||||
);
|
);
|
||||||
|
|
|
@ -7,7 +7,13 @@ stivale_header:
|
||||||
dq 0 ; entry point
|
dq 0 ; entry point
|
||||||
dq stack.top ; rsp
|
dq stack.top ; rsp
|
||||||
dq 0 ; flags
|
dq 0 ; flags
|
||||||
dq 0 ; tags
|
dq lv5 ; tags
|
||||||
|
|
||||||
|
section .rodata
|
||||||
|
|
||||||
|
lv5:
|
||||||
|
dq 0x932f477032007e8f
|
||||||
|
dq 0
|
||||||
|
|
||||||
section .bss
|
section .bss
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue