M ip/ipifc.c => ip/ipifc.c +2 -0
@@ 135,6 135,7 @@ ipifcbind(Conv *c, char **argv, int argc)
ifc->m = m;
ifc->minmtu = ifc->m->minmtu;
ifc->maxmtu = ifc->m->maxmtu;
+ ifc->conv->inuse++;
ifc->ifcid++;
wunlock(ifc);
@@ 160,6 161,7 @@ ipifcunbind(Ipifc *ifc)
wlock(ifc);
/* dissociate routes */
+ ifc->conv->inuse--;
ifc->ifcid++;
/* disassociate device */
M ip/ipmux.c => ip/ipmux.c +6 -6
@@ 296,7 296,7 @@ parsemux(char *p)
f->ctype = nomask ? Cshort : Cmshort;
break;
case 4:
- if(f->type == Cifc)
+ if(f->type == Tifc)
f->ctype = nomask ? Cifc : Cmifc;
else
f->ctype = nomask ? Clong : Cmlong;
@@ 674,7 674,7 @@ ipmuxiput(Proto *p, uchar *ia, Block *bp)
goto yes;
break;
case Cmbyte:
- if((*mux->val & *mux->mask) == *hp)
+ if((*hp & *mux->mask) == *mux->val)
goto yes;
break;
case Cshort:
@@ 682,7 682,7 @@ ipmuxiput(Proto *p, uchar *ia, Block *bp)
goto yes;
break;
case Cmshort:
- if((*((ushort*)mux->val) & (*((ushort*)mux->mask))) == *(ushort*)hp)
+ if((*(ushort*)hp & (*((ushort*)mux->mask))) == *((ushort*)mux->val))
goto yes;
break;
case Clong:
@@ 690,15 690,15 @@ ipmuxiput(Proto *p, uchar *ia, Block *bp)
goto yes;
break;
case Cmlong:
- if((*((ulong*)mux->val) & (*((ulong*)mux->mask))) == *(ulong*)hp)
+ if((*(ulong*)hp & (*((ulong*)mux->mask))) == *((ulong*)mux->val))
goto yes;
break;
case Cifc:
- if(*((ulong*)mux->val) == *(ulong*)ia)
+ if(*((ulong*)mux->val) == *(ulong*)(ia + IPv4off))
goto yes;
break;
case Cmifc:
- if((*((ulong*)mux->val) & (*((ulong*)mux->mask))) == *(ulong*)ia)
+ if((*(ulong*)(ia + IPv4off) & (*((ulong*)mux->mask))) == *((ulong*)mux->val))
goto yes;
break;
default:
M pc/ether82557.c => pc/ether82557.c +8 -0
@@ 530,6 530,13 @@ promiscuous(void* arg, int on)
}
static void
+multicast(void* arg, uchar *addr, int on)
+{
+ USED(addr, on);
+ configure(arg, 1);
+}
+
+static void
transmit(Ether* ether)
{
Ctlr *ctlr;
@@ 1010,6 1017,7 @@ reset(Ether* ether)
ether->ifstat = ifstat;
ether->promiscuous = promiscuous;
+ ether->multicast = multicast;
ether->arg = ether;
return 0;
M pc/screen.h => pc/screen.h +2 -0
@@ 92,6 92,8 @@ struct VGAscr {
int isupamem;
int apsize;
+ ulong io; /* device specific registers */
+
ulong colormap[Pcolours][3];
Memimage* gscreen;
A pc/vgamach64xx.c => pc/vgamach64xx.c +256 -0
@@ 0,0 1,256 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "io.h"
+#include "../port/error.h"
+
+#define Image IMAGE
+#include <draw.h>
+#include <memdraw.h>
+#include "screen.h"
+
+/*
+ * ATI Mach64.
+ */
+static ushort mach64xxdid[] = {
+ ('C'<<8)|'T',
+ ('E'<<8)|'T',
+ ('G'<<8)|'P',
+ ('G'<<8)|'T',
+ ('G'<<8)|'U',
+ ('V'<<8)|'T',
+ ('V'<<8)|'U',
+ 0,
+};
+
+static Pcidev*
+mach64xxpci(void)
+{
+ Pcidev *p;
+ ushort *did;
+
+ if((p = pcimatch(nil, 0x1002, 0)) == nil)
+ return nil;
+ for(did = mach64xxdid; *did; did++){
+ if(*did == p->did)
+ break;
+ }
+ if(*did == 0)
+ return nil;
+
+ return p;
+}
+
+static void
+mach64xxenable(VGAscr* scr)
+{
+ Pcidev *p;
+
+ /*
+ * Only once, can't be disabled for now.
+ */
+ if(scr->io)
+ return;
+ if(p = mach64xxpci())
+ scr->io = p->mem[1].bar & ~0x01;
+}
+
+static ulong
+mach64xxlinear(VGAscr* scr, int* size, int* align)
+{
+ ulong aperture, oaperture;
+ int oapsize, wasupamem;
+ Pcidev *p;
+
+ oaperture = scr->aperture;
+ oapsize = scr->apsize;
+ wasupamem = scr->isupamem;
+ if(wasupamem)
+ upafree(oaperture, oapsize);
+ scr->isupamem = 0;
+
+ if(p = mach64xxpci()){
+ aperture = p->mem[0].bar & ~0x0F;
+ *size = p->mem[0].size;
+ }
+ else
+ aperture = 0;
+
+ aperture = upamalloc(aperture, *size, *align);
+ if(aperture == 0){
+ if(wasupamem && upamalloc(oaperture, oapsize, 0))
+ scr->isupamem = 1;
+ }
+ else
+ scr->isupamem = 1;
+
+ return aperture;
+}
+
+enum { /* I/O select */
+ CurClr0 = 0x18,
+ CurClr1 = 0x19,
+ CurOffset = 0x1a,
+ CurHVposn = 0x1b,
+ CurHVoff = 0x1c,
+
+ GenTestCntl = 0x34,
+};
+
+static ulong
+ior32(VGAscr* scr, int r)
+{
+ return inl((r<<2)+scr->io);
+}
+
+static void
+iow32(VGAscr* scr, int r, ulong l)
+{
+ outl(((r)<<2)+scr->io, l);
+}
+
+static void
+mach64xxcurdisable(VGAscr* scr)
+{
+ ulong r;
+
+ r = ior32(scr, GenTestCntl);
+ iow32(scr, GenTestCntl, r & ~0x80);
+}
+
+static void
+mach64xxcurload(VGAscr* scr, Cursor* curs)
+{
+ uchar *p;
+ int i, y;
+ ulong c, s, m, r;
+
+ /*
+ * Disable the cursor.
+ */
+ r = ior32(scr, GenTestCntl);
+ iow32(scr, GenTestCntl, r & ~0x80);
+
+ p = KADDR(scr->aperture);
+ p += scr->storage;
+
+ for(y = 0; y < 16; y++){
+ for(i = 0; i < (64-16)/8; i++){
+ *p++ = 0xAA;
+ *p++ = 0xAA;
+ }
+
+ c = (curs->clr[2*y]<<8)|curs->clr[y*2 + 1];
+ s = (curs->set[2*y]<<8)|curs->set[y*2 + 1];
+
+ m = 0x00000000;
+ for(i = 0; i < 16; i++){
+ if(s & (1<<(15-i)))
+ m |= 0x01<<(2*i);
+ else if(c & (1<<(15-i)))
+ ;
+ else
+ m |= 0x02<<(2*i);
+ }
+ *p++ = m;
+ *p++ = m>>8;
+ *p++ = m>>16;
+ *p++ = m>>24;
+ }
+ memset(p, 0xAA, (64-16)*16);
+
+ /*
+ * Set the cursor hotpoint and enable the cursor.
+ */
+ scr->offset = curs->offset;
+ iow32(scr, GenTestCntl, 0x80|r);
+}
+
+static int
+mach64xxcurmove(VGAscr* scr, Point p)
+{
+ int x, xo, y, yo;
+
+ /*
+ * Mustn't position the cursor offscreen even partially,
+ * or it disappears. Therefore, if x or y is -ve, adjust the
+ * cursor presets instead. If y is negative also have to
+ * adjust the starting offset.
+ */
+ if((x = p.x+scr->offset.x) < 0){
+ xo = x;
+ x = 0;
+ }
+ else
+ xo = 0;
+ if((y = p.y+scr->offset.y) < 0){
+ yo = y;
+ y = 0;
+ }
+ else
+ yo = 0;
+
+ iow32(scr, CurHVoff, ((64-16-yo)<<16)|(64-16-xo));
+ iow32(scr, CurOffset, scr->storage/8 + (-yo*2));
+ iow32(scr, CurHVposn, (y<<16)|x);
+
+ return 0;
+}
+
+static void
+mach64xxcurenable(VGAscr* scr)
+{
+ ulong r, storage;
+
+ mach64xxenable(scr);
+ if(scr->io == 0)
+ return;
+
+ r = ior32(scr, GenTestCntl);
+ iow32(scr, GenTestCntl, r & ~0x80);
+
+ iow32(scr, CurClr0, (Pwhite<<24)|(Pwhite<<16)|(Pwhite<<8)|Pwhite);
+ iow32(scr, CurClr1, (Pblack<<24)|(Pblack<<16)|(Pblack<<8)|Pblack);
+
+ /*
+ * Find a place for the cursor data in display memory.
+ * Must be 64-bit aligned.
+ */
+ storage = (scr->gscreen->width*BY2WD*scr->gscreen->r.max.y+7)/8;
+ iow32(scr, CurOffset, storage);
+ scr->storage = storage*8;
+
+ /*
+ * Cursor goes in the top right corner of the 64x64 array
+ * so the horizontal and vertical presets are 64-16.
+ */
+ iow32(scr, CurHVposn, (0<<16)|0);
+ iow32(scr, CurHVoff, ((64-16)<<16)|(64-16));
+
+ /*
+ * Load, locate and enable the 64x64 cursor.
+ */
+ mach64xxcurload(scr, &arrow);
+ mach64xxcurmove(scr, ZP);
+ iow32(scr, GenTestCntl, 0x80|r);
+}
+
+VGAdev vgamach64xxdev = {
+ "mach64xx",
+
+ mach64xxenable, /* enable */
+ 0, /* disable */
+ 0, /* page */
+ mach64xxlinear, /* linear */
+};
+
+VGAcur vgamach64xxcur = {
+ "mach64xxhwgc",
+
+ mach64xxcurenable, /* enable */
+ mach64xxcurdisable, /* disable */
+ mach64xxcurload, /* load */
+ mach64xxcurmove, /* move */
+};
M pc/vgamga2164w.c => pc/vgamga2164w.c +95 -46
@@ 12,44 12,33 @@
#include "screen.h"
/*
- * Matrox Millenium II.
- * MGA-2164W 3D graphics accelerator + Tvp3026 RAMDAC.
+ * Matrox Millenium and Matrox Millenium II.
+ * Matrox MGA-2064W, MGA-2164W 3D graphics accelerators
+ * Texas Instruments Tvp3026 RAMDAC.
*/
-static void
-mga2164wenable(VGAscr* scr)
+
+enum {
+ /* pci chip manufacturer */
+ MATROX = 0x102B,
+
+ /* pci chip device ids */
+ MGA2064 = 0x0519,
+ MGA2164 = 0x051B,
+ MGA2164AGP = 0x051F
+};
+
+static Pcidev*
+mgapcimatch(void)
{
Pcidev *p;
- Physseg seg;
- /*
- * Only once, can't be disabled for now.
- * scr->storage holds the virtual address of
- * the MMIO registers, this is different
- * usage from other VGA drivers.
- */
- if(scr->storage)
- return;
-
- p = pcimatch(nil, 0x102B, 0x051B);
+ p = pcimatch(nil, MATROX, MGA2164AGP);
if(p == nil) {
- p = pcimatch(nil, 0x102B, 0x051F);
+ p = pcimatch(nil, MATROX, MGA2164);
if(p == nil)
- return;
+ p = pcimatch(nil, MATROX, MGA2064);
}
-
- scr->storage = upamalloc(p->mem[1].bar & ~0x0F, p->mem[1].size, 0);
- if(scr->storage == 0)
- return;
-
- memset(&seg, 0, sizeof(seg));
- seg.attr = SG_PHYSICAL;
- seg.name = smalloc(NAMELEN);
- snprint(seg.name, NAMELEN, "mga2164wmmio");
- seg.pa = scr->storage;
- seg.size = p->mem[1].size;
- addphysseg(&seg);
-
- scr->storage = (ulong)KADDR(scr->storage);
+ return p;
}
static ulong
@@ 62,21 51,29 @@ mga2164wlinear(VGAscr* scr, int* size, int* align)
oaperture = scr->aperture;
oapsize = scr->apsize;
wasupamem = scr->isupamem;
- if(wasupamem)
- upafree(oaperture, oapsize);
- scr->isupamem = 0;
- if(p = pcimatch(nil, 0x102B, 0x051B)){
- aperture = p->mem[0].bar & ~0x0F;
- *size = p->mem[0].size;
+ if(p = mgapcimatch()){
+ aperture = p->mem[p->did==MGA2064? 1 : 0].bar & ~0x0F;
+ *size = 16*1024*1024;
}
else
aperture = 0;
+ if(wasupamem) {
+ if(oaperture == aperture)
+ return oaperture;
+ upafree(oaperture, oapsize);
+ }
+ scr->isupamem = 0;
+
aperture = upamalloc(aperture, *size, *align);
if(aperture == 0){
- if(wasupamem && upamalloc(oaperture, oapsize, 0))
+ if(wasupamem && upamalloc(oaperture, oapsize, 0)) {
+ aperture = oaperture;
scr->isupamem = 1;
+ }
+ else
+ scr->isupamem = 0;
}
else
scr->isupamem = 1;
@@ 84,6 81,58 @@ mga2164wlinear(VGAscr* scr, int* size, int* align)
return aperture;
}
+static void
+mga2164wenable(VGAscr* scr)
+{
+ Pcidev *p;
+ Physseg seg;
+ int size, align, immio;
+ ulong aperture;
+
+ /*
+ * Only once, can't be disabled for now.
+ * scr->io holds the virtual address of
+ * the MMIO registers.
+ */
+ if(scr->io)
+ return;
+
+ p = mgapcimatch();
+ if(p == nil)
+ return;
+
+ immio = p->did==MGA2064? 0 : 1;
+ scr->io = upamalloc(p->mem[immio].bar & ~0x0F, p->mem[immio].size, 0);
+ if(scr->io == 0)
+ return;
+
+ memset(&seg, 0, sizeof(seg));
+ seg.attr = SG_PHYSICAL;
+ seg.name = smalloc(NAMELEN);
+ snprint(seg.name, NAMELEN, "mga2164wmmio");
+ seg.pa = scr->io;
+ seg.size = p->mem[immio].size;
+ addphysseg(&seg);
+
+ scr->io = (ulong)KADDR(scr->io);
+
+ /* need to map frame buffer here too, so vga can find memory size */
+ size = 16*1024*1024;
+ align = 0;
+ aperture = mga2164wlinear(scr, &size, &align);
+ if(aperture) {
+ scr->aperture = aperture;
+ scr->apsize = size;
+ memset(&seg, 0, sizeof(seg));
+ seg.attr = SG_PHYSICAL;
+ seg.name = smalloc(NAMELEN);
+ snprint(seg.name, NAMELEN, "mga2164wscreen");
+ seg.pa = aperture;
+ seg.size = size;
+ addphysseg(&seg);
+ }
+}
+
enum {
Index = 0x00, /* Index */
Data = 0x0A, /* Data */
@@ 106,9 155,9 @@ tvp3026disable(VGAscr* scr)
{
uchar *tvp3026;
- if(scr->storage == 0)
+ if(scr->io == 0)
return;
- tvp3026 = KADDR(scr->storage+0x3C00);
+ tvp3026 = KADDR(scr->io+0x3C00);
/*
* Make sure cursor is off
@@ 125,9 174,9 @@ tvp3026load(VGAscr* scr, Cursor* curs)
int x, y;
uchar *tvp3026;
- if(scr->storage == 0)
+ if(scr->io == 0)
return;
- tvp3026 = KADDR(scr->storage+0x3C00);
+ tvp3026 = KADDR(scr->io+0x3C00);
/*
* Make sure cursor is off by initialising the cursor
@@ 187,9 236,9 @@ tvp3026move(VGAscr* scr, Point p)
int x, y;
uchar *tvp3026;
- if(scr->storage == 0)
+ if(scr->io == 0)
return 1;
- tvp3026 = KADDR(scr->storage+0x3C00);
+ tvp3026 = KADDR(scr->io+0x3C00);
x = p.x+scr->offset.x;
y = p.y+scr->offset.y;
@@ 208,9 257,9 @@ tvp3026enable(VGAscr* scr)
int i;
uchar *tvp3026;
- if(scr->storage == 0)
+ if(scr->io == 0)
return;
- tvp3026 = KADDR(scr->storage+0x3C00);
+ tvp3026 = KADDR(scr->io+0x3C00);
tvp3026disable(scr);