提交 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 void static pme_t*
pgmap(void *va, void *last, paddr pa) descend(pme_t *dir, void *va, u64 flags, int create, int level)
{ {
pml4e_t *pml4; pme_t entry;
pml4e_t pml4e; pme_t *next;
pdpe_t *pdp;
pdpe_t pdpe; dir = &dir[PX(level, va)];
pde_t *pd; entry = *dir;
pde_t pde; if (entry == 0) {
pte_t *pt; if (!create)
return NULL;
for(;;){ next = (u64*) pgalloc();
pml4 = &kpml4[PML4X(va)]; if (!next)
pml4e = *pml4; return NULL;
if (pml4e == 0) { *dir = v2p(next) | PTE_P | PTE_W | flags;
pdp = (pdpe_t *) pgalloc();
*pml4 = v2p(pdp) | PTE_P | PTE_W;
} else { } else {
pdp = (pdpe_t*)p2v(PTE_ADDR(pml4e)); next = p2v(PTE_ADDR(entry));
} }
pdp = &pdp[PDPX(va)]; return next;
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)]; static void
pde = *pd; pgmap(void *va, void *last, paddr pa)
if (pde == 0) { {
pt = (pte_t *) pgalloc(); pme_t *pdp;
*pd = v2p(pt) | PTE_P | PTE_W; pme_t *pd;
} else { pme_t *pt;
pt = (pde_t*)p2v(PTE_ADDR(pde));
}
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; *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 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论