From fd5d765be48434f680845f99a399ff352f3e97b5 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sat, 30 Nov 2002 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2002-11-30 --- alphapc/devarch.c | 44 ++++++++++-- alphapc/devether.c | 76 +++++++++++++++------ alphapc/etherif.h | 6 ++ alphapc/main.c | 165 +++++++++++++++++++++++++++++++++++++++++---- alphapc/pci.c | 9 ++- alphapc/random.c | 139 +------------------------------------- bitsy/main.c | 2 +- boot/bootauth.c | 6 +- boot/bootcache.c | 6 +- boot/bootip.c | 2 +- boot/embed.c | 6 +- boot/local.c | 4 +- boot/paq.c | 2 +- port/devroot.c | 140 +++++++++++++++++++++++++++----------- port/portfns.h | 2 +- 15 files changed, 376 insertions(+), 233 deletions(-) diff --git a/alphapc/devarch.c b/alphapc/devarch.c index 8ef79ab9fa13ac35f3192e8b8c1edf77c9b06451..352e47c6f065f32d201bea06cdf23c2fc1542352 100644 --- a/alphapc/devarch.c +++ b/alphapc/devarch.c @@ -401,13 +401,49 @@ PCArch archgeneric = { static char *sysnames[] = { -// [26] "EB164", -[26] "AlphaPC 164", +[1] "Alpha Demo. Unit", +[2] "DEC 4000; Cobra", +[3] "DEC 7000; Ruby", +[4] "DEC 3000/500; Flamingo family (TC)", +[6] "DEC 2000/300; Jensen (EISA/ISA)", +[7] "DEC 3000/300; Pelican (TC)", +[8] "Avalon A12; Avalon Multicomputer", +[9] "DEC 2100/A500; Sable", +[10] "DEC APXVME/64; AXPvme (VME?)", +[11] "DEC AXPPCI/33; NoName (PCI/ISA)", +[12] "DEC 21000; TurboLaser (PCI/EISA)", +[13] "DEC 2100/A50; Avanti (PCI/ISA)", +[14] "DEC MUSTANG; Mustang", +[15] "DEC KN20AA; kn20aa (PCI/EISA)", +[17] "DEC 1000; Mikasa (PCI/ISA?)", +[19] "EB66; EB66 (PCI/ISA?)", // DEC? +[20] "EB64P; EB64+ (PCI/ISA?)", // DEC? +[21] "Alphabook1; Alphabook", +[22] "DEC 4100; Rawhide (PCI/EISA)", +[23] "DEC EV45/PBP; Lego", +[24] "DEC 2100A/A500; Lynx", +[26] "DEC AlphaPC 164", // only supported one: "EB164 (PCI/ISA)" +[27] "DEC 1000A; Noritake", +[28] "DEC AlphaVME/224; Cortex", +[30] "DEC 550; Miata (PCI/ISA)", +[32] "DEC EV56/PBP; Takara", +[33] "DEC AlphaVME/320; Yukon (VME?)", +[34] "DEC 6600; MonetGoldrush", +// 200 and up is Alpha Processor Inc. machines +// [201] "API UP1000; Nautilus", }; static char *cpunames[] = { -[7] "21164A", +[1] "EV3", +[2] "EV4: 21064", +[3] "Simulation", +[4] "LCA4: 2106[68]", +[5] "EV5: 21164", +[6] "EV45: 21064A", +[7] "21164A", /* only supported one: EV56 */ +[8] "EV6: 21264", +[9] "PCA256: 21164PC", }; void @@ -430,7 +466,7 @@ cpuidprint(void) s = ""; if (hwrpb->systype < nelem(sysnames)) s = sysnames[hwrpb->systype]; - print("DEC %s (%llux, %llux, %llux)\n", s, hwrpb->systype, hwrpb->sysvar, hwrpb->sysrev); + print("%s (%llux, %llux, %llux)\n", s, hwrpb->systype, hwrpb->sysvar, hwrpb->sysrev); } for (i = 0; i < hwrpb->ncpu; i++) { diff --git a/alphapc/devether.c b/alphapc/devether.c index 52cebbf3d5b0f383a0943eb4d463f2a9b72dd3f3..c4de95b8e318a8308a87e865cf6dcaaf35152dfa 100644 --- a/alphapc/devether.c +++ b/alphapc/devether.c @@ -10,7 +10,7 @@ #include "etherif.h" -static Ether *etherxx[MaxEther]; +static volatile Ether *etherxx[MaxEther]; Chan* etherattach(char* spec) @@ -176,7 +176,8 @@ etheriq(Ether* ether, Block* bp, int fromwire) else if(xbp = iallocb(len)){ memmove(xbp->wp, pkt, len); xbp->wp += len; - qpass(f->in, xbp); + if(qpass(f->in, xbp) < 0) + ether->soverflows++; } else ether->soverflows++; @@ -239,21 +240,26 @@ etherwrite(Chan* chan, void* buf, long n, vlong) { Ether *ether; Block *bp; + int nn; ether = etherxx[chan->dev]; - if(NETTYPE(chan->qid.path) != Ndataqid){ - + if(NETTYPE(chan->qid.path) != Ndataqid) { + nn = netifwrite(ether, chan, buf, n); + if(nn >= 0) + return nn; if(n == sizeof("nonblocking")-1 && strncmp((char*)buf, "nonblocking", n) == 0){ qnoblock(ether->oq, 1); return n; } + if(ether->ctl!=nil) + return ether->ctl(ether,buf,n); - return netifwrite(ether, chan, buf, n); + error(Ebadctl); } - if(n > ETHERMAXTU) + if(n > ether->maxmtu) error(Etoobig); - if(n < ETHERMINTU) + if(n < ether->minmtu) error(Etoosmall); bp = allocb(n); @@ -276,18 +282,23 @@ etherbwrite(Chan* chan, Block* bp, ulong) long n; n = BLEN(bp); - ether = etherxx[chan->dev]; if(NETTYPE(chan->qid.path) != Ndataqid){ - n = netifwrite(ether, chan, bp->rp, n); + if(waserror()) { + freeb(bp); + nexterror(); + } + n = etherwrite(chan, bp->rp, n, 0); + poperror(); freeb(bp); return n; } + ether = etherxx[chan->dev]; - if(n > ETHERMAXTU){ + if(n > ether->maxmtu){ freeb(bp); - error(Ebadarg); + error(Etoobig); } - if(n < ETHERMINTU){ + if(n < ether->minmtu){ freeb(bp); error(Etoosmall); } @@ -320,7 +331,7 @@ parseether(uchar *to, char *from) int i; p = from; - for(i = 0; i < 6; i++){ + for(i = 0; i < Eaddrlen; i++){ if(*p == 0) return -1; nip[0] = *p++; @@ -340,7 +351,7 @@ etherreset(void) { Ether *ether; int i, n, ctlrno; - char name[32], buf[128]; + char name[32], buf[256]; for(ether = 0, ctlrno = 0; ctlrno < MaxEther; ctlrno++){ if(ether == 0) @@ -359,9 +370,9 @@ etherreset(void) for(i = 0; i < ether->nopt; i++){ if(strncmp(ether->opt[i], "ea=", 3)) continue; - if(parseether(ether->ea, ðer->opt[i][3]) == -1) + if(parseether(ether->ea, ðer->opt[i][3])) memset(ether->ea, 0, Eaddrlen); - } + } if(cards[n].reset(ether)) break; @@ -373,10 +384,17 @@ etherreset(void) if(ether->irq == 2 && BUSTYPE(ether->tbdf) != BusPCI) ether->irq = 9; snprint(name, sizeof(name), "ether%d", ctlrno); - intrenable(ether->irq, ether->interrupt, ether, ether->tbdf, name); + /* + * If ether->irq is 0, it is a hack to indicate no + * interrupt used by ethersink. + */ + if(ether->irq > 0) + intrenable(ether->irq, ether->interrupt, + ether, ether->tbdf, name); - i = sprint(buf, "#l%d: %s: %dMbps port 0x%luX irq %lud", - ctlrno, ether->type, ether->mbps, ether->port, ether->irq); + i = sprint(buf, "#l%d (%s): %s: %dMbps port 0x%luX irq %lud", + ctlrno, name, ether->type, ether->mbps, + ether->port, ether->irq); if(ether->mem) i += sprint(buf+i, " addr 0x%luX", PADDR(ether->mem)); if(ether->size) @@ -412,6 +430,26 @@ etherreset(void) free(ether); } +/* imported from ../pc; not ready for use yet */ +static void +ethershutdown(void) +{ + Ether *ether; + int i; + + for(i = 0; i < MaxEther; i++){ + ether = etherxx[i]; + if(ether == nil) + continue; + if(ether->shutdown == nil) { + print("#l%d: no shutdown fuction\n", i); + continue; + } + (*ether->shutdown)(ether); + } +} + + #define POLY 0xedb88320 /* really slow 32 bit crc for ethers */ diff --git a/alphapc/etherif.h b/alphapc/etherif.h index 5af59e14629aa7a477e37d4e7114b5c506400fc5..fc54938c274a90ab34aa87e271dacbc4148085da 100644 --- a/alphapc/etherif.h +++ b/alphapc/etherif.h @@ -15,10 +15,15 @@ struct Ether { uchar ea[Eaddrlen]; void (*attach)(Ether*); /* filled in by reset routine */ + void (*detach)(Ether*); /* NEW, from ../pc */ void (*transmit)(Ether*); void (*interrupt)(Ureg*, void*); long (*ifstat)(Ether*, void*, long, ulong); long (*ctl)(Ether*, void*, long); /* custom ctl messages */ +/* START NEW, from ../pc */ + void (*power)(Ether*, int); /* power on/off */ + void (*shutdown)(Ether*); /* shutdown hardware before reboot */ +/* END NEW */ void *ctlr; Queue* oq; @@ -29,6 +34,7 @@ struct Ether { extern Block* etheriq(Ether*, Block*, int); extern void addethercard(char*, int(*)(Ether*)); extern ulong ethercrc(uchar*, int); +extern int parseether(uchar*, char*); #define NEXT(x, l) (((x)+1)%(l)) #define PREV(x, l) (((x) == 0) ? (l)-1: (x)-1) diff --git a/alphapc/main.c b/alphapc/main.c index e459bc233afc5483f755ddcb98b2edb299d79b0d..611fc7f72a919f8101ec1796221eb003a0dde42b 100644 --- a/alphapc/main.c +++ b/alphapc/main.c @@ -32,6 +32,7 @@ options(void) cp = bootargs; strncpy(cp, bootconf->bootargs, BOOTARGSLEN); cp[BOOTARGSLEN-1] = 0; + /* can't print in this routine, see below in main() */ /* * Strip out '\r', change '\t' -> ' '. @@ -60,6 +61,18 @@ options(void) } } +/* debugging only */ +static void +dumpopts(void) +{ + int i; + + print("dumpopts: found /alpha/conf options at 0x%lux\n", + bootconf->bootargs); + for(i = 0; i < nconf; i++) + print("dumpopts: read %s=%s\n", confname[i], confval[i]); +} + void main(void) { @@ -80,6 +93,8 @@ main(void) trapinit(); screeninit(); printinit(); + /* it's now safe to print */ + /* dumpopts(); /* DEBUG */ kbdinit(); i8250console(); quotefmtinstall(); @@ -102,6 +117,26 @@ initfp.fpstatus = 0x68028000; schedinit(); } +/* cpu->state bits */ +enum { + Cpubootinprog = 1, /* boot in progress */ + Cpucanrestart = 2, /* restart possible */ + Cpuavail = 4, /* processor available */ + Cpuexists = 8, /* processor present */ + Cpuuserhalted = 0x10, /* user halted */ + Cpuctxtokay = 0x20, /* context valid */ + Cpupalokay = 0x40, /* PALcode valid */ + Cpupalmemokay = 0x80, /* PALcode memory valid */ + Cpupalloaded = 0x100, /* PALcode loaded */ + Cpuhaltmask = 0xff0000, /* halt request mask */ + Cpuhaltdflt = 0, + Cpuhaltsaveexit = 0x10000, + Cpuhaltcoldboot = 0x20000, + Cpuhaltwarmboot = 0x30000, + Cpuhaltstayhalted = 0x40000, + Cpumustbezero = 0xffffffffff000000, /* 24:63 -- must be zero */ +}; + /* * initialize a processor's mach structure. each processor does this * for itself. @@ -121,15 +156,16 @@ machinit(void) active.machs = 1; cpu = (Hwcpu*) ((ulong)hwrpb + hwrpb->cpuoff + n*hwrpb->cpulen); - cpu->state &= ~1; /* boot in progress - not */ -/* cpu->state |= (4<<16); /* stay halted */ + cpu->state &= ~Cpubootinprog; + if (0) + cpu->state |= Cpuhaltstayhalted; } void init0(void) { int i; - char tstr[32]; + char buf[2*KNAMELEN]; up->nerrlab = 0; @@ -147,9 +183,9 @@ init0(void) chandevinit(); if(!waserror()){ + snprint(buf, sizeof(buf), "alpha %s alphapc", conffile); + ksetenv("terminal", buf, 0); ksetenv("cputype", "alpha", 0); - sprint(tstr, "alpha %s alphapc", conffile); - ksetenv("terminal", tstr, 0); if(cpuserver) ksetenv("service", "cpu", 0); else @@ -254,15 +290,104 @@ procsave(Proc *p) mmupark(); } -/* still to do */ void -reboot(void*, void*, ulong) +setupboot(int halt) { + int n = 0; // cpu id of primary cpu, not just m->machno + Hwcpu *cpu = (Hwcpu*)((ulong)hwrpb + hwrpb->cpuoff + n*hwrpb->cpulen); + + cpu->state &= ~(Cpucanrestart | Cpuhaltmask); + cpu->state |= (halt? Cpuhaltstayhalted: Cpuhaltwarmboot); +} + +/* from ../pc */ +static void +shutdown(int ispanic) +{ + int ms, once; + + lock(&active); + if(ispanic) + active.ispanic = ispanic; + else if(m->machno == 0 && (active.machs & (1<machno)) == 0) + active.ispanic = 0; + once = active.machs & (1<machno); + active.machs &= ~(1<machno); + active.exiting = 1; + unlock(&active); + + if(once) + print("cpu%d: exiting\n", m->machno); + spllo(); + for(ms = 5*1000; ms > 0; ms -= TK2MS(2)){ + delay(TK2MS(2)); + if(active.machs == 0 && consactive() == 0) + break; + } + + if(active.ispanic && m->machno == 0) { + if(cpuserver) + delay(10000); + else + for (;;) + continue; + } else + delay(1000); +} + +/* from ../pc: */ +void +reboot(void *entry, void *code, ulong size) +{ + // writeconf(); // pass kernel environment to next kernel + shutdown(0); + + /* + * should be the only processor running now + */ + print("shutting down...\n"); + delay(200); + + splhi(); + + /* turn off buffered serial console */ + serialoq = nil; + + /* shutdown devices */ + chandevshutdown(); + +#ifdef FUTURE +{ + ulong *pdb; + /* + * Modify the machine page table to directly map the low 4MB of memory + * This allows the reboot code to turn off the page mapping + */ + pdb = m->pdb; + pdb[PDX(0)] = pdb[PDX(KZERO)]; + mmuflushtlb(PADDR(pdb)); +} + /* setup reboot trampoline function */ +{ + void (*f)(ulong, ulong, ulong) = (void*)REBOOTADDR; + + memmove(f, rebootcode, sizeof(rebootcode)); +#else + USED(entry, code, size); +#endif + + print("rebooting...\n"); +#ifdef FUTURE + /* off we go - never to return */ + (*f)(PADDR(entry), PADDR(code), size); +} +#endif + setupboot(0); // reboot, don't halt exit(0); } void -exit(int) +exit(int ispanic) { canlock(&active); active.machs &= ~(1<machno); @@ -277,9 +402,21 @@ exit(int) splhi(); delay(1000); /* give serial fifo time to finish flushing */ + if (getconf("*debug") != nil) { + USED(ispanic); + delay(60*1000); /* give us time to read the screen */ + } if(arch->coredetach) arch->coredetach(); - firmware(); + setupboot(1); // set up to halt + for (; ; ) + firmware(); + + // on PC is just: + if (0) { + shutdown(ispanic); + // arch->reset(); + } } void @@ -414,7 +551,7 @@ void memholes(void) { Bank *b, *eb; - + b = bootconf->bank; eb = b+bootconf->nbank; while(b < eb) { @@ -453,10 +590,10 @@ getconf(char *name) { int n; - for(n = 0; n < nconf; n++){ - if(cistrcmp(confname[n], name) == 0) + for(n = 0; n < nconf; n++) + if(cistrcmp(confname[n], name) == 0) { return confval[n]; - } + } return 0; } @@ -501,7 +638,7 @@ cistrcmp(char *a, char *b) for(;;){ ac = *a++; bc = *b++; - + if(ac >= 'A' && ac <= 'Z') ac = 'a' + (ac - 'A'); if(bc >= 'A' && bc <= 'Z') diff --git a/alphapc/pci.c b/alphapc/pci.c index d474f6387d17ae368a24da99a4af724f94122f0f..13d431c1a255b54dd321176caff357c5fdfcd422 100644 --- a/alphapc/pci.c +++ b/alphapc/pci.c @@ -197,15 +197,14 @@ pciscan(int bno, Pcidev** list) static void pcicfginit(void) { -/* char *p; */ + char *p; lock(&pcicfginitlock); if(pcicfgmode == -1){ pcicfgmode = 0; -/* if(p = getconf("*pcimaxdno")) - pcimaxdno = strtoul(p, 0, 0); */ -pcimaxdno = 15 /* was 20; what is correct value??? */; - + pcimaxdno = 15; /* was 20; what is correct value??? */ + if(p = getconf("*pcimaxdno")) + pcimaxdno = strtoul(p, 0, 0); pciscan(0, &pciroot); } unlock(&pcicfginitlock); diff --git a/alphapc/random.c b/alphapc/random.c index 4a74700f3c19f40c1d65430e64ddc64b5b116c67..b39dd6d15b7fef75c879bec807a082d9a76f3a08 100644 --- a/alphapc/random.c +++ b/alphapc/random.c @@ -1,138 +1 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "../port/error.h" - - -struct Rb -{ - QLock; - Rendez producer; - Rendez consumer; - ulong randomcount; - uchar buf[1024]; - uchar *ep; - uchar *rp; - uchar *wp; - uchar next; - uchar wakeme; - ushort bits; - ulong randn; -} rb; - -static int -rbnotfull(void*) -{ - int i; - - i = rb.rp - rb.wp; - return i != 1 && i != (1 - sizeof(rb.buf)); -} - -static int -rbnotempty(void*) -{ - return rb.wp != rb.rp; -} - -void -genrandom(void*) -{ - up->basepri = PriNormal; - up->priority = up->basepri; - - for(;;){ - for(;;) - if(++rb.randomcount > 100000) - break; - if(anyhigher()) - sched(); - if(!rbnotfull(0)) - sleep(&rb.producer, rbnotfull, 0); - } -} - -/* - * produce random bits in a circular buffer - */ -static void -randomclock(void) -{ - if(rb.randomcount == 0 || !rbnotfull(0)) - return; - - rb.bits = (rb.bits<<2) ^ rb.randomcount; - rb.randomcount = 0; - - rb.next++; - if(rb.next != 8/2) - return; - rb.next = 0; - - *rb.wp ^= rb.bits; - if(rb.wp+1 == rb.ep) - rb.wp = rb.buf; - else - rb.wp = rb.wp+1; - - if(rb.wakeme) - wakeup(&rb.consumer); -} - -void -randominit(void) -{ - addclock0link(randomclock, 1000/HZ); - rb.ep = rb.buf + sizeof(rb.buf); - rb.rp = rb.wp = rb.buf; - kproc("genrandom", genrandom, 0); -} - -/* - * consume random bytes from a circular buffer - */ -ulong -randomread(void *xp, ulong n) -{ - uchar *e, *p; - ulong x; - - p = xp; - - if(waserror()){ - qunlock(&rb); - nexterror(); - } - - qlock(&rb); - for(e = p + n; p < e; ){ - if(rb.wp == rb.rp){ - rb.wakeme = 1; - wakeup(&rb.producer); - sleep(&rb.consumer, rbnotempty, 0); - rb.wakeme = 0; - continue; - } - - /* - * beating clocks will be precictable if - * they are synchronized. Use a cheap pseudo - * random number generator to obscure any cycles. - */ - x = rb.randn*1103515245 ^ *rb.rp; - *p++ = rb.randn = x; - - if(rb.rp+1 == rb.ep) - rb.rp = rb.buf; - else - rb.rp = rb.rp+1; - } - qunlock(&rb); - poperror(); - - wakeup(&rb.producer); - - return n; -} +#include "../pc/random.c" diff --git a/bitsy/main.c b/bitsy/main.c index 6dce965a7685648b0f966d0af31ccca97b16ad75..5dd226a6329f7d6a56367352ba4b2819f84343ef 100644 --- a/bitsy/main.c +++ b/bitsy/main.c @@ -145,7 +145,7 @@ bootargs(ulong base) */ sp = (uchar*)base + BY2PG - sizeof(Sargs); - bootpath = pusharg("/boot"); + bootpath = pusharg("/boot/boot"); ac = 0; av[ac++] = pusharg("boot"); diff --git a/boot/bootauth.c b/boot/bootauth.c index 306195032bb3f41aceb43fc801c7a75b1d784857..07166715675d163521e7fed33c01ce5cb20a9d7b 100644 --- a/boot/bootauth.c +++ b/boot/bootauth.c @@ -13,7 +13,7 @@ authentication(int cpuflag) char *argv[16], **av; int ac; - if(access("/factotum", AEXEC) < 0){ + if(access("/boot/factotum", AEXEC) < 0){ glenda(); return; } @@ -38,8 +38,8 @@ authentication(int cpuflag) case -1: fatal("starting factotum: %r"); case 0: - exec("/factotum", av); - fatal("execing /factotum"); + exec("/boot/factotum", av); + fatal("execing /boot/factotum"); default: break; } diff --git a/boot/bootcache.c b/boot/bootcache.c index c8efd98f976a9d00e4f1888e7ce825657775a50a..b0951cbaf7ac49c6c7aaee447da8e00e34ecc6e4 100644 --- a/boot/bootcache.c +++ b/boot/bootcache.c @@ -10,7 +10,7 @@ cache(int fd) int argc, i, p[2]; char *argv[5], bd[32], buf[256], partition[64], *pp; - if(stat("/cfs", statbuf, sizeof statbuf) < 0) + if(stat("/boot/cfs", statbuf, sizeof statbuf) < 0) return fd; *partition = 0; @@ -63,9 +63,9 @@ cache(int fd) dup(p[0], 1); close(p[0]); if(fflag) - execl("/cfs", "bootcfs", "-rs", "-f", partition, 0); + execl("/boot/cfs", "bootcfs", "-rs", "-f", partition, 0); else - execl("/cfs", "bootcfs", "-s", "-f", partition, 0); + execl("/boot/cfs", "bootcfs", "-s", "-f", partition, 0); break; default: close(p[0]); diff --git a/boot/bootip.c b/boot/bootip.c index 4b943959cdbd74581b5e8aec06effea45c6f1888..c1e4e10199408a2456e1da67b0aa7f20f7e272dd 100644 --- a/boot/bootip.c +++ b/boot/bootip.c @@ -60,7 +60,7 @@ configip(void) case -1: fatal("configuring ip: %r"); case 0: - exec("/ipconfig", arg); + exec("/boot/ipconfig", arg); fatal("execing /ipconfig"); default: break; diff --git a/boot/embed.c b/boot/embed.c index c4c27eacfc4ec35b534fe493222a9ad48a469190..d14de65f50b4a38a96486f4e817f0891dfce8651 100644 --- a/boot/embed.c +++ b/boot/embed.c @@ -28,7 +28,7 @@ connectembed(void) Dir *dir; char **arg, **argp; - dir = dirstat("/paqfs"); + dir = dirstat("/boot/paqfs"); if(dir == nil) return -1; free(dir); @@ -51,7 +51,7 @@ connectembed(void) case 0: arg = malloc((bargc+5)*sizeof(char*)); argp = arg; - *argp++ = "/paqfs"; + *argp++ = "/boot/paqfs"; *argp++ = "-iv"; *argp++ = paqfile; for(i=1; i= Nfiles) + if(l->ndir >= l->mdir) panic("too many root files"); - rootdata[nroot] = contents; - d = &rootdir[nroot]; + l->data[l->ndir] = contents; + d = &l->dir[l->ndir]; strcpy(d->name, name); d->length = len; d->perm = perm; d->qid.type = 0; d->qid.vers = 0; - d->qid.path = nroot+1; + d->qid.path = ++l->ndir + l->base; if(perm & DMDIR) d->qid.type |= QTDIR; - nroot++; } /* * add a root file */ void -addrootfile(char *name, uchar *contents, ulong len) +addbootfile(char *name, uchar *contents, ulong len) { - addroot(name, contents, len, 0555); + addlist(&bootlist, name, contents, len, 0555); } /* - * add a root file + * add a root directory */ static void addrootdir(char *name) { - addroot(name, nil, 0, DMDIR|0555); + addlist(&rootlist, name, nil, 0, DMDIR|0555); } static void @@ -75,8 +104,6 @@ rootreset(void) addrootdir("proc"); addrootdir("root"); addrootdir("srv"); - - addrootfile("boot", bootcode, bootlen); /* always have a boot file */ } static Chan* @@ -85,27 +112,57 @@ rootattach(char *spec) return devattach('/', spec); } +static int +rootgen(Chan *c, char *name, Dirtab*, int, int s, Dir *dp) +{ + int t; + Dirtab *d; + Dirlist *l; + + switch((int)c->qid.path){ + case Qdir: + return devgen(c, name, rootlist.dir, rootlist.ndir, s, dp); + case Qboot: + if(s == DEVDOTDOT){ + devdir(c, (Qid){Qdir, 0, QTDIR}, "#/", 0, eve, 0555, dp); + return 1; + } + return devgen(c, name, bootlist.dir, bootlist.ndir, s, dp); + default: + if((int)c->qid.path < Qboot){ + t = c->qid.path-1; + l = &rootlist; + }else{ + t = c->qid.path - Qboot - 1; + l = &bootlist; + } + if(t >= l->ndir) + return -1; + if(s != 0) + return -1; + d = &l->dir[t]; + devdir(c, d->qid, d->name, d->length, eve, d->perm, dp); + return 1; + } + return -1; +} + static Walkqid* rootwalk(Chan *c, Chan *nc, char **name, int nname) { - return devwalk(c, nc, name, nname, rootdir, nroot, devgen); + return devwalk(c, nc, name, nname, nil, 0, rootgen); } static int rootstat(Chan *c, uchar *dp, int n) { - return devstat(c, dp, n, rootdir, nroot, devgen); + return devstat(c, dp, n, nil, 0, rootgen); } static Chan* rootopen(Chan *c, int omode) { - switch((ulong)c->qid.path) { - default: - break; - } - - return devopen(c, omode, rootdir, nroot, devgen); + return devopen(c, omode, nil, 0, devgen); } /* @@ -121,17 +178,26 @@ rootread(Chan *c, void *buf, long n, vlong off) { ulong t; Dirtab *d; + Dirlist *l; uchar *data; ulong offset = off; t = c->qid.path; switch(t){ case Qdir: - return devdirread(c, buf, n, rootdir, nroot, devgen); + case Qboot: + return devdirread(c, buf, n, nil, 0, rootgen); + } + + if(tdir[t-1]; + data = l->data[t-1]; if(offset >= d->length) return 0; if(offset+n > d->length) @@ -141,12 +207,9 @@ rootread(Chan *c, void *buf, long n, vlong off) } static long -rootwrite(Chan *c, void*, long, vlong) +rootwrite(Chan*, void*, long, vlong) { - switch((ulong)c->qid.path){ - default: - error(Egreg); - } + error(Egreg); return 0; } @@ -170,3 +233,4 @@ Dev rootdevtab = { devremove, devwstat, }; + diff --git a/port/portfns.h b/port/portfns.h index d82e93cd579d44a867e43192e1ebf99fc488c29d..1bfccea1208cf938ee0edcd5d07732bda50ce8a1 100644 --- a/port/portfns.h +++ b/port/portfns.h @@ -1,7 +1,7 @@ void accounttime(void); void addclock0link(void (*)(void), int); int addphysseg(Physseg*); -void addrootfile(char*, uchar*, ulong); +void addbootfile(char*, uchar*, ulong); Block* adjustblock(Block*, int); void alarmkproc(void*); Block* allocb(int);