From 62db2a7b9d0a48d47223dc6a192e45aaa1921c64 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Thu, 30 Aug 1990 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1990-08-30 --- gnot/devcons.c | 24 ++++++++++++++++++------ gnot/errno.h | 2 +- gnot/fns.h | 3 +++ gnot/l.s | 29 ++++++++++++++--------------- gnot/screen.c | 43 +++++++++++++++++++++++++++++++++++++------ gnot/stream.c | 4 ++++ port/devdk.c | 8 ++++++-- port/stream.c | 16 +++++++++++++--- power/errno.h | 2 +- power/io.h | 14 ++++++++++++++ power/trap.c | 16 +++++++++++----- 11 files changed, 122 insertions(+), 39 deletions(-) diff --git a/gnot/devcons.c b/gnot/devcons.c index 168d85488bb5137cbce1b87d4501fec423d32b36..a614996104e66986459e8a83659634ab0fe1d7b8 100644 --- a/gnot/devcons.c +++ b/gnot/devcons.c @@ -583,7 +583,10 @@ consread(Chan *c, void *buf, long n) return i; case Qrs232ctl: - return 0; + if(c->offset) + return 0; + *(char *)buf = duartinputport(); + return 1; case Qcputime: k = c->offset; @@ -712,12 +715,21 @@ conswrite(Chan *c, void *va, long n) qunlock(&rs232oq); nexterror(); } - if(n>2 && n=sizeof buf) error(0, Ebadarg); + strncpy(buf, a, n); + buf[n] = 0; + l = strtoul(buf+1, 0, 0); + switch(buf[0]){ + case 'B': + duartbaud(l); break; + case 'D': + duartdtr(l); break; + case 'K': + duartbreak(l); break; + default: + error(0, Ebadarg); + } qunlock(&rs232oq); break; diff --git a/gnot/errno.h b/gnot/errno.h index 4ac80562c89324daa3612a6731601e569e28c10f..9502813e1b4ca8524405cbef0d9533f816c302fe 100644 --- a/gnot/errno.h +++ b/gnot/errno.h @@ -56,5 +56,5 @@ enum{ Ebadcnt, /* read count greater than requested */ Enofont, /* out of font descriptors */ Enovmem, /* virtual memory allocation failed */ - Egreg, /* it's all greg's fault */ + Egreg, /* rob made me do it */ }; diff --git a/gnot/fns.h b/gnot/fns.h index 550bc2ea9dda851806617479c2209cd60d5ae995..7af8fa4935a6d6334c14bf6ea19b0b40909593c8 100644 --- a/gnot/fns.h +++ b/gnot/fns.h @@ -32,6 +32,9 @@ Chan* devopen(Chan*, int, Dirtab*, int, Devgen*); void devstat(Chan*, char*, Dirtab*, int, Devgen*); int devwalk(Chan*, char*, Dirtab*, int, Devgen*); void duartbaud(int); +void duartbreak(int); +void duartdtr(int); +int duartinputport(void); void duartstartrs232o(void); void duartstarttimer(void); void duartstoptimer(void); diff --git a/gnot/l.s b/gnot/l.s index b854f39b1689761a657e4d82d30c4aab66e7ac1b..a4f7436699937812f00d2b6f03a096055ea1681f 100644 --- a/gnot/l.s +++ b/gnot/l.s @@ -142,17 +142,16 @@ TEXT rfnote(SB), $0 MOVL uregpp+0(FP), A0 MOVL (A0), A7 - MOVL A7, -(A7) - MOVL ((1+8+8)*BY2WD)(A7), A0 + MOVL ((8+8)*BY2WD)(A7), A0 MOVL A0, USP - MOVL ((1+8+6)*BY2WD)(A7), A6 - ADDL $((1+8+8+1)*4), A7 + MOVEM (A7), $0x7FFF + ADDL $((8+8+1)*BY2WD), A7 RTE TEXT illegal(SB), $0 SUBL $((8+8+1)*BY2WD), A7 - MOVEM $0xFFFF, (A7) + MOVEM $0x7FFF, (A7) MOVL $a6base(SB), A6 MOVL USP, A0 MOVL A0, ((8+8)*BY2WD)(A7) @@ -161,8 +160,8 @@ TEXT illegal(SB), $0 ADDL $4, A7 MOVL ((8+8)*BY2WD)(A7), A0 MOVL A0, USP - MOVEM (A7), $0xFFFF - ADDL $((8+8+1)*4), A7 + MOVEM (A7), $0x7FFF + ADDL $((8+8+1)*BY2WD), A7 RTE TEXT systrap(SB), $0 @@ -184,7 +183,7 @@ TEXT systrap(SB), $0 TEXT buserror(SB), $0 SUBL $((8+8+1)*BY2WD), A7 - MOVEM $0xFFFF, (A7) + MOVEM $0x7FFF, (A7) MOVL $a6base(SB), A6 MOVL USP, A0 MOVL A0, ((8+8)*BY2WD)(A7) @@ -194,7 +193,7 @@ TEXT buserror(SB), $0 ADDL $8, A7 MOVL ((8+8)*BY2WD)(A7), A0 MOVL A0, USP - MOVEM (A7), $0xFFFF + MOVEM (A7), $0x7FFF ADDL $((8+8+1)*4), A7 RTE @@ -208,7 +207,7 @@ TEXT tacintr(SB), $0 /* level 1 */ TEXT dkintr(SB), $0 /* level 2 */ SUBL $((8+8+1)*BY2WD), A7 - MOVEM $0xFFFF, (A7) + MOVEM $0x7FFF, (A7) MOVL $a6base(SB), A6 MOVL USP, A0 MOVL A0, ((8+8)*BY2WD)(A7) @@ -217,7 +216,7 @@ TEXT dkintr(SB), $0 /* level 2 */ ADDL $4, A7 MOVL ((8+8)*BY2WD)(A7), A0 MOVL A0, USP - MOVEM (A7), $0xFFFF + MOVEM (A7), $0x77FFF ADDL $((8+8+1)*4), A7 RTE @@ -240,7 +239,7 @@ TEXT mouseintr(SB), $0 /* level 4 */ TEXT uartintr(SB), $0 /* level 5 */ SUBL $((8+8+1)*BY2WD), A7 - MOVEM $0xFFFF, (A7) + MOVEM $0x7FFF, (A7) MOVL $a6base(SB), A6 MOVL USP, A0 MOVL A0, ((8+8)*BY2WD)(A7) @@ -249,14 +248,14 @@ TEXT uartintr(SB), $0 /* level 5 */ ADDL $4, A7 MOVL ((8+8)*BY2WD)(A7), A0 MOVL A0, USP - MOVEM (A7), $0xFFFF + MOVEM (A7), $0x7FFF ADDL $((8+8+1)*4), A7 RTE TEXT syncintr(SB), $0 /* level 6 */ SUBL $((8+8+1)*BY2WD), A7 - MOVEM $0xFFFF, (A7) + MOVEM $0x7FFF, (A7) MOVL $a6base(SB), A6 MOVL USP, A0 MOVL A0, ((8+8)*BY2WD)(A7) @@ -265,7 +264,7 @@ TEXT syncintr(SB), $0 /* level 6 */ ADDL $4, A7 MOVL ((8+8)*BY2WD)(A7), A0 MOVL A0, USP - MOVEM (A7), $0xFFFF + MOVEM (A7), $0x7FFF ADDL $((8+8+1)*4), A7 RTE diff --git a/gnot/screen.c b/gnot/screen.c index cf963c0c5335474f564977d680e1d0da89f0bbc5..d754b0ecdc4197f7fa22899d6b6f919a8f2a018b 100644 --- a/gnot/screen.c +++ b/gnot/screen.c @@ -22,6 +22,7 @@ struct{ void duartinit(void); int duartacr; +int duartimr; Bitmap screen = { @@ -205,7 +206,7 @@ duartinit(void) duart[1].ip_opcr = 0x00; duart[1].scc_ropbc = 0xFF; /* make sure the port is reset first */ duart[1].scc_sopbc = 0x04; /* dtr = 1, pp = 01 */ - duart[0].is_imr = IM_IPC|IM_RRDYB|IM_XRDYB|IM_RRDYA|IM_XRDYA; + duart[0].is_imr = duartimr = IM_IPC|IM_RRDYB|IM_XRDYB|IM_RRDYA|IM_XRDYA; duart[0].cmnd = ENB_TX|ENB_RX; /* enable TX and RX last */ duart[1].cmnd = ENB_TX|ENB_RX; @@ -217,13 +218,17 @@ duartinit(void) duart[0].data = 0x02; } +int +duartinputport(void) +{ + Duart *duart = DUARTREG; + return duart[1].ip_opcr; +} void duartbaud(int b) { int x; - Duart *duart; - - duart = DUARTREG; + Duart *duart = DUARTREG; switch(b){ case 38400: @@ -257,6 +262,32 @@ duartbaud(int b) duart[1].sr_csr = x; } +void +duartdtr(int val) +{ + Duart *duart = DUARTREG; + if (val) + duart[1].scc_ropbc=0x01; + else + duart[1].scc_sopbc=0x01; +} + +void +duartbreak(int ms) +{ + static QLock brk; + Duart *duart = DUARTREG; + if (ms<=0 || ms >20000) + error(0, Ebadarg); + qlock(&brk); + duart[0].is_imr = duartimr &= ~IM_XRDYB; + duart[1].cmnd = STRT_BRK|ENB_TX; + tsleep(&u->p->sleep, return0, 0, ms); + duart[1].cmnd = STOP_BRK|ENB_TX; + duart[0].is_imr = duartimr |= IM_XRDYB; + qunlock(&brk); +} + enum{ Kptime=200 /* about once per ms */ }; @@ -269,7 +300,7 @@ duartstarttimer(void) duart = DUARTREG; duart[0].ctur = (Kptime)>>8; duart[0].ctlr = (Kptime)&255; - duart[0].is_imr = IM_IPC|IM_RRDYB|IM_XRDYB|IM_RRDYA|IM_CRDY; + duart[0].is_imr = duartimr |= IM_CRDY; x = duart[1].scc_sopbc; } @@ -281,7 +312,7 @@ duartstoptimer(void) duart = DUARTREG; x = duart[1].scc_ropbc; - duart[0].is_imr = IM_IPC|IM_RRDYB|IM_XRDYB|IM_RRDYA; + duart[0].is_imr = duartimr &= ~IM_CRDY; } void diff --git a/gnot/stream.c b/gnot/stream.c index 645de94f5e194dfc528adf644e4856cd0e0eb514..b58a642457b32ed07854da4942f7c9c30c398a0b 100644 --- a/gnot/stream.c +++ b/gnot/stream.c @@ -986,6 +986,10 @@ streamread(Chan *c, void *vbuf, long n) qunlock(&s->rdlock); poperror(); + if(left<0 || left>n){ + print("streamread returns %d for a %d read\n", n-left, n); + panic("streamread"); + } return n - left; } diff --git a/port/devdk.c b/port/devdk.c index dd6c6ed75729bb518c81e1117e8df49b8879a204..4000b2d8abf83c2fb51b404d636797e1a21a4c6a 100644 --- a/port/devdk.c +++ b/port/devdk.c @@ -415,8 +415,12 @@ dkoput(Queue *q, Block *bp) if(bp->base && bp->rptr - bp->base >= 2) bp->rptr -= 2; - else - panic("dkoput"); + else { + print("dkoput l %d b %ux r %ux w %ux\n", line, bp->base, bp->rptr, + bp->wptr); + freeb(bp); + return; + } bp->rptr[0] = line; bp->rptr[1] = line>>8; diff --git a/port/stream.c b/port/stream.c index 645de94f5e194dfc528adf644e4856cd0e0eb514..9c65b4161f06682796d39dbd4e7fc82ed5ed0db9 100644 --- a/port/stream.c +++ b/port/stream.c @@ -48,6 +48,11 @@ static Lock garbagelock; /* * The block classes. There are Nclass block sizes, each with its own free list. * All are ialloced at qinit() time. + * + * NOTE: to help the mappings on the IO2 and IO3 boards, the data pointed + * to by a block must not cross a 4k boundary. Therefore: + * 1) all the following block sizes divide evenly into 4k + * 2) all the blocks are ialloc'd to not cross 4k boundaries */ typedef struct { int size; @@ -57,8 +62,8 @@ typedef struct { } Bclass; Bclass bclass[Nclass]={ { 0 }, - { 68 }, - { 260 }, + { 64 }, + { 256 }, { 4096 }, }; @@ -133,8 +138,13 @@ streaminit(void) n = n/2; bcp = &bclass[class]; for(i = 0; i < n; i++) { + /* + * The i == 0 means that each allocation range + * starts on a page boundary. This makes sure + * no block crosses a page boundary. + */ if(bcp->size) - bp->base = (uchar *)ialloc(bcp->size, 0); + bp->base = (uchar *)ialloc(bcp->size, i == 0); bp->lim = bp->base + bcp->size; bp->flags = class; freeb(bp); diff --git a/power/errno.h b/power/errno.h index f83ad0c595e287bcafe0cd5e8fa214ef5c0f002f..5f5c20bbfe5cad0b5d3294757770fd5b5fa42051 100644 --- a/power/errno.h +++ b/power/errno.h @@ -51,5 +51,5 @@ enum{ Ebadcnt, /* read count greater than requested */ Enoannounce, /* listening on an unannounced network connection */ Enovmem, /* virtual memory allocation failed */ - Egreg, /* it's all greg's fault */ + Egreg, /* rob made me do it */ }; diff --git a/power/io.h b/power/io.h index 423068b3083f8651f88f835fb44d3132eb5082f6..b676eadfaaa1e14a01cc6f5ce7f31dd51ea9bf60 100644 --- a/power/io.h +++ b/power/io.h @@ -87,3 +87,17 @@ struct INTVEC { * IO board type */ extern int ioid; + +/* + * The IO2/IO3 slave maps. These maps are used to map + * external addresses to MP bus addresses. + */ +enum { + a24map, /* VME A24 non-priv address space */ + a32map, /* VME A32 non-priv address space */ + lancemap, /* Lance chip address space */ + scsi1map, /* SCSI bus 1 address space */ + scsi0map, /* SCSI bus 0 address space */ + nomap, +}; +#define WRITEMAP IO2(ulong, 0xFA0000); diff --git a/power/trap.c b/power/trap.c index fd25d1f7e6539cf43ec42acbebf7f3533d033ee9..098bbbe19efa31f25614c7d5be8f0adfc479fabc 100644 --- a/power/trap.c +++ b/power/trap.c @@ -197,7 +197,7 @@ intr(ulong cause, ulong pc) if(cause & INTR5){ if(!(*MPBERR1 & (1<<8))){ -/* print("MP bus error %lux\n", *MPBERR0); /**/ + print("MP bus error %lux %lux\n", *MPBERR0, *MPBERR1); /**/ *MPBERR0 = 0; i = *SBEADDR; } @@ -230,8 +230,11 @@ intr(ulong cause, ulong pc) loop: if(pend & 1) { v = INTVECREG->i[0].vec; - if(!(v & (1<<12))) - print("io2 mp bus error %d\n", 0); + if(!(v & (1<<12))){ + print("io2 mp bus error %d %lux %lux\n", 0, + *MPBERR0, *MPBERR1); + *MPBERR0 = 0; + } switch(ioid){ case IO2R1: case IO2R2: @@ -260,8 +263,11 @@ intr(ulong cause, ulong pc) for(i=1; pend; i++) { if(pend & 1) { v = INTVECREG->i[i].vec; - if(!(v & (1<<12))) - print("io2 mp bus error %d\n", i); + if(!(v & (1<<12))){ + print("io2 mp bus error %d %lux %lux\n", i, + *MPBERR0, *MPBERR1); + *MPBERR0 = 0; + } v &= 0xff; (*vmevec[v])(v); }