M ip/ip.c => ip/ip.c +12 -3
@@ 322,9 322,18 @@ ipiput(Fs *f, uchar *ia, Block *bp)
// DBG(nhgetl(h->src))(Logipmsg, "ipiput %V %V len %d proto %d\n",
// h->src, h->dst, BLEN(bp), h->proto);
- /* Ensure we have enough data to process */
- if(BLEN(bp) < IPHDR) {
- bp = pullupblock(bp, IPHDR);
+ /*
+ * Ensure we have allt he header info in the first
+ * block. Make life easier for other protocols by
+ * collecting up to the first 64 bytes in the first block.
+ */
+ if(BLEN(bp) < 64) {
+ hl = blocklen(bp);
+ if(hl < IPHDR)
+ hl = IPHDR;
+ if(hl > 64)
+ hl = 64;
+ bp = pullupblock(bp, hl);
if(bp == nil)
return;
}
M ip/ipmux.c => ip/ipmux.c +25 -29
@@ 59,7 59,7 @@ struct Ipmux
Ipmux *yes;
Ipmux *no;
uchar type;
- ushort len; /* length in bytes of item to compare */
+ uchar len; /* length in bytes of item to compare */
ushort off; /* offset of comparison */
int n; /* number of items val points to */
uchar *val;
@@ 591,47 591,43 @@ static void
ipmuxiput(Proto *p, uchar *ia, Block *bp)
{
int len;
- Iphdr *ip;
Fs *f = p->f;
- uchar *p;
+ uchar *m, *h, *v, *e, *ve, *hp;
Conv *c;
- ip = bp->rptr;
rlock(f);
mux = f->t2m[ip->proto];
if(mux == nil)
goto out;
- /* run the v4 filter */
- len = BLEN(bp);
- if(len < 64 && bp->next){
- bp = concatblock(bp);
- len = BLEN(bp);
+ /* make interface address part of packet */
+ h = bp->rptr - IPHDR - IPv4addrlen;
+ if(h < bp->base){
+ bp = padblock(bp, IPHDR + IPv4addrlen);
+ h = bp->rptr;
+ bp->rptr += IPHDR + IPv4addrlen;
}
+ memmove(h, ia+IPv4off, ia);
+
+ /* run the v4 filter */
c = nil;
while(mux != nil){
- while(mux){
- switch(mux->type){
- case Tia:
- p = ia;
- break;
- case Tsrc:
- p = ip->src;
- break;
- case Tdst:
- p = ip->dst;
- break;
- case Tdata:
- p = ip->data;
- if(mux->off+mux->len > len)
- goto no;
- break;
+ v = mux->val;
+ for(e = v + mux->n*mux->len; v < e; v = ve){
+ m = mux->mask;
+ hp = h + mux->off;
+ for(ve = v + mux->len; v < ve; v++){
+ if((*hp++ & *m++) != *v++)
+ break;
}
+ if(v == ve){
+ if(mux->c != nil)
+ c = mux->c;
+ mux = mux->yes;
+ if(
+
}
- if(mux->mask != nil){
- } else {
- }
-no:
+
mux = mux->no;
continue;
}
M ip/kio.c => ip/kio.c +1 -1
@@ 124,7 124,7 @@ kseek(int fd, vlong offset, int whence)
case 2:
devtab[c->type]->stat(c, buf);
convM2D(buf, &dir);
- c->offset = dir.length1 + offset; /* BOTCH */
+ c->offset = dir.length + offset;
off = c->offset;
break;
}
M pc/etherelnk3.c => pc/etherelnk3.c +1 -1
@@ 49,7 49,7 @@
#include "etherif.h"
-#define XCVRDEBUG if(1)print
+#define XCVRDEBUG if(0)print
enum {
IDport = 0x0110, /* anywhere between 0x0100 and 0x01F0 */
M pc/segment.h => pc/segment.h +1 -6
@@ 1,13 1,8 @@
/*
* Attach segment types
*/
-
-Physseg physseg[] =
-{
- { SG_SHARED, "lock", 0, SEGMAXSIZE, 0, 0 },
+static Physseg physseg[10] = {
{ SG_SHARED, "shared", 0, SEGMAXSIZE, 0, 0 },
- { SG_PHYSICAL, "dseg", 0xd0000, 64*1024, 0, 0 },
{ SG_BSS, "memory", 0, SEGMAXSIZE, 0, 0 },
- { SG_PHYSICAL, "pcivctl", 0, 16*1024, 0, 0 },
{ 0, 0, 0, 0, 0, 0 },
};
M pc/u.h => pc/u.h +1 -4
@@ 10,10 10,7 @@ typedef ushort Rune;
union Length
{
- struct{
- long length1;
- long length2;
- };
+ vlong length;
};
typedef char *va_list;
M pc/vgamga2164w.c => pc/vgamga2164w.c +185 -24
@@ 11,39 11,41 @@
#include <memdraw.h>
#include "screen.h"
+/*
+ * Matrox Millenium II.
+ * MGA-2164W 3D graphics accelerator + Tvp3026 RAMDAC.
+ */
static void
-mga2164wenable(VGAscr*)
+mga2164wenable(VGAscr* scr)
{
Pcidev *p;
- Physseg *s;
-/*
- ulong mmio;
- uchar *rp;
- int i;
-*/
+ Physseg seg;
- if((p = pcimatch(nil, 0x102B, 0x051B)) == nil)
+ /*
+ * 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;
- for(s = physseg; s->name; s++)
- if(strcmp("pcivctl", s->name) == 0)
- s->pa = p->mem[1].bar & ~0x0F;
+ if((p = pcimatch(nil, 0x102B, 0x051B)) == nil)
+ return;
-/*
- mmio = p->mem[1].bar & ~0x0F;
- mmio = upamalloc(mmio, 16*1024, 0);
- if(mmio == 0){
- print("mmio == 0\n");
+ scr->storage = upamalloc(p->mem[1].bar & ~0x0F, p->mem[1].size, 0);
+ if(scr->storage == 0)
return;
- }
- rp = (uchar*)(mmio+0x3C00);
- for(i = 0; i < 16; i++){
- print("%2.2uX ", *rp);
- rp++;
- }
- print("\n");
-*/
+ 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);
}
static ulong
@@ 78,6 80,156 @@ mga2164wlinear(VGAscr* scr, int* size, int* align)
return aperture;
}
+enum {
+ Index = 0x00, /* Index */
+ Data = 0x0A, /* Data */
+
+ CaddrW = 0x04, /* Colour Write Address */
+ Cdata = 0x05, /* Colour Data */
+
+ Cctl = 0x09, /* Direct Cursor Control */
+ Cram = 0x0B, /* Cursor Ram Data */
+ Cxlsb = 0x0C, /* Cursor X LSB */
+ Cxmsb = 0x0D, /* Cursor X MSB */
+ Cylsb = 0x0E, /* Cursor Y LSB */
+ Cymsb = 0x0F, /* Cursor Y MSB */
+
+ Icctl = 0x06, /* Indirect Cursor Control */
+};
+
+static void
+tvp3026disable(VGAscr* scr)
+{
+ uchar *tvp3026;
+
+ if(scr->storage == 0)
+ return;
+ tvp3026 = KADDR(scr->storage+0x3C00);
+
+ /*
+ * Make sure cursor is off
+ * and direct control enabled.
+ */
+ *(tvp3026+Index) = Icctl;
+ *(tvp3026+Data) = 0x90;
+ *(tvp3026+Cctl) = 0x00;
+}
+
+static void
+tvp3026load(VGAscr* scr, Cursor* curs)
+{
+ int x, y;
+ uchar *tvp3026;
+
+ if(scr->storage == 0)
+ return;
+ tvp3026 = KADDR(scr->storage+0x3C00);
+
+ /*
+ * Make sure cursor is off by initialising the cursor
+ * control to defaults.
+ * Write to the indirect control register to make sure
+ * direct register is enabled and upper 2 bits of cursor
+ * RAM address are 0.
+ * The LSBs of the cursor RAM address are in PaddrW.
+ */
+ tvp3026disable(scr);
+ vgao(PaddrW, 0x00);
+
+ /*
+ * Initialise the 64x64 cursor RAM array. There are 2 planes,
+ * p0 and p1. Data is written 8 pixels per byte, with p0 in the
+ * first 512 bytes of the array and p1 in the second.
+ * The cursor is set in 3-colour mode which gives the following
+ * truth table:
+ * p1 p0 colour
+ * 0 0 transparent
+ * 0 1 cursor colour 0
+ * 1 0 cursor colour 1
+ * 1 1 cursor colour 2
+ * Put the cursor into the top-left of the 64x64 array.
+ * The 0,0 cursor point is bottom-right, so positioning will
+ * have to take that into account.
+ */
+ for(y = 0; y < 64; y++){
+ for(x = 0; x < 64/8; x++){
+ if(x < 16/8 && y < 16)
+ *(tvp3026+Cram) = curs->clr[x+y*2];
+ else
+ *(tvp3026+Cram) = 0x00;
+ }
+ }
+ for(y = 0; y < 64; y++){
+ for(x = 0; x < 64/8; x++){
+ if(x < 16/8 && y < 16)
+ *(tvp3026+Cram) = curs->set[x+y*2];
+ else
+ *(tvp3026+Cram) = 0x00;
+ }
+ }
+
+ /*
+ * Initialise the cursor hotpoint
+ * and enable the cursor in 3-colour mode.
+ */
+ scr->offset.x = 64+curs->offset.x;
+ scr->offset.y = 64+curs->offset.y;
+ *(tvp3026+Cctl) = 0x01;
+}
+
+static int
+tvp3026move(VGAscr* scr, Point p)
+{
+ int x, y;
+ uchar *tvp3026;
+
+ if(scr->storage == 0)
+ return 1;
+ tvp3026 = KADDR(scr->storage+0x3C00);
+
+ x = p.x+scr->offset.x;
+ y = p.y+scr->offset.y;
+
+ *(tvp3026+Cxlsb) = x & 0xFF;
+ *(tvp3026+Cxmsb) = (x>>8) & 0x0F;
+ *(tvp3026+Cylsb) = y & 0xFF;
+ *(tvp3026+Cymsb) = (y>>8) & 0x0F;
+
+ return 0;
+}
+
+static void
+tvp3026enable(VGAscr* scr)
+{
+ int i;
+ uchar *tvp3026;
+
+ if(scr->storage == 0)
+ return;
+ tvp3026 = KADDR(scr->storage+0x3C00);
+
+ tvp3026disable(scr);
+
+ /*
+ * Overscan colour,
+ * cursor colour 1 (white),
+ * cursor colour 2, 3 (black).
+ */
+ *(tvp3026+CaddrW) = 0x00;
+ for(i = 0; i < 6; i++)
+ *(tvp3026+Cdata) = Pwhite;
+ for(i = 0; i < 6; i++)
+ *(tvp3026+Cdata) = Pblack;
+
+ /*
+ * Load, locate and enable the
+ * 64x64 cursor in 3-colour mode.
+ */
+ tvp3026load(scr, &arrow);
+ tvp3026move(scr, ZP);
+ *(tvp3026+Cctl) = 0x01;
+}
+
VGAdev vgamga2164wdev = {
"mga2164w",
@@ 86,3 238,12 @@ VGAdev vgamga2164wdev = {
0, /* page */
mga2164wlinear, /* linear */
};
+
+VGAcur vgamga2164wcur = {
+ "mga2164whwgc",
+
+ tvp3026enable,
+ tvp3026disable,
+ tvp3026load,
+ tvp3026move,
+};
M port/dev.c => port/dev.c +2 -3
@@ 23,7 23,7 @@ devno(int c, int user)
}
void
-devdir(Chan *c, Qid qid, char *n, long length, char *user, long perm, Dir *db)
+devdir(Chan *c, Qid qid, char *n, vlong length, char *user, long perm, Dir *db)
{
strcpy(db->name, n);
db->qid = qid;
@@ 37,8 37,7 @@ devdir(Chan *c, Qid qid, char *n, long length, char *user, long perm, Dir *db)
db->mode |= CHMOUNT;
db->atime = seconds();
db->mtime = kerndate;
- db->length1 = length; /* BOTCH */
- db->length2 = length; /* BOTCH */
+ db->length = length;
memmove(db->uid, user, NAMELEN);
memmove(db->gid, eve, NAMELEN);
}
M port/netif.c => port/netif.c +2 -2
@@ 479,7 479,7 @@ hnputv(void *p, vlong v)
a = p;
hnputl(a, v>>32);
- hnputl(a+8, v);
+ hnputl(a+4, v);
}
void
@@ 510,7 510,7 @@ nhgetv(void *p)
uchar *a;
a = p;
- return ((vlong)nhgetl(a) << 32) | nhgetl(a+8);
+ return ((vlong)nhgetl(a) << 32) | nhgetl(a+4);
}
ulong
M port/portdat.h => port/portdat.h +0 -1
@@ 705,4 705,3 @@ enum
};
extern int nsyscall;
-extern Physseg physseg[];
M port/portfns.h => port/portfns.h +2 -1
@@ 1,5 1,6 @@
void accounttime(void);
void addclock0link(void (*)(void));
+int addphysseg(Physseg*);
void addrootfile(char*, uchar*, ulong);
Block* adjustblock(Block*, int);
void alarmkproc(void*);
@@ 60,7 61,7 @@ Block* devbread(Chan*, long, ulong);
long devbwrite(Chan*, Block*, ulong);
Chan* devclone(Chan*, Chan*);
void devcreate(Chan*, char*, int, ulong);
-void devdir(Chan*, Qid, char*, long, char*, long, Dir*);
+void devdir(Chan*, Qid, char*, vlong, char*, long, Dir*);
long devdirread(Chan*, char*, long, Dirtab*, int, Devgen*);
Devgen devgen;
void devinit(void);
M port/segment.c => port/segment.c +34 -7
@@ 5,19 5,19 @@
#include "fns.h"
#include "../port/error.h"
-Page* lkpage(Segment*, ulong);
-void lkpgfree(Page*);
-void imagereclaim(void);
-void imagechanreclaim(void);
+static void imagereclaim(void);
+static void imagechanreclaim(void);
/* System specific segattach devices */
#include "io.h"
#include "segment.h"
+static Lock physseglock;
+
#define NFREECHAN 64
#define IHASHSIZE 64
#define ihash(s) imagealloc.hash[s%IHASHSIZE]
-struct
+static struct
{
Lock;
Image *free;
@@ 278,7 278,7 @@ found:
return i;
}
-void
+static void
imagereclaim(void)
{
Page *p;
@@ 303,7 303,7 @@ imagereclaim(void)
* since close can block, this has to be called outside of
* spin locks.
*/
-void
+static void
imagechanreclaim(void)
{
Chan *c;
@@ 475,6 475,33 @@ isoverlap(Proc *p, ulong va, int len)
return 0;
}
+int
+addphysseg(Physseg* new)
+{
+ Physseg *ps;
+
+ /*
+ * Check not already entered and there is room
+ * for a new entry and the terminating null entry.
+ */
+ lock(&physseglock);
+ for(ps = physseg; ps->name; ps++){
+ if(strcmp(ps->name, new->name) == 0){
+ unlock(&physseglock);
+ return -1;
+ }
+ }
+ if(ps-physseg >= nelem(physseg)-2){
+ unlock(&physseglock);
+ return -1;
+ }
+
+ *ps = *new;
+ unlock(&physseglock);
+
+ return 0;
+}
+
ulong
segattach(Proc *p, ulong attr, char *name, ulong va, ulong len)
{
M port/sysfile.c => port/sysfile.c +24 -14
@@ 467,8 467,8 @@ syswrite(ulong *arg)
return n;
}
-long
-sysvseek(ulong *arg)
+static void
+sseek(ulong *arg)
{
Chan *c;
char buf[DIRLEN];
@@ 479,7 479,7 @@ sysvseek(ulong *arg)
ulong u[2];
} o;
- c = fdtochan(arg[0], -1, 1, 0);
+ c = fdtochan(arg[1], -1, 1, 0);
if(c->qid.path & CHDIR)
error(Eisdir);
@@ 487,9 487,9 @@ sysvseek(ulong *arg)
error(Eisstream);
off = 0;
- o.u[0] = arg[1];
- o.u[1] = arg[2];
- switch(arg[3]){
+ o.u[0] = arg[2];
+ o.u[1] = arg[3];
+ switch(arg[4]){
case 0:
off = o.v;
c->offset = off;
@@ 505,11 505,19 @@ sysvseek(ulong *arg)
case 2:
devtab[c->type]->stat(c, buf);
convM2D(buf, &dir);
- off = (long)dir.length1 + o.v; /* BOTCH */
+ off = dir.length + o.v;
c->offset = off;
break;
}
- return off;
+ *(vlong*)arg[0] = off;
+}
+
+long
+sysvseek(ulong *arg)
+{
+ validaddr(arg[0], BY2V, 1);
+ sseek(arg);
+ return 0;
}
long
@@ 519,14 527,16 @@ sysseek(ulong *arg)
vlong v;
ulong u[2];
} o;
- ulong a[4];
+ ulong a[5];
o.v = arg[1];
- a[0] = arg[0];
- a[1] = o.u[0];
- a[2] = o.u[1];
- a[3] = arg[2];
- return sysvseek(a);
+ a[0] = (ulong)&o.v;
+ a[1] = arg[0];
+ a[2] = o.u[0];
+ a[3] = o.u[1];
+ a[4] = arg[2];
+ sseek(a);
+ return o.v;
}
long