M carrera/devrtc.c => carrera/devrtc.c +55 -27
@@ 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;
M pc/devvga.c => pc/devvga.c +7 -0
@@ 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;
}
M pc/memory.c => pc/memory.c +0 -2
@@ 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();
M port/netif.c => port/netif.c +43 -0
@@ 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);
+ }
+}
M port/netif.h => port/netif.h +13 -0
@@ 1,4 1,5 @@
typedef struct Etherpkt Etherpkt;
+typedef struct Netaddr Netaddr;
typedef struct Netfile Netfile;
typedef struct Netif Netif;
@@ 41,6 42,16 @@ struct Netfile
};
/*
+ * a network address
+ */
+struct Netaddr
+{
+ Netaddr *next;
+ char *addr;
+ int ref;
+};
+
+/*
* a network interface
*/
struct Netif
@@ 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);