~kris/9p

9hist

ffea75c01c9521c8b21cfcb1c846b757df55e39c — David du Colombier 26 years ago b1beaa1
Plan 9 from Bell Labs 2000-09-05
9 files changed, 350 insertions(+), 33 deletions(-)

M bitsy/clock.c
M bitsy/dat.h
M bitsy/devuart.c
M bitsy/fns.h
M bitsy/l.s
M bitsy/main.c
M bitsy/mmu.c
M ip/ip.c
M pc/vga3dfx.c
M bitsy/clock.c => bitsy/clock.c +3 -1
@@ 49,5 49,7 @@ clockintr(Ureg*, void*)
void
delay(int ms)
{
	USED(ms);
	ms *= 1000;
	while(ms-->0)
		;
}

M bitsy/dat.h => bitsy/dat.h +2 -2
@@ 52,7 52,6 @@ struct Conf
{
	ulong	nmach;		/* processors */
	ulong	nproc;		/* processes */
	ulong	monitor;	/* has monitor? */
	ulong	npage0;		/* total physical pages of memory */
	ulong	npage1;		/* total physical pages of memory */
	ulong	npage;		/* total physical pages of memory */


@@ 63,7 62,8 @@ struct Conf
	ulong	base0;		/* base of bank 0 */
	ulong	base1;		/* base of bank 1 */
	ulong	copymode;	/* 0 is copy on write, 1 is copy on reference */
	ulong	ialloc;		/* max interrupt time allocation in bytes */
	int	monitor;
	ulong	ialloc;		/* bytes available for interrupt time allocation */
	ulong	pipeqsize;	/* size in bytes of pipe queues */
};


M bitsy/devuart.c => bitsy/devuart.c +7 -6
@@ 22,9 22,9 @@ struct Uartregs
	ulong	ctl1;
	ulong	ctl2;
	ulong	ctl3;
	uchar	dummyd[4];
	ulong	dummya;
	ulong	data;
	uchar	dummyf[4];
	ulong	dummyb;
	ulong	status0;
	ulong	status1;
};


@@ 33,6 33,8 @@ struct Uartregs
/* ctl0 bits */
enum
{
	/* status register 1 bits */
	XmitBusy = (1 << 0),
	XmitNotFull = (1 << 2),
};



@@ 491,16 493,15 @@ Dev uartdevtab = {
};

void
putuartstr(char *str)
serialputs(char *str, int n)
{
	Uartregs *ur;

	ur = UART3REGS;
	while(*str){
	while(n-- > 0){
		/* wait for output ready */
		while(ur->status1 & XmitNotFull)
		while((ur->status1 & XmitNotFull) == 0)
			;
		ur->data = *str++;

	}
}

M bitsy/fns.h => bitsy/fns.h +2 -0
@@ 12,6 12,8 @@ void	evenaddr(ulong);
void	idle(void);
#define	idlehands()			/* nothing to do in the runproc */
int	iprint(char*, ...);
void	meminit(void);
void	mmuinit(void);
#define	procrestore(p)
void	procsave(Proc*);
void	procsetup(Proc*);

M bitsy/l.s => bitsy/l.s +13 -6
@@ 12,13 12,20 @@ _main:
	MOVW	$(PsrDirq|PsrDfiq|PsrMsvc), R1
	MOVW	R1, CPSR

	/* turn on caches and write buffer */
	MRC	CpMMU, 0, R1, C(CpControl), C(0x0)
	ORR	$(CpCdcache|CpCwb), R1
	MCR     CpMMU, 0, R1, C(CpControl), C(0x0)
	/* flush TLB's */
	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0x0)
	/* drain prefetch */
	MOVW	R0,R0						
	MOVW	R0,R0
	MOVW	R0,R0
	MOVW	R0,R0

	/* turn off interrupts */
	BL	splhi(SB)
	/* drain write buffer */
	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0x0), 4

	/* disable the MMU */
	MOVW	$0x130, R1
	MCR     CpMMU, 0, R1, C(CpControl), C(0x0)

	MOVW	$(MACHADDR+BY2PG), R13		/* stack */
	SUB	$4, R13				/* link */

