From fd71a85ff948f7c3058aaa8e67195015d11709ce Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Thu, 25 Apr 1991 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1991-04-25 --- gnot/dat.h | 8 +++++ port/devcons.c | 35 +++++++++++++++++++-- port/devdup.c | 13 +++++++- port/devmnt.c | 33 +++++++++++++------ port/fault.c | 7 +++-- port/page.c | 2 ++ port/proc.c | 9 +++++- port/tcpoutput.c | 1 + power/dat.h | 20 ++++++++++-- power/devbit3.c | 2 ++ power/faultmips.c | 1 + power/fns.h | 2 ++ power/l.s | 47 ++++++++++++++++++++++++++++ power/main.c | 9 ++++-- power/mem.h | 5 +++ power/mmu.c | 80 +++++++++++++++++++++++++++++++++++++++++------ power/trap.c | 4 +++ 17 files changed, 248 insertions(+), 30 deletions(-) diff --git a/gnot/dat.h b/gnot/dat.h index 4d326c800f3214d2925c496d02782cebfa0f652f..2b8fa8c7325b3b984a63f5def3ecc2ea7416a194 100644 --- a/gnot/dat.h +++ b/gnot/dat.h @@ -223,6 +223,14 @@ struct Mach Lock alarmlock; /* access to alarm list */ void *alarm; /* alarms bound to this clock */ int fpstate; /* state of fp registers on machine */ + + int tlbfault; + int pfault; + int cs; + int syscall; + int spinlock; + int intr; + int stack[1]; }; diff --git a/port/devcons.c b/port/devcons.c index 0b79c2e2657a7dd663f37ce4ef65638ca1ca5737..e16ead37b0b3b4bea82f555ee2e59a2ee804485c 100644 --- a/port/devcons.c +++ b/port/devcons.c @@ -320,6 +320,7 @@ enum{ Qtime, Quser, Qvmereset, + Qsysstat, }; Dirtab consdir[]={ @@ -334,6 +335,7 @@ Dirtab consdir[]={ "time", {Qtime}, 12, 0600, "user", {Quser}, 0, 0600, "vmereset", {Qvmereset}, 0, 0600, + "sysstat", {Qsysstat}, 0, 0600, }; #define NCONS (sizeof consdir/sizeof(Dirtab)) @@ -443,13 +445,14 @@ consclose(Chan *c) long consread(Chan *c, void *buf, long n, ulong offset) { - int ch, i, j, k; + int ch, i, j, k, id; ulong l; uchar *out; char *cbuf = buf; char *user; int userlen; - char tmp[6*NUMSIZE]; + char tmp[6*NUMSIZE], xbuf[512]; + Mach *mp; if(n <= 0) return n; @@ -532,6 +535,18 @@ consread(Chan *c, void *buf, long n, ulong offset) case Qlog: return readlog(offset, buf, n); + case Qsysstat: + j = 0; + for(id = 0; id < 32; id++) { + if(active.machs & (1<cs, mp->intr, mp->syscall, mp->pfault, + mp->tlbfault, mp->tlbpurge, mp->spinlock); + } + } + + return readstr(offset, buf, n, xbuf); case Qnull: return 0; @@ -547,7 +562,9 @@ conswrite(Chan *c, void *va, long n, ulong offset) char cbuf[64]; char buf[256]; long l, m; + int id; char *a = va; + Mach *mp; switch(c->qid.path){ case Qcons: @@ -601,7 +618,21 @@ conswrite(Chan *c, void *va, long n, ulong offset) error(Eperm); vmereset(); break; + case Qsysstat: + for(id = 0; id < 32; id++) { + if(active.machs & (1<cs = 0; + mp->intr = 0; + mp->syscall = 0; + mp->pfault = 0; + mp->tlbfault = 0; + mp->tlbpurge = 0; + mp->spinlock = 0; + } + } + break; default: error(Egreg); } diff --git a/port/devdup.c b/port/devdup.c index 9ec8cd45a549ef71a3db6a48aedc2869998186e3..10b0951323db0e1da2e35fb6176ddf670e13939d 100644 --- a/port/devdup.c +++ b/port/devdup.c @@ -61,7 +61,18 @@ dupwalk(Chan *c, char *name) void dupstat(Chan *c, char *db) { - devstat(c, db, (Dirtab *)0, 0L, dupgen); + int fd; + Chan *f; + + if(c->qid.path == CHDIR){ + devstat(c, db, (Dirtab *)0, 0L, dupgen); + }else{ + fd = c->qid.path; + SET(f); + if(fd<0 || NFD<=fd || (f=u->fd[fd])==0) + error(Ebadfd); + (*devtab[f->type].stat)(f, (char*)db); + } } Chan * diff --git a/port/devmnt.c b/port/devmnt.c index a1dfea6800b0cc5ce6564db0889f87b0e2f861f2..828b530c066bf64fd53c70eed493ff2782f06537 100644 --- a/port/devmnt.c +++ b/port/devmnt.c @@ -397,11 +397,6 @@ mntclwalk(Chan *c, char *name) Mnthdr *mh; Chan *nc; - if(waserror()){ /* BUG: can check type of error? */ - freechan(nc); - nc = 0; - goto Out; - } nc = newchan(); nc->type = c->type; nc->dev = c->dev; @@ -413,6 +408,13 @@ mntclwalk(Chan *c, char *name) nc->aux = c->aux; nc->mchan = c->mchan; nc->mqid = c->qid; + mh = 0; + if(waserror()){ + close(nc); + if(mh) + mhfree(mh); + return 0; + } m = mntdev(c, 0); mh = mhalloc(); mh->thdr.type = Tclwalk; @@ -420,12 +422,21 @@ mntclwalk(Chan *c, char *name) mh->thdr.newfid = nc->fid; strcpy(mh->thdr.name, name); mntxmit(m, mh); - if(mh->rhdr.fid == mh->thdr.fid) - errors("directory entry not found"); poperror(); - nc->qid = mh->rhdr.qid; - incref(m); - Out: + if(mh->rhdr.fid == mh->thdr.fid){ + /* + * just free the chan, the other side has + * already clunked + */ + freechan(nc); + nc = 0; + } else { + /* + * it worked, keep the channel + */ + nc->qid = mh->rhdr.qid; + incref(m); + } mhfree(mh); return nc; } @@ -780,10 +791,12 @@ mntxmit(Mnt *m, Mnthdr *mh) print("type mismatch %d %d\n", mh->rhdr.type, mh->thdr.type+1); error(Ebadmsg); } +#ifdef PHILW_HACK if(mh->rhdr.fid != mh->thdr.fid){ print("fid mismatch %d %d type %d\n", mh->rhdr.fid, mh->thdr.fid, mh->rhdr.type); error(Ebadmsg); } +#endif /* * Copy out on read diff --git a/port/fault.c b/port/fault.c index fe479170c16c71feeb90d64dae2f3ea8d1480f7a..0feeaca3dd54d9c0271ec2e060dd406c53d080b2 100644 --- a/port/fault.c +++ b/port/fault.c @@ -16,7 +16,7 @@ fault(ulong addr, int read) char *l; Page *pg; int zeroed = 0, head = 1; - int i; + int i, touched = 0; KMap *k, *k1; s = seg(u->p, addr); @@ -61,6 +61,7 @@ fault(ulong addr, int read) pte = opte; } if(pte->page == 0){ + touched = 1; if(o->chan==0 || addr>(o->va+(o->maxca-o->minca))){ /* * Zero fill page. If we are really doing a copy-on-write @@ -114,7 +115,7 @@ fault(ulong addr, int read) if((o->flag & OWRPERM) && (conf.copymode || !read) && ((head && ((o->flag&OPURE) || o->nproc>1)) || (!head && pte->page->ref>1))){ - + touched = 1; /* * Look for the easy way out: are we the last non-modified? */ @@ -194,6 +195,8 @@ fault(ulong addr, int read) panic("addr %lux seg %d wrong proc in tail", addr, s-u->p->seg); } unlock(o); + if(touched == 0) + m->tlbfault++; putmmu(mmuvirt, mmuphys); return 0; } diff --git a/port/page.c b/port/page.c index 8357e319dfce36fd208ac4620509a428d0384fbd..ca30a77962973146d92fc6272c57ed18f41d8f40 100644 --- a/port/page.c +++ b/port/page.c @@ -47,6 +47,8 @@ struct{ PTEA *free; }modalloc; +extern long end; + /* * Called to allocate permanent data structures, before calling pageinit(). */ diff --git a/port/proc.c b/port/proc.c index 1fbd92d1ce8538daa0082e7018b0e30d006f3cd8..d775ac0f6e652dd7def2705d766c4d002471f31c 100644 --- a/port/proc.c +++ b/port/proc.c @@ -84,6 +84,7 @@ sched(void) if(u){ splhi(); + m->cs++; procsave(procstate, sizeof(procstate)); if(setlabel(&u->p->sched)){ /* woke up */ p = u->p; @@ -190,6 +191,7 @@ loop: p->exiting = 0; p->pgrp = 0; p->fpstate = FPinit; + p->kp = 0; memset(p->pidonmach, 0, sizeof p->pidonmach); memset(p->seg, 0, sizeof p->seg); lock(&pidalloc); @@ -327,13 +329,18 @@ postnote(Proc *p, int dolock, char *n, int flag) int s; Rendez *r; + SET(k); + USED(k); + if(dolock) lock(&p->debug); + if(p != u->p){ k = kmap(p->upage); up = (User*)VA(k); - }else + }else up = u; + if(flag!=NUser && (up->notify==0 || up->notified)) up->nnote = 0; /* force user's hand */ else if(up->nnote == NNOTE-1){ diff --git a/port/tcpoutput.c b/port/tcpoutput.c index c3ead71ffb2da7e512a2981520cc9cfea3ce80c1..57fe97eb3c25e527cc6cb600be1467d116c3aba8 100644 --- a/port/tcpoutput.c +++ b/port/tcpoutput.c @@ -93,6 +93,7 @@ tcp_output(Ipconv *s) stop_timer(&tcb->acktimer); tcb->flags &= ~FORCE; + tcprcvwin(s); seg.source = s->psrc; seg.dest = s->pdst; diff --git a/power/dat.h b/power/dat.h index a1cf8bd43ed86ed8503b81729ab1c7d6192e9f35..42d4ae0c9b5834db1741ba3b4ef37f245e730826 100644 --- a/power/dat.h +++ b/power/dat.h @@ -18,6 +18,7 @@ typedef struct Label Label; typedef struct List List; typedef struct Lock Lock; typedef struct Mach Mach; +typedef struct Softtlb Softtlb; typedef struct Mount Mount; typedef struct Mtab Mtab; typedef struct Note Note; @@ -218,10 +219,16 @@ struct Envp int chref; /* # chans from pgrp pointing here */ }; +struct Softtlb +{ + ulong virt; + ulong phys; +}; + struct Mach { - int machno; /* physical id of processor */ - int mmask; /* 1<machno */ + int machno; /* physical id of processor NB. MUST BE FIRST */ + Softtlb *stb; /* Software tlb simulation NB. MUST BE SECOND */ ulong ticks; /* of the clock since boot time */ Proc *proc; /* current process on this processor */ Label sched; /* scheduler wakeup */ @@ -230,6 +237,15 @@ struct Mach char pidhere[NTLBPID]; /* is this pid possibly in this mmu? */ int lastpid; /* last pid allocated on this machine */ Proc *pidproc[NTLBPID]; /* process that owns this tlbpid on this mach */ + + int tlbfault; + int tlbpurge; + int pfault; + int cs; + int syscall; + int spinlock; + int intr; + int stack[1]; }; diff --git a/power/devbit3.c b/power/devbit3.c index 2676a64e7719464715b54418f51380b5c981ce45..bf1a9931143b6a9543d9d892d0fe12a57751b81c 100644 --- a/power/devbit3.c +++ b/power/devbit3.c @@ -30,6 +30,7 @@ enum void bit3send(Bit3msg *bp, ulong cmd, void *addr, ulong count) { + do; while(*BIT3ADDR); bp->cmd = cmd; bp->addr = (ulong)addr; @@ -38,6 +39,7 @@ bit3send(Bit3msg *bp, ulong cmd, void *addr, ulong count) wbflush(); do; while(*BIT3HOLD); *BIT3INTR = 0x20; + } void diff --git a/power/faultmips.c b/power/faultmips.c index a86a63ca34e92ac2026d008dbfbe9d8bd292b379..0b7e360373f02491144cfad39e08ee32997cbc1f 100644 --- a/power/faultmips.c +++ b/power/faultmips.c @@ -17,6 +17,7 @@ faultmips(Ureg *ur, int user, int code) extern char *excname[]; int read; + m->pfault++; addr = ur->badvaddr; addr &= ~(BY2PG-1); read = !(code==CTLBM || code==CTLBS); diff --git a/power/fns.h b/power/fns.h index 5164334b1c7d1de180c790f07c9729709817e5bc..4a696d3402e0fd7a31e1c89b7dece50558a05a08 100644 --- a/power/fns.h +++ b/power/fns.h @@ -147,6 +147,7 @@ Block *pullup(Block *, int); void purgetlb(int); Queue *pushq(Stream*, Qinfo*); void putmmu(ulong, ulong); +void putstlb(ulong, ulong); void puttlb(ulong, ulong); void puttlbx(int, ulong, ulong); int putb(Blist*, Block*); @@ -207,6 +208,7 @@ void userinit(void); void validaddr(ulong, ulong, int); void vecinit(void); void vector80(void); +void vector0(void); void *vmemchr(void*, int, int); void vmereset(void); void wakeme(Alarm*); diff --git a/power/l.s b/power/l.s index a170898270738e4b8ed228dbcca9961d6fc1f08c..39f4d9afd276b465eb8c33fb49342bf2214c2a14 100644 --- a/power/l.s +++ b/power/l.s @@ -175,6 +175,7 @@ TEXT puttlb(SB), $4 NOOP JAL splx(SB) RET + index: TLBWI NOOP @@ -241,6 +242,52 @@ TEXT vector80(SB), $-4 MOVW $exception(SB), R26 JMP (R26) +TEXT vector0(SB), $-4 + + MOVW $utlbmiss(SB), R26 + MOVW M(TLBVIRT), R27 + SLL $(STLBLOG-9), R27 /* delay slot fodder */ + JMP (R26) + +TEXT utlbmiss(SB), $-4 + + SRL $(STLBLOG), R27, R26 + XOR R26, R27 + AND $((STLBSIZE-1)<<3), R27 + MOVW R27, M(TLBPHYS) /* scratch register, store */ + + MOVW $((MACHADDR+4) & 0xffff0000), R26 + MOVW $MPID, R27 + MOVB 3(R27), R27 + AND $7, R27 + SLL $PGSHIFT, R27 + ADDU R27, R26 + + MOVW M(TLBPHYS), R27 /* scratch register, load */ + MOVW ((MACHADDR+4) & 0xffff)(R26), R26 + ADDU R26, R27 + MOVW 4(R27), R26 + MOVW R26, M(TLBPHYS) + + MOVW M(TLBVIRT), R26 + MOVW (R27), R27 + BNE R26, R27, stlbm + + TLBP + MOVW M(EPC), R27 + MOVW M(INDEX), R26 + BGEZ R26, uind + TLBWR + NOOP + RFE (R27) +uind: + TLBWI + NOOP + RFE (R27) +stlbm: + MOVW $exception(SB), R26 + JMP (R26) + TEXT exception(SB), $-4 MOVW M(STATUS), R26 diff --git a/power/main.c b/power/main.c index 434414af48c2bae624e9b7e441984ae4c5defcda..b0da007618a49691ce2ecda607435cf9f02ddd40 100644 --- a/power/main.c +++ b/power/main.c @@ -7,6 +7,11 @@ #include "ureg.h" #include "init.h" +/* + * software tlb simulation + */ +Softtlb stlb[4][STLBSIZE]; + /* * args passed by boot process */ @@ -77,7 +82,7 @@ machinit(void) n = m->machno; memset(m, 0, sizeof(Mach)); m->machno = n; - m->mmask = 1<machno; + m->stb = &stlb[n][0]; } void @@ -100,7 +105,7 @@ vecinit(void) for(size=0; size<4; size++) *p++ = *q++; p = (ulong*)UTLBMISS; - q = (ulong*)vector80; + q = (ulong*)vector0; for(size=0; size<4; size++) *p++ = *q++; } diff --git a/power/mem.h b/power/mem.h index 2c57a4cc5702c2c6d7999dd118790f91c43de46d..e4a63db90d5056fcd3454c4447c012cb72a47958 100644 --- a/power/mem.h +++ b/power/mem.h @@ -96,6 +96,11 @@ #define PTEWRITE (1<<10) #define PTERONLY 0 #define PTEPID(n) ((n)<<6) +#define TLBPID(n) (((n)>>6)&0x3F) + +/* N.B. MUST CHANGE l.s utlbmiss if you want to change this */ +#define STLBLOG 13 +#define STLBSIZE (1<upage->pa | PTEWRITE | PTEVALID | PTEGLOBL; puttlbx(0, tlbvirt, tlbphys); + putstlb(tlbvirt, tlbphys); u = (User*)USERADDR; } @@ -34,19 +35,44 @@ mapstack(Proc *p) int newtlbpid(Proc *p) { - int i; + int i, s; Proc *sp; - + char *h; +/* + s = m->lastpid; + if(s >= NTLBPID) + s = 1; + i = s; + h = m->pidhere; + do{ + i++; + if(i >= NTLBPID) + i = 1; + }while(h[i] && i != s); + + if(i == s){ + sp = m->pidproc[i]; + if(sp){ + if(sp->pidonmach[m->machno] == i) + sp->pidonmach[m->machno] = 0; + purgetlb(i); + } + } +*/ i = m->lastpid+1; if(i >= NTLBPID) i = 1; sp = m->pidproc[i]; if(sp){ + if(sp->pidonmach[m->machno] == i) + sp->pidonmach[m->machno] = 0; + sp->pidonmach[m->machno] = 0; purgetlb(i); } - m->pidproc[i] = p; + m->lastpid = i; + m->pidproc[i] = p; return i; } @@ -68,6 +94,7 @@ putmmu(ulong tlbvirt, ulong tlbphys) p->pidonmach[m->machno] = tp; } tlbvirt |= PTEPID(tp); + putstlb(tlbvirt, tlbphys); puttlb(tlbvirt, tlbphys); m->pidhere[tp] = 1; p->state = Running; @@ -77,18 +104,38 @@ putmmu(ulong tlbvirt, ulong tlbphys) void purgetlb(int pid) { + Softtlb *entry, *etab; + char p[NTLBPID]; + Proc *sp; int i, rpid; - if(m->pidhere[pid] == 0) + if(m->pidproc[pid] == 0) return; - memset(m->pidhere, 0, sizeof m->pidhere); - for(i=TLBROFF; i>6) & 0x3F; - if(rpid == pid) + + m->tlbpurge++; + m->pidproc[pid] = 0; + memset(p, 0, sizeof p); + for(i=TLBROFF; ipidhere[rpid] = 1; + entry = m->stb; + etab = &entry[STLBSIZE]; + for(; entry < etab; entry++){ + rpid = TLBPID(entry->virt); + if(rpid == pid){ + entry->phys = 0; + entry->virt = 0; + }else + p[rpid] = 1; } + for(i = 0; i < NTLBPID; i++) + if(p[i] == 0){ + sp = m->pidproc[i]; + if(sp && sp->pidonmach[m->machno] == i) + sp->pidonmach[m->machno] = 0; + m->pidproc[i] = 0; + m->pidhere[i] = 0; + } } void @@ -111,4 +158,17 @@ void invalidateu(void) { puttlbx(0, KZERO | PTEPID(0), 0); + putstlb(KZERO | PTEPID(0), 0); +} + +void +putstlb(ulong tlbvirt, ulong tlbphys) +{ + Softtlb *entry; + + entry = &m->stb[((tlbvirt<<1) ^ (tlbvirt>>12)) & (STLBSIZE-1)]; + entry->phys = tlbphys; + entry->virt = tlbvirt; + if(tlbphys == 0) + entry->virt = 0; } diff --git a/power/trap.c b/power/trap.c index 242813929727bc1f665e89bc7659ec2a5a549f66..7b645b746719b96cf4da4fcfa9582e4bfa49a6a7 100644 --- a/power/trap.c +++ b/power/trap.c @@ -151,6 +151,7 @@ trap(Ureg *ur) sprint(buf, "sys: fp: %s FCR31 %lux", fpexcname(x), x); else sprint(buf, "sys: trap: %s[%d]", excname[ecode], m->machno); + postnote(u->p, 1, buf, NDebug); }else{ print("%s %s pc=%lux\n", user? "user": "kernel", excname[ecode], ur->pc); @@ -182,6 +183,7 @@ intr(Ureg *ur) ulong cause; static int bogies; + m->intr++; cause = ur->cause&(INTR5|INTR4|INTR3|INTR2|INTR1); if(cause & (INTR2|INTR4)){ clock(ur); @@ -237,6 +239,7 @@ intr(Ureg *ur) print("new pend %ux\n", xxx); npend = pend |= xxx; i = SBCCREG->flevel; + USED(i); } /* @@ -468,6 +471,7 @@ syscall(Ureg *aur) Ureg *ur; char *msg; + m->syscall++; u->p->insyscall = 1; ur = aur; u->p->pc = ur->pc; /* BUG */