M boot/boot.c => boot/boot.c +2 -1
@@ 39,7 39,8 @@ boot(int argc, char *argv[])
open("#c/cons", OREAD);
open("#c/cons", OWRITE);
open("#c/cons", OWRITE);
-/* for(fd = 0; fd < argc; fd++)
+/**/ print("argc=%d\n", argc);
+ for(fd = 0; fd < argc; fd++)
print("%s ", argv[fd]);
print("\n");/**/
M power/trap.c => power/trap.c +2 -1
@@ 161,9 161,10 @@ trap(Ureg *ur)
if(ecode == FPEXC)
print("fp: %s\n", fpexcname(ur, fcr31, buf1));
dumpregs(ur);
+ dumpstack();
if(m->machno == 0)
spllo();
- exit();
+ exit(1);
}
}
M ss/faultsparc.c => ss/faultsparc.c +1 -0
@@ 38,6 38,7 @@ faultsparc(Ureg *ur)
dumpregs(ur);
panic("fault u==0 pc=%lux addr=%lux", ur->pc, addr);
}
+
/* addr &= VAMASK; /**/
badvaddr = addr;
addr &= ~(BY2PG-1);
M ss/io.h => ss/io.h +20 -3
@@ 1,3 1,4 @@
+#define FRAMEBUF 0xFE000000
#define FRAMEBUFID 0xFE000000
#define DISPLAYRAM 0xFE800000
#define EPROM 0xF6000000
@@ 89,7 90,7 @@ typedef struct SCSIdev SCSIdev;
struct SCSIdev {
uchar countlo; /* byte count, low bits */
uchar pad1[3];
- uchar counthi; /* byte count, hi bits */
+ uchar countmi; /* byte count, middle bits */
uchar pad2[3];
uchar fifo; /* data fifo */
uchar pad3[3];
@@ 105,12 106,20 @@ struct SCSIdev {
uchar pad07[3];
uchar fflags; /* fifo flags */
uchar pad08[3];
- uchar config; /* configuration */
+ uchar config; /* RW: configuration */
uchar pad09[3];
uchar Reserved1;
uchar pad0A[3];
uchar Reserved2;
uchar pad0B[3];
+ uchar conf2; /* RW: configuration */
+ uchar pad0C[3];
+ uchar conf3; /* RW: configuration */
+ uchar pad0D[3];
+ uchar partid; /* unique part id */
+ uchar pad0E[3];
+ uchar fbottom; /* RW: fifo bottom */
+ uchar pad0F[3];
};
struct { /* write only... */
uchar destid; /* destination id */
@@ 121,12 130,20 @@ struct SCSIdev {
uchar pad17[3];
uchar syncoffset; /* synchronous xfr offset */
uchar pad18[3];
- uchar XXX;
+ uchar RW0;
uchar pad19[3];
uchar clkconf;
uchar pad1A[3];
uchar test;
uchar pad1B[3];
+ uchar RW1;
+ uchar pad1C[3];
+ uchar RW2;
+ uchar pad1D[3];
+ uchar counthi; /* byte count, hi bits */
+ uchar pad1E[3];
+ uchar RW3;
+ uchar pad1F[3];
};
};
};
M ss/main.c => ss/main.c +60 -34
@@ 140,6 140,7 @@ init0(void)
print("bank 0: %dM 1: %dM\n", bank[0], bank[1]);
print("frame buffer id %lux %s\n", conf.monitor, fbstr);
print("NKLUDGE %d\n", NKLUDGE);
+mapdump();
u->slash = (*devtab[0].attach)(0);
u->dot = clone(u->slash, 0);
@@ 288,44 289,69 @@ confinit(void)
putw4(va, PPN(EEPROM)|PTEPROBEIO);
memmove(idprom, (char*)(va+0x7d8), 32);
if(idprom[0]!=1 || (idprom[1]&0xF0)!=0x50)
- *(ulong*)va = 0;
+ *(ulong*)va = 0; /* not a sparcstation; die! */
putw4(va, INVALIDPTE);
- /* map frame buffer id; we expect it to be in SBUS slot 3 */
- putw4(va, ((FRAMEBUFID>>PGSHIFT)&0xFFFF)|PTEPROBEIO);
- conf.monitor = 0;
- /* if frame buffer not present, we will trap, so prepare to catch it */
- if(setlabel(&catch) == 0){
- conf.monitor = *(ulong*)va;
- switch(conf.monitor){
- case 0xFE010101:
- strcpy(fbstr, "cgthree");
- break;
- case 0xFE010104:
- strcpy(fbstr, "bwtwo");
- break;
- }
- if(fbstr[0] == 0){
- j = *(ulong*)(va+4);
- if(j > BY2PG-8)
- j = BY2PG - 8; /* -8 for safety */
- for(i=0; i<j && fbstr[0]==0; i++)
- switch(*(uchar*)(va+i)){
- case 'b':
- if(strncmp((char*)(va+i), "bwtwo", 5) == 0)
- strcpy(fbstr, "bwtwo");
- break;
- case 'c':
- if(strncmp((char*)(va+i), "cgthree", 7) == 0)
- strcpy(fbstr, "cgthree");
- if(strncmp((char*)(va+i), "cgsix", 5) == 0)
- strcpy(fbstr, "cgsix");
- break;
- }
+ /*
+ * Look for a frame buffer. This isn't done the way the
+ * ROM does it. Instead we ask if we know the machine type
+ * and just use the builtin frame buffer if we can. Otherwise
+ * we just look in slot 3 which is where it usually is.
+ * The ROM scans the slots in a specified order and uses
+ * the first one it finds. Too much bother.
+ *
+ * If we find a frame buffer, we always use it as a console
+ * rather than the attached terminal, if any. This means
+ * if you have a frame buffer you'd better have a builtin
+ * keyboard, too.
+ */
+ switch(idprom[1]){
+ case 0x52: /* IPC */
+ case 0x54: /* SLC */
+ conf.monitor = 1;
+ strcpy(fbstr, "bwtwo");
+ break;
+ case 0x57: /* IPX */
+ conf.monitor = 1;
+ strcpy(fbstr, "cgsix");
+ break;
+ default:
+ /* map frame buffer id in SBUS slot 3 */
+ putw4(va, ((FRAMEBUFID>>PGSHIFT)&0xFFFF)|PTEPROBEIO);
+ conf.monitor = 0;
+ /* if frame buffer not present, we will trap, so prepare to catch it */
+ if(setlabel(&catch) == 0){
+ conf.monitor = *(ulong*)va;
+ switch(conf.monitor){
+ case 0xFE010101:
+ strcpy(fbstr, "cgthree");
+ break;
+ case 0xFE010104:
+ strcpy(fbstr, "bwtwo");
+ break;
+ }
+ if(fbstr[0] == 0){
+ j = *(ulong*)(va+4);
+ if(j > BY2PG-8)
+ j = BY2PG - 8; /* -8 for safety */
+ for(i=0; i<j && fbstr[0]==0; i++)
+ switch(*(uchar*)(va+i)){
+ case 'b':
+ if(strncmp((char*)(va+i), "bwtwo", 5) == 0)
+ strcpy(fbstr, "bwtwo");
+ break;
+ case 'c':
+ if(strncmp((char*)(va+i), "cgthree", 7) == 0)
+ strcpy(fbstr, "cgthree");
+ if(strncmp((char*)(va+i), "cgsix", 5) == 0)
+ strcpy(fbstr, "cgsix");
+ break;
+ }
+ }
}
+ catch.pc = 0;
+ putw4(va, INVALIDPTE);
}
- catch.pc = 0;
- putw4(va, INVALIDPTE);
for(sparam = sysparam; sparam->id; sparam++)
if(sparam->id == idprom[1])
M ss/mmu.c => ss/mmu.c +4 -5
@@ 163,7 163,7 @@ mmuinit(void)
putcxsegm(c, KZERO+i*BY2SEGM, i);
kmapalloc.lowpmeg = i;
- if(PADDR(ktop) & (BY2SEGM-1))
+ if(ktop & (BY2SEGM-1))
kmapalloc.lowpmeg++;
/*
@@ 196,11 196,11 @@ mmuinit(void)
putsegm(ROMSEGM, ROMPMEG);
if(c == 0){
pte = PTEVALID|PTEKERNEL|PTENOCACHE|
- PTEIO|((EPROM>>PGSHIFT)&0xFFFF);
+ PTEIO|PPN(EPROM);
for(i=0; i<PG2ROM; i++)
- putpmeg(IOSEGM0+i*BY2PG, pte+i);
+ putpmeg(ROMSEGM+i*BY2PG, pte+i);
for(; i<PG2SEGM; i++)
- putpmeg(IOSEGM0+i*BY2PG, INVALIDPTE);
+ putpmeg(ROMSEGM+i*BY2PG, INVALIDPTE);
}
/*
* Segments for IO and kmap
@@ 214,7 214,6 @@ mmuinit(void)
}
putcontext(0);
NKLUDGE = ((TOPPMEG-kmapalloc.lowpmeg)/conf.ncontext);
-if(NKLUDGE>11)NKLUDGE=11;
}
void
M ss/screen.c => ss/screen.c +115 -14
@@ 20,7 20,19 @@ struct{
int bwid;
}out;
-void (*kprofp)(ulong);
+static ulong rep(ulong, int);
+void (*kprofp)(ulong);
+
+/* Brooktree 458/451 */
+typedef struct DAC DAC;
+struct DAC
+{
+ uchar pad[16];
+ ulong dacaddr; /* DAC address register */
+ ulong daccolor; /* DAC color palette */
+ ulong daccntrl; /* DAC control register */
+ ulong dacovrl; /* DAC overlay palette */
+}*dac;
GBitmap gscreen;
@@ 30,10 42,11 @@ struct screens
int x;
int y;
int ld;
+ ulong dacaddr;
}screens[] = {
- { "bwtwo", 1152, 900, 0 },
- { "cgsix", 1152, 900, 3 },
- { "cgthree", 1152, 900, 3 },
+ { "bwtwo", 1152, 900, 0, 0x400000 },
+ { "cgsix", 1152, 900, 3, 0x400000 },
+ { "cgthree", 1152, 900, 3, 0x200000 },
0
};
@@ 43,7 56,9 @@ void
screeninit(char *str)
{
struct screens *s;
- ulong n;
+ ulong n, r, g, b;
+ int i;
+ int havecol;
for(s=screens; s->type; s++)
if(strcmp(s->type, str) == 0)
@@ 70,6 85,57 @@ screeninit(char *str)
out.pos.x = MINX;
out.pos.y = 0;
out.bwid = defont0.info[' '].width;
+ dac = (DAC*)kmappa(FRAMEBUF+s->dacaddr, PTENOCACHE|PTEIO);
+ if(gscreen.ldepth == 3){
+ havecol = 0;
+ if(havecol) {
+ /*
+ * For now, just use a fixed colormap, where pixel i is
+ * regarded as 3 bits of red, 3 bits of green, and 2 bits of blue.
+ * Intensities are inverted so that 0 means white, 255 means black.
+ * Exception: pixels 85 and 170 are set to intermediate grey values
+ * so that 2-bit grey scale images will look ok on this screen.
+ */
+ for(i = 0; i<256; i++) {
+ r = ~rep((i>>5) & 7, 3);
+ g = ~rep((i>>2) & 7, 3);
+ b = ~rep(i & 3, 2);
+ setcolor(i, r, g, b);
+ }
+ setcolor(85, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA);
+ setcolor(170, 0x55555555, 0x55555555, 0x55555555);
+ } else {
+dac->dacaddr = 4;
+dac->daccntrl = 0xFF;
+dac->dacaddr = 5;
+dac->daccntrl = 0x00;
+dac->dacaddr = 6;
+dac->daccntrl = 0x40;
+dac->dacaddr = 7;
+dac->daccntrl = 0x00;
+
+ dac->dacaddr = 0;
+ for(i=0; i<252; i+=4) {
+ dac->daccolor = ~rep(i,8);
+ dac->daccolor = ~rep(i,8);
+ dac->daccolor = ~rep(i,8);
+ }
+
+/*
+ for(i = 0; i<256; i++)
+ setcolor(i, ~rep(i,8), ~rep(i,8), ~rep(i,8));
+*/
+ }
+ }
+}
+
+void
+mapdump(void)
+{
+ int i;
+ dac->dacaddr = 0;
+ for(i=0; i<100; i++)
+ print("%lux ", dac->daccolor);
}
void
@@ 128,11 194,12 @@ screenputs(char *s, int n)
/*
* Map is indexed by keyboard char, output is ASCII.
- * Gnotisms: Return sends newline and Line Feed sends carriage return.
+ * Plan 9-isms:
+ * Return sends newline and Line Feed sends carriage return.
* Delete and Backspace both send backspace.
* Num Lock sends delete (rubout).
* Alt Graph is VIEW (scroll).
- * Compose builds Latin-1 characters.
+ * Compose builds Unicode characters.
*/
uchar keymap[128] = {
/* 00 L1 02 L2 04 F1 F2 07 */
@@ 393,24 460,45 @@ screenbits(void)
void
getcolor(ulong p, ulong *pr, ulong *pg, ulong *pb)
{
+ uchar r, g, b;
ulong ans;
/*
* The slc monochrome says 0 is white (max intensity)
*/
- if(p == 0)
- ans = ~0;
- else
- ans = 0;
- *pr = *pg = *pb = ans;
+ if(1 || gscreen.ldepth == 0) {
+ if(p == 0)
+ ans = ~0;
+ else
+ ans = 0;
+ *pr = *pg = *pb = ans;
+ } else {
+ *(uchar *)&dac->dacaddr = p & 0xFF;
+ r = *(uchar *)&dac->daccolor;
+ g = *(uchar *)&dac->daccolor;
+ b = *(uchar *)&dac->daccolor;
+ *pr = (r<<24) | (r<<16) | (r<<8) | r;
+ *pg = (g<<24) | (g<<16) | (g<<8) | g;
+ *pb = (b<<24) | (b<<16) | (b<<8) | b;
+ }
}
int
setcolor(ulong p, ulong r, ulong g, ulong b)
{
- USED(p, r, g, b);
- return 0; /* can't change mono screen colormap */
+ if(1 || gscreen.ldepth == 0)
+ return 0; /* can't change mono screen colormap */
+ else {
+ /* perhaps not reliable unless done while vertical blanking ? */
+ *(uchar *)&dac->dacaddr = p & 0xFF;
+/*
+ *(uchar *)&dac->daccolor = r >> 24;
+ *(uchar *)&dac->daccolor = g >> 24;
+ *(uchar *)&dac->daccolor = b >> 24;
+*/
+ return 1;
+ }
}
int
@@ 432,3 520,16 @@ mouseclock(void) /* called splhi */
{
mouseupdate(1);
}
+
+/* replicate (from top) value in v (n bits) until it fills a ulong */
+static ulong
+rep(ulong v, int n)
+{
+ int o;
+ ulong rv;
+
+ rv = 0;
+ for(o = 32 - n; o >= 0; o -= n)
+ rv |= (v << o);
+ return rv;
+}
M ss/scsi.c => ss/scsi.c +57 -37
@@ 47,13 47,11 @@ scsialloc(ulong n)
return b;
}
-/*
- * NCR 53C90 commands
- */
+enum {
+ ResetIntDis = 0x40, /* config regsiter */
+ Penable = 0x10,
-enum
-{
- Dma = 0x80,
+ Dma = 0x80, /* NCR 53C90 commands */
Nop = 0x00,
Flush = 0x01,
Reset = 0x02,
@@ 73,12 71,29 @@ struct {
SCSIdev *scsi;
} ioaddr;
+static void
+scsibusreset(void)
+{
+ SCSIdev *dev = ioaddr.scsi;
+ int s;
+ uchar intr;
+
+ s = splhi();
+ dev->config |= ResetIntDis;
+ dev->cmd = Busreset;
+ dev->config &= ~ResetIntDis;
+ intr = dev->intr;
+ USED(intr);
+ splx(s);
+}
+
void
resetscsi(void)
{
SCSIdev *dev;
DMAdev *dma;
KMap *k;
+ uchar intr;
k = kmappa(DMA, PTENOCACHE|PTEIO);
ioaddr.dma = (DMAdev*)k->va;
@@ 88,18 103,6 @@ resetscsi(void)
dev = ioaddr.scsi;
dma = ioaddr.dma;
- dev->cmd = Reset;
- dev->cmd = Dma|Nop; /* 2 are necessary */
- dev->cmd = Dma|Nop;
-
- dev->countlo = 0;
- dev->counthi = 0;
- dev->timeout = 146;
- dev->syncperiod = 0;
- dev->syncoffset = 0;
- dev->config = 0x10|(scsiownid&7);
- dev->cmd = Dma|Nop;
-
dma->csr = Dma_Reset;
delay(1);
dma->csr = Int_en;
@@ 107,6 110,37 @@ resetscsi(void)
dmatype = (dma->csr>>28) & 0xF;
+ /*
+ * try to determine chip type
+ dev->conf2 = 0;
+ dev->conf2 = 0x0A;
+ delay(1);
+ if((dev->conf2 & 0x0F) == 0x0A){
+ dev->conf3 = 0;
+ dev->conf3 = 0x05;
+ delay(1);
+ if(dev->conf3 == 0x05)
+ print("scsi type ESP236\n");
+ else
+ print("scsi type ESP100A\n");
+ }
+ else
+ print("scsi type NCR53C90\n");
+ */
+
+ dev->cmd = Reset;
+ dev->cmd = Dma|Nop; /* 2 are necessary for some chips */
+ dev->cmd = Dma|Nop;
+
+ dev->clkconf = 4; /* BUG: 20MHz */
+ dev->timeout = 160; /* BUG: magic */
+ dev->syncperiod = 0;
+ dev->syncoffset = 0;
+ dev->config = Penable|(scsiownid&7);
+
+ intr = dev->intr;
+ USED(intr);
+
putenab(getenab()|ENABDMA); /**/
}
@@ 141,8 175,8 @@ scsiexec(Scsi *p, int rflag)
dma->csr = Dma_Flush|Int_en;
dma->addr = (ulong)p->data.ptr;
- dev->counthi = 0;
dev->countlo = 0;
+ dev->countmi = 0;
dev->cmd = Dma|Nop;
dev->cmd = Flush; /* clear scsi fifo */
@@ 151,8 185,8 @@ scsiexec(Scsi *p, int rflag)
dev->destid = p->target&7;
n = p->data.lim - p->data.ptr;
- dev->counthi = n>>8;
dev->countlo = n;
+ dev->countmi = n>>8;
dev->cmd = Dma|Nop;
dma->csr = Int_en;
@@ 166,20 200,6 @@ scsiexec(Scsi *p, int rflag)
return p->status;
}
-
-void
-scsibusreset(void)
-{
- SCSIdev *dev = ioaddr.scsi;
- int s;
-
- s = splhi();
- dev->cmd = Nop;
- dev->cmd = Busreset;
- dev->cmd = Nop;
- splx(s);
-}
-
static void
scsimoan(char *msg, int status, int intr, int dmastat)
{
@@ 251,7 271,7 @@ scsiintr(void)
case 0x41: /* data transfer, if any, is finished */
p->status = 0x4600;
- p->data.ptr = p->data.lim - ((dev->counthi<<8)|dev->countlo);
+ p->data.ptr = p->data.lim - ((dev->countmi<<8)|dev->countlo);
if((status & 0x07) != 3){
scsimoan("weird phase after xfr",
status, intr, csr);
@@ 303,12 323,12 @@ scsidump(void)
print("\nscsi:\n");
print(" countlo=0x%2.2ux\n", dev->countlo);
- print(" counthi=0x%2.2ux\n", dev->counthi);
+ print(" countmi=0x%2.2ux\n", dev->countmi);
print(" cmd =0x%2.2ux\n", dev->cmd);
print(" status =0x%2.2ux\n", dev->status);
print(" intr =0x%2.2ux\n", dev->intr);
print(" step =0x%2.2ux\n", dev->step);
- print(" fflags =0x%2.2ux\n", dev->countlo);
+ print(" fflags =0x%2.2ux\n", dev->fflags);
print(" config =0x%2.2ux\n", dev->config);
print("dma:\n");
print(" csr =0x%8.8ux\n", dma->csr);