|
|
|
@ -104,15 +104,14 @@ int map_page(uintptr_t phys, void *virt, enum mm_page_flags flags)
|
|
|
|
|
usize pd_index = ((uintptr_t)virt >> PAGE_SHIFT) / 1024;
|
|
|
|
|
usize pt_index = ((uintptr_t)virt >> PAGE_SHIFT) % 1024;
|
|
|
|
|
|
|
|
|
|
struct x86_page_directory *pd = X86_CURRENT_PD;
|
|
|
|
|
/*
|
|
|
|
|
* warning: pt might not be present yet before the if block below,
|
|
|
|
|
* we only define it here already so we can easily call memset() in
|
|
|
|
|
* the if block
|
|
|
|
|
*/
|
|
|
|
|
struct x86_page_table *pt = &X86_CURRENT_PT_BASE[pd_index];
|
|
|
|
|
struct x86_page_table *pt = X86_CURRENT_PT(pd_index);
|
|
|
|
|
|
|
|
|
|
struct x86_page_directory_entry *pd_entry = &pd->entries[pd_index];
|
|
|
|
|
struct x86_page_directory_entry *pd_entry = &X86_CURRENT_PD->entries[pd_index];
|
|
|
|
|
if (!pd_entry->present) {
|
|
|
|
|
uintptr_t pt_phys = get_page();
|
|
|
|
|
if (!pt_phys)
|
|
|
|
@ -153,7 +152,7 @@ uintptr_t unmap_page(void *virt)
|
|
|
|
|
if (!pd_entry->present)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
struct x86_page_table *pt = &X86_CURRENT_PT_BASE[pd_index];
|
|
|
|
|
struct x86_page_table *pt = X86_CURRENT_PT(pd_index);
|
|
|
|
|
struct x86_page_table_entry *pt_entry = &pt->entries[pt_index];
|
|
|
|
|
if (!pt_entry->present)
|
|
|
|
|
return 0;
|
|
|
|
@ -170,8 +169,13 @@ uintptr_t get_page(void)
|
|
|
|
|
|
|
|
|
|
for (usize i = 0; i < pagemap_len; i++) {
|
|
|
|
|
if (~pagemap[i] != 0) {
|
|
|
|
|
int bit = ffsl((long)~pagemap[i]);
|
|
|
|
|
if (bit < sizeof(*pagemap) * 8) {
|
|
|
|
|
/*
|
|
|
|
|
* for some stupid reason, the bit index returned by
|
|
|
|
|
* ffsl() starts at 1 rather than 0
|
|
|
|
|
* (and is 0 if there is no bit set)
|
|
|
|
|
*/
|
|
|
|
|
int bit = ffsl((long)~pagemap[i]) - 1;
|
|
|
|
|
if (bit >= 0) {
|
|
|
|
|
unsigned long page_number = i * sizeof(*pagemap) * 8 + bit;
|
|
|
|
|
page = dynpage_start + page_number * PAGE_SIZE;
|
|
|
|
|
pagemap[i] |= (1lu << bit);
|
|
|
|
@ -258,7 +262,7 @@ uintptr_t virt_to_phys(void *virt)
|
|
|
|
|
if (!pd->entries[pd_index].present)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
struct x86_page_table *pt = &X86_CURRENT_PT_BASE[pd_index];
|
|
|
|
|
struct x86_page_table *pt = X86_CURRENT_PT(pd_index);
|
|
|
|
|
if (!pt->entries[pt_index].present)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
@ -308,15 +312,14 @@ static void setup_pagemap(void)
|
|
|
|
|
* map it to a virtual address so we can fill its entries.
|
|
|
|
|
* So this is basically a replacement for a call to map_page().
|
|
|
|
|
*/
|
|
|
|
|
struct x86_page_directory *pd = X86_CURRENT_PD;
|
|
|
|
|
struct x86_page_directory_entry *pd_entry = &pd->entries[1022];
|
|
|
|
|
struct x86_page_directory_entry *pd_entry = &X86_CURRENT_PD->entries[1022];
|
|
|
|
|
*(unsigned long *)pd_entry = 0;
|
|
|
|
|
pd_entry->shifted_address = (uintptr_t)pt_phys >> PAGE_SHIFT;
|
|
|
|
|
pd_entry->shifted_address = pt_phys >> PAGE_SHIFT;
|
|
|
|
|
pd_entry->rw = 1;
|
|
|
|
|
pd_entry->present = 1;
|
|
|
|
|
vm_flush();
|
|
|
|
|
|
|
|
|
|
struct x86_page_table *pt = &X86_CURRENT_PT_BASE[1022];
|
|
|
|
|
struct x86_page_table *pt = X86_CURRENT_PT(1022);
|
|
|
|
|
memset(pt, 0, sizeof(*pt));
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|