From b3e988465483e72c4825249cc6317a4a4b415841 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Thu, 26 Mar 1998 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1998-03-26 --- ip/ip.c | 15 +++- ip/ipmux.c | 54 ++++++------ ip/kio.c | 2 +- pc/etherelnk3.c | 2 +- pc/segment.h | 7 +- pc/u.h | 5 +- pc/vgamga2164w.c | 209 +++++++++++++++++++++++++++++++++++++++++------ port/dev.c | 5 +- port/netif.c | 4 +- port/portdat.h | 1 - port/portfns.h | 3 +- port/segment.c | 41 ++++++++-- port/sysfile.c | 38 +++++---- 13 files changed, 290 insertions(+), 96 deletions(-) diff --git a/ip/ip.c b/ip/ip.c index 8a073d7a85136fbb03ae9cd049d070422d04b72a..e46400985d0dbe5925f5ae78f704ed24d4063f4a 100644 --- a/ip/ip.c +++ b/ip/ip.c @@ -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; } diff --git a/ip/ipmux.c b/ip/ipmux.c index 5e2e49fc0617a3301b30ca9573156171b723623d..d2e271419afd6aedc3996ff4fd396e3c39148abf 100644 --- a/ip/ipmux.c +++ b/ip/ipmux.c @@ -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; } diff --git a/ip/kio.c b/ip/kio.c index 05f34e13abb78a970cf0b5616a23d7b10a2c5752..96dcc2af727ded690147437606e65b0796014cec 100644 --- a/ip/kio.c +++ b/ip/kio.c @@ -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; } diff --git a/pc/etherelnk3.c b/pc/etherelnk3.c index 9f98cfc8508f87f75c37b0e8ce8bed9fbb124fcb..25bd595610ccfabedc348c12ea1c098ecc7aa11a 100644 --- a/pc/etherelnk3.c +++ b/pc/etherelnk3.c @@ -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 */ diff --git a/pc/segment.h b/pc/segment.h index e15b9f543929e30530af76e77e78e56b95a6d8c0..3f6e9542bee2c5956771b00436fa8bbb8f17f350 100644 --- a/pc/segment.h +++ b/pc/segment.h @@ -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 }, }; diff --git a/pc/u.h b/pc/u.h index efa4e95d6594f051ce87b5b9041659bf8514b198..aa12cd272b9f26a6ed4de3b9e622efde80d919e1 100644 --- a/pc/u.h +++ b/pc/u.h @@ -10,10 +10,7 @@ typedef ushort Rune; union Length { - struct{ - long length1; - long length2; - }; + vlong length; }; typedef char *va_list; diff --git a/pc/vgamga2164w.c b/pc/vgamga2164w.c index 4fdc172922d64da4e0cca80faebf93d458c7f66d..7be867579516740b247a7c4899df1c880ac7029b 100644 --- a/pc/vgamga2164w.c +++ b/pc/vgamga2164w.c @@ -11,39 +11,41 @@ #include #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, +}; diff --git a/port/dev.c b/port/dev.c index 9db4ee28bd36e4c8ba7e7c74a3b140a3c43cc3b7..5b8252a90d3dda18271d1c82cd130c0b09afc260 100644 --- a/port/dev.c +++ b/port/dev.c @@ -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); } diff --git a/port/netif.c b/port/netif.c index 20455aa4772013f61555bed339b30199d470f318..a9425e8d9f078c3920a1e5179f5aecfc9a0baff6 100644 --- a/port/netif.c +++ b/port/netif.c @@ -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 diff --git a/port/portdat.h b/port/portdat.h index ebfb79e6111df963e222bb30f8d5b3c537b67fc3..eb19bab07c9160f4f8b85cf312b92850ad720e25 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -705,4 +705,3 @@ enum }; extern int nsyscall; -extern Physseg physseg[]; diff --git a/port/portfns.h b/port/portfns.h index 0979fd46940558802964c3413c15d42205470014..d313969ed4896d24ee0e7781822c698eeec7b738 100644 --- a/port/portfns.h +++ b/port/portfns.h @@ -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); diff --git a/port/segment.c b/port/segment.c index 25bf4a3a2a637b7caf30b3e723dc3d3edf3daaab..e236463956b579dd3a90580395bd6d87f3f55e9f 100644 --- a/port/segment.c +++ b/port/segment.c @@ -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) { diff --git a/port/sysfile.c b/port/sysfile.c index c2486f1bd8a6691b4ae8b45570562afc140e3d06..793067279154239871bb0a002ac89a52d0d94a09 100644 --- a/port/sysfile.c +++ b/port/sysfile.c @@ -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