From 5d2bed487ed9c3b99fb666256a73194a0a8fcbfd Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 1 Apr 1997 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1997-04-01 --- carrera/devrtc.c | 82 ++++++++++++++++++++++++++++++++---------------- pc/devvga.c | 7 +++++ pc/memory.c | 2 -- port/netif.c | 43 +++++++++++++++++++++++++ port/netif.h | 13 ++++++++ 5 files changed, 118 insertions(+), 29 deletions(-) diff --git a/carrera/devrtc.c b/carrera/devrtc.c index c3e43047fd35dd291e20480a2cbfec57a4797405..6800a369af5b55a7738418a0d07a7fe5ff5e8a0b 100644 --- a/carrera/devrtc.c +++ b/carrera/devrtc.c @@ -98,38 +98,68 @@ bcd2binary(int reg) return (x&0xf) + 10*(x>>4); } -long -rtctime(void) +static long +_rtctime(void) { Rtc rtc; - int x; + int i, x; - /* - * read and convert from bcd - */ - x = splhi(); - rtc.sec = bcd2binary(Seconds); - rtc.min = bcd2binary(Minutes); - rtc.hour = bcd2binary(Hours); - rtc.mday = bcd2binary(Mday); - rtc.mon = bcd2binary(Month); - rtc.year = bcd2binary(Year); - splx(x); + for(i = 0; i < 10000; i++){ + x = (*(uchar*)Rtcindex)&~0x7f; + *(uchar*)Rtcindex = x|Status; + x = *(uchar*)Rtcdata; + if(x & 0x80) + continue; + + /* + * read and convert from bcd + */ + rtc.sec = bcd2binary(Seconds); + rtc.min = bcd2binary(Minutes); + rtc.hour = bcd2binary(Hours); + rtc.mday = bcd2binary(Mday); + rtc.mon = bcd2binary(Month); + rtc.year = bcd2binary(Year)+1970; + + x = (*(uchar*)Rtcindex)&~0x7f; + *(uchar*)Rtcindex = x|Status; + x = *(uchar*)Rtcdata; + if((x & 0x80) == 0) + break; + } - /* - * the world starts jan 1 1970 - */ - if(rtc.year < 70) - rtc.year += 2000; - else - rtc.year += 1900; return rtc2sec(&rtc); } +static Lock rtlock; + +long +rtctime(void) +{ + int i; + long t, ot; + + ilock(&rtlock); + + /* loop till we get two reads in a row the same */ + t = _rtctime(); + for(i = 0; i < 100; i++){ + ot = t; + t = _rtctime(); + if(ot == t) + break; + } + if(i == 100) print("we are boofheads\n"); + + iunlock(&rtlock); + + return t; +} + static long rtcread(Chan *c, void *buf, long n, ulong offset) { - ulong t, ot; + ulong t; uchar *f, *to, *e; if(c->qid.path & CHDIR) @@ -137,11 +167,9 @@ rtcread(Chan *c, void *buf, long n, ulong offset) switch(c->qid.path){ case Qrtc: + qlock(&rtclock); t = rtctime(); - do{ - ot = t; - t = rtctime(); /* make sure there's no skew */ - }while(t != ot); + qunlock(&rtclock); n = readnum(offset, buf, n, t, 12); return n; case Qnvram: @@ -204,7 +232,7 @@ rtcwrite(Chan *c, void *buf, long n, ulong offset) binary2bcd(Hours, rtc.hour); binary2bcd(Mday, rtc.mday); binary2bcd(Month, rtc.mon); - binary2bcd(Year, rtc.year); + binary2bcd(Year, rtc.year-1970); splx(s); return n; diff --git a/pc/devvga.c b/pc/devvga.c index 5ee904a10ddca4174e8f32504f89c3d7c5805b49..3bb0ac6043f1d9ab123cc8225ba4924bdca675e0 100644 --- a/pc/devvga.c +++ b/pc/devvga.c @@ -34,6 +34,7 @@ extern Cursor curs; /* barf */ Bitmap gscreen; Lock palettelock; /* access to DAC registers */ Cursor curcursor; /* current cursor */ +static Lock vgaxlock; /* access to index registers */ /* vga screen */ extern QLock screenlock; @@ -431,6 +432,7 @@ vgaxi(long port, uchar index) { uchar data; + ilock(&vgaxlock); switch(port){ case Seqx: @@ -464,8 +466,10 @@ vgaxi(long port, uchar index) break; default: + iunlock(&vgaxlock); return -1; } + iunlock(&vgaxlock); return data & 0xFF; } @@ -473,6 +477,7 @@ vgaxi(long port, uchar index) int vgaxo(long port, uchar index, uchar data) { + ilock(&vgaxlock); switch(port){ case Seqx: @@ -502,8 +507,10 @@ vgaxo(long port, uchar index, uchar data) break; default: + iunlock(&vgaxlock); return -1; } + iunlock(&vgaxlock); return 0; } diff --git a/pc/memory.c b/pc/memory.c index 2a0ada0ca7a03beb42a8acf28e3ce7e5b0287d52..4bd05a6ba44833a1d11627d9bcbebc8cf67d5eec 100644 --- a/pc/memory.c +++ b/pc/memory.c @@ -74,7 +74,6 @@ static RMap rmapumbrw = { &mapumbrw[7], }; -#define notdef #ifdef notdef void dumpmembank(void) @@ -438,7 +437,6 @@ meminit(ulong maxmem) mmuflushtlb(PADDR(m->pdb)); umbscan(); -dumpmembank(); ramscan(maxmem); upainit(); diff --git a/port/netif.c b/port/netif.c index 22fb1292fed431706404353aaa03b7e88640dc92..b63d018141e5f441f900494a95ca303f3ddf003a 100644 --- a/port/netif.c +++ b/port/netif.c @@ -9,6 +9,7 @@ static int netown(Netfile*, char*, int); static int openfile(Netif*, int); static char* matchtoken(char*, char*); +static void netmulti(Netif*, char*, int); /* * set up a new network interface @@ -234,6 +235,10 @@ netifwrite(Netif *nif, Chan *c, void *a, long n) nif->prom++; if(nif->prom == 1 && nif->promiscuous != nil) nif->promiscuous(nif->arg, 1); + } else if(p = matchtoken(buf, "addmulti")){ + netmulti(nif, p, 1); + } else if(p = matchtoken(buf, "remmulti")){ + netmulti(nif, p, 0); } qunlock(nif); return n; @@ -444,3 +449,41 @@ nhgets(void *p) a = p; return (a[0]<<8)|(a[1]<<0); } + +/* called with nif locked */ +static void +netmulti(Netif *nif, char *addr, int add) +{ + Netaddr **l, *ap; + + if(nif->multicast == nil) + return; + + l = &nif->maddr; + for(ap = *l; ap; ap = *l){ + if(strcmp(addr, ap->addr) == 0) + break; + l = &ap->next; + } + + if(add){ + if(ap == 0){ + ap = smalloc(sizeof(*ap)); + ap->addr = smalloc(strlen(addr)+1); + strcpy(ap->addr, addr); + ap->next = nif->maddr; + ap->ref = 1; + nif->maddr = ap; + } else { + ap->ref++; + } + if(ap->ref == 1) + nif->multicast(nif->arg, addr, 1); + } else { + if(ap == 0 || ap->ref == 0) + return; + ap->ref--; + if(ap->ref == 0) + nif->multicast(nif->arg, addr, 0); + } +} diff --git a/port/netif.h b/port/netif.h index 4344cc934a764a37285556c267be4099e61cfd66..8d22fdc4f168fe933431c84dd36a390a46b2687c 100644 --- a/port/netif.h +++ b/port/netif.h @@ -1,4 +1,5 @@ typedef struct Etherpkt Etherpkt; +typedef struct Netaddr Netaddr; typedef struct Netfile Netfile; typedef struct Netif Netif; @@ -40,6 +41,16 @@ struct Netfile Queue *in; /* input buffer */ }; +/* + * a network address + */ +struct Netaddr +{ + Netaddr *next; + char *addr; + int ref; +}; + /* * a network interface */ @@ -57,6 +68,7 @@ struct Netif int alen; /* address length */ uchar addr[Nmaxaddr]; uchar bcast[Nmaxaddr]; + Netaddr *maddr; /* multicast addresses */ int prom; /* number of promiscuous opens */ int all; /* number of -1 multiplexors */ @@ -74,6 +86,7 @@ struct Netif /* routines for touching the hardware */ void *arg; void (*promiscuous)(void*, int); + void (*multicast)(void*, char*, int); }; void netifinit(Netif*, char*, int, ulong);