M gnot/chan.c => gnot/chan.c +4 -6
@@ 134,7 134,7 @@ mountsplit(Mount *omnt)
nmnt->mountid = omnt->mountid;
nmnt->next = omnt->next;
if(nmnt->next)
- incref(nmnt);
+ incref(nmnt->next);
nmnt->c = omnt->c;
incref(nmnt->c);
omnt->ref--;
@@ 207,14 207,12 @@ mount(Chan *new, Chan *old, int flag)
/* fall through */
case MREPL:
- omnt = mt->mnt;
- if(omnt)
- incref(omnt);
- mnt->next = omnt;
+ mnt->next = mt->mnt;
mt->mnt = mnt;
- mnt->term = 1;
if((flag&MORDER) == MBEFORE)
mnt->term = 0;
+ else
+ mnt->term = 1;
break;
/*
M gnot/dat.h => gnot/dat.h +13 -1
@@ 12,6 12,7 @@ typedef struct Envval Envval;
typedef struct Error Error;
typedef struct FFrame FFrame;
typedef struct FPsave FPsave;
+typedef struct KMap KMap;
typedef struct Label Label;
typedef struct List List;
typedef struct Lock Lock;
@@ 112,6 113,10 @@ struct Conf
int nmach; /* processors */
int nproc; /* processes */
int npgrp; /* process groups */
+ ulong npage0; /* total physical pages of memory, bank 0 */
+ ulong npage1; /* total physical pages of memory, bank 1 */
+ ulong base0; /* base of bank 0 */
+ ulong base1; /* base of bank 1 */
ulong npage; /* total physical pages of memory */
ulong norig; /* origins */
ulong npte; /* contiguous page table entries */
@@ 176,6 181,13 @@ struct Envp
int chref; /* # chans from pgrp pointing here */
};
+struct KMap
+{
+ KMap *next;
+ ulong pa;
+ ulong va;
+};
+
struct Mach
{
int machno; /* physical id of processor */
@@ 298,7 310,7 @@ struct Proc
Proc *sib; /* non-ascendant relatives (circular list) */
int nchild;
QLock wait; /* exiting children to be waited for */
- Waitmsg *waitmsg;
+ ulong waitmsg;
Proc *child;
Proc *parent;
Pgrp *pgrp;
M gnot/devproc.c => gnot/devproc.c +19 -7
@@ 201,6 201,7 @@ procread(Chan *c, void *va, long n)
Seg *s;
Orig *o;
Page *pg;
+ KMap *k;
PTE *pte, *opte;
int i;
long l;
@@ 253,8 254,10 @@ procread(Chan *c, void *va, long n)
pprint("nonresident page addr %lux (complain to rob)\n", c->offset);
memset(a, 0, n);
}else{
- b = (char*)(pg->pa|KZERO);
+ k = kmap(pg);
+ b = (char*)k->va;
memcpy(a, b+(c->offset&(BY2PG-1)), n);
+ kunmap(k);
}
return n;
}
@@ 266,15 269,17 @@ procread(Chan *c, void *va, long n)
pg = p->upage;
if(pg==0 || (p->pid&PIDMASK)!=PID(c->qid))
error(0, Eprocdied);
- b = (char*)(pg->pa|KZERO);
+ k = kmap(pg);
+ b = (char*)k->va;
memcpy(a, b+(c->offset-USERADDR), n);
+ kunmap(k);
return n;
}
/* kernel memory. BUG: shouldn't be so easygoing. BUG: mem mapping? */
- if(c->offset>=KZERO && c->offset<KZERO+conf.npage*BY2PG){
- if(c->offset+n > KZERO+conf.npage*BY2PG)
- n = KZERO+conf.npage*BY2PG - c->offset;
+ if(c->offset>=KZERO && c->offset<KZERO+conf.npage0*BY2PG){
+ if(c->offset+n > KZERO+conf.npage0*BY2PG)
+ n = KZERO+conf.npage0*BY2PG - c->offset;
memcpy(a, (char*)c->offset, n);
return n;
}
@@ 289,8 294,10 @@ procread(Chan *c, void *va, long n)
}
if((p->pid&PIDMASK) != PID(c->qid))
error(0, Eprocdied);
- up = (User*)(p->upage->pa|KZERO);
+ k = kmap(p->upage);
+ up = (User*)k->va;
if(up->p != p){
+ kunmap(k);
pprint("note read u/p mismatch");
error(0, Egreg);
}
@@ 304,6 311,7 @@ procread(Chan *c, void *va, long n)
memcpy(&up->note[0], &up->note[1], up->nnote*sizeof(Note));
n = ERRLEN;
}
+ kunmap(k);
unlock(&p->debug);
return n;
@@ 340,6 348,7 @@ procwrite(Chan *c, void *va, long n)
{
Proc *p;
User *up;
+ KMap *k;
char buf[ERRLEN];
if(c->qid & CHDIR)
@@ 362,11 371,14 @@ procwrite(Chan *c, void *va, long n)
error(0, Ebadctl);
break;
case Qnote:
- up = (User*)(p->upage->pa|KZERO);
+ k = kmap(p->upage);
+ up = (User*)k->va;
if(up->p != p){
+ kunmap(k);
pprint("note write u/p mismatch");
error(0, Egreg);
}
+ kunmap(k);
if(n >= ERRLEN-1)
error(0, Etoobig);
if(n>=4 && strncmp(va, "sys:", 4)==0)
M gnot/fault.c => gnot/fault.c +15 -5
@@ 51,11 51,14 @@ fault(Ureg *ur, FFrame *f)
Orig *o;
char *l;
Page *pg;
+ KMap *k, *k1;
int zeroed = 0, head = 1;
int i, user, read, insyscall;
- if(u == 0)
- panic("fault");
+ if(u == 0){
+ dumpregs(ur);
+ panic("fault u==0 pc=%lux", ur->pc);
+ }
insyscall = u->p->insyscall;
u->p->insyscall = 1;
if(f->ssw & DF)
@@ 149,24 152,27 @@ fault(Ureg *ur, FFrame *f)
if(n > BY2PG)
n = BY2PG;
pg = newpage(1, o, addr);
+ k = kmap(pg);
qlock(o->chan);
if(waserror()){
print("demand load i/o error %d\n", u->error.code);
+ kunmap(k);
qunlock(o->chan);
pg->o = 0;
pg->ref--;
goto cant;
}
o->chan->offset = (addr-o->va) + o->minca;
- l = (char*)(pg->pa|KZERO);
+ l = (char*)k->va;
if((*devtab[o->chan->type].read)(o->chan, l, n) != n)
error(0, Eioload);
qunlock(o->chan);
- poperror();
/* BUG: if was first page of bss, move to data */
if(n<BY2PG)
memset(l+n, 0, BY2PG-n);
lock(o);
+ kunmap(k);
+ poperror();
opte = &o->pte[(addr-s->minva)>>PGSHIFT]; /* could move */
pte = opte;
if(pte->page == 0){
@@ 231,7 237,11 @@ fault(Ureg *ur, FFrame *f)
opte->page = 0;
}else{ /* copy page */
pte->page = newpage(1, o, addr);
- memcpy((void*)(pte->page->pa|KZERO), (void*)(pg->pa|KZERO), BY2PG);
+ k = kmap(pte->page);
+ k1 = kmap(pg);
+ memcpy((void*)k->va, (void*)k1->va, BY2PG);
+ kunmap(k);
+ kunmap(k1);
if(pg->ref <= 1)
panic("pg->ref <= 1");
pg->ref--;
M gnot/fns.h => gnot/fns.h +3 -0
@@ 63,8 63,11 @@ void isdir(Chan*);
void kbdchar(int);
void kbdrepeat(int);
void kbdclock(void);
+void kmapinit(void);
+KMap *kmap(Page*);
void kproc(char*, void(*)(void*), void*);
void kproftimer(ulong);
+void kunmap(KMap*);
void lock(Lock*);
void lockinit(void);
Orig *lookorig(ulong, ulong, int, Chan*);
M gnot/main.c => gnot/main.c +61 -19
@@ 17,6 17,7 @@ typedef struct Boot{
#define BOOT ((Boot*)0)
char protouser[NAMELEN];
+int bank[2];
void unloadboot(void);
@@ 27,7 28,9 @@ main(void)
machinit();
mmuinit();
confinit();
+ kmapinit();
printinit();
+ print("bank 0: %dM bank 1: %dM\n", bank[0], bank[1]);
flushmmu();
procinit0();
pgrpinit();
@@ 36,6 39,7 @@ main(void)
chandevreset();
streaminit();
pageinit();
+ kmapinit();
userinit();
schedinit();
}
@@ 102,6 106,7 @@ userinit(void)
Proc *p;
Seg *s;
User *up;
+ KMap *k;
p = newproc();
p->pgrp = newpgrp();
@@ 121,8 126,10 @@ userinit(void)
/*
* User
*/
- up = (User*)(p->upage->pa|KZERO);
+ k = kmap(p->upage);
+ up = (User*)k->va;
up->p = p;
+ kunmap(k);
/*
* User Stack
@@ 140,7 147,9 @@ userinit(void)
s->proc = p;
s->o = neworig(UTZERO, 1, 0, 0);
s->o->pte[0].page = newpage(0, 0, UTZERO);
- memcpy((ulong*)(s->o->pte[0].page->pa|KZERO), initcode, sizeof initcode);
+ k = kmap(s->o->pte[0].page);
+ memcpy((ulong*)k->va, initcode, sizeof initcode);
+ kunmap(k);
s->minva = UTZERO;
s->maxva = UTZERO+BY2PG;
@@ 225,34 234,67 @@ delete(List **head, List *where, List *old)
where->next = old->next;
}
+banksize(int base)
+{
+ ulong va;
+
+ if(&end > (int *)((KZERO|1024L*1024L)-BY2PG))
+ return 0;
+ va = UZERO; /* user page 1 is free to play with */
+ putmmu(va, PTEVALID|(base+0)*1024L*1024L/BY2PG);
+ *(ulong*)va=0; /* 0 at 0M */
+ putmmu(va, PTEVALID|(base+1)*1024L*1024L/BY2PG);
+ *(ulong*)va=1; /* 1 at 1M */
+ putmmu(va, PTEVALID|(base+4)*1024L*1024L/BY2PG);
+ *(ulong*)va=4; /* 4 at 4M */
+ putmmu(va, PTEVALID|(base+0)*1024L*1024L/BY2PG);
+ if(*(ulong*)va==0)
+ return 16;
+ putmmu(va, PTEVALID|(base+1)*1024L*1024L/BY2PG);
+ if(*(ulong*)va==1)
+ return 4;
+ putmmu(va, PTEVALID|(base+4)*1024L*1024L/BY2PG);
+ if(*(ulong*)va==2)
+ return 1;
+ return 0;
+}
+
Conf conf;
void
confinit(void)
{
+ int mul;
conf.nmach = 1;
if(conf.nmach > MAXMACH)
panic("confinit");
- conf.nproc = 32;
- conf.npgrp = 15;
- conf.npage = (4*1024*1024-256*1024)/BY2PG;
- conf.npte = 500;
- conf.nmod = 200;
+ bank[0] = banksize(0);
+ bank[1] = banksize(16);
+ conf.npage0 = (bank[0]*1024*1024)/BY2PG;
+ conf.base0 = 0;
+ conf.npage1 = (bank[1]*1024*1024)/BY2PG;
+ conf.base1 = 16*1024*1024;
+ conf.npage = conf.npage0+conf.npage1;
+ mul = 1 + (conf.npage0>0);
+ conf.nproc = 32*mul;
+ conf.npgrp = 15*mul;
+ conf.npte = 700*mul;
+ conf.nmod = 400*mul;
conf.nalarm = 1000;
- conf.norig = 100;
- conf.nchan = 200;
- conf.nenv = 100;
- conf.nenvchar = 8000;
- conf.npgenv = 200;
- conf.nmtab = 50;
- conf.nmount = 100;
- conf.nmntdev = 20;
+ conf.norig = 150*mul;
+ conf.nchan = 150*mul;
+ conf.nenv = 100*mul;
+ conf.nenvchar = 8000*mul;
+ conf.npgenv = 200*mul;
+ conf.nmtab = 50*mul;
+ conf.nmount = 100*mul;
+ conf.nmntdev = 10*mul;
conf.nmntbuf = 2*conf.nmntdev;
conf.nmnthdr = 2*conf.nmntdev;
- conf.nstream = 64;
+ conf.nstream = 64*mul;
conf.nqueue = 5 * conf.nstream;
conf.nblock = 12 * conf.nstream;
- conf.nsrv = 32;
- conf.nbitmap = 100;
- conf.nbitbyte = 400*1024;
+ conf.nsrv = 32*mul;
+ conf.nbitmap = 100*mul;
+ conf.nbitbyte = 300*1024*mul;
}
M gnot/mmu.c => gnot/mmu.c +58 -0
@@ 4,6 4,14 @@
#include "dat.h"
#include "fns.h"
+struct
+{
+ Lock;
+ int init;
+ KMap *free;
+ KMap arena[4*1024*1024/BY2PG]; /* kernel mmu maps up to 4MB */
+}kmapalloc;
+
/*
* Called splhi, not in Running state
*/
@@ 46,3 54,53 @@ flushmmu(void)
*PARAM &= ~TLBFLUSH_;
*PARAM |= TLBFLUSH_;
}
+
+void
+kmapinit(void)
+{
+ KMap *k;
+ int i, e;
+
+ if(kmapalloc.init == 0){
+ k = &kmapalloc.arena[0];
+ k->va = KZERO|(3*1024*1024);
+ k->next = 0;
+ kmapalloc.free = k;
+ kmapalloc.init = 1;
+ return;
+ }
+ e = (4*1024*1024 - 256*1024)/BY2PG; /* screen lives at top 256K */
+ i = (((ulong)ialloc(0, 0))&~KZERO)/BY2PG;
+ kmapalloc.free = 0;
+ for(k=&kmapalloc.arena[i]; i<e; i++,k++){
+ k->va = i*BY2PG|KZERO;
+ kunmap(k);
+ }
+}
+
+KMap*
+kmap(Page *pg)
+{
+ KMap *k;
+
+ lock(&kmapalloc);
+ k = kmapalloc.free;
+ if(k == 0)
+ panic("kmap");
+ kmapalloc.free = k->next;
+ unlock(&kmapalloc);
+ k->pa = pg->pa;
+ putkmmu(k->va, PPN(k->pa) | PTEVALID | PTEKERNEL);
+ return k;
+}
+
+void
+kunmap(KMap *k)
+{
+ k->pa = 0;
+ lock(&kmapalloc);
+ k->next = kmapalloc.free;
+ kmapalloc.free = k;
+ putkmmu(k->va, INVALIDPTE);
+ unlock(&kmapalloc);
+}
M gnot/page.c => gnot/page.c +15 -6
@@ 10,7 10,7 @@ struct
Lock;
ulong addr;
int active;
- Page *page; /* base of Page structures, indexed by phys addr */
+ Page *page; /* base of Page structures, indexed by phys page number */
ulong minppn; /* index of first usable page */
Page *head; /* most recently used */
Page *tail; /* least recently used */
@@ 54,10 54,12 @@ ialloc(ulong n, int align)
{
ulong p;
- if(palloc.active)
- print("ialloc bad\n");
if(palloc.addr == 0)
palloc.addr = ((ulong)&end)&~KZERO;
+ if(n == 0) /* done by kmapinit */
+ return (void*)(palloc.addr|KZERO);
+ if(palloc.active)
+ print("ialloc bad\n");
if(align){
palloc.addr += BY2PG-1;
palloc.addr &= ~(BY2PG-1);
@@ 150,7 152,10 @@ pageinit(void)
for(p=palloc.head; p<=palloc.tail; p++,ppn++){
p->next = p+1;
p->prev = p-1;
- p->pa = ppn<<PGSHIFT;
+ if(ppn < conf.npage0)
+ p->pa = conf.base0+(ppn<<PGSHIFT);
+ else
+ p->pa = conf.base1+((ppn-conf.npage0)<<PGSHIFT);
}
palloc.head->prev = 0;
palloc.tail->next = 0;
@@ 161,6 166,7 @@ newpage(int noclear, Orig *o, ulong va)
{
Page *p;
Orig *o1;
+ KMap *k;
if(palloc.active == 0)
print("newpage inactive\n");
@@ 205,8 211,11 @@ loop:
p->ref = 1;
usepage(p, 0);
unlock(&palloc);
- if(!noclear)
- memset((void*)(p->pa|KZERO), 0, BY2PG);
+ if(!noclear){
+ k = kmap(p);
+ memset((void*)k->va, 0, BY2PG);
+ kunmap(k);
+ }
p->o = o;
p->va = va;
M gnot/proc.c => gnot/proc.c +21 -10
@@ 303,18 303,23 @@ int
postnote(Proc *p, int dolock, char *n, int flag)
{
User *up;
+ KMap *k;
int s;
Rendez *r;
if(dolock)
lock(&p->debug);
- up = (User*)(p->upage->pa|KZERO);
+ k = kmap(p->upage);
+ up = (User*)k->va;
if(flag!=NUser && (up->notify==0 || up->notified))
up->nnote = 0; /* force user's hand */
- else if(up->nnote == NNOTE-1)
+ else if(up->nnote == NNOTE-1){
+ kunmap(k);
return 0;
+ }
strcpy(up->note[up->nnote].msg, n);
up->note[up->nnote++].flag = flag;
+ kunmap(k);
if(dolock)
unlock(&p->debug);
if(r = p->r){ /* assign = */
@@ 398,7 403,7 @@ pexit(char *s, int freemem)
/*
* Pass info through back door, to avoid huge Proc's
*/
- p->waitmsg = (Waitmsg*)(c->upage->pa|(((ulong)&w)&(BY2PG-1))|KZERO);
+ p->waitmsg = (((ulong)&w)&(BY2PG-1));
c->state = Exiting;
if(p->state == Inwait)
ready(p);
@@ 499,6 504,7 @@ ulong
pwait(Waitmsg *w)
{
Proc *c, *p;
+ KMap *k;
ulong cpid;
p = u->p;
@@ 521,9 527,11 @@ again:
goto again;
}
p->child = 0;
+ k = kmap(c->upage);
if(w)
- *w = *p->waitmsg;
- cpid = p->waitmsg->pid;
+ *w = *(Waitmsg*)(p->waitmsg|k->va);
+ cpid = ((Waitmsg*)(p->waitmsg|k->va))->pid;
+ kunmap(k);
p->time[TCUser] += c->time[TUser] + c->time[TCUser];
p->time[TCSys] += c->time[TSys] + c->time[TCSys];
p->time[TCReal] += c->time[TReal];
@@ 564,23 572,25 @@ kproc(char *name, void (*func)(void *), void *arg)
ulong upa;
int lastvar; /* used to compute stack address */
User *up;
+ KMap *k;
/*
* Kernel stack
*/
p = newproc();
p->upage = newpage(1, 0, USERADDR|(p->pid&0xFFFF));
- upa = p->upage->pa|KZERO;
- up = (User *)upa;
+ k = kmap(p->upage);
+ upa = k->va;
+ up = (User*)upa;
+ up->p = p;
/*
* Save time: only copy u-> data and useful stack
*/
- memcpy((void*)upa, u, sizeof(User));
+ memcpy(up, u, sizeof(User));
n = USERADDR+BY2PG - (ulong)&lastvar;
n = (n+32) & ~(BY2WD-1); /* be safe & word align */
- memcpy((void*)(upa+BY2PG-n), (void*)((u->p->upage->pa|KZERO)+BY2PG-n), n);
- ((User *)upa)->p = p;
+ memcpy((void*)(upa+BY2PG-n), (void*)(USERADDR+BY2PG-n), n);
/*
* Refs
@@ 589,6 599,7 @@ kproc(char *name, void (*func)(void *), void *arg)
for(n=0; n<=up->maxfd; n++)
up->fd[n] = 0;
up->maxfd = 0;
+ kunmap(k);
/*
* Sched
M gnot/sysproc.c => gnot/sysproc.c +12 -6
@@ 26,6 26,7 @@ sysfork(ulong *arg)
ulong usp, upa, pid;
Chan *c;
Orig *o;
+ KMap *k;
int n, on, i;
int lastvar; /* used to compute stack address */
@@ 34,15 35,18 @@ sysfork(ulong *arg)
*/
p = newproc();
p->upage = newpage(1, 0, USERADDR|(p->pid&0xFFFF));
- upa = p->upage->pa|KZERO;
+ k = kmap(p->upage);
+ upa = k->va;
+
/*
* Save time: only copy u-> data and useful stack
*/
memcpy((void*)upa, u, sizeof(User));
n = USERADDR+BY2PG - (ulong)&lastvar;
n = (n+32) & ~(BY2WD-1); /* be safe & word align */
- memcpy((void*)(upa+BY2PG-n), (void*)((u->p->upage->pa|KZERO)+BY2PG-n), n);
+ memcpy((void*)(upa+BY2PG-n), (void*)(USERADDR+BY2PG-n), n);
((User *)upa)->p = p;
+ kunmap(k);
/*
* User stack
@@ 70,13 74,15 @@ sysfork(ulong *arg)
op = u->p->seg[SSEG].o->pte[i+(on-n)].page;
if(op){
np = newpage(1, s->o, op->va);
+ k = kmap(np);
p->seg[SSEG].o->pte[i].page = np;
if(i == 0){ /* only part of last stack page */
- memset((void*)(np->pa|KZERO), 0, usp);
- memcpy((void*)((np->pa+usp)|KZERO),
- (void*)((op->pa+usp)|KZERO), BY2PG-usp);
+ memset((void*)k->va, 0, usp);
+ memcpy((void*)(k->va+usp),
+ (void*)(op->va+usp), BY2PG-usp);
}else /* all of higher pages */
- memcpy((void*)(np->pa|KZERO), (void*)(op->pa|KZERO), BY2PG);
+ memcpy((void*)k->va, (void*)op->va, BY2PG);
+ kunmap(k);
}
}
unlock(s->o);
M port/chan.c => port/chan.c +4 -6
@@ 134,7 134,7 @@ mountsplit(Mount *omnt)
nmnt->mountid = omnt->mountid;
nmnt->next = omnt->next;
if(nmnt->next)
- incref(nmnt);
+ incref(nmnt->next);
nmnt->c = omnt->c;
incref(nmnt->c);
omnt->ref--;
@@ 207,14 207,12 @@ mount(Chan *new, Chan *old, int flag)
/* fall through */
case MREPL:
- omnt = mt->mnt;
- if(omnt)
- incref(omnt);
- mnt->next = omnt;
+ mnt->next = mt->mnt;
mt->mnt = mnt;
- mnt->term = 1;
if((flag&MORDER) == MBEFORE)
mnt->term = 0;
+ else
+ mnt->term = 1;
break;
/*