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

Clean up amd64 page table code.

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