M bitsy/main.c => bitsy/main.c +114 -4
@@ 8,13 8,17 @@
#include	"init.h"
#include	"pool.h"

#include	"sa1110.h"

Mach *m;
Conf conf;

void
main(void)
{
	putuartstr("hello ken");
	iprint("bitsy kernel\n");
	confinit();
	mmuinit();
}

/*


@@ 25,6 29,9 @@ exit(int ispanic)
{
	void (*f)();

	USED(ispanic);
	delay(1000);

	f = nil;
	(*f)();
}


@@ 48,15 55,118 @@ procsave(Proc *p)
}

/* place holder */
/*
 *  dummy since rdb is not included 
 */
void
serialputs(char*, int)
rdb(void)
{
}

enum
{
	OneMeg=	1024*1024,
};

/*
 *  dummy since rdb is not included 
 *  probe the last location in a meg of memory, make sure it's not
 *  reflected into something else we've already found.
 */
int
probemem(ulong addr)
{
	ulong *p;
	ulong a;

	addr += OneMeg - sizeof(ulong);
	p = (ulong*)addr;
	*p = addr;
	for(a = conf.base0+OneMeg-sizeof(ulong); a < conf.npage0; a += OneMeg){
		p = (ulong*)a;
		*p = 0;
	}
	for(a = conf.base1+OneMeg-sizeof(ulong); a < conf.npage1; a += OneMeg){
		p = (ulong*)a;
		*p = 0;
	}
	p = (ulong*)addr;
	iprint("%lux @ %lux\n", *p, addr);
	if(*p != addr)
		return -1;
	return 0;
}

/*
 *  we assume that the kernel is at the beginning of one of the
 *  contiguous chunks of memory.
 */
void
rdb(void)
confinit(void)
{
	int i;
	ulong addr;
	ulong ktop;

	/* find first two contiguous sections of available memory */
	addr = PHYSDRAM0;
	conf.base0 = conf.npage0 = addr;
	conf.base1 = conf.npage1 = addr;
	for(i = 0; i < 512; i++){
		if(probemem(addr) == 0)
			break;
		addr += OneMeg;
	}
	for(; i < 512; i++){
		if(probemem(addr) < 0)
			break;
		addr += OneMeg;
		conf.npage0 = addr;
	}

	conf.base1 = conf.npage1 = addr;
	for(; i < 512; i++){
		if(probemem(addr) == 0)
			break;
		addr += OneMeg;
	}
	for(; i < 512; i++){
		if(probemem(addr) < 0)
			break;
		addr += OneMeg;
		conf.npage1 = addr;
	}

	/* take kernel out of allocatable space */
	ktop = PGROUND((ulong)end);
	if(ktop >= conf.base0 && ktop <= conf.npage0)
		conf.base0 = ktop;
	else if(ktop >= conf.base1 && ktop <= conf.npage1)
		conf.base1 = ktop;
	else
		iprint("kernel not in allocatable space\n");
	iprint("%lux-%lux %lux-%lux\n", conf.base0, conf.npage0, conf.base1, conf.npage1);

	/* make npages the right thing */
	conf.npage0 = (conf.npage0 - conf.base0)/BY2PG;
	conf.npage1 = (conf.npage1 - conf.base1)/BY2PG;
	conf.npage = conf.npage0+conf.npage1;

	if(conf.npage > 16*MB/BY2PG){
		conf.upages = (conf.npage*60)/100;
		imagmem->minarena = 4*1024*1024;
	}else
		conf.upages = (conf.npage*40)/100;
	conf.ialloc = ((conf.npage-conf.upages)/2)*BY2PG;

	conf.nmach = 1;

	/* set up other configuration parameters */
	conf.nproc = 100;
	conf.nswap = conf.npage*3;
	conf.nswppo = 4096;
	conf.nimage = 200;

	conf.monitor = 1;

	conf.copymode = 0;		/* copy on write */
}

M bitsy/mmu.c => bitsy/mmu.c +5 -0
@@ 8,6 8,11 @@
#include	"../port/error.h"

