Avoid repition in walkpgdir
This commit is contained in:
parent
572e106e6f
commit
155c13b7f8
2 changed files with 24 additions and 60 deletions
26
mmu.h
26
mmu.h
|
@ -91,26 +91,22 @@ struct segdesc {
|
||||||
// +------+-------+--------------+----------+------------+-------------+
|
// +------+-------+--------------+----------+------------+-------------+
|
||||||
// \-PMX(va)-/\-PDPX(va)--/ \-PDX(va)-/ \-PTX(va)-/
|
// \-PMX(va)-/\-PDPX(va)--/ \-PDX(va)-/ \-PTX(va)-/
|
||||||
|
|
||||||
#define PMX(va) (((uint64)(va) >> PML4XSHIFT) & PXMASK)
|
|
||||||
#define PDPX(va) (((uint64)(va) >> PDPXSHIFT) & PXMASK)
|
|
||||||
// page directory index
|
|
||||||
#define PDX(va) (((uint64)(va) >> PDXSHIFT) & PXMASK)
|
|
||||||
// page table index
|
|
||||||
#define PTX(va) (((uint64)(va) >> PTXSHIFT) & PXMASK)
|
|
||||||
|
|
||||||
// construct virtual address from indexes and offset
|
|
||||||
#define PGADDR(d, t, o) ((uint64)((d) << PDXSHIFT | (t) << PTXSHIFT | (o)))
|
|
||||||
|
|
||||||
// Page directory and page table constants.
|
// Page directory and page table constants.
|
||||||
#define NPDENTRIES 512 // # directory entries per page directory
|
#define NPDENTRIES 512 // # directory entries per page directory
|
||||||
#define NPTENTRIES 512 // # PTEs per page table
|
#define NPTENTRIES 512 // # PTEs per page table
|
||||||
#define PGSIZE 4096 // bytes mapped by a page
|
#define PGSIZE 4096 // bytes mapped by a page
|
||||||
|
#define PGSHIFT 12 // offset of PTX in a linear address
|
||||||
#define PTXSHIFT 12 // offset of PTX in a linear address
|
|
||||||
#define PDXSHIFT 21 // offset of PDX 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
|
#define PXMASK 0x1FF
|
||||||
#define PXMASK 0X1FF
|
#define PXSHIFT(n) (PGSHIFT+(9*(n)))
|
||||||
|
#define PDX(va) (((uint64)(va) >> PDXSHIFT) & PXMASK)
|
||||||
|
#define PTX(va) (((uint64)(va) >> PGSHIFT) & PXMASK)
|
||||||
|
#define PX(n, va) ((((uint64) (va)) >> PXSHIFT(n)) & PXMASK)
|
||||||
|
#define L_PML4 3
|
||||||
|
|
||||||
|
// construct virtual address from indexes and offset
|
||||||
|
#define PGADDR(d, t, o) ((uint64)((d) << PDXSHIFT | (t) << PGSHIFT | (o)))
|
||||||
|
|
||||||
#define PGROUNDUP(sz) (((sz)+PGSIZE-1) & ~(PGSIZE-1))
|
#define PGROUNDUP(sz) (((sz)+PGSIZE-1) & ~(PGSIZE-1))
|
||||||
#define PGROUNDDOWN(a) (((a)) & ~(PGSIZE-1))
|
#define PGROUNDDOWN(a) (((a)) & ~(PGSIZE-1))
|
||||||
|
|
58
vm.c
58
vm.c
|
@ -66,53 +66,21 @@ seginit(void)
|
||||||
static pte_t *
|
static pte_t *
|
||||||
walkpgdir(pde_t *pml4, const void *va, int alloc)
|
walkpgdir(pde_t *pml4, const void *va, int alloc)
|
||||||
{
|
{
|
||||||
pml4e_t *pml4e;
|
pde_t *pgtab = pml4;
|
||||||
pdpe_t *pdp;
|
|
||||||
pdpe_t *pdpe;
|
|
||||||
pde_t *pde;
|
pde_t *pde;
|
||||||
pde_t *pd;
|
int level;
|
||||||
pte_t *pgtab;
|
|
||||||
|
for (level = L_PML4; level > 0; level--) {
|
||||||
// level 4
|
pde = &pgtab[PX(level, va)];
|
||||||
pml4e = &pml4[PMX(va)];
|
if(*pde & PTE_P)
|
||||||
if(*pml4e & PTE_P)
|
pgtab = (pte_t*)P2V(PTE_ADDR(*pde));
|
||||||
pdp = (pdpe_t*)P2V(PTE_ADDR(*pml4e));
|
else {
|
||||||
else {
|
if(!alloc || (pgtab = (pte_t*)kalloc()) == 0)
|
||||||
if(!alloc || (pdp = (pdpe_t*)kalloc()) == 0)
|
return 0;
|
||||||
return 0;
|
memset(pgtab, 0, PGSIZE);
|
||||||
// Make sure all those PTE_P bits are zero.
|
*pde = V2P(pgtab) | PTE_P | PTE_W | PTE_U;
|
||||||
memset(pdp, 0, PGSIZE);
|
}
|
||||||
// The permissions here are overly generous, but they can
|
|
||||||
// be further restricted by the permissions in the page table
|
|
||||||
// entries, if necessary.
|
|
||||||
*pml4e = V2P(pdp) | PTE_P | PTE_W | PTE_U;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX avoid repetition
|
|
||||||
|
|
||||||
// level 3
|
|
||||||
pdpe = &pdp[PDPX(va)];
|
|
||||||
if(*pdpe & PTE_P)
|
|
||||||
pd = (pde_t*)P2V(PTE_ADDR(*pdpe));
|
|
||||||
else {
|
|
||||||
if(!alloc || (pd = (pde_t*)kalloc()) == 0)
|
|
||||||
return 0;
|
|
||||||
memset(pd, 0, PGSIZE);
|
|
||||||
*pdpe = V2P(pd) | PTE_P | PTE_W | PTE_U;
|
|
||||||
}
|
|
||||||
|
|
||||||
// level 2
|
|
||||||
pde = &pd[PDX(va)];
|
|
||||||
if(*pde & PTE_P)
|
|
||||||
pgtab = (pte_t*)P2V(PTE_ADDR(*pde));
|
|
||||||
else {
|
|
||||||
if(!alloc || (pgtab = (pte_t*)kalloc()) == 0)
|
|
||||||
return 0;
|
|
||||||
memset(pgtab, 0, PGSIZE);
|
|
||||||
*pde = V2P(pgtab) | PTE_P | PTE_W | PTE_U;
|
|
||||||
}
|
|
||||||
|
|
||||||
// level 1
|
|
||||||
return &pgtab[PTX(va)];
|
return &pgtab[PTX(va)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue