~kris/9p

9hist

920fe64e4f04de28f4e8eead34b2188974505c87 — David du Colombier 32 years ago 320e99c
Plan 9 from Bell Labs 1994-03-11
12 files changed, 233 insertions(+), 26 deletions(-)

M boot/boot.c
M boot/boot.h
M carrera/dat.h
M carrera/fns.h
M carrera/l.s
M carrera/trap.c
M pc/dat.h
M pc/devvga.c
M pc/mem.h
M port/portfns.h
M port/proc.c
M port/qio.c
M boot/boot.c => boot/boot.c +55 -22
@@ 13,6 13,7 @@ char	sys[2*NAMELEN];
char	username[NAMELEN];
char	bootfile[3*NAMELEN];
char	conffile[NAMELEN];
char 	reply[64];
int	printcol;
int	mflag;
int	fflag;


@@ 23,6 24,8 @@ int	afd = -1;
static void	swapproc(void);
static void	recover(Method*);
static Method	*rootserver(char*);
char	*bargv[6];
int	bargc;

void
boot(int argc, char *argv[])


@@ 38,6 41,7 @@ boot(int argc, char *argv[])
	open("#c/cons", OREAD);
	open("#c/cons", OWRITE);
	open("#c/cons", OWRITE);
	bind("#c", "/dev", MAFTER);
#ifdef DEBUG
	print("argc=%d\n", argc);
	for(fd = 0; fd < argc; fd++)


@@ 149,6 153,29 @@ boot(int argc, char *argv[])
	fatal(cmd);
}

Method*
findmethod(char *a)
{
	Method *mp;
	int i, j;
	char *cp;

	i = strlen(a);
	cp = strchr(a, '!');
	if(cp)
		i = cp - a;
	for(mp = method; mp->name; mp++){
		j = strlen(mp->name);
		if(j > i)
			j = i;
		if(strncmp(a, mp->name, j) == 0)
			break;
	}
	if(mp->name)
		return mp;
	return 0;
}

/*
 *  ask user from whence cometh the root file system
 */