void
mmuinit(void)
{
}

void
putmmu(ulong va, ulong pa, Page*)
{
	USED(va, pa);

M ip/ip.c => ip/ip.c +1 -1
@@ 15,7 15,7 @@ enum
{
	IPHDR		= 20,		/* sizeof(Iphdr) */
	IP_VER		= 0x40,		/* Using IP version 4 */
	IP_HLEN		= 0x05,		/* Header length in characters */
	IP_HLEN		= 0x05,		/* Header length in words */
	IP_DF		= 0x4000,	/* Don't fragment */
	IP_MF		= 0x2000,	/* More fragments */
	IP_MAX		= (32*1024),	/* Maximum Internet packet size */

M pc/vga3dfx.c => pc/vga3dfx.c +203 -13
@@ 12,12 12,27 @@
#include <cursor.h>
#include "screen.h"

typedef struct {
	int	vidProcCfg;
	int	hwCurPatAddr;
	int	hwCurLoc;
	int	hwCurC0;
	int	hwCurC1;
} Cursor3dfx;

enum {
	dramInit0	= 0x18,
	dramInit1	= 0x1C,

	hwCur		= 0x5C,
};

static ulong
tdfxlinear(VGAscr* scr, int* size, int* align)
{
	ulong aperture, oaperture;
	int oapsize, wasupamem;
	Pcidev *p;
	int oapsize, wasupamem;
	ulong aperture, oaperture;

	oaperture = scr->aperture;
	oapsize = scr->apsize;


@@ 26,7 41,7 @@ tdfxlinear(VGAscr* scr, int* size, int* align)
	aperture = 0;
	if(p = pcimatch(nil, 0x121A, 0)){
		switch(p->did){
		case 0x0005:		/* Voodoo 3 3000 */
		case 0x0005:		/* Avenger (a.k.a. Voodoo3) */
			aperture = p->mem[1].bar & ~0x0F;
			*size = p->mem[1].size;
			break;


@@ 57,22 72,197 @@ tdfxlinear(VGAscr* scr, int* size, int* align)
	return aperture;
}

static void
tdfxenable(VGAscr* scr)
{
	Pcidev *p;
	Physseg seg;
	ulong aperture;
	int align, i, *mmio, size;

	/*
	 * Only once, can't be disabled for now.
	 * scr->io holds the physical address of
	 * the MMIO registers.
	 */
	if(scr->io)
		return;
	if(p = pcimatch(nil, 0x121A, 0)){
		switch(p->did){
		case 0x0005:		/* Avenger (a.k.a. Voodoo3) */
			break;
		default:
			return;
		}
	}
	else
		return;
	scr->io = upamalloc(p->mem[0].bar & ~0x0F, p->mem[0].size, 0);
	if(scr->io == 0)
		return;

	memset(&seg, 0, sizeof(seg));
	seg.attr = SG_PHYSICAL;
	seg.name = smalloc(NAMELEN);
	snprint(seg.name, NAMELEN, "3dfxmmio");
	seg.pa = scr->io;
	seg.size = p->mem[0].size;
	addphysseg(&seg);

	size = p->mem[1].size;
	align = 0;
	aperture = tdfxlinear(scr, &size, &align);
	if(aperture) {
		scr->aperture = aperture;
		scr->apsize = size;
		memset(&seg, 0, sizeof(seg));
		seg.attr = SG_PHYSICAL;
		seg.name = smalloc(NAMELEN);
		snprint(seg.name, NAMELEN, "3dfxscreen");
		seg.pa = aperture;
		seg.size = size;
		addphysseg(&seg);
	}

	/*
	 * Find a place for the cursor data in display memory.
	 * If SDRAM then there's 16MB memory else it's SGRAM
	 * and can count it based on the power-on straps -
	 * chip size can be 8Mb or 16Mb, and there can be 4 or
	 * 8 of them.
	 * Use the last 1KB of the framebuffer.
	 */
	mmio = KADDR(scr->io + dramInit0);
	if(*(mmio+1) & 0x40000000)
		i = 16*1024*1024;
	else{
		if(*mmio & 0x08000000)
			i = 16*1024*1024/8;
		else
			i = 8*1024*1024/8;
		if(*mmio & 0x04000000)
			i *= 8;
		else
			i *= 4;
	}
	scr->storage = i - 1024;
}

static void
tdfxcurdisable(VGAscr* scr)
{
	Cursor3dfx *cursor3dfx;

	if(scr->io == 0)
		return;
	cursor3dfx = KADDR(scr->io+hwCur);
	cursor3dfx->vidProcCfg &= ~0x08000000;
}

static void
tdfxcurload(VGAscr* scr, Cursor* curs)
{
	int y;
	uchar *p;
	Cursor3dfx *cursor3dfx;

	if(scr->io == 0)
		return;
	cursor3dfx = KADDR(scr->io+hwCur);

	/*
	 * Disable the cursor then load the new image in
	 * the top-left of the 64x64 array.
	 * The cursor data is stored in memory as 128-bit
	 * words consisting of plane 0 in the least significant 64-bits
	 * and plane 1 in the most significant.
	 * The X11 cursor truth table is:
	 *	p0 p1	colour
	 *	 0  0	transparent
	 *	 0  1	transparent
	 *	 1  0	hwCurC0
	 *	 1  1	hwCurC1
	 * Unused portions of the image have been initialised to be
	 * transparent.
	 */
	cursor3dfx->vidProcCfg &= ~0x08000000;
	p = KADDR(scr->aperture + scr->storage);
	for(y = 0; y < 16; y++){
		*p++ = curs->clr[2*y]|curs->set[2*y];
		*p++ = curs->clr[2*y+1]|curs->set[2*y+1];
		p += 6;
		*p++ = curs->set[2*y];
		*p++ = curs->set[2*y+1];
		p += 6;
	}

	/*
	 * Save the cursor hotpoint and enable the cursor.
	 * The 0,0 cursor point is bottom-right.
	 */
	scr->offset.x = 63+curs->offset.x;
	scr->offset.y = 63+curs->offset.y;
	cursor3dfx->vidProcCfg |= 0x08000000;
}

static int
tdfxcurmove(VGAscr* scr, Point p)
{
	Cursor3dfx *cursor3dfx;

	if(scr->io == 0)
		return 1;
	cursor3dfx = KADDR(scr->io+hwCur);

	cursor3dfx->hwCurLoc = ((p.y+scr->offset.y)<<16)|(p.x+scr->offset.x);

	return 0;
}

static void
tdfxcurenable(VGAscr* scr)
{
	Cursor3dfx *cursor3dfx;

	tdfxenable(scr);
	if(scr->io == 0)
		return;
	cursor3dfx = KADDR(scr->io+hwCur);

	/*
	 * Cursor colours.
	 */
	cursor3dfx->hwCurC0 = 0xFFFFFFFF;
	cursor3dfx->hwCurC1 = 0x00000000;

	/*
	 * Initialise the 64x64 cursor to be transparent (X11 mode).
	 */
	cursor3dfx->hwCurPatAddr = scr->storage;
	memset(KADDR(scr->aperture + scr->storage), 0, 64*16);

	/*
	 * Load, locate and enable the 64x64 cursor in X11 mode.
	 */
	tdfxcurload(scr, &arrow);
	tdfxcurmove(scr, ZP);
	cursor3dfx->vidProcCfg |= 0x08000002;
}

VGAdev vga3dfxdev = {
	"3dfx",

	nil,				/* enable */
	nil,				/* disable */
	nil,				/* page */
	tdfxlinear,			/* linear */
	nil,				/* drawinit */
	nil,				/* fill */
	tdfxenable,
	nil,
	nil,
	tdfxlinear,
};

VGAcur vga3dfxcur = {
	"3dfxhwgc",

	nil,				/* enable */
	nil,				/* disable */
	nil,				/* load */
	nil,				/* move */
	tdfxcurenable,
	tdfxcurdisable,
	tdfxcurload,
	tdfxcurmove,
};