~kris/9p

9hist

afec3802f7a9437fb2169cf0edff22699c17e708 — David du Colombier 29 years ago ace7c98
Plan 9 from Bell Labs 1997-04-04
M carrera/devrtc.c => carrera/devrtc.c +60 -125
@@ 20,8 20,6 @@ struct Rtc
	int	mon;
	int	year;
};
static QLock rtclock;	/* mutex on clock operations */


enum
{


@@ 39,11 37,16 @@ enum
	StatusC=	0x0C,
	StatusD=	0x0D,

	Update=		0x80,

	Nvsize = 4096,

	Nclock=		6,
};

#define GETBCD(v)	(((v) & 0x0F) + 10*((v)>>4))
#define PUTBCD(v)	((v) % 10)|((((v)/10) % 10)<<4)

Dirtab rtcdir[]={
	"nvram",	{Qnvram, 0},	Nvsize,	0664,
	"rtc",		{Qrtc, 0},	0,	0664,


@@ 52,10 55,11 @@ Dirtab rtcdir[]={
static ulong rtc2sec(Rtc*);
static void sec2rtc(ulong, Rtc*);

static uchar statusB;
static int isbinary;
static Lock rtclock;

static void
getstatusB(void)
rtcreset(void)
{
	int i, x;
	uchar r;


@@ 68,7 72,7 @@ getstatusB(void)
			continue;

		*(uchar*)Rtcindex = x|StatusB;
		statusB = *(uchar*)Rtcdata;
		isbinary = *(uchar*)Rtcdata & 0x04;
		break;
	}
}


@@ 76,7 80,6 @@ getstatusB(void)
static Chan*
rtcattach(char *spec)
{
	getstatusB();
	return devattach('r', spec);
}



@@ 114,106 117,51 @@ rtcclose(Chan *c)
	USED(c);
}

static uchar
bcd2binary(int reg)
{
	uchar x;

	x = (*(uchar*)Rtcindex)&~0x7f;
	*(uchar*)Rtcindex = x|reg;
	x = *(uchar*)Rtcdata;
	return (x&0xf) + 10*(x>>4);
}

#define GETBCD(o) ((clock[o]&0xf) + 10*(clock[o]>>4))

static void
dumprtcstatus(void)
{
	int i, x;
	uchar status[4], r;

	for(i = 0; i < 10000; i++){
		x = (*(uchar*)Rtcindex)&~0x7f;
		*(uchar*)Rtcindex = x|Status;
		r = *(uchar*)Rtcdata;
		if(r & 0x80)
			continue;

		status[0] = r;
		*(uchar*)Rtcindex = x|StatusB;
		status[1] = *(uchar*)Rtcdata;
		*(uchar*)Rtcindex = x|StatusC;
		status[2] = *(uchar*)Rtcdata;
		*(uchar*)Rtcindex = x|StatusD;
		status[3] = *(uchar*)Rtcdata;

		*(uchar*)Rtcindex = x|Status;
		r = *(uchar*)Rtcdata;
		if((r & 0x80) == 0)
			break;
	}

	print("RTC: %uX %uX %uX %uX\n", status[0], status[1], status[2], status[3]);
}

static long	 
_rtctime(void)
{
	Rtc rtc;
	int i, x;
	uchar clock[Nclock], r;
	int busy;
	uchar r;

	/* don't do the read until the clock is no longer busy */
	busy = 0;
	for(i = 0; i < 10000; i++){
		x = (*(uchar*)Rtcindex)&~0x7f;
		*(uchar*)Rtcindex = x|Status;
		r = *(uchar*)Rtcdata;
		if(r & 0x80){
			busy++;
		if(r & Update)
			continue;
		}

		/* read clock values */
		*(uchar*)Rtcindex = x|Seconds;
		clock[0] = *(uchar*)Rtcdata;
		rtc.sec = *(uchar*)Rtcdata;
		*(uchar*)Rtcindex = x|Minutes;
		clock[1] = *(uchar*)Rtcdata;
		rtc.min = *(uchar*)Rtcdata;
		*(uchar*)Rtcindex = x|Hours;
		clock[2] = *(uchar*)Rtcdata;
		rtc.hour = *(uchar*)Rtcdata;
		*(uchar*)Rtcindex = x|Mday;
		clock[3] = *(uchar*)Rtcdata;
		rtc.mday = *(uchar*)Rtcdata;
		*(uchar*)Rtcindex = x|Month;
		clock[4] = *(uchar*)Rtcdata;
		rtc.mon = *(uchar*)Rtcdata;
		*(uchar*)Rtcindex = x|Year;
		clock[5] = *(uchar*)Rtcdata;
		rtc.year = *(uchar*)Rtcdata;

		*(uchar*)Rtcindex = x|Status;
		r = *(uchar*)Rtcdata;
		if((r & 0x80) == 0)
		if((r & Update) == 0)
			break;
	}

	if(statusB & 0x04){
		rtc.sec = clock[0];
		rtc.min = clock[1];
		rtc.hour = clock[2];
		rtc.mday = clock[3];
		rtc.mon = clock[4];
		rtc.year = clock[5];
	}
	else{
	if(!isbinary){
		/*
		 *  convert from BCD
		 */
		rtc.sec = GETBCD(0);
		rtc.min = GETBCD(1);
		rtc.hour = GETBCD(2);
		rtc.mday = GETBCD(3);
		rtc.mon = GETBCD(4);
		rtc.year = GETBCD(5);
		rtc.sec = GETBCD(rtc.sec);
		rtc.min = GETBCD(rtc.min);
		rtc.hour = GETBCD(rtc.hour);
		rtc.mday = GETBCD(rtc.mday);
		rtc.mon = GETBCD(rtc.mon);
		rtc.year = GETBCD(rtc.year);
	}

	/*


@@ 224,17 172,13 @@ _rtctime(void)
	return rtc2sec(&rtc);
}

static Lock rtlock;

long
rtctime(void)
{
#define notdef
#ifdef notdef
	int i;
	long t, ot;

	ilock(&rtlock);
	ilock(&rtclock);

	/* loop till we get two reads in a row the same */
	t = _rtctime();


@@ 244,22 188,14 @@ rtctime(void)
		if(ot == t)
			break;
	}
	iunlock(&rtlock);

	if(i == 100) print("we are boofheads\n");
	iunlock(&rtclock);

	return t;
#else
	extern ulong boottime;

	return boottime+TK2SEC(MACHP(0)->ticks);
#endif /* notdef */
}

