From 8bc4874889427a816fe88a8f6ee8c9d3ad04ae12 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Mon, 16 Oct 2000 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2000-10-16 --- bitsy/dat.h | 6 +- bitsy/devsac.c | 16 +- bitsy/fns.h | 3 + bitsy/main.c | 8 +- bitsy/mem.h | 7 + bitsy/mmu.c | 39 +-- bitsy/tar.c | 84 +++++++ bitsy/trap.c | 20 +- bitsy/unsac.c | 627 +++++++++++++++++++++++++++++++++++++++++++++++++ boot/sac.c | 2 +- 10 files changed, 771 insertions(+), 41 deletions(-) create mode 100644 bitsy/tar.c create mode 100644 bitsy/unsac.c diff --git a/bitsy/dat.h b/bitsy/dat.h index 0cf9966ef37503f977da7ab3097ef17eb9d067d9..5ae9b28508ba8df3edbb57872a3d1543a773a915 100644 --- a/bitsy/dat.h +++ b/bitsy/dat.h @@ -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 { diff --git a/bitsy/devsac.c b/bitsy/devsac.c index 3ee3e104e9f7abb950d6079d3cfd59bfd51c2d95..93ba4b1be4b6681388536bfd2c80abf2db276d3a 100644 --- a/bitsy/devsac.c +++ b/bitsy/devsac.c @@ -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); diff --git a/bitsy/fns.h b/bitsy/fns.h index dc7c745685ef8b0bf54f0de082f700ffb5719155..687f733b64864ae73c9e1c25ecc00fca1dee5846 100644 --- a/bitsy/fns.h +++ b/bitsy/fns.h @@ -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); diff --git a/bitsy/main.c b/bitsy/main.c index 90525ddc8b4403b83e6b3811b5e5a16f870ac7b5..8de68676fe5d0ce4e6c8af9666d0bd4e2f78ec2e 100644 --- a/bitsy/main.c +++ b/bitsy/main.c @@ -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) { diff --git a/bitsy/mem.h b/bitsy/mem.h index 75a3a494870e5a98703a9ec2f4cc06d96bf62613..becedebd409b51055bab75107d440cae91ee78a1 100644 --- a/bitsy/mem.h +++ b/bitsy/mem.h @@ -62,6 +62,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 */ diff --git a/bitsy/mmu.c b/bitsy/mmu.c index ad7bc4d053aeca7040b347d34d8d52026fd31836..acaf5e5f8d1285dd8b3791c88440ccea2fb22190 100644 --- a/bitsy/mmu.c +++ b/bitsy/mmu.c @@ -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; diff --git a/bitsy/tar.c b/bitsy/tar.c new file mode 100644 index 0000000000000000000000000000000000000000..35792796df84909867d28f53abac0fb2ef66d906 --- /dev/null +++ b/bitsy/tar.c @@ -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); +} diff --git a/bitsy/trap.c b/bitsy/trap.c index e715c27b506f2280f890ef7679cc81509a715c64..54c24abb2e8a2698bc2997490a19897774e62a81 100644 --- a/bitsy/trap.c +++ b/bitsy/trap.c @@ -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 */ } diff --git a/bitsy/unsac.c b/bitsy/unsac.c new file mode 100644 index 0000000000000000000000000000000000000000..f918792eef7b6c1333d51bc59299900b45b14916 --- /dev/null +++ b/bitsy/unsac.c @@ -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<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<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); +} diff --git a/boot/sac.c b/boot/sac.c index 5cd225b8e65a9f88e103fb1bc2b518a9c2962b56..df2765a52c66f7fb52ebf2fc023f7bdd7273bad9 100644 --- a/boot/sac.c +++ b/boot/sac.c @@ -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); }