From 43b828beaacd10f8c9a561a982d1c84270c1f313 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 6 Aug 1991 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1991-08-06 --- pc/clock.c | 1 + pc/devfloppy.c | 1 + pc/devuart.c | 92 +++++++++++++++++++++++++++-------------------- pc/io.h | 4 +-- pc/l.s | 10 ++++++ pc/main.c | 15 +++++++- pc/trap.c | 26 +++++++++++++- port/page.c | 12 ++++++- port/pgrp.c | 1 + port/portdat.h | 9 +++++ port/proc.c | 19 ++++++++++ port/sysproc.c | 43 ++++++++++++++++++++++ port/systab.h | 2 ++ power/boot.c | 1 - power/devhotrod.c | 5 +-- 15 files changed, 194 insertions(+), 47 deletions(-) diff --git a/pc/clock.c b/pc/clock.c index 82af8e911e2769c05e364951c5e118cafdfc7dcb..4ef21ed523977aac0431d1fc2b140e8933dbc93c 100644 --- a/pc/clock.c +++ b/pc/clock.c @@ -62,6 +62,7 @@ clock(Ureg *ur) checkalarms(); mouseclock(); + uartintr0(ur); p = m->proc; if(p){ diff --git a/pc/devfloppy.c b/pc/devfloppy.c index 61522d42824554f2e94c1dfecf692fdbd52f32ef..50f21a39ff7dedfdc65407f3cef848a201d26f66 100644 --- a/pc/devfloppy.c +++ b/pc/devfloppy.c @@ -754,6 +754,7 @@ print("new offset %d instead of %d\n", offset, off+dp->len); static void floppyintr(Ureg *ur) { +print("floppy intr\n"); floppy.intr = 1; wakeup(&floppy.r); } diff --git a/pc/devuart.c b/pc/devuart.c index 1c688f70a51d03fee202b525282c302615810f82..f049df86ef2d3e66ced2711c1ae05a98459a74bc 100644 --- a/pc/devuart.c +++ b/pc/devuart.c @@ -206,44 +206,39 @@ uartintr(Uart *up) { int ch; IOQ *cq; - int s; + int s, l; + l = uartrdreg(up, Lstat); s = uartrdreg(up, Istat); -print("uartintr %lux\n", s); - switch(s){ - case 3: - /* - * get any input characters - */ - cq = up->iq; - while(uartrdreg(up, Lstat) & Inready){ - ch = uartrdreg(up, Data) & 0xff; - if(cq->putc) - (*cq->putc)(cq, ch); - else { - putc(cq, ch); - if(up->delim[ch/8] & (1<<(ch&7)) ) - wakeup(&cq->r); - } - } - break; - case 5: - /* - * send next output character - */ - if(uartrdreg(up, Lstat)&Outready){ - cq = up->oq; - lock(cq); - ch = getc(cq); -print("", ch);/**/ - if(ch < 0){ - up->printing = 0; + + cq = up->iq; + while(l & Inready){ + ch = uartrdreg(up, Data) & 0xff; +print("", ch); + if(cq->putc) + (*cq->putc)(cq, ch); + else { + putc(cq, ch); + if(up->delim[ch/8] & (1<<(ch&7)) ) wakeup(&cq->r); - }else - outb(up->port + Data, ch); - unlock(cq); } - break; + l = uartrdreg(up, Lstat); + } + + /* + * send next output character + */ + if(up->printing && (l&Outready)){ + cq = up->oq; + lock(cq); + ch = getc(cq); +print("", ch);/**/ + if(ch < 0){ + up->printing = 0; + wakeup(&cq->r); + }else + outb(up->port + Data, ch); + unlock(cq); } } void @@ -263,6 +258,8 @@ uartintr1(Ureg *ur) void uartenable(Uart *up) { + int x; + /* * set up i/o routines */ @@ -287,6 +284,15 @@ uartenable(Uart *up) */ uartdtr(up, 1); uartrts(up, 1); + + /* + * read interrupt status till there aren't any pending + */ + while(uartrdreg(up, Istat) != 1){ + x = splhi(); + uartintr(up); + splx(x); + } } /* @@ -303,6 +309,10 @@ uartspecial(int port, IOQ *oq, IOQ *iq, int baud) up->iq = iq; uartenable(up); uartsetbaud(up, baud); + if(port == 0){ + if(serial(0) < 0) + print("can't turn on serial port power\n"); + } if(iq){ /* @@ -366,9 +376,14 @@ uartstopen(Queue *q, Stream *s) Uart *up; char name[NAMELEN]; - kprint("uartstopen: q=0x%ux, inuse=%d, type=%d, dev=%d, id=%d\n", +print("uartstopen: q=0x%ux, inuse=%d, type=%d, dev=%d, id=%d\n", q, s->inuse, s->type, s->dev, s->id); + up = &uart[s->id]; + uartenable(up); + if(s->id==0 && serial(0)<0) + print("can't turn on serial power\n"); + qlock(up); up->wq = WR(q); WR(q)->ptr = up; @@ -399,6 +414,9 @@ uartstclose(Queue *q) WR(q)->ptr = 0; RD(q)->ptr = 0; qunlock(up); + + if(serial(1) < 0) + print("can't turn off serial power\n"); } static void @@ -511,9 +529,6 @@ uartreset(void) { Uart *up; - if(serial(0) < 0) - print("can't turn on power\n"); - uartsetup(); for(up = uart; up < &uart[2]; up++){ if(up->nostream) @@ -522,7 +537,6 @@ uartreset(void) initq(up->iq); up->oq = ialloc(sizeof(IOQ), 0); initq(up->oq); - uartenable(up); } } diff --git a/pc/io.h b/pc/io.h index f20e2737bad17075e96c87ce48fe0101da0a5a1d..0a213a62d01902ec96910f0a4d1a60102cf2948d 100644 --- a/pc/io.h +++ b/pc/io.h @@ -7,8 +7,8 @@ enum Int0vec= 16, /* first 8259 */ Clockvec= Int0vec+0, /* clock interrupts */ Kbdvec= Int0vec+1, /* keyboard interrupts */ - Uart0vec= Int0vec+3, /* inerrupt from uart b */ - Uart1vec= Int0vec+4, /* inerrupt from uart a */ + Uart0vec= Int0vec+3, /* serial line */ + Uart1vec= Int0vec+4, /* modem line */ Floppyvec= Int0vec+6, /* floppy interrupts */ Int1vec= Int0vec+8, /* second 8259 */ Mousevec= Int1vec+4, /* mouse interrupt */ diff --git a/pc/l.s b/pc/l.s index f4fa78a8ac1e9eb10244793cc99edf1918c90283..e3b5f14d770dab1a3cf83d0ee3adee6a6c1b88c4 100644 --- a/pc/l.s +++ b/pc/l.s @@ -488,3 +488,13 @@ TEXT fpsave(SB),$0 TEXT fprestore(SB),$0 RET + +/* + * set configuration register + */ +TEXT config(SB),$0 + MOVL l+0(FP),AX + MOVL $0x3F3,DX + OUTB + OUTB + RET diff --git a/pc/main.c b/pc/main.c index 4527eb17477b31682ab7b4dfea852d9a9ddf2641..3dd33264683af430c5b48c1b96daa21c23f2b0af 100644 --- a/pc/main.c +++ b/pc/main.c @@ -285,7 +285,12 @@ enum Pmudata= 0x198, Pmucsr= 0x199, - Busy= 0x1, + Busy= 0x1, + + /* + * configuration port + */ + Pconfig= 0x3F3, }; /* @@ -368,6 +373,14 @@ pmuwrbit(int index, int bit, int pos) int serial(int onoff) { + int x; + + /* + * set config (enable everything) + */ + x = splhi(); + config(0x00); + splx(x); return pmuwrbit(1, onoff, 6); } diff --git a/pc/trap.c b/pc/trap.c index 20e2dd561936e094eb930d0ba04cf1d5f8b4e8bc..5c49bd793183cad11a46282ba0a0ca86bfddf063 100644 --- a/pc/trap.c +++ b/pc/trap.c @@ -176,6 +176,9 @@ trap(Ureg *ur) if(v>=256 || ivec[v] == 0) panic("bad trap type %d %lux\n", v, ur->pc); + if(v==19 || v==20) + print("trap = %d\n", v); + /* * tell the 8259 that we're done with the * highest level interrupt (interrupts are still @@ -183,9 +186,9 @@ trap(Ureg *ur) */ c = v&~0x7; if(c==Int0vec || c==Int1vec){ - outb(Int0ctl, EOI); if(c == Int1vec) outb(Int1ctl, EOI); + outb(Int0ctl, EOI); } /* @@ -194,6 +197,27 @@ trap(Ureg *ur) (*ivec[v])(ur); } +/* + * print 8259 status + */ +void +dump8259(void) +{ + int c; + + outb(Int0ctl, 0x0a); /* read ir */ + print("ir0 %lux\n", inb(Int0ctl)); + outb(Int0ctl, 0x0b); /* read is */ + print("is0 %lux\n", inb(Int0ctl)); + print("im0 %lux\n", inb(Int0aux)); + + outb(Int1ctl, 0x0a); /* read ir */ + print("ir1 %lux\n", inb(Int1ctl)); + outb(Int1ctl, 0x0b); /* read is */ + print("is1 %lux\n", inb(Int1ctl)); + print("im1 %lux\n", inb(Int1aux)); +} + /* * dump registers */ diff --git a/port/page.c b/port/page.c index 14a5f26757f63cedaef0741a0dd76cbd04804172..a3998b546d03d4582660431fcf6894c37554c802 100644 --- a/port/page.c +++ b/port/page.c @@ -168,16 +168,26 @@ newpage(int clear, Segment **s, ulong va) /* The kp test is a poor guard against the pager deadlocking */ while((palloc.freecount < HIGHWATER && u->p->kp == 0) || palloc.freecount == 0) { palloc.wanted++; - unlock(&palloc); + unlock(&palloc); if(s && *s) { qunlock(&((*s)->lk)); *s = 0; } qlock(&palloc.pwait); /* Hold memory requesters here */ + if(waserror()) { + qunlock(&palloc.pwait); + lock(&palloc); + palloc.wanted--; + unlock(&palloc); + nexterror(); + } + kickpager(); tsleep(&palloc.r, ispages, 0, 1000); + poperror(); + qunlock(&palloc.pwait); lock(&palloc); palloc.wanted--; diff --git a/port/pgrp.c b/port/pgrp.c index 9cd03c0b081f30301f85bfa368171039ffb4529d..fde7389c6c25ed0ed2c7811c2ee09632eb928105 100644 --- a/port/pgrp.c +++ b/port/pgrp.c @@ -120,6 +120,7 @@ newpgrp(void) p->ref = 1; p->pgrpid = ++pgrpalloc.pgrpid; p->nmtab = 0; + memset(p->rendhash, 0, sizeof(p->rendhash)); unlock(&pgrpalloc); return p; } diff --git a/port/portdat.h b/port/portdat.h index a7b567153775fce9ae67ad681d2a2f88502b86f7..35e5faa7d8fddd3a913875345056eefad09a031b 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -355,6 +355,9 @@ struct Segment Pte *map[SEGMAPSIZE]; /* segment pte map */ }; +#define RENDHASH 32 +#define REND(p,s) ((p)->rendhash[(s)%RENDHASH]) + struct Pgrp { Ref; /* also used as a lock when mounting */ @@ -365,6 +368,7 @@ struct Pgrp int nmtab; /* highest active mount table entry, +1 */ QLock debug; /* single access via devproc.c */ Mtab *mtab; + Proc *rendhash[RENDHASH]; /* Rendezvous tag hash */ }; struct Egrp @@ -437,6 +441,7 @@ enum Wakeme, Broken, Stopped, + Rendezvous, }; /* @@ -499,6 +504,10 @@ struct Proc int hasspin; /* I hold a spin lock */ int newtlb; /* Pager has touched my tables so I must flush */ int procctl; /* Control for /proc debugging */ + + ulong rendtag; /* Tag for rendezvous */ + ulong rendval; /* Value for rendezvous */ + Proc *rendhash; /* Hash list for tag values */ /* * machine specific MMU goo */ diff --git a/port/proc.c b/port/proc.c index e16161a455a8a17fb110fda8239c7a71671ae12f..bd5d0c6d9deb56ed0211542ec5fbc0d66cd57cdf 100644 --- a/port/proc.c +++ b/port/proc.c @@ -41,6 +41,7 @@ char *statename[]={ /* BUG: generate automatically */ "Wakeme", "Broken", "Stopped", + "Rendez", }; /* @@ -390,6 +391,7 @@ postnote(Proc *p, int dolock, char *n, int flag) KMap *k; int s; Rendez *r; + Proc *d, **l; SET(k); USED(k); @@ -436,6 +438,23 @@ postnote(Proc *p, int dolock, char *n, int flag) unlock(r); splx(s); } + if(p->state == Rendezvous) { + lock(p->pgrp); + if(p->state == Rendezvous) { + p->rendval = 0; + l = &REND(p->pgrp, p->rendtag); + for(d = *l; d; d = d->rendhash) { + if(d == p) { + *l = p->rendhash; + break; + } + l = &d->rendhash; + } + ready(p); + } + unlock(p->pgrp); + } + return 1; } diff --git a/port/sysproc.c b/port/sysproc.c index e1be1c56bcd6ca74fdd632a66c0716fac30a6239..6ad3db1c8a4681af16b762fbdae767ff843fcf3a 100644 --- a/port/sysproc.c +++ b/port/sysproc.c @@ -562,3 +562,46 @@ sysbrk_(ulong *arg) { return ibrk(arg[0], BSEG); } + +long +sysrendezvous(ulong *arg) +{ + Proc *p, *d, **l; + int s, tag; + ulong val; + + tag = arg[0]; + l = &REND(u->p->pgrp, tag); + + lock(u->p->pgrp); + for(p = *l; p; p = p->rendhash) { + if(p->rendtag == tag) { + *l = p->rendhash; + val = p->rendval; + p->rendval = arg[1]; + + if(p->state != Rendezvous) + panic("rendezvous"); + ready(p); + unlock(u->p->pgrp); + return val; + } + l = &p->rendhash; + } + + /* Going to sleep here */ + p = u->p; + p->rendtag = tag; + p->rendval = arg[1]; + p->rendhash = *l; + *l = p; + + unlock(p->pgrp); + + s = splhi(); + u->p->state = Rendezvous; + sched(); + splx(s); + + return u->p->rendval; +} diff --git a/port/systab.h b/port/systab.h index 483f3c2fa678ef93538ded8d913ae40a3aa0ebfd..6ab3e64ee5f0d94f12b8f2f41a0c26355fc42f22 100644 --- a/port/systab.h +++ b/port/systab.h @@ -8,6 +8,7 @@ Syscall sysfstat, sysfwstat, sysgetpid, sysmount, sysnoted; Syscall sysnotify, sysopen, syspipe, sysr1, sysread, sysremove, sysseek; Syscall syssleep, sysstat, syswait, syswrite, syswstat, sysalarm, syssegbrk; Syscall syssegattach, syssegdetach, syssegfree, syssegflush; +Syscall sysrendezvous; Syscall *systab[]={ [SYSR1] sysr1, @@ -44,4 +45,5 @@ Syscall *systab[]={ [SEGDETACH] syssegdetach, [SEGFREE] syssegfree, [SEGFLUSH] syssegflush, + [RENDEZVOUS] sysrendezvous, }; diff --git a/power/boot.c b/power/boot.c index 7d2dd66dae35facd42c95980d3e635d3fee9552b..51b6f776ccf0433455947cd2d6597113c6850a85 100644 --- a/power/boot.c +++ b/power/boot.c @@ -485,7 +485,6 @@ error(char *s) * prompt and get input */ int -int outin(char *prompt, char *def, int len) { int n; diff --git a/power/devhotrod.c b/power/devhotrod.c index 6a48cbb346b7214a4cc91618c168e0ad62dfb431..9ef6e1f74f68614d79a06bde53fee53f79387e92 100644 --- a/power/devhotrod.c +++ b/power/devhotrod.c @@ -13,7 +13,6 @@ /* * If defined, ENABMEMTEST causes memory test to be run at device open */ -#define ENABMEMTEST #ifdef ENABMEMTEST void mem(Hot*, ulong*, ulong); #define NTESTBUF 256 @@ -22,6 +21,7 @@ ulong testbuf[NTESTBUF]; /* * If defined, ENABBUSTEST causes bus error diagnostic to be run at device open */ +#define ENABBUSTEST /* * If 1, ENABCKSUM causes data transfers to have checksums @@ -224,8 +224,9 @@ hotrodopen(Chan *c, int omode) */ mp = &u->khot; mp->cmd = Ubus; - hmp = hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->khot, 0); + hmp = hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->khot); hotwait(hmp); +for(;;) ; #endif } c->mode = openmode(omode);