diff options
| -rw-r--r-- | sys/src/9/pc64/fns.h | 1 | ||||
| -rw-r--r-- | sys/src/9/pc64/main.c | 39 | ||||
| -rw-r--r-- | sys/src/9/pc64/mmu.c | 65 |
3 files changed, 65 insertions, 40 deletions
diff --git a/sys/src/9/pc64/fns.h b/sys/src/9/pc64/fns.h index e993e60b1..d0d585ef3 100644 --- a/sys/src/9/pc64/fns.h +++ b/sys/src/9/pc64/fns.h @@ -157,6 +157,7 @@ void pcmspecialclose(int); void (*_pcmspecialclose)(int); void pcmunmap(int, PCMmap*); void pmap(uintptr *, uintptr, uintptr, vlong); +void preallocpages(void); void procrestore(Proc*); void procsave(Proc*); void procsetup(Proc*); diff --git a/sys/src/9/pc64/main.c b/sys/src/9/pc64/main.c index e61840ea0..c8e705f49 100644 --- a/sys/src/9/pc64/main.c +++ b/sys/src/9/pc64/main.c @@ -103,45 +103,6 @@ confinit(void) } } -/* - * The palloc.pages array can be a large chunk out of the 2GB - * window above KZERO, so we allocate the array from - * upages and map in the VMAP window before pageinit() - */ -static void -preallocpages(void) -{ - Pallocmem *pm; - uintptr va, base, top; - vlong size; - ulong np; - int i; - - np = 0; - for(i=0; i<nelem(palloc.mem); i++){ - pm = &palloc.mem[i]; - np += pm->npage; - } - size = (uvlong)np * BY2PG; - size += sizeof(Page) + BY2PG; /* round up */ - size = (size / (sizeof(Page) + BY2PG)) * sizeof(Page); - size = ROUND(size, PGLSZ(1)); - - for(i=0; i<nelem(palloc.mem); i++){ - pm = &palloc.mem[i]; - base = ROUND(pm->base, PGLSZ(1)); - top = pm->base + (uvlong)pm->npage * BY2PG; - if((base + size) <= VMAPSIZE && (vlong)(top - base) >= size){ - va = base + VMAP; - pmap(m->pml4, base | PTEGLOBAL|PTEWRITE|PTEVALID, va, size); - palloc.pages = (Page*)va; - pm->base = base + size; - pm->npage = (top - pm->base)/BY2PG; - break; - } - } -} - void machinit(void) { diff --git a/sys/src/9/pc64/mmu.c b/sys/src/9/pc64/mmu.c index 9261354e8..dfb165ef5 100644 --- a/sys/src/9/pc64/mmu.c +++ b/sys/src/9/pc64/mmu.c @@ -271,7 +271,11 @@ mmuwalk(uintptr* table, uintptr va, int level, int create) if(pte & PTEVALID){ if(pte & PTESIZE) return 0; - table = KADDR(PPN(pte)); + pte = PPN(pte); + if(pte >= (uintptr)-KZERO) + table = (void*)(pte + VMAP); + else + table = (void*)(pte + KZERO); } else { if(!create) return 0; @@ -570,3 +574,62 @@ patwc(void *a, int n) *pte = (*pte & ~mask) | (attr & mask); } } + +/* + * The palloc.pages array and mmupool can be a large chunk + * out of the 2GB window above KZERO, so we allocate from + * upages and map in the VMAP window before pageinit() + */ +void +preallocpages(void) +{ + Pallocmem *pm; + uintptr va, base, top; + vlong tsize, psize; + ulong np, nt; + int i; + + np = 0; + for(i=0; i<nelem(palloc.mem); i++){ + pm = &palloc.mem[i]; + np += pm->npage; + } + nt = np / 50; /* 2% for mmupool */ + np -= nt; + + nt = (uvlong)nt*BY2PG / (sizeof(MMU)+PTSZ); + tsize = (uvlong)nt * (sizeof(MMU)+PTSZ); + + psize = (uvlong)np * BY2PG; + psize += sizeof(Page) + BY2PG; + psize = (psize / (sizeof(Page)+BY2PG)) * sizeof(Page); + + psize += tsize; + psize = ROUND(psize, PGLSZ(1)); + + for(i=0; i<nelem(palloc.mem); i++){ + pm = &palloc.mem[i]; + base = ROUND(pm->base, PGLSZ(1)); + top = pm->base + (uvlong)pm->npage * BY2PG; + if((base + psize) <= VMAPSIZE && (vlong)(top - base) >= psize){ + pm->base = base + psize; + pm->npage = (top - pm->base)/BY2PG; + + va = base + VMAP; + pmap(m->pml4, base | PTEGLOBAL|PTEWRITE|PTEVALID, va, psize); + + palloc.pages = (void*)(va + tsize); + + mmupool.nfree = mmupool.nalloc = nt; + mmupool.free = (void*)(va + (uvlong)nt*PTSZ); + for(i=0; i<nt; i++){ + mmupool.free[i].page = (uintptr*)va; + mmupool.free[i].next = &mmupool.free[i+1]; + va += PTSZ; + } + mmupool.free[i-1].next = nil; + + break; + } + } +} |
