~kris/9p

9hist

7ab5a6b37eebebd02eb861730704a30fa6267ad2 — David du Colombier 34 years ago 944a30a
Plan 9 from Bell Labs 1992-08-13
8 files changed, 261 insertions(+), 95 deletions(-)

M boot/boot.c
M power/trap.c
M ss/faultsparc.c
M ss/io.h
M ss/main.c
M ss/mmu.c
M ss/screen.c
M ss/scsi.c
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);