~kris/9p

9hist

d328ec63b144226d80a24dbbd985f9e16469b3b1 — David du Colombier 27 years ago 723ef48
Plan 9 from Bell Labs 1999-06-10
6 files changed, 259 insertions(+), 119 deletions(-)

M boot/boot.h
A boot/sac.c
M mpc/devsac.c
M mpc/unsac.c
M pc/devlml.c
M pc/devlml.h
M boot/boot.h => boot/boot.h +3 -0
@@ 59,3 59,6 @@ extern int	connecttcp(void);
extern void	configlocal(Method*);
extern int	authlocal(void);
extern int	connectlocal(void);
extern void	configsac(Method*);
extern int	authsac(void);
extern int	connectsac(void);

A boot/sac.c => boot/sac.c +63 -0
@@ 0,0 1,63 @@
#include <u.h>
#include <libc.h>
#include <../boot/boot.h>

void configip(char* dev);

// HACK - take over from boot since files system is not
// available on a pipe

void
configsac(Method *mp)
{
	int fd;
	char cmd[64];

	USED(mp);

print("configsac\n");
	/*
	 *  create the name space, mount the root fs
	 */
	if(bind("/", "/", MREPL) < 0)
		fatal("bind /");
	if(bind("#C", "/", MAFTER) < 0)
		fatal("bind /");

	fd = open("#c/sysname", OWRITE);
	if(fd < 0)
		fatal("open sysname");
	write(fd, "brick", 5);
	close(fd);

	fd = open("#c/hostowner", OWRITE);
	if(fd < 0)
		fatal("open sysname");
	write(fd, "brick", 5);
	close(fd);

	bargc = parsefields("-n 135.104.9.69 255.255.255.0 135.104.9.1 "
						"135.104.9.69 135.104.9.69", bargv, Nbarg-1, " ");
	configip("ether0");

	// fixed sysname - enables correct cpurc and namespace files
	// to be used

	sprint(cmd, "/%s/init", cputype);
	execl(cmd, "init", "-c", 0);
	fatal(cmd);
}

int
authsac(void)
{
	// does not get here
	return -1;
}

int
connectsac(void)
{
	// does not get here
	return -1;
}

M mpc/devsac.c => mpc/devsac.c +4 -12
@@ 98,7 98,6 @@ print("devsac: bad magic\n");
		return;
	}
	blocksize = getl(hdr->blocksize);
print("blocksize = %d\n", blocksize);
	root.SacDir = *(SacDir*)(data + sizeof(SacHeader));
}



@@ 137,7 136,8 @@ sacwalk(Chan *c, char *name)
	Sac *sac;
	Path *op;

print("sacwalk\n");
//print("walk %s\n", name);

	isdir(c);
	if(name[0]=='.' && name[1]==0)
		return 1;


@@ 150,7 150,6 @@ print("sacwalk\n");
	c->aux = sac;
	c->qid = (Qid){getl(sac->qid), 0};
	op = c->path;
print("op=%ux name = %s\n", op, name);
	c->path = ptenter(&syspt, op, name);
	decref(op);
	return 1;


@@ 199,8 198,8 @@ sacread(Chan *c, void *a, long n, vlong off)
			error("i/o error");
		return sacdirread(c, buf, off, cnt);
	}
print("data read\n");
	sac = c->aux;
//print("sacread: %s %llx %d\n", sac->name, off, n);
	length = getv(sac->length);
	if(off >= length)
		return 0;


@@ 221,6 220,7 @@ print("data read\n");
		memmove(buf, buf2+j, nn);
		cnt -= nn;
		off += nn;
		buf += nn;
	}
	free(buf2);
	return n;


@@ 237,7 237,6 @@ static void
sacclose(Chan* c)
{
	Sac *sac = c->aux;
print("close %ux\n", sac);
	c->aux = nil;
	sacfree(sac);
}


@@ 255,7 254,6 @@ saccpy(Sac *s)
	Sac *ss;
	
	ss = malloc(sizeof(Sac));
print("saccpy = %ux\n", ss);
	*ss = *s;
	if(ss->path)
		incref(ss->path);


@@ 324,11 322,9 @@ loadblock(void *buf, uchar *offset, int blocksize)
		if(n < 0)
			n = -n;
		n -= block;
