summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/src/9/pc64/fns.h1
-rw-r--r--sys/src/9/pc64/main.c39
-rw-r--r--sys/src/9/pc64/mmu.c65
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;
+ }
+ }
+}