~kris/9p

9hist

4f839b7c6128baf19bfd353e19f6c36085cd67dc — David du Colombier 27 years ago d454670
Plan 9 from Bell Labs 1999-05-17
6 files changed, 77 insertions(+), 83 deletions(-)

M pc/devlml.c
M pc/devlml.h
M pc/trap.c
M port/portdat.h
M port/print.c
M port/tod.c
M pc/devlml.c => pc/devlml.c +37 -29
@@ 11,10 11,16 @@
#define DBGREGS 0x1
#define DBGREAD 0x2
#define DBGWRIT 0x4
int debug = DBGREAD|DBGWRIT;
int debug = DBGREAD|DBGWRIT|DBGREGS;

// Lml 22 driver

struct {
	ulong pci;
	ulong dma;
	ulong codedata;
} lmlmap;

enum{
	Qdir,
	Q819,


@@ 29,8 35,8 @@ static Dirtab lmldir[]={
//	 name,		 qid,		size,		mode
	"lml819",	{Q819},		0,		0644,
	"lml856",	{Q856},		0,		0644,
	"lmlreg",	{Qreg},		0,		0644,
	"lmlmap",	{Qmap},		0,		0444,
	"lmlreg",	{Qreg},		0x400,		0644,
	"lmlmap",	{Qmap},		sizeof lmlmap,	0444,
	"jvideo",	{Qjvideo},	0,		0666,
	"jframe",	{Qjframe},	0,		0666,
};


@@ 48,12 54,6 @@ int		hdrPos;
int		nopens;
uchar		q856[3];

struct {
	ulong pci;
	ulong dma;
	ulong codedata;
} lmlmap;

static FrameHeader frameHeader = {
	MRK_SOI, MRK_APP3, (sizeof(FrameHeader)-4) << 8,
	{ 'L', 'M', 'L', '\0'},


@@ 63,24 63,24 @@ static FrameHeader frameHeader = {
ulong
writel(ulong v, ulong a) {
	if (debug&DBGREGS)
		pprint("writing %.8lux  to  %.8lux (%.4lux)\n",
			v, a, (ulong)a-pciBaseAddr);
		pprint("%.8lux (%.8lux) <-- %.8lux\n",
			a, (ulong)a-pciBaseAddr, v);
	return *(ulong *)a = v;
}

ushort
writew(ushort v, ulong a) {
	if (debug&DBGREGS)
		pprint("writing     %.4ux  to  %.8lux (%.4lux)\n",
			v, a, (ulong)a-pciBaseAddr);
		pprint("%.8lux (%.8lux) <--     %.4ux\n",
			a, (ulong)a-pciBaseAddr, v);
	return *(ushort *)a = v;
}

uchar
writeb(uchar v, ulong a) {
	if (debug&DBGREGS)
		pprint("writing       %.2ux  to  %.8lux (%.4lux)\n",
			v, a, (ulong)a-pciBaseAddr);
		pprint("%.8lux (%.8lux) <--       %.2ux\n",
			a, (ulong)a-pciBaseAddr, v);
	return *(uchar *)a = v;
}



@@ 90,8 90,8 @@ readl(ulong a) {

	v = *(ulong*)a;
	if (debug&DBGREGS)
		pprint("reading %.8lux from %.8lux (%.4lux)\n",
			v, a, (ulong)a-pciBaseAddr);
		pprint("%.8lux (%.8lux) --> %.8lux\n",
			a, (ulong)a-pciBaseAddr, v);
	return v;
}



@@ 101,8 101,8 @@ readw(ulong a) {

	v = *(ushort*)a;
	if (debug&DBGREGS)
		pprint("reading     %.4ux from %.8lux (%.4lux)\n",
			v, a, (ulong)a-pciBaseAddr);
		pprint("%.8lux (%.8lux) -->     %.4ux\n",
			a, (ulong)a-pciBaseAddr, v);
	return v;
}



@@ 112,8 112,8 @@ readb(ulong a) {

	v = *(uchar*)a;
	if (debug&DBGREGS)
		pprint("reading       %.2ux from %.8lux (%.4lux)\n",
			v, a, (ulong)a-pciBaseAddr);
		pprint("%.8lux (%.8lux) -->       %.2ux\n",
			a, (ulong)a-pciBaseAddr, v);
	return v;
}



@@ 330,7 330,7 @@ static int
prepareBuffer(CodeData * this, int bufferNo) {
  if(bufferNo >= 0 && bufferNo < NBUF && (this->statCom[bufferNo] & STAT_BIT)) {
    this->statCom[bufferNo] = this->statComInitial[bufferNo];
    return this->fragmDescr[bufferNo].fragmLength;
    return this->fragdesc[bufferNo].leng;
  } else
    return -1;
}


@@ 354,7 354,7 @@ static int
getBuffer(CodeData *this, int bufferNo, void** bufferPtr, int* frameNo) {
	int codeLength;
	if(this->statCom[bufferNo] & STAT_BIT) {
		*bufferPtr = (void*)this->fragmDescr[bufferNo].fragmAddress;
		*bufferPtr = (void*)this->fragdesc[bufferNo].addr;
		*frameNo = this->statCom[bufferNo] >> 24;
		codeLength=((this->statCom[bufferNo] & 0x00FFFFFF) >> 1);
		return codeLength;


@@ 560,12 560,11 @@ lmlreset(void)
	strncpy(codeData->idString, MJPG_VERSION, strlen(MJPG_VERSION));

	for(i = 0; i < NBUF; i++) {
		codeData->statCom[i] = PADDR(&(codeData->fragmDescr[i]));
		codeData->statCom[i] = PADDR(&(codeData->fragdesc[i]));
		codeData->statComInitial[i] = codeData->statCom[i];
		codeData->fragmDescr[i].fragmAddress =
			(Fragment *)PADDR(&(codeData->frag[i]));
		codeData->fragdesc[i].addr = PADDR(&(codeData->frag[i]));
		// Length is in double words, in position 1..20
		codeData->fragmDescr[i].fragmLength = (FRAGSIZE >> 1) | FRAGM_FINAL_B;
		codeData->fragdesc[i].leng = (FRAGSIZE >> 1) | FRAGM_FINAL_B;
	}

	print("initializing LML33 board...");


@@ 620,6 619,8 @@ lmlstat(Chan *c, char *dp)
static Chan*
lmlopen(Chan *c, int omode)
{
	int i;

	c->aux = 0;
	switch(c->qid.path){
	case Q819:


@@ 639,7 640,14 @@ lmlopen(Chan *c, int omode)
		frameNo = 0;
		bufferPrepared = 0;
		hdrPos = -1;

		for (i = 0; i < 4; i++) {
			codeData->statCom[i] = codeData->statComInitial[i];
			// Also memset the buffer with some fill value
			memset(&(codeData->frag[i]),0x55,sizeof codeData->frag[i]);
		}
		// allow one open total for these two
		intrenable(pcidev->intl, lmlintr, nil, pcidev->tbdf);
		break;
	}
	return devopen(c, omode, lmldir, nelem(lmldir), devgen);


@@ 707,7 715,7 @@ lmlread(Chan *c, void *va, long n, vlong voff) {
		if (off < 0)
			return 0;
		for (i = 0; i < n; i++) {
			if (off + i > sizeof lmlmap)
			if (off + i >= sizeof lmlmap)
				break;
			buf[i] = ((uchar *)&lmlmap)[off + i];
		}


@@ 749,7 757,7 @@ lmlwrite(Chan *c, void *va, long n, vlong voff) {
		error(Eperm);

	case Q819:
		if (off < 0 || off + n > 0x20)
		if (off < 0 || off + n >= 0x20)
			return 0;
		for (i = n; i > 0; i--)
			if (i2c_wr8(BT819Addr, off++, *buf++) == 0)

M pc/devlml.h => pc/devlml.h +7 -29
@@ 50,28 50,6 @@ typedef struct {
	int	zr060addr;	// Which guest bus address for the ZR36060
} Device;

// An entry in the fragment table
typedef struct {
	ulong	address;	// bus address of page
	int	length;		// length of page
} RingPage;

// The structure that we will use to tell the '57 about the buffers
// The sizeof(RingData) should not exceed page size
typedef struct {
	void		*buffer[4];
	ulong		i_stat_com[4];
	RingPage	ring_pages[4][PAGES];
} RingData;

typedef struct {
	int	expect;		// the buffer the int routine expects next
	int	which;		// which ring buffer the read or write uses
	int	filled;		// the current number of filled buffers
	int	pages;		// the number of complete pages
	int	remainder;	// the number of bytes in incomplete page
} RingPtr;

// The remainder of the #defs are constants which should not need changing.

// The PCI vendor and device ids of the zoran chipset on the dc30


@@ 103,16 81,16 @@ struct Fragment {
};

struct FragmentTable {	// Don't modify this struct, used by h/w
	Fragment *		fragmAddress;			// Physical address
	ulong			fragmLength;
	ulong		addr;		// Physical address
	ulong		leng;
};

struct CodeData {	// Don't modify this struct, used by h/w
	char			idString[16];
	ulong			statCom[4];				// Physical address
	ulong			statComInitial[4];		// Physical address
	FragmentTable	fragmDescr[4];
	Fragment		frag[4];
	char		idString[16];
	ulong		statCom[4];		// Physical address
	ulong		statComInitial[4];	// Physical address
	FragmentTable	fragdesc[4];
	Fragment	frag[4];
};

static void *		pciPhysBaseAddr;

M pc/trap.c => pc/trap.c +6 -1
@@ 681,8 681,13 @@ linkproc(void)
void
kprocchild(Proc* p, void (*func)(void*), void* arg)
{
	/*
	 * gotolabel() needs a word on the stack in
	 * which to place the return PC used to jump
	 * to linkproc().
	 */
	p->sched.pc = (ulong)linkproc;
	p->sched.sp = (ulong)p->kstack+KSTACK;
	p->sched.sp = (ulong)p->kstack+KSTACK-BY2WD;

	p->kpfun = func;
	p->kparg = arg;

M port/portdat.h => port/portdat.h +1 -0
@@ 784,3 784,4 @@ extern int nsyscall;
#pragma	varargck	type	"V"	uchar*
#pragma	varargck	type	"E"	uchar*
#pragma	varargck	type	"M"	uchar*
#pragma	varargck	type	"p"	void*

M port/print.c => port/print.c +10 -0
@@ 18,6 18,7 @@ enum
	FSHORT	= 1<<4,
	FUNSIGN	= 1<<5,
	FVLONG	= 1<<6,
	FPOINTER	= 1<<7,
};

int	printcol;


@@ 64,6 65,7 @@ initfmt(void)
	fmtindex['o'] = cc;
	fmtindex['x'] = cc;
	fmtindex['X'] = cc;
	fmtindex['p'] = cc;
	cc++;

	fmtconv[cc] = cconv;


@@ 242,6 244,10 @@ numbconv(va_list *arg, Fconv *fp)
	case 'x':
		b = 16;
		break;
	case 'p':
		fp->f3 |= FPOINTER|FUNSIGN;
		b = 16;
		break;
	}

	f = 0;


@@ 272,6 278,10 @@ numbconv(va_list *arg, Fconv *fp)
		v = (ushort)h;
		break;

	case FUNSIGN|FPOINTER:
		v = (ulong)va_arg(*arg, void*);
		break;

	default:
		v = va_arg(*arg, int);
		break;

M port/tod.c => port/tod.c +16 -24
@@ 29,9 29,7 @@

struct {
	Lock;
	int	s1;		// time = ((ticks>>s2)*multiplier)>>(s1-s2)
	vlong	multiplier;	// ...
	int	s2;		// ...
	vlong	multiplier;	// t = off + (multiplier*ticks)>>31
	vlong	hz;		// frequency of fast clock
	vlong	last;		// last reading of fast clock
	vlong	off;		// offset from epoch to last


@@ 55,19 53,6 @@ todinit(void)
void
todsetfreq(vlong f)
{
	// the shift is an attempt to maintain precision
	// during the caculations.  the number of bits in
	// the multiplier should be log(TODFREQ) + 31 - log(f).
	//
	//	Freq		bits
	//	167 MHZ		34
	//	267 MHZ		33
	//	500 MHZ		32
	//
	// in all cases, we need to call todget() at least once
	// a second to keep the subsequent calculations from
	// overflowing.

	ilock(&tod);
	tod.hz = f;
	tod.multiplier = (TODFREQ<<31)/f;


@@ 81,11 66,12 @@ void
todset(vlong t, vlong delta, int n)
{
	ilock(&tod);
	tod.sstart = tod.send = 0;
	if(t >= 0){
		tod.off = t;
		tod.last = fastticks(nil);
		tod.lasttime = 0;
		tod.delta = 0;
		tod.sstart = tod.send;
	} else {
		if(n <= 0)
			n = 1;


@@ 121,7 107,7 @@ todget(void)
	diff = ticks - tod.last;

	// add in correction
	if(tod.sstart < tod.send){
	if(tod.sstart != tod.send){
		t = MACHP(0)->ticks;
		if(t >= tod.send)
			t = tod.send;


@@ 129,13 115,15 @@ todget(void)
		tod.sstart = t;
	}

	// convert to epoch, make sure calculation is unsigned
	x = (((uvlong)diff) * ((uvlong)tod.multiplier)) >> 31;
	// convert to epoch
	x = (diff * tod.multiplier) >> 31;
	x += tod.off;

	// protect against overflows (gettod is called at least once a second)
	tod.last = ticks;
	tod.off = x;
	// protect against overflows
	if(diff > tod.hz){
		tod.last = ticks;
		tod.off = x;
	}

	// time can't go backwards
	if(x < tod.lasttime)


@@ 152,9 140,13 @@ todget(void)
void
todfix(void)
{
	static ulong last;

	// once a second, make sure we don't overflow
	if((MACHP(0)->ticks % HZ) == 0)
	if(MACHP(0)->ticks - last >= HZ){
		last = MACHP(0)->ticks;
		todget();
	}
}

long