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

View File

@ -35,21 +35,29 @@ Modification:
#include "mmu_common.h" #include "mmu_common.h"
#include "trap_common.h" #include "trap_common.h"
#include "asm/csr.h"
#include "asm/pfn.h"
#include "printf.h"
// extern struct MmuCommonDone mmu_common_done; // extern struct MmuCommonDone mmu_common_done;
static struct MmuDriverRightGroup right_group; static struct MmuDriverRightGroup right_group;
void load_pgdir(uintptr_t pgdir_paddr) void load_pgdir(uintptr_t pgdir_paddr)
{ {
/* get cache driver */ /* get cache driver */
struct ICacheDone* p_icache_done = AchieveResource(&right_group.icache_driver_tag); struct ICacheDone* p_icache_done = AchieveResource(&right_group.icache_driver_tag);
struct DCacheDone* p_dcache_done = AchieveResource(&right_group.dcache_driver_tag); struct DCacheDone* p_dcache_done = AchieveResource(&right_group.dcache_driver_tag);
TTBR0_W((uint64_t)pgdir_paddr); printk("load_pgdir pgdir_paddr=%08lx\n", pgdir_paddr);
DSB(); csr_write(CSR_SATP, PFN_DOWN(pgdir_paddr) | SATP_MODE);
CLEARTLB(0); __asm__ __volatile__ ("sfence.vma" : : : "memory");
ISB(); printf_early("load_pgdir pgdir_paddr=%08lx ok\n", pgdir_paddr);
p_icache_done->invalidateall(); p_icache_done->invalidateall();
p_dcache_done->flushall(); p_dcache_done->flushall();
} }
__attribute__((always_inline)) inline static void _tlb_flush(uintptr_t va) __attribute__((always_inline)) inline static void _tlb_flush(uintptr_t va)

View File

@ -29,52 +29,37 @@ Modification:
#include "mmu.h" #include "mmu.h"
#include "mmu_common.h" #include "mmu_common.h"
// clang-format off #include "asm/pgtable-bits.h"
#define ARMV8_PTE_ATTR_MASK(attr) (((attr) & 0b111) << 2)
#define ARMV8_PTE_DEVICE ARMV8_PTE_ATTR_MASK(0x0)
#define ARMV8_PTE_NORMAL ARMV8_PTE_ATTR_MASK(0x1)
#define ARMV8_PTE_AP(ap) (((ap) & 0b11) << 6) #define _PAGE_KERNEL (_PAGE_READ \
#define ARMV8_PTE_AP_U ARMV8_PTE_AP(0x01) | _PAGE_WRITE \
#define ARMV8_PTE_AP_K ARMV8_PTE_AP(0x00) | _PAGE_PRESENT \
#define ARMV8_PTE_AP_RO ARMV8_PTE_AP(0b10) | _PAGE_ACCESSED \
#define ARMV8_PTE_AP_RW ARMV8_PTE_AP(0b00) | _PAGE_DIRTY \
| _PAGE_GLOBAL)
#define ARMV8_PTE_AF (0x1 << 10)
#define ARMV8_PTE_PXN (1ULL << 53) // Privileged eXecute Never
#define ARMV8_PTE_UXN (1ULL << 54) // Unprivileged(user) eXecute Never
#define ARMV8_PTE_XN (ARMV8_PTE_PXN | ARMV8_PTE_UXN)
#define ARMV8_PTE_VALID (0b11 << 0)
#define ARMV8_PDE_VALID (0b11 << 0)
// clang-format on
void GetUsrPteAttr(uintptr_t* attr) void GetUsrPteAttr(uintptr_t* attr)
{ {
// *attr = ARMV8_PTE_AP_U | ARMV8_PTE_AP_RW | ARMV8_PTE_AF | ARMV8_PTE_NORMAL | ARMV8_PTE_VALID; *attr = _PAGE_KERNEL | _PAGE_USER | _PAGE_EXEC;
*attr = 0x713 | ARMV8_PTE_AP_U;
} }
void GetUsrDevPteAttr(uintptr_t* attr) void GetUsrDevPteAttr(uintptr_t* attr)
{ {
// *attr = ARMV8_PTE_AP_U | ARMV8_PTE_AP_RW | ARMV8_PTE_AF | ARMV8_PTE_DEVICE | ARMV8_PTE_XN | ARMV8_PTE_VALID; *attr = _PAGE_KERNEL | _PAGE_USER;
*attr = 0x403 | ARMV8_PTE_AP_U;
} }
void GetDevPteAttr(uintptr_t* attr) void GetDevPteAttr(uintptr_t* attr)
{ {
// *attr = ARMV8_PTE_AP_K | ARMV8_PTE_AP_RW | ARMV8_PTE_AF | ARMV8_PTE_DEVICE | ARMV8_PTE_XN | ARMV8_PTE_VALID; *attr = _PAGE_KERNEL;
*attr = 0x403ULL;
} }
void GetKernPteAttr(uintptr_t* attr) void GetKernPteAttr(uintptr_t* attr)
{ {
// *attr = ARMV8_PTE_AP_K | ARMV8_PTE_AP_RW | ARMV8_PTE_AF | ARMV8_PTE_NORMAL | ARMV8_PTE_VALID; *attr = _PAGE_KERNEL | _PAGE_EXEC;
*attr = 0x713ULL;
} }
void GetPdeAttr(uintptr_t* attr) void GetPdeAttr(uintptr_t* attr)
{ {
*attr = ARMV8_PDE_VALID; *attr = _PAGE_PRESENT;
} }

