~kris/9p

9hist

01480269e7bf542ce714d3c56578c9e490fd687d — David du Colombier 35 years ago f0c62e9
Plan 9 from Bell Labs 1991-02-09
10 files changed, 139 insertions(+), 136 deletions(-)

M gnot/dat.h
M port/devnonet.c
M port/proc.c
M port/stnoether.c
M power/clock.c
M power/dat.h
M power/devhotrod.c
M power/fns.h
M power/trap.c
M ss/dat.h
M gnot/dat.h => gnot/dat.h +0 -3
@@ 220,9 220,6 @@ struct Mach
	Lock	alarmlock;		/* access to alarm list */
	void	*alarm;			/* alarms bound to this clock */
	int	fpstate;		/* state of fp registers on machine */
	void	(*intr)(ulong, ulong);	/* !!Compatability with mips!! */
	ulong	cause;			/*	... */
	ulong	pc;			/*	... */
	int	stack[1];
};


M port/devnonet.c => port/devnonet.c +4 -16
@@ 489,7 489,7 @@ noclose(Queue *q)
		 */
		nosendctl(cp, NO_HANGUP, 1);
		for(i=0; i<10 && !ishungup(cp); i++){
			nosendctl(cp, NO_HANGUP, 1);
			nosendctl(cp, NO_HANGUP, 0);
			tsleep(&cp->r, ishungup, cp, MSrexmit);
		}
		break;


@@ 1009,20 1009,10 @@ nosend(Noconv *cp, Nomsg *mp)
	wq = ifc->wq->next;

	/*
	 *  one transmitter at a time for this connection
	 */
	qlock(&cp->xlock);

	if(waserror()){
		qunlock(&cp->xlock);
		return;
	}

	/*
	 *  get the next acknowledge to use if the next queue up
	 *  is not full.
	 */
	if(cp->afirst != cp->anext && cp->rq->next->len < 16*1024){
	if(cp->afirst!=cp->anext && cp->rq->next->len<16*1024){
		cp->hdr->ack = cp->ack[cp->afirst];
		cp->afirst = (cp->afirst+1)&Nmask;
	}


@@ 1103,8 1093,6 @@ nosend(Noconv *cp, Nomsg *mp)
	else
		mp->time = NOW + (cp->rexmit+1)*MSrexmit;
	(*wq->put)(wq, pkt);
	qunlock(&cp->xlock);
	poperror();
}

/*


@@ 1409,9 1397,9 @@ loop:
			 */
			if(cp->first!=cp->next && NOW>=cp->out[cp->first].time){
				mp = &(cp->out[cp->first]);
				if(cp->rexmit++ > 60){
				if(cp->rexmit++ > 15){
					norack(cp, mp->mid);
					nohangup(cp);
					noreset(cp);
				} else
					nosend(cp, mp);
			}

M port/proc.c => port/proc.c +1 -7
@@ 94,10 94,6 @@ sched(void)
		}
		gotolabel(&m->sched);
	}
	if(f = m->intr){			/* assign = */
		m->intr = 0;
		(*f)(m->cause, m->pc);
	}
	spllo();
	p = runproc();
	splhi();


