提交 36f95831 创建 作者: Silas Boyd-Wickizer's avatar Silas Boyd-Wickizer

Clean up amd64 page table code.

上级 ccb4db66
......@@ -3,22 +3,8 @@
#define PGSIZE 4096
#define PGSHIFT 12 // log2(PGSIZE)
#define PTXSHIFT 12 // offset of PTX in a linear address
#define PDXSHIFT 21 // offset of PDX in a linear address
#define PDPXSHIFT 30 // offset of PDPX in a linear address
#define PML4XSHIFT 39 // offset of PML4X in a linear address
// page table index
#define PTX(la) (((uptr)(la) >> PTXSHIFT) & 0x1FF)
// page directory index
#define PDX(la) (((uptr)(la) >> PDXSHIFT) & 0x1FF)
// page diretory pointer index
#define PDPX(la) (((uptr)(la) >> PDPXSHIFT) & 0x1FF)
// page map level 4 index
#define PML4X(la) (((uptr)(la) >> PML4XSHIFT) & 0x1FF)
#define PXSHIFT(n) (PGSHIFT+(9*(n)))
#define PX(n, la) ((((uptr) (la)) >> PXSHIFT(n)) & 0x1FF)
// Page table/directory entry flags.
#define PTE_P 0x001 // Present
......
......@@ -13,9 +13,7 @@ typedef uint64 u64;
typedef uint64 uptr;
typedef uptr paddr;
typedef u64 pml4e_t;
typedef u64 pdpe_t;
typedef u64 pde_t;
typedef u64 pte_t;
typedef u64 pme_t; // Page Map Entry (refers to any entry in any level)
typedef pme_t pml4e_t;
#define __mpalign__ __attribute__((aligned(CACHELINE)))
......@@ -19,46 +19,40 @@ extern pml4e_t kpml4[];
extern char* pgalloc(void);
static void
pgmap(void *va, void *last, paddr pa)
static pme_t*
descend(pme_t *dir, void *va, u64 flags, int create, int level)
{
pml4e_t *pml4;
pml4e_t pml4e;
pdpe_t *pdp;
pdpe_t pdpe;
pde_t *pd;
pde_t pde;
pte_t *pt;
for(;;){
pml4 = &kpml4[PML4X(va)];
pml4e = *pml4;
if (pml4e == 0) {
pdp = (pdpe_t *) pgalloc();
*pml4 = v2p(pdp) | PTE_P | PTE_W;
pme_t entry;
pme_t *next;
dir = &dir[PX(level, va)];
entry = *dir;
if (entry == 0) {
if (!create)
return NULL;
next = (u64*) pgalloc();
if (!next)
return NULL;
*dir = v2p(next) | PTE_P | PTE_W | flags;
} else {
pdp = (pdpe_t*)p2v(PTE_ADDR(pml4e));
next = p2v(PTE_ADDR(entry));
}
pdp = &pdp[PDPX(va)];
pdpe = *pdp;
if (pdpe == 0) {
pd = (pde_t *) pgalloc();
*pdp = v2p(pd) | PTE_P | PTE_W;
} else {
pd = (pde_t*)p2v(PTE_ADDR(pdpe));
}
return next;
}
pd = &pd[PDX(va)];
pde = *pd;
if (pde == 0) {
pt = (pte_t *) pgalloc();
*pd = v2p(pt) | PTE_P | PTE_W;
} else {
pt = (pde_t*)p2v(PTE_ADDR(pde));
}
static void
pgmap(void *va, void *last, paddr pa)
{
pme_t *pdp;
pme_t *pd;
pme_t *pt;
pt = &pt[PTX(va)];
for (;;) {
pdp = descend(kpml4, va, 0, 1, 3);
pd = descend(pdp, va, 0, 1, 2);
pt = descend(pd, va, 0, 1, 1);
pt = &pt[PX(0,va)];
*pt = pa | PTE_W | PTE_P;
if(va == last)
break;
......@@ -101,7 +95,7 @@ setupkvm(void)
if((pml4 = (pml4e_t*)kalloc()) == 0)
return 0;
k = PML4X(PBASE);
k = PX(3, PBASE);
memset(&pml4[0], 0, 8*k);
memmove(&pml4[k], &kpml4[k], 8*(512-k));
return pml4;
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论