Modify map_pages
This commit is contained in:
parent
a2ed0ee073
commit
197957f202
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
|
@ -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);
|
|
@ -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)
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue