From 197957f202f2a3d1e60056f6a05d5b74eea39eb2 Mon Sep 17 00:00:00 2001 From: songyanguang <345810377@qq.com> Date: Thu, 19 Dec 2024 21:34:23 +0800 Subject: [PATCH] Modify map_pages --- .../hardkernel/mmu/riscv/rv64gc/mmu.c | 16 ++++++-- .../mmu/riscv/rv64gc/pagetable_attr.c | 39 ++++++------------- .../XiZi_AIoT/softkernel/include/pagetable.h | 16 +++++++- .../softkernel/memory/pagetable_riscv.c | 25 +++++++++++- .../memory/pagetable_riscv_level3.c | 14 +++---- 5 files changed, 69 insertions(+), 41 deletions(-) diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/mmu/riscv/rv64gc/mmu.c b/Ubiquitous/XiZi_AIoT/hardkernel/mmu/riscv/rv64gc/mmu.c index 7fcf5a1f6..508c88296 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/mmu/riscv/rv64gc/mmu.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/mmu/riscv/rv64gc/mmu.c @@ -35,21 +35,29 @@ Modification: #include "mmu_common.h" #include "trap_common.h" +#include "asm/csr.h" +#include "asm/pfn.h" +#include "printf.h" + + // extern struct MmuCommonDone mmu_common_done; static struct MmuDriverRightGroup right_group; void load_pgdir(uintptr_t pgdir_paddr) { + /* get cache driver */ struct ICacheDone* p_icache_done = AchieveResource(&right_group.icache_driver_tag); struct DCacheDone* p_dcache_done = AchieveResource(&right_group.dcache_driver_tag); - TTBR0_W((uint64_t)pgdir_paddr); - DSB(); - CLEARTLB(0); - ISB(); + printk("load_pgdir pgdir_paddr=%08lx\n", pgdir_paddr); + csr_write(CSR_SATP, PFN_DOWN(pgdir_paddr) | SATP_MODE); + __asm__ __volatile__ ("sfence.vma" : : : "memory"); + printf_early("load_pgdir pgdir_paddr=%08lx ok\n", pgdir_paddr); + p_icache_done->invalidateall(); p_dcache_done->flushall(); + } __attribute__((always_inline)) inline static void _tlb_flush(uintptr_t va) diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/mmu/riscv/rv64gc/pagetable_attr.c b/Ubiquitous/XiZi_AIoT/hardkernel/mmu/riscv/rv64gc/pagetable_attr.c index 8085ad036..9a540b040 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/mmu/riscv/rv64gc/pagetable_attr.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/mmu/riscv/rv64gc/pagetable_attr.c @@ -29,52 +29,37 @@ Modification: #include "mmu.h" #include "mmu_common.h" -// clang-format off -#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) +#include "asm/pgtable-bits.h" -#define ARMV8_PTE_AP(ap) (((ap) & 0b11) << 6) -#define ARMV8_PTE_AP_U ARMV8_PTE_AP(0x01) -#define ARMV8_PTE_AP_K ARMV8_PTE_AP(0x00) -#define ARMV8_PTE_AP_RO ARMV8_PTE_AP(0b10) -#define ARMV8_PTE_AP_RW ARMV8_PTE_AP(0b00) +#define _PAGE_KERNEL (_PAGE_READ \ + | _PAGE_WRITE \ + | _PAGE_PRESENT \ + | _PAGE_ACCESSED \ + | _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) { - // *attr = ARMV8_PTE_AP_U | ARMV8_PTE_AP_RW | ARMV8_PTE_AF | ARMV8_PTE_NORMAL | ARMV8_PTE_VALID; - *attr = 0x713 | ARMV8_PTE_AP_U; + *attr = _PAGE_KERNEL | _PAGE_USER | _PAGE_EXEC; } 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 = 0x403 | ARMV8_PTE_AP_U; + *attr = _PAGE_KERNEL | _PAGE_USER; } 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 = 0x403ULL; + *attr = _PAGE_KERNEL; } void GetKernPteAttr(uintptr_t* attr) { - // *attr = ARMV8_PTE_AP_K | ARMV8_PTE_AP_RW | ARMV8_PTE_AF | ARMV8_PTE_NORMAL | ARMV8_PTE_VALID; - *attr = 0x713ULL; + *attr = _PAGE_KERNEL | _PAGE_EXEC; } void GetPdeAttr(uintptr_t* attr) { - *attr = ARMV8_PDE_VALID; + *attr = _PAGE_PRESENT; } \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/softkernel/include/pagetable.h b/Ubiquitous/XiZi_AIoT/softkernel/include/pagetable.h index e0938d322..2894a4291 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/include/pagetable.h +++ b/Ubiquitous/XiZi_AIoT/softkernel/include/pagetable.h @@ -48,6 +48,19 @@ Modification: #define LEVEL3_PDE_ADDR(v) ALIGNDOWN(v, LEVEL3_PDE_SIZE) #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 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); extern struct XiziPageManager xizi_pager; -bool module_pager_init(struct PagerRightGroup*); \ No newline at end of file +bool module_pager_init(struct PagerRightGroup*); +bool _new_pgdir(struct TopLevelPageDirectory* pgdir); \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/softkernel/memory/pagetable_riscv.c b/Ubiquitous/XiZi_AIoT/softkernel/memory/pagetable_riscv.c index 53404786f..e70a06c81 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/memory/pagetable_riscv.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/memory/pagetable_riscv.c @@ -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) diff --git a/Ubiquitous/XiZi_AIoT/softkernel/memory/pagetable_riscv_level3.c b/Ubiquitous/XiZi_AIoT/softkernel/memory/pagetable_riscv_level3.c index f9501b6f8..04d0afc4c 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/memory/pagetable_riscv_level3.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/memory/pagetable_riscv_level3.c @@ -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)); }