static long	 
rtcread(Chan *c, void *buf, long n, ulong offset)
{
	ulong t;
	uchar *f, *to, *e;

	if(c->qid.path & CHDIR)


@@ 267,12 203,7 @@ rtcread(Chan *c, void *buf, long n, ulong offset)

	switch(c->qid.path){
	case Qrtc:
		qlock(&rtclock);
		t = rtctime();
dumprtcstatus();
		qunlock(&rtclock);
		n = readnum(offset, buf, n, t, 12);
		return n;
		return readnum(offset, buf, n, rtctime(), 12);
	case Qnvram:
		if(offset > Nvsize)
			return -1;


@@ 289,20 220,6 @@ dumprtcstatus();
	return 0;
}

static void
binary2bcd(int reg, uchar val)
{
	uchar x;

	x = (*(uchar*)Rtcindex)&~0x7f;
	*(uchar*)Rtcindex = x|reg;
	if(statusB & 0x04)
		*(uchar*)Rtcdata = val;
	else
		*(uchar*)Rtcdata = (val % 10) | (((val / 10) % 10)<<4);
}


static long	 
rtcwrite(Chan *c, void *buf, long n, ulong offset)
{


@@ 310,7 227,7 @@ rtcwrite(Chan *c, void *buf, long n, ulong offset)
	ulong secs;
	char *cp, *ep;
	uchar *f, *t, *e;
	int s;
	uchar x;

	USED(c);
	switch(c->qid.path){


@@ 327,18 244,36 @@ rtcwrite(Chan *c, void *buf, long n, ulong offset)
		}
		secs = strtoul(cp, 0, 0);
		sec2rtc(secs, &rtc);
	
		/*
		 *  convert to bcd
		 */
		s = splhi();
		binary2bcd(Seconds, rtc.sec);
		binary2bcd(Minutes, rtc.min);
		binary2bcd(Hours, rtc.hour);
		binary2bcd(Mday, rtc.mday);
		binary2bcd(Month, rtc.mon);
		binary2bcd(Year, rtc.year-1970);
		splx(s);
		rtc.year -= 1970;

		if(!isbinary){	
			/*
			 *  convert to bcd
			 */
			rtc.sec = PUTBCD(rtc.sec);
			rtc.min = PUTBCD(rtc.min);
			rtc.hour = PUTBCD(rtc.hour);
			rtc.mday = PUTBCD(rtc.mday);
			rtc.mon = PUTBCD(rtc.mon);
			rtc.year = PUTBCD(rtc.year);
		}

		ilock(&rtclock);
		/* set clock values */
		x = (*(uchar*)Rtcindex)&~0x7f;
		*(uchar*)Rtcindex = x|Seconds;
		*(uchar*)Rtcdata = rtc.sec;
		*(uchar*)Rtcindex = x|Minutes;
		*(uchar*)Rtcdata = rtc.min;
		*(uchar*)Rtcindex = x|Hours;
		*(uchar*)Rtcdata = rtc.hour;
		*(uchar*)Rtcindex = x|Mday;
		*(uchar*)Rtcdata = rtc.mday;
		*(uchar*)Rtcindex = x|Month;
		*(uchar*)Rtcdata = rtc.mon;
		*(uchar*)Rtcindex = x|Year;
		*(uchar*)Rtcdata = rtc.year;
		iunlock(&rtclock);

		return n;
	case Qnvram:


@@ 358,7 293,7 @@ rtcwrite(Chan *c, void *buf, long n, ulong offset)
}

Dev rtcdevtab = {
	devreset,
	rtcreset,
	devinit,
	rtcattach,
	devclone,

M ip/il.c => ip/il.c +1 -1
@@ 184,7 184,7 @@ ilannounce(Conv *c, char **argv, int argc)
	char *e;

	e = Fsstdannounce(c, argv, argc);
	if(e != nil);
	if(e != nil)
		return e;
	e = ilstart(c, IL_LISTEN, 20);
	if(e != nil)

M pc/archgeneric.c => pc/archgeneric.c +2 -1
@@ 56,9 56,10 @@ static X86type x86type[] =
	{ 5,	1,	23,	"P5", },
	{ 5,	2,	23,	"P54C", },
	{ 5,	3,	23,	"P24T", },	/* PODP5V83 */
	{ 5,	4,	23,	"PODP54", },
	{ 5,	4,	23,	"P54C MMX", },
	{ 5,	5,	23,	"PODDX4", },
	{ 5,	6,	23,	"PODP5", },
	{ 5,	7,	23,	"P54C VRT", },
	{ 6,	4,	23,	"P55CT", },
	{ 6,	1,	16,	"PentiumPro", },/* determined by trial and error */


M pc/audio.h => pc/audio.h +1 -1
@@ 6,7 6,7 @@ enum
	SBswab		= 0,
};

#define seteisadma(a, b)	;
#define seteisadma(a, b)	dmainit(a);
#define CACHELINESZ		8
#define UNCACHED(type, v)	(type*)((ulong)(v))


M pc/devether.c => pc/devether.c +11 -0
@@ 145,6 145,17 @@ etheriq(Ether* ether, Block* bp, int freebp)
	fx = 0;
	ep = &ether->f[Ntypes];

	/* check for valid multcast addresses */
	if((pkt->d[0] & 1) && memcmp(pkt->d, ether->bcast, sizeof(pkt->d)) != 0 && ether->prom == 0){
		if(!activemulti(ether, pkt->d, sizeof(pkt->d))){
			if(freebp){
				freeb(bp);
				bp = 0;
			}
			return bp;
		}
	}

	/*
	 * Multiplex the packet to all the connections which want it.
	 * If the packet is not to be used subsequently (freebp != 0),

M pc/devfloppy.c => pc/devfloppy.c +7 -1
@@ 19,6 19,7 @@
 * floppyeject() 
 * floppysetup0()
 * floppysetup1()
 * dmainit()
 * dmasetup()
 * dmaend()
 * 


@@ 143,6 144,8 @@ floppyreset(void)
	FDrive *dp;
	FType *t;
	ulong maxtsize;

	dmainit(DMAchan);
	
	floppysetup0(&fl);



@@ 793,6 796,8 @@ floppyxfer(FDrive *dp, int cmd, void *a, long off, long n)
		nexterror();
	}
	dp->len = dmasetup(DMAchan, a, dp->len, cmd==Fread);
	if(dp->len < 0)
		error(Eio);

	/*
	 *  start operation


@@ 930,7 935,8 @@ floppyformat(FDrive *dp, char *params)
			dmaend(DMAchan);
			nexterror();
		}
		dmasetup(DMAchan, buf, bp-buf, 0);
		if(dmasetup(DMAchan, buf, bp-buf, 0) < 0)
			error(Eio);

		/*
		 *  start operation

M pc/dma.c => pc/dma.c +25 -14
@@ 79,26 79,33 @@ DMA dma[2] = {
};

/*
 *  DMA must be in the first 16 meg.  This gets called early by main() to
 *  ensure that.
 *  DMA must be in the first 16MB.  This gets called early by the
 *  initialisation routines of any devices which require DMA to ensure
 *  the allocated bounce buffers are below the 16MB limit.
 */
void
dmainit(void)
dmainit(int chan)
{
	int i, chan;
	DMA *dp;
	DMAxfer *xp;
	ulong v;

	for(i = 0; i < 2; i++){
		dp = &dma[i];
		for(chan = 0; chan < 4; chan++){
			xp = &dp->x[chan];
			xp->bva = xspanalloc(BY2PG, BY2PG, 0);
			xp->bpa = PADDR(xp->bva);
			xp->len = 0;
			xp->isread = 0;
		}
	dp = &dma[(chan>>2)&1];
	chan = chan & 3;
	xp = &dp->x[chan];
	if(xp->bva != nil)
		return;

	v = (ulong)xalloc(BY2PG+BY2PG);
	if(v == 0 || PADDR(v) >= 16*MB){
		print("dmainit: chan %d: 0x%luX out of range\n", chan, v);
		xfree((void*)v);
		v = 0;
	}
	xp->bva = (void*)ROUND(v, BY2PG);
	xp->bpa = PADDR(xp->bva);
	xp->len = 0;
	xp->isread = 0;
}

/*


@@ 131,6 138,8 @@ dmasetup(int chan, void *va, long len, int isread)
	if((((ulong)va)&0xF0000000) != KZERO
	|| (pa&0xFFFF0000) != ((pa+len)&0xFFFF0000)
	|| pa > 16*MB) {
		if(xp->bva == nil)
			return -1;
		if(len > BY2PG)
			len = BY2PG;
		if(!isread)


@@ 205,7 214,8 @@ dmaend(int chan)
	memmove(xp->va, xp->bva, xp->len);
	xp->len = 0;
}
 

/*
int
dmacount(int chan)
{


@@ 218,3 228,4 @@ dmacount(int chan)
	retval |= inb(dp->count[chan]) << 8;
	return((retval<<dp->shift)+1);
}
 */

M pc/etherelnk3.c => pc/etherelnk3.c +6 -1
@@ 457,14 457,17 @@ promiscuous(void* arg, int on)
}

static void
multicast(void* arg, char *addr, int on)
multicast(void* arg, uchar *addr, int on)
{
	int filter, port;
	Ether *ether;

	USED(addr, on);

	ether = (Ether*)arg;
	port = ether->port;

print("mutlicast nmaddr == %d\n", ether->nmaddr);
	filter = receiveBroadcast|receiveIndividual;
	if(ether->nmaddr)
		filter |= receiveMulticast;


@@ 1314,6 1317,7 @@ etherelnk3reset(Ether* ether)
		rxstatus9 = 1;
		break;
	}
	USED(did);

	/*
	 * Check if the adapter's station address is to be overridden.


@@ 1436,6 1440,7 @@ etherelnk3reset(Ether* ether)
	ether->ifstat = ifstat;

	ether->promiscuous = promiscuous;
	ether->multicast = multicast;
	ether->arg = ether;

	return 0;

M pc/fns.h => pc/fns.h +1 -1
@@ 18,7 18,7 @@ void	delay(int);
int	dmacount(int);
int	dmadone(int);
void	dmaend(int);
void	dmainit(void);
void	dmainit(int);
long	dmasetup(int, void*, long, int);
#define	evenaddr(x)				/* x86 doesn't care */
void	fpenv(FPsave*);

M pc/main.c => pc/main.c +0 -1
@@ 138,7 138,6 @@ main(void)
	confinit();
	archinit();
	xinit();
	dmainit();
	trapinit();
	printinit();
	if(isoldbcom)

M port/netif.c => port/netif.c +78 -14
@@ 9,7 9,8 @@
static int netown(Netfile*, char*, int);
static int openfile(Netif*, int);
static char* matchtoken(char*, char*);
static void netmulti(Netif*, Netfile*, char*, int);
static char* netmulti(Netif*, Netfile*, uchar*, int);
static int parseaddr(uchar*, char*, int);

/*
 *  set up a new network interface


@@ 215,6 216,7 @@ netifwrite(Netif *nif, Chan *c, void *a, long n)
	Netfile *f;
	char *p;
	char buf[256];
	uchar binaddr[Nmaxaddr];

	if(NETTYPE(c->qid.path) != Nctlqid)
		error(Eperm);


@@ 224,6 226,11 @@ netifwrite(Netif *nif, Chan *c, void *a, long n)
	memmove(buf, a, n);
	buf[n] = 0;

	if(waserror()){
		qunlock(nif);
		nexterror();
	}

	qlock(nif);
	f = nif->f[NETID(c->qid.path)];
	if((p = matchtoken(buf, "connect")) != 0){


@@ 236,11 243,20 @@ netifwrite(Netif *nif, Chan *c, void *a, long n)
		if(nif->prom == 1 && nif->promiscuous != nil)
			nif->promiscuous(nif->arg, 1);
	} else if((p = matchtoken(buf, "addmulti")) != 0){
		netmulti(nif, f, p, 1);
		if(parseaddr(binaddr, p, nif->alen) < 0)
			error("bad address");
		p = netmulti(nif, f, binaddr, 1);
		if(p)
			error(p);
	} else if((p = matchtoken(buf, "remmulti")) != 0){
		netmulti(nif, f, p, 0);
		if(parseaddr(binaddr, p, nif->alen) < 0)
			error("bad address");
		p = netmulti(nif, f, binaddr, 0);
		if(p)
			error(p);
	}
	qunlock(nif);
	poperror();
	return n;
}



@@ 461,26 477,71 @@ nhgets(void *p)
	return (a[0]<<8)|(a[1]<<0);
}

static ulong
hash(uchar *a, int len)
{
	ulong sum = 0;

	while(len-- > 0)
		sum = (sum << 1) + *a++;
	return sum%Nmhash;
}

int
activemulti(Netif *nif, uchar *addr, int alen)
{
	Netaddr *hp;

	for(hp = nif->mhash[hash(addr, alen)]; hp; hp = hp->hnext)
		if(memcmp(addr, hp->addr, alen) == 0){
			if(hp->ref)
				return 1;
			else
				break;
		}
	return 0;
}

static int
parseaddr(uchar *to, char *from, int alen)
{
	char nip[4];
	char *p;
	int i;

	p = from;
	for(i = 0; i < alen; i++){
		if(*p == 0)
			return -1;
		nip[0] = *p++;
		if(*p == 0)
			return -1;
		nip[1] = *p++;
		nip[2] = 0;
		to[i] = strtoul(nip, 0, 16);
		if(*p == ':')
			p++;
	}
	return 0;
}

/*
 *  keep track of multicast addresses
 */
static void
netmulti(Netif *nif, Netfile *f, char *addr, int add)
static char*
netmulti(Netif *nif, Netfile *f, uchar *addr, int add)
{
	Netaddr **l, *ap;
	int i;
	uchar hexaddr[Nmaxaddr];
	ulong h;

	if(nif->multicast == nil)
		return;

	if(strlen(addr) != 2*nif->alen)
		return;
		return "interface does not support multicast";

	l = &nif->maddr;
	i = 0;
	for(ap = *l; ap; ap = *l){
		if(strcmp(addr, ap->addr) == 0)
		if(memcmp(addr, ap->addr, nif->alen) == 0)
			break;
		i++;
		l = &ap->next;


@@ 489,10 550,12 @@ netmulti(Netif *nif, Netfile *f, char *addr, int add)
	if(add){
		if(ap == 0){
			*l = ap = smalloc(sizeof(*ap));
			ap->addr = smalloc(strlen(addr)+1);
			strcpy(ap->addr, addr);
			memmove(ap->addr, addr, nif->alen);
			ap->next = 0;
			ap->ref = 1;
			h = hash(addr, nif->alen);
			ap->hnext = nif->mhash[h];
			nif->mhash[h] = ap;
		} else {
			ap->ref++;
		}


@@ 507,7 570,7 @@ netmulti(Netif *nif, Netfile *f, char *addr, int add)
		}
	} else {
		if(ap == 0 || ap->ref == 0)
			return;
			return 0;
		ap->ref--;
		if(ap->ref == 0){
			nif->nmaddr--;


@@ 519,4 582,5 @@ netmulti(Netif *nif, Netfile *f, char *addr, int add)
			f->maddr[i/8] &= ~(1<<(i%8));
		}
	}
	return 0;
}

M port/netif.h => port/netif.h +9 -5
@@ 6,6 6,7 @@ typedef struct Netif	Netif;
enum
{
	Nmaxaddr=	64,
	Nmhash=		31,

	Ncloneqid=	1,
	N2ndqid,


@@ 48,8 49,9 @@ struct Netfile
 */
struct Netaddr
{
	Netaddr	*next;
	char	*addr;
	Netaddr	*next;		/* allocation chain */
	Netaddr	*hnext;
	uchar	addr[Nmaxaddr];
	int	ref;
};



@@ 70,8 72,9 @@ struct Netif
	int	alen;			/* address length */
	uchar	addr[Nmaxaddr];
	uchar	bcast[Nmaxaddr];
	Netaddr	*maddr;			/* multicast addresses */
	int	nmaddr;			/* number of multicast addresses */
	Netaddr	*maddr;			/* known multicast addresses */
	int	nmaddr;			/* number of known multicast addresses */
	Netaddr *mhash[Nmhash];		/* hash table of multicast addresses */
	int	prom;			/* number of promiscuous opens */
	int	all;			/* number of -1 multiplexors */



@@ 89,7 92,7 @@ struct Netif
	/* routines for touching the hardware */
	void	*arg;
	void	(*promiscuous)(void*, int);
	void	(*multicast)(void*, char*, int);
	void	(*multicast)(void*, uchar*, int);
};

void	netifinit(Netif*, char*, int, ulong);


@@ 101,6 104,7 @@ Block*	netifbread(Netif*, Chan*, long, ulong);
long	netifwrite(Netif*, Chan*, void*, long);
void	netifwstat(Netif*, Chan*, char*);
void	netifstat(Netif*, Chan*, char*);
int	activemulti(Netif*, uchar*, int);

/*
 *  Ethernet specific

M port/qio.c => port/qio.c +5 -0
@@ 586,6 586,11 @@ qpass(Queue *q, Block *b)
	/* sync with qread */
	dowakeup = 0;
	ilock(q);
	if(q->len >= q->limit){
		freeb(b);
		iunlock(q);
		return -1;
	}

	/* add buffer to queue */
	if(q->bfirst)