Modify map_pages

This commit is contained in:
songyanguang
2024-12-19 21:34:23 +08:00
parent a2ed0ee073
commit 197957f202
5 changed files with 69 additions and 41 deletions
@@ -38,9 +38,11 @@ Modification:
static struct PagerRightGroup right_group;
struct MmuCommonDone* _p_pgtbl_mmu_access = NULL;
static bool _new_pgdir(struct TopLevelPageDirectory* pgdir)
{
void* new_pgdir_addr = 0;
if (UNLIKELY((new_pgdir_addr = kalloc(TOPLEVLE_PAGEDIR_SIZE)) == NULL)) {
return false;
}
@@ -70,7 +72,7 @@ static bool _map_pages(uintptr_t* pgdir, uintptr_t vaddr, uintptr_t paddr, intpt
return false;
}
*pte = paddr | attr;
*pte = PFN_PTE(PFN_DOWN(paddr)) | attr;
if (vaddr == vaddr_last) {
break;
@@ -170,7 +172,6 @@ static uintptr_t _resize_user_pgdir(struct MemSpace* pmemspace, uintptr_t old_si
return cur_size;
}
CreateResourceTag(NULL, &pmemspace->tag, NULL, TRACER_MEM_FROM_BUDDY_AC_RESOURCE, V2P_WO(new_page));
return new_size;
}
@@ -246,6 +247,19 @@ bool module_pager_init(struct PagerRightGroup* _right_group)
return _p_pgtbl_mmu_access != NULL;
}
#if 0
static int test_access_map_address(void)
{
unsigned long address = KERN_MEM_BASE + (PHY_MEM_STOP - PHY_MEM_BASE) - 4096;
printf_early("%s to access 0x%lx\n", __func__, address);
*(unsigned long *)address = 0x55;
if(*(unsigned long *)address == 0x55) {
printf_early("%s access 0x%lx done\n", __func__, address);
}
return 0;
}
#endif
/// @brief kernel pagedir
struct TopLevelPageDirectory kern_pgdir;
@@ -259,17 +273,24 @@ void load_kern_pgdir(struct TraceTag* mmu_driver_tag, struct TraceTag* intr_driv
if (!_new_pgdir(&kern_pgdir)) {
panic("cannot alloc kernel page directory");
}
uintptr_t kern_attr = 0;
_p_pgtbl_mmu_access->MmuKernPteAttr(&kern_attr);
uintptr_t dev_attr = 0;
_p_pgtbl_mmu_access->MmuDevPteAttr(&dev_attr);
// kern mem link
_map_pages((uintptr_t*)kern_pgdir.pd_addr, KERNEL_LINK_ADDR, PHY_MEM_BASE, (PHY_USER_FREEMEM_BASE - PHY_MEM_BASE), kern_attr);
// kern mem
_map_pages((uintptr_t*)kern_pgdir.pd_addr, KERN_MEM_BASE, PHY_MEM_BASE, (PHY_MEM_STOP - PHY_MEM_BASE), kern_attr);
// dev mem
_map_pages((uintptr_t*)kern_pgdir.pd_addr, DEV_VRTMEM_BASE, DEV_PHYMEM_BASE, DEV_MEM_SIZE, dev_attr);
_p_pgtbl_mmu_access->LoadPgdir((uintptr_t)V2P(kern_pgdir.pd_addr));
#if 0
test_access_map_address();
#endif
}
void secondary_cpu_load_kern_pgdir(struct TraceTag* mmu_driver_tag, struct TraceTag* intr_driver_tag)
@@ -38,7 +38,6 @@ Modification:
uintptr_t* _page_walk(uintptr_t* pgdir, uintptr_t vaddr, bool alloc)
{
// get page table addr
assert(pgdir != NULL);
uintptr_t pde_attr = 0;
@@ -48,7 +47,7 @@ uintptr_t* _page_walk(uintptr_t* pgdir, uintptr_t vaddr, bool alloc)
uintptr_t* l3_pde_vaddr;
if (*l2_pde_ptr != 0) {
uintptr_t l3_table_paddr = ALIGNDOWN(*l2_pde_ptr, PAGE_SIZE);
uintptr_t l3_table_paddr = PFN_PHYS(_PGD_PFN(*l2_pde_ptr));
l3_pde_vaddr = (uintptr_t*)P2V(l3_table_paddr);
} else {
if (!alloc || !(l3_pde_vaddr = (uintptr_t*)kalloc(sizeof(uintptr_t) * NUM_LEVEL3_PDE))) {
@@ -56,14 +55,14 @@ uintptr_t* _page_walk(uintptr_t* pgdir, uintptr_t vaddr, bool alloc)
}
memset(l3_pde_vaddr, 0, sizeof(uintptr_t) * NUM_LEVEL3_PDE);
*l2_pde_ptr = V2P(l3_pde_vaddr) | pde_attr;
*l2_pde_ptr = PFN_PGD(PFN_DOWN(V2P(l3_pde_vaddr))) | pde_attr;
}
uintptr_t* l3_pde_ptr = (uintptr_t*)&l3_pde_vaddr[(vaddr >> LEVEL3_PDE_SHIFT) & (NUM_LEVEL3_PDE - 1)];
uintptr_t* l4_pte_vaddr;
if (*l3_pde_ptr != 0) {
uintptr_t l4_table_paddr = ALIGNDOWN(*l3_pde_ptr, PAGE_SIZE);
uintptr_t l4_table_paddr = PFN_PHYS(_PMD_PFN(*l3_pde_ptr));
l4_pte_vaddr = (uintptr_t*)P2V(l4_table_paddr);
} else {
if (!alloc || !(l4_pte_vaddr = (uintptr_t*)kalloc(sizeof(uintptr_t) * NUM_LEVEL4_PTE))) {
@@ -71,12 +70,13 @@ uintptr_t* _page_walk(uintptr_t* pgdir, uintptr_t vaddr, bool alloc)
}
memset(l4_pte_vaddr, 0, sizeof(uintptr_t) * NUM_LEVEL4_PTE);
*l3_pde_ptr = V2P(l4_pte_vaddr) | pde_attr;
*l3_pde_ptr = PFN_PMD(PFN_DOWN(V2P(l4_pte_vaddr))) | pde_attr;
}
return &l4_pte_vaddr[LEVEL4_PTE_IDX(vaddr)];
}
void _free_user_pgdir(struct TopLevelPageDirectory* pgdir)
{
if (pgdir->pd_addr == NULL) {
@@ -87,11 +87,11 @@ void _free_user_pgdir(struct TopLevelPageDirectory* pgdir)
for (uintptr_t l2_entry_idx = 0; l2_entry_idx < end_idx; l2_entry_idx++) {
// free each level3 page table
uintptr_t* l3_table_paddr = (uintptr_t*)ALIGNDOWN(pgdir->pd_addr[l2_entry_idx], PAGE_SIZE);
uintptr_t* l3_table_paddr = (uintptr_t*)PFN_PHYS(_PMD_PFN(pgdir->pd_addr[l2_entry_idx]));
if (l3_table_paddr != NULL) {
uintptr_t* l3_table_vaddr = P2V(l3_table_paddr);
for (uintptr_t l3_entry_idx = 0; l3_entry_idx < NUM_LEVEL3_PDE; l3_entry_idx++) {
uintptr_t* l4_table_paddr = (uintptr_t*)LEVEL4_PTE_ADDR(l3_table_vaddr[l3_entry_idx]);
uintptr_t* l4_table_paddr = (uintptr_t*)PFN_PHYS(_PTE_PFN(l3_table_vaddr[l3_entry_idx]));
if (l4_table_paddr != NULL) {
kfree(P2V(l4_table_paddr));
}