From 6c24a0c57f3b580016e27b5ff270abd1a3b46914 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Thu, 18 Oct 1990 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1990-10-18 --- gnot/dat.h | 5 +- gnot/devdk.c | 9 ++-- gnot/stream.c | 2 + port/devcons.c | 131 ++++++++++++++++++++++++++++------------------ port/devdk.c | 9 ++-- port/page.c | 1 + port/stream.c | 2 + power/dat.h | 4 +- power/devhotrod.c | 53 ++++++++++++++++--- 9 files changed, 141 insertions(+), 75 deletions(-) diff --git a/gnot/dat.h b/gnot/dat.h index 89be61df5370aceacc43fe45ebc2f189b4f7314c..b3525e01f23a076714747d4bbb3ae4927b00619c 100644 --- a/gnot/dat.h +++ b/gnot/dat.h @@ -4,12 +4,10 @@ typedef struct Blist Blist; typedef struct Chan Chan; typedef struct Conf Conf; typedef struct Dev Dev; -typedef struct Dir Dir; typedef struct Dirtab Dirtab; typedef struct Env Env; typedef struct Envp Envp; typedef struct Envval Envval; -typedef struct Error Error; typedef struct FFrame FFrame; typedef struct FPsave FPsave; typedef struct KMap KMap; @@ -175,7 +173,7 @@ struct Dev struct Dirtab { char name[NAMELEN]; - long qid; + ulong qid; long length; long perm; }; @@ -445,6 +443,7 @@ struct Queue { Queue *other; /* opposite direction, same line discipline */ Queue *next; /* next queue in the stream */ void (*put)(Queue*, Block*); + QLock rlock; /* mutex for processes sleeping at r */ Rendez r; void *ptr; /* private info for the queue */ }; diff --git a/gnot/devdk.c b/gnot/devdk.c index a1d628c6f81830bf1cb3298890d062b07a395a2f..3220ae9877af76205e3e34ab81fdddc2cf18a7d4 100644 --- a/gnot/devdk.c +++ b/gnot/devdk.c @@ -118,7 +118,7 @@ struct Line { struct Dk { QLock; int ref; - char name[64]; /* dk name */ + char name[64]; /* dk name */ Queue *wq; /* dk output queue */ int lines; /* number of lines */ int ncsc; /* csc line number */ @@ -420,11 +420,8 @@ dkoput(Queue *q, Block *bp) bp->rptr[0] = line; bp->rptr[1] = line>>8; - if(QFULL(dp->wq->next)){ - print("dk wq full\n"); - freeb(bp); - } else - PUTNEXT(dp->wq, bp); + FLOWCTL(dp->wq); + PUTNEXT(dp->wq, bp); } /* diff --git a/gnot/stream.c b/gnot/stream.c index 6ea84c554e7604539ac3ac50830a4d7aa4125dbf..bd317bf6e200f6cbff3bab455c07c1d55394e138 100644 --- a/gnot/stream.c +++ b/gnot/stream.c @@ -1047,7 +1047,9 @@ notfull(void *arg) void flowctl(Queue *q) { + qlock(&q->rlock); sleep(&q->r, notfull, q->next); + qunlock(&q->rlock); } /* diff --git a/port/devcons.c b/port/devcons.c index ff2efdde14274287f3e4c57dd55e5727a495a64e..1db49ce118d081d958ffe2c6c03aa8fb369ae947 100644 --- a/port/devcons.c +++ b/port/devcons.c @@ -36,15 +36,15 @@ struct IOQ{ IOQ kbdq; /* qlock to getc; interrupt putc's */ IOQ lineq; /* lock to getc; interrupt putc's */ -#define SYSLOGMAGIC 0x23456789 -#define SYSLOG ((Syslog *)(UNCACHED | KZERO | 0x1B00)) +#define SYSLOGMAGIC 0xdeadbeaf +#define SYSLOG ((Syslog *)(UNCACHED | 0x1B00)) typedef struct Syslog Syslog; struct Syslog { ulong magic; - char *start; + int wrapped; char *next; - char buf[2*BY2PG - 3*BY2WD]; + char buf[2*1024]; }; @@ -67,7 +67,6 @@ printinit(void) unlock(&lineq); duartinit(); - sysloginit(); /* must be at the end of printinit */ } /* @@ -177,15 +176,12 @@ panic(char *fmt, ...) { char buf[PRINTSIZE]; int n; - Syslog *s; strcpy(buf, "panic: "); n = doprint(buf+7, buf+sizeof(buf), fmt, (&fmt+1)) - buf; buf[n] = '\n'; putstrn(buf, n+1); dumpstack(); - s = SYSLOG; - print("start/next is %lux/%lux\n", s->start, s->next); exit(); } @@ -309,6 +305,7 @@ enum{ Qcputime, Qlog, Qnull, +/* Qpanic, /**/ Qpgrpid, Qpid, Qppid, @@ -321,6 +318,7 @@ Dirtab consdir[]={ "cputime", Qcputime, 72, 0600, "log", Qlog, BY2PG-8, 0600, "null", Qnull, 0, 0600, +/* "panic", Qpanic, 0, 0666, /**/ "pgrpid", Qpgrpid, 12, 0600, "pid", Qpid, 12, 0600, "ppid", Qppid, 12, 0600, @@ -618,78 +616,111 @@ void sysloginit(void) { Syslog *s; - char *start, *next; + int i; s = SYSLOG; - next = s->next; - start = s->start; - if(s->magic!=SYSLOGMAGIC || next>=&s->buf[sizeof(s->buf)] - || start>=&s->buf[sizeof(s->buf)] || nextbuf){ - s->start = s->buf; + if(s->magic!=SYSLOGMAGIC || s->next>=&s->buf[sizeof(s->buf)] || s->nextbuf){ + s->wrapped = 0; s->next = s->buf; s->magic = SYSLOGMAGIC; } - print("start/next is %lux/%lux was %lux/%lux\n", s->start, s->next, - start, next); } void syslog(char *p, int n) { - int restart; Syslog *s; char *end; + int m; + sysloginit(); s = SYSLOG; end = &s->buf[sizeof(s->buf)]; - restart = 0; - while(n-- > 0){ - *s->next++ = *p++; - if(s->next >= end) + while(n){ + if(s->next + n > end) + m = end - s->next; + else + m = n; + memcpy(s->next, p, m); + s->next += m; + p += m; + n -= m; + if(s->next >= end){ + s->wrapped = 1; s->next = s->buf; - if(s->next == s->start) - restart = 1; - } - if(restart){ - s->start = s->next + 1; - if(s->start >= end) - s->start = s->buf; + } } wbflush(); } long -readlog(ulong off, char *buf, ulong n) +readlog(ulong off, char *buf, ulong len) { Syslog *s; - char *p; char *end; - char *a = buf; + char *start; + int n, m; + char *p; + n = len; + p = buf; + + sysloginit(); s = SYSLOG; + end = &s->buf[sizeof(s->buf)]; - /* past end */ - if(off >= sizeof(s->buf)) + if(s->wrapped){ + start = s->next; + m = sizeof(s->buf); + } else { + start = s->buf; + m = s->next - start; + } + + if(off > m) return 0; + if(off + n > m) + n = m - off; + start += off; + if(start > end) + start -= sizeof(s->buf); - /* point to start of area to be read */ + while(n > 0){ + if(start + n > end) + m = end - start; + else + m = n; + memcpy(p, start, m); + start += m; + p += m; + n -= m; + if(start >= end) + start = s->buf; + } + + return p-buf; +} + +/* + * Read and write every byte of the log. This seems to ensure that + * on reboot, the bytes will really be in memory. I don't understand -- presotto + */ +void +flushsyslog(void) +{ + Syslog *s; + char *p, *end; + int x; + + s = SYSLOG; end = &s->buf[sizeof(s->buf)]; - p = s->start; - /* skip offset */ - while(off-- > 0){ - if(p == s->next) - return 0; - p++; - } + x = splhi(); + lock(&printq); + for(p = s->buf; p < end; p++) + *p = *p; + unlock(&printq); + splx(x); - /* copy out */ - while(n-- > 0){ - if(p == s->next) - break; - *a++ = *p++; - if(p >= end) - p = s->buf; - } - return a-buf; + wbflush(); } diff --git a/port/devdk.c b/port/devdk.c index 61087c15582d3047a71c4a8af87c92d28463ea80..3220ae9877af76205e3e34ab81fdddc2cf18a7d4 100644 --- a/port/devdk.c +++ b/port/devdk.c @@ -118,7 +118,7 @@ struct Line { struct Dk { QLock; int ref; - char name[64]; /* dk name */ + char name[64]; /* dk name */ Queue *wq; /* dk output queue */ int lines; /* number of lines */ int ncsc; /* csc line number */ @@ -420,11 +420,8 @@ dkoput(Queue *q, Block *bp) bp->rptr[0] = line; bp->rptr[1] = line>>8; - if(QFULL(dp->wq->next)){ -/* print("dk wq full\n");/**/ - freeb(bp); - } else - PUTNEXT(dp->wq, bp); + FLOWCTL(dp->wq); + PUTNEXT(dp->wq, bp); } /* diff --git a/port/page.c b/port/page.c index 76f8a37b03da02d387322c352bcc46fcd8f472e9..193be982432f5dd33db77a3b41becfbd92272422 100644 --- a/port/page.c +++ b/port/page.c @@ -463,6 +463,7 @@ freesegs(int save) if(i == save) continue; o = s->o; + s->o = 0; /* seg() won't match it (e.g. in procread()) */ if(o == 0) continue; lock(o); diff --git a/port/stream.c b/port/stream.c index 6ea84c554e7604539ac3ac50830a4d7aa4125dbf..bd317bf6e200f6cbff3bab455c07c1d55394e138 100644 --- a/port/stream.c +++ b/port/stream.c @@ -1047,7 +1047,9 @@ notfull(void *arg) void flowctl(Queue *q) { + qlock(&q->rlock); sleep(&q->r, notfull, q->next); + qunlock(&q->rlock); } /* diff --git a/power/dat.h b/power/dat.h index 02657abb3774354421c2fd7e6147f32f1d426e83..73a386d2a62e77732e4c050f20112d16060f8aae 100644 --- a/power/dat.h +++ b/power/dat.h @@ -9,7 +9,6 @@ typedef struct Dirtab Dirtab; typedef struct Env Env; typedef struct Envp Envp; typedef struct Envval Envval; -typedef struct Error Error; typedef struct FPsave FPsave; typedef struct Label Label; typedef struct List List; @@ -174,7 +173,7 @@ struct Dev struct Dirtab { char name[NAMELEN]; - long qid; + ulong qid; long length; long perm; }; @@ -439,6 +438,7 @@ struct Queue { Queue *other; /* opposite direction, same line discipline */ Queue *next; /* next queue in the stream */ void (*put)(Queue*, Block*); + QLock rlock; /* mutex for r */ Rendez r; void *ptr; /* private info for the queue */ }; diff --git a/power/devhotrod.c b/power/devhotrod.c index 85a9566b57b30d8603f571b6d855b36a630eba67..007d2b6cd8b28300b2795f02b3fdc808fe33ccbb 100644 --- a/power/devhotrod.c +++ b/power/devhotrod.c @@ -14,7 +14,7 @@ typedef struct Device Device; enum { Vmevec= 0xd2, /* vme vector for interrupts */ Intlevel= 5, /* level to interrupt on */ - Nhotrod= 1, + Nhotrod= 2, }; /* @@ -24,9 +24,9 @@ enum { * and 0xB00000 to 0xBFFFFF in A24 space */ struct Device { - uchar mem[1*1024*1024]; + ulong mem[1024*1024/sizeof(ulong)]; }; -#define HOTROD VMEA32SUP(Device, 0x30000000) +#define HOTROD VMEA24SUP(Device, 0xB00000) struct Hotrod { QLock; @@ -56,7 +56,7 @@ void hotrodreset(void) { int i; - Hsvme *hp; + Hotrod *hp; for(i=0; iqid == CHDIR){ if(omode != OREAD) error(0, Eperm); - }else - streamopen(c, &hotrodinfo); + } c->mode = openmode(omode); c->flag |= COPEN; c->offset = 0; @@ -143,6 +142,18 @@ hotrodread(Chan *c, void *buf, long n) { Hotrod *hp; Device *dp; + ulong *from; + ulong *to; + ulong *end; + + if(c->qid&CHDIR) + return devdirread(c, buf, n, 0, 0, hotrodgen); + + /* + * allow full word access only + */ + if((c->offset&(sizeof(ulong)-1)) || (n&(sizeof(ulong)-1))) + error(0, Ebadarg); hp = &hotrod[c->dev]; dp = hp->addr; @@ -150,8 +161,16 @@ hotrodread(Chan *c, void *buf, long n) return 0; if(c->offset+n > sizeof(dp->mem)) n = sizeof(dp->mem) - c->offset; + + /* + * avoid memcpy to ensure VME 32-bit reads + */ qlock(hp); - memcpy(buf, &dp->mem[c->offset], n); + to = buf; + from = &dp->mem[c->offset/sizeof(ulong)]; + end = to + (n/sizeof(ulong)); + while(to != end) + *to++ = *from++; qunlock(hp); return n; } @@ -164,6 +183,15 @@ hotrodwrite(Chan *c, void *buf, long n) { Hotrod *hp; Device *dp; + ulong *from; + ulong *to; + ulong *end; + + /* + * allow full word access only + */ + if((c->offset&(sizeof(ulong)-1)) || (n&(sizeof(ulong)-1))) + error(0, Ebadarg); hp = &hotrod[c->dev]; dp = hp->addr; @@ -171,8 +199,16 @@ hotrodwrite(Chan *c, void *buf, long n) return 0; if(c->offset+n > sizeof(dp->mem)) n = sizeof(dp->mem) - c->offset; + + /* + * avoid memcpy to ensure VME 32-bit writes + */ qlock(hp); - memcpy(&dp->mem[c->offset], buf, n); + from = buf; + to = &dp->mem[c->offset/sizeof(ulong)]; + end = to + (n/sizeof(ulong)); + while(to != end) + *to++ = *from++; qunlock(hp); return n; } @@ -201,6 +237,7 @@ hotroderrstr(Error *e, char *buf) rooterrstr(e, buf); } +static void hotrodintr(int vec) { Hotrod *hp;