print("blocksize = %d, block = %lld n = %lld\n", blocksize, block, n);
		if(unsac(buf, data+block, blocksize, n)<0)
			panic("unsac failed!");
	} else {
print("memmove: blocksize = %d\n", blocksize);
		memmove(buf, data+block, blocksize);
	}
}


@@ 349,14 345,12 @@ sacparent(Sac *s)
	}
	p = p->up;

print("sacparent = %lld %d\n", p->blocks, p->entry);
	blocks = data + p->blocks;
	per = blocksize/sizeof(SacDir);
	i = p->entry/per;
	buf = malloc(per*sizeof(SacDir));
	loadblock(buf, blocks + i*8, per*sizeof(SacDir));
	s->SacDir = buf[p->entry-i*per];
print("sacparent = %s\n", s->name);
	free(buf);
	incref(p);
	sacpathfree(s->path);


@@ 372,7 366,6 @@ sacdirread(Chan *c, char *p, long off, long cnt)
	int iblock, per, i, j, ndir;
	Sac *s;

print("sacdirread %d %d\n", off, cnt);
	s = c->aux;
	blocks = data + getv(s->blocks);
	per = blocksize/sizeof(SacDir);


@@ 428,7 421,6 @@ saclookup(Sac *s, char *name)
		sd = buf+i-j;
		k = strcmp(name, sd->name);
		if(k == 0) {
print("walk %s %lld %d\n", name, getv(s->blocks), i);
		s->path = sacpathalloc(s->path, getv(s->blocks), i);
			s->SacDir = *sd;
			free(buf);

M mpc/unsac.c => mpc/unsac.c +62 -59
@@ 17,7 17,7 @@ enum

	MaxLeaf		= MaxLit+LitBase,
	MaxHuffBits	= 15,			/* max bits in a huffman code */
	MaxSelHuffBits	= 15,			/* max bits for a table selector huffman code */
	MaxFlatbits	= 4,			/* max bits decoded in flat table */

	Nhuffblock	= 16*1024,		/* symbols encoded before output */
	Nhuffslop	= 64,			/* slop for stuffing zeros, etc. */


@@ 28,7 28,7 @@ struct Huff
	int	minbits;
	int	maxbits;
	int	flatbits;
	ulong	flat[1<<8];
	ulong	flat[1<<MaxFlatbits];
	ulong	maxcode[MaxHuffBits+1];
	ulong	last[MaxHuffBits+1];
	ulong	decode[MaxLeaf];


@@ 47,10 47,9 @@ struct Decode{
	uchar	*smax;				/* limit */
};

static	void	fatal(Decode *dec, char*, ...);
static	void	fatal(Decode *dec, char*);

static	int	hdec(Decode*);
static	void	hflush(Decode*);
static	void	hbflush(Decode*);
static	ulong	bitget(Decode*, int);
static	int	mtf(uchar*, int);


@@ 58,46 57,52 @@ static	int	mtf(uchar*, int);
int
unsac(uchar *dst, uchar *src, int n, int nsrc)
{
	Decode dec;
	uchar *buf, front[256];
	ulong *suflink, sums[256];
	Decode *dec;
	uchar *buf, *front;
	ulong *suflink, *sums;
	ulong sum;
	int i, m, I, j, c;

	dec = malloc(sizeof *dec);
	buf = malloc(n+2);
	suflink = malloc((n+2) * sizeof *suflink);
	front = malloc(256 * sizeof *front);
	sums = malloc(256 * sizeof *sums);

	if(waserror()) {
	if(waserror()){
		free(dec);
		free(buf);
		free(suflink);
		free(front);
		free(sums);
		nexterror();
	}

	dec.src = src;
	dec.smax = src + nsrc;
	dec->src = src;
	dec->smax = src + nsrc;

	dec.nbits = 0;
	dec.bits = 0;
	dec.nzero = 0;
	dec->nbits = 0;
	dec->bits = 0;
	dec->nzero = 0;
	for(i = 0; i < 256; i++)
		front[i] = i;

	n++;
	I = bitget(&dec, 16);
	I = bitget(dec, 16);
	if(I >= n)
		fatal(&dec, "corrupted input file: n=%d I=%d", n, I);
		fatal(dec, "corrupted input");

	/*
	 * decode the character usage map
	 */
	for(i = 0; i < 256; i++)
		sums[i] = 0;
	c = bitget(&dec, 1);
	c = bitget(dec, 1);
	for(i = 0; i < 256; ){
		m = bitget(&dec, 8) + 1;
		m = bitget(dec, 8) + 1;
		while(m--){
			if(i >= 256)
				fatal(&dec, "bad format encoding char map %d", m);
				fatal(dec, "corrupted char map");
			front[i++] = c;
		}
		c = c ^ 1;


@@ 110,17 115,17 @@ unsac(uchar *dst, uchar *src, int n, int nsrc)
	for(i = 0; i < 256; i++)
		if(front[i])
			front[c++] = i;
	dec.maxblocksym = c + LitBase;
	dec->maxblocksym = c + LitBase;

	/*
	 * huffman decoding, move to front decoding,
	 * along with character counting
	 */
	hbflush(&dec);
	hbflush(dec);
	for(i = 0; i < n; i++){
		if(i == I)
			continue;
		m = hdec(&dec);
		m = hdec(dec);

		/*
		 * move to front


@@ 171,8 176,11 @@ unsac(uchar *dst, uchar *src, int n, int nsrc)
	}

	poperror();
	free(dec);
	free(buf);
	free(suflink);
	free(front);
	free(sums);
	return n;
}



@@ 200,7 208,7 @@ fillbits(Decode *dec)

	while(dec->nbits < 24){
		if(dec->src >= dec->smax)
			fatal(dec, "premature eof 2: nbits %d", dec->nbits);
			fatal(dec, "premature eof 2");
		c = *dec->src++;
		dec->bits <<= 8;
		dec->bits |= c;


@@ 221,7 229,7 @@ hdecsym(Decode *dec, Huff *h)
	for(b = h->flatbits; (c = dec->bits >> (dec->nbits - b)) > h->maxcode[b]; b++)
		;
	if(b > h->maxbits)
		fatal(dec, "too many bits consumed: b=%d minbits=%d maxbits=%d", b, h->minbits, h->maxbits);
		fatal(dec, "too many bits consumed");
	dec->nbits -= b;
	c = h->decode[h->last[b] - c];



@@ 266,15 274,7 @@ hdec(Decode *dec)
}

static void
hbflush(Decode *dec)
{
	dec->base = 1;
	dec->ndec = 0;
	hflush(dec);
}

static void
hufftab(Decode *dec, Huff *h, ulong *hb, ulong *bitcount, int maxleaf, int maxbits, int flatbits)
hufftab(Decode *dec, Huff *h, uchar *hb, ulong *bitcount, int maxleaf, int maxbits, int flatbits)
{
	ulong c, code, nc[MaxHuffBits+1];
	int i, b, ec;


@@ 295,7 295,7 @@ hufftab(Decode *dec, Huff *h, ulong *hb, ulong *bitcount, int maxleaf, int maxbi
		h->last[b] += code - 1;
	}
	if(code != (1 << maxbits))
		fatal(dec, "huffman table not full %d %d", code, 1<<maxbits);
		fatal(dec, "huffman table not full");
	h->maxbits = b;
	if(flatbits > b)
		flatbits = b;


@@ 311,31 311,37 @@ hufftab(Decode *dec, Huff *h, ulong *hb, ulong *bitcount, int maxleaf, int maxbi
			continue;
		c = nc[b]++;
		if(b <= flatbits){
if(c > (1<<(b+1)))fatal(dec, "xx1");
			code = (i << 8) | b;
			ec = (c + 1) << (flatbits - b);
			if(ec > (1<<flatbits))
				fatal(dec, "too big: ec=%d c=%d %d b=%d nc=%d\n", ec, c, c & ((1<<b)-1), b, nc[b]);
				fatal(dec, "flat code too big");
			for(c <<= (flatbits - b); c < ec; c++)
				h->flat[c] = code;
		}else{
			c = h->last[b] - c;
			if(c >= maxleaf)
				fatal(dec, "corrupted huffman table: c=%d maxleaf=%d i=%d b=%d maxbits=%d last=%d, nc=%d",
					c, maxleaf, i, b, maxbits, h->last[b], nc[b]);
				fatal(dec, "corrupted huffman table");
			h->decode[c] = i;
		}
	}
}

static void
hflush(Decode *dec)
hbflush(Decode *dec)
{
	Huff codetab;
	ulong bitcount[MaxHuffBits+1], hb[MaxLeaf];
	uchar tmtf[MaxHuffBits+1];
	ulong bitcount[MaxHuffBits+1];
	uchar tmtf[MaxHuffBits+1], *hb;
	int i, b, m, maxbits;

	dec->base = 1;
	dec->ndec = 0;

	hb = malloc(MaxLeaf * sizeof *hb);
	if(waserror()) {
		free(hb);
		nexterror();
	}

	/*
	 * read the tables for the tables
	 */


@@ 349,19 355,19 @@ hflush(Decode *dec)
		if(b > maxbits)
			maxbits = b;
	}
	hufftab(dec, &codetab, hb, bitcount, MaxHuffBits+1, maxbits, 8);
	for(i = 0; i <= MaxHuffBits; i++)
	hufftab(dec, &dec->tab, hb, bitcount, MaxHuffBits+1, maxbits, MaxFlatbits);
	for(i = 0; i <= MaxHuffBits; i++){
		tmtf[i] = i;
	for(i = 0; i <= MaxHuffBits; i++)
		bitcount[i] = 0;
	}
	maxbits = 0;
	for(i = 0; i < dec->maxblocksym; i++){
		if(dec->nbits <= codetab.maxbits)
		if(dec->nbits <= dec->tab.maxbits)
			fillbits(dec);
		dec->bits &= (1 << dec->nbits) - 1;
		m = codetab.flat[dec->bits >> (dec->nbits - codetab.flatbits)];
		m = dec->tab.flat[dec->bits >> (dec->nbits - dec->tab.flatbits)];
		if(m == ~0)
			m = hdecsym(dec, &codetab);
			m = hdecsym(dec, &dec->tab);
		else{
			dec->nbits -= m & 0xff;
			m >>= 8;


@@ 372,7 378,7 @@ hflush(Decode *dec)
		tmtf[0] = b;

		if(b > MaxHuffBits)
			fatal(dec, "bit length %d too large, max %d i %d maxval %d", b, MaxHuffBits, i, dec->maxblocksym);
			fatal(dec, "bit length too big");
		hb[i] = b;
		bitcount[b]++;
		if(b > maxbits)


@@ 381,19 387,16 @@ hflush(Decode *dec)
	for(; i < MaxLeaf; i++)
		hb[i] = 0;

	hufftab(dec, &dec->tab, hb, bitcount, MaxLeaf, maxbits, 8);
	hufftab(dec, &dec->tab, hb, bitcount, MaxLeaf, maxbits, MaxFlatbits);

	poperror();
	free(hb);
}

static void
fatal(Decode *dec, char *fmt, ...)
fatal(Decode *dec, char *msg)
{
	char buf[128];
	va_list arg;

	va_start(arg, fmt);
	doprint(buf, buf+sizeof(buf), fmt, arg);
	va_end(arg);

	print("devsac: %s\n", buf);
	error(buf);
	USED(dec);
print("unsac: %s\n", msg);
	error(msg);
}

M pc/devlml.c => pc/devlml.c +126 -32
@@ 23,20 23,49 @@ int debug = 0;

enum{
	Qdir,
	Qjcount,
	Qjpg,
//	Qraw,
};

static Dirtab lmldir[]={
//	 name,		 qid,		size,		mode
	"jcount",	{Qjcount},	0,		0444,
//	 name,		qid,	size,	mode
	"lmljpg",	{Qjpg},	0,	0444,
//	"lmlraw",	{Qraw},	0,	0444,
};

CodeData *	codeData;
static CodeData *	codeData;

static ulong		jpgframeno;
//static ulong		rawframeno;

//static FrameHeader	rawheader;

static FrameHeader	jpgheader[NBUF] = {
	{
		MRK_SOI, MRK_APP3, (sizeof(FrameHeader)-4) << 8,
		{ 'L', 'M', 'L', '\0'},
		-1, 0, 0, 0, 0
	}, {
		MRK_SOI, MRK_APP3, (sizeof(FrameHeader)-4) << 8,
		{ 'L', 'M', 'L', '\0'},
		-1, 0, 0, 0, 0
	}, {
		MRK_SOI, MRK_APP3, (sizeof(FrameHeader)-4) << 8,
		{ 'L', 'M', 'L', '\0'},
		-1, 0, 0, 0, 0
	}, {
		MRK_SOI, MRK_APP3, (sizeof(FrameHeader)-4) << 8,
		{ 'L', 'M', 'L', '\0'},
		-1, 0, 0, 0, 0
	}
};

int		frameNo;
Rendez		sleeper;
Rendez		sleepjpg;
//Rendez		sleepraw;
int		singleFrame;
int		nopens;
int		jpgopens;
//int		rawopens;

#define writel(v, a) *(ulong *)(a) = (v)
#define readl(a) *(ulong*)(a)


@@ 51,24 80,57 @@ getbuffer(void){
		if (codeData->statCom[last] & STAT_BIT)
			return last;
		if (last == l)
			sleep(&sleeper, return0, 0);
			sleep(&sleepjpg, return0, 0);
	}
	return 0;
}

static long
vcount(Chan *, void *va, long nbytes, vlong) {
	char *p = (char *)va;
jpgread(Chan *, void *va, long nbytes, vlong) {
	int bufno;

	// reads should be of size 1 or sizeof(FrameHeader)
	// Frameno is the number of the buffer containing the data
	bufno = getbuffer();
	if (nbytes == sizeof(FrameHeader)) {
		memmove(va, &jpgheader[bufno], sizeof jpgheader[bufno]);
		return sizeof jpgheader[bufno];
	}
	if (nbytes == 1) {
		*(char *)va = bufno;
		return 1;
	}
	return 0;
}

	// reads always return one byte: the next available buffer number
	if (nbytes <= 0) return 0;
	*p = getbuffer();
	return 1;
/*
static long
rawread(Chan *, void *va, long nbytes, vlong) {

	// reads should be at least sizeof(FrameHeader) long
	// Frameno is the number of the buffer containing the data
	if (nbytes < sizeof(FrameHeader)) return 0;
	sleep(&sleepraw, return0, 0);
	memmove(va, &rawheader, sizeof rawheader);
	return sizeof rawheader;
}
*/

static void lmlintr(Ureg *, void *);

static void
prepbuf(void) {
	int i;

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

static void
lmlreset(void)
{
	Physseg segbuf;


@@ 78,7 140,6 @@ lmlreset(void)
	ulong cdsize;
	void *grabbuf;
	ulong grablen;
	int i;

	pcidev = pcimatch(nil, PCI_VENDOR_ZORAN, PCI_DEVICE_ZORAN_36067);
	if (pcidev == nil) {


@@ 105,12 166,8 @@ lmlreset(void)
	// Get access to DMA memory buffer
	codeData->pamjpg = PADDR(codeData->statCom);
	codeData->pagrab = PADDR(grabbuf);
	for (i = 0; i < NBUF; i++) {
		codeData->statCom[i] = PADDR(&(codeData->fragdesc[i]));
		codeData->fragdesc[i].addr = PADDR(&(codeData->frag[i]));
		// Length is in double words, in position 1..20
		codeData->fragdesc[i].leng = ((sizeof codeData->frag[i]) >> 1) | FRAGM_FINAL_B;
	}

	prepbuf();

	pciPhysBaseAddr = (void *)(pcidev->mem[0].bar & ~0x0F);



@@ 186,12 243,22 @@ lmlopen(Chan *c, int omode) {

	c->aux = 0;
	switch(c->qid.path){
	case Qjcount:
	case Qjpg:
		// allow one open
		if (nopens)
		if (jpgopens)
			error(Einuse);
		nopens = 1;
		jpgopens = 1;
		jpgframeno = 0;
		prepbuf();
		break;
/*	case Qraw:
		// allow one open
		if (rawopens)
			error(Einuse);
		rawopens = 1;
		rawframeno = 0;
		break;
*/
	}
	return devopen(c, omode, lmldir, nelem(lmldir), devgen);
}


@@ 200,10 267,15 @@ static void
lmlclose(Chan *c) {

	switch(c->qid.path){
	case Qjcount:
		nopens = 0;
		authclose(c);
	case Qjpg:
		jpgopens = 0;
		break;
/*	case Qraw:
		rawopens = 0;
		break;
*/
	}
	authclose(c);
}

static long


@@ 215,8 287,11 @@ lmlread(Chan *c, void *va, long n, vlong voff) {

	case Qdir:
		return devdirread(c, (char *)buf, n, lmldir, nelem(lmldir), devgen);
	case Qjcount:
		return vcount(c, buf, n, off);
	case Qjpg:
		return jpgread(c, buf, n, off);
/*	case Qraw:
		return rawread(c, buf, n, off);
*/
	}
}



@@ 250,7 325,7 @@ Dev lmldevtab = {

static void
lmlintr(Ureg *, void *) {
	static count;
	ulong fstart, fno;
	ulong flags = readl(pciBaseAddr+INTR_STAT);
	
	if(debug&(DBGINTR))


@@ 260,9 335,28 @@ lmlintr(Ureg *, void *) {
	writel(0xff000000, pciBaseAddr + INTR_STAT);

	if(flags & INTR_JPEGREP) {
		if ((debug&DBGINTR) || ((debug&DBGINTS) && (count++ % 128) == 0))
			print("MjpgDrv_intrHandler wakeup\n");
		wakeup(&sleeper);
		vlong thetime;

		fstart = jpgframeno & 0x00000003;
		for (;;) {
			jpgframeno++;
			fno = jpgframeno & 0x00000003;
			if (codeData->statCom[fno] & STAT_BIT)
				break;
			if (fno == fstart) {
				if (debug & DBGINTR)
					print("Spurious lml jpg intr?\n");
				return;
			}
		}
		thetime = todget(nil);
		jpgheader[fno].sec  = (ulong)(thetime / 1000000000LL);
		jpgheader[fno].usec = (ulong)(thetime % 1000000000LL) / 1000;
		jpgheader[fno].frameSize =
			(codeData->statCom[fno] & 0x00ffffff) >> 1;
		jpgheader[fno].frameSeqNo = codeData->statCom[fno] >> 24;
		jpgheader[fno].frameNo = jpgframeno;
		wakeup(&sleepjpg);
	}
	return;
}

M pc/devlml.h => pc/devlml.h +1 -16
@@ 2,12 2,6 @@

#define MJPG_VERSION "LML33 v0.2"

// Various minor numbers (functions) of the device
#define MJPG_MINOR_STATUS 0
#define MJPG_MINOR_VIDEO 1
#define MJPG_MINOR_FRAME 2
#define MJPG_MINOR_STILL 3

// The following values can be modified to tune/set default behaviour of the
// driver.



@@ 28,19 22,13 @@
// card found is mapped to a device minor number starting from 0.
#define MAX_CARDS 1

// The following is the number of device types supported.
#define DEVICE_COUNT 2

// The number of 8K pages per buffer, we will allocate four buffers,
// locked into memory whenever the device is open so modify with care.
#define PAGES 32

// The following are the datastructures needed by the device.
#define I2C_BUS		0x044
// which bit of I2C_BUS is which
#define I2C_SCL		1
#define I2C_SDA		2
#define INTR_JPEGREP	0x08000000
#define INTR_GIRQ0	0x20000000
#define INTR_STAT	0x03c

// A Device records the properties of the various card types supported.


@@ 61,18 49,15 @@ typedef struct {
#define BT819Addr 0x8a
#define BT856Addr 0x88

#define MB 0x100000
#define NBUF 4

#define FRAGM_FINAL_B 1
#define STAT_BIT 1

typedef struct	FrameHeader		FrameHeader;
typedef struct	MjpgDrv			MjpgDrv;
typedef union	Fragment		Fragment;
typedef struct	FragmentTable		FragmentTable;
typedef struct	CodeData		CodeData;
typedef struct	ML33Board		LML33Board;

//If we're on the little endian architecture, then 0xFF, 0xD8 byte sequence is
#define MRK_SOI		0xD8FF