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, /* rob made me do it */
+ Egreg, /* ken hasn't implemented datakit */
};
M gnot/stream.c => gnot/stream.c +1 -1
@@ 246,7 246,7 @@ padb(Block *bp, int n)
nbp = allocb(n);
nbp->wptr = nbp->lim;
nbp->rptr = nbp->wptr - n;
- nbp->next = nbp;
+ nbp->next = bp;
return nbp;
}
}
M port/chan.c => port/chan.c +3 -0
@@ 96,11 96,14 @@ loop:
void
close(Chan *c)
{
+ if(c->flag & CFREE)
+ panic("close");
if(decref(c) == 0){
if(!waserror()){
(*devtab[c->type].close)(c);
poperror();
}
+ c->flag = CFREE;
lock(&chanalloc);
c->next = chanalloc.free;
chanalloc.free = c;
M port/devcons.c => port/devcons.c +1 -0
@@ 169,6 169,7 @@ panic(char *fmt, ...)
n = doprint(buf+7, buf+sizeof(buf), fmt, (&fmt+1)) - buf;
buf[n] = '\n';
putstrn(buf, n+1);
+ dumpstack();
exit();
}
M port/stream.c => port/stream.c +72 -42
@@ 24,6 24,19 @@ Qinfo procinfo = { stputq, nullput, 0, 0, "process" };
*/
static Qinfo *lds[Nlds+1];
+void
+newqinfo(Qinfo *qi)
+{
+ int i;
+
+ for(i=0; i<Nlds && lds[i]; i++)
+ if(lds[i] == qi)
+ return;
+ if(i == Nlds)
+ panic("pushable");
+ lds[i] = qi;
+}
+
/*
* All stream structures are ialloc'd at boot time
*/
@@ 55,14 68,6 @@ Bclass bclass[Nclass]={
};
/*
- * the per stream directory structure
- */
-Dirtab streamdir[]={
- "data", Sdataqid, 0, 0600,
- "ctl", Sctlqid, 0, 0600,
-};
-
-/*
* Dump all block information of how many blocks are in which queues
*/
void
@@ 115,26 120,19 @@ dumpqueues(void)
* Allocate streams, queues, and blocks. Allocate n block classes with
* 1/2(m+1) to class m < n-1
* 1/2(n-1) to class n-1
- *
- * All data areas are alligned to their size.
- *
- * No data area crosses a 4k boundary. This allows us to use the
- * VME/SCSI/LANCE to MP bus maps on the SGI power series machines.
*/
void
streaminit(void)
{
- int class, i, n, left;
+ int class, i, n;
Block *bp;
Bclass *bcp;
- uchar *ptr;
slist = (Stream *)ialloc(conf.nstream * sizeof(Stream), 0);
qlist = (Queue *)ialloc(conf.nqueue * sizeof(Queue), 0);
blist = (Block *)ialloc(conf.nblock * sizeof(Block), 0);
bp = blist;
n = conf.nblock;
- left = 0;
for(class = 0; class < Nclass; class++){
if(class < Nclass-1)
n = n/2;
@@ 145,15 143,8 @@ streaminit(void)
* starts on a page boundary. This makes sure
* no block crosses a page boundary.
*/
- if(bcp->size){
- if(bcp->size > left){
- left = bcp->size>4096 ? bcp->size : 4096;
- ptr = (uchar *)ialloc(left, 1);
- }
- bp->base = ptr;
- ptr += bcp->size;
- left -= bcp->size;
- }
+ if(bcp->size)
+ bp->base = (uchar *)ialloc(bcp->size, i == 0);
bp->lim = bp->base + bcp->size;
bp->flags = class;
freeb(bp);
@@ 488,6 479,54 @@ getb(Blist *q)
}
/*
+ * make sure the first block has n bytes
+ */
+Block *
+pullup(Block *bp, int n)
+{
+ Block *nbp;
+ int i;
+
+ /*
+ * this should almost always be true, the rest it
+ * just for to avoid every caller checking.
+ */
+ if(BLEN(bp) >= n)
+ return bp;
+
+ /*
+ * if not enough room in the first block,
+ * add another to the front of the list.
+ if(bp->lim - bp->rptr < n){
+ nbp = allocb(n);
+ nbp->next = bp;
+ bp = nbp;
+ }
+
+ /*
+ * copy bytes from the trailing blocks into the first
+ */
+ n -= BLEN(bp);
+ while(nbp = bp->next){
+ i = BLEN(nbp);
+ if(i > n) {
+ memcpy(bp->wptr, nbp->rptr, n);
+ bp->wptr += n;
+ nbp->rptr += n;
+ return bp;
+ } else {
+ memcpy(bp->wptr, nbp->rptr, i);
+ bp->wptr += i;
+ bp->next = nbp->next;
+ nbp->next = 0;
+ freeb(nbp);
+ }
+ }
+ freeb(bp);
+ return 0;
+}
+
+/*
* grow the front of a list of blocks by n bytes
*/
Block *
@@ 587,6 626,14 @@ streamparse(char *name, Block *bp)
}
/*
+ * the per stream directory structure
+ */
+Dirtab streamdir[]={
+ "data", Sdataqid, 0, 0600,
+ "ctl", Sctlqid, 0, 0600,
+};
+
+/*
* A stream device consists of the contents of streamdir plus
* any directory supplied by the actual device.
*
@@ 1150,20 1197,3 @@ streamstat(Chan *c, char *db, char *name)
devdir(c, c->qid, name, n, 0, &dir);
convD2M(&dir, db);
}
-
-/*
- * announce a line discipline that can be pushed
- */
-void
-newqinfo(Qinfo *qi)
-{
- int i;
-
- for(i=0; i<Nlds && lds[i]; i++)
- if(lds[i] == qi)
- return;
- if(i == Nlds)
- panic("pushable");
- lds[i] = qi;
-}
-
M power/dat.h => power/dat.h +1 -0
@@ 635,6 635,7 @@ extern char *statename[];
#define CMOUNT 2 /* is result of a mount/bind */
#define CCREATE 4 /* permits creation if CMOUNT */
#define CCEXEC 8 /* close on exec */
+#define CFREE 16 /* not in use */
/*
* Proc.time
M power/duart.c => power/duart.c +20 -0
@@ 202,3 202,23 @@ duartxmit(int c)
duart->cmnd = ENB_TX;
duart->data = c;
}
+
+void
+duartputs(char *s)
+{
+ int i;
+ while(*s){
+ duartputc(*s++);
+ }
+ for(i=0; i < 1000000; i++)
+ ;
+}
+
+void
+iprint(char *s, void *a, void *b, void *c, void *d)
+{
+ char buf[1024];
+
+ sprint(buf, s, a, b, c, d);
+ duartputs(buf);
+}
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, /* rob made me do it */
+ Egreg, /* ken hasn't implemented datakit */
};
M power/fns.h => power/fns.h +4 -1
@@ 43,6 43,7 @@ int devwalk(Chan*, char*, Dirtab*, int, Devgen*);
void duartinit(void);
void duartintr(void);
int duartputc(int);
+void duartputs(char*);
void duartreset(void);
void duartxmit(int);
void dumpregs(Ureg*);
@@ 97,7 98,6 @@ Orig *lookorig(ulong, ulong, int, Chan*);
void machinit(void);
void mapstack(Proc*);
int mount(Chan*, Chan*, int);
-void mpbuserror(void);
Chan *namec(char*, int, int, ulong);
void nexterror(void);
Alarm *newalarm(void);
@@ 160,11 160,14 @@ Seg *seg(Proc*, ulong);
int segaddr(Seg*, ulong, ulong);
int setlabel(Label*);
void setvmevec(int, void (*)(int));
+void sinit(void);
char* skipslash(char*);
void sleep(Rendez*, int(*)(void*), void*);
+uchar* smap(int, uchar*);
int splhi(void);
int spllo(void);
void splx(int);
+void sunmap(int, uchar*);
Devgen streamgen;
void streamclose(Chan*);
int streamenter(Stream*);
M power/io.h => power/io.h +3 -3
@@ 44,8 44,8 @@ struct SBCC
#define LANCERAM IO2(uchar, 0xE00000)
#define LANCEEND IO2(uchar, 0xF00000)
-#define LANCE3RAM IO2(uchar, 0xFF4000)
-#define LANCE3END IO2(uchar, 0xFF8000)
+#define LANCE3RAM IO2(ushort, 0xFF4000)
+#define LANCE3END IO2(ushort, 0xFF8000)
#define LANCERDP IO2(ushort, 0xFC0002)
#define LANCERAP IO2(ushort, 0xFC000a)
#define LANCEID IO2(ushort, 0xFF0002)
@@ 102,4 102,4 @@ enum {
Scsi0map, /* SCSI bus 0 address space */
Nomap,
};
-#define WRITEMAP IO2(ulong, 0xFA0000);
+#define WRITEMAP IO2(ulong, 0xFA0000)
M power/main.c => power/main.c +20 -31
@@ 35,17 35,13 @@ char confbuf[4*1024];
char sysname[64];
/*
- * IO board type, number of interrupt levels, and interrupt enable mask
+ * IO board type
*/
int ioid;
-int iolevels;
-int iomask;
void
main(void)
{
- int i;
-
machinit();
active.exiting = 0;
active.machs = 1;
@@ 61,12 57,12 @@ main(void)
clockinit();
alarminit();
ioboardinit();
+ ioboardid();
chandevreset();
streaminit();
sysloginit();
pageinit();
userinit();
- ioboardid();
launchinit();
schedinit();
}
@@ 113,16 109,16 @@ ioboardid(void)
{
switch(ioid){
case IO2R1:
- print("IO2 revision 1\n");
+ iprint("IO2 revision 1\n");
break;
case IO2R2:
- print("IO2 revision 2\n");
+ iprint("IO2 revision 2\n");
break;
case IO3R1:
- print("IO3 revision 1\n");
+ iprint("IO3 revision 1\n");
break;
default:
- print("unknown IO board\n");
+ iprint("unknown IO board\n");
break;
}
}
@@ 135,31 131,16 @@ void
ioboardinit(void)
{
long i;
- int intrs;
- /*
- * set up interrupts based on IO board type
- */
ioid = *IOID;
- switch(ioid){
- case IO2R1:
- case IO2R2:
- iolevels = 8;
- iomask = 0xff;
- break;
- case IO3R1:
- iolevels = 11;
- iomask = 0x7fe;
- break;
- }
/*
* reset VME bus (MODEREG is on the IO2)
*/
- MODEREG->resetforce = (1<<1);
+ MODEREG->resetforce = (1<<1) | (1<<0);
for(i=0; i<1000000; i++)
;
- MODEREG->resetforce = 0;
+ MODEREG->resetforce = (1<<0);
MODEREG->masterslave = (SLAVE<<4) | MASTER;
/*
@@ 169,9 150,9 @@ ioboardinit(void)
setvmevec(i, novme);
/*
- * tell IO2 to send all interrupts to CPU 0's SBCC
+ * tell IO2 to sent all interrupts to CPU 0's SBCC
*/
- for(i=0; i<iolevels; i++)
+ for(i=0; i<8; i++)
INTVECREG->i[i].vec = 0<<8;
/*
@@ 191,13 172,13 @@ ioboardinit(void)
* The SBCC 16 bit registers are read/written as ulong, but only
* bits 23-16 and 7-0 are meaningful.
*/
- SBCCREG->fintenable |= iomask; /* turn on all interrupts */
+ SBCCREG->fintenable |= 0xff; /* allow all interrupts on the IO2 */
SBCCREG->idintenable |= 0x800000; /* allow interrupts from the IO2 */
/*
* enable all interrupts on the IO2
*/
- *IO2SETMASK = iomask;
+ *IO2SETMASK = 0xff;
}
void
@@ 606,6 587,11 @@ confinit(void)
conf.npage = conf.npage0;
/*
+ * clear MP bus error caused by sizing memory
+ */
+ i = *SBEADDR;
+
+ /*
* set minimal default values
*/
conf.nmach = 1;
@@ 628,6 614,9 @@ confinit(void)
conf.npte = 4 * conf.npage;
conf.nqueue = 5 * conf.nstream;
conf.nblock = 16 * conf.nstream;
+ conf.nnoifc = 1;
+ conf.nnoconv = 32;
+ conf.nurp = 256;
confread();
M power/mem.h => power/mem.h +1 -1
@@ 109,7 109,7 @@
#define USTKTOP KZERO /* byte just beyond user stack */
#define TSTKTOP (USERADDR+100*BY2PG) /* top of temporary stack */
#define KZERO KSEG0 /* base of kernel address space */
-#define KTZERO (KSEG0+0x20000) /* first address in kernel text */
+#define KTZERO (KZERO+0x20000) /* first address in kernel text */
#define USTACKSIZE (4*1024*1024) /* size of user stack */
/*
* Exception codes
M power/trap.c => power/trap.c +32 -38
@@ 180,14 180,6 @@ trap(Ureg *ur)
}
void
-mpbuserror(void)
-{
- print("io2 mp bus error %d %lux %lux\n", 0,
- *MPBERR0, *MPBERR1);
- *MPBERR0 = 0;
-}
-
-void
intr(ulong cause, ulong pc)
{
int i, pend;
@@ 205,7 197,7 @@ intr(ulong cause, ulong pc)
if(cause & INTR5){
if(!(*MPBERR1 & (1<<8))){
- print("MP bus error %lux %lux\n", *MPBERR0, *MPBERR1); /**/
+ iprint("MP bus error %lux %lux\n", *MPBERR0, *MPBERR1); /**/
*MPBERR0 = 0;
i = *SBEADDR;
}
@@ 235,34 227,33 @@ intr(ulong cause, ulong pc)
/*
* 5a. process lance, scsi
*/
+ loop:
if(pend & 1) {
v = INTVECREG->i[0].vec;
- if(!(v & (1<<12)))
- mpbuserror();
- if(!(v & (1<<2)))
- lanceintr();
- if(!(v & (1<<1)))
- lanceparity();
- if(!(v & (1<<0)))
- print("SCSI interrupt\n");
- }
- if(pend & (1<<10)) {
- v = INTVECREG->i[10].vec;
- if(!(v & (1<<12)))
- mpbuserror();
- lance3intr();
- }
- if(pend & (1<<8)) {
- v = INTVECREG->i[10].vec;
- if(!(v & (1<<12)))
- mpbuserror();
- print("SCSI0 interrupt\n");
- }
- if(pend & (1<<9)) {
- v = INTVECREG->i[10].vec;
- if(!(v & (1<<12)))
- mpbuserror();
- print("SCSI1 interrupt\n");
+ if(!(v & (1<<12))){
+ print("io2 mp bus error %d %lux %lux\n", 0,
+ *MPBERR0, *MPBERR1);
+ *MPBERR0 = 0;
+ }
+ switch(ioid){
+ case IO2R1:
+ case IO2R2:
+ if(!(v & (1<<2)))
+ lanceintr();
+ if(!(v & (1<<1)))
+ lanceparity();
+ if(!(v & (1<<0)))
+ print("SCSI interrupt\n");
+ break;
+ case IO3R1:
+ if(v & (1<<2))
+ lance3intr();
+ if(v & (1<<1))
+ print("SCSI 1 interrupt\n");
+ if(v & (1<<0))
+ print("SCSI 0 interrupt\n");
+ break;
+ }
}
/*
* 5b. process vme
@@ 272,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)))
- mpbuserror();
+ if(!(v & (1<<12))){
+ print("io2 mp bus error %d %lux %lux\n", i,
+ *MPBERR0, *MPBERR1);
+ *MPBERR0 = 0;
+ }
v &= 0xff;
(*vmevec[v])(v);
}
@@ 282,7 276,7 @@ intr(ulong cause, ulong pc)
/*
* 6. re-enable interrupts
*/
- *IO2SETMASK = iomask;
+ *IO2SETMASK = 0xff;
cause &= ~INTR5;
}
if(cause)