~kris/9p

9hist

b3e988465483e72c4825249cc6317a4a4b415841 — David du Colombier 28 years ago 17dd2cf
Plan 9 from Bell Labs 1998-03-26
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