M pc/devether.c => pc/devether.c +44 -0
@@ 94,6 94,46 @@ etherwstat(Chan *c, char *dp)
netifwstat(ether[c->dev], c, dp);
}
+void
+etherrloop(Ether *ctlr, Etherpkt *pkt, long len)
+{
+ ushort type;
+ Netfile *f, **fp, **ep;
+
+ type = (pkt->type[0]<<8)|pkt->type[1];
+ ep = &ctlr->f[Ntypes];
+ for(fp = ctlr->f; fp < ep; fp++){
+ f = *fp;
+ if(f && (f->type == type || f->type < 0)){
+ switch(qproduce(f->in, pkt->d, len)){
+
+ case -1:
+ print("etherrloop overflow\n");
+ break;
+
+ case -2:
+ print("etherrloop memory\n");
+ break;
+ }
+ }
+ }
+}
+
+static int
+etherwloop(Ether *ctlr, Etherpkt *pkt, long len)
+{
+ int s, different;
+
+ different = memcmp(pkt->d, pkt->s, sizeof(pkt->s));
+ if(different && memcmp(pkt->d, ctlr->bcast, sizeof(pkt->d)))
+ return 0;
+
+ s = splhi();
+ etherrloop(ctlr, pkt, len);
+ splx(s);
+ return !different;
+}
+
long
etherwrite(Chan *c, void *buf, long n, ulong offset)
{
@@ 107,6 147,9 @@ etherwrite(Chan *c, void *buf, long n, ulong offset)
if(NETTYPE(c->qid.path) != Ndataqid)
return netifwrite(ctlr, c, buf, n);
+ if(etherwloop(ctlr, buf, n))
+ return n;
+
qlock(&ctlr->tlock);
if(waserror()){
qunlock(&ctlr->tlock);
@@ 204,6 247,7 @@ etherreset(void)
ether[ctlrno] = ctlr;
ctlr = 0;
+ break;
}
}
if(ctlr)
M pc/ether8003.c => pc/ether8003.c +0 -5
@@ 57,10 57,6 @@ static int intrmap[] = {
9, 3, 5, 7, 10, 11, 15, 4,
};
-static uchar debugea[6] = {
- 0x00, 0x60, 0x8c, 0x00, 0x1a, 0x42,
-};
-
/*
* Get configuration parameters, enable memory.
* There are opportunities here for buckets of code.
@@ 188,7 184,6 @@ reset(Ether *ether)
* ethernet address.
*/
dp8390reset(ether);
-memmove(ether->ea, debugea, 6);
dp8390setea(ether);
return 0;
M pc/ether8390.c => pc/ether8390.c +28 -11
@@ 446,10 446,7 @@ receive(Ether *ether)
for(fp = ether->f; fp < ep; fp++) {
f = *fp;
if(f && (f->type == type || f->type < 0))
-{
-print("Q%d|", len);
qproduce(f->in, ðer->rpkt, len);
-}
}
}
@@ 473,10 470,11 @@ istxavail(void *arg)
}
static long
-write(Ether *ether, void *buf, long n)
+write(Ether *ether, void *buf, long len)
{
Dp8390 *dp8390;
ulong port;
+ Etherpkt *pkt;
dp8390 = ether->private;
port = dp8390->dp8390;
@@ 486,18 484,38 @@ write(Ether *ether, void *buf, long n)
print("dp8390: transmitter jammed\n");
return 0;
}
- ether->tlen = n;
+ ether->tlen = len;
+ /*
+ * If it's a shared-memory interface, copy the packet
+ * directly to the shared-memory area. Otherwise, copy
+ * it to a staging buffer so the I/O-port write can be
+ * done in one.
+ */
if(dp8390->ram)
- memmove((void*)(ether->mem+dp8390->tstart*Dp8390BufSz), buf, n);
+ pkt = (Etherpkt*)(ether->mem+dp8390->tstart*Dp8390BufSz);
else
- dp8390write(dp8390, dp8390->tstart*Dp8390BufSz, buf, n);
+ pkt = ðer->tpkt;
+ memmove(pkt, buf, len);
+
+ /*
+ * Give the packet a source address and make sure it
+ * is of minimum length.
+ */
+ memmove(pkt->s, ether->ea, sizeof(ether->ea));
+ if(len < ETHERMINTU){
+ memset(pkt->d+len, 0, ETHERMINTU-len);
+ len = ETHERMINTU;
+ }
+
+ if(dp8390->ram == 0)
+ dp8390write(dp8390, dp8390->tstart*Dp8390BufSz, pkt, len);
- dp8390outb(port+Tbcr0, n & 0xFF);
- dp8390outb(port+Tbcr1, (n>>8) & 0xFF);
+ dp8390outb(port+Tbcr0, len & 0xFF);
+ dp8390outb(port+Tbcr1, (len>>8) & 0xFF);
dp8390outb(port+Cr, Page0|RDMAabort|Txp|Sta);
- return n;
+ return len;
}
static void
@@ 551,7 569,6 @@ interrupt(Ether *ether)
*/
dp8390outb(port+Imr, 0x00);
while(isr = dp8390inb(port+Isr)){
-print("I%2.2ux|", isr);
if(isr & Ovw){
overflow(ether);
M port/devcons.c => port/devcons.c +2 -5
@@ 654,11 654,8 @@ consread(Chan *c, void *buf, long n, ulong offset)
return n;
case Qswap:
- k = 0;
- for(i = 0; i < NCOLOR; i++)
- k += palloc.freecol[i];
-
- sprint(tmp, "%d/%d memory %d/%d swap\n", palloc.user-k,
+ sprint(tmp, "%d/%d memory %d/%d swap\n",
+ palloc.user-palloc.freecount,
palloc.user, conf.nswap-swapalloc.free, conf.nswap);
return readstr(offset, buf, n, tmp);
M port/page.c => port/page.c +28 -28
@@ 29,7 29,7 @@ pageinit(void)
p->next = p+1;
p->pa = palloc.p0;
p->color = color;
- palloc.freecol[color]++;
+ palloc.freecount++;
color = (color+1)%NCOLOR;
palloc.p0 += BY2PG;
palloc.np0--;
@@ 40,7 40,7 @@ pageinit(void)
p->next = p+1;
p->pa = palloc.p1;
p->color = color;
- palloc.freecol[color]++;
+ palloc.freecount++;
color = (color+1)%NCOLOR;
palloc.p1 += BY2PG;
palloc.np1--;
@@ 70,18 70,17 @@ newpage(int clear, Segment **s, ulong va)
KMap *k;
int i, hw, dontalloc, color;
-retry:
- lock(&palloc);
+ lock(&palloc);
+retry:
color = getpgcolor(va);
hw = swapalloc.highwater;
for(;;) {
- if(palloc.freecol[color] > hw/NCOLOR)
+ if(palloc.freecount > hw)
break;
- if(up->kp && palloc.freecol[color] > 0)
+ if(up->kp && palloc.freecount > 0)
break;
- palloc.wanted++;
unlock(&palloc);
dontalloc = 0;
if(s && *s) {
@@ 89,17 88,17 @@ retry:
*s = 0;
dontalloc = 1;
}
- qlock(&palloc.pwait[color]); /* Hold memory requesters here */
+ qlock(&palloc.pwait); /* Hold memory requesters here */
while(waserror()) /* Ignore interrupts */
;
kickpager();
- tsleep(&palloc.r[color], ispages, (void*)color, 1000);
+ tsleep(&palloc.r, ispages, 0, 1000);
poperror();
- qunlock(&palloc.pwait[color]);
+ qunlock(&palloc.pwait);
/*
* If called from fault and we lost the segment from
@@ 111,15 110,18 @@ retry:
return 0;
lock(&palloc);
- palloc.wanted--;
}
+ /* First try for out colour */
for(p = palloc.head; p; p = p->next)
if(p->color == color)
break;
- if(p == 0)
- panic("newpage");
+ if(p == 0) {
+ p = palloc.head;
+ memset(p->cachectl, PG_DATFLUSH, sizeof(p->cachectl));
+ p->color = color;
+ }
if(p->prev)
p->prev->next = p->next;
@@ 132,12 134,15 @@ retry:
palloc.tail = p->prev;
- palloc.freecol[color]--;
+ palloc.freecount--;
unlock(&palloc);
lock(p);
if(p->ref != 0) { /* lookpage has priority on steal */
unlock(p);
+ print("stolen\n");
+ lock(&palloc);
+ palloc.freecount++;
goto retry;
}
@@ 161,17 166,13 @@ retry:
int
ispages(void *p)
{
- int color;
-
- color = (int)p;
- return palloc.freecol[color] >= swapalloc.highwater/NCOLOR;
+ USED(p);
+ return palloc.freecount >= swapalloc.highwater;
}
void
putpage(Page *p)
{
- Rendez *r;
-
if(onswap(p)) {
putswap(p);
return;
@@ 209,10 210,9 @@ putpage(Page *p)
p->prev = 0;
}
- palloc.freecol[p->color]++;
- r = &palloc.r[p->color];
- if(r->p != 0)
- wakeup(r);
+ palloc.freecount++;
+ if(palloc.r.p != 0)
+ wakeup(&palloc.r);
unlock(&palloc);
unlock(p);
@@ 225,13 225,13 @@ auxpage()
lock(&palloc);
p = palloc.head;
- if(palloc.freecol[p->color] < swapalloc.highwater/NCOLOR) {
+ if(palloc.freecount < swapalloc.highwater) {
unlock(&palloc);
return 0;
}
p->next->prev = 0;
palloc.head = p->next;
- palloc.freecol[p->color]--;
+ palloc.freecount--;
unlock(&palloc);
lock(p);
@@ 259,7 259,7 @@ duppage(Page *p) /* Always call with p locked */
lock(&palloc);
/* No freelist cache when memory is very low */
- if(palloc.freecol[p->color] < swapalloc.highwater/NCOLOR) {
+ if(palloc.freecount < swapalloc.highwater) {
unlock(&palloc);
uncachepage(p);
return;
@@ 419,7 419,7 @@ lookpage(Image *i, ulong daddr)
else
palloc.tail = f->prev;
- palloc.freecol[f->color]--;
+ palloc.freecount--;
}
unlock(&palloc);
M port/portdat.h => port/portdat.h +3 -4
@@ 455,13 455,12 @@ struct Palloc
ulong np0, np1; /* number of pages in bank 0/1 */
Page *head; /* most recently used */
Page *tail; /* least recently used */
- ulong freecol[NCOLOR]; /* how many pages on free list now */
+ ulong freecount; /* how many pages on free list now */
ulong user; /* how many user pages */
Page *hash[PGHSIZE];
Lock hashlock;
- Rendez r[NCOLOR]; /* Sleep for free mem */
- QLock pwait[NCOLOR]; /* Queue of procs waiting for memory */
- int wanted; /* Do the wakeup at free */
+ Rendez r; /* Sleep for free mem */
+ QLock pwait; /* Queue of procs waiting for memory */
ulong cmembase; /* Key memory */
ulong cmemtop;
};
M port/swap.c => port/swap.c +6 -10
@@ 118,7 118,9 @@ loop:
if(p->state == Dead || p->kp)
continue;
- /* don't swap out programs from devroot.c */
+ /* don't swap out programs from devroot.c - they
+ * supply important system services
+ */
img = p->seg[SG_TEXT]->image;
if(img && devchar[img->c->type] == '/')
continue;
@@ 155,9 157,8 @@ loop:
/* Emulate the old system if no swap channel */
print("no physical memory\n");
- tsleep(&swapalloc.r, return0, 0, 1000);
- for(i = 0; i < NCOLOR; i++)
- wakeup(&palloc.r[i]);
+ tsleep(&swapalloc.r, return0, 0, 5000);
+ wakeup(&palloc.r);
}
}
goto loop;
@@ 326,13 327,8 @@ executeio(void)
int
needpages(void *p)
{
- int i;
-
USED(p);
- for(i = 0; i < NCOLOR; i++)
- if(palloc.freecol[i] < swapalloc.headroom/NCOLOR)
- return 1;
- return 0;
+ return palloc.freecount < swapalloc.headroom;
}
void