From 98c387c2baab2f0f8bda32ad6623ba0eab985384 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 29 Oct 1991 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1991-10-29 --- pc/devfloppy.c | 4 + pc/fns.h | 2 + pc/main.c | 11 +++ port/devarp.c | 203 ++++++++++++++++++------------------------------- port/devip.c | 7 +- port/ipdat.h | 7 +- port/stip.c | 7 +- 7 files changed, 101 insertions(+), 140 deletions(-) diff --git a/pc/devfloppy.c b/pc/devfloppy.c index d0984cd7d591dd7ac728f08a520db90cbe222aaa..6f08484c335940b79bf703bf08787b0e4c7c3fd0 100644 --- a/pc/devfloppy.c +++ b/pc/devfloppy.c @@ -455,6 +455,10 @@ floppywrite(Chan *c, void *a, long n) } else if(SNCMP(aa, "reset") == 0){ fl.confused = 1; floppyon(dp); + } else if(SNCMP(aa, "fast") == 0){ + cpuspeed(1); + } else if(SNCMP(aa, "slow") == 0){ + cpuspeed(0); } qunlock(&fl); break; diff --git a/pc/fns.h b/pc/fns.h index 0bb3cb767d5b3c49b625f5257409efb6bd004006..6161e8a9533abeefcbaaaefb430976d3780d4abf 100644 --- a/pc/fns.h +++ b/pc/fns.h @@ -5,6 +5,7 @@ void meminit(void); void clock(Ureg*); void clockinit(void); void config(int); +int cpuspeed(int); void delay(int); void dmaend(int); long dmasetup(int, void*, long, int); @@ -29,6 +30,7 @@ void mmuinit(void); int modem(int); void outb(int, int); void outss(int, void*, int); +int pmuwrbit(int, int, int); void prhex(ulong); void procrestore(Proc*, uchar*); void procsave(uchar*, int); diff --git a/pc/main.c b/pc/main.c index 2465a51cb8d35dd972d166858b06e0b4bc5be511..8d3bdab0f117a9bf5801ff6ce5b0a3950eed7a2c 100644 --- a/pc/main.c +++ b/pc/main.c @@ -476,6 +476,17 @@ modem(int onoff) return pmuwrbit(1, 1^onoff, 5); } +/* + * CPU speed + * onoff == 0 means 2 MHZ + * onoff == 1 means 20 MHZ + */ +int +cpuspeed(int speed) +{ + return pmuwrbit(0, speed, 0); +} + void buzz(int f, int d) { diff --git a/port/devarp.c b/port/devarp.c index a893dd736fb6fa52dc7d625d47600a8841c3955f..b984303b490b4a98421df07fb853b0910fbd1a04 100644 --- a/port/devarp.c +++ b/port/devarp.c @@ -9,36 +9,42 @@ #include "devtab.h" +#define ARP_FREE 0 +#define ARP_OK 1 +#define ARP_ASKED 2 +#define ARP_TEMP 0 +#define ARP_PERM 1 +#define Arphashsize 32 +#define ARPHASH(p) arphash[((p[2]^p[3])%Arphashsize)] + +typedef struct Arpcache Arpcache; +struct Arpcache { + uchar status; + uchar type; + uchar eip[4]; + uchar et[6]; + Arpcache *hash; + Arpcache **hashhd; + Arpcache *frwd; + Arpcache *prev; +}; + Arpstats arpstats; Arpcache *arplruhead, *arplrutail; Arpcache *arp, **arphash; Queue *Servq; +Lock larphash; + +void arpiput(Queue *, Block *); +void arpoput(Queue *, Block *); +void arpopn(Queue *, Stream *); +void arpcls(Queue *); +void arpenter(Arpentry*, int); +void arpflush(void); +int arpdelete(char*); +void arplinkhead(Arpcache*); +int arplookup(uchar*, uchar*); -typedef struct Arpq Arpq; -struct Arpq -{ - uchar ip[4]; - uchar *etheraddr; - Block *bp; - Queue *put; - ulong time; - Arpq *next; -}; - -struct arpalloc -{ - Lock; - Lock list; - Lock hash; - Arpq *free; - Arpq *head; - Arpq *tail; -}arpalloc; - -void arpiput(Queue *, Block *); -void arpoput(Queue *, Block *); -void arpopn(Queue *, Stream *); -void arpcls(Queue *); Qinfo arpinfo = { arpiput, arpoput, arpopn, arpcls, "arp" }; #define ARP_ENTRYLEN 50 @@ -253,8 +259,6 @@ arpwrite(Chan *c, char *a, long n, ulong offset) void arpopn(Queue *q, Stream *s) { - if(!Servq) - Servq = RD(q); } void @@ -273,7 +277,40 @@ arpiput(Queue *q, Block *bp) void arpoput(Queue *q, Block *bp) { - PUTNEXT(q, bp); + uchar ip[4]; + Etherhdr *eh; + + if(bp->type != M_DATA) { + if(Servq == 0 && streamparse("arpd", bp)) { +print("setting arp channel\n"); + Servq = RD(q); + freeb(bp); + } + else + PUTNEXT(q, bp); + return; + } + + if(!Servq) { + print("arp: No server, packet dropped\n"); + freeb(bp); + return; + } + + eh = (Etherhdr *)bp->rptr; + iproute(eh->dst, ip); + + /* Send downstream to the ethernet */ + if(arplookup(ip, eh->d)) { +print("arp hit %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]); + PUTNEXT(q, bp); + return; + } +print("arp miss %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]); + + /* Return the packet to the arp server for address resolution */ + memmove(eh->d, ip, sizeof(ip)); + PUTNEXT(Servq, bp); } int @@ -281,77 +318,19 @@ arplookup(uchar *ip, uchar *et) { Arpcache *ap; - lock(&arpalloc.hash); + lock(&larphash); for(ap = ARPHASH(ip); ap; ap = ap->hash) { if(ap->status == ARP_OK && memcmp(ap->eip, ip, sizeof(ap->eip)) == 0) { memmove(et, ap->et, sizeof(ap->et)); arplinkhead(ap); - unlock(&arpalloc.hash); + unlock(&larphash); arpstats.hit++; return 1; } } - unlock(&arpalloc.hash); - return 0; -} - -void -arpsendpkt(uchar *unroutedip, uchar *ether, Queue *put, Block *bp) -{ - Arpq *aq; - Block *nbp; - uchar ip[4]; - - if(!Servq) { - print("arp: No server\n"); - freeb(bp); - return; - } - - iproute(unroutedip, ip); - if(arplookup(ip, ether)) { -print("hit %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]); - PUTNEXT(put, bp); - return; - } -print("miss %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]); - - /* Send the request out to the user level arp daemon */ - nbp = allocb(sizeof(ip)); - memmove(nbp->rptr, ip, sizeof(ip)); - nbp->wptr += sizeof(ip); - nbp->flags |= S_DELIM; - PUTNEXT(Servq, nbp); arpstats.miss++; - - lock(&arpalloc); - if(aq = arpalloc.free) - arpalloc.free = aq->next; - unlock(&arpalloc); - - if(aq == 0) { - freeb(bp); - return; - } - - /* Stash the work away until the arp completes or times out */ - memmove(aq->ip, ip, sizeof(aq->ip)); - aq->etheraddr = ether; - aq->bp = bp; - aq->put = put; - aq->time = MACHP(0)->ticks; - - lock(&arpalloc.list); - if(arpalloc.head) { - arpalloc.tail->next = aq; - arpalloc.tail = aq; - } - else { - arpalloc.tail = aq; - arpalloc.head = aq; - } - aq->next = 0; - unlock(&arpalloc.list); + unlock(&larphash); + return 0; } void @@ -371,7 +350,7 @@ arpenter(Arpentry *ape, int type) /* Update an entry if we have one already */ l = &ARPHASH(ape->ipaddr); - lock(&arpalloc.hash); + lock(&larphash); for(ap = *l; ap; ap = ap->hash) { if(ap->status == ARP_OK && memcmp(ap->eip, ape->ipaddr, sizeof(ap->eip)) == 0) { if(ap->type != ARP_PERM) { @@ -379,7 +358,7 @@ arpenter(Arpentry *ape, int type) memmove(ap->et, ape->etaddr, sizeof(ap->et)); ap->status = ARP_OK; } - unlock(&arpalloc.hash); + unlock(&larphash); return; } } @@ -390,7 +369,7 @@ arpenter(Arpentry *ape, int type) if(!ap) { print("arp: too many permanent entries\n"); - unlock(&arpalloc.hash); + unlock(&larphash); return; } @@ -408,43 +387,11 @@ arpenter(Arpentry *ape, int type) ap->status = ARP_OK; memmove(ap->eip, ape->ipaddr, sizeof(ape->ipaddr)); memmove(ap->et, ape->etaddr, sizeof(ape->etaddr)); - ap->ip = nhgetl(ap->eip); ap->hashhd = l; ap->hash = *l; *l = ap; arplinkhead(ap); - unlock(&arpalloc.hash); - pusharpq(); -} - -void -pusharpq(void) -{ - int sent; - Arpq *aq, *prev; - -loop: prev = 0; - lock(&arpalloc.list); - for(aq = arpalloc.head; aq; aq = aq->next) { - if(arplookup(aq->ip, aq->etheraddr)) { - if(prev) - prev->next = aq->next; - else - arpalloc.head = 0; - if(aq->next == 0) - arpalloc.tail = prev; - unlock(&arpalloc.list); - PUTNEXT(aq->put, aq->bp); - - lock(&arpalloc); - aq->next = arpalloc.free; - arpalloc.free = aq; - unlock(&arpalloc); - goto loop; - } - prev = aq; - } - unlock(&arpalloc.list); + unlock(&larphash); } int @@ -464,14 +411,14 @@ arpdelete(char *addr) ptr = strchr(ptr, ':')+1; } - lock(&arpalloc.hash); + lock(&larphash); for(ap = arplruhead; ap; ap = ap->frwd) { if(memcmp(ap->et, ptr, sizeof(ap->et)) == 0) { ap->status = ARP_FREE; break; } } - unlock(&arpalloc.hash); + unlock(&larphash); } void diff --git a/port/devip.c b/port/devip.c index eddb6518524cdfb7790167887b503b604bc614b4..e93b5c897b90d665eb195ed9c5d0a99cc8771c26 100644 --- a/port/devip.c +++ b/port/devip.c @@ -176,14 +176,14 @@ ipopen(Chan *c, int omode) error(Ebadarg); break; case iplistenqid: - if(cp->stproto != &tcpinfo && - cp->stproto != &ilinfo) + if(cp->stproto != &tcpinfo && cp->stproto != &ilinfo) error(Eprotonosup); if(cp->backlog == 0) cp->backlog = 3; streamopen(c, &ipinfo); + if(c->stream->devq->next->info != cp->stproto) pushq(c->stream, cp->stproto); @@ -196,6 +196,7 @@ ipopen(Chan *c, int omode) break; case Sdataqid: streamopen(c, &ipinfo); + if(c->stream->devq->next->info != cp->stproto) pushq(c->stream, cp->stproto); @@ -207,6 +208,7 @@ ipopen(Chan *c, int omode) break; case Sctlqid: streamopen(c, &ipinfo); + if(c->stream->devq->next->info != cp->stproto) pushq(c->stream, cp->stproto); break; @@ -697,6 +699,7 @@ print("listen awoke\n"); new->newcon = 0; c->qid.path = CHDIR|STREAMQID(new-base, ipchanqid); devwalk(c, "ctl", 0, 0, streamgen); + streamopen(c, &ipinfo); pushq(c->stream, new->stproto); new->ref--; diff --git a/port/ipdat.h b/port/ipdat.h index 85bd7fde380cebdd468cbc44455e5e686c67b91b..7f9f0741f4f255287e67a5dc12d6320ebc77cb40 100644 --- a/port/ipdat.h +++ b/port/ipdat.h @@ -429,11 +429,6 @@ Block *btrim(Block*, int, int); Block *ip_reassemble(int, Block*, Etherhdr*); Ipconv *portused(Ipconv *, Port); Port nextport(Ipconv *, Port); -void arpenter(Arpentry*, int); -void arpflush(void); -int arpdelete(char*); -void pusharpq(void); -void arplinkhead(Arpcache*); Fragq *ipfragallo(void); void ipfragfree(Fragq*); void iproute(uchar*, uchar*); @@ -486,7 +481,6 @@ void tcp_acktimer(void *); Ipconv *ipclonecon(Chan *); void iplisten(Chan *, Ipconv *, Ipconv *); void iloutoforder(Ipconv*, Ilhdr*, Block*); -void arpsendpkt(uchar*, uchar*, Queue*, Block*); #define fmtaddr(xx) (xx>>24)&0xff,(xx>>16)&0xff,(xx>>8)&0xff,xx&0xff #define MIN(a, b) ((a) < (b) ? (a) : (b)) @@ -508,4 +502,5 @@ extern Qinfo tcpinfo; extern Qinfo ipinfo; extern Qinfo udpinfo; extern Qinfo ilinfo; +extern Qinfo arpinfo; extern Queue *Ipoutput; diff --git a/port/stip.c b/port/stip.c index 9d022ff6325799658599784acedb4195350589a8..2045b17ed5998a2afcfa99fb1bb99c6537ec9111 100644 --- a/port/stip.c +++ b/port/stip.c @@ -198,9 +198,9 @@ ipetheroput(Queue *q, Block *bp) eh->cksum[1] = 0; hnputs(eh->cksum, ip_csum(&eh->vihl)); - /* Finally put in the ethernet level information */ + /* Finally put in the type and pass down to the arp layer */ hnputs(eh->type, ET_IP); - arpsendpkt(eh->dst, eh->d, Etherq, bp); + PUTNEXT(Etherq, bp); return; } @@ -263,9 +263,8 @@ ipetheroput(Queue *q, Block *bp) feh->cksum[1] = 0; hnputs(feh->cksum, ip_csum(&feh->vihl)); nb->flags |= S_DELIM; - arpsendpkt(feh->dst, feh->d, Etherq, nb); + PUTNEXT(Etherq, nb); } - drop: freeb(bp); }