diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2014-02-15 16:43:55 +0100 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2014-02-15 16:43:55 +0100 |
commit | 25189924dbde3852b68adb9ce97cd5ff101ee3fb (patch) | |
tree | fcdf21c5d31305cec005027a287b1d86211ee853 /sys | |
parent | c6f6396faaf06122e2c242ca0006165fe0c59977 (diff) |
pc64: simplify mmuwalk by factoring out mmu page table creation into separate function
Diffstat (limited to 'sys')
-rw-r--r-- | sys/src/9/pc64/mmu.c | 93 |
1 files changed, 50 insertions, 43 deletions
diff --git a/sys/src/9/pc64/mmu.c b/sys/src/9/pc64/mmu.c index 74857b90f..2d7633aa6 100644 --- a/sys/src/9/pc64/mmu.c +++ b/sys/src/9/pc64/mmu.c @@ -205,12 +205,58 @@ mmualloc(void) return p; } +static uintptr* +mmucreate(uintptr *table, uintptr va, int level, int index) +{ + uintptr *page, flags; + MMU *p; + + flags = PTEWRITE|PTEVALID; + if(va < VMAP){ + assert(up != nil); + assert((va < TSTKTOP) || (va >= KMAP && va < KMAP+KMAPSIZE)); + + p = mmualloc(); + p->index = level; + p->level = index; + if(va < TSTKTOP){ + flags |= PTEUSER; + if(level == PML4E){ + if((p->next = up->mmuhead) == nil) + up->mmutail = p; + up->mmuhead = p; + m->mmumap[index/MAPBITS] |= 1ull<<(index%MAPBITS); + } else { + up->mmutail->next = p; + up->mmutail = p; + } + up->mmucount++; + } else { + if(level == PML4E){ + up->kmaptail = p; + up->kmaphead = p; + } else { + up->kmaptail->next = p; + up->kmaptail = p; + } + up->kmapcount++; + } + page = p->page; + } else if(didmmuinit) { + page = mallocalign(PTSZ, BY2PG, 0, 0); + } else { + page = rampage(); + } + memset(page, 0, PTSZ); + table[index] = PADDR(page) | flags; + return page; +} + uintptr* mmuwalk(uintptr* table, uintptr va, int level, int create) { - uintptr pte, *page; + uintptr pte; int i, x; - MMU *p; x = PTLX(va, 3); for(i = 2; i >= level; i--){ @@ -219,49 +265,10 @@ mmuwalk(uintptr* table, uintptr va, int level, int create) if(pte & PTESIZE) return 0; table = KADDR(PPN(pte)); - } else { + } else { if(!create) return 0; - pte = PTEWRITE|PTEVALID; - if(va < VMAP){ - if(va < TSTKTOP){ - pte |= PTEUSER; - - p = mmualloc(); - p->index = x; - p->level = i; - if(i == PML4E){ - if((p->next = up->mmuhead) == nil) - up->mmutail = p; - up->mmuhead = p; - m->mmumap[p->index/MAPBITS] |= 1ull<<(p->index%MAPBITS); - } else { - up->mmutail->next = p; - up->mmutail = p; - } - up->mmucount++; - } else if(va >= KMAP && va < (KMAP+KMAPSIZE)) { - p = mmualloc(); - p->index = x; - p->level = i; - if(i == PML4E){ - up->kmaptail = p; - up->kmaphead = p; - } else { - up->kmaptail->next = p; - up->kmaptail = p; - } - up->kmapcount++; - } else - return 0; - page = p->page; - } else if(didmmuinit) { - page = mallocalign(PTSZ, BY2PG, 0, 0); - } else - page = rampage(); - memset(page, 0, PTSZ); - table[x] = PADDR(page) | pte; - table = page; + table = mmucreate(table, va, i, x); } x = PTLX(va, i); } |