M alphapc/devarch.c => alphapc/devarch.c +40 -4
@@ 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 = "<unknown>";
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++) {
M alphapc/devether.c => alphapc/devether.c +57 -19
@@ 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 */
M alphapc/etherif.h => alphapc/etherif.h +6 -0
@@ 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)
M alphapc/main.c => alphapc/main.c +151 -14
@@ 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<<m->machno)) == 0)
+ active.ispanic = 0;
+ once = active.machs & (1<<m->machno);
+ active.machs &= ~(1<<m->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<<m->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')
M alphapc/pci.c => alphapc/pci.c +4 -5
@@ 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);
M alphapc/random.c => alphapc/random.c +1 -138
@@ 1,138 1,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"
M bitsy/main.c => bitsy/main.c +1 -1
@@ 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");
M boot/bootauth.c => boot/bootauth.c +3 -3
@@ 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;
}
M boot/bootcache.c => boot/bootcache.c +3 -3
@@ 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]);
M boot/bootip.c => boot/bootip.c +1 -1
@@ 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;
M boot/embed.c => boot/embed.c +3 -3
@@ 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<bargc; i++)
@@ 62,7 62,7 @@ connectembed(void)
dup(p[1], 1);
close(p[0]);
close(p[1]);
- exec("/paqfs", arg);
+ exec("/boot/paqfs", arg);
fatal("can't exec paqfs");
default:
break;
M boot/local.c => boot/local.c +2 -2
@@ 58,7 58,7 @@ connectlocal(void)
char **arg, **argp;
ulong mode;
- if(stat("/kfs", statbuf, sizeof statbuf) < 0)
+ if(stat("/boot/kfs", statbuf, sizeof statbuf) < 0)
return -1;
dev = disk ? disk : bootdisk;
@@ 100,7 100,7 @@ connectlocal(void)
dup(p[1], 1);
close(p[0]);
close(p[1]);
- exec("/kfs", arg);
+ exec("/boot/kfs", arg);
fatal("can't exec kfs");
default:
break;
M boot/paq.c => boot/paq.c +1 -1
@@ 55,7 55,7 @@ connectpaq(void)
dup(p[1], 1);
close(p[0]);
close(p[1]);
- exec("/paqfs", arg);
+ exec("/boot/paqfs", arg);
fatal("can't exec paqfs");
default:
break;
M port/devroot.c => port/devroot.c +102 -38
@@ 5,61 5,90 @@
#include "fns.h"
#include "../port/error.h"
-enum{
- Qdir= 0,
+enum
+{
+ Qdir = 0,
+ Qboot = 0x1000,
- Nfiles=32, /* max root files */
+ Nrootfiles = 32,
+ Nbootfiles = 16,
};
-extern ulong bootlen;
-extern uchar bootcode[];
+typedef struct Dirlist Dirlist;
+struct Dirlist
+{
+ uint base;
+ Dirtab *dir;
+ uchar **data;
+ int ndir;
+ int mdir;
+};
-Dirtab rootdir[Nfiles] = {
- ".", {Qdir, 0, QTDIR}, 0, DMDIR|0555,
+static Dirtab rootdir[Nrootfiles] = {
+ "#/", {Qdir, 0, QTDIR}, 0, DMDIR|0555,
+ "boot", {Qboot, 0, QTDIR}, 0, DMDIR|0555,
+};
+static uchar *rootdata[Nrootfiles];
+static Dirlist rootlist =
+{
+ 0,
+ rootdir,
+ rootdata,
+ 2,
+ Nrootfiles
};
-static uchar *rootdata[Nfiles];
-static int nroot = 1;
+static Dirtab bootdir[Nbootfiles] = {
+ "boot", {Qboot, 0, QTDIR}, 0, DMDIR|0555,
+};
+static uchar *bootdata[Nbootfiles];
+static Dirlist bootlist =
+{
+ Qboot,
+ bootdir,
+ bootdata,
+ 1,
+ Nbootfiles
+};
/*
- * add a root file
+ * add a file to the list
*/
static void
-addroot(char *name, uchar *contents, ulong len, int perm)
+addlist(Dirlist *l, char *name, uchar *contents, ulong len, int perm)
{
Dirtab *d;
- if(nroot >= 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(t<Qboot)
+ l = &rootlist;
+ else{
+ t -= Qboot;
+ l = &bootlist;
}
- d = &rootdir[t-1];
- data = rootdata[t-1];
+ d = &l->dir[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,
};
+
M port/portfns.h => port/portfns.h +1 -1
@@ 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);