@@ 320,10 316,8 @@ postnote(Proc *p, int dolock, char *n, int flag)
	if(p != u->p){
		k = kmap(p->upage);
		up = (User*)VA(k);
	}else{
		SET(k);
	}else
		up = u;
	}
	if(flag!=NUser && (up->notify==0 || up->notified))
		up->nnote = 0;	/* force user's hand */
	else if(up->nnote == NNOTE-1){

M port/stnoether.c => port/stnoether.c +8 -0
@@ 120,6 120,7 @@ noetherbad(Noifc *ifc, Block *bp)
	Etherhdr *eh, *neh;
	int circuit;
	Block *nbp;
	int r;

	/*
	 *  crack the packet header


@@ 132,6 133,13 @@ noetherbad(Noifc *ifc, Block *bp)
		goto out;

	/*
	 *  only one reset per message
	 */
	r = (eh->remain[1]<<8) | eh->remain[0];
	if(r<0)
		goto out;

	/*
	 *  craft an error reply
	 */
	print("sending reset\n");

M power/clock.c => power/clock.c +11 -7
@@ 81,29 81,26 @@ clockinit(void)


void
clock(ulong n, ulong pc)
clock(Ureg *ur)
{
	int i;
	Proc *p;

	if(n&INTR2){
	if(ur->cause & INTR2){
		i = *CLRTIM0;
		USED(i);
		m->ticks++;
		if(m->machno == 0){
			p = m->proc;
			if(p == 0)
				p = m->intrp;
			if(p)
				p->time[p->insyscall]++;
			for(i=1; i<conf.nmach; i++){
				if(active.machs & (1<<i)){
					p = MACHP(i)->proc;
					if(p && p!=m->intrp)
					if(p)
						p->time[p->insyscall]++;
				}
			}
			m->intrp = 0;
			printslave();
		}
		if(active.exiting && active.machs&(1<<m->machno)){


@@ 111,9 108,16 @@ clock(ulong n, ulong pc)
			exit();
		}
		checkalarms();
		p = m->proc;
		if((ur->status&IEP) && p && p->state==Running){
			if(anyready())
				sched();
			if(u->nnote && (ur->status&KUP))
				notify(ur);
		}
		return;
	}
	if(n & INTR4){
	if(ur->cause & INTR4){
		extern ulong start;

		i = *CLRTIM1;

M power/dat.h => power/dat.h +17 -7
@@ 11,6 11,7 @@ typedef struct Envp	Envp;
typedef struct Envval	Envval;
typedef struct Etherpkt	Etherpkt;
typedef struct FPsave	FPsave;
typedef struct Hotmsg	Hotmsg;
typedef struct Lance	Lance;
typedef struct Lancemem	Lancemem;
typedef struct Label	Label;


@@ 91,6 92,12 @@ struct Bit3msg
	ulong	rcount;
};

struct Hotmsg
{
	ulong	cmd;
	ulong	param[5];
};

#define	CHDIR	0x80000000L
struct Chan
{


@@ 207,10 214,6 @@ struct Mach
	Label	sched;			/* scheduler wakeup */
	Lock	alarmlock;		/* access to alarm list */
	void	*alarm;			/* alarms bound to this clock */
	void	(*intr)(ulong, ulong);	/* pending interrupt */
	Proc	*intrp;			/* process that was interrupted */
	ulong	cause;			/* arg to intr */
	ulong	pc;			/* pc that was interrupted */
	char	pidhere[NTLBPID];	/* is this pid possibly in this mmu? */
	int	lastpid;		/* last pid allocated on this machine */
	Proc	*pidproc[NTLBPID];	/* process that owns this tlbpid on this mach */


@@ 360,11 363,18 @@ struct User
	Chan	*fd[NFD];
	int	maxfd;			/* highest fd in use */
	/*
	 * I/O point for bit3 interface.  This is the easiest way to allocate
	 * I/O point for bit3 and hotrod interfaces.
	 * This is the easiest way to allocate
	 * them, but not the prettiest or most general.
	 */
	Bit3msg	kbit3;
	Bit3msg	ubit3;
	union{
		Bit3msg	kbit3;
		Hotmsg	khot;
	};
	union{
		Bit3msg	ubit3;
		Hotmsg	uhot;
	};
	/*
	 * Rest of structure controlled by devproc.c and friends.
	 * lock(&p->debug) to modify.

M power/devhotrod.c => power/devhotrod.c +88 -78
@@ 9,59 9,72 @@
#include	"io.h"

typedef struct Hotrod	Hotrod;
typedef struct HotQ	HotQ;
typedef struct Device	Device;
typedef struct Printbuf	Printbuf;

enum {
	Vmevec=		0xd2,		/* vme vector for interrupts */
	Intlevel=	5,		/* level to interrupt on */
	Nhotrod=	2,
	Qdir=		0,		/* Qid's */
	Qhotrod=	1,
	NhotQ=		10,		/* size of communication queues */
	Nhotrod=	1,
};

/*
 *  circular 2 pointer queue for hotrod prnt's
 */
struct Printbuf {
	char	*rptr;
	char	*wptr;
	char	*lim;
	char	buf[4*1024];
};

/*
 *  the hotrod fiber interface responds to 1MB
 *  The hotrod fiber interface responds to 1MB
 *  of either user or supervisor accesses at:
 *  	0x30000000 to 0x300FFFFF  in	A32 space
 *  and	  0xB00000 to   0xBFFFFF  in	A24 space
 *  and	  0xB00000 to   0xBFFFFF  in	A24 space.
 *  The second 0x40000 of this space is on-board SRAM.
 */
struct Device {
	ulong	mem[1024*1024/sizeof(ulong)];
	ulong	mem[0x100000/sizeof(ulong)];
};
#define HOTROD		VMEA24SUP(Device, 0xB00000)

struct Hotrod {
	QLock;
struct HotQ{
	ulong	i;			/* index into queue */
	Hotmsg	*msg[NhotQ];		/* pointer to command buffer */
	ulong	pad[3];			/* unused; for hotrod prints */
};


struct Hotrod{
	QLock;
	Lock		busy;
	Device		*addr;		/* address of the device */
	int		vec;		/* vme interrupt vector */
	char		name[NAMELEN];	/* hot rod name */
	Printbuf	pbuf;		/* circular queue for hotrod print's */
	int		kprocstarted;
	HotQ		*wq;		/* write this queue to send cmds */
	int		wi;		/* where to write next cmd */
	HotQ		rq;		/* read this queue to receive replies */
	int		ri;		/* where to read next response */
	Rendez		r;
};

Hotrod hotrod[Nhotrod];

void	hotrodintr(int);
void	hotrodkproc(void *a);

int
hotrodgen(Chan *c, Dirtab *tab, int ntab, int i, Dir *dp)
/*
 * Commands
 */
enum{
	RESET=	0,	/* params: Q address, length of queue */
	REBOOT=	1,	/* params: none */
};

void
hotsend(Hotrod *h, Hotmsg *m)
{
	if(i || c->dev>=Nhotrod)
		return -1;
	devdir(c, (Qid){0,0}, hotrod[c->dev].name, sizeof(Device), 0666, dp);
	return 1;
print("hotsend send %d %lux %lux\n", m->cmd, m, m->param[0]);
	h->wq->msg[h->wi] = m;
	while(h->wq->msg[h->wi])
		;
print("hotsend done\n");
	h->wi++;
	if(h->wi >= NhotQ)
		h->wi = 0;
}

/*


@@ 73,11 86,14 @@ hotrodreset(void)
	int i;
	Hotrod *hp;

	for(i=0; i<Nhotrod; i++){
		hotrod[i].addr = HOTROD+i;
		hotrod[i].vec = Vmevec+i;
		sprint(hotrod[i].name, "hotrod%d", i);
		setvmevec(hotrod[i].vec, hotrodintr);
	for(hp=hotrod,i=0; i<Nhotrod; i++,hp++){
		hp->addr = HOTROD+i;
		/*
		 * Write queue is at end of hotrod memory
		 */
		hp->wq = (HotQ*)((ulong)hp->addr+2*0x40000-sizeof(HotQ));
		hp->vec = Vmevec+i;
		setvmevec(hp->vec, hotrodintr);
	}	
	wbflush();
	delay(20);


@@ 102,10 118,6 @@ hotrodattach(char *spec)
	if(i >= Nhotrod)
		error(Ebadarg);

	hp = &hotrod[i];
	if(hp->kprocstarted == 0)
		kproc(hp->name, hotrodkproc, hp);

	c = devattach('H', spec);
	c->dev = i;
	c->qid.path = CHDIR;


@@ 122,13 134,20 @@ hotrodclone(Chan *c, Chan *nc)
int	 
hotrodwalk(Chan *c, char *name)
{
	return devwalk(c, name, 0, 0, hotrodgen);
	if(c->qid.path != CHDIR)
		return 0;
	if(strncmp(name, "hotrod", 6) == 0){
		c->qid.path = Qhotrod;
		return 1;
	}
	return 0;
}

void	 
hotrodstat(Chan *c, char *dp)
{
	devstat(c, dp, 0, 0, hotrodgen);
	print("hotrodstat\n");
	error(Egreg);
}

Chan*


@@ 137,19 156,28 @@ hotrodopen(Chan *c, int omode)
	Device *dp;
	Hotrod *hp;

#ifdef asdf
	/*
	 *  Remind hotrod where the print buffer is.  The address we store
	 *  is the address of the printbuf in VME A32 space.
	 */
	hp = &hotrod[c->dev];
	dp = hp->addr;
	dp->mem[256*1024/sizeof(ulong)] = (((ulong)&hp->pbuf) - KZERO) | (SLAVE<<28);
#endif

	if(c->qid.path == CHDIR){
		if(omode != OREAD)
			error(Eperm);
	}else if(c->qid.path == Qhotrod){
		hp = &hotrod[c->dev];
		if(!canlock(&hp->busy))
			error(Einuse);
		/*
		 * Clear communications region
		 */
		memset(hp->wq->msg, 0, sizeof(hp->wq->msg));
		hp->wq->i = 0;

		/*
		 * Issue reset
		 */
		hp->wi = 0;
		hp->ri = 0;
		u->khot.cmd = RESET;
		u->khot.param[0] = (ulong)&hp->rq;
		u->khot.param[1] = NhotQ;
		hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->khot);
	}
	c->mode = openmode(omode);
	c->flag |= COPEN;


@@ 166,6 194,14 @@ hotrodcreate(Chan *c, char *name, int omode, ulong perm)
void	 
hotrodclose(Chan *c)
{
	Hotrod *hp;

	hp = &hotrod[c->dev];
	if(c->qid.path != CHDIR){
		u->khot.cmd = REBOOT;
		hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->khot);
		unlock(&hp->busy);
	}
}

/*


@@ 180,8 216,8 @@ hotrodread(Chan *c, void *buf, long n)
	ulong *to;
	ulong *end;

	if(c->qid.path & CHDIR)
		return devdirread(c, buf, n, 0, 0, hotrodgen);
	if(c->qid.path != Qhotrod)
		error(Egreg);

	/*
	 *  allow full word access only


@@ 222,6 258,8 @@ hotrodwrite(Chan *c, void *buf, long n)
	ulong *to;
	ulong *end;

	if(c->qid.path != Qhotrod)
		error(Egreg);
	/*
	 *  allow full word access only
	 */


@@ 272,31 310,3 @@ hotrodintr(int vec)
		return;
	}
}