@@ 156,45 183,51 @@ Method*
rootserver(char *arg)
{
	char prompt[256];
	char reply[64];
	Method *mp;
	char *cp;
	int n, j;
	int n;
	int notfirst;

	/* make list of methods */
	mp = method;
	n = sprint(prompt, "root is from (%s", mp->name);
	for(mp++; mp->name; mp++)
		n += sprint(prompt+n, ", %s", mp->name);
	sprint(prompt+n, ")");

	strcpy(reply, method->name);
	if(arg){
		j = strlen(arg);
		for(mp = method; mp->name; mp++)
			if(strncmp(arg, mp->name, j) == 0)
				break;
		if(mp->name)
			strcpy(reply, arg);
	/* create default reply */
	readfile("#e/bootargs", reply, sizeof(reply));
	if(reply[0] == 0 && arg != 0)
		strcpy(reply, arg);
	if(reply[0]){
		mp = findmethod(reply);
		if(mp == 0)
			reply[0] = 0;
	}
	if(reply[0] == 0)
		strcpy(reply, method->name);

	/* parse replies */
	for(notfirst = 0;; notfirst = 1){
		if(pflag || notfirst)
			outin(prompt, reply, sizeof(reply));
		cp = strchr(reply, '!');
		if(cp)
			j = cp - reply;
		else
			j = strlen(reply);
		for(mp = method; mp->name; mp++)
			if(strncmp(reply, mp->name, j) == 0){
				if(cp)
					strcpy(sys, cp+1);
				return mp;
		mp = findmethod(reply);
		if(mp){
			for(cp = reply; *cp; cp++){
				while(*cp && *cp != ' ')
					cp++;
				while(*cp == ' ')
					*cp++ = 0;
				if(*cp)
					bargv[bargc++] = cp;
			}
		if(mp->name == 0)
			continue;
			cp = strchr(reply, '!');
			if(cp)
				strcpy(sys, cp+1);
			return mp;
		}
	}

	return 0;		/* not reached */
}


M boot/boot.h => boot/boot.h +2 -0
@@ 22,6 22,8 @@ extern char	terminal[];
extern char	username[NAMELEN];
extern char	bootfile[];
extern char	conffile[];
extern int	bargc;
extern char	*bargv[];
extern int	afd;

/* libc equivalent */

M carrera/dat.h => carrera/dat.h +7 -0
@@ 85,6 85,8 @@ struct Notsave

#include "../port/portdat.h"

#define NCALLBACK	32

/* First FOUR members offsets known by l.s */
struct Mach
{


@@ 112,6 114,11 @@ struct Mach
	Schedq	hiq;
	Schedq	loq;

	void	(**cbin)(void);
	void	(**cbout)(void);
	void	(**cbend)(void);
	void	(*calls[NCALLBACK])(void);

	int	pfault;
	int	cs;
	int	syscall;

M carrera/fns.h => carrera/fns.h +9 -1
@@ 125,8 125,16 @@ ushort	nhgets(void*);
void	ifwrite(void*, Block*);
void*	ifinit(int);
void	ifjab(void);
void	fiberint(int);
ulong	ifaddr(void*);
void	filiput(Block*);
void	fiberint(int);
void	audiosbintr(void);
void	audiodmaintr(void);
ulong	fwblock(void*, void*, ulong);
ulong	frblock(void*, void*, ulong);
void	ifree(void*);
Block*	iallocb(int);
void*	ifroute(ulong);
ulong	ifunroute(ulong);
void	parseip(char*, char*);


M carrera/l.s => carrera/l.s +20 -1
@@ 815,7 815,7 @@ TEXT	uvst(SB), $-4		/* uvst(address, src) */
	MOVV	R5, 0(R1)
	RET

TEXT	fwblock(SB), $-4	/* wblock(void*port, void *block, csum) */
TEXT	fwblock(SB), $-4	/* fwblock(void*port, void *block, csum) */
	MOVW	4(FP), R2
	MOVW	8(FP), R3



@@ 833,3 833,22 @@ fwloop:

	MOVW	R3, R1
	RET

TEXT	frblock(SB), $-4	/* frblock(void*port, void *block, csum) */
	MOVW	4(FP), R2
	MOVW	8(FP), R3

	MOVW	$64, R4
frloop:
	MOVV	0(R1), R5
	MOVV	R5, 0(R2)
	ADDU	R5, R3
	SRLV	$32, R5
	ADDU	R5, R3

	ADD	$8, R2
	SUB	$1, R4
	BNE	R4, frloop

	MOVW	R3, R1
	RET

M carrera/trap.c => carrera/trap.c +4 -1
@@ 402,7 402,10 @@ kernfault(Ureg *ur, int code)
	print("kfault %s badvaddr=0x%lux\n", excname[code], ur->badvaddr);
	print("UP=0x%lux SR=0x%lux PC=0x%lux R31=%lux SP=0x%lux\n",
				up, ur->status, ur->pc, ur->r31, ur->sp);
	kpteprint(ur);

	dumpregs(ur);
	splhi();
	for(;;);
	panic("kfault");
}


M pc/dat.h => pc/dat.h +7 -0
@@ 113,6 113,8 @@ struct Notsave
 *  machine dependent definitions not used by ../port/dat.h
 */

#define NCALLBACK	32

struct Mach
{
	int	machno;			/* physical id of processor */


@@ 126,6 128,11 @@ struct Mach
	Schedq	hiq;
	Schedq	loq;

	void	(**cbin)(void);
	void	(**cbout)(void);
	void	(**cbend)(void);
	void	(*calls[NCALLBACK])(void);

	int	tlbfault;
	int	tlbpurge;
	int	pfault;

M pc/devvga.c => pc/devvga.c +32 -1
@@ 146,11 146,12 @@ enum
	Trident,	/* Trident 8900 */
	Tseng,		/* tseng labs te4000 */
	Cirrus,		/* Cirrus CLGD542X */
	S3,
	Generic,
};

static void	nopage(int), tsengpage(int), tridentpage(int), parapage(int);
static void	atipage(int), cirruspage(int);
static void	atipage(int), cirruspage(int), s3page(int);

Vgacard vgachips[] =
{


@@ 159,6 160,7 @@ Vgacard vgachips[] =
[Trident]	{ "trident", tridentpage, },
[Tseng]		{ "tseng", tsengpage, },
[Cirrus]	{ "cirrus", cirruspage, },
[S3]		{ "s3", s3page, },
[Generic]	{ "generic", nopage, },
		{ 0, 0, },
};


@@ 963,6 965,35 @@ parapage(int page)
{
	grout(0x9, page<<4);
}
static void
s3page(int page)
{
#ifdef notdef
	uchar crt51;

	/*
	 * The S3 registers need to be unlocked for this.
	 * Let's hope they are already:
	 *	crout(0x38, 0x48);
	 *	crout(0x39, 0xA0);
	 *
	 * The page is 6 bits, the lower 4 bits in Crt35<3:0>,
	 * the upper 2 in Crt51<3:2>.
	 */
	crout(0x35, page & 0x0F);
	outb(CRX, 0x51);
	crt51 = (0xF3 & inb(CR))|((page & 0x30)>>2);
	outb(CR, crt51);
{
uchar crt35;
outb(CRX, 0x35);
crt35 = inb(CR);
print("page #%ux, crt51=#%ux, crt35=#%ux\n", page, crt51, crt35);
}
#else
	crout(0x35, (page<<2) & 0x0f);
#endif /* notdef
}

void
mousescreenupdate(void)

M pc/mem.h => pc/mem.h +1 -0
@@ 8,6 8,7 @@
#define	BI2BY		8			/* bits per byte */
#define BI2WD		32			/* bits per word */
#define	BY2WD		4			/* bytes per word */
#define	BY2V		8			/* bytes per double word */
#define	BY2PG		4096			/* bytes per page */
#define	WD2PG		(BY2PG/BY2WD)		/* words per page */
#define	PGSHIFT		12			/* log(BY2PG) */

M port/portfns.h => port/portfns.h +3 -0
@@ 15,6 15,8 @@ Page*		auxpage(void);
void		buzz(int, int);
void		cachedel(Image*, ulong);
void		cachepage(Page*, Image*);
void		callbacks(void);
void		newcallback(void (*)(void));
int		cangetc(void*);
int		canlock(Lock*);
int		canpage(Proc*);


@@ 193,6 195,7 @@ void		qinit(void);
int		qlen(Queue*);
void		qlock(QLock*);
Queue*		qopen(int, int, void (*)(void*), void*);
int		qpass(Queue*, Block*);
int		qproduce(Queue*, void*, int);
long		qread(Queue*, void*, int);
void		qreopen(Queue*);

M port/proc.c => port/proc.c +26 -0
@@ 44,6 44,10 @@ char *statename[] =
void
schedinit(void)		/* never returns */
{
	m->cbin = m->calls;
	m->cbout = m->calls;
	m->cbend = &m->calls[NCALLBACK];

	setlabel(&m->sched);
	if(up) {
		m->proc = 0;


@@ 87,6 91,7 @@ sched(void)
		procsave(up);
		if(setlabel(&up->sched)) {
			procrestore(up);
			callbacks();
			spllo();
			return;
		}


@@ 100,6 105,27 @@ sched(void)
	gotolabel(&up->sched);
}

void
newcallback(void (*func)(void))
{
	*m->cbin = func;
	if(++m->cbin >= m->cbend)
		m->cbin = m->calls;
}

void
callbacks(void)
{
	void (*func)(void);

	while(m->cbin != m->cbout) {
		func = *m->cbout;
		if(++m->cbout >= m->cbend)
			m->cbout = m->calls;
		func();
	}
}

int
anyready(void)
{

M port/qio.c => port/qio.c +67 -0
@@ 369,6 369,73 @@ checkb(b, "qconsume 2");
}

int
qpass(Queue *q, Block *b)
{
	int s, i, len;
	int dowakeup;

	s = splhi();

	len = BLEN(b);

	/* sync with qread */
	dowakeup = 0;
	lock(q);

	if(q->syncbuf){
		/* synchronous communications, just copy into buffer */
		if(len < q->synclen)
			q->synclen = len;
		i = q->synclen;
		memmove(q->syncbuf, b->rp, i);
		q->syncbuf = 0;		/* tell reader buffer is full */
		len -= i;
		if(len <= 0 || (q->state & Qmsg)){
			unlock(q);
			wakeup(&q->rr);
			ifree(b);
			splx(s);
			return i;
		}

		/* queue anything that's left */
		dowakeup = 1;
		b->rp += i;
	}

	/* no waiting receivers, room in buffer? */
	if(q->len >= q->limit){
		unlock(q);
		splx(s);
		return -1;
	}

	/* save in buffer */
	if(q->bfirst)
		q->blast->next = b;
	else
		q->bfirst = b;
	q->blast = b;
	q->len += len;
checkb(b, "qproduce");

	if(q->state & Qstarve){
		q->state &= ~Qstarve;
		dowakeup = 1;
	}
	unlock(q);

	if(dowakeup){
		if(q->kick)
			(*q->kick)(q->arg);
		wakeup(&q->rr);
	}
	splx(s);

	return len;
}

int
qproduce(Queue *q, void *vp, int len)
{
	Block *b;