From 895278034d4570dac2e4070d588f6e08059fa5db Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Thu, 19 Mar 1992 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1992-03-19 --- boot/boot.c | 1 - boot/nopsession.c | 76 +++--- gnot/lib.h | 6 +- port/devarp.c | 2 + port/devcons.c | 3 + port/devip.c | 1 + port/devkprof.c | 2 +- port/devlance.c | 2 + port/fault.c | 2 + port/lib.h | 6 +- port/page.c | 3 +- port/portdat.h | 2 + port/proc.c | 4 + port/stfcall.c | 1 + port/stip.c | 5 +- port/stream.c | 66 +++++- port/tcpinput.c | 52 +++- port/tcpoutput.c | 74 +++--- power/bboot.c | 591 ++++++++++++---------------------------------- power/boot.c | 477 ------------------------------------- power/l.s | 2 +- power/trap.c | 9 +- 22 files changed, 379 insertions(+), 1008 deletions(-) delete mode 100644 power/boot.c diff --git a/boot/boot.c b/boot/boot.c index dcfa7639d874ba493a0864ef703bd615104f74e1..b1be81dcd72a5cfef312423e127b101a942eacb1 100644 --- a/boot/boot.c +++ b/boot/boot.c @@ -111,7 +111,6 @@ main(int argc, char *argv[]) settime(islocal); swapproc(); - sleep(1000); sprint(cmd, "/%s/init", cputype); sprint(flags, "-%s%s", cpuflag ? "c" : "t", mflag ? "m" : ""); execl(cmd, "init", flags, 0); diff --git a/boot/nopsession.c b/boot/nopsession.c index 8178cda0f022089319c6f9f3215db4b9b3cec429..2eeff09ce50d6f04151cbf4b9b056061cac7ba8c 100644 --- a/boot/nopsession.c +++ b/boot/nopsession.c @@ -4,53 +4,55 @@ #include "../boot/boot.h" static Fcall hdr; -static char buf[4*1024]; -void -nop(int fd) +static void +rpc(int fd, int type) { - long n; + int n, l; + char buf[128], *p; - print("nop..."); - hdr.type = Tnop; + hdr.type = type; hdr.tag = NOTAG; n = convS2M(&hdr, buf); if(write(fd, buf, n) != n) - fatal("write nop"); - n = read(fd, buf, sizeof buf); - if(n==2 && buf[0]=='O' && buf[1]=='K') - n = read(fd, buf, sizeof buf); - if(n <= 0) - fatal("read nop"); - if(convM2S(buf, &hdr, n) == 0) { - print("n = %d; buf = %#.2x %#.2x %#.2x %#.2x\n", - n, buf[0], buf[1], buf[2], buf[3]); - fatal("format nop"); + fatal("write rpc"); + + print("..."); + p = buf; + l = 0; + while(l < 3) { + n = read(fd, p, 3); + if(n <= 0) + fatal("read rpc"); + if(n == 2 && l == 0 && buf[0] == 'O' && buf[1] == 'K') + continue; + p += n; + l += n; + } + if(convM2S(buf, &hdr, n) == 0){ + print("%ux %ux %ux\n", buf[0], buf[1], buf[2]); + fatal("rpc format"); + } + if(hdr.tag != NOTAG) + fatal("rpc tag not NOTAG"); + if(hdr.type == Rerror){ + print("error %s;", hdr.ename); + fatal("remote error"); } - if(hdr.type != Rnop) - fatal("not Rnop"); + if(hdr.type != type+1) + fatal("not reply"); } void -session(int fd) +nop(int fd) { - long n; + print("nop"); + rpc(fd, Tnop); +} - print("session..."); - hdr.type = Tsession; - hdr.tag = NOTAG; - n = convS2M(&hdr, buf); - if(write(fd, buf, n) != n) - fatal("write session"); - n = read(fd, buf, sizeof buf); - if(n <= 0) - fatal("read session"); - if(convM2S(buf, &hdr, n) == 0) - fatal("format session"); - if(hdr.type == Rerror){ - print("error %s;", hdr.ename); - fatal(hdr.ename); - } - if(hdr.type != Rsession) - fatal("not Rsession"); +void +session(int fd) +{ + print("session"); + rpc(fd, Tsession); } diff --git a/gnot/lib.h b/gnot/lib.h index 29a424440bde2cb38378006e3d432924d6e8bd6f..a47eababc62403d45314ba20f36101077a07c3c4 100644 --- a/gnot/lib.h +++ b/gnot/lib.h @@ -62,9 +62,9 @@ extern int print(char*, ...); */ extern long strtol(char*, char**, int); extern ulong strtoul(char*, char**, int); -extern long etext; -extern long edata; -extern long end; +extern char etext[]; +extern char edata[]; +extern char end[]; /* * Syscall data structures */ diff --git a/port/devarp.c b/port/devarp.c index dbc3e4ea3cc0a7f7db678826849237eaf1648514..8b72de81781c8dbbebcc24e645ac8d185cde3821 100644 --- a/port/devarp.c +++ b/port/devarp.c @@ -286,6 +286,8 @@ arpwrite(Chan *c, char *a, long n, ulong offset) void arpopn(Queue *q, Stream *s) { + if(Myip[Myself]) + error(Einuse); USED(q, s); } diff --git a/port/devcons.c b/port/devcons.c index 405e5c65aa2509809b9541ec4899900de42f8aec..d74bb771b819625b910aafe7349a4f43b3198464 100644 --- a/port/devcons.c +++ b/port/devcons.c @@ -240,6 +240,9 @@ echo(Rune r, char *buf, int n) case 'r': exit(); break; + case 't': + tcpdump(); + break; } }else if(r == 0x14){ ctrlt++; diff --git a/port/devip.c b/port/devip.c index 8ab322898a20266876c4eada1eeaa3341565f931..f7b397ab24b1568b81da8d8e133fcab5734b5f1b 100644 --- a/port/devip.c +++ b/port/devip.c @@ -530,6 +530,7 @@ tcpstoput(Queue *q, Block *bp) case Close_wait: qlock(tcb); tcb->sndcnt += blen(bp); + print("q %d\n", blen(bp)); if(tcb->sndq == 0) tcb->sndq = bp; else { diff --git a/port/devkprof.c b/port/devkprof.c index 4497e9f1c29088d224739175b8480a89bf6d842e..18295a2e57aae1d6d2bbfef8f30b682a40ec9194 100644 --- a/port/devkprof.c +++ b/port/devkprof.c @@ -39,7 +39,7 @@ kprofreset(void) ulong n; kprof.minpc = KTZERO; - kprof.maxpc = (ulong)&etext; + kprof.maxpc = (ulong)etext; kprof.nbuf = (kprof.maxpc-kprof.minpc) >> LRES; n = kprof.nbuf*SZ; kprof.buf = ialloc(n, 0); diff --git a/port/devlance.c b/port/devlance.c index 17a5928483fc63ef07c025abc30117a2f39ea40d..ef77b39e57ab42a9caf3a5c463b7033deb47d8d6 100644 --- a/port/devlance.c +++ b/port/devlance.c @@ -753,10 +753,12 @@ lanceup(Etherpkt *p, int len) */ if(!canqlock(e)) continue; + if(e->q==0 || e->q->next->len>Streamhi || (t!=e->type && e->type!=-1)){ qunlock(e); continue; } + if(!waserror()){ bp = allocb(len); memmove(bp->rptr, (uchar *)p, len); diff --git a/port/fault.c b/port/fault.c index c3a5d97642803135d76ba95b35f6eb15cf76f22d..1aef2270d711d768355a99e1ab2d361d2d51f9b7 100644 --- a/port/fault.c +++ b/port/fault.c @@ -66,6 +66,7 @@ fixfault(Segment *s, ulong addr, int read, int doputmmu) switch(type) { default: panic("fault"); + break; case SG_TEXT: if(pagedout(*pg)) /* Demand load */ @@ -209,6 +210,7 @@ pio(Segment *s, ulong addr, ulong soff, Page **p) ask = s->flen-soff; if(ask > BY2PG) ask = BY2PG; + n = (*devtab[c->type].read)(c, kaddr, ask, daddr); if(n != ask) error(Eioload); diff --git a/port/lib.h b/port/lib.h index 29a424440bde2cb38378006e3d432924d6e8bd6f..a47eababc62403d45314ba20f36101077a07c3c4 100644 --- a/port/lib.h +++ b/port/lib.h @@ -62,9 +62,9 @@ extern int print(char*, ...); */ extern long strtol(char*, char**, int); extern ulong strtoul(char*, char**, int); -extern long etext; -extern long edata; -extern long end; +extern char etext[]; +extern char edata[]; +extern char end[]; /* * Syscall data structures */ diff --git a/port/page.c b/port/page.c index 7648f7fd7df5cb6efaef5922a7d54202edb4c5e6..ca3f7dc379aa50a444bfc15cc193de830908e275 100644 --- a/port/page.c +++ b/port/page.c @@ -17,7 +17,6 @@ struct Ptealloc int pages; }ptealloclk; -extern long end; ulong hiaddr; static Lock pglock; @@ -115,7 +114,7 @@ iallocspan(ulong n, int align, ulong crevasse) print("ialloc bad\n"); if(palloc.addr0 == 0){ - region[Nregion-2].start = (((ulong)&end)&~KZERO) + conf.base0; + region[Nregion-2].start = (((ulong)end)&~KZERO) + conf.base0; region[Nregion-2].end = conf.base0 + (conf.npage0<state != Wakeme) panic("wakeup: state"); p->r = 0; +if((p->sched.pc&KZERO) != KZERO){ + spllo(); + panic("wakeup"); +} ready(p); } unlock(r); diff --git a/port/stfcall.c b/port/stfcall.c index e5f915394b6cd1b77013557adb4919abdd3bbc4f..a765bef950af5338ea498dc4edd2160f18903024 100644 --- a/port/stfcall.c +++ b/port/stfcall.c @@ -109,6 +109,7 @@ upstream(Queue *q, ulong len) for(bp = bl; bp->next; bp = bp->next) ; bp->flags |= S_DELIM; +if(bl->rptr[0] == 73) print("fcall Rclunk %d\n", blen(bl)); PUTNEXT(q, bl); } diff --git a/port/stip.c b/port/stip.c index 0a949633901553608324388c4f1bc7cd4286ed5b..baed0248cbb69c23d2f22d739e49307ba0f91766 100644 --- a/port/stip.c +++ b/port/stip.c @@ -405,6 +405,7 @@ ip_reassemble(int offset, Block *bp, Etherhdr *ip) ushort id; Block *bl, **l, *last, *prev; int ovlap, len, fragsize, pktposn; + int end; /* Check lance has handed us a contiguous buffer */ if(bp->next) @@ -476,7 +477,7 @@ ip_reassemble(int offset, Block *bp, Etherhdr *ip) bp->next = *l; *l = bp; - /* Check to see if suceeding segments overlap */ + /* Check to see if succeeding segments overlap */ if(bp->next) { l = &bp->next; end = BLKFRAG(bp)->foff + BLKFRAG(bp)->flen; @@ -491,7 +492,7 @@ ip_reassemble(int offset, Block *bp, Etherhdr *ip) BLKFRAG(*l)->flen -= ovlap; (*l)->rptr += ovlap; break; - } + } last = (*l)->next; freeb(*l); *l = last; diff --git a/port/stream.c b/port/stream.c index 7fd17c82fa7cd0ea2ff3022de0081ebf8260c0ce..bfa40a956765bfa0e5d267f6d61e51bf6821ef49 100644 --- a/port/stream.c +++ b/port/stream.c @@ -8,6 +8,8 @@ #include "devtab.h" #include "fcall.h" +ulong fpcs[100], refsa[100], refsf[100], apcs[100]; + enum { Nclass=4, /* number of block classes */ }; @@ -184,6 +186,9 @@ allocb(ulong size) { Block *bp; Bclass *bcp; + ulong pc; + + pc = getcallerpc(((uchar*)&size) - sizeof(size)); /* * map size to class @@ -207,6 +212,25 @@ allocb(ulong size) bcp->first = bp->next; if(bcp->first == 0) bcp->last = 0; + + if(bcp->size == 68) { + int i, hole, fnd; + fnd = 0; + hole = -1; + for(i = 0; i < 100; i++) { + if(apcs[i] == pc) { + refsa[i]++; + fnd = 1; + break; + } + if(refsa[i] == 0 && hole<0) + hole = i; + } + if(fnd == 0 && hole>=0) { + refsa[hole] = 1; + apcs[hole] = pc; + } + } qunlock(bcp); /* @@ -221,6 +245,7 @@ allocb(ulong size) if(bp->lim-bp->rptrlim, bp->rptr, size, bp->flags, bcp-bclass); + bp->pc = pc; return bp; } @@ -236,10 +261,21 @@ freeb(Block *bp) Bclass *bcp; int x; ulong pc; +int i; pc = getcallerpc(((uchar*)&bp) - sizeof(bp)); if((bp->flags&S_CLASS) >= Nclass) /* Check for double free */ panic("freeb class last(%lux) this(%lux)", bp->pc, pc); + + bcp = &bclass[bp->flags & S_CLASS]; + if(bcp->size == 68) { + for(i = 0; i < 100; i++) + if(apcs[i] == bp->pc) { + refsf[i]++; + fpcs[i] = pc; + } + } + bp->pc = pc; for(; bp; bp = nbp){ @@ -424,6 +460,7 @@ putq(Queue *q, Block *bp) int delim; lock(q); + q->pp = u->p; if(q->first) q->last->next = bp; else @@ -536,6 +573,7 @@ getq(Queue *q) Block *bp; lock(q); + q->pg = u->p; bp = q->first; if(bp) { q->first = bp->next; @@ -1038,6 +1076,7 @@ stputq(Queue *q, Block *bp) delim = 1; } else { lock(q); + q->pp = u->p; if(q->first) q->last->next = bp; else @@ -1468,9 +1507,10 @@ dumpblocks(Queue *q, char c) lock(q); for(bp = q->first; bp; bp = bp->next){ - print("%c%d%c", c, bp->wptr-bp->rptr, (bp->flags&S_DELIM)?'D':' '); - for(cp = bp->rptr; cpwptr && cprptr+10; cp++) - print(" %uo", *cp); + print("%c %c%d%c", c, bp->type == M_DATA ? 'd' : 'c', + bp->wptr-bp->rptr, (bp->flags&S_DELIM)?'D':' '); + for(cp = bp->rptr; cpwptr && cprptr+30; cp++) + print(" %.2x", *cp); print("\n"); } unlock(q); @@ -1483,18 +1523,28 @@ dumpqueues(void) int count, qcount; Block *bp; Bclass *bcp; - +int i; print("\n"); qcount = 0; for(q = qlist; q < qlist + conf.nqueue; q++, q++){ if(!(q->flag & QINUSE)) continue; qcount++; - print("%10s %ux R n %d l %d f %ux r %ux", q->info->name, q, + print("%10s %ux R n %d l %d f %ux r %ux ", + q->info->name, q, q->nb, q->len, q->flag, &(q->r)); - print(" W n %d l %d f %ux r %ux next %lux put %lux Rz %lux\n", + if(q->pg) + print("get %d %s ", q->pg->pid, q->pg->text); + if(q->pp) + print("put %d %s ", q->pp->pid, q->pp->text); + print(" W n %d l %d f %ux r %ux next %lux put %lux Rz %lux", WR(q)->nb, WR(q)->len, WR(q)->flag, &(WR(q)->r), q->next, q->put, q->rp); + if(q->pg) + print("get %d %s ", q->pg->pid, q->pg->text); + if(q->pp) + print("put %d %s ", q->pp->pid, q->pp->text); + print("\n"); dumpblocks(q, 'R'); dumpblocks(WR(q), 'W'); } @@ -1508,4 +1558,8 @@ dumpqueues(void) bcp->made, count); } print("\n"); + for(i = 0; i < 100; i++) { + if(refsa[i] != refsf[i]) + print("%d alloc %lux %d free %lux\n", refsa[i], apcs[i], refsf[i], fpcs[i]); + } } diff --git a/port/tcpinput.c b/port/tcpinput.c index 4b5969ff4804e17b5b1caae2aaf4e93ae878b39e..73917c6ab505a3381090bec4ec4de4acbb3518a7 100644 --- a/port/tcpinput.c +++ b/port/tcpinput.c @@ -42,6 +42,7 @@ tcp_input(Ipconv *ipc, Block *bp) Ipaddr source, dest; char tos; ushort length; + Block *f; DPRINT("tcp_input.\n"); @@ -290,6 +291,7 @@ process: /* Ignore segment text */ freeb(bp); break; + case Syn_received: case Established: case Finwait1: @@ -298,6 +300,13 @@ process: tcb->rcvcnt += blen(bp); if(bp) if(s->readq) { + print("bl %d ty %d\n", blen(bp), bp->rptr[0]); + for(f = bp; bp->next; f = f->next) + ; + if((f->flags&S_DELIM) == 0) { + print("No delim upstream rcp"); + f->flags |= S_DELIM; + } PUTNEXT(s->readq, bp); bp = 0; } @@ -347,7 +356,9 @@ process: break; } } - while(tcb->reseq != 0 && seq_ge(tcb->rcv.nxt, tcb->reseq->seg.seq)) { + while(tcb->reseq != 0) { + if(seq_ge(tcb->rcv.nxt, tcb->reseq->seg.seq) == 0) + break; get_reseq(tcb, &tos, &seg, &bp, &length); if(trim(tcb, &seg, &bp, &length) == 0) goto gotone; @@ -880,7 +891,8 @@ htontcp(Tcp *tcph, Block *data, Tcphdr *ph) if(data) { dlen = blen(data); - if((data = padb(data, hdrlen + TCP_PKT)) == 0) + data = padb(data, hdrlen + TCP_PKT); + if(data == 0) return 0; /* If we collected blocks delimit the end of the chain */ for(bp = data; bp->next; bp = bp->next) @@ -977,3 +989,39 @@ ntohtcp(Tcp *tcph, Block **bpp) } return hdrlen; } + +void +tcpdumpconv(Ipconv *c) +{ + if(c->tcpctl.state == Closed) + return; + + print("%s %d -> %d.%d.%d.%d/%d snd %d recv %d una %d nxt %d ptr %d wnd %d\n", + tcpstate[c->tcpctl.state], + c->psrc, + fmtaddr(c->dst), + c->pdst, + c->tcpctl.sndcnt, + c->tcpctl.rcvcnt, + c->tcpctl.snd.una, + c->tcpctl.snd.nxt, + c->tcpctl.snd.ptr, + c->tcpctl.snd.wnd); +} + +void +tcpdump(void) +{ + Ipifc *ep, *ifp; + Ipconv *cp, *ecp; + extern Ipifc *ipifc; + + ep = &ipifc[conf.ipif]; + for(ifp = ipifc; ifp < ep; ifp++) + if(strcmp(ifp->name, "TCP") == 0) { + ecp = &ifp->connections[conf.ip]; + for(cp = ifp->connections; cp < ecp; cp++) + tcpdumpconv(cp); + break; + } +} diff --git a/port/tcpoutput.c b/port/tcpoutput.c index 1bd5e5a028871efe966355349ab8b5b038d0025d..9a2da98e3b19719c7dc692136cc3c357469e727f 100644 --- a/port/tcpoutput.c +++ b/port/tcpoutput.c @@ -99,18 +99,15 @@ tcp_output(Ipconv *s) * in sndcnt but don't actually sit in the send queue, * dupb will return one less than dsize if a FIN needs to be sent. */ + dbp = 0; if(dsize != 0){ if(dupb(&dbp, sndq, sent, dsize) != dsize) { seg.flags |= FIN; dsize--; } - DPRINT("dupb: 1st char = %c\n", dbp->rptr[0]); - } else - dbp = 0; + print("dupb: %d\n", dbp->rptr[0]); + } - /* If the entire send queue will now be in the pipe, set the - * push flag - */ if(sent+dsize == qlen) seg.flags |= PSH; @@ -157,13 +154,32 @@ tcp_output(Ipconv *s) tcb->rttseq = tcb->snd.ptr; } } - DPRINT("tcp_output: ip_send s%lux a%lux w%lux u%lux\n", - seg.seq, seg.ack, seg.wnd, seg.up); - + print("snd: %d %x\n", blen(hbp), seg.seq); PUTNEXT(Ipoutput, hbp); } } +void +tcprxmit(Ipconv *s) +{ + Tcpctl *tcb; + + print("tcp! rexmit\n"); + tcb = &s->tcpctl; + qlock(tcb); + tcb->flags |= RETRAN|FORCE; + tcb->snd.ptr = tcb->snd.una; + + /* Reduce slowstart threshold to half current window */ + tcb->ssthresh = tcb->cwind / 2; + tcb->ssthresh = MAX(tcb->ssthresh,tcb->mss); + + /* Shrink congestion window to 1 packet */ + tcb->cwind = tcb->mss; + tcp_output(s); + qunlock(tcb); +} + void tcp_timeout(void *arg) { @@ -173,11 +189,17 @@ tcp_timeout(void *arg) s = (Ipconv *)arg; tcb = &s->tcpctl; - DPRINT("Timer %lux state = %d\n", s, tcb->state); + print("Timer %lux state = %d\n", s, tcb->state); switch(tcb->state){ - case Closed: - panic("tcptimeout"); + default: + tcb->backoff++; + DPRINT("tcp_timeout: retransmit %d %x\n", tcb->backoff, s); + if (tcb->backoff >= MAXBACKOFF) + close_self(s, Etimedout); + else + tcprxmit(s); + break; case Time_wait: close_self(s, 0); @@ -186,30 +208,8 @@ tcp_timeout(void *arg) case Established: if(tcb->backoff < MAXBACKOFF) tcb->backoff++; - goto retran; - default: - tcb->backoff++; - DPRINT("tcp_timeout: retransmit %d %x\n", tcb->backoff, s); - - if (tcb->backoff >= MAXBACKOFF) { - DPRINT("tcp_timeout: timeout\n"); - close_self(s, Etimedout); - } - else { - retran: - qlock(tcb); - tcb->flags |= RETRAN|FORCE; - tcb->snd.ptr = tcb->snd.una; - - /* Reduce slowstart threshold to half current window */ - tcb->ssthresh = tcb->cwind / 2; - tcb->ssthresh = MAX(tcb->ssthresh,tcb->mss); - - /* Shrink congestion window to 1 packet */ - tcb->cwind = tcb->mss; - tcp_output(s); - qunlock(tcb); - } + tcprxmit(s); + break; } } @@ -239,7 +239,7 @@ tcp_acktimer(Ipconv *s) } void -tcprcvwin(Ipconv *s) +tcprcvwin(Ipconv *s) /* Call with tcb locked */ { Tcpctl *tcb = &s->tcpctl; diff --git a/power/bboot.c b/power/bboot.c index d63030005f96044c33333a1a9f84fad2216ee5de..786b00a450d141f5ed9ab978d867ca2d1abc2343 100644 --- a/power/bboot.c +++ b/power/bboot.c @@ -1,37 +1,6 @@ #include #include - -#include - -#define DEFFILE "/mips/9power" -#define DEFSYS "bit!bootes" - -Fcall hdr; -char *scmd; -char bootfile[5*NAMELEN]; -char conffile[5*NAMELEN]; -char sys[NAMELEN]; - -char buf[4*1024]; - -int fd; -int cfd; -int efd; - -typedef -struct address { - char *name; - char *cmd; -} Address; - -Address addr[] = { - { "ross", "connect 020701005eff" }, - { "bootes", "connect 0800690203f3" }, - { "helix", "connect 080069020427" }, - { "spindle", "connect 0800690202df" }, - { "r70", "connect 08002b04265d" }, - { 0 } -}; +#include "../boot/boot.h" struct a_out_h { ulong magic; /* magic and sections */ @@ -56,399 +25,162 @@ struct a_out_h { ulong mystery; /* complete mystery */ } a_out; -/* - * predeclared - */ -int dkdial(char *); -int nonetdial(char *); -int bitdial(char *); -int readseg(int, int, long, long, int); -int readkernel(int); +typedef struct Net Net; +typedef struct Flavor Flavor; + +int printcol; + +char cputype[NAMELEN]; +char terminal[NAMELEN]; +char sys[2*NAMELEN]; +char username[NAMELEN]; +char conffile[2*NAMELEN]; +char sysname[2*NAMELEN]; +char buf[8*1024]; + +int mflag; +int fflag; +int kflag; + +int cache(int); +Method *rootserver(char*); int readconf(int); -int outin(char *, char *, int); -void prerror(char *); -void error(char *); -void boot(int, char *); +void readkernel(int); +int readseg(int, int, long, long, int); /* - * usage: 9b [-a] [server] [file] - * - * default server is `bitbootes', default file is `/sys/src/9/mips/9' + * default boot file */ +#define DEFFILE "/mips/9power" + +void main(int argc, char *argv[]) { - int i; - char *sysname; - - open("#c/cons", 0); - open("#c/cons", 1); - open("#c/cons", 1); - - sysname = argv[0]; - - argv++; - argc--; - while(argc > 0){ - if(argv[0][0] == '-'){ - argc--; - argv++; - } else - break; - } - - strcpy(sys, DEFSYS); - strcpy(bootfile, DEFFILE); - switch(argc){ - case 1: - strcpy(bootfile, argv[0]); - break; - case 2: - strcpy(bootfile, argv[0]); - strcpy(sys, argv[1]); - break; - } - - boot(0, sysname); - for(;;){ - if(fd > 0) - close(fd); - if(cfd > 0) - close(cfd); - fd = cfd = 0; - boot(1, sysname); - } -} + int fd; + Method *mp; + char cmd[64]; + char flags[6]; + int islocal; + char *bootfile; -int -bitdial(char *arg) -{ - return open("#3/bit3", ORDWR); -} + sleep(1000); -int -nonetdial(char *arg) -{ - int efd, cfd, fd; - Address *a; - static int mounted; + open("#c/cons", OREAD); + open("#c/cons", OWRITE); + open("#c/cons", OWRITE); - for(a = addr; a->name; a++){ - if(strcmp(a->name, arg) == 0) - break; - } - if(a->name == 0){ - print("can't convert nonet address to ether address\n"); - return -1; - } + ARGBEGIN{ + case 'u': + strcpy(username, ARGF()); + break; + case 'k': + kflag = 1; + break; + case 'm': + mflag = 1; + break; + case 'f': + fflag = 1; + break; + }ARGEND - if(!mounted){ - /* - * grab a lance channel, make it recognize ether type 0x900, - * and push the nonet ethernet multiplexor onto it. - */ - efd = open("#l/1/ctl", 2); - if(efd < 0){ - prerror("opening #l/1/ctl"); - return -1; - } - if(write(efd, "connect 0x900", sizeof("connect 0x900")-1)<0){ - close(efd); - prerror("connect 0x900"); - return -1; - } - if(write(efd, "push noether", sizeof("push noether")-1)<0){ - close(efd); - prerror("push noether"); - return -1; - } - if(write(efd, "config nonet", sizeof("config nonet")-1)<0){ - close(efd); - prerror("config nonet"); - return -1; - } - mounted = 1; - } + readenv("cputype", cputype, sizeof(cputype)); + readenv("terminal", terminal, sizeof(cputype)); + readenv("sysname", sysname, sizeof(sysname)); + if(argc > 1) + bootfile = argv[1]; + else + bootfile = DEFFILE; /* - * grab a nonet channel and call up the file server + * pick a method and initialize it */ - fd = open("#nnonet/2/data", 2); - if(fd < 0) { - prerror("opening #nnonet/2/data"); - return -1; - } - cfd = open("#nnonet/2/ctl", 2); - if(cfd < 0){ - close(fd); - fd = -1; - prerror("opening #nnonet/2/ctl"); - return -1; - } - if(write(cfd, a->cmd, strlen(a->cmd))<0){ - close(cfd); - close(fd); - cfd = fd = -1; - prerror(a->cmd); - return -1; - } - return fd; -} - -int -dkdial(char *arg) -{ - int fd; - char cmd[64]; - static int mounted; - - if(!mounted){ - /* - * grab the hsvme and configure it for a datakit - */ - efd = open("#h/ctl", 2); - if(efd < 0){ - prerror("opening #h/ctl"); - return -1; - } - if(write(efd, "push dkmux", sizeof("push dkmux")-1)<0){ - close(efd); - prerror("push dkmux"); - return -1; - } - if(write(efd, "config 4 256 restart dk", sizeof("config 4 256 restart dk")-1)<0){ - close(efd); - prerror("config 4 256 restart dk"); - return -1; - } - mounted = 1; - sleep(2000); /* wait for things to settle down */ - } + mp = rootserver(argc ? *argv : 0); + (*mp->config)(mp); + islocal = strcmp(mp->name, "local") == 0; /* - * grab a datakit channel and call up the file server + * connect to the root file system */ - fd = open("#k/dk/5/data", 2); - if(fd < 0) { - prerror("opening #k/dk/5/data"); - return -1; - } - cfd = open("#k/dk/5/ctl", 2); - if(cfd < 0){ - close(fd); - fd = -1; - prerror("opening #k/dk/5/ctl"); - return -1; - } - sprint(cmd, "connect %s", arg); - if(write(cfd, cmd, strlen(cmd))<0){ - close(cfd); - close(fd); - cfd = fd = -1; - prerror(cmd); - return -1; - } - return fd; -} - -void -boot(int ask, char *addr) -{ - int n, tries; - char *srvname; - - if(ask){ - outin("bootfile", bootfile, sizeof(bootfile)); - outin("server", sys, sizeof(sys)); - } - - for(tries = 0; tries < 5; tries++){ - fd = -1; - if(strncmp(sys, "bit!", 4) == 0) - fd = bitdial(srvname = &sys[4]); - else if(strncmp(sys, "dk!", 3) == 0) - fd = dkdial(srvname = &sys[3]); - else if(strncmp(sys, "nonet!", 6) == 0) - fd = nonetdial(srvname = &sys[6]); - else - fd = nonetdial(srvname = sys); - if(fd >= 0) - break; - print("can't connect, retrying...\n"); - sleep(1000); - } - if(fd < 0){ - print("can't connect\n"); - return; - } - - print("nop..."); - hdr.type = Tnop; - hdr.tag = NOTAG; - n = convS2M(&hdr, buf); - if(write(fd, buf, n) != n){ - print("n = %d\n", n); - prerror("write nop"); - return; - } - reread: - n = read(fd, buf, sizeof buf); - if(n <= 0){ - prerror("read nop"); - return; - } - if(n == 2) - goto reread; - if(convM2S(buf, &hdr, n) == 0) { - print("n = %d; buf = %.2x %.2x %.2x %.2x\n", - n, buf[0], buf[1], buf[2], buf[3]); - prerror("format nop"); - return; - } - if(hdr.type != Rnop){ - prerror("not Rnop"); - return; - } - if(hdr.tag != NOTAG){ - prerror("tag not NOTAG"); - return; - } - - print("session..."); - hdr.type = Tsession; - hdr.tag = NOTAG; - n = convS2M(&hdr, buf); - if(write(fd, buf, n) != n){ - prerror("write session"); - return; - } - n = read(fd, buf, sizeof buf); - if(n <= 0){ - prerror("read session"); - return; - } - if(convM2S(buf, &hdr, n) == 0){ - prerror("format session"); - return; - } - if(hdr.tag != NOTAG){ - prerror("tag not NOTAG"); - return; - } - if(hdr.type == Rerror){ - fprint(2, "boot: error %s\n", hdr.ename); - return; - } - if(hdr.type != Rsession){ - prerror("not Rsession"); - return; + fd = (*mp->connect)(); + if(fd < 0) + fatal("can't connect to file server"); + if(!islocal){ + nop(fd); + session(fd); + if(cfs) + fd = (*cfs)(fd); } - print("mount..."); - if(bind("/", "/", MREPL) < 0){ - prerror("bind"); - return; - } - if(mount(fd, "/", MAFTER|MCREATE, "", "") < 0){ - prerror("mount"); - return; - } + /* + * create the name space, mount the root fs + */ + if(bind("/", "/", MREPL) < 0) + fatal("bind"); + if(mount(fd, "/", MAFTER|MCREATE, "", "") < 0) + fatal("mount"); close(fd); - sprint(conffile, "/mips/conf/%s", addr); + /* + * open the configuration file and read it + * into the kernel + */ + sprint(conffile, "/mips/conf/%s", sysname); print("%s...", conffile); - while((fd = open(conffile, OREAD)) < 0){ + while((fd = open(conffile, OREAD)) < 0) outin("conffile", conffile, sizeof(conffile)); - } if(readconf(fd) < 0) - prerror("readconf"); + fatal("readconf"); close(fd); + /* + * read in real kernel + */ print("%s...", bootfile); - while((fd = open(bootfile, OREAD)) < 0){ + while((fd = open(bootfile, OREAD)) < 0) outin("bootfile", bootfile, sizeof(bootfile)); - } readkernel(fd); - prerror("couldn't read kernel"); -} - -/* - * print error - */ -void -prerror(char *s) -{ - char buf[64]; - - errstr(buf); - fprint(2, "boot: %s: %s\n", s, buf); -} - -/* - * print error and exit - */ -void -error(char *s) -{ - char buf[64]; - - errstr(buf); - fprint(2, "boot: %s: %s\n", s, buf); - exits(0); + fatal("couldn't read kernel"); } /* - * lookup the address for a system + * ask user from whence cometh the root file system */ -Address * -lookup(char *arg) +Method* +rootserver(char *arg) { - Address *a; + char prompt[256]; + char reply[64]; + Method *mp; + char *cp; + int n; - if(strcmp(arg, "?")==0 || strcmp(arg, "help")==0){ - for(a = addr; a->name; a++) - print("%s\n", a->name); - return 0; - } - for(a = addr; a->name; a++){ - if(strcmp(a->name, arg) == 0) - return a; - } - return 0; -} + mp = method; + n = sprint(prompt, "root is from (%s", mp->name); + for(mp++; mp->name; mp++) + n += sprint(prompt+n, ", %s", mp->name); + sprint(prompt+n, ")"); -/* - * read a segment into memory - */ -int -readseg(int in, int out, long inoff, long outoff, int len) -{ - long n, i; - - if(seek(in, inoff, 0) < 0){ - prerror("seeking bootfile"); - return -1; - } - if(seek(out, outoff, 0) != outoff){ - prerror("seeking #b/mem"); - return -1; - } - for(; len > 0; len -= n){ - if((n = read(in, buf, sizeof buf)) <= 0){ - prerror("reading bootfile"); - return -1; - } - if(write(out, buf, n) != n){ - prerror("writing #b/mem"); - return -1; - } + if(arg) + strcpy(reply, arg); + else + strcpy(reply, method->name); + for(;;){ + if(arg == 0 || mflag) + outin(prompt, reply, sizeof(reply)); + arg = 0; + for(mp = method; mp->name; mp++) + if(*reply == *mp->name){ + cp = strchr(reply, '!'); + if(cp) + strcpy(sys, cp+1); + return mp; + } + if(mp->name == 0) + continue; } - return 0; } -/* - * set a configuration value - */ - /* * read the configuration @@ -472,10 +204,8 @@ readconf(int fd) * write into 4 meg - 4k */ bfd = open("#b/mem", OWRITE); - if(bfd < 0){ - prerror("can't open #b/mem"); - return; - } + if(bfd < 0) + fatal("can't open #b/mem"); x = 0x80000000 | 4*1024*1024 - 4*1024; if(seek(bfd, x, 0) != x){ close(bfd); @@ -489,76 +219,69 @@ readconf(int fd) close(bfd); return 0; } + /* * read the kernel into memory and jump to it */ -int +void readkernel(int fd) { int n; int bfd; bfd = open("#b/mem", OWRITE); - if(bfd < 0){ - prerror("can't open #b/mem"); - return; - } + if(bfd < 0) + fatal("can't open #b/mem"); n = read(fd, &a_out, sizeof(a_out)); - if(n <= 0){ - prerror("can't read boot file"); - close(bfd); - return; - } + if(n <= 0) + fatal("can't read boot file"); print("\n%d", a_out.text); - if(readseg(fd, bfd, 20*4, a_out.textva, a_out.text)<0){ - prerror("can't read boot file"); - close(bfd); - return; - } + if(readseg(fd, bfd, 20*4, a_out.textva, a_out.text)<0) + fatal("can't read boot file"); print("+%d", a_out.data); - if(readseg(fd, bfd, 20*4 + a_out.text, a_out.textva + a_out.text, a_out.data)<0){ - prerror("can't read boot file"); - close(bfd); - return; - } + if(readseg(fd, bfd, 20*4 + a_out.text, a_out.textva + a_out.text, a_out.data)<0) + fatal("can't read boot file"); print("+%d", a_out.bss); close(bfd); bfd = open("#b/boot", OWRITE); - if(bfd < 0){ - prerror("can't open #b/boot"); - return; - } + if(bfd < 0) + fatal("can't open #b/boot"); print(" entry: 0x%ux\n", a_out.entryva); sleep(1000); - if(write(bfd, &a_out.entryva, sizeof a_out.entryva) != sizeof a_out.entryva){ - prerror("can't start kernel"); - close(bfd); - } - - return; + if(write(bfd, &a_out.entryva, sizeof a_out.entryva) != sizeof a_out.entryva) + fatal("can't start kernel"); } /* - * prompt and get input + * read a segment into memory */ int -outin(char *prompt, char *def, int len) +readseg(int in, int out, long inoff, long outoff, int len) { - int n; + long n, i; - do{ - print("%s[%s]: ", prompt, def); - n = read(0, buf, len); - }while(n==0); - if(n < 0) - error("can't read #c/cons; please reboot"); - if(n != 1){ - buf[n-1] = 0; - strcpy(def, buf); + if(seek(in, inoff, 0) < 0){ + warning("seeking bootfile"); + return -1; } - return n; + if(seek(out, outoff, 0) != outoff){ + warning("seeking #b/mem"); + return -1; + } + for(; len > 0; len -= n){ + if((n = read(in, buf, sizeof buf)) <= 0){ + warning("reading bootfile"); + return -1; + } + if(write(out, buf, n) != n){ + warning("writing #b/mem"); + return -1; + } + } + return 0; } + diff --git a/power/boot.c b/power/boot.c deleted file mode 100644 index 1647da788def8600d288987cc3e8cb66a55356b2..0000000000000000000000000000000000000000 --- a/power/boot.c +++ /dev/null @@ -1,477 +0,0 @@ -#include -#include -#include - -#define DEFSYS "cyc!bootes" -#define DEFFILE "/mips/9" - -Fcall hdr; -char *scmd; - -char buf[4*1024]; -char bootfile[5*NAMELEN]; -char sys[NAMELEN]; - -int printcol; /* so we can use the kernel's small print */ - -int fd; -int cfd; -int efd; -int setkey; - -/* - * predeclared - */ -int outin(char *, char *, int); -void prerror(char *); -void error(char *); -void boot(int); -int dkdial(char *); -int bitdial(char *); -int preamble(int); -void srvcreate(char*, int); -void settime(void); -void key(void); -int passwd(char*, int); -int passtokey(char*, char*, int); - -/* - * usage: 9b [-mp] [server] [file] - * - * default server is `bitbootes', default file is `/mips/9' - */ -void -main(int argc, char *argv[]) -{ - int i; - int manual=0; - - open("#c/cons", OREAD); - open("#c/cons", OWRITE); - open("#c/cons", OWRITE); - - argv++; - argc--; - - while(argc > 0){ - if(argv[0][0] == '-'){ - if(argv[0][1] == 'm') - manual = 1; - else if(argv[0][1] == 'k') - setkey = 1; - argc--; - argv++; - } else - break; - } - - strcpy(sys, DEFSYS); - strcpy(bootfile, DEFFILE); - switch(argc){ - case 1: - strcpy(bootfile, argv[0]); - break; - case 2: - strcpy(bootfile, argv[0]); - strcpy(sys, argv[1]); - break; - } - - key(); - boot(manual); - for(;;){ - if(fd > 0) - close(fd); - if(cfd > 0) - close(cfd); - fd = cfd = 0; - boot(1); - } -} - -int -bitdial(char *arg) -{ - USED(arg); - return open("#3/bit3", ORDWR); -} - -int -dkdial(char *arg) -{ - int fd; - char cmd[64]; - static int mounted; - - if(!mounted){ - /* - * grab the hsvme and configure it for a datakit - */ - efd = open("#h/ctl", ORDWR); - if(efd < 0){ - prerror("opening #h/ctl"); - return -1; - } - if(write(efd, "push dkmux", sizeof("push dkmux")-1)<0){ - close(efd); - prerror("push dkmux"); - return -1; - } - if(write(efd, "config 4 256 restart dk", sizeof("config 4 256 restart dk")-1)<0){ - close(efd); - prerror("config 4 256 restart dk"); - return -1; - } - mounted = 1; - sleep(2000); /* wait for things to settle down */ - } - - /* - * grab a datakit channel and call up the file server - */ - fd = open("#k/dk/5/data", ORDWR); - if(fd < 0) { - prerror("opening #k/dk/5/data"); - return -1; - } - cfd = open("#k/dk/5/ctl", ORDWR); - if(cfd < 0){ - close(fd); - prerror("opening #k/dk/5/ctl"); - return -1; - } - sprint(cmd, "connect %s", arg); - if(write(cfd, cmd, strlen(cmd))<0){ - close(cfd); - close(fd); - prerror(cmd); - return -1; - } - return fd; -} - -int -hotdial(char *arg) -{ - USED(arg); - return open("#H/hotrod", ORDWR); -} - -int -preamble(int fd) -{ - int n; - - print("nop..."); - hdr.type = Tnop; - hdr.tag = NOTAG; - n = convS2M(&hdr, buf); - if(write(fd, buf, n) != n){ - print("n = %d\n", n); - prerror("write nop"); - return 0; - } - reread: - n = read(fd, buf, sizeof buf); - if(n <= 0){ - prerror("read nop"); - return 0; - } - if(n == 2) - goto reread; - if(convM2S(buf, &hdr, n) == 0) { - print("n = %d; buf = %.2x %.2x %.2x %.2x\n", - n, buf[0], buf[1], buf[2], buf[3]); - prerror("format nop"); - return 0; - } - if(hdr.type != Rnop){ - prerror("not Rnop"); - return 0; - } - if(hdr.tag != NOTAG){ - prerror("tag not NOTAG"); - return 0; - } - - print("session..."); - hdr.type = Tsession; - hdr.tag = NOTAG; - n = convS2M(&hdr, buf); - if(write(fd, buf, n) != n){ - prerror("write session"); - return 0; - } - n = read(fd, buf, sizeof buf); - if(n <= 0){ - prerror("read session"); - return 0; - } - if(convM2S(buf, &hdr, n) == 0){ - prerror("format session"); - return 0; - } - if(hdr.tag != NOTAG){ - prerror("tag not NOTAG"); - return 0; - } - if(hdr.type == Rerror){ - fprint(2, "boot: error %s\n", hdr.ename); - return 0; - } - if(hdr.type != Rsession){ - prerror("not Rsession"); - return 0; - } - return 1; -} - -void -boot(int ask) -{ - int n, f, tries; - - if(ask) - outin("server", sys, sizeof(sys)); - - for(tries = 0; tries < 5; tries++){ - fd = -1; - if(strncmp(sys, "bit!", 4) == 0) - fd = bitdial(&sys[4]); - else if(strncmp(sys, "cyc!", 4) == 0) - fd = hotdial(&sys[4]); - else if(strncmp(sys, "dk!", 3) == 0) - fd = dkdial(&sys[3]); - if(fd >= 0) - break; - print("can't connect, retrying...\n"); - sleep(1000); - } - if(fd < 0){ - print("can't connect\n"); - return; - } - - if(!preamble(fd)) - return; - - srvcreate("boot", fd); - srvcreate("bootes", fd); - - print("mount..."); - if(mount(fd, "/", MAFTER|MCREATE, "", "") < 0) - error("mount"); - - settime(); - - print("success\n"); - - if(ask){ - execl("/mips/init", "init", "-mc", 0); - } else { - execl("/mips/init", "init", "-c", 0); - } - error("/mips/init"); -} - -/* - * print error - */ -void -prerror(char *s) -{ - char buf[64]; - - errstr(buf); - fprint(2, "boot: %s: %s\n", s, buf); -} - -/* - * print error and exit - */ -void -error(char *s) -{ - char buf[64]; - - errstr(buf); - fprint(2, "boot: %s: %s\n", s, buf); - exits(0); -} - -/* - * prompt and get input - */ -int -outin(char *prompt, char *def, int len) -{ - int n; - char buf[256]; - - do{ - print("%s[%s]: ", prompt, def); - n = read(0, buf, len); - }while(n==0); - if(n < 0) - error("can't read #c/cons; please reboot"); - if(n != 1){ - buf[n-1] = 0; - strcpy(def, buf); - } - return n; -} - -void -srvcreate(char *name, int fd) -{ - char *srvname; - int f; - - srvname = strrchr(name, '/'); - if(srvname) - srvname++; - else - srvname = name; - - sprint(buf, "#s/%s", srvname); - f = create(buf, 1, 0666); - if(f < 0) - error("create"); - sprint(buf, "%d", fd); - if(write(f, buf, strlen(buf)) != strlen(buf)) - error("write"); - close(f); -} - -void -settime(void) -{ - char dirbuf[DIRLEN]; - Dir dir; - int f; - - print("time..."); - /* - * set the time from the access time of the root - * of the file server - */ - f = open("#s/boot", ORDWR); - if(f < 0) - return; - if(mount(f, "/n/boot", MREPL, "", "") < 0){ - close(f); - return; - } - close(f); - if(stat("/n/boot", dirbuf) < 0) - error("stat"); - convM2D(dirbuf, &dir); - sprint(dirbuf, "%ld", dir.atime); - unmount(0, "/n/boot"); - f = open("#c/time", OWRITE); - write(f, dirbuf, strlen(dirbuf)); - close(f); -} - -void -key(void) -{ - char password[20], key[7]; - int prompt, fd; - - prompt = setkey; - fd = open("#r/nvram", ORDWR); - if(fd < 0){ - prompt = 1; - prerror("can't open nvram"); - } - if(prompt){ - do - if(passwd(password, sizeof password) < 0){ - prerror("can't read cons"); - return; - } - while(!passtokey(key, password, strlen(password))); - }else if(seek(fd, 1024+900, 0) < 0 || read(fd, key, 7) != 7){ - close(fd); - prerror("can't read key from nvram"); - } - if(setkey && (seek(fd, 1024+900, 0) < 0 || write(fd, key, 7) != 7)){ - close(fd); - prerror("can't write key to nvram"); - } - close(fd); - fd = open("#c/key", OWRITE); - if(fd < 0) - prerror("can't open key"); - else if(write(fd, key, 7) != 7) - prerror("can't write key"); - close(fd); -} - -int -passwd(char *p, int len) -{ - char c; - int i, n, fd; - - fd = open("#c/consctl", OWRITE); - if(fd < 0) - return -1; - write(fd, "rawon", 5); - Prompt: - print("password: "); - n = 0; - for(;;){ - do{ - i = read(0, &c, 1); - if(i < 0){ - close(fd); - return -1; - } - }while(i == 0); - switch(c){ - case '\n': - p[n] = '\0'; - close(fd); - print("\n"); - return 0; - case '\b': - if(n > 0) - n--; - break; - case 'u' - 'a' + 1: /* cntrl-u */ - print("\n"); - goto Prompt; - default: - if(n < len - 1) - p[n++] = c; - break; - } - } -} - -int -passtokey(char *key, char *p, int n) -{ - uchar t[10]; - int c; - - memset(t, ' ', sizeof t); - if(n < 5) - return 0; - if(n > 10) - n = 10; - strncpy((char*)t, p, n); - if(n >= 9){ - c = p[8] & 0xf; - if(n == 10) - c += p[9] << 4; - for(n = 0; n < 8; n++) - if(c & (1 << n)) - t[n] -= ' '; - } - for(n = 0; n < 7; n++) - key[n] = (t[n] >> n) + (t[n+1] << (8 - (n+1))); - return 1; -} diff --git a/power/l.s b/power/l.s index 4df247cbc45efdc21ab40a30b378d5cc62909121..ef7c241fbc327984a10d7044ec916b589212e8cd 100644 --- a/power/l.s +++ b/power/l.s @@ -151,7 +151,7 @@ TEXT gotolabel(SB), $-4 TEXT getcallerpc(SB), $0 - MOVW 4(SP), R1 + MOVW 0(SP), R1 RET TEXT gotopc(SB), $8 diff --git a/power/trap.c b/power/trap.c index dd0b58c34e900cfb9e9f8b8fed7eb5d5f8754ceb..1d3b51d25f2a25d16b404a48f259c74e8a6c89bb 100644 --- a/power/trap.c +++ b/power/trap.c @@ -340,8 +340,11 @@ dumpstack(void) if(u) for(l=(ulong)&l; lstatus; - for(i=0; i