/*
 *  print hotrod processor messages on the console
 */
void
hotrodkproc(void *a)
{
	Hotrod	*hp = a;
	char	*p;

	hp->kprocstarted = 1;
	hp->pbuf.rptr = hp->pbuf.wptr = hp->pbuf.buf;
	hp->pbuf.lim = &hp->pbuf.buf[sizeof(hp->pbuf.buf)];

	for(;;){
		p = hp->pbuf.wptr;
		if(p != hp->pbuf.rptr){
			if(p > hp->pbuf.rptr){
				putstrn(hp->pbuf.rptr, p - hp->pbuf.rptr);
			} else {
				putstrn(hp->pbuf.rptr, hp->pbuf.lim - hp->pbuf.rptr);
				putstrn(hp->pbuf.buf, hp->pbuf.wptr - hp->pbuf.buf);
			}
			hp->pbuf.rptr = p;
		}
		tsleep(&(hp->r), return0, 0, 1000);
	}
}

M power/fns.h => power/fns.h +4 -2
@@ 1,6 1,7 @@
Alarm	*alarm(int, void (*)(Alarm*), void*);
void	alarminit(void);
Block	*allocb(ulong);
int	anyready(void);
void	append(List**, List*);
void	arginit(void);
void	cancel(Alarm*);


