From 53e22ebac2a4352c4f4463df1c020eedbfd18e00 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sun, 3 Jun 1990 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1990-06-03 --- gnot/chan.c | 10 +++---- gnot/dat.h | 14 ++++++++- gnot/devproc.c | 26 +++++++++++----- gnot/fault.c | 20 +++++++++---- gnot/fns.h | 3 ++ gnot/main.c | 80 ++++++++++++++++++++++++++++++++++++++------------ gnot/mmu.c | 58 ++++++++++++++++++++++++++++++++++++ gnot/page.c | 21 +++++++++---- gnot/proc.c | 31 ++++++++++++------- gnot/sysproc.c | 18 ++++++++---- port/chan.c | 10 +++---- 11 files changed, 225 insertions(+), 66 deletions(-) diff --git a/gnot/chan.c b/gnot/chan.c index 374bd4e1cb8c2b82f1ac78eca627093856bc8737..3e0a52475429d7b71a1e7c7c9316899612e9a068 100644 --- a/gnot/chan.c +++ b/gnot/chan.c @@ -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; /* diff --git a/gnot/dat.h b/gnot/dat.h index a7c3e368981a8b2e6a542eb0cd28374b5c5e38a6..2c08e0a9db700649c4082ec74fa600555d0c908b 100644 --- a/gnot/dat.h +++ b/gnot/dat.h @@ -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; diff --git a/gnot/devproc.c b/gnot/devproc.c index b00dc39c94b2d03ec0651989798ef02611c189e2..85290bdecc3a901b99dc1961bde6678bfeab3bf3 100644 --- a/gnot/devproc.c +++ b/gnot/devproc.c @@ -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->offsetoffset+n > KZERO+conf.npage*BY2PG) - n = KZERO+conf.npage*BY2PG - c->offset; + if(c->offset>=KZERO && c->offsetoffset+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) diff --git a/gnot/fault.c b/gnot/fault.c index 44d48af80ea158b2d323f11fb5187337106adec7..88e2afabf6025ae3bb2ebb9041e8df5fcdffc59b 100644 --- a/gnot/fault.c +++ b/gnot/fault.c @@ -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(npte[(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--; diff --git a/gnot/fns.h b/gnot/fns.h index 7376942ae3c2cb29ce3bef0d50e7d88220e1284e..a57c08fb76eb2b34b5b58e76a285f678ffcad0df 100644 --- a/gnot/fns.h +++ b/gnot/fns.h @@ -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*); diff --git a/gnot/main.c b/gnot/main.c index 13691cfadc4c141213572f43de358f6ac6aec822..73f01404440e7f837dc95f0da9f4d0dcedc22026 100644 --- a/gnot/main.c +++ b/gnot/main.c @@ -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; } diff --git a/gnot/mmu.c b/gnot/mmu.c index 7a29b69855391ed0df800abfd294885502786e6f..974aa2070f71217d47cc8555d80f783c178c034e 100644 --- a/gnot/mmu.c +++ b/gnot/mmu.c @@ -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]; iva = 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); +} diff --git a/gnot/page.c b/gnot/page.c index 2889dcbeda970773d0016f2228fceb4cc93dd18c..b13b469c31f1b0ca756afe31802bc448bd03a4ba 100644 --- a/gnot/page.c +++ b/gnot/page.c @@ -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<pa = conf.base0+(ppn<pa = conf.base1+((ppn-conf.npage0)<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; diff --git a/gnot/proc.c b/gnot/proc.c index 5f39b75ac757c956a65735d6ff01c07fca45b072..5567d380e1043284f6086e921bb2d563323f84cb 100644 --- a/gnot/proc.c +++ b/gnot/proc.c @@ -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 diff --git a/gnot/sysproc.c b/gnot/sysproc.c index 3a8e504e8cd0be7ab8c614b516ba8ea8f409ccbc..19c52a878a850af29f143dd20a72394bbdb9c649 100644 --- a/gnot/sysproc.c +++ b/gnot/sysproc.c @@ -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); diff --git a/port/chan.c b/port/chan.c index 374bd4e1cb8c2b82f1ac78eca627093856bc8737..3e0a52475429d7b71a1e7c7c9316899612e9a068 100644 --- a/port/chan.c +++ b/port/chan.c @@ -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; /*