From 6b920f7528e492ddaf64e4db29df83dfc8f43450 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Thu, 14 Jun 1990 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1990-06-14 --- gnot/dat.h | 1 + gnot/devproc.c | 8 ++++---- gnot/fault.c | 4 ++-- gnot/main.c | 4 ++-- gnot/page.c | 2 +- gnot/proc.c | 8 ++++---- gnot/sysproc.c | 8 ++++---- port/devcons.c | 6 +++--- port/devproc.c | 47 +++++++++++++++++++++++++++++++++-------------- port/lib.h | 1 + port/proc.c | 6 +++--- port/sysproc.c | 22 ++++++++++++++-------- power/clock.c | 2 +- power/conf.h | 1 + power/dat.h | 9 +++++++++ power/main.c | 3 ++- power/mem.h | 9 ++++++++- power/ureg.h | 5 ++++- 18 files changed, 97 insertions(+), 49 deletions(-) diff --git a/gnot/dat.h b/gnot/dat.h index 2c08e0a9db700649c4082ec74fa600555d0c908b..877b06ad7eda171fd1a25aa57a238e50809cc5bb 100644 --- a/gnot/dat.h +++ b/gnot/dat.h @@ -187,6 +187,7 @@ struct KMap ulong pa; ulong va; }; +#define VA(k) ((k)->va) struct Mach { diff --git a/gnot/devproc.c b/gnot/devproc.c index e6698f329814ebf1cd8cb34fbae3a6f7e978ba72..0a6a4e10bf9c380b4cf9a3dbd0c92e17ccd28b36 100644 --- a/gnot/devproc.c +++ b/gnot/devproc.c @@ -255,7 +255,7 @@ procread(Chan *c, void *va, long n) memset(a, 0, n); }else{ k = kmap(pg); - b = (char*)k->va; + b = (char*)VA(k); memcpy(a, b+(c->offset&(BY2PG-1)), n); kunmap(k); } @@ -270,7 +270,7 @@ procread(Chan *c, void *va, long n) if(pg==0 || (p->pid&PIDMASK)!=PID(c->qid)) error(0, Eprocdied); k = kmap(pg); - b = (char*)k->va; + b = (char*)VA(k); memcpy(a, b+(c->offset-USERADDR), n); kunmap(k); return n; @@ -295,7 +295,7 @@ procread(Chan *c, void *va, long n) if((p->pid&PIDMASK) != PID(c->qid)) error(0, Eprocdied); k = kmap(p->upage); - up = (User*)k->va; + up = (User*)VA(k); if(up->p != p){ kunmap(k); pprint("note read u/p mismatch"); @@ -372,7 +372,7 @@ procwrite(Chan *c, void *va, long n) break; case Qnote: k = kmap(p->upage); - up = (User*)k->va; + up = (User*)VA(k); if(up->p != p){ kunmap(k); pprint("note write u/p mismatch"); diff --git a/gnot/fault.c b/gnot/fault.c index 88e2afabf6025ae3bb2ebb9041e8df5fcdffc59b..01bf2ef5839fe97a751137136c4e95ec457301f0 100644 --- a/gnot/fault.c +++ b/gnot/fault.c @@ -163,7 +163,7 @@ fault(Ureg *ur, FFrame *f) goto cant; } o->chan->offset = (addr-o->va) + o->minca; - l = (char*)k->va; + l = (char*)VA(k); if((*devtab[o->chan->type].read)(o->chan, l, n) != n) error(0, Eioload); qunlock(o->chan); @@ -239,7 +239,7 @@ fault(Ureg *ur, FFrame *f) pte->page = newpage(1, o, addr); k = kmap(pte->page); k1 = kmap(pg); - memcpy((void*)k->va, (void*)k1->va, BY2PG); + memcpy((void*)VA(k), (void*)VA(k1), BY2PG); kunmap(k); kunmap(k1); if(pg->ref <= 1) diff --git a/gnot/main.c b/gnot/main.c index 26f94631eadb6a726a702cf634a9f25f57f2f6ef..6398b23996999700060752f74cf20a37bb15c668 100644 --- a/gnot/main.c +++ b/gnot/main.c @@ -140,7 +140,7 @@ userinit(void) * User */ k = kmap(p->upage); - up = (User*)k->va; + up = (User*)VA(k); up->p = p; kunmap(k); @@ -161,7 +161,7 @@ userinit(void) s->o = neworig(UTZERO, 1, 0, 0); s->o->pte[0].page = newpage(0, 0, UTZERO); k = kmap(s->o->pte[0].page); - memcpy((ulong*)k->va, initcode, sizeof initcode); + memcpy((ulong*)VA(k), initcode, sizeof initcode); kunmap(k); s->minva = UTZERO; s->maxva = UTZERO+BY2PG; diff --git a/gnot/page.c b/gnot/page.c index b13b469c31f1b0ca756afe31802bc448bd03a4ba..2846e56897dcc75e396b22a64424d1d1e55132ea 100644 --- a/gnot/page.c +++ b/gnot/page.c @@ -213,7 +213,7 @@ loop: unlock(&palloc); if(!noclear){ k = kmap(p); - memset((void*)k->va, 0, BY2PG); + memset((void*)VA(k), 0, BY2PG); kunmap(k); } p->o = o; diff --git a/gnot/proc.c b/gnot/proc.c index 5e5a9ac4ef0a847b8a80a91d4f104095406db41a..515bb9a36e8888534070068ec609ae799e5f93a6 100644 --- a/gnot/proc.c +++ b/gnot/proc.c @@ -310,7 +310,7 @@ postnote(Proc *p, int dolock, char *n, int flag) if(dolock) lock(&p->debug); k = kmap(p->upage); - up = (User*)k->va; + up = (User*)VA(k); if(flag!=NUser && (up->notify==0 || up->notified)) up->nnote = 0; /* force user's hand */ else if(up->nnote == NNOTE-1){ @@ -529,8 +529,8 @@ again: p->child = 0; k = kmap(c->upage); if(w) - *w = *(Waitmsg*)(p->waitmsg|k->va); - cpid = ((Waitmsg*)(p->waitmsg|k->va))->pid; + *w = *(Waitmsg*)(p->waitmsg|VA(k)); + cpid = ((Waitmsg*)(p->waitmsg|VA(k)))->pid; kunmap(k); p->time[TCUser] += c->time[TUser] + c->time[TCUser]; p->time[TCSys] += c->time[TSys] + c->time[TCSys]; @@ -580,7 +580,7 @@ kproc(char *name, void (*func)(void *), void *arg) p = newproc(); p->upage = newpage(1, 0, USERADDR|(p->pid&0xFFFF)); k = kmap(p->upage); - upa = k->va; + upa = VA(k); up = (User*)upa; up->p = p; diff --git a/gnot/sysproc.c b/gnot/sysproc.c index 19c52a878a850af29f143dd20a72394bbdb9c649..091ac437786e40a5270f1e62a9e7e3ea8af6da26 100644 --- a/gnot/sysproc.c +++ b/gnot/sysproc.c @@ -36,7 +36,7 @@ sysfork(ulong *arg) p = newproc(); p->upage = newpage(1, 0, USERADDR|(p->pid&0xFFFF)); k = kmap(p->upage); - upa = k->va; + upa = VA(k); /* * Save time: only copy u-> data and useful stack @@ -77,11 +77,11 @@ sysfork(ulong *arg) k = kmap(np); p->seg[SSEG].o->pte[i].page = np; if(i == 0){ /* only part of last stack page */ - memset((void*)k->va, 0, usp); - memcpy((void*)(k->va+usp), + memset((void*)VA(k), 0, usp); + memcpy((void*)(VA(k)+usp), (void*)(op->va+usp), BY2PG-usp); }else /* all of higher pages */ - memcpy((void*)k->va, (void*)op->va, BY2PG); + memcpy((void*)VA(k), (void*)op->va, BY2PG); kunmap(k); } } diff --git a/port/devcons.c b/port/devcons.c index de7a51b8ddcd1f60e05152b81f82a4fe2776ec91..4324ec30fb5077ff22334ce718792f8401409c66 100644 --- a/port/devcons.c +++ b/port/devcons.c @@ -315,7 +315,7 @@ ulong boottime; /* seconds since epoch at boot */ long seconds(void) { - return boottime + MACHP(0)->ticks*MS2HZ/1000; + return boottime + TK2MS(MACHP(0)->ticks); } int @@ -470,7 +470,7 @@ consread(Chan *c, void *buf, long n) l = u->p->time[i]; if(i == TReal) l = MACHP(0)->ticks - l; - l *= MS2HZ; + l = TK2MS(l); readnum(0, tmp+NUMSIZE*i, NUMSIZE, l, NUMSIZE); } memcpy(buf, tmp+k, n); @@ -486,7 +486,7 @@ consread(Chan *c, void *buf, long n) return readnum(c->offset, buf, n, u->p->parentpid, NUMSIZE); case Qtime: - return readnum(c->offset, buf, n, boottime+MACHP(0)->ticks/(1000/MS2HZ), 12); + return readnum(c->offset, buf, n, boottime+TK2MS(MACHP(0)->ticks), 12); case Quser: return readstr(c->offset, buf, n, u->p->pgrp->user); diff --git a/port/devproc.c b/port/devproc.c index 60f72d4646aedde575ea53222ace95dc5c102ef3..0a6a4e10bf9c380b4cf9a3dbd0c92e17ccd28b36 100644 --- a/port/devproc.c +++ b/port/devproc.c @@ -147,15 +147,12 @@ procopen(Chan *c, int omode) case Qnote: break; case Qdir: + case Qmem: case Qproc: case Qstatus: if(omode!=OREAD) error(0, Eperm); break; - case Qmem: - if(omode!=OREAD) - error(0, Eperm); - break; default: pprint("unknown qid in devopen\n"); error(0, Egreg); @@ -204,6 +201,8 @@ procread(Chan *c, void *va, long n) Seg *s; Orig *o; Page *pg; + KMap *k; + PTE *pte, *opte; int i; long l; long pid; @@ -240,14 +239,25 @@ procread(Chan *c, void *va, long n) unlock(o); error(0, Egreg); } - pg = o->pte[(c->offset-o->va)>>PGSHIFT].page; + pte = &o->pte[(c->offset-o->va)>>PGSHIFT]; + if(s->mod){ + opte = pte; + while(pte = pte->nextmod) /* assign = */ + if(pte->proc == p) + break; + if(pte == 0) + pte = opte; + } + pg = pte->page; unlock(o); if(pg == 0){ - pprint("nonresident page (complain to rob)\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*)VA(k); memcpy(a, b+(c->offset&(BY2PG-1)), n); + kunmap(k); } return n; } @@ -259,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*)VA(k); 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; } @@ -282,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*)VA(k); if(up->p != p){ + kunmap(k); pprint("note read u/p mismatch"); error(0, Egreg); } @@ -297,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; @@ -318,7 +333,7 @@ procread(Chan *c, void *va, long n) l = p->time[i]; if(i == TReal) l = MACHP(0)->ticks - l; - l *= MS2HZ; + l = TK2MS(l); readnum(0, statbuf+2*NAMELEN+12+NUMSIZE*i, NUMSIZE, l, NUMSIZE); } memcpy(a, statbuf+c->offset, n); @@ -333,6 +348,7 @@ procwrite(Chan *c, void *va, long n) { Proc *p; User *up; + KMap *k; char buf[ERRLEN]; if(c->qid & CHDIR) @@ -355,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*)VA(k); 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/port/lib.h b/port/lib.h index 867455b95afd3a337c7957fa17ee664bb862e744..c180289a2c6543f253a452045902b31b30d4e22e 100644 --- a/port/lib.h +++ b/port/lib.h @@ -43,6 +43,7 @@ struct Op }; extern void strconv(char*, Op*, int, int); extern int numbconv(Op*, int); +extern char *doprint(char*, char*, char*, void*); extern int fmtinstall(char, int (*)(Op*)); extern int sprint(char*, char*, ...); extern int print(char*, ...); diff --git a/port/proc.c b/port/proc.c index af1b0c519270ce47b09c56312fff5bcded58292e..83c3dc1bc335f2a74533f6e57dff41e4e16fddc1 100644 --- a/port/proc.c +++ b/port/proc.c @@ -391,9 +391,9 @@ pexit(char *s, int freemem) wp = &w.time[TUser]; up = &c->time[TUser]; ucp = &c->time[TCUser]; - *wp++ = (*up++ + *ucp++)*MS2HZ; - *wp++ = (*up++ + *ucp )*MS2HZ; - *wp = (*up )*MS2HZ; + *wp++ = TK2MS(*up++ + *ucp++); + *wp++ = TK2MS(*up++ + *ucp ); + *wp = TK2MS(*up ); p->child = c; /* * Pass info through back door, to avoid huge Proc's diff --git a/port/sysproc.c b/port/sysproc.c index af45ad0c31ee9e3cf4fd339aeebf46a9c8873311..6c5af9cf8f6cb1d41270967c8a5e3ffc560428c7 100644 --- a/port/sysproc.c +++ b/port/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 = VA(k); + /* * 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 @@ -51,7 +55,7 @@ sysfork(ulong *arg) s = &p->seg[SSEG]; s->proc = p; on = (s->maxva-s->minva)>>PGSHIFT; - usp = ((Ureg*)UREGADDR)->sp; + usp = ((Ureg*)UREGADDR)->usp; if(usp >= USTKTOP) panic("fork bad usp %lux", usp); if(usp < u->p->seg[SSEG].minva) @@ -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*)VA(k), 0, usp); + memcpy((void*)(VA(k)+usp), + (void*)(op->va+usp), BY2PG-usp); }else /* all of higher pages */ - memcpy((void*)(np->pa|KZERO), (void*)(op->pa|KZERO), BY2PG); + memcpy((void*)VA(k), (void*)op->va, BY2PG); + kunmap(k); } } unlock(s->o); @@ -350,7 +356,7 @@ sysexec(ulong *arg) ((Ureg*)UREGADDR)->pc = exec.entry - 4; sp = (ulong*)(USTKTOP - ssize); *--sp = nargs; - ((Ureg*)UREGADDR)->sp = (ulong)sp; + ((Ureg*)UREGADDR)->usp = (ulong)sp; lock(&p->debug); u->nnote = 0; u->notify = 0; diff --git a/power/clock.c b/power/clock.c index 26fe96ed34dfd23109155aade662541884aa0184..0ad8e1c9e27d04f2548fdbb3d98c9d728ae3faf8 100644 --- a/power/clock.c +++ b/power/clock.c @@ -17,7 +17,7 @@ alarm(int ms, void (*f)(Alarm*), void *arg) if(ms < 0) ms = 0; a = newalarm(); - a->dt = ms/MS2HZ; + a->dt = MS2TK(ms); a->f = f; a->arg = arg; s = splhi(); diff --git a/power/conf.h b/power/conf.h index ac406d65cba6a6114377d5d4f1534a29711a522e..89d3acea340d8490b7fdc347b6e5b1e3fe110f03 100644 --- a/power/conf.h +++ b/power/conf.h @@ -2,6 +2,7 @@ Conftab conftab[] = { {"nmach", &conf.nmach }, {"nproc", &conf.nproc }, {"npgrp", &conf.npgrp }, + {"npage0", &conf.npage0 }, {"npage", &conf.npage }, {"norig", &conf.norig }, {"npte", &conf.npte }, diff --git a/power/dat.h b/power/dat.h index 90a8abc2391c5890b11af82f30134c27c6a768ba..d4d7575b7e249ce9ff725be2a81916444598163b 100644 --- a/power/dat.h +++ b/power/dat.h @@ -118,6 +118,7 @@ struct Conf ulong nmach; /* processors */ ulong nproc; /* processes */ ulong npgrp; /* process groups */ + ulong npage0; /* total physical pages of memory */ ulong npage; /* total physical pages of memory */ ulong norig; /* origins */ ulong npte; /* contiguous page table entries */ @@ -358,6 +359,14 @@ struct User void *ureg; }; +/* + * Fake kmap + */ +typedef void KMap; +#define VA(k) ((ulong)(k)) +#define kmap(p) (KMap*)(p->pa|KZERO) +#define kunmap(k) + /* * operations available to a queue */ diff --git a/power/main.c b/power/main.c index 2e40d646120c5d2af870e906e2ecd90426dd93d4..9e585168e5d1e4b03c0bae124073f309d8d79826 100644 --- a/power/main.c +++ b/power/main.c @@ -546,7 +546,8 @@ confinit(void) break; x += 0x3141526; } - conf.npage = i*1024/4; + conf.npage0 = i*1024/4; + conf.npage = conf.npage0; /* * set minimal default values diff --git a/power/mem.h b/power/mem.h index 7ecde107569842755d9f6ba210ffe7f09cfb13aa..fd5622c01840b0e005b81ba15e9c4d95bd53e70d 100644 --- a/power/mem.h +++ b/power/mem.h @@ -12,10 +12,17 @@ #define BY2PG 4096 /* bytes per page */ #define WD2PG (BY2PG/BY2WD) /* words per page */ #define PGSHIFT 12 /* log(BY2PG) */ -#define MS2HZ 50 /* millisec per clock tick */ #define MAXMACH 4 /* max # cpus system can run */ +/* + * Time + */ +#define MS2HZ 50 /* millisec per clock tick */ +#define TK2SEC(t) ((t)/20) /* ticks to seconds */ +#define TK2MS(t) ((t)*MS2HZ) /* ticks to milliseconds */ +#define MS2TK(t) ((t)/MS2HZ) /* milliseconds to ticks */ + /* * CP0 registers */ diff --git a/power/ureg.h b/power/ureg.h index a2f08891112b4ae508cc60ff168fadbcadfc6bec..32cbfb3fc85f67d4204766ce48ca339d2d651916 100644 --- a/power/ureg.h +++ b/power/ureg.h @@ -2,7 +2,10 @@ struct Ureg { ulong status; ulong pc; - ulong sp; /* r29 */ + union{ + ulong sp; /* r29 */ + ulong usp; /* r29 */ + }; ulong cause; ulong badvaddr; ulong tlbvirt;