From 01480269e7bf542ce714d3c56578c9e490fd687d Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sat, 9 Feb 1991 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1991-02-09 --- gnot/dat.h | 3 - port/devnonet.c | 20 ++---- port/proc.c | 8 +-- port/stnoether.c | 8 +++ power/clock.c | 18 +++-- power/dat.h | 24 +++++-- power/devhotrod.c | 166 ++++++++++++++++++++++++---------------------- power/fns.h | 6 +- power/trap.c | 19 ++---- ss/dat.h | 3 - 10 files changed, 139 insertions(+), 136 deletions(-) diff --git a/gnot/dat.h b/gnot/dat.h index 2ef31e13341424f309e74eefcca9c0caca4b30fb..21470d2d8feeaa6257f31cd71976603045b93088 100644 --- a/gnot/dat.h +++ b/gnot/dat.h @@ -220,9 +220,6 @@ struct Mach Lock alarmlock; /* access to alarm list */ void *alarm; /* alarms bound to this clock */ int fpstate; /* state of fp registers on machine */ - void (*intr)(ulong, ulong); /* !!Compatability with mips!! */ - ulong cause; /* ... */ - ulong pc; /* ... */ int stack[1]; }; diff --git a/port/devnonet.c b/port/devnonet.c index 07b01d9127b48e24142ab7e3d3ac58a665f5d042..48d27c1485e0cad3135d35a4050b5736f8a168a6 100644 --- a/port/devnonet.c +++ b/port/devnonet.c @@ -489,7 +489,7 @@ noclose(Queue *q) */ nosendctl(cp, NO_HANGUP, 1); for(i=0; i<10 && !ishungup(cp); i++){ - nosendctl(cp, NO_HANGUP, 1); + nosendctl(cp, NO_HANGUP, 0); tsleep(&cp->r, ishungup, cp, MSrexmit); } break; @@ -1008,21 +1008,11 @@ nosend(Noconv *cp, Nomsg *mp) return; wq = ifc->wq->next; - /* - * one transmitter at a time for this connection - */ - qlock(&cp->xlock); - - if(waserror()){ - qunlock(&cp->xlock); - return; - } - /* * get the next acknowledge to use if the next queue up * is not full. */ - if(cp->afirst != cp->anext && cp->rq->next->len < 16*1024){ + if(cp->afirst!=cp->anext && cp->rq->next->len<16*1024){ cp->hdr->ack = cp->ack[cp->afirst]; cp->afirst = (cp->afirst+1)&Nmask; } @@ -1103,8 +1093,6 @@ nosend(Noconv *cp, Nomsg *mp) else mp->time = NOW + (cp->rexmit+1)*MSrexmit; (*wq->put)(wq, pkt); - qunlock(&cp->xlock); - poperror(); } /* @@ -1409,9 +1397,9 @@ loop: */ if(cp->first!=cp->next && NOW>=cp->out[cp->first].time){ mp = &(cp->out[cp->first]); - if(cp->rexmit++ > 60){ + if(cp->rexmit++ > 15){ norack(cp, mp->mid); - nohangup(cp); + noreset(cp); } else nosend(cp, mp); } diff --git a/port/proc.c b/port/proc.c index 4e8f8b112e94a4294d3b172b1ee2d402ee52bd6d..f0df4ab4e45ac96ab2984906aa5d1be5a31137de 100644 --- a/port/proc.c +++ b/port/proc.c @@ -94,10 +94,6 @@ sched(void) } gotolabel(&m->sched); } - if(f = m->intr){ /* assign = */ - m->intr = 0; - (*f)(m->cause, m->pc); - } spllo(); p = runproc(); splhi(); @@ -320,10 +316,8 @@ postnote(Proc *p, int dolock, char *n, int flag) if(p != u->p){ k = kmap(p->upage); up = (User*)VA(k); - }else{ - SET(k); + }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/stnoether.c b/port/stnoether.c index f1c99fb8f97cebaa8af8cb7e110bf9d6b116ed41..be4feab52c683906619fc3b6e44bdcb3fcfb0742 100644 --- a/port/stnoether.c +++ b/port/stnoether.c @@ -120,6 +120,7 @@ noetherbad(Noifc *ifc, Block *bp) Etherhdr *eh, *neh; int circuit; Block *nbp; + int r; /* * crack the packet header @@ -131,6 +132,13 @@ noetherbad(Noifc *ifc, Block *bp) if(eh->flag & NO_RESET) goto out; + /* + * only one reset per message + */ + r = (eh->remain[1]<<8) | eh->remain[0]; + if(r<0) + goto out; + /* * craft an error reply */ diff --git a/power/clock.c b/power/clock.c index 1cf8bd47b7d4d6d2ddde1c79cc8f15adced1c784..eb59e88d11c864c8563a7c3236e2fad8a0248069 100644 --- a/power/clock.c +++ b/power/clock.c @@ -81,29 +81,26 @@ clockinit(void) void -clock(ulong n, ulong pc) +clock(Ureg *ur) { int i; Proc *p; - if(n&INTR2){ + if(ur->cause & INTR2){ i = *CLRTIM0; USED(i); m->ticks++; if(m->machno == 0){ p = m->proc; - if(p == 0) - p = m->intrp; if(p) p->time[p->insyscall]++; for(i=1; iproc; - if(p && p!=m->intrp) + if(p) p->time[p->insyscall]++; } } - m->intrp = 0; printslave(); } if(active.exiting && active.machs&(1<machno)){ @@ -111,9 +108,16 @@ clock(ulong n, ulong pc) exit(); } checkalarms(); + p = m->proc; + if((ur->status&IEP) && p && p->state==Running){ + if(anyready()) + sched(); + if(u->nnote && (ur->status&KUP)) + notify(ur); + } return; } - if(n & INTR4){ + if(ur->cause & INTR4){ extern ulong start; i = *CLRTIM1; diff --git a/power/dat.h b/power/dat.h index 24892d78f0ad06c8de6962cc71480607f81a0e6e..5494825a472e296d006dd06428eeaa3968dc6723 100644 --- a/power/dat.h +++ b/power/dat.h @@ -11,6 +11,7 @@ typedef struct Envp Envp; typedef struct Envval Envval; typedef struct Etherpkt Etherpkt; typedef struct FPsave FPsave; +typedef struct Hotmsg Hotmsg; typedef struct Lance Lance; typedef struct Lancemem Lancemem; typedef struct Label Label; @@ -91,6 +92,12 @@ struct Bit3msg ulong rcount; }; +struct Hotmsg +{ + ulong cmd; + ulong param[5]; +}; + #define CHDIR 0x80000000L struct Chan { @@ -207,10 +214,6 @@ struct Mach Label sched; /* scheduler wakeup */ Lock alarmlock; /* access to alarm list */ void *alarm; /* alarms bound to this clock */ - void (*intr)(ulong, ulong); /* pending interrupt */ - Proc *intrp; /* process that was interrupted */ - ulong cause; /* arg to intr */ - ulong pc; /* pc that was interrupted */ 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 */ @@ -360,11 +363,18 @@ struct User Chan *fd[NFD]; int maxfd; /* highest fd in use */ /* - * I/O point for bit3 interface. This is the easiest way to allocate + * I/O point for bit3 and hotrod interfaces. + * This is the easiest way to allocate * them, but not the prettiest or most general. */ - Bit3msg kbit3; - Bit3msg ubit3; + union{ + Bit3msg kbit3; + Hotmsg khot; + }; + union{ + Bit3msg ubit3; + Hotmsg uhot; + }; /* * Rest of structure controlled by devproc.c and friends. * lock(&p->debug) to modify. diff --git a/power/devhotrod.c b/power/devhotrod.c index 75d319ef096b678b9899b014a96822fbc271ff6d..f6b4988a0b3cb1a5277614b9d69d50295c3ff7e6 100644 --- a/power/devhotrod.c +++ b/power/devhotrod.c @@ -9,59 +9,72 @@ #include "io.h" typedef struct Hotrod Hotrod; +typedef struct HotQ HotQ; typedef struct Device Device; -typedef struct Printbuf Printbuf; enum { Vmevec= 0xd2, /* vme vector for interrupts */ Intlevel= 5, /* level to interrupt on */ - Nhotrod= 2, + Qdir= 0, /* Qid's */ + Qhotrod= 1, + NhotQ= 10, /* size of communication queues */ + Nhotrod= 1, }; /* - * circular 2 pointer queue for hotrod prnt's - */ -struct Printbuf { - char *rptr; - char *wptr; - char *lim; - char buf[4*1024]; -}; - -/* - * the hotrod fiber interface responds to 1MB + * The hotrod fiber interface responds to 1MB * of either user or supervisor accesses at: * 0x30000000 to 0x300FFFFF in A32 space - * and 0xB00000 to 0xBFFFFF in A24 space + * and 0xB00000 to 0xBFFFFF in A24 space. + * The second 0x40000 of this space is on-board SRAM. */ struct Device { - ulong mem[1024*1024/sizeof(ulong)]; + ulong mem[0x100000/sizeof(ulong)]; }; #define HOTROD VMEA24SUP(Device, 0xB00000) -struct Hotrod { - QLock; +struct HotQ{ + ulong i; /* index into queue */ + Hotmsg *msg[NhotQ]; /* pointer to command buffer */ + ulong pad[3]; /* unused; for hotrod prints */ +}; + +struct Hotrod{ + QLock; + Lock busy; Device *addr; /* address of the device */ int vec; /* vme interrupt vector */ - char name[NAMELEN]; /* hot rod name */ - Printbuf pbuf; /* circular queue for hotrod print's */ - int kprocstarted; + HotQ *wq; /* write this queue to send cmds */ + int wi; /* where to write next cmd */ + HotQ rq; /* read this queue to receive replies */ + int ri; /* where to read next response */ Rendez r; }; Hotrod hotrod[Nhotrod]; void hotrodintr(int); -void hotrodkproc(void *a); -int -hotrodgen(Chan *c, Dirtab *tab, int ntab, int i, Dir *dp) +/* + * Commands + */ +enum{ + RESET= 0, /* params: Q address, length of queue */ + REBOOT= 1, /* params: none */ +}; + +void +hotsend(Hotrod *h, Hotmsg *m) { - if(i || c->dev>=Nhotrod) - return -1; - devdir(c, (Qid){0,0}, hotrod[c->dev].name, sizeof(Device), 0666, dp); - return 1; +print("hotsend send %d %lux %lux\n", m->cmd, m, m->param[0]); + h->wq->msg[h->wi] = m; + while(h->wq->msg[h->wi]) + ; +print("hotsend done\n"); + h->wi++; + if(h->wi >= NhotQ) + h->wi = 0; } /* @@ -73,11 +86,14 @@ hotrodreset(void) int i; Hotrod *hp; - for(i=0; iaddr = HOTROD+i; + /* + * Write queue is at end of hotrod memory + */ + hp->wq = (HotQ*)((ulong)hp->addr+2*0x40000-sizeof(HotQ)); + hp->vec = Vmevec+i; + setvmevec(hp->vec, hotrodintr); } wbflush(); delay(20); @@ -102,10 +118,6 @@ hotrodattach(char *spec) if(i >= Nhotrod) error(Ebadarg); - hp = &hotrod[i]; - if(hp->kprocstarted == 0) - kproc(hp->name, hotrodkproc, hp); - c = devattach('H', spec); c->dev = i; c->qid.path = CHDIR; @@ -122,13 +134,20 @@ hotrodclone(Chan *c, Chan *nc) int hotrodwalk(Chan *c, char *name) { - return devwalk(c, name, 0, 0, hotrodgen); + if(c->qid.path != CHDIR) + return 0; + if(strncmp(name, "hotrod", 6) == 0){ + c->qid.path = Qhotrod; + return 1; + } + return 0; } void hotrodstat(Chan *c, char *dp) { - devstat(c, dp, 0, 0, hotrodgen); + print("hotrodstat\n"); + error(Egreg); } Chan* @@ -137,19 +156,28 @@ hotrodopen(Chan *c, int omode) Device *dp; Hotrod *hp; -#ifdef asdf - /* - * Remind hotrod where the print buffer is. The address we store - * is the address of the printbuf in VME A32 space. - */ - hp = &hotrod[c->dev]; - dp = hp->addr; - dp->mem[256*1024/sizeof(ulong)] = (((ulong)&hp->pbuf) - KZERO) | (SLAVE<<28); -#endif - if(c->qid.path == CHDIR){ if(omode != OREAD) error(Eperm); + }else if(c->qid.path == Qhotrod){ + hp = &hotrod[c->dev]; + if(!canlock(&hp->busy)) + error(Einuse); + /* + * Clear communications region + */ + memset(hp->wq->msg, 0, sizeof(hp->wq->msg)); + hp->wq->i = 0; + + /* + * Issue reset + */ + hp->wi = 0; + hp->ri = 0; + u->khot.cmd = RESET; + u->khot.param[0] = (ulong)&hp->rq; + u->khot.param[1] = NhotQ; + hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->khot); } c->mode = openmode(omode); c->flag |= COPEN; @@ -166,6 +194,14 @@ hotrodcreate(Chan *c, char *name, int omode, ulong perm) void hotrodclose(Chan *c) { + Hotrod *hp; + + hp = &hotrod[c->dev]; + if(c->qid.path != CHDIR){ + u->khot.cmd = REBOOT; + hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->khot); + unlock(&hp->busy); + } } /* @@ -180,8 +216,8 @@ hotrodread(Chan *c, void *buf, long n) ulong *to; ulong *end; - if(c->qid.path & CHDIR) - return devdirread(c, buf, n, 0, 0, hotrodgen); + if(c->qid.path != Qhotrod) + error(Egreg); /* * allow full word access only @@ -222,6 +258,8 @@ hotrodwrite(Chan *c, void *buf, long n) ulong *to; ulong *end; + if(c->qid.path != Qhotrod) + error(Egreg); /* * allow full word access only */ @@ -272,31 +310,3 @@ hotrodintr(int vec) return; } } - -/* - * print hotrod processor messages on the console - */ -void -hotrodkproc(void *a) -{ - Hotrod *hp = a; - char *p; - - hp->kprocstarted = 1; - hp->pbuf.rptr = hp->pbuf.wptr = hp->pbuf.buf; - hp->pbuf.lim = &hp->pbuf.buf[sizeof(hp->pbuf.buf)]; - - for(;;){ - p = hp->pbuf.wptr; - if(p != hp->pbuf.rptr){ - if(p > hp->pbuf.rptr){ - putstrn(hp->pbuf.rptr, p - hp->pbuf.rptr); - } else { - putstrn(hp->pbuf.rptr, hp->pbuf.lim - hp->pbuf.rptr); - putstrn(hp->pbuf.buf, hp->pbuf.wptr - hp->pbuf.buf); - } - hp->pbuf.rptr = p; - } - tsleep(&(hp->r), return0, 0, 1000); - } -} diff --git a/power/fns.h b/power/fns.h index 18dd6b685da4bea446a288141f369dd549513aa5..194f8fc7d1fcbee1ed412bc876708f0de54b397a 100644 --- a/power/fns.h +++ b/power/fns.h @@ -1,6 +1,7 @@ Alarm *alarm(int, void (*)(Alarm*), void*); void alarminit(void); Block *allocb(ulong); +int anyready(void); void append(List**, List*); void arginit(void); void cancel(Alarm*); @@ -10,7 +11,7 @@ void chaninit(void); void chandevreset(void); void chandevinit(void); void checkalarms(void); -void clock(ulong, ulong); +void clock(Ureg*); void clockinit(void); Chan *clone(Chan*, Chan*); void close(Chan*); @@ -84,7 +85,7 @@ void *ialloc(ulong, int); void icflush(void *, int); int incref(Ref*); void insert(List**, List*, List*); -void intr(ulong, ulong); +void intr(Ureg*); void invalidateu(void); void ioboardinit(void); void isdir(Chan*); @@ -120,6 +121,7 @@ int nonetcksum(Block*, int); void nonetfreeifc(Noifc*); Noifc* nonetnewifc(Queue*, Stream*, int, int, int, void (*)(Noconv*, char*)); void nonetrcvmsg(Noconv*, Block*); +void notify(Ureg*); void novme(int); void nullput(Queue*, Block*); void online(void); diff --git a/power/trap.c b/power/trap.c index 712cf5df1a971934c2bf38ba9ac033431aaad9ed..2c682e640d5de75730d1b3d7b3b2024eaf34a8f8 100644 --- a/power/trap.c +++ b/power/trap.c @@ -12,7 +12,6 @@ */ void (*vmevec[256])(int); -void notify(Ureg*); void noted(Ureg**); void rfnote(Ureg**); @@ -87,7 +86,6 @@ trap(Ureg *ur) u->p->pc = ur->pc; /* BUG */ switch(ecode){ case CINT: - m->intrp = 0; if(u && u->p->state==Running){ if(u->p->fpstate == FPactive) { if(ur->cause & INTR3){ /* FP trap */ @@ -100,14 +98,8 @@ trap(Ureg *ur) if(ecode == FPEXC) goto Default; } - m->intr = intr; - m->cause = ur->cause; - m->pc = ur->pc; - if(ur->cause & INTR2) - m->intrp = u->p; - sched(); - }else - intr(ur->cause, ur->pc); + } + intr(ur); break; case CTLBM: @@ -181,14 +173,15 @@ trap(Ureg *ur) } void -intr(ulong cause, ulong pc) +intr(Ureg *ur) { int i, pend; long v; + ulong cause; - cause &= INTR5|INTR4|INTR3|INTR2|INTR1; + cause = ur->cause&(INTR5|INTR4|INTR3|INTR2|INTR1); if(cause & (INTR2|INTR4)){ - clock(cause, pc); + clock(ur); cause &= ~(INTR2|INTR4); } if(cause & INTR1){ diff --git a/ss/dat.h b/ss/dat.h index 4abf930cb17d24c8775e37904774e447dd4a27f8..b941445f70c2d1b33e69ebffc3866c8e56aba08c 100644 --- a/ss/dat.h +++ b/ss/dat.h @@ -222,9 +222,6 @@ struct Mach Lock alarmlock; /* access to alarm list */ void *alarm; /* alarms bound to this clock */ int fpstate; /* state of fp registers on machine */ - void (*intr)(ulong, ulong); /* !!Compatibility with mips!! */ - ulong cause; /* ... */ - ulong pc; /* ... */ char pidhere[NTLBPID]; /* is this tlbpid possibly in this mmu? */ int lastpid; /* last pid allocated on this machine */ Proc *pidproc[NTLBPID]; /* process that owns this pid on this mach */