Browse Source

Plan 9 from Bell Labs 2012-04-17

David du Colombier 12 years ago
parent
commit
dd1df06531

+ 13 - 4
sys/lib/backup/backup

@@ -1,20 +1,26 @@
 #!/bin/rc
-# backup [-n] [-d dev] [-s set] - backup venti arenas to disc set using dev
+# backup [-np] [-d dev] [-s set] - backup venti arenas to disc set using dev
 #	and record that.  also print recent fossil dump scores.
+#
+# it would be good to have some way to cope with truncated tracks left
+# by write errors causing fewer tracks than expected to fit on a disc.
+
 rfork ne
 cd /sys/lib/backup
 . funcs
 bind -a . /bin
 
 done=0
+print=yes
 while (~ $done 0 && ! ~ $#* 0 && ~ $1 -*) {
 	switch ($1) {
 	case -d;	rdev=$2; shift
 	case -n;	debug=yes		# don't dump; use with -s test
+	case -p;	print=no
 	case -s;	set=$2 ; shift
 	case --;	done = 1		# no break in rc, alas
 	case -*
-		echo usage: $0 '[-n] [-d dev] [-s set]' >[1=2]
+		echo usage: $0 '[-np] [-d dev] [-s set]' >[1=2]
 		exit usage
 	}
 	shift
@@ -51,7 +57,10 @@ fn backup1 {
 	disc1arenas=()
 	if (! ~ $disc1trks 0)
 		disc1arenas=`{sed $disc1trks^q arenas}
-	if (! ~ $#disc1arenas 0 && ! ~ $disc1trks 0 && backupdisc $disc1arenas){
+	if (! ~ $#disc1arenas 0 && ! ~ $disc1trks 0) {
+		backupdisc $disc1arenas
+		quitonfailure $status
+
 		tracks = `{hoc -e $tracks+$#disc1arenas}
 		if (test $tracks -ge $ntracks) {
 			disc=`{hoc -e $disc+1}
@@ -80,7 +89,7 @@ if (test -s disc)
 if not
 	updprog
 
-if (! ~ $debug yes && ~ $set set1) {
+if (! ~ $debug yes && ~ $set set1 && ~ $print yes) {
 	9fs log
 	# don't hang in lp
 	tail -50 /n/$fs/sys/log/fs.archive |

+ 10 - 3
sys/lib/backup/backuparenas

@@ -17,12 +17,19 @@ unmount /mnt/cd >[2]/dev/null
 cdfs -d $1 || exit
 shift
 
+grep next /mnt/cd/ctl
+echo -n 'nwa ok? '
+ok=`{read}
+if (! ~ $ok [Yy]*)
+	exit bad-nwa
+
 cd $fsroot/dev/fs
 for (name) {
 	grep next /mnt/cd/ctl
-	if (! {venti/rdarena arena0 $name |
-	    pump -i 65536 -o 1048576 -k 51200 -d 10 >/mnt/cd/wd/$name})
-		exit
+	venti/rdarena arena0 $name |
+		pump -i 65536 -o 1048576 -k 51200 -d 10 >/mnt/cd/wd/$name
+	quitonfailure $status
+
 #	ls -l /mnt/cd
 	if (test -e '/env/fn#dumpdone' -a -e '/env/set')
 		dumpdone arena0 $name

+ 5 - 2
sys/man/8/backup

@@ -4,7 +4,7 @@ backup, tobackup, dumparenas, restore \- backup venti arenas to blu-ray discs or
 .SH SYNOPSIS
 .B backup
 [
-.B -n
+.B -np
 ] [
 .B -d
 .I dev
@@ -69,7 +69,10 @@ run on the default dump set,
 .LR set1 ,
 will also print the last few
 .I fossil
-dump scores.
+dump scores
+unless the
+.B -p
+option is given.
 .PP
 .I Tobackup
 prints the names of all the sealed arenas not yet backed up to a disc

+ 33 - 1
sys/src/9/pc/dat.h

@@ -2,7 +2,10 @@ typedef struct BIOS32si	BIOS32si;
 typedef struct BIOS32ci	BIOS32ci;
 typedef struct Conf	Conf;
 typedef struct Confmem	Confmem;
+typedef union FPanystate FPanystate;
 typedef struct FPsave	FPsave;
+typedef struct FPssestate FPssestate;
+typedef struct FPstate	FPstate;
 typedef struct ISAConf	ISAConf;
 typedef struct Label	Label;
 typedef struct Lock	Lock;
@@ -67,7 +70,7 @@ enum
 	FPillegal=	0x100,
 };
 
-struct	FPsave
+struct	FPstate			/* x87 fpu state */
 {
 	ushort	control;
 	ushort	r1;
@@ -84,6 +87,34 @@ struct	FPsave
 	uchar	regs[80];	/* floating point registers */
 };
 
+struct	FPssestate			/* SSE fp state */
+{
+	ushort	fcw;		/* control */
+	ushort	fsw;		/* status */
+	ushort	ftw;		/* tag */
+	ushort	fop;		/* opcode */
+	ulong	fpuip;		/* pc */
+	ushort	cs;		/* pc segment */
+	ushort	r1;		/* reserved */
+	ulong	fpudp;		/* data pointer */
+	ushort	ds;		/* data pointer segment */
+	ushort	r2;
+	ulong	mxcsr;		/* MXCSR register state */
+	ulong	mxcsr_mask;	/* MXCSR mask register */
+	uchar	xregs[480];	/* extended registers */
+};
+
+#define FPalign	16	/* required for FXSAVE */
+
+union FPanystate {
+	FPstate;
+	FPssestate;
+};
+
+struct FPsave {
+	FPanystate *addr;	/* addr of fp state if it is alloced */ 
+};
+
 struct Confmem
 {
 	ulong	base;
@@ -293,6 +324,7 @@ enum {
 //	Pse2	= 1<<17,	/* more page size extensions */
 	Clflush = 1<<19,
 	Mmx	= 1<<23,
+	Fxsr	= 1<<24,	/* have SSE FXSAVE/FXRSTOR */
 	Sse	= 1<<25,	/* thus sfence instr. */
 	Sse2	= 1<<26,	/* thus mfence & lfence instr.s */
 };

+ 14 - 0
sys/src/9/pc/devarch.c

@@ -37,6 +37,11 @@ enum {
 
 	Qmax = 16,
 };
+
+enum {
+	CR4Osfxsr = 1 << 9,
+};
+
 enum {				/* cpuid standard function codes */
 	Highstdfunc = 0,	/* also returns vendor string */
 	Procsig,
@@ -839,6 +844,15 @@ cpuidentify(void)
 			rdmsr(0x01, &mct);
 	}
 
+	if(m->cpuiddx & Fxsr){			/* have sse fp? */
+		fpsave = fpssesave;
+		fprestore = fpsserestore;
+		putcr4(getcr4() | CR4Osfxsr);
+	} else {
+		fpsave = fpx87save;
+		fprestore = fpx87restore;
+	}
+
 	cputype = t;
 	return t->family;
 }

+ 6 - 2
sys/src/9/pc/fns.h

@@ -31,9 +31,13 @@ void	fpclear(void);
 void	fpenv(FPsave*);
 void	fpinit(void);
 void	fpoff(void);
-void	fprestore(FPsave*);
-void	fpsave(FPsave*);
+void	(*fprestore)(FPsave*);
+void	(*fpsave)(FPsave*);
+void	fpsserestore(FPsave*);
+void	fpssesave(FPsave*);
 ulong	fpstatus(void);
+void	fpx87restore(FPsave*);
+void	fpx87save(FPsave*);
 ulong	getcr0(void);
 ulong	getcr2(void);
 ulong	getcr3(void);

+ 34 - 14
sys/src/9/pc/l.s

@@ -17,6 +17,8 @@
 #define HLT		BYTE $0xF4
 #define INVLPG	BYTE $0x0F; BYTE $0x01; BYTE $0x39	/* INVLPG (%ecx) */
 #define WBINVD	BYTE $0x0F; BYTE $0x09
+#define FXSAVE		BYTE $0x0f; BYTE $0xae; BYTE $0x00  /* SSE FP save */
+#define FXRSTOR		BYTE $0x0f; BYTE $0xae; BYTE $0x08  /* SSE FP restore */
 
 /*
  * Macros for calculating offsets within the page directory base
@@ -754,13 +756,8 @@ _aamloop:
  * FNxxx variations) so WAIT instructions must be explicitly placed in the
  * code as necessary.
  */
-#define	FPOFF(l)						 ;\
-	MOVL	CR0, AX 					 ;\
-	ANDL	$0xC, AX			/* EM, TS */	 ;\
-	CMPL	AX, $0x8					 ;\
-	JEQ 	l						 ;\
+#define	FPOFF							 ;\
 	WAIT							 ;\
-l:								 ;\
 	MOVL	CR0, AX						 ;\
 	ANDL	$~0x4, AX			/* EM=0 */	 ;\
 	ORL	$0x28, AX			/* NE=1, TS=1 */ ;\
@@ -772,7 +769,7 @@ l:								 ;\
 	MOVL	AX, CR0
 	
 TEXT fpoff(SB), $0				/* disable */
-	FPOFF(l1)
+	FPOFF
 	RET
 
 TEXT fpinit(SB), $0				/* enable and init */
@@ -787,15 +784,19 @@ TEXT fpinit(SB), $0				/* enable and init */
 	WAIT
 	RET
 
-TEXT fpsave(SB), $0				/* save state and disable */
-	MOVL	p+0(FP), AX
+/* fpx87save(&fpstateptr) */
+TEXT fpx87save(SB), $0				/* save state and disable */
+	MOVL	p+0(FP), AX			/* points to pointer */
+	MOVL	(AX), AX			/* now points to state buffer */
 	FSAVE	0(AX)				/* no WAIT */
-	FPOFF(l2)
+	FPOFF
 	RET
 
-TEXT fprestore(SB), $0				/* enable and restore state */
+/* fpx87restore(&fpstateptr) */
+TEXT fpx87restore(SB), $0			/* enable and restore state */
 	FPON
-	MOVL	p+0(FP), AX
+	MOVL	p+0(FP), AX			/* points to pointer */
+	MOVL	(AX), AX			/* now points to state buffer */
 	FRSTOR	0(AX)
 	WAIT
 	RET
@@ -804,15 +805,34 @@ TEXT fpstatus(SB), $0				/* get floating point status */
 	FSTSW	AX
 	RET
 
+/* fpenv(&fpstateptr) */
 TEXT fpenv(SB), $0				/* save state without waiting */
-	MOVL	p+0(FP), AX
+	MOVL	p+0(FP), AX			/* points to pointer */
+	MOVL	(AX), AX			/* now points to state buffer */
 	FSTENV	0(AX)
 	RET
 
 TEXT fpclear(SB), $0				/* clear pending exceptions */
 	FPON
 	FCLEX					/* no WAIT */
-	FPOFF(l3)
+	FPOFF
+	RET
+
+/* fpssesave(&fpstateptr) */
+TEXT fpssesave(SB), $0				/* save state and disable */
+	MOVL	p+0(FP), AX			/* points to pointer */
+	MOVL	(AX), AX			/* now points to state buffer */
+	FXSAVE					/* no WAIT */
+	FPOFF
+	RET
+
+/* fpsserestore(&fpstateptr) */
+TEXT fpsserestore(SB), $0				/* enable and restore state */
+	FPON
+	MOVL	p+0(FP), AX			/* points to pointer */
+	MOVL	(AX), AX			/* now points to state buffer */
+	FXRSTOR
+	WAIT
 	RET
 
 /*

+ 60 - 8
sys/src/9/pc/main.c

@@ -465,14 +465,37 @@ static char* mathmsg[] =
 	"precision loss",
 };
 
+static void
+mathstate(ulong *status, ulong *pc, ulong *control)
+{
+	ulong sts, fpc, ctl;
+	FPanystate *f = (FPanystate *)up->fpsave.addr;
+
+	if(fpsave == fpx87save){
+		sts = f->status;
+		fpc = f->pc;
+		ctl = f->control;
+	} else {
+		sts = f->fsw;
+		fpc = f->fpuip;
+		ctl = f->fcw;
+	}
+	if(status)
+		*status = sts;
+	if(pc)
+		*pc = fpc;
+	if(control)
+		*control = ctl;
+}
+
 static void
 mathnote(void)
 {
 	int i;
-	ulong status;
+	ulong status, pc;
 	char *msg, note[ERRMAX];
 
-	status = up->fpsave.status;
+	mathstate(&status, &pc, nil);
 
 	/*
 	 * Some attention should probably be paid here to the
@@ -495,16 +518,37 @@ mathnote(void)
 			msg = "invalid operation";
 	}
 	snprint(note, sizeof note, "sys: fp: %s fppc=0x%lux status=0x%lux",
-		msg, up->fpsave.pc, status);
+		msg, pc, status);
 	postnote(up, 1, note, NDebug);
 }
 
+static void
+fpexit(void)
+{
+	free(up->fpsave.addr);
+	up->fpsave.addr = nil;
+}
+
+static void*
+fpalloc(void)
+{
+	if(up->fpsave.addr == nil) {
+		up->fpsave.addr = fpsave == fpx87save? smalloc(sizeof(FPstate)):
+			mallocalign(sizeof(FPssestate), FPalign, 0, 0);
+		if (up->fpsave.addr)
+			up->fpexit = fpexit;
+	}
+	return up->fpsave.addr;
+}
+
 /*
  *  math coprocessor error
  */
 static void
 matherror(Ureg *ur, void*)
 {
+	ulong status, pc;
+
 	/*
 	 *  a write cycle to port 0xF0 clears the interrupt latch attached
 	 *  to the error# line from the 387
@@ -512,15 +556,18 @@ matherror(Ureg *ur, void*)
 	if(!(m->cpuiddx & 0x01))
 		outb(0xF0, 0xFF);
 
+	fpalloc();
+
 	/*
 	 *  save floating point state to check out error
 	 */
 	fpenv(&up->fpsave);
 	mathnote();
 
-	if((ur->pc & 0xf0000000) == KZERO)
-		panic("fp: status %ux fppc=0x%lux pc=0x%lux",
-			up->fpsave.status, up->fpsave.pc, ur->pc);
+	if((ur->pc & 0xf0000000) == KZERO){
+		mathstate(&status, &pc, nil);
+		panic("fp: status %#lux fppc=%#lux pc=%#lux", status, pc, ur->pc);
+	}
 }
 
 /*
@@ -529,6 +576,8 @@ matherror(Ureg *ur, void*)
 static void
 mathemu(Ureg *ureg, void*)
 {
+	ulong status, control;
+
 	if(up->fpstate & FPillegal){
 		/* someone did floating point in a note handler */
 		postnote(up, 1, "sys: floating point in note handler", NDebug);
@@ -536,6 +585,7 @@ mathemu(Ureg *ureg, void*)
 	}
 	switch(up->fpstate){
 	case FPinit:
+		fpalloc();
 		fpinit();
 		up->fpstate = FPactive;
 		break;
@@ -547,7 +597,8 @@ mathemu(Ureg *ureg, void*)
 		 * More attention should probably be paid here to the
 		 * exception masks and error summary.
 		 */
-		if((up->fpsave.status & ~up->fpsave.control) & 0x07F){
+		mathstate(&status, nil, &control);
+		if((status & ~control) & 0x07F){
 			mathnote();
 			break;
 		}
@@ -623,7 +674,8 @@ procsave(Proc *p)
 			 * until the process runs again and generates an
 			 * emulation fault to activate the FPU.
 			 */
-			fpsave(&p->fpsave);
+			if(p->fpsave.addr != nil)
+				fpsave(&p->fpsave);
 		}
 		p->fpstate = FPinactive;
 	}

+ 3 - 3
sys/src/9/pc/mkfile

@@ -92,10 +92,10 @@ $p%.gz:D:	$p%
 	strip -o /fd/1 9pccd | gzip -9 >9pccd.gz
 
 
-install:V:	$p$CONF $p$CONF.gz
-	cp $p$CONF $p$CONF.gz /$objtype/
+install:V:	$p$CONF
+	cp $p$CONF /$objtype/
 	for(i in $EXTRACOPIES)
-		import $i / /n/$i && cp $p$CONF $p$CONF.gz /n/$i/$objtype/
+		import $i / /n/$i && cp $p$CONF /n/$i/$objtype/
 
 <../boot/bootmkfile
 <../port/portmkfile

+ 2 - 0
sys/src/9/port/master

@@ -2,6 +2,7 @@
 
 $	pnp
 /	root
+9	p9am
 A	audio
 A	uda1341
 B	bridge
@@ -57,6 +58,7 @@ y	pcmcia
 μ	moipv6
 ⁲	twsi
 ↔	usbcons
+☹	bios
 霞	kasumi
 
 α	local use

+ 4 - 0
sys/src/9/port/portdat.h

@@ -229,6 +229,9 @@ struct Dev
 	int	(*wstat)(Chan*, uchar*, int);
 	void	(*power)(int);	/* power mgt: power(1) => on, power (0) => off */
 	int	(*config)(int, char*, DevConf*);	/* returns nil on error */
+
+	/* not initialised */
+	int	attached;				/* debugging */
 };
 
 struct Dirtab
@@ -704,6 +707,7 @@ struct Proc
 	void	*kparg;
 
 	FPsave	fpsave;		/* address of this is known by db */
+	void	(*fpexit)(void); /* if non-nil, called by pexit */
 	int	scallnr;	/* sys call number - known by db */
 	Sargs	s;		/* address of this is known by db */
 	int	nerrlab;

+ 3 - 0
sys/src/9/port/proc.c

@@ -1047,6 +1047,9 @@ pexit(char *exitstr, int freemem)
 
 	if(up->syscalltrace)
 		free(up->syscalltrace);
+	up->fpstate = FPinit;
+	if(up->fpexit)
+		up->fpexit();
 	up->alarm = 0;
 	if (up->tt)
 		timerdel(up);

+ 2 - 2
sys/src/cmd/aan.c

@@ -79,13 +79,13 @@ static void
 usage(void)
 {
 	fprint(2, "Usage: %s [-cd] [-m maxto] dialstring|netdir\n", progname);
-	exits("usage");
+	threadexitsall("usage");
 }
 
 static int
 catch(void *, char *s)
 {
-	if (!strcmp(s, "alarm")) {
+	if (strcmp(s, "alarm") == 0) {
 		syslog(0, Logname, "Timed out while waiting for client on %s, exiting...",
 			   devdir);
 		threadexitsall(nil);

+ 1 - 1
sys/src/cmd/usb/usbd/mkfile

@@ -35,5 +35,5 @@ $LIBU:
 	mk clean
 
 devtab.c: usbdb ../lib/usb.h mkdev
-	mkdev >$target
+	./mkdev >$target