From d328ec63b144226d80a24dbbd985f9e16469b3b1 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Thu, 10 Jun 1999 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1999-06-10 --- boot/boot.h | 3 + boot/sac.c | 63 ++++++++++++++++++++ mpc/devsac.c | 16 ++---- mpc/unsac.c | 121 ++++++++++++++++++++------------------- pc/devlml.c | 158 ++++++++++++++++++++++++++++++++++++++++----------- pc/devlml.h | 17 +----- 6 files changed, 259 insertions(+), 119 deletions(-) create mode 100644 boot/sac.c diff --git a/boot/boot.h b/boot/boot.h index 1ca7b9e48676b136700b978749e2c9b2f3bd60dd..690b794a9eaeda4965df68b0af483ce4b1ef5953 100644 --- a/boot/boot.h +++ b/boot/boot.h @@ -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); diff --git a/boot/sac.c b/boot/sac.c new file mode 100644 index 0000000000000000000000000000000000000000..da7c724b29e093b4e111b399b9fb7629d09fa2cc --- /dev/null +++ b/boot/sac.c @@ -0,0 +1,63 @@ +#include +#include +#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; +} diff --git a/mpc/devsac.c b/mpc/devsac.c index f0824eaf4424af7cd618b603590a9e2fb9a391ec..6223ff7abbf9d8737e839b9864d433ee8665f870 100644 --- a/mpc/devsac.c +++ b/mpc/devsac.c @@ -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); diff --git a/mpc/unsac.c b/mpc/unsac.c index 55f971349853b7314b6aa7fe182e28b196bf7a49..aaf5c1b9410c213bdb048382f3102fbf0fa22ad8 100644 --- a/mpc/unsac.c +++ b/mpc/unsac.c @@ -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<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 = 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<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); } diff --git a/pc/devlml.c b/pc/devlml.c index 38ffbb711af0bb4beb0eb85272668a995b481fa3..0eb47b232f702b66a50d57b0237504818e0fae7e 100644 --- a/pc/devlml.c +++ b/pc/devlml.c @@ -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,23 +80,56 @@ 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) { @@ -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; } diff --git a/pc/devlml.h b/pc/devlml.h index a1ef7a18e877deab42c9cdf3a19b972b2b5e8df8..195393639a548dc53f1f5dfda72410bcfaef6513 100644 --- a/pc/devlml.h +++ b/pc/devlml.h @@ -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