M gnot/devcons.c => gnot/devcons.c +18 -6
@@ 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 && *a=='B'){
- strncpy(buf, a, n);
- buf[n] = 0;
- duartbaud(strtoul(buf+1, 0, 0));
- }else
+ 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;
M gnot/errno.h => gnot/errno.h +1 -1
@@ 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 */
};
M gnot/fns.h => gnot/fns.h +3 -0
@@ 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);
M gnot/l.s => gnot/l.s +14 -15
@@ 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
M gnot/screen.c => gnot/screen.c +37 -6
@@ 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
M gnot/stream.c => gnot/stream.c +4 -0
@@ 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;
}
M port/devdk.c => port/devdk.c +6 -2
@@ 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;
M port/stream.c => port/stream.c +13 -3
@@ 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);
M power/errno.h => power/errno.h +1 -1
@@ 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 */
};
M power/io.h => power/io.h +14 -0
@@ 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);
M power/trap.c => power/trap.c +11 -5
@@ 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);
}