From 21c56d2dcf9d1a90e2a2b37188aba9e0c1f5c8aa Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sat, 25 Jul 1998 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1998-07-25 --- carrera/clock.c | 6 ++++++ carrera/dat.h | 2 ++ pc/clock.c | 6 ++++++ pc/dat.h | 4 ++-- pc/etherelnk3.c | 31 +++++++++++++++++++++---------- port/portfns.h | 1 + port/proc.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ port/segment.c | 11 +++++++++-- 8 files changed, 92 insertions(+), 14 deletions(-) diff --git a/carrera/clock.c b/carrera/clock.c index e5339e84f2b6404f15e434c7e15a4b565f749cdf..7f7af44aa2688b6c2d678fb951254bd21a15b3e8 100644 --- a/carrera/clock.c +++ b/carrera/clock.c @@ -105,6 +105,12 @@ clock(Ureg *ur) unlock(&clock0lock); } + if(m->flushmmu){ + if(up) + flushmmu(); + m->flushmmu = 0; + } + if(up == 0 || up->state != Running) return; diff --git a/carrera/dat.h b/carrera/dat.h index 8b63611a6e7af1eacd3bb2925d5386461ddcce2f..53b899558c6b288cd86f9336997e663def6235c5 100644 --- a/carrera/dat.h +++ b/carrera/dat.h @@ -114,6 +114,8 @@ struct Mach ulong delayloop; /* for the delay() routine */ int nrdy; ulong fairness; /* for runproc */ + vlong fastclock; /* last sampled value */ + int flushmmu; /* make current proc flush it's mmu state */ int pfault; int cs; diff --git a/pc/clock.c b/pc/clock.c index ea116bc6924e6a8edfc710fc9f19bcbaffd7d603..2fa498cc1ceeab515bffd70cf92af323b2c560d6 100644 --- a/pc/clock.c +++ b/pc/clock.c @@ -59,6 +59,12 @@ clockintr(Ureg* ureg, void*) iunlock(&clock0lock); } + if(m->flushmmu){ + if(up) + flushmmu(); + m->flushmmu = 0; + } + if(up == 0 || up->state != Running) return; diff --git a/pc/dat.h b/pc/dat.h index ab787ddab5d01d8619598e56c5aa3ce8e2183e8e..06521c298bd37775fc82c4227f7c00d667c33bd7 100644 --- a/pc/dat.h +++ b/pc/dat.h @@ -170,6 +170,8 @@ struct Mach int syscall; int load; int intr; + vlong fastclock; /* last sampled value */ + int flushmmu; /* make current proc flush it's mmu state */ ulong spuriousintr; ulong lastintr; @@ -187,8 +189,6 @@ struct Mach vlong mtrrfix[11]; vlong mtrrvar[32]; /* 256 max. */ - vlong fastclock; /* last sampled value */ - int stack[1]; }; diff --git a/pc/etherelnk3.c b/pc/etherelnk3.c index 1b5be6abd00e18e47c8c0234030f087e05ac80d9..f81be87440f627913d8e083f4ebbdc0e00cb6c5d 100644 --- a/pc/etherelnk3.c +++ b/pc/etherelnk3.c @@ -1632,7 +1632,7 @@ eepromdata(int port, int offset) int etherelnk3reset(Ether* ether) { - int an, busmaster, did, i, phyaddr, port, rxearly, rxstatus9, x, xcvr; + int anar, anlpar, busmaster, did, i, phyaddr, port, rxearly, rxstatus9, x, xcvr; Block *bp, **bpp; Adapter *ap; uchar ea[Eaddrlen]; @@ -1757,22 +1757,33 @@ else scanphy(port); */ phyaddr = 24; - an = miir(port, phyaddr, 0x04); - an &= miir(port, phyaddr, 0x05) & 0x03E0; - XCVRDEBUG("mii an: %uX\n", an); + anar = miir(port, phyaddr, 0x04); + anlpar = miir(port, phyaddr, 0x05) & 0x03E0; + anar &= anlpar; + miir(port, phyaddr, 0x00); + XCVRDEBUG("mii an: %uX r0:%uX r1:%uX\n", + anar, anlpar, miir(port, phyaddr, 0x00), miir(port, phyaddr, 0x01)); for(i = 0; i < ether->nopt; i++){ if(cistrcmp(ether->opt[i], "fullduplex") == 0) - an |= 0x0100; + anar |= 0x0100; else if(cistrcmp(ether->opt[i], "100BASE-TXFD") == 0) - an |= 0x0100; + anar |= 0x0100; else if(cistrcmp(ether->opt[i], "force100") == 0) - an |= 0x0080; + anar |= 0x0080; } - XCVRDEBUG("mii an: %uX\n", an); - if(an & 0x380) + XCVRDEBUG("mii anar: %uX\n", anar); + if(anar & 0x0100){ /* 100BASE-TXFD */ ether->mbps = 100; - if(an & 0x0140) setfullduplex(port); + } + else if(anar & 0x0200) /* 100BASE-T4 */ + ; + else if(anar & 0x0080) /* 100BASE-TX */ + ether->mbps = 100; + else if(anar & 0x0040) /* 10BASE-TFD */ + setfullduplex(port); + else /* 10BASE-T */ + ; break; case xcvr100BaseTX: diff --git a/port/portfns.h b/port/portfns.h index 7a1a033e8cbb02e9b4b052cda42ae786cfe82d48..d17798402c632451ca23e98915c1ea66676af18a 100644 --- a/port/portfns.h +++ b/port/portfns.h @@ -191,6 +191,7 @@ int proccounter(char *name); void procctl(Proc*); void procdump(void); void procinit0(void); +void procsegflush(Segment*); Proc* proctab(int); void procwired(Proc*); void ptclone(Chan*, int, int); diff --git a/port/proc.c b/port/proc.c index b8b9b15cbfcb1585b883d2655c4e58adb4f9761b..2053a8c306850f6b2387e0b670ec0cb589941700 100644 --- a/port/proc.c +++ b/port/proc.c @@ -921,6 +921,51 @@ procdump(void) } } +/* + * wait till all processes have flushed their mmu + * state about segement s + */ +void +procflushseg(Segment *s) +{ + int i, ns, nm, nwait; + Proc *p; + + /* + * tell all processes with this + * segment to flush their mmu's + */ + nwait = 0; + for(i=0; istate == Dead) + continue; + for(ns = 0; ns < NSEG; ns++) + if(p->seg[ns] == s){ + p->newtlb = 1; + for(nm = 0; nm < conf.nmach; nm++){ + if(MACHP(nm)->proc == p){ + MACHP(nm)->flushmmu = 1; + nwait++; + } + } + break; + } + } + + if(nwait == 0) + return; + + /* + * wait for all processors to take a clock interrupt + * and flush their mmu's + */ + for(nm = 0; nm < conf.nmach; nm++) + if(MACHP(nm) != m) + while(MACHP(nm)->flushmmu) + sched(); +} + void scheddump(void) { diff --git a/port/segment.c b/port/segment.c index 7c84bbf7f8fef3b1155949900e6145ab9bfc5b39..32cdb765739bde43714d26da342d197375521c48 100644 --- a/port/segment.c +++ b/port/segment.c @@ -460,9 +460,16 @@ mfreeseg(Segment *s, ulong start, int pages) j = 0; } out: - /* wait for others to get fix their tlb's and then free the pages */ - if((s->type&SG_TYPE) == SG_SHARED){ + /* flush this seg in all other processes */ + i = s->type&SG_TYPE; + switch(i){ + case SG_SHARED: + case SG_SHDATA: + procflushseg(s); + break; } + + /* free the pages */ for(pg = list; pg != nil; pg = list){ list = list->next; putpage(pg);