From 199caac4a5a50eec65c2ed0244db029bf359a26b Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Thu, 8 Aug 1991 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1991-08-08 --- pc/clock.c | 52 ++++++++++++++++++++--- pc/devuart.c | 105 +++++++++++++++++++++++----------------------- pc/fault386.c | 2 +- pc/fns.h | 6 +++ pc/main.c | 8 ---- pc/mem.h | 2 +- pc/trap.c | 10 +++-- port/devcons.c | 9 ++++ port/devmnt.c | 19 +++++++-- port/queue.c | 83 ++++++++++++++++-------------------- port/sysproc.c | 26 ++++++------ power/devhotrod.c | 6 +-- 12 files changed, 190 insertions(+), 138 deletions(-) diff --git a/pc/clock.c b/pc/clock.c index 1c82ddf08d1abebd38ee964563e3398f69670df8..2c9aa7ce432cff499d27a4c14dca2ebf79a8a27e 100644 --- a/pc/clock.c +++ b/pc/clock.c @@ -21,6 +21,7 @@ enum * period is the counter period */ Freq= 1193182, /* Real clock frequency */ + FHZ= 1000, /* hertz for fast clock */ }; /* @@ -60,14 +61,12 @@ clock(Ureg *ur) m->ticks++; - uartintr0(ur); - - if(m->ticks % 50) - return; - checkalarms(); mouseclock(); + /* + * process time accounting + */ p = m->proc; if(p){ p->pc = ur->pc; @@ -76,15 +75,56 @@ clock(Ureg *ur) } if(u && p && p->state==Running){ + /* + * preemption + */ if(anyready()){ if(p->hasspin) p->hasspin = 0; else sched(); } - if((ur->cs&0xffff) == UESEL){ /* if was in user mode */ + /* + * notes for processes that might be spinning + * in user mode. + */ + if((ur->cs&0xffff) == UESEL){ if(u->nnote) notify(ur); } } } + +/* + * a faster (1 MS) clock tick for a non-interrupting serial port or + * kernel profiling. m->ticks still increments as usual. + */ +void +fclock(Ureg *ur) +{ + static ulong ticks; + + uartintr0(ur); /* poll the serial port */ + if((ticks++ % (FHZ/HZ)) == 0) + clock(ur); +} + +void +fclockinit(void) +{ + int x; + + /* + * set vector for clock interrupts + */ + setvec(Clockvec, fclock); + + /* + * make clock output a square wave with a 1/FHZ period + */ + x = splhi(); + outb(Tmode, Load0square); + outb(T0cntr, (Freq/FHZ)); /* low byte */ + outb(T0cntr, (Freq/FHZ)>>8); /* high byte */ + splx(x); +} diff --git a/pc/devuart.c b/pc/devuart.c index 46e125cab82d9829ff00bb675620d0b0fc7434bb..b33a9b5ad5ae6162622886db63e46ce115b4ac62 100644 --- a/pc/devuart.c +++ b/pc/devuart.c @@ -1,4 +1,4 @@ -#include "u.h" + #include "u.h" #include "lib.h" #include "mem.h" #include "dat.h" @@ -18,9 +18,8 @@ enum */ Data= 0, /* xmit/rcv buffer */ Iena= 1, /* interrupt enable */ - Ircv= (1<<0), /* interrupt on receive */ - Ixmt= (1<<1), /* interrupt on xmit */ - Istat= 2, /* interrupt flag */ + Istat= 2, /* interrupt flag (read) */ + Tctl= 2, /* test control (write) */ Format= 3, /* byte format */ Bits8= (3<<0), /* 8 bits/byte */ Stop2= (1<<2), /* 2 stop bits */ @@ -42,6 +41,9 @@ enum Scratch=7, /* scratchpad */ Dlsb= 0, /* divisor lsb */ Dmsb= 1, /* divisor msb */ + + Serial= 0, + Modem= 1, }; typedef struct Uart Uart; @@ -62,7 +64,6 @@ struct Uart Queue *wq; /* write queue */ Rendez r; /* kproc waiting for input */ Alarm *a; /* alarm for waking the kernel process */ - int delay; /* between character input and waking kproc */ int kstarted; /* kproc started */ uchar delim[256/8]; /* characters that act as delimiters */ }; @@ -248,7 +249,8 @@ uartintr0(Ureg *ur) void uartintr1(Ureg *ur) { - uartintr(&uart[1]); + if(uart[1].enabled) + uartintr(&uart[1]); } /* @@ -262,36 +264,42 @@ uartenable(Uart *up) /* * turn on power to the port */ - if(up == &uart[0]){ + if(up == &uart[Serial]){ if(serial(0) < 0) print("can't turn on serial port power\n"); } + /* + * speed up the clock to poll the uart + */ + fclockinit(); + /* * set up i/o routines */ if(up->oq){ up->oq->puts = uartputs; up->oq->ptr = up; - up->sticky[Iena] |= Ixmt; } if(up->iq){ up->iq->ptr = up; - up->sticky[Iena] |= Ircv; } up->enabled = 1; - up->sticky[Iena] |= (1<<2) | (1<<3); + up->sticky[Iena] = 0xf; /* * turn on interrupts */ uartwrreg(up, Iena, 0); + uartwrreg(up, Tctl, 0x0); /* * turn on DTR and RTS */ uartdtr(up, 1); uartrts(up, 1); + +print("uart enabled: Iena=%lux\n", uartrdreg(up, Iena)); } /* @@ -316,10 +324,15 @@ uartdisable(Uart *up) /* * turn off power */ - if(up == &uart[0]){ + if(up == &uart[Serial]){ if(serial(1) < 0) print("can't turn off serial power\n"); } + + /* + * slow the clock down again + */ + clockinit(); } /* @@ -374,25 +387,6 @@ uarttimer(Alarm *a) wakeup(&up->iq->r); } -static int -uartputc(IOQ *cq, int ch) -{ - Uart *up = cq->ptr; int r; - - r = putc(cq, ch); - - /* - * pass upstream within up->delay milliseconds - */ - if(up->a==0){ - if(up->delay == 0) - wakeup(&cq->r); - else - up->a = alarm(up->delay, uarttimer, up); - } - return r; -} - static void uartstopen(Queue *q, Stream *s) { @@ -403,18 +397,17 @@ 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]; + up->iq->putc = 0; uartenable(up); qlock(up); up->wq = WR(q); WR(q)->ptr = up; RD(q)->ptr = up; - up->delay = 64; - up->iq->putc = uartputc; qunlock(up); /* start with all characters as delimiters */ - memset(up->delim, 1, sizeof(up->delim)); + memset(up->delim, 0xff, sizeof(up->delim)); if(up->kstarted == 0){ up->kstarted = 1; @@ -468,6 +461,18 @@ uartoput(Queue *q, Block *bp) case 'd': uartdtr(up, n); break; + case 'e': + case 'E': + /* + * the characters in the block are the message + * delimiters to use upstream + */ + memset(up->delim, 0, sizeof(up->delim)); + while(++(bp->rptr) < bp->wptr){ + m = *bp->rptr; + up->delim[m/8] |= 1<<(m&7); + } + break; case 'K': case 'k': uartbreak(up, n); @@ -476,15 +481,9 @@ uartoput(Queue *q, Block *bp) case 'r': uartrts(up, n); break; - case 'W': - case 'w': - if(n>=0 && n<1000) - up->delay = n; - break; } }else while((m = BLEN(bp)) > 0){ while ((n = canputc(cq)) == 0){ -print("uartoput: sleeping\n"); sleep(&cq->r, canputc, cq); } if(n > m) @@ -507,21 +506,23 @@ uartkproc(void *a) Block *bp; int n; -loop: - while ((n = cangetc(cq)) == 0){ + if(waserror()) + print("uartkproc got an error\n"); + + for(;;){ sleep(&cq->r, cangetc, cq); + qlock(up); + if(up->wq == 0){ + cq->out = cq->in; + }else{ + n = cangetc(cq); + bp = allocb(n); + bp->flags |= S_DELIM; + bp->wptr += gets(cq, bp->wptr, n); + PUTNEXT(RD(up->wq), bp); + } + qunlock(up); } - qlock(up); - if(up->wq == 0){ - cq->out = cq->in; - }else{ - bp = allocb(n); - bp->flags |= S_DELIM; - bp->wptr += gets(cq, bp->wptr, n); - PUTNEXT(RD(up->wq), bp); - } - qunlock(up); - goto loop; } enum{ diff --git a/pc/fault386.c b/pc/fault386.c index e95741b8da5c79f2986fdb5aeb076dff46bea91b..9333a8b5f5638ad9c961406592d54f6488a661c1 100644 --- a/pc/fault386.c +++ b/pc/fault386.c @@ -35,7 +35,7 @@ fault386(Ureg *ur) } u->p->state = MMUing; dumpregs(ur); - panic("fault: 0x%lux 0x%lux", addr); + panic("fault: 0x%lux", addr); } faulting = 0; u->p->insyscall = insyscall; diff --git a/pc/fns.h b/pc/fns.h index 961da73598662924fba147c3ef89df592f308883..7d58da1f5287d243b90f8d41e655349691989498 100644 --- a/pc/fns.h +++ b/pc/fns.h @@ -4,12 +4,15 @@ void a20enable(void); #define clearmmucache() /* 386 doesn't have one */ void clock(Ureg*); void clockinit(void); +void config(int); void delay(int); void dmaend(int); long dmasetup(int, void*, long, int); #define evenaddr(x) /* 386 doesn't care */ void fault386(Ureg*); void faultinit(void); +void fclock(Ureg*); +void fclockinit(void); #define flushvirt(); void fpsave(FPsave*); void fprestore(FPsave*); @@ -20,8 +23,10 @@ int inss(int, void*, int); int outss(int, void*, int); void kbdinit(void); void kbdintr(Ureg*); +int mail(int); void mmuinit(void); void outb(int, int); +int owl(int); void prhex(ulong); void procrestore(Proc*, uchar*); void procsave(uchar*, int); @@ -39,5 +44,6 @@ void systrap(void); void touser(void); void trapinit(void); int tas(Lock*); +void uartintr0(Ureg*); void vgainit(void); #define waserror() (u->nerrlab++, setlabel(&u->errlab[u->nerrlab-1])) diff --git a/pc/main.c b/pc/main.c index 3dd33264683af430c5b48c1b96daa21c23f2b0af..c77f6f74ad14a44c2c7adec6061282c18e4ac1b8 100644 --- a/pc/main.c +++ b/pc/main.c @@ -373,14 +373,6 @@ 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/mem.h b/pc/mem.h index 758dd5fc30e35b79249510685743e744f048f826..b057a35bfc111dc84b8c68999465c541fad8b988 100644 --- a/pc/mem.h +++ b/pc/mem.h @@ -18,7 +18,7 @@ /* * Time */ -#define HZ (1000) /* clock frequency */ +#define HZ (20) /* clock frequency */ #define MS2HZ (1000/HZ) /* millisec per clock tick */ #define TK2SEC(t) ((t)/HZ) /* ticks to seconds */ #define TK2MS(t) ((((ulong)(t))*1000)/HZ) /* ticks to milliseconds */ diff --git a/pc/trap.c b/pc/trap.c index 8329b77668015451eb5497369faaf3629268707e..83c108c10addfaa8e09499541afd310455b9479d 100644 --- a/pc/trap.c +++ b/pc/trap.c @@ -34,8 +34,8 @@ enum EOI= 0x20, /* non-specific end of interrupt */ }; -int int0mask = 0xff; /* interrupts enabled for first 8259 */ -int int1mask = 0xff; /* interrupts enabled for second 8259 */ +int int0mask = 0x00; /* interrupts enabled for first 8259 */ +int int1mask = 0x00; /* interrupts enabled for second 8259 */ /* * trap/interrupt gates @@ -231,7 +231,7 @@ dumpregs(Ureg *ur) else print("registers for kernel\n"); print("FLAGS=%lux ECODE=%lux CS=%lux PC=%lux SS=%lux USP=%lux\n", ur->flags, - ur->ecode, ur->cs, ur->pc, ur->ss, ur->usp); + ur->ecode, ur->cs&0xff, ur->pc, ur->ss&0xff, ur->usp); print(" AX %8.8lux BX %8.8lux CX %8.8lux DX %8.8lux\n", ur->ax, ur->bx, ur->cx, ur->dx); @@ -286,7 +286,11 @@ syscall(Ureg *ur) } if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-(1+MAXSYSARG)*BY2WD)) validaddr(sp, (1+MAXSYSARG)*BY2WD, 0); + if(ax == EXITS) + print("%d exiting\n", u->p->pid); ret = (*systab[ax])((ulong*)(sp+BY2WD)); + if(ax == EXITS) + print("%d returned from sysexits!\n", u->p->pid); poperror(); } if(u->nerrlab){ diff --git a/port/devcons.c b/port/devcons.c index d6d388759ed1acce193f9a50e717c8c12c3cceb7..7e0e6d9f9138e922e3ce9c586c540eda4f1c6739 100644 --- a/port/devcons.c +++ b/port/devcons.c @@ -44,7 +44,14 @@ putstrn(char *str, int n) { int s, c, m; char *t; +static Lock fuck; +loop: +s = splhi(); +if(!canlock(&fuck)){ + splx(s); + goto loop; +} while(n > 0){ if(printq.puts && *str=='\n') (*printq.puts)(&printq, "\r", 1); @@ -59,6 +66,8 @@ putstrn(char *str, int n) n -= m; str += m; } +unlock(&fuck); +splx(s); } /* diff --git a/port/devmnt.c b/port/devmnt.c index 1b31d703a7f0835e3bb0f7a7fd57c13ba15de4f1..beccd6e9a4635e397c5ae67b60dfc1b33724447b 100644 --- a/port/devmnt.c +++ b/port/devmnt.c @@ -124,7 +124,10 @@ loop: lock(&mnthdralloc); if(mh = mnthdralloc.free){ /* assign = */ mnthdralloc.free = mh->next; - mh->flushing = 0; +if(mh->active) print("mh->active\n"); +if(mh->flushing) print("mh->flushing\n"); +if(mh->mbr) print("mh->mbr\n"); + mh->mbr = 0; unlock(&mnthdralloc); return mh; } @@ -619,8 +622,10 @@ mntflush(Mnt *m, Mnthdr *omh) /* queue is unlocked */ { Mnthdr *mh; - if(omh->thdr.type == Tflush) + if(omh->thdr.type == Tflush){ + omh->flushing = 0; return; + } mh = mhalloc(); if(waserror()){ @@ -680,8 +685,10 @@ mntxmit(Mnt *m, Mnthdr *mh) mh->mbr = 0; mbw = mballoc(); if(waserror()){ /* 1 */ - if(mh->mbr) + if(mh->mbr){ mbfree(mh->mbr); + mh->mbr = 0; + } mbfree(mbw); nexterror(); } @@ -780,6 +787,7 @@ mntxmit(Mnt *m, Mnthdr *mh) qunlock(q); qlocked = 0; if(waserror()){ /* 3 */ +print("%d interrupted read %lux %lux\n", u->p->pid, mh, mh->mbr); mnterrdequeue(m, mh); nexterror(); } @@ -789,7 +797,7 @@ mntxmit(Mnt *m, Mnthdr *mh) }while(n == 0); poperror(); /* 3 */ if(convM2S(mh->mbr->buf, &mh->rhdr, n) == 0){ -print("POO bad len %d %ux!\n", n, mh->mbr->buf[0]); +print("%d POO bad len %d %ux %lux %lux\n", u->p->pid, n, mh->mbr->buf[0], mh, mh->mbr); mnterrdequeue(m, mh); error(Ebadmsg); } @@ -845,7 +853,9 @@ print("POO bad len %d %ux!\n", n, mh->mbr->buf[0]); qunlock(q); qlocked = 0; if(waserror()){ /* interrupted sleep */ +print("%d interrupted queued sleep %lux %lux %d %d\n", u->p->pid, mh, mh->mbr, mh->active, mh->flushing); mnterrdequeue(m, mh); +print("%d after flush sleep %lux %lux %d %d\n", u->p->pid, mh, mh->mbr, mh->active, mh->flushing); nexterror(); } sleep(&mh->r, mntreadreply, mh); @@ -885,6 +895,7 @@ print("POO bad len %d %ux!\n", n, mh->mbr->buf[0]); memmove(mh->thdr.data, mh->rhdr.data, mh->rhdr.count); } mbfree(mh->mbr); + mh->mbr = 0; mbfree(mbw); USED(qlocked); poperror(); /* 1 */ diff --git a/port/queue.c b/port/queue.c index d15e29ea5bd937e9514dc404ea9b180406fda362..6c7c15b22154fd6345fe3441c2101f54c5dd76c0 100644 --- a/port/queue.c +++ b/port/queue.c @@ -18,15 +18,16 @@ initq(IOQ *q) int putc(IOQ *q, int c) { - uchar *nextin; - if(q->in >= &q->buf[sizeof(q->buf)-1]) - nextin = q->buf; + uchar *next; + + if(q->in == &q->buf[NQ-1]) + next = q->buf; else - nextin = q->in+1; - if(nextin == q->out) + next = q->in+1; + if(next == q->out) return -1; *q->in = c; - q->in = nextin; + q->in = next; return 0; } @@ -38,7 +39,7 @@ getc(IOQ *q) if(q->in == q->out) return -1; c = *q->out; - if(q->out == q->buf+sizeof(q->buf)-1) + if(q->out == &q->buf[NQ-1]) q->out = q->buf; else q->out++; @@ -48,60 +49,44 @@ getc(IOQ *q) void puts(IOQ *q, void *buf, int n) { - int m; uchar *nextin; - uchar *s = buf; + uchar *next; + uchar *p = buf; - while(n){ - m = q->out - q->in - 1; - if(m < 0) - m = &q->buf[NQ] - q->in; - if(m == 0) - break; - if(m > n) - m = n; - memmove(q->in, s, m); - n -= m; - s += m; - nextin = q->in + m; - if(nextin >= &q->buf[NQ]) - q->in = q->buf; + for(; n; n--){ + if(q->in == &q->buf[NQ-1]) + next = q->buf; else - q->in = nextin; + next = q->in + 1; + if(next == q->out) + break; + *q->in = *p++; + q->in = next; } } int gets(IOQ *q, void *buf, int n) { - int m, k = 0; uchar *nextout; - uchar *s = buf; + uchar *p = buf; - while(n){ - m = q->in - q->out; - if(m < 0) - m = &q->buf[NQ] - q->out; - if(m == 0) - return k; - if(m > n) - m = n; - memmove(s, q->out, m); - s += m; - k += m; - n -= m; - nextout = q->out + m; - if(nextout >= &q->buf[NQ]) + for(; n && q->out != q->in; n--){ + *p++ = *q->out; + if(q->out == &q->buf[NQ-1]) q->out = q->buf; else - q->out = nextout; + q->out++; } - return k; + return p - (uchar*)buf; } int cangetc(void *arg) { - IOQ *q = (IOQ *)arg; - int n = q->in - q->out; + IOQ *q; + int n; + + q = (IOQ *)arg; + n = q->in - q->out; if (n < 0) n += sizeof(q->buf); return n; @@ -110,6 +95,12 @@ cangetc(void *arg) int canputc(void *arg) { - IOQ *q = (IOQ *)arg; - return sizeof(q->buf)-cangetc(q)-1; + IOQ *q; + int n; + + q = (IOQ *)arg; + n = q->out - q->in - 1; + if (n < 0) + n += sizeof(q->buf); + return n; } diff --git a/port/sysproc.c b/port/sysproc.c index 700b1eca66813b61bbffae4e9e9fb622634851c2..9fa7aa1f6d3917cebfbc64ea3545fc3ed8ece980 100644 --- a/port/sysproc.c +++ b/port/sysproc.c @@ -21,7 +21,7 @@ sysr1(ulong *arg) long sysfork(ulong *arg) { - return rfork(Forkfd|Forkeg|Forkpg); + return rfork(Forkfd); } /* This call will obsolete fork */ @@ -76,28 +76,28 @@ rfork(ulong flag) if(flag & Forkfd) p->fgrp = dupfgrp(u->p->fgrp); - else { + else{ p->fgrp = u->p->fgrp; incref(p->fgrp); } if(flag & Forkpg) { - p->pgrp = u->p->pgrp; /* Process groups */ - incref(p->pgrp); - } - else { p->pgrp = newpgrp(); pgrpcpy(p->pgrp, u->p->pgrp); } + else { + p->pgrp = u->p->pgrp; /* Process groups */ + incref(p->pgrp); + } if(flag & Forkeg) { - p->egrp = u->p->egrp; /* Environment group */ - incref(p->egrp); - } - else { p->egrp = newegrp(); envcpy(p->egrp, u->p->egrp); } + else { + p->egrp = u->p->egrp; /* Environment group */ + incref(p->egrp); + } /* * Sched @@ -406,14 +406,16 @@ long sysexits(ulong *arg) { char *status; + char *inval = "invalid exit string"; status = (char*)arg[0]; if(status){ if(waserror()) - status = "invalid exit string"; + status = inval; else{ validaddr((ulong)status, 1, 0); - vmemchr(status, 0, ERRLEN); + if(vmemchr(status, 0, ERRLEN) == 0) + status = inval; } poperror(); diff --git a/power/devhotrod.c b/power/devhotrod.c index 9ef6e1f74f68614d79a06bde53fee53f79387e92..c87589244b88535ce2ae552288f8b8b38104d09a 100644 --- a/power/devhotrod.c +++ b/power/devhotrod.c @@ -21,12 +21,11 @@ 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 */ -#define ENABCKSUM 1 +#define ENABCKSUM 0 typedef struct Hotrod Hotrod; @@ -72,14 +71,11 @@ hotsend(Hotrod *h, Hotmsg *m) lock(h); mp = (Hotmsg**)&h->addr->reqstq[h->wi]; -print("send 1 %lux\n", MP2VME(m)); delay(500); *mp = (Hotmsg*)MP2VME(m); -print("send 2\n"); delay(500); h->wi++; if(h->wi >= NRQ) h->wi = 0; unlock(h); -print("send 3\n"); delay(500); return mp; }