M bitsy/dat.h => bitsy/dat.h +3 -3
@@ 100,8 100,8 @@ struct Mach
int machno; /* physical id of processor */
ulong splpc; /* pc of last caller to splhi */
- Proc* proc; /* current process on this processor */
- Proc* externup; /* extern register Proc *up */
+ Proc *proc; /* current process */
+ ulong mmupid; /* process id currently in mmu & cache */
ulong ticks; /* of the clock since boot time */
Label sched; /* scheduler wakeup */
@@ 171,7 171,7 @@ struct
#define MACHP(n) ((Mach *)(MACHADDR+(n)*BY2PG))
extern Mach *m;
-#define up (((Mach*)MACHADDR)->externup)
+extern Proc *up;
enum
{
M bitsy/devsac.c => bitsy/devsac.c +2 -14
@@ 98,21 98,9 @@ sacinit(void)
{
SacHeader *hdr;
uchar *p;
- char *s;
int i;
-print("sacinit\n");
- s = getconf("flash");
- if(s == nil) {
- print("devsac: no flash file system\n");
- return;
- }
-
- p = (uchar*)strtoul(s, 0, 0);
- if(p == 0) {
- print("devsac: bad address for flash file system\n");
- return;
- }
+ p = (uchar*)Flash_tar+4;
data = tarlookup(p, sacfs, &i);
if(data == 0) {
print("devsac: could not find file: %s\n", sacfs);
@@ 120,7 108,7 @@ print("sacinit\n");
}
hdr = (SacHeader*)data;
if(getl(hdr->magic) != Magic) {
-print("devsac: bad magic\n");
+ print("devsac: bad magic\n");
return;
}
blocksize = getl(hdr->blocksize);
M bitsy/fns.h => bitsy/fns.h +3 -0
@@ 9,6 9,7 @@ void clockinit(void);
void delay(int);
void evenaddr(ulong);
void flushmmu(void);
+char* getconf(char*);
ulong getfar(void);
ulong getfsr(void);
#define getpgcolor(a) 0
@@ 45,6 46,7 @@ void screeninit(void);
int screenprint(char*, ...); /* debugging */
void screenputs(char*, int);
void setr13(int, ulong*);
+uchar* tarlookup(uchar*, char*, int*);
void touser(void*);
void trapdump(char *tag);
void trapinit(void);
@@ 52,6 54,7 @@ int tas(void*);
int uartstageoutput(Uart*);
void uartkick(void*);
void uartrecv(Uart*, char);
+int unsac(uchar*, uchar*, int, int);
void vectors(void);
void vtable(void);
void wbflush(void);
M bitsy/main.c => bitsy/main.c +4 -4
@@ 8,13 8,13 @@
#include "init.h"
#include "pool.h"
-Mach *m;
-Conf conf;
+Mach *m;
+Proc *up;
+Conf conf;
+int noprint;
static void gpioinit(void);
-int noprint;
-
void
main(void)
{
M bitsy/mem.h => bitsy/mem.h +7 -0
@@ 63,6 63,13 @@
#define KSTACK (16*1024) /* Size of kernel stack */
/*
+ * Offsets into flash
+ */
+#define Flash_bootldr (FLASHZERO+0x0) /* boot loader */
+#define Flash_kernel (FLASHZERO+0x10000) /* boot kernel */
+#define Flash_tar (FLASHZERO+0x100000) /* tar file containing fs.sac */
+
+/*
* virtual MMU
*/
#define PTEMAPMEM (1024*1024)
M bitsy/mmu.c => bitsy/mmu.c +24 -15
@@ 222,30 222,35 @@ static ulong mmubits[16] =
void
putmmu(ulong va, ulong pa, Page*)
{
- Page *p;
+ Page *pg;
ulong *t;
-//iprint("putmmu(0x%.8lux, 0x%.8lux)\n", va, pa);
+print("putmmu(0x%.8lux, 0x%.8lux)\n", va, pa);
/* always point L1 entry to L2 page, can't hurt */
- p = up->l1page[va>>20];
- if(p == nil){
- p = auxpage();
- if(p == nil)
- pexit("out of memory", 1);
- p->va = VA(kmap(p));
- up->l1page[va>>20] = p;
- memset((uchar*)(p->va), 0, BY2PG);
+ pg = up->l1page[va>>20];
+ if(pg == nil){
+ pg = up->mmufree;
+ if(pg != nil){
+ up->mmufree = pg->next;
+ } else {
+ pg = auxpage();
+ if(pg == nil)
+ pexit("out of memory", 1);
+ }
+ pg->va = VA(kmap(pg));
+ up->l1page[va>>20] = pg;
+ memset((uchar*)(pg->va), 0, BY2PG);
}
- l1table[va>>20] = L1PageTable | L1Domain0 | (p->pa & L1PTBaseMask);
+ l1table[va>>20] = L1PageTable | L1Domain0 | (pg->pa & L1PTBaseMask);
cacheflushaddr((ulong)&l1table[va>>20]);
-//iprint("%lux[%lux] = %lux\n", l1table, va>>20, l1table[va>>20]);
+print("%lux[%lux] = %lux\n", l1table, va>>20, l1table[va>>20]);
up->l1table[va>>20] = l1table[va>>20];
- t = (ulong*)p->va;
+ t = (ulong*)pg->va;
/* set L2 entry */
t[(va & (OneMeg-1))>>PGSHIFT] = mmubits[pa & (PTEKERNEL|PTEVALID|PTEUNCACHED|PTEWRITE)]
| (pa & ~(PTEKERNEL|PTEVALID|PTEUNCACHED|PTEWRITE));
-//iprint("%lux[%lux] = %lux\n", (ulong)t, (va & (OneMeg-1))>>PGSHIFT, t[(va & (OneMeg-1))>>PGSHIFT]);
+print("%lux[%lux] = %lux\n", (ulong)t, (va & (OneMeg-1))>>PGSHIFT, t[(va & (OneMeg-1))>>PGSHIFT]);
cacheflushaddr((ulong)&t[(va & (OneMeg-1))>>PGSHIFT]);
wbflush();
@@ 298,8 303,12 @@ mmurelease(Proc* p)
}
void
-mmuswitch(Proc* p)
+mmuswitch(Proc *p)
{
+ if(m->mmupid == p->pid && p->newtlb == 0)
+ return;
+ m->mmupid = p->pid;
+
if(p->newtlb){
mmuptefree(p);
p->newtlb = 0;
A bitsy/tar.c => bitsy/tar.c +84 -0
@@ 0,0 1,84 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "io.h"
+#include "../port/error.h"
+
+typedef union Hblock Hblock;
+
+#define TBLOCK 512
+#define NAMSIZ 100
+union Hblock
+{
+ char dummy[TBLOCK];
+ struct header
+ {
+ char name[NAMSIZ];
+ char mode[8];
+ char uid[8];
+ char gid[8];
+ char size[12];
+ char mtime[12];
+ char chksum[8];
+ char linkflag;
+ char linkname[NAMSIZ];
+ } dbuf;
+};
+
+static int getdir(Hblock *hb, Dir *sp);
+static int checksum(Hblock *hb);
+
+uchar*
+tarlookup(uchar *addr, char *file, int *dlen)
+{
+ Hblock *hp;
+ Dir dir;
+
+ hp = (Hblock*)addr;
+ while(getdir(hp, &dir) != 0) {
+ if(strcmp(file, hp->dbuf.name) == 0) {
+ *dlen = dir.length;
+ return (uchar*)(hp+1);
+ }
+ hp += (dir.length+TBLOCK-1)/TBLOCK + 1;
+ }
+ return 0;
+}
+
+static int
+getdir(Hblock *hp, Dir *sp)
+{
+ int chksum;
+
+ if (hp->dbuf.name[0] == '\0')
+ return 0;
+ sp->mode = strtol(hp->dbuf.mode, 0, 8);
+ strncpy(sp->uid, "adm", sizeof(sp->uid));
+ strncpy(sp->gid, "adm", sizeof(sp->gid));
+ sp->length = strtol(hp->dbuf.size, 0, 8);
+ sp->mtime = strtol(hp->dbuf.mtime, 0, 8);
+ chksum = strtol(hp->dbuf.chksum, 0, 8);
+ if (chksum != checksum(hp)) {
+ print("directory checksum error\n");
+ return 0;
+ }
+ return 1;
+}
+
+static int
+checksum(Hblock *hp)
+{
+ int i;
+ char *cp;
+
+ i = 0;
+ for (cp = hp->dummy; cp < &hp->dummy[TBLOCK]; cp++) {
+ if(cp < hp->dbuf.chksum || cp >= &hp->dbuf.chksum[sizeof(hp->dbuf.chksum)])
+ i += *cp & 0xff;
+ else
+ i += ' ' & 0xff;
+ }
+ return(i);
+}
M bitsy/trap.c => bitsy/trap.c +16 -4
@@ 147,12 147,21 @@ faultarm(Ureg *ureg, ulong va, int user, int read)
up->insyscall = insyscall;
}
+/* all Pabt+1 faults are caused by loads or stores. The Lbit of
+ * the instruction distinquishes between them.
+ */
+enum
+{
+ Lbit = 1<<20, /* load instruction */
+};
+
/*
* here on all exceptions other than syscall (SWI)
*/
void
trap(Ureg *ureg)
{
+ ulong inst;
int i, found;
Vctl *v;
int user;
@@ 175,12 184,13 @@ trap(Ureg *ureg)
panic("unknown trap");
break;
case PsrMabt: /* prefetch fault */
-//iprint("prefetch abort at 0x%lux\n", ureg->pc);
+print("%d: prefetch abort at 0x%lux\n", m->lastpid, ureg->pc);
faultarm(ureg, ureg->pc, user, 1);
break;
case PsrMabt+1: /* data fault */
va = getfar();
-//iprint("data fault pc 0x%lux(0x%lux) va 0x%lux fsr 0x%lux\n", ureg->pc, *(ulong*)(ureg->pc), va, getfsr());
+ inst = *(ulong*)(ureg->pc);
+print("%d: data fault pc 0x%lux(0x%lux) va 0x%lux fsr 0x%lux\n", m->lastpid, ureg->pc, inst, va, getfsr());
switch(getfsr() & 0xf){
case 0x0:
panic("vector exception at %lux\n", ureg->pc);
@@ 208,7 218,7 @@ trap(Ureg *ureg)
case 0x5:
case 0x7:
/* translation fault, i.e., no pte entry */
- faultarm(ureg, va, user, 1);
+ faultarm(ureg, va, user, inst & Lbit);
break;
case 0x9:
case 0xb:
@@ 222,7 232,7 @@ trap(Ureg *ureg)
case 0xd:
case 0xf:
/* permission error, copy on write or real permission error */
- faultarm(ureg, va, user, 0);
+ faultarm(ureg, va, user, inst & Lbit);
break;
}
break;
@@ 569,8 579,10 @@ execregs(ulong entry, ulong ssize, ulong nargs)
*--sp = nargs;
ureg = up->dbgreg;
+ memset(ureg, 0, 15*sizeof(ulong));
ureg->r13 = (ulong)sp;
ureg->pc = entry;
+print("execregs pc 0x%lux sp 0x%lux\n", ureg->pc, ureg->r13);
return USTKTOP-BY2WD; /* address of user-level clock */
}
A bitsy/unsac.c => bitsy/unsac.c +627 -0
@@ 0,0 1,627 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "io.h"
+
+typedef struct Huff Huff;
+typedef struct Mtf Mtf;
+typedef struct Decode Decode;
+
+enum
+{
+ ZBase = 2, /* base of code to encode 0 runs */
+ LitBase = ZBase-1, /* base of literal values */
+ MaxLit = 256,
+
+ MaxLeaf = MaxLit+LitBase,
+ MaxHuffBits = 16, /* max bits in a huffman code */
+ MaxFlatbits = 5, /* max bits decoded in flat table */
+
+ CombLog = 4,
+ CombSpace = 1 << CombLog, /* mtf speedup indices spacing */
+ CombMask = CombSpace - 1,
+};
+
+struct Mtf
+{
+ int maxcomb; /* index of last valid comb */
+ uchar prev[MaxLit];
+ uchar next[MaxLit];
+ uchar comb[MaxLit / CombSpace + 1];
+};
+
+struct Huff
+{
+ int maxbits;
+ int flatbits;
+ ulong flat[1<<MaxFlatbits];
+ ulong maxcode[MaxHuffBits];
+ ulong last[MaxHuffBits];
+ ulong decode[MaxLeaf];
+};
+
+struct Decode{
+ Huff tab;
+ Mtf mtf;
+ int nbits;
+ ulong bits;
+ int nzero;
+ int base;
+ ulong maxblocksym;
+
+ uchar *src; /* input buffer */
+ uchar *smax; /* limit */
+};
+
+static void fatal(Decode *dec, char*);
+
+static int hdec(Decode*);
+static void recvtab(Decode*, Huff*, int, ushort*);
+static ulong bitget(Decode*, int);
+static int mtf(uchar*, int);
+
+#define FORWARD 0
+
+static void
+mtflistinit(Mtf *m, uchar *front, int n)
+{
+ int last, me, f, i, comb;
+
+ if(n == 0)
+ return;
+
+ /*
+ * add all entries to free list
+ */
+ last = MaxLit - 1;
+ for(i = 0; i < MaxLit; i++){
+ m->prev[i] = last;
+ m->next[i] = i + 1;
+ last = i;
+ }
+ m->next[last] = 0;
+ f = 0;
+
+ /*
+ * pull valid entries off free list and enter into mtf list
+ */
+ comb = 0;
+ last = front[0];
+ for(i = 0; i < n; i++){
+ me = front[i];
+
+ f = m->next[me];
+ m->prev[f] = m->prev[me];
+ m->next[m->prev[f]] = f;
+
+ m->next[last] = me;
+ m->prev[me] = last;
+ last = me;
+ if((i & CombMask) == 0)
+ m->comb[comb++] = me;
+ }
+
+ /*
+ * pad out the list with dummies to the next comb,
+ * using free entries
+ */
+ for(; i & CombMask; i++){
+ me = f;
+
+ f = m->next[me];
+ m->prev[f] = m->prev[me];
+ m->next[m->prev[f]] = f;
+
+ m->next[last] = me;
+ m->prev[me] = last;
+ last = me;
+ }
+ me = front[0];
+ m->next[last] = me;
+ m->prev[me] = last;
+ m->comb[comb] = me;
+ m->maxcomb = comb;
+}
+
+static int
+mtflist(Mtf *m, int pos)
+{
+ uchar *next, *prev, *mycomb;
+ int c, c0, pc, nc, off;
+
+ if(pos == 0)
+ return m->comb[0];
+
+ next = m->next;
+ prev = m->prev;
+ mycomb = &m->comb[pos >> CombLog];
+ off = pos & CombMask;
+ if(off >= CombSpace / 2){
+ c = mycomb[1];
+ for(; off < CombSpace; off++)
+ c = prev[c];
+ }else{
+ c = *mycomb;
+ for(; off; off--)
+ c = next[c];
+ }
+
+ nc = next[c];
+ pc = prev[c];
+ prev[nc] = pc;
+ next[pc] = nc;
+
+ for(; mycomb > m->comb; mycomb--)
+ *mycomb = prev[*mycomb];
+ c0 = *mycomb;
+ *mycomb = c;
+ mycomb[m->maxcomb] = c;
+
+ next[c] = c0;
+ pc = prev[c0];
+ prev[c] = pc;
+ prev[c0] = c;
+ next[pc] = c;
+ return c;
+}
+
+static void
+hdecblock(Decode *dec, ulong n, ulong I, uchar *buf, ulong *sums, ulong *prev)
+{
+ ulong i, nn, sum;
+ int m, z, zz, c;
+
+ nn = I;
+ n--;
+ i = 0;
+again:
+ for(; i < nn; i++){
+ while((m = hdec(dec)) == 0 && i + dec->nzero < n)
+ ;
+ if(z = dec->nzero){
+ dec->nzero = 0;
+ c = dec->mtf.comb[0];
+ sum = sums[c];
+ sums[c] = sum + z;
+
+ z += i;
+ zz = z;
+ if(i < I && z > I){
+ zz = I;
+ z++;
+ }
+
+ zagain:
+ for(; i < zz; i++){
+ buf[i] = c;
+ prev[i] = sum++;
+ }
+ if(i != z){
+ zz = z;
+ nn = ++n;
+ i++;
+ goto zagain;
+ }
+ if(i == nn){
+ if(i == n)
+ return;
+ nn = ++n;
+ i++;
+ }
+ }
+
+ c = mtflist(&dec->mtf, m);
+
+ buf[i] = c;
+ sum = sums[c];
+ prev[i] = sum++;
+ sums[c] = sum;
+
+ }
+ if(i == n)
+ return;
+ nn = ++n;
+ i++;
+ goto again;
+}
+
+int
+unsac(uchar *dst, uchar *src, int n, int nsrc)
+{
+ Decode *dec;
+ uchar *buf, *front;
+ ulong *prev, *sums;
+ ulong sum, i, I;
+ int m, j, c;
+
+ dec = malloc(sizeof *dec);
+ buf = malloc(n+2);
+ prev = malloc((n+2) * sizeof *prev);
+ front = malloc(MaxLit * sizeof *front);
+ sums = malloc(MaxLit * sizeof *sums);
+
+ if(waserror()){
+ free(dec);
+ free(buf);
+ free(prev);
+ free(front);
+ free(sums);
+ nexterror();
+ }
+
+ dec->src = src;
+ dec->smax = src + nsrc;
+
+ dec->nbits = 0;
+ dec->bits = 0;
+ dec->nzero = 0;
+ for(i = 0; i < MaxLit; i++)
+ front[i] = i;
+
+ n++;
+ I = bitget(dec, 16);
+ if(I >= n)
+ fatal(dec, "corrupted input");
+
+ /*
+ * decode the character usage map
+ */
+ for(i = 0; i < MaxLit; i++)
+ sums[i] = 0;
+ c = bitget(dec, 1);
+ for(i = 0; i < MaxLit; ){
+ m = bitget(dec, 8) + 1;
+ while(m--){
+ if(i >= MaxLit)
+ fatal(dec, "corrupted char map");
+ front[i++] = c;
+ }
+ c = c ^ 1;
+ }
+
+ /*
+ * initialize mtf state
+ */
+ c = 0;
+ for(i = 0; i < MaxLit; i++)
+ if(front[i])
+ front[c++] = i;
+ mtflistinit(&dec->mtf, front, c);
+ dec->maxblocksym = c + LitBase;
+
+ /*
+ * huffman decoding, move to front decoding,
+ * along with character counting
+ */
+ dec->base = 1;
+ recvtab(dec, &dec->tab, MaxLeaf, nil);
+ hdecblock(dec, n, I, buf, sums, prev);
+
+ sum = 1;
+ for(i = 0; i < MaxLit; i++){
+ c = sums[i];
+ sums[i] = sum;
+ sum += c;
+ }
+
+ i = 0;
+ for(j = n - 2; j >= 0; j--){
+ if(i > n || i < 0 || i == I)
+ fatal(dec, "corrupted data");
+ c = buf[i];
+ dst[j] = c;
+ i = prev[i] + sums[c];
+ }
+
+ poperror();
+
+ free(dec);
+ free(buf);
+ free(prev);
+ free(front);
+ free(sums);
+ return n;
+}
+
+static ulong
+bitget(Decode *dec, int nb)
+{
+ int c;
+
+ while(dec->nbits < nb){
+ if(dec->src >= dec->smax)
+ fatal(dec, "premature eof 1");
+ c = *dec->src++;
+ dec->bits <<= 8;
+ dec->bits |= c;
+ dec->nbits += 8;
+ }
+ dec->nbits -= nb;
+ return (dec->bits >> dec->nbits) & ((1 << nb) - 1);
+}
+
+static void
+fillbits(Decode *dec)
+{
+ int c;
+
+ while(dec->nbits < 24){
+ if(dec->src >= dec->smax)
+ fatal(dec, "premature eof 2");
+ c = *dec->src++;
+ dec->bits <<= 8;
+ dec->bits |= c;
+ dec->nbits += 8;
+ }
+}
+
+/*
+ * decode one symbol
+ */
+static int
+hdecsym(Decode *dec, Huff *h, int b)
+{
+ long c;
+ ulong bits;
+ int nbits;
+
+ bits = dec->bits;
+ nbits = dec->nbits;
+ for(; (c = bits >> (nbits - b)) > h->maxcode[b]; b++)
+ ;
+ if(b > h->maxbits)
+ fatal(dec, "too many bits consumed");
+ dec->nbits = nbits - b;
+ return h->decode[h->last[b] - c];
+}
+
+static int
+hdec(Decode *dec)
+{
+ ulong c;
+ int nbits, nb;
+
+ if(dec->nbits < dec->tab.maxbits)
+ fillbits(dec);
+ nbits = dec->nbits;
+ dec->bits &= (1 << nbits) - 1;
+ c = dec->tab.flat[dec->bits >> (nbits - dec->tab.flatbits)];
+ nb = c & 0xff;
+ c >>= 8;
+ if(nb == 0xff)
+ c = hdecsym(dec, &dec->tab, c);
+ else
+ dec->nbits = nbits - nb;
+
+ /*
+ * reverse funny run-length coding
+ */
+ if(c < ZBase){
+ dec->nzero += dec->base << c;
+ dec->base <<= 1;
+ return 0;
+ }
+
+ dec->base = 1;
+ c -= LitBase;
+ return c;
+}
+
+static void
+hufftab(Decode *dec, Huff *h, char *hb, ulong *bitcount, int maxleaf, int maxbits, int flatbits)
+{
+ ulong c, mincode, code, nc[MaxHuffBits];
+ int i, b, ec;
+
+ h->maxbits = maxbits;
+ if(maxbits < 0)
+ return;
+
+ code = 0;
+ c = 0;
+ for(b = 0; b <= maxbits; b++){
+ h->last[b] = c;
+ c += bitcount[b];
+ mincode = code << 1;
+ nc[b] = mincode;
+ code = mincode + bitcount[b];
+ if(code > (1 << b))
+ fatal(dec, "corrupted huffman table");
+ h->maxcode[b] = code - 1;
+ h->last[b] += code - 1;
+ }
+ if(code != (1 << maxbits))
+ fatal(dec, "huffman table not full");
+ if(flatbits > maxbits)
+ flatbits = maxbits;
+ h->flatbits = flatbits;
+
+ b = 1 << flatbits;
+ for(i = 0; i < b; i++)
+ h->flat[i] = ~0;
+
+ /*
+ * initialize the flat table to include the minimum possible
+ * bit length for each code prefix
+ */
+ for(b = maxbits; b > flatbits; b--){
+ code = h->maxcode[b];
+ if(code == -1)
+ break;
+ mincode = code + 1 - bitcount[b];
+ mincode >>= b - flatbits;
+ code >>= b - flatbits;
+ for(; mincode <= code; mincode++)
+ h->flat[mincode] = (b << 8) | 0xff;
+ }
+
+ for(i = 0; i < maxleaf; i++){
+ b = hb[i];
+ if(b == -1)
+ continue;
+ c = nc[b]++;
+ if(b <= flatbits){
+ code = (i << 8) | b;
+ ec = (c + 1) << (flatbits - b);
+ if(ec > (1<<flatbits))
+ 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");
+ h->decode[c] = i;
+ }
+ }
+}
+
+static void
+elimBit(int b, char *tmtf, int maxbits)
+{
+ int bb;
+
+ for(bb = 0; bb < maxbits; bb++)
+ if(tmtf[bb] == b)
+ break;
+ while(++bb <= maxbits)
+ tmtf[bb - 1] = tmtf[bb];
+}
+
+static int
+elimBits(int b, ulong *bused, char *tmtf, int maxbits)
+{
+ int bb, elim;
+
+ if(b < 0)
+ return 0;
+
+ elim = 0;
+
+ /*
+ * increase bits counts for all descendants
+ */
+ for(bb = b + 1; bb < maxbits; bb++){
+ bused[bb] += 1 << (bb - b);
+ if(bused[bb] == (1 << bb)){
+ elim++;
+ elimBit(bb, tmtf, maxbits);
+ }
+ }
+
+ /*
+ * steal bits from parent & check for fullness
+ */
+ for(; b >= 0; b--){
+ bused[b]++;
+ if(bused[b] == (1 << b)){
+ elim++;
+ elimBit(b, tmtf, maxbits);
+ }
+ if((bused[b] & 1) == 0)
+ break;
+ }
+ return elim;
+}
+
+static void
+recvtab(Decode *dec, Huff *tab, int maxleaf, ushort *map)
+{
+ ulong bitcount[MaxHuffBits+1], bused[MaxHuffBits+1];
+ char tmtf[MaxHuffBits+1], *hb;
+ int i, b, ttb, m, maxbits, max, elim;
+
+ hb = malloc(MaxLeaf * sizeof *hb);
+ if(waserror()) {
+ free(hb);
+ nexterror();
+ }
+
+ /*
+ * read the tables for the tables
+ */
+ max = 8;
+ for(i = 0; i <= MaxHuffBits; i++){
+ bitcount[i] = 0;
+ tmtf[i] = i;
+ bused[i] = 0;
+ }
+ tmtf[0] = -1;
+ tmtf[max] = 0;
+ elim = 0;
+ maxbits = -1;
+ for(i = 0; i <= MaxHuffBits && elim != max; i++){
+ ttb = 4;
+ while(max - elim < (1 << (ttb-1)))
+ ttb--;
+ b = bitget(dec, ttb);
+ if(b > max - elim)
+ fatal(dec, "corrupted huffman table table");
+ b = tmtf[b];
+ hb[i] = b;
+ bitcount[b]++;
+ if(b > maxbits)
+ maxbits = b;
+
+ elim += elimBits(b, bused, tmtf, max);
+ }
+ if(elim != max)
+ fatal(dec, "incomplete huffman table table");
+ hufftab(dec, tab, hb, bitcount, i, maxbits, MaxFlatbits);
+ for(i = 0; i <= MaxHuffBits; i++){
+ tmtf[i] = i;
+ bitcount[i] = 0;
+ bused[i] = 0;
+ }
+ tmtf[0] = -1;
+ tmtf[MaxHuffBits] = 0;
+ elim = 0;
+ maxbits = -1;
+ for(i = 0; i < maxleaf && elim != MaxHuffBits; i++){
+ if(dec->nbits <= tab->maxbits)
+ fillbits(dec);
+ dec->bits &= (1 << dec->nbits) - 1;
+ m = tab->flat[dec->bits >> (dec->nbits - tab->flatbits)];
+ b = m & 0xff;
+ m >>= 8;
+ if(b == 0xff)
+ m = hdecsym(dec, tab, m);
+ else
+ dec->nbits -= b;
+ b = tmtf[m];
+ for(; m > 0; m--)
+ tmtf[m] = tmtf[m-1];
+ tmtf[0] = b;
+
+ if(b > MaxHuffBits)
+ fatal(dec, "bit length too big");
+ m = i;
+ if(map != nil)
+ m = map[m];
+ hb[m] = b;
+ bitcount[b]++;
+ if(b > maxbits)
+ maxbits = b;
+ elim += elimBits(b, bused, tmtf, MaxHuffBits);
+ }
+ if(elim != MaxHuffBits && elim != 0)
+ fatal(dec, "incomplete huffman table");
+ if(map != nil)
+ for(; i < maxleaf; i++)
+ hb[map[i]] = -1;
+
+ hufftab(dec, tab, hb, bitcount, i, maxbits, MaxFlatbits);
+
+ poperror();
+ free(hb);
+}
+
+static void
+fatal(Decode *dec, char *msg)
+{
+ USED(dec);
+print("unsac: %s\n", msg);
+ error(msg);
+}
M boot/sac.c => boot/sac.c +1 -1
@@ 36,8 36,8 @@ configsac(Method *mp)
write(fd, "brick", 5);
close(fd);
-
sprint(cmd, "/%s/init", cputype);
+ print("starting %s\n", cmd);
execl(cmd, "init", "-c", 0);
fatal(cmd);
}