~kris/9p

9hist

ace215e79cb72065fe219e86d3583bbd34da94be — David du Colombier 34 years ago bd4a67d
Plan 9 from Bell Labs 1992-09-02
M boot/boot.c => boot/boot.c +11 -12
@@ 115,19 115,18 @@ boot(int argc, char *argv[])
	 *  if a local file server exists and it's not
	 *  running, start it and mount it onto /n/kfs
	 */
	for(mp = method; mp->name; mp++){
		if(strcmp(mp->name, "local") != 0)
			continue;
		if(access("#s/kfs", ORDWR) >= 0)
			break;
		(*mp->config)(mp);
		fd = (*mp->connect)();
		if(fd < 0)
	if(!islocal){
		for(mp = method; mp->name; mp++){
			if(strcmp(mp->name, "local") != 0)
				continue;
			(*mp->config)(mp);
			fd = (*mp->connect)();
			if(fd < 0)
				break;
			mount(fd, "/n/kfs", MAFTER|MCREATE, "", "") ;
			close(fd);
			break;
		if(mount(fd, "/n/kfs", MAFTER|MCREATE, "", "") < 0)
			print("failed to mount kfs\n");
		close(fd);
		break;
		}
	}

	settime(islocal);

M boot/local.c => boot/local.c +18 -11
@@ 25,16 25,21 @@ connectlocal(void)
{
	int p[2];
	char d[DIRLEN];
	char sbuf[32];
	char rbuf[32];
	char partition[2*NAMELEN];
	char *dev;

	if(stat("/kfs", d) < 0)
	if(stat("/fs", d) < 0)
		return -1;
	sprint(partition, "%sfs", disk ? disk : bootdisk);
	if(stat(partition, d) < 0)
		return -1;
	print("kfs...");

	dev = disk ? disk : bootdisk;
	sprint(partition, "%sfs", dev);
	if(stat(partition, d) < 0){
		strcpy(partition, dev);
		if(stat(partition, d) < 0)
			return -1;
	}

	print("fs...");
	if(bind("#c", "/dev", MREPL) < 0)
		fatal("bind #c");
	if(bind("#p", "/proc", MREPL) < 0)


@@ 45,10 50,12 @@ connectlocal(void)
	case -1:
		fatal("fork");
	case 0:
		sprint(sbuf, "%d", p[0]);
		sprint(rbuf, "%d", p[1]);
		execl("/kfs", "kfs", "-f", partition, "-s", sbuf, rbuf, 0);
		fatal("can't exec kfs");
		dup(p[0], 0);
		dup(p[1], 1);
		close(p[0]);
		close(p[1]);
		execl("/fs", "fs", "-f", partition, "-s", 0);
		fatal("can't exec fs");
	default:
		break;
	}

M pc/dat.h => pc/dat.h +8 -3
@@ 184,7 184,12 @@ extern int	flipD[];	/* for flipping bitblt destination polarity */

enum
{
	At=		0,
	Attnsx=		1,
	PMUnsx20=	0,
	PMUother=	1,

	Mouseserial=	0,
	MousePS2=	1,
	Mouseother=	2,
};
extern int machtype;
extern int mousetype;
extern int pmutype;

M pc/devhard.c => pc/devhard.c +73 -23
@@ 40,6 40,7 @@ enum
	Cident=		0xEC,
	Cident2=	0xFF,	/* pseudo command for post Cident interrupt */
	Csetbuf=	0xEF,
	Cinitparam=	0x91,

	/* file types */
	Qdir=		0,


@@ 159,7 160,8 @@ Drive		*hard;
static void	hardintr(Ureg*);
static long	hardxfer(Drive*, Partition*, int, long, long, char*);
static void	hardident(Drive*);
static void	hardsetbuf(Drive*);
static void	hardsetbuf(Drive*, int);
static void	hardinitparam(Drive*);
static void	hardpart(Drive*);

static int


@@ 239,28 241,32 @@ hardattach(char *spec)

	for(dp = hard; dp < &hard[conf.nhard]; dp++){
		if(!waserror()){
			dp->bytes = 512;
			/*
			 *  the following is magic to determine the parameters
			 *  (number of cylinders/sectors/heads) on an IDE drive.
			 *  I haven't found a method that is guaranteed to work.
			 *  For some drives, it may be necessary to compile the
			 *  numbers into this driver and circumvent this code.
			 *  The BIOS disk type & tables doesn't help since the
			 *  types are inconsistent from one BIOS to the next.
			 */
			dp->bytes = 512;	/* until we know better */
			hardsetbuf(dp, 0);	/* turned off during ident */
			hardident(dp);
			hardsetbuf(dp, 1);
			/*
			 *  for now use the configuration word to identify the
			 *  wayward 6386 disk.  BUG!!!  This word isn't
			 *  meant to identify disks, but we have nothing
			 *  better.
			 */
			switch(dp->id.magic){
			case 0xA5A:	/* conner drive on the AT&T NSX (safari) */
				dp->cyl = dp->id.lcyls;
				dp->heads = dp->id.lheads;
				dp->sectors = dp->id.ls2t;
				hardsetbuf(dp);
				break;
			case 0x324A:	/* hard drive on the AT&T 6386 */
			case 0x324A:	/* hard drive on the AT&T 6386, it lies */
				dp->cyl = dp->id.lcyls - 4;
				dp->heads = dp->id.lheads;
				dp->sectors = dp->id.ls2t - 1;
				break;
			default:	/* others: we hope this works */
				if (drivecomment) {
					print("unknown hard disk type, magic=%04x",
						dp->id.magic);
					print("  cyl=%d h=%d sec=%d\n",
						dp->id.lcyls, dp->id.lheads, dp->id.ls2t);
				}
			case 0x427a:	/* for now: a list of those that work */
				dp->cyl = dp->id.lcyls;
				dp->heads = dp->id.lheads;
				dp->sectors = dp->id.ls2t;


@@ 269,7 275,23 @@ hardattach(char *spec)
			dp->bytes = 512;
			dp->cap = dp->bytes * dp->cyl * dp->heads * dp->sectors;
			dp->online = 1;
			hardpart(dp);
			/*
			 *  Try reading the partition table (last disk sector).
			 *  If an error occurs set the drive parameters and try
			 *  again.  This works if the parameters reported
			 *  by the disk are the physical parameters rather than
			 *  the current logical ones (as they are on the NCR 3170).
			 *
			 *  We don't routinely set the parameters since it confuses
			 *  some disks (on the Gateway and AT&T Safari for example).
			 */
			if(waserror()){
				hardinitparam(dp);	/* set drive parameters */
				hardpart();
			} else {
				hardpart();
				poperror();
			}
			poperror();
		} else
			dp->online = 0;


@@ 579,7 601,7 @@ hardxfer(Drive *dp, Partition *pp, int cmd, long start, long len, char *buf)
 *  set read ahead mode
 */
static void
hardsetbuf(Drive *dp)
hardsetbuf(Drive *dp, int on)
{
	Controller *cp = dp->cp;



@@ 592,7 614,7 @@ hardsetbuf(Drive *dp)
	cmdreadywait(cp);

	cp->cmd = Csetbuf;
	outb(cp->pbase+Pprecomp, 0xAA);
	outb(cp->pbase+Pprecomp, on ? 0xAA : 0x55);
	outb(cp->pbase+Pdh, 0x20 | (dp->drive<<4));
	outb(cp->pbase+Pcmd, Csetbuf);



@@ 607,6 629,37 @@ hardsetbuf(Drive *dp)
}

/*
 *  set the drive parameters
 */
static void
hardinitparam(Drive *dp)
{
	Controller *cp = dp->cp;

	qlock(cp);
	if(waserror()){
		qunlock(cp);
		nexterror();
	}

	cmdreadywait(cp);

	cp->cmd = Cinitparam;
	outb(cp->pbase+Psector, dp->sectors);
	outb(cp->pbase+Pdh, 0x20 | (dp->heads-1) | (dp->drive<<4));
	outb(cp->pbase+Pcmd, Cinitparam);

	sleep(&cp->r, cmddone, cp);

	if(cp->status & Serr)
		DPRINT("hd%d initparam err: status %lux, err %lux\n",
			dp-hard, cp->status, cp->error);

	poperror();
	qunlock(cp);
}

/*
 *  get parameters from the drive
 */
static void


@@ 865,6 918,7 @@ hardintr(Ureg *ur)
			wakeup(&cp->r);
		}
		break;
	case Cinitparam:
	case Csetbuf:
		cp->lastcmd = cp->cmd;
		cp->cmd = 0;


@@ 874,10 928,6 @@ hardintr(Ureg *ur)
		cp->lastcmd = cp->cmd;
		cp->cmd = 0;
		break;
	case 0:
		print("interrupt cmd=0, lastcmd=%02x status=%02x\n",
			cp->lastcmd, cp->status);
		break;
	default:
		print("weird disk interrupt, cmd=%02x, status=%02x\n",
			cp->cmd, cp->status);

M pc/devrtc.c => pc/devrtc.c +1 -1
@@ 92,7 92,7 @@ rtcopen(Chan *c, int omode)
	omode = openmode(omode);
	switch(c->qid.path){
	case Qrtc:
		if(omode != OREAD && strcmp(u->p->user, eve)!=0)
		if(strcmp(u->p->user, eve)!=0 && omode!=OREAD)
			error(Eperm);
		break;
	case Qnvram:

M pc/kbd.c => pc/kbd.c +25 -5
@@ 182,6 182,19 @@ i8042a20(void)
	outready();
}

/*
 *  ask 8042 to reset the machine
 */
void
i8042reset(void)
{
	outready();
	outb(Cmd, 0xD1);
	outready();
	outb(Data, 0xDE);
	outready();
}

void
kbdinit(void)
{


@@ 194,8 207,8 @@ kbdinit(void)
		if(c & Inready)
			inb(Data);

	switch(machtype){
	case Attnsx:
	switch(mousetype){
	case MousePS2:
		bigcursor();
		setvec(Mousevec, kbdintr);



@@ 216,7 229,7 @@ kbdinit(void)
		/* turn on mouse acceleration */
		mouseaccelerate(0);
		break;
	case At:
	case Mouseserial:
		/* enable kbd xfers and interrupts */
		outb(Cmd, 0x60);
		if(outready() < 0)


@@ 226,6 239,13 @@ kbdinit(void)
		/* set up /dev/eia0 as the mouse */
		uartspecial(0, 0, &mouseq, 1200);
		break;
	case Mouseother:
		/* enable kbd xfers and interrupts */
		outb(Cmd, 0x60);
		if(outready() < 0)
			print("kbd init failed\n");
		outb(Data, 0x65);
		break;
	}
}



@@ 236,8 256,8 @@ void
mouseaccelerate(int on)
{

	switch(machtype){
	case Attnsx:
	switch(mousetype){
	case MousePS2:
		if(on)
			mousecmd(0xE7);
		else

M pc/main.c => pc/main.c +30 -40
@@ 7,14 7,15 @@
#include	"ureg.h"
#include	"init.h"

int machtype;	/* machine type, mostly for power management */
int mousetype;
int pmutype;
uchar	*sp;	/* stack pointer for /boot */

void
main(void)
{
	ident();
	meminit();
	i8042a20();		/* enable address lines 20 and up */
	machinit();
	active.exiting = 0;
	active.machs = 1;


@@ 39,16 40,26 @@ main(void)
	schedinit();
}

/*
 *  this should be changed to describe architecture dependencies outside the
 *  PC model
 */
void
ident(void)
{
	char *id = (char*)(ROMBIOS + 0xFF40);

	/* check for a safari (tres special) */
	if(strncmp(id, "AT&TNSX", 7) == 0)
		machtype = Attnsx;
	else
		machtype = At;
	if(strncmp(id, "AT&TNSX", 7) == 0){
		mousetype = MousePS2;
		pmutype = PMUnsx20;
	}else if(strncmp(id, "NCRD.0", 6) == 0){
		mousetype = MousePS2;
		pmutype = PMUother;
	}else{
		mousetype = Mouseserial;
		pmutype = PMUother;
	}
}

void


@@ 243,7 254,6 @@ confinit(void)
	conf.npage0 -= ktop/BY2PG;
	conf.base0 += ktop;

	/* for meminit() */
	conf.topofmem = i*MB;

	conf.monitor = 1;


@@ 393,20 403,6 @@ procrestore(Proc *p)
 *  PC to PC.
 */

/* enable address bit 20 (extended memory) */
void
meminit(void)
{
	switch(machtype){
	case Attnsx:
		heada20();		/* via headland chip */
		break;
	case At:
		i8042a20();		/* via keyboard controller */
		break;
	}
}

/*
 *  reset the i387 chip
 */


@@ 417,15 413,9 @@ exit(int ispanic)
	print("exiting\n");
	if(ispanic)
		for(;;);
	switch(machtype){
	case Attnsx:
		headreset();		/* via headland chip */
		break;
	case At:
		print("hit the button...");
		for(;;);
		putcr3(0);		/* crash and burn */
	}
	i8042reset();		/* via keyboard controller */
	print("can't reset via software, do something drastic!\n");
	for(;;);
}

/*


@@ 436,8 426,8 @@ exit(int ispanic)
int
cpuspeed(int speed)
{
	switch(machtype){
	case Attnsx:
	switch(pmutype){
	case PMUnsx20:
		return pmucpuspeed(speed);
	default:
		return 0;


@@ 451,8 441,8 @@ cpuspeed(int speed)
void
buzz(int f, int d)
{
	switch(machtype){
	case Attnsx:
	switch(pmutype){
	case PMUnsx20:
		pmubuzz(f, d);
		break;
	default:


@@ 466,8 456,8 @@ buzz(int f, int d)
void
lights(int val)
{
	switch(machtype){
	case Attnsx:
	switch(pmutype){
	case PMUnsx20:
		pmulights(val);
		break;
	default:


@@ 483,8 473,8 @@ lights(int val)
int
serial(int onoff)
{
	switch(machtype){
	case Attnsx:
	switch(pmutype){
	case PMUnsx20:
		return pmuserial(onoff);
	default:
		return 0;


@@ 499,8 489,8 @@ serial(int onoff)
int
modem(int onoff)
{
	switch(machtype){
	case Attnsx:
	switch(pmutype){
	case PMUnsx20:
		return pmumodem(onoff);
	default:
		return 0;

M port/devcdrom.c => port/devcdrom.c +0 -2
@@ 226,8 226,6 @@ cdromsize(int dev)
		error(Ecap);

	scsiinquiry(dev, buf, sizeof buf);
	if(buf[0]!=5 || buf[0]!=4)	/* CD-ROM or CD-R writer */
		print("warning: scsi device %d type=%d, not type 4 or 5\n", dev>>3, buf[0]);
	dp->drive = dev;
	dp->blocks = nb;
	dp->bsize = bs;

M port/devroot.c => port/devroot.c +12 -12
@@ 16,15 16,15 @@ enum{

	Qboot,
	Qcfs,
	Qkfs,
	Qfs,
};

extern long	cfslen;
extern ulong	cfscode[];
extern long	kfslen;
extern ulong	kfscode[];
extern long	fslen;
extern ulong	fscode[];
extern ulong	bootlen;
extern ulong	bootcode[];
extern uchar	bootcode[];

Dirtab rootdir[]={
	"bin",		{Qbin|CHDIR},	0,			0777,


@@ 37,7 37,7 @@ Dirtab rootdir[]={
#define	NROOT	(sizeof rootdir/sizeof(Dirtab))
Dirtab rootpdir[]={
	"cfs",		{Qcfs},		0,			0777,
	"kfs",		{Qkfs},		0,			0777,
	"fs",		{Qfs},		0,			0777,
};
Dirtab *rootmap[sizeof rootpdir/sizeof(Dirtab)];
int	nroot;


@@ 67,7 67,7 @@ rootreset(void)
	i = 0;
	if(cfslen)
		rootmap[i++] = &rootpdir[0];
	if(kfslen)
	if(fslen)
		rootmap[i++] = &rootpdir[1];
	nroot = NROOT + i;
}


@@ 142,7 142,7 @@ rootread(Chan *c, void *buf, long n, ulong offset)
			return 0;
		if(offset+n > bootlen)
			n = bootlen - offset;
		memmove(buf, ((char*)bootcode)+offset, n);
		memmove(buf, bootcode+offset, n);
		return n;

	case Qcfs:		/* cfs */


@@ 153,12 153,12 @@ rootread(Chan *c, void *buf, long n, ulong offset)
		memmove(buf, ((char*)cfscode)+offset, n);
		return n;

	case Qkfs:		/* kfs */
		if(offset >= kfslen)
	case Qfs:		/* fs */
		if(offset >= fslen)
			return 0;
		if(offset+n > kfslen)
			n = kfslen - offset;
		memmove(buf, ((char*)kfscode)+offset, n);
		if(offset+n > fslen)
			n = fslen - offset;
		memmove(buf, ((char*)fscode)+offset, n);
		return n;

	case Qdev:

M port/portdat.h => port/portdat.h +1 -1
@@ 732,7 732,7 @@ extern	int	cpuserver;
extern	char*	devchar;
extern	Dev	devtab[];
extern  char	eve[];
extern	ulong	initcode[];
extern	uchar	initcode[];
extern	FPsave	initfp;
extern  KIOQ	kbdq;
extern  IOQ	lineq;

M port/proc.c => port/proc.c +5 -2
@@ 529,8 529,11 @@ pexit(char *exitstr, int freemem)
	 * do some housekeeping.
	 */
	if(c->kp == 0) {
		if((p = c->parent) == 0)
			panic("boot process died");
		if((p = c->parent) == 0) {
			if(exitstr == 0)
				exitstr = "unknown";
			panic("boot process died: %s", exitstr);
		}

		while(waserror())
			;	

M power/devrtc.c => power/devrtc.c +3 -3
@@ 100,9 100,9 @@ rtcopen(Chan *c, int omode)
	omode = openmode(omode);
	switch(c->qid.path){
	case Qrtc:
		if(omode == OREAD)
			break;
		/* fall through */
		if(strcmp(u->p->user, eve)!=0 && omode!=OREAD)
			error(Eperm);
		break;
	case Qnvram:
		if(strcmp(u->p->user, eve)!=0 || !cpuserver)
			error(Eperm);

M ss/devrtc.c => ss/devrtc.c +3 -3
@@ 92,9 92,9 @@ rtcopen(Chan *c, int omode)
	omode = openmode(omode);
	switch(c->qid.path){
	case Qrtc:
		if(omode == OREAD)
			break;
		/* fall through */
		if(strcmp(u->p->user, eve)!=0 && omode!=OREAD)
			error(Eperm);
		break;
	case Qnvram:
		if(strcmp(u->p->user, eve)!=0 || !cpuserver)
			error(Eperm);