View File

@ -48,6 +48,19 @@ Modification:
#define LEVEL3_PDE_ADDR(v) ALIGNDOWN(v, LEVEL3_PDE_SIZE) #define LEVEL3_PDE_ADDR(v) ALIGNDOWN(v, LEVEL3_PDE_SIZE)
#define TOPLEVLE_PAGEDIR_SIZE sizeof(uintptr_t) * NUM_TOPLEVEL_PDE #define TOPLEVLE_PAGEDIR_SIZE sizeof(uintptr_t) * NUM_TOPLEVEL_PDE
//#define PAGE_SHIFT (12)
#define _PAGE_PFN_SHIFT 10
#define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
#define PFN_PGD(x) ((x) << _PAGE_PFN_SHIFT)
#define PFN_PHYS(x) ((x) << PAGE_SHIFT)
#define _PGD_PFN(x) ((x) >> _PAGE_PFN_SHIFT)
#define PFN_PMD PFN_PGD
#define _PMD_PFN _PGD_PFN
#define PFN_PTE PFN_PGD
#define _PTE_PFN _PGD_PFN
// clang-format on // clang-format on
struct PagerRightGroup { struct PagerRightGroup {
@ -74,4 +87,5 @@ void load_kern_pgdir(struct TraceTag* mmu_driver_tag, struct TraceTag* intr_driv
void secondary_cpu_load_kern_pgdir(struct TraceTag* mmu_driver_tag, struct TraceTag* intr_driver_tag); void secondary_cpu_load_kern_pgdir(struct TraceTag* mmu_driver_tag, struct TraceTag* intr_driver_tag);
extern struct XiziPageManager xizi_pager; extern struct XiziPageManager xizi_pager;
bool module_pager_init(struct PagerRightGroup*); bool module_pager_init(struct PagerRightGroup*);
bool _new_pgdir(struct TopLevelPageDirectory* pgdir);

View File

@ -38,9 +38,11 @@ Modification:
static struct PagerRightGroup right_group; static struct PagerRightGroup right_group;
struct MmuCommonDone* _p_pgtbl_mmu_access = NULL; struct MmuCommonDone* _p_pgtbl_mmu_access = NULL;
static bool _new_pgdir(struct TopLevelPageDirectory* pgdir) static bool _new_pgdir(struct TopLevelPageDirectory* pgdir)
{ {
void* new_pgdir_addr = 0; void* new_pgdir_addr = 0;
if (UNLIKELY((new_pgdir_addr = kalloc(TOPLEVLE_PAGEDIR_SIZE)) == NULL)) { if (UNLIKELY((new_pgdir_addr = kalloc(TOPLEVLE_PAGEDIR_SIZE)) == NULL)) {
return false; return false;
} }
@ -70,7 +72,7 @@ static bool _map_pages(uintptr_t* pgdir, uintptr_t vaddr, uintptr_t paddr, intpt
return false; return false;
} }
*pte = paddr | attr; *pte = PFN_PTE(PFN_DOWN(paddr)) | attr;
if (vaddr == vaddr_last) { if (vaddr == vaddr_last) {
break; break;
@ -170,7 +172,6 @@ static uintptr_t _resize_user_pgdir(struct MemSpace* pmemspace, uintptr_t old_si
return cur_size; return cur_size;
} }
CreateResourceTag(NULL, &pmemspace->tag, NULL, TRACER_MEM_FROM_BUDDY_AC_RESOURCE, V2P_WO(new_page)); CreateResourceTag(NULL, &pmemspace->tag, NULL, TRACER_MEM_FROM_BUDDY_AC_RESOURCE, V2P_WO(new_page));
return new_size; return new_size;
} }
@ -246,6 +247,19 @@ bool module_pager_init(struct PagerRightGroup* _right_group)
return _p_pgtbl_mmu_access != NULL; 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 /// @brief kernel pagedir
struct TopLevelPageDirectory kern_pgdir; 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)) { if (!_new_pgdir(&kern_pgdir)) {
panic("cannot alloc kernel page directory"); panic("cannot alloc kernel page directory");
} }
uintptr_t kern_attr = 0; uintptr_t kern_attr = 0;
_p_pgtbl_mmu_access->MmuKernPteAttr(&kern_attr); _p_pgtbl_mmu_access->MmuKernPteAttr(&kern_attr);
uintptr_t dev_attr = 0; uintptr_t dev_attr = 0;
_p_pgtbl_mmu_access->MmuDevPteAttr(&dev_attr); _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 // kern mem
_map_pages((uintptr_t*)kern_pgdir.pd_addr, KERN_MEM_BASE, PHY_MEM_BASE, (PHY_MEM_STOP - PHY_MEM_BASE), kern_attr); _map_pages((uintptr_t*)kern_pgdir.pd_addr, KERN_MEM_BASE, PHY_MEM_BASE, (PHY_MEM_STOP - PHY_MEM_BASE), kern_attr);
// dev mem // dev mem
_map_pages((uintptr_t*)kern_pgdir.pd_addr, DEV_VRTMEM_BASE, DEV_PHYMEM_BASE, DEV_MEM_SIZE, dev_attr); _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)); _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) void secondary_cpu_load_kern_pgdir(struct TraceTag* mmu_driver_tag, struct TraceTag* intr_driver_tag)

