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