@@ 10,7 11,7 @@ void	chaninit(void);
void	chandevreset(void);
void	chandevinit(void);
void	checkalarms(void);
void	clock(ulong, ulong);
void	clock(Ureg*);
void	clockinit(void);
Chan	*clone(Chan*, Chan*);
void	close(Chan*);


@@ 84,7 85,7 @@ void	*ialloc(ulong, int);
void	icflush(void *, int);
int	incref(Ref*);
void	insert(List**, List*, List*);
void	intr(ulong, ulong);
void	intr(Ureg*);
void	invalidateu(void);
void	ioboardinit(void);
void	isdir(Chan*);


@@ 120,6 121,7 @@ int	nonetcksum(Block*, int);
void	nonetfreeifc(Noifc*);
Noifc*	nonetnewifc(Queue*, Stream*, int, int, int, void (*)(Noconv*, char*));
void	nonetrcvmsg(Noconv*, Block*);
void	notify(Ureg*);
void	novme(int);
void	nullput(Queue*, Block*);
void	online(void);

M power/trap.c => power/trap.c +6 -13
@@ 12,7 12,6 @@
 */
void	(*vmevec[256])(int);

void	notify(Ureg*);
void	noted(Ureg**);
void	rfnote(Ureg**);



@@ 87,7 86,6 @@ trap(Ureg *ur)
		u->p->pc = ur->pc;		/* BUG */
	switch(ecode){
	case CINT:
		m->intrp = 0;
		if(u && u->p->state==Running){
			if(u->p->fpstate == FPactive) {
				if(ur->cause & INTR3){	/* FP trap */


@@ 100,14 98,8 @@ trap(Ureg *ur)
				if(ecode == FPEXC)
					goto Default;
			}
			m->intr = intr;
			m->cause = ur->cause;
			m->pc = ur->pc;
			if(ur->cause & INTR2)
				m->intrp = u->p;
			sched();
		}else
			intr(ur->cause, ur->pc);
		}
		intr(ur);
		break;

	case CTLBM:


@@ 181,14 173,15 @@ trap(Ureg *ur)
}

void
intr(ulong cause, ulong pc)
intr(Ureg *ur)
{
	int i, pend;
	long v;
	ulong cause;

	cause &= INTR5|INTR4|INTR3|INTR2|INTR1;
	cause = ur->cause&(INTR5|INTR4|INTR3|INTR2|INTR1);
	if(cause & (INTR2|INTR4)){
		clock(cause, pc);
		clock(ur);
		cause &= ~(INTR2|INTR4);
	}
	if(cause & INTR1){

M ss/dat.h => ss/dat.h +0 -3
@@ 222,9 222,6 @@ struct Mach
	Lock	alarmlock;		/* access to alarm list */
	void	*alarm;			/* alarms bound to this clock */
	int	fpstate;		/* state of fp registers on machine */
	void	(*intr)(ulong, ulong);	/* !!Compatibility with mips!! */
	ulong	cause;			/*	... */
	ulong	pc;			/*	... */
	char	pidhere[NTLBPID];	/* is this tlbpid possibly in this mmu? */
	int	lastpid;		/* last pid allocated on this machine */
	Proc	*pidproc[NTLBPID];	/* process that owns this pid on this mach */