View File

@ -38,7 +38,6 @@ Modification:
uintptr_t* _page_walk(uintptr_t* pgdir, uintptr_t vaddr, bool alloc) uintptr_t* _page_walk(uintptr_t* pgdir, uintptr_t vaddr, bool alloc)
{ {
// get page table addr // get page table addr
assert(pgdir != NULL); assert(pgdir != NULL);
uintptr_t pde_attr = 0; 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; uintptr_t* l3_pde_vaddr;
if (*l2_pde_ptr != 0) { 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); l3_pde_vaddr = (uintptr_t*)P2V(l3_table_paddr);
} else { } else {
if (!alloc || !(l3_pde_vaddr = (uintptr_t*)kalloc(sizeof(uintptr_t) * NUM_LEVEL3_PDE))) { 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); 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* l3_pde_ptr = (uintptr_t*)&l3_pde_vaddr[(vaddr >> LEVEL3_PDE_SHIFT) & (NUM_LEVEL3_PDE - 1)];
uintptr_t* l4_pte_vaddr; uintptr_t* l4_pte_vaddr;
if (*l3_pde_ptr != 0) { 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); l4_pte_vaddr = (uintptr_t*)P2V(l4_table_paddr);
} else { } else {
if (!alloc || !(l4_pte_vaddr = (uintptr_t*)kalloc(sizeof(uintptr_t) * NUM_LEVEL4_PTE))) { 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); 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)]; return &l4_pte_vaddr[LEVEL4_PTE_IDX(vaddr)];
} }
void _free_user_pgdir(struct TopLevelPageDirectory* pgdir) void _free_user_pgdir(struct TopLevelPageDirectory* pgdir)
{ {
if (pgdir->pd_addr == NULL) { 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++) { for (uintptr_t l2_entry_idx = 0; l2_entry_idx < end_idx; l2_entry_idx++) {
// free each level3 page table // 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) { if (l3_table_paddr != NULL) {
uintptr_t* l3_table_vaddr = P2V(l3_table_paddr); 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++) { 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) { if (l4_table_paddr != NULL) {
kfree(P2V(l4_table_paddr)); kfree(P2V(l4_table_paddr));
} }