Browse Source

Plan 9 from Bell Labs 2006-01-14

David du Colombier 18 years ago
parent
commit
1136e83433

+ 9 - 7
dist/replica/_plan9.db

@@ -7772,18 +7772,19 @@ sys/src/9/alphapc/fns.h - 664 sys sys 1131289707 3613
 sys/src/9/alphapc/fptrap.c - 664 sys sys 1015012785 707
 sys/src/9/alphapc/i8259.c - 664 sys sys 1015012785 3409
 sys/src/9/alphapc/initcode - 664 sys sys 1039753419 779
-sys/src/9/alphapc/io.h - 664 sys sys 1087657423 4540
+sys/src/9/alphapc/io.h - 664 sys sys 1137179966 4618
 sys/src/9/alphapc/kbd.c - 664 sys sys 1015012785 8676
-sys/src/9/alphapc/l.s - 664 sys sys 1067722580 9124
-sys/src/9/alphapc/main.c - 664 sys sys 1131289707 13672
-sys/src/9/alphapc/mem.h - 664 sys sys 1077408326 3131
+sys/src/9/alphapc/l.s - 664 sys sys 1137179966 9141
+sys/src/9/alphapc/main.c - 664 sys sys 1137179966 13675
+sys/src/9/alphapc/mem.h - 664 sys sys 1137179967 2312
 sys/src/9/alphapc/memmove.s - 664 sys sys 1015012786 2936
 sys/src/9/alphapc/memset.s - 664 sys sys 1015012786 844
 sys/src/9/alphapc/mkfile - 664 sys sys 1109218102 1682
 sys/src/9/alphapc/mmu.c - 664 sys sys 1131538486 4981
+sys/src/9/alphapc/osf1pal.h - 664 sys sys 1137179966 1471
 sys/src/9/alphapc/pci.c - 664 sys sys 1039753420 7868
 sys/src/9/alphapc/screen.h - 664 sys sys 1131289708 3818
-sys/src/9/alphapc/sd53c8xx.c - 664 sys sys 1132448433 50964
+sys/src/9/alphapc/sd53c8xx.c - 664 sys sys 1137179967 55257
 sys/src/9/alphapc/sio.c - 664 sys sys 1015012787 293
 sys/src/9/alphapc/trap.c - 664 sys sys 1105030177 18099
 sys/src/9/bitsy - 20000000775 sys sys 1018721429 0
@@ -8952,15 +8953,16 @@ sys/src/boot/alphapc/dat.h - 664 sys sys 954267449 2716
 sys/src/boot/alphapc/exec.c - 664 sys sys 954267449 785
 sys/src/boot/alphapc/fns.h - 664 sys sys 954479197 1056
 sys/src/boot/alphapc/ip.h - 664 sys sys 954267449 2434
-sys/src/boot/alphapc/l.s - 664 sys sys 954479198 1496
+sys/src/boot/alphapc/l.s - 664 sys sys 1137178711 1513
 sys/src/boot/alphapc/lib.h - 664 sys sys 954267449 3219
 sys/src/boot/alphapc/main.c - 664 sys sys 954479198 344
-sys/src/boot/alphapc/mem.h - 664 sys sys 954267450 802
+sys/src/boot/alphapc/mem.h - 664 sys sys 1137178711 363
 sys/src/boot/alphapc/memory.c - 664 sys sys 954479198 2075
 sys/src/boot/alphapc/mkfile - 664 sys sys 1045537256 449
 sys/src/boot/alphapc/mmu.c - 664 sys sys 954479198 2736
 sys/src/boot/alphapc/print.c - 664 sys sys 954267450 7971
 sys/src/boot/alphapc/u.h - 664 sys sys 954267450 687
+sys/src/boot/alphapc/vmspal.h - 664 sys sys 1137178711 2580
 sys/src/boot/arm - 20000000775 sys sys 1017696239 0
 sys/src/boot/arm/dat.h - 664 sys sys 985642785 0
 sys/src/boot/arm/donprint.c - 664 sys sys 985642785 4089

+ 9 - 7
dist/replica/plan9.db

@@ -7772,18 +7772,19 @@ sys/src/9/alphapc/fns.h - 664 sys sys 1131289707 3613
 sys/src/9/alphapc/fptrap.c - 664 sys sys 1015012785 707
 sys/src/9/alphapc/i8259.c - 664 sys sys 1015012785 3409
 sys/src/9/alphapc/initcode - 664 sys sys 1039753419 779
-sys/src/9/alphapc/io.h - 664 sys sys 1087657423 4540
+sys/src/9/alphapc/io.h - 664 sys sys 1137179966 4618
 sys/src/9/alphapc/kbd.c - 664 sys sys 1015012785 8676
-sys/src/9/alphapc/l.s - 664 sys sys 1067722580 9124
-sys/src/9/alphapc/main.c - 664 sys sys 1131289707 13672
-sys/src/9/alphapc/mem.h - 664 sys sys 1077408326 3131
+sys/src/9/alphapc/l.s - 664 sys sys 1137179966 9141
+sys/src/9/alphapc/main.c - 664 sys sys 1137179966 13675
+sys/src/9/alphapc/mem.h - 664 sys sys 1137179967 2312
 sys/src/9/alphapc/memmove.s - 664 sys sys 1015012786 2936
 sys/src/9/alphapc/memset.s - 664 sys sys 1015012786 844
 sys/src/9/alphapc/mkfile - 664 sys sys 1109218102 1682
 sys/src/9/alphapc/mmu.c - 664 sys sys 1131538486 4981
+sys/src/9/alphapc/osf1pal.h - 664 sys sys 1137179966 1471
 sys/src/9/alphapc/pci.c - 664 sys sys 1039753420 7868
 sys/src/9/alphapc/screen.h - 664 sys sys 1131289708 3818
-sys/src/9/alphapc/sd53c8xx.c - 664 sys sys 1132448433 50964
+sys/src/9/alphapc/sd53c8xx.c - 664 sys sys 1137179967 55257
 sys/src/9/alphapc/sio.c - 664 sys sys 1015012787 293
 sys/src/9/alphapc/trap.c - 664 sys sys 1105030177 18099
 sys/src/9/bitsy - 20000000775 sys sys 1018721429 0
@@ -8952,15 +8953,16 @@ sys/src/boot/alphapc/dat.h - 664 sys sys 954267449 2716
 sys/src/boot/alphapc/exec.c - 664 sys sys 954267449 785
 sys/src/boot/alphapc/fns.h - 664 sys sys 954479197 1056
 sys/src/boot/alphapc/ip.h - 664 sys sys 954267449 2434
-sys/src/boot/alphapc/l.s - 664 sys sys 954479198 1496
+sys/src/boot/alphapc/l.s - 664 sys sys 1137178711 1513
 sys/src/boot/alphapc/lib.h - 664 sys sys 954267449 3219
 sys/src/boot/alphapc/main.c - 664 sys sys 954479198 344
-sys/src/boot/alphapc/mem.h - 664 sys sys 954267450 802
+sys/src/boot/alphapc/mem.h - 664 sys sys 1137178711 363
 sys/src/boot/alphapc/memory.c - 664 sys sys 954479198 2075
 sys/src/boot/alphapc/mkfile - 664 sys sys 1045537256 449
 sys/src/boot/alphapc/mmu.c - 664 sys sys 954479198 2736
 sys/src/boot/alphapc/print.c - 664 sys sys 954267450 7971
 sys/src/boot/alphapc/u.h - 664 sys sys 954267450 687
+sys/src/boot/alphapc/vmspal.h - 664 sys sys 1137178711 2580
 sys/src/boot/arm - 20000000775 sys sys 1017696239 0
 sys/src/boot/arm/dat.h - 664 sys sys 985642785 0
 sys/src/boot/arm/donprint.c - 664 sys sys 985642785 4089

+ 9 - 0
dist/replica/plan9.log

@@ -24800,3 +24800,12 @@
 1137081716 2 c sys/src/games/mahjongg/level.c - 664 sys sys 1137080360 2560
 1137081716 3 c sys/src/games/mahjongg/mahjongg.c - 664 sys sys 1137080360 3631
 1137081716 4 c sys/src/games/mahjongg/mahjongg.h - 664 sys sys 1137080360 1687
+1137178824 0 c sys/src/boot/alphapc/l.s - 664 sys sys 1137178711 1513
+1137178824 1 c sys/src/boot/alphapc/mem.h - 664 sys sys 1137178711 363
+1137178824 2 a sys/src/boot/alphapc/vmspal.h - 664 sys sys 1137178711 2580
+1137180625 0 c sys/src/9/alphapc/io.h - 664 sys sys 1137179966 4618
+1137180625 1 c sys/src/9/alphapc/l.s - 664 sys sys 1137179966 9141
+1137180625 2 c sys/src/9/alphapc/main.c - 664 sys sys 1137179966 13675
+1137180625 3 c sys/src/9/alphapc/mem.h - 664 sys sys 1137179967 2312
+1137180625 4 a sys/src/9/alphapc/osf1pal.h - 664 sys sys 1137179966 1471
+1137180625 5 c sys/src/9/alphapc/sd53c8xx.c - 664 sys sys 1137179967 55257

+ 6 - 1
sys/src/9/alphapc/io.h

@@ -127,10 +127,14 @@ typedef struct Pcidev {
 	ushort	vid;			/* vendor ID */
 	ushort	did;			/* device ID */
 
+	ushort	pcr;
+
 	uchar	rid;
 	uchar	ccrp;
 	uchar	ccru;
 	uchar	ccrb;
+	uchar	cls;
+	uchar	ltr;
 
 	struct {
 		ulong	bar;		/* base address */
@@ -147,7 +151,8 @@ typedef struct Pcidev {
 		ulong	bar;
 		int	size;
 	} ioa, mema;
-	ulong	pcr;
+
+	int	pmrb;			/* power management register block */
 };
 
 #define PCIWINDOW	0x40000000

+ 17 - 16
sys/src/9/alphapc/l.s

@@ -1,4 +1,5 @@
 #include "mem.h"
+#include "osf1pal.h"
 
 #define SP	R30
 
@@ -174,22 +175,22 @@ tas2:
 	RET
 
 TEXT	_xdec(SB), $-8
-	MOVQ	R0, R1		/* p */
+	MOVQ	R0, R1			/* p */
 dec1:
 	MOVLL	(R1), R0		/* *p */
-	SUBL		$1, R0
+	SUBL	$1, R0
 	MOVQ	R0, R2
 	MOVLC	R2, (R1)		/* --(*p) */
-	BEQ		R2, dec1		/* write failed, retry */
+	BEQ	R2, dec1		/* write failed, retry */
 	RET
 
 TEXT	_xinc(SB), $-8
-	MOVQ	R0, R1		/* p */
+	MOVQ	R0, R1			/* p */
 inc1:
 	MOVLL	(R1), R0		/* *p */
 	ADDL	$1, R0
 	MOVLC	R0, (R1)		/* (*p)++ */
-	BEQ		R0, inc1		/* write failed, retry */
+	BEQ	R0, inc1		/* write failed, retry */
 	RET
 
 TEXT	fpenab(SB), $-8
@@ -222,25 +223,25 @@ TEXT	arith(SB), $-8
 	SUBQ	$(4*BY2WD+31*BY2V), R30
 	MOVQ	R0, (4*BY2WD+4*BY2V)(R30)
 	MOVQ	$1, R0
-	JMP		trapcommon
+	JMP	trapcommon
 
 TEXT	illegal0(SB), $-8
 	SUBQ	$(4*BY2WD+31*BY2V), R30
 	MOVQ	R0, (4*BY2WD+4*BY2V)(R30)
 	MOVQ	$2, R0
-	JMP		trapcommon
+	JMP	trapcommon
 
 TEXT	fault0(SB), $-8
 	SUBQ	$(4*BY2WD+31*BY2V), R30
 	MOVQ	R0, (4*BY2WD+4*BY2V)(R30)
 	MOVQ	$4, R0
-	JMP		trapcommon
+	JMP	trapcommon
 
 TEXT	unaligned(SB), $-8
 	SUBQ	$(4*BY2WD+31*BY2V), R30
 	MOVQ	R0, (4*BY2WD+4*BY2V)(R30)
 	MOVQ	$6, R0
-	JMP		trapcommon
+	JMP	trapcommon
 
 TEXT	intr0(SB), $-8
 	SUBQ	$(4*BY2WD+31*BY2V), R30
@@ -283,12 +284,12 @@ trapcommon:
 	MOVQ	$HI_IPL, R16
 	CALL_PAL $PALswpipl
 
-	CALL_PAL	$PALrdusp
+	CALL_PAL $PALrdusp
 	MOVQ	R0, (4*BY2WD+30*BY2V)(R30)	/* save USP */
 
 	MOVQ	$mach0(SB), R(MACH)
 	MOVQ	$(4*BY2WD)(R30), R0
-	JSR		trap(SB)
+	JSR	trap(SB)
 trapret:
 	MOVQ	(4*BY2WD+30*BY2V)(R30), R16	/* USP */
 	CALL_PAL $PALwrusp			/* ... */
@@ -320,10 +321,10 @@ trapret:
 	MOVQ	(4*BY2WD+29*BY2V)(R30), R28
 	/* USP already restored from (4*BY2WD+30*BY2V)(R30) */
 	ADDQ	$(4*BY2WD+31*BY2V), R30
-	CALL_PAL	$PALrti
+	CALL_PAL $PALrti
 
 TEXT	forkret(SB), $0
-	MOVQ	R31, R0			/* Fake out system call return */
+	MOVQ	R31, R0				/* Fake out system call return */
 	JMP	systrapret
 
 TEXT	syscall0(SB), $-8
@@ -339,10 +340,10 @@ TEXT	syscall0(SB), $-8
 	JSR	syscall(SB)
 systrapret:
 	MOVQ	(4*BY2WD+30*BY2V)(R30), R16	/* USP */
-	CALL_PAL $PALwrusp		/* consider doing this in execregs... */
+	CALL_PAL $PALwrusp			/* consider doing this in execregs... */
 	MOVQ	(4*BY2WD+27*BY2V)(R30), R26	/* restore last return address */
 	ADDQ	$(4*BY2WD+31*BY2V), R30
-	CALL_PAL	$PALretsys
+	CALL_PAL $PALretsys
 
 /*
  * Take first processor into user mode
@@ -355,7 +356,7 @@ TEXT	touser(SB), $-8
 	SUBQ	$(6*BY2V), R30			/* create frame for retsys */
 	MOVQ	$(UTZERO+32), R26		/* header appears in text */
 	MOVQ	R26, (1*BY2V)(R30)		/* PC -- only reg that matters */
-	CALL_PAL	$PALretsys
+	CALL_PAL $PALretsys
 
 TEXT	rfnote(SB), $0
 	SUBL	$(2*BY2WD), R0, SP

+ 1 - 1
sys/src/9/alphapc/main.c

@@ -134,7 +134,7 @@ enum {
 	Cpuhaltcoldboot = 0x20000,
 	Cpuhaltwarmboot = 0x30000,
 	Cpuhaltstayhalted = 0x40000,
-	Cpumustbezero = 0xffffffffff000000,	/* 24:63 -- must be zero */
+	Cpumustbezero = 0xffffffffff000000ULL,	/* 24:63 -- must be zero */
 };
 
 /*

+ 0 - 40
sys/src/9/alphapc/mem.h

@@ -79,46 +79,6 @@
 #define	KTZERO	(KZERO+0x400000)	/* first address in kernel text */
 #define	USTKSIZE	(4*1024*1024)	/* size of user stack */
 
-/*
- * Palcode instructions a la OSF/1
- */
-#define	PALbpt		0x80
-#define	PALbugchk	0x81
-#define	PALcallsys	0x83
-#define	PALimb		0x86
-#define	PALgentrap	0xaa
-#define	PALrdunique	0x9e
-#define	PALwrunique	0x9f
-
-#define	PALhalt		0x00
-#define	PALdraina	0x02
-#define	PALcserve	0x09
-#define	PALrdps		0x36
-#define	PALrdusp	0x3a
-#define	PALrdval	0x32
-#define	PALretsys	0x3d
-#define	PALrti		0x3f
-#define	PALswpctx	0x30
-#define	PALswpipl	0x35
-#define	PALtbi		0x33
-#define	PALwhami	0x3c
-#define	PALwrent	0x34
-#define	PALwrfen	0x2b
-#define	PALwrkgp	0x37
-#define	PALwrusp	0x38
-#define	PALwrval	0x31
-#define	PALwrvptptr	0x2d
-
-/*
- * Plus some useful VMS ones (needed at early boot time)
- */
-#define	PALmfpr_pcbb	0x12
-#define	PALmfpr_ptbr	0x15
-#define	PALmfpr_vptb	0x29
-#define	PALldqp		0x03
-#define	PALstqp		0x04
-#define	PALswppal	0x0a
-
 /*
  * Processor Status (as returned by rdps)
  */

+ 78 - 0
sys/src/9/alphapc/osf1pal.h

@@ -0,0 +1,78 @@
+/*
+ * OSF/1 PALcode instructions, in numerical order.
+ * Values are from Digital EBSDK and FreeBSD/Alpha.
+ */
+
+/* Privilaged PAL functions */
+#define	PALhalt		0x00	/* required per Alpha architecture */
+#define	PALcflush	0x01
+#define	PALdraina	0x02	/* required per Alpha architecture */
+/*
+ * ... 0x03 to 0x08 ?
+ */
+#define	PALcserve	0x09
+#define	PALswppal	0x0a
+/*
+ * ... 0x0b to 0x0c ?
+ */
+#define	PALwripir	0x0d
+/*
+ * ... 0x0e to 0x0f ?
+ */
+#define	PALrdmces	0x10
+#define	PALwrmces	0x11
+/*
+ * ... 0x12 to 0x2a ?
+ */
+#define	PALwrfen	0x2b
+				/* 0x2c OSF/1 ? */
+#define	PALwrvptptr	0x2d
+/*
+ * ... 0x2e to 0x2f ?
+ */
+#define	PALswpctx	0x30
+#define	PALwrval	0x31
+#define	PALrdval	0x32
+#define	PALtbi		0x33
+#define	PALwrent	0x34
+#define	PALswpipl	0x35
+#define	PALrdps		0x36
+#define	PALwrkgp	0x37
+#define	PALwrusp	0x38
+#define	PALwrperfmon	0x39
+#define	PALrdusp	0x3a
+				/* 0x3b OSF/1 ? */
+#define	PALwhami	0x3c
+#define	PALretsys	0x3d
+#define	PALwtint	0x3e
+#define	PALrti		0x3f
+
+/* Unprivileged PAL functions */
+#define	PALbpt		0x80
+#define	PALbugchk	0x81
+#define	PALcallsys	0x83
+#define	PALimb		0x86	/* required per Alpha architecture */
+/*
+ * ... 0x89 to 0x91 ?
+ */
+#define	PALurti		0x92
+/*
+ * ... 0x93 to 0x9d ?
+ */
+#define	PALrdunique	0x9e
+#define	PALwrunique	0x9f
+/*
+ * ... 0xa0 to 0xa9 ?
+ */
+#define	PALgentrap	0xaa
+/*
+ * ... 0xab to 0xac ?
+ */
+#define	PALdbgstop	0xad
+#define	PALclrfen	0xae
+/*
+ * ... 0xaf to 0xbd ?
+ */
+#define	PALnphalt	0xbe
+#define	PALcopypal	0xbf
+

+ 289 - 102
sys/src/9/alphapc/sd53c8xx.c

@@ -2,6 +2,8 @@
  * NCR/Symbios/LSI Logic 53c8xx driver for Plan 9
  * Nigel Roles (nigel@9fs.org)
  *
+ * 27/5/02	Fixed problems with transfers >= 256 * 512
+ *
  * 13/3/01	Fixed microcode to support targets > 7
  *
  * 01/12/00	Removed previous comments. Fixed a small problem in
@@ -45,13 +47,14 @@ extern SDifc sd53c8xxifc;
 
 #define KPRINT oprint
 #define IPRINT intrprint
-#define DEBUG(n) 0
+#define DEBUG(n) 1
 #define IFLUSH() iflush()
 
 #else
 
-#define KPRINT	if(0)print
-#define IPRINT	if(0)print
+static int idebug = 1;
+#define KPRINT	if(0) iprint
+#define IPRINT	if(idebug) iprint
 #define DEBUG(n)	(0)
 #define IFLUSH()
 
@@ -205,7 +208,10 @@ typedef struct Dsa {
 	uchar dmablks;
 	uchar flag;	/* setbyte(state,3,...) */
 
-	uchar dmaaddr[4];
+	union {
+		ulong dmancr;		/* For block transfer: NCR order (little-endian) */
+		uchar dmaaddr[4];
+	};
 
 	uchar target;			/* Target */
 	uchar pad0[3];
@@ -299,7 +305,6 @@ typedef struct Controller {
 	struct {
 		Lock;
 		uchar head[4];		/* head of free list (NCR byte order) */
-		Dsa	*tail;
 		Dsa	*freechain;
 	} dsalist;
 
@@ -378,30 +383,51 @@ oprint(char *format, ...)
 
 #include "sd53c8xx.i"
 
+/*
+ * We used to use a linked list of Dsas with nil as the terminator,
+ * but occasionally the 896 card seems not to notice that the 0
+ * is really a 0, and then it tries to reference the Dsa at address 0.
+ * To address this, we use a sentinel dsa that links back to itself
+ * and has state A_STATE_END.  If the card takes an iteration or
+ * two to notice that the state says A_STATE_END, that's no big 
+ * deal.  Clearly this isn't the right approach, but I'm just
+ * stumped.  Even with this, we occasionally get prints about
+ * "WSR set", usually with about the same frequency that the
+ * card used to walk past 0. 
+ */
+static Dsa *dsaend;
+
+static Dsa*
+dsaallocnew(Controller *c)
+{
+	Dsa *d;
+	
+	/* c->dsalist must be ilocked */
+	d = xalloc(sizeof *d);
+	lesetl(d->next, legetl(c->dsalist.head));
+	lesetl(&d->stateb, A_STATE_FREE);
+	coherence();
+	lesetl(c->dsalist.head, DMASEG(d));
+	coherence();
+	return d;
+}
+
 static Dsa *
 dsaalloc(Controller *c, int target, int lun)
 {
 	Dsa *d;
 
 	ilock(&c->dsalist);
-	if ((d = c->dsalist.freechain) == 0) {
-		d = xalloc(sizeof(*d));
+	if ((d = c->dsalist.freechain) != 0) {
 		if (DEBUG(1))
-			KPRINT(PRINTPREFIX "%d/%d: allocated new dsa %lux\n", target, lun, (ulong)d);
-		lesetl(d->next, 0);
-		lesetl(&d->stateb, A_STATE_ALLOCATED);
-		if (legetl(c->dsalist.head) == 0)
-			lesetl(c->dsalist.head, DMASEG(d));	/* ATOMIC?!? */
-		else
-			lesetl(c->dsalist.tail->next, DMASEG(d));	/* ATOMIC?!? */
-		c->dsalist.tail = d;
-	}
-	else {
+			IPRINT(PRINTPREFIX "%d/%d: reused dsa %lux\n", target, lun, (ulong)d);
+	} else {	
+		d = dsaallocnew(c);
 		if (DEBUG(1))
-			KPRINT(PRINTPREFIX "%d/%d: reused dsa %lux\n", target, lun, (ulong)d);
-		c->dsalist.freechain = d->freechain;
-		lesetl(&d->stateb, A_STATE_ALLOCATED);
+			IPRINT(PRINTPREFIX "%d/%d: allocated dsa %lux\n", target, lun, (ulong)d);
 	}
+	c->dsalist.freechain = d->freechain;
+	lesetl(&d->stateb, A_STATE_ALLOCATED);
 	iunlock(&c->dsalist);
 	d->target = target;
 	d->lun = lun;
@@ -418,11 +444,50 @@ dsafree(Controller *c, Dsa *d)
 	iunlock(&c->dsalist);
 }
 
+static void
+dsadump(Controller *c)
+{
+	Dsa *d;
+	u32int *a;
+	
+	iprint("dsa controller list: c=%p head=%.8lux\n", c, legetl(c->dsalist.head));
+	for(d=KPTR(legetl(c->dsalist.head)); d != dsaend; d=KPTR(legetl(d->next))){
+		if(d == (void*)-1){
+			iprint("\t dsa %p\n", d);
+			break;
+		}
+		a = (u32int*)d;
+		iprint("\tdsa %p %.8ux %.8ux %.8ux %.8ux %.8ux %.8ux\n", a, a[0], a[1], a[2], a[3], a[4], a[5]);
+	}
+
+/*
+	a = KPTR(c->scriptpa+E_dsa_addr);
+	iprint("dsa_addr: %.8ux %.8ux %.8ux %.8ux %.8ux\n",
+		a[0], a[1], a[2], a[3], a[4]);
+	a = KPTR(c->scriptpa+E_issue_addr);
+	iprint("issue_addr: %.8ux %.8ux %.8ux %.8ux %.8ux\n",
+		a[0], a[1], a[2], a[3], a[4]);
+
+	a = KPTR(c->scriptpa+E_issue_test_begin);
+	e = KPTR(c->scriptpa+E_issue_test_end);
+	iprint("issue_test code (at offset %.8ux):\n", E_issue_test_begin);
+	
+	i = 0;
+	for(; a<e; a++){
+		iprint(" %.8ux", *a);
+		if(++i%8 == 0)
+			iprint("\n");
+	}
+	if(i%8)
+		iprint("\n");
+*/
+}
+
 static Dsa *
 dsafind(Controller *c, uchar target, uchar lun, uchar state)
 {
 	Dsa *d;
-	for (d = KPTR(legetl(c->dsalist.head)); d; d = KPTR(legetl(d->next))) {
+	for (d = KPTR(legetl(c->dsalist.head)); d != dsaend; d = KPTR(legetl(d->next))) {
 		if (d->target != 0xff && d->target != target)
 			continue;
 		if (lun != 0xff && d->lun != lun)
@@ -441,7 +506,12 @@ dumpncrregs(Controller *c, int intr)
 	Ncr *n = c->n;
 	int depth = c->v->registers / 4;
 
-	KPRINT("sa = %.8lux\n", c->scriptpa);
+	if (intr) {
+		IPRINT("sa = %.8lux\n", c->scriptpa);
+	}
+	else {
+		KPRINT("sa = %.8lux\n", c->scriptpa);
+	}
 	for (i = 0; i < depth; i++) {
 		int j;
 		for (j = 0; j < 4; j++) {
@@ -450,16 +520,20 @@ dumpncrregs(Controller *c, int intr)
 
 			/* display little-endian to make 32-bit values readable */
 			p = (uchar*)n+k*4;
-			if (intr)
+			if (intr) {
 				IPRINT(" %.2x%.2x%.2x%.2x %.2x %.2x", p[3], p[2], p[1], p[0], k * 4, (k * 4) + 0x80);
-			else
+			}
+			else {
 				KPRINT(" %.2x%.2x%.2x%.2x %.2x %.2x", p[3], p[2], p[1], p[0], k * 4, (k * 4) + 0x80);
+			}
 			USED(p);
 		}
-		if (intr)
+		if (intr) {
 			IPRINT("\n");
-		else
+		}
+		else {
 			KPRINT("\n");
+		}
 	}
 }	
 
@@ -748,6 +822,7 @@ start(Controller *c, long entry)
 	c->running = 1;
 	p = c->scriptpa + entry;
 	lesetl(c->n->dsp, p);
+	coherence();
 	if (c->ssm)
 		c->n->dcntl |= 0x4;		/* start DMA in SSI mode */
 }
@@ -759,6 +834,7 @@ ncrcontinue(Controller *c)
 		panic(PRINTPREFIX "ncrcontinue called while running");
 	/* set the start DMA bit to continue execution */
 	c->running = 1;
+	coherence();
 	c->n->dcntl |= 0x4;
 }
 
@@ -999,8 +1075,7 @@ calcblockdma(Dsa *d, ulong base, ulong count)
 	d->dmaaddr[2] = base >> 16;
 	d->dmaaddr[3] = base >> 24;
 	setmovedata(&d->data_buf, base + blocks * A_BSIZE, count - blocks * A_BSIZE);
-	if (legetl(d->data_buf.dbc) == 0)
-		d->flag = 1;
+	d->flag = legetl(d->data_buf.dbc) == 0;
 }
 
 static ulong
@@ -1111,48 +1186,73 @@ sd53c8xxinterrupt(Ureg *ur, void *a)
 	int wakeme = 0;
 	int cont = -1;
 	Dsa *dsa;
+	ulong dsapa;
 	Controller *c = a;
 	Ncr *n = c->n;
 
 	USED(ur);
-	if (DEBUG(1))
+	if (DEBUG(1)) {
 		IPRINT(PRINTPREFIX "int\n");
+	}
 	ilock(c);
 	istat = n->istat;
 	if (istat & Intf) {
 		Dsa *d;
 		int wokesomething = 0;
-		if (DEBUG(1))
+		if (DEBUG(1)) {
 			IPRINT(PRINTPREFIX "Intfly\n");
+		}
 		n->istat = Intf;
 		/* search for structures in A_STATE_DONE */
-		for (d = KPTR(legetl(c->dsalist.head)); d; d = KPTR(legetl(d->next))) {
+		for (d = KPTR(legetl(c->dsalist.head)); d != dsaend; d = KPTR(legetl(d->next))) {
 			if (d->stateb == A_STATE_DONE) {
 				d->p9status = d->status;
-				if (DEBUG(1))
+				if (DEBUG(1)) {
 					IPRINT(PRINTPREFIX "waking up dsa %lux\n", (ulong)d);
+				}
 				wakeup(d);
 				wokesomething = 1;
 			}
 		}
-		if (!wokesomething)
+		if (!wokesomething) {
 			IPRINT(PRINTPREFIX "nothing to wake up\n");
+		}
 	}
 
 	if ((istat & (Sip | Dip)) == 0) {
-		if (DEBUG(1))
+		if (DEBUG(1)) {
 			IPRINT(PRINTPREFIX "int end %x\n", istat);
+		}
 		iunlock(c);
 		return;
 	}
 
 	sist = (n->sist1<<8)|n->sist0;	/* BUG? can two-byte read be inconsistent? */
 	dstat = n->dstat;
-	dsa = (Dsa *)DMASEG_TO_KADDR(legetl(n->dsa));
+	dsapa = legetl(n->dsa);
+
+	/*
+	 * Can't compute dsa until we know that dsapa is valid.
+	 */
+	if(dsapa < -KZERO)
+		dsa = (Dsa*)DMASEG_TO_KADDR(dsapa);
+	else{
+		dsa = nil;
+		/*
+		 * happens at startup on some cards but we 
+		 * don't actually deref dsa because none of the
+		 * flags we are about are set.
+		 * still, print in case that changes and we're
+		 * about to dereference nil.
+		 */
+		iprint("sd53c8xxinterrupt: dsa=%.8lux istat=%ux sist=%ux dstat=%ux\n", dsapa, istat, sist, dstat);
+	}
+
 	c->running = 0;
 	if (istat & Sip) {
-		if (DEBUG(1))
+		if (DEBUG(1)) {
 			IPRINT("sist = %.4x\n", sist);
+		}
 		if (sist & 0x80) {
 			ulong addr;
 			ulong sa;
@@ -1163,20 +1263,29 @@ sd53c8xxinterrupt(Ureg *ur, void *a)
 
 			addr = legetl(n->dsp);
 			sa = addr - c->scriptpa;
-			if (DEBUG(1) || DEBUG(2))
+			if (DEBUG(1) || DEBUG(2)) {
 				IPRINT(PRINTPREFIX "%d/%d: Phase Mismatch sa=%.8lux\n",
 				    dsa->target, dsa->lun, sa);
+			}
 			/*
 			 * now recover
 			 */
 			if (sa == E_data_in_mismatch) {
+				/*
+				 * though this is a failure in the residue, there may have been blocks
+				 * as well. if so, dmablks will not have been zeroed, since the state
+				 * was not saved by the microcode. 
+				 */
 				dbc = read_mismatch_recover(c, n, dsa);
 				tbc = legetl(dsa->data_buf.dbc) - dbc;
+				dsa->dmablks = 0;
+				n->scratcha[2] = 0;
 				advancedata(&dsa->data_buf, tbc);
-				if (DEBUG(1) || DEBUG(2))
+				if (DEBUG(1) || DEBUG(2)) {
 					IPRINT(PRINTPREFIX "%d/%d: transferred = %ld residue = %ld\n",
 					    dsa->target, dsa->lun, tbc, legetl(dsa->data_buf.dbc));
-				cont = E_to_decisions;
+				}
+				cont = E_data_mismatch_recover;
 			}
 			else if (sa == E_data_in_block_mismatch) {
 				dbc = read_mismatch_recover(c, n, dsa);
@@ -1196,17 +1305,20 @@ sd53c8xxinterrupt(Ureg *ur, void *a)
 				    dsa->dmablks, legetl(dsa->dmaaddr),
 				    legetl(dsa->data_buf.pa), legetl(dsa->data_buf.dbc));
 				n->scratcha[2] = dsa->dmablks;
-				lesetl(n->scratchb, *(ulong*)dsa->dmaaddr);
+				lesetl(n->scratchb, dsa->dmancr);
 				cont = E_data_block_mismatch_recover;
 			}
 			else if (sa == E_data_out_mismatch) {
 				dbc = write_mismatch_recover(c, n, dsa);
 				tbc = legetl(dsa->data_buf.dbc) - dbc;
+				dsa->dmablks = 0;
+				n->scratcha[2] = 0;
 				advancedata(&dsa->data_buf, tbc);
-				if (DEBUG(1) || DEBUG(2))
+				if (DEBUG(1) || DEBUG(2)) {
 					IPRINT(PRINTPREFIX "%d/%d: transferred = %ld residue = %ld\n",
 					    dsa->target, dsa->lun, tbc, legetl(dsa->data_buf.dbc));
-				cont = E_to_decisions;
+				}
+				cont = E_data_mismatch_recover;
 			}
 			else if (sa == E_data_out_block_mismatch) {
 				dbc = write_mismatch_recover(c, n, dsa);
@@ -1223,7 +1335,7 @@ sd53c8xxinterrupt(Ureg *ur, void *a)
 				    dmablks * A_BSIZE - tbc + legetl(dsa->data_buf.dbc));
 				/* copy changes into scratch registers */
 				n->scratcha[2] = dsa->dmablks;
-				lesetl(n->scratchb, *(ulong*)dsa->dmaaddr);
+				lesetl(n->scratchb, dsa->dmancr);
 				cont = E_data_block_mismatch_recover;
 			}
 			else if (sa == E_id_out_mismatch) {
@@ -1277,10 +1389,12 @@ sd53c8xxinterrupt(Ureg *ur, void *a)
 			}
 		}
 		/*else*/ if (sist & 0x400) {
-			if (DEBUG(0))
+			if (DEBUG(0)) {
 				IPRINT(PRINTPREFIX "%d/%d Sto\n", dsa->target, dsa->lun);
+			}
 			dsa->p9status = SDtimeout;
 			dsa->stateb = A_STATE_DONE;
+			coherence();
 			softreset(c);
 			cont = E_issue_check;
 			wakeme = 1;
@@ -1298,11 +1412,11 @@ sd53c8xxinterrupt(Ureg *ur, void *a)
 		}
 	}
 	if (istat & Dip) {
-		if (DEBUG(1))
+		if (DEBUG(1)) {
 			IPRINT("dstat = %.2x\n", dstat);
+		}
 		/*else*/ if (dstat & Ssi) {
-			ulong *p = DMASEG_TO_KADDR(legetl(n->dsp));
-			ulong w = (uchar *)p - (uchar *)c->script;
+			ulong w = legetl(n->dsp) - c->scriptpa;
 			IPRINT("[%lux]", w);
 			USED(w);
 			cont = -2;	/* restart */
@@ -1323,12 +1437,14 @@ sd53c8xxinterrupt(Ureg *ur, void *a)
 				/* back up one in the data transfer */
 				IPRINT(PRINTPREFIX "%d/%d: ignore wide residue %d, WSR = %d\n",
 				    dsa->target, dsa->lun, n->scratcha[1], n->scntl2 & 1);
-				if (dsa->dmablks == 0 && dsa->flag)
+				if (dsa->flag == 2) {
 					IPRINT(PRINTPREFIX "%d/%d: transfer over; residue ignored\n",
 					    dsa->target, dsa->lun);
-				else
+				}
+				else {
 					calcblockdma(dsa, legetl(dsa->dmaaddr) - 1,
 					    dsa->dmablks * A_BSIZE + legetl(dsa->data_buf.dbc) + 1);
+				}
 				cont = -2;
 				break;
 			case A_SIR_ERROR_NOT_MSG_IN_AFTER_RESELECT:
@@ -1338,6 +1454,15 @@ sd53c8xxinterrupt(Ureg *ur, void *a)
 				dumpncrregs(c, 1);
 				wakeme = 1;
 				break;
+			case A_SIR_NOTIFY_LOAD_STATE:
+				IPRINT(PRINTPREFIX ": load_state dsa=%p\n", dsa);
+				if (dsa == (void*)KZERO || dsa == (void*)-1) {
+					dsadump(c);
+					dumpncrregs(c, 1);
+					panic("bad dsa in load_state");
+				}
+				cont = -2;
+				break;
 			case A_SIR_NOTIFY_MSG_IN:
 				IPRINT(PRINTPREFIX "%d/%d: msg_in %d\n",
 				    dsa->target, dsa->lun, n->sfbr);
@@ -1394,7 +1519,7 @@ sd53c8xxinterrupt(Ureg *ur, void *a)
 				cont = -2;
 				break;
 			case A_SIR_NOTIFY_ISSUE:
-				IPRINT(PRINTPREFIX "%d/%d: issue:", dsa->target, dsa->lun);
+				IPRINT(PRINTPREFIX "%d/%d: issue dsa=%p end=%p:", dsa->target, dsa->lun, dsa, dsaend);
 			dsadump:
 				IPRINT(" tgt=%d", dsa->target);
 				IPRINT(" time=%ld", TK2MS(m->ticks));
@@ -1410,11 +1535,12 @@ sd53c8xxinterrupt(Ureg *ur, void *a)
 				cont = -2;
 				break;
 			case A_SIR_NOTIFY_DUMP_NEXT_CODE: {
-				ulong *dsp = DMASEG_TO_KADDR(legetl(n->dsp));
+				ulong *dsp = c->script + (legetl(n->dsp)-c->scriptpa)/4;
 				int x;
 				IPRINT(PRINTPREFIX "code at %lux", dsp - c->script);
-				for (x = 0; x < 6; x++)
+				for (x = 0; x < 6; x++) {
 					IPRINT(" %.8lux", dsp[x]);
+				}
 				IPRINT("\n");
 				USED(dsp);
 				cont = -2;
@@ -1430,15 +1556,18 @@ sd53c8xxinterrupt(Ureg *ur, void *a)
 				cont = -2;
 				break;
 			case A_SIR_NOTIFY_RESELECTED_ON_SELECT:
-				IPRINT(PRINTPREFIX "%d/%d: reselected during select\n",
-				    dsa->target, dsa->lun);
+				if (DEBUG(2)) {
+					IPRINT(PRINTPREFIX "%d/%d: reselected during select\n",
+ 					    dsa->target, dsa->lun);
+				}
 				cont = -2;
 				break;
 			case A_error_reselected:		/* dsa isn't valid here */
-				print(PRINTPREFIX "reselection error\n");
+				iprint(PRINTPREFIX "reselection error\n");
 				dumpncrregs(c, 1);
-				for (dsa = KPTR(legetl(c->dsalist.head)); dsa; dsa = KPTR(legetl(dsa->next)))
+				for (dsa = KPTR(legetl(c->dsalist.head)); dsa != dsaend; dsa = KPTR(legetl(dsa->next))) {
 					IPRINT(PRINTPREFIX "dsa target %d lun %d state %d\n", dsa->target, dsa->lun, dsa->stateb);
+				}
 				break;
 			default:
 				IPRINT(PRINTPREFIX "%d/%d: script error %ld\n",
@@ -1448,15 +1577,40 @@ sd53c8xxinterrupt(Ureg *ur, void *a)
 			}
 		}
 		/*else*/ if (dstat & Iid) {
-			ulong addr = legetl(n->dsp);
-			ulong dbc = (n->dbc[2]<<16)|(n->dbc[1]<<8)|n->dbc[0];
+			int i, target, lun;
+			ulong addr, dbc, *v;
+			
+			addr = legetl(n->dsp);
+			if(dsa){
+				target = dsa->target;
+				lun = dsa->lun;
+			}else{
+				target = -1;
+				lun = -1;
+			}
+			dbc = (n->dbc[2]<<16)|(n->dbc[1]<<8)|n->dbc[0];
+
+		//	if(dsa == nil)
+				idebug++;
 			IPRINT(PRINTPREFIX "%d/%d: Iid pa=%.8lux sa=%.8lux dbc=%lux\n",
-			    dsa->target, dsa->lun,
+			    target, lun,
 			    addr, addr - c->scriptpa, dbc);
-			addr = (ulong)DMASEG_TO_KADDR(addr);
-			IPRINT("%.8lux %.8lux %.8lux\n",
-			    *(ulong *)(addr - 12), *(ulong *)(addr - 8), *(ulong *)(addr - 4));
+			addr = (ulong)c->script + addr - c->scriptpa;
+			addr -= 64;
+			addr &= ~63;
+			v = (ulong*)addr;
+			for(i=0; i<8; i++){
+				IPRINT("%.8lux: %.8lux %.8lux %.8lux %.8lux\n", 
+					addr, v[0], v[1], v[2], v[3]);
+				addr += 4*4;
+				v += 4;
+			}
 			USED(addr, dbc);
+			if(dsa == nil){
+				dsadump(c);
+				dumpncrregs(c, 1);
+				panic("bad dsa");
+			}
 			dsa->p9status = SDeio;
 			wakeme = 1;
 		}
@@ -1520,8 +1674,9 @@ dumpwritedata(uchar *data, int datalen)
 
 	if (datalen) {
 		KPRINT(PRINTPREFIX "write:");
-		for (i = 0, bp = data; i < 50 && i < datalen; i++, bp++)
+		for (i = 0, bp = data; i < 50 && i < datalen; i++, bp++) {
 			KPRINT("%.2ux", *bp);
+		}
 		if (i < datalen) {
 			KPRINT("...");
 		}
@@ -1541,8 +1696,9 @@ dumpreaddata(uchar *data, int datalen)
 
 	if (datalen) {
 		KPRINT(PRINTPREFIX "read:");
-		for (i = 0, bp = data; i < 50 && i < datalen; i++, bp++)
+		for (i = 0, bp = data; i < 50 && i < datalen; i++, bp++) {
 			KPRINT("%.2ux", *bp);
+		}
 		if (i < datalen) {
 			KPRINT("...");
 		}
@@ -1587,10 +1743,11 @@ sd53c8xxrio(SDreq* r)
 	uchar *bp;
 	Controller *c;
 	uchar target_expo, my_expo;
-	int bc, check, status, target;
+	int bc, check, i, status, target;
 
 	if((target = r->unit->subno) == 0x07)
 		return r->status = SDtimeout;	/* assign */
+
 	c = r->unit->dev->ctlr;
 
 	check = 0;
@@ -1659,16 +1816,18 @@ docheck:
 
 	setmovedata(&d->msg_out_buf, DMASEG(d->msg_out), bc);
 	setmovedata(&d->cmd_buf, DMASEG(r->cmd), r->clen);
-	calcblockdma(d, DMASEG(r->data), r->dlen);
+	calcblockdma(d, r->data ? DMASEG(r->data) : 0, r->dlen);
 
 	if (DEBUG(0)) {
 		KPRINT(PRINTPREFIX "%d/%d: exec: ", target, r->lun);
-		for (bp = r->cmd; bp < &r->cmd[r->clen]; bp++)
+		for (bp = r->cmd; bp < &r->cmd[r->clen]; bp++) {
 			KPRINT("%.2ux", *bp);
+		}
 		KPRINT("\n");
-		if (!r->write)
+		if (!r->write) {
 			KPRINT(PRINTPREFIX "%d/%d: exec: limit=(%d)%ld\n",
 			  target, r->lun, d->dmablks, legetl(d->data_buf.dbc));
+		}
 		else
 			dumpwritedata(r->data, r->dlen);
 	}
@@ -1677,14 +1836,15 @@ docheck:
 
 	d->p9status = SDnostatus;
 	d->parityerror = 0;
-
+	coherence();
 	d->stateb = A_STATE_ISSUE;		/* start operation */
+	coherence();
 
 	ilock(c);
 	if (c->ssm)
-		c->n->dcntl |= 0x10;		/* SSI */
+		c->n->dcntl |= 0x10;		/* single step */
 	if (c->running) {
-		c->n->istat |= Sigp;
+		c->n->istat = Sigp;
 	}
 	else {
 		start(c, E_issue_check);
@@ -1716,15 +1876,21 @@ docheck:
 	 * adjust datalen
 	 */
 	r->rlen = r->dlen;
-	if (d->dmablks > 0)
+	if (DEBUG(0)) {
+		KPRINT(PRINTPREFIX "%d/%d: exec: before rlen adjust: dmablks %d flag %d dbc %lud\n",
+		    target, r->lun, d->dmablks, d->flag, legetl(d->data_buf.dbc));
+	}
+	r->rlen = r->dlen;
+	if (d->flag != 2) {
 		r->rlen -= d->dmablks * A_BSIZE;
-	else if (d->flag == 0)
 		r->rlen -= legetl(d->data_buf.dbc);
+	}
 	if(!r->write)
 		dumpreaddata(r->data, r->rlen);
-	if (DEBUG(0))
+	if (DEBUG(0)) {
 		KPRINT(PRINTPREFIX "%d/%d: exec: p9status=%d status %d rlen %ld\n",
 		    target, r->lun, d->p9status, status, r->rlen);
+	}
 	/*
 	 * spot the identify
 	 */
@@ -1751,6 +1917,7 @@ docheck:
 		 * so the Dsa can be re-used.
 		 */
 		lesetl(&d->stateb, A_STATE_ALLOCATED);
+		coherence();
 		goto docheck;
 	}
 	qunlock(&c->q[target]);
@@ -1760,11 +1927,22 @@ docheck:
 		status = SDcheck;
 		r->flags |= SDvalidsense;
 	}
-	KPRINT(PRINTPREFIX "%d: r flags %8.8uX status %d rlen %ld\n",
-		target, r->flags, status, r->rlen);
+	if(DEBUG(0))
+		KPRINT(PRINTPREFIX "%d: r flags %8.8uX status %d rlen %ld\n",
+			target, r->flags, status, r->rlen);
+	if(r->flags & SDvalidsense){
+		if(!DEBUG(0))
+			KPRINT(PRINTPREFIX "%d: r flags %8.8uX status %d rlen %ld\n",
+				target, r->flags, status, r->rlen);
+		for(i = 0; i < r->rlen; i++)
+			KPRINT(" %2.2uX", r->sense[i]);
+		KPRINT("\n");
+	}
 	return r->status = status;
 }
 
+#define	vpt ((ulong*)VPT)
+#define	VPTX(va)		(((ulong)(va))>>12)
 static void
 cribbios(Controller *c)
 {
@@ -1796,6 +1974,7 @@ bios_set_differential(Controller *c)
 #define SYM_885_DID	0x000d	/* ditto */
 #define SYM_875_DID	0x000f	/* ditto */
 #define SYM_1010_DID	0x0020
+#define SYM_1011_DID	0x0021
 #define SYM_875J_DID	0x008f
 
 static Variant variant[] = {
@@ -1815,6 +1994,7 @@ static Variant variant[] = {
 { SYM_895_DID,   0xff, "SYM53C895",	Burst128, 16, 24, Prefetch|LocalRAM|BigFifo|Wide|Ultra|Ultra2 },
 { SYM_896_DID,   0xff, "SYM53C896",	Burst128, 16, 64, Prefetch|LocalRAM|BigFifo|Wide|Ultra|Ultra2 },
 { SYM_1010_DID,  0xff, "SYM53C1010",	Burst128, 16, 64, Prefetch|LocalRAM|BigFifo|Wide|Ultra|Ultra2 },
+{ SYM_1011_DID,   0xff, "SYM53C1010",	Burst128, 16, 64, Prefetch|LocalRAM|BigFifo|Wide|Ultra|Ultra2 },
 };
 
 static int
@@ -1904,6 +2084,7 @@ sd53c8xxpnp(void)
 	Controller *ctlr;
 	SDev *sdev, *head, *tail;
 	ulong regpa, *script, scriptpa;
+	void *regva, *scriptva;
 
 	if(cp = getconf("*maxsd53c8xx"))
 		nctlr = strtoul(cp, 0, 0);
@@ -1921,7 +2102,7 @@ sd53c8xxpnp(void)
 			print("no match\n");
 			continue;
 		}
-		print(PRINTPREFIX "%s rev. 0x%2.2x intr=%d command=%4.4luX\n",
+		print(PRINTPREFIX "%s rev. 0x%2.2x intr=%d command=%4.4uX\n",
 			v->name, p->rid, p->intl, p->pcr);
 
 		regpa = p->mem[1].bar;
@@ -1931,23 +2112,27 @@ sd53c8xxpnp(void)
 				continue;
 			ba++;
 		}
-		regpa = upamalloc(regpa & ~0x0F, p->mem[1].size, 0);
 		if(regpa == 0)
+			print("regpa 0\n");
+		regpa &= ~0xF;
+		regva = vmap(regpa, p->mem[1].size);
+		if(regva == 0)
 			continue;
 
 		script = nil;
 		scriptpa = 0;
+		scriptva = nil;
 		scriptma = nil;
 		if((v->feature & LocalRAM) && sizeof(na_script) <= 4096){
 			scriptpa = p->mem[ba].bar;
 			if((scriptpa & 0x04) && p->mem[ba+1].bar){
-				upafree(regpa, p->mem[1].size);
+				vunmap(regva, p->mem[1].size);
 				continue;
 			}
-			scriptpa = upamalloc(scriptpa & ~0x0F,
-					p->mem[ba].size, 0);
-			if(scriptpa)
-				script = KADDR(scriptpa);
+			scriptpa &= ~0x0F;
+			scriptva = vmap(scriptpa, p->mem[ba].size);
+			if(scriptva)
+				script = scriptva;
 		}
 		if(scriptpa == 0){
 			/*
@@ -1956,7 +2141,7 @@ sd53c8xxpnp(void)
 			 */
 			scriptma = malloc(sizeof(na_script));
 			if(scriptma == nil){
-				upafree(regpa, p->mem[1].size);
+				vunmap(regva, p->mem[1].size);
 				continue;
 			}
 			scriptpa = DMASEG(scriptma);
@@ -1973,13 +2158,23 @@ buggery:
 				free(sdev);
 			if(scriptma)
 				free(scriptma);
-			else
-				upafree(scriptpa, p->mem[ba].size);
-			upafree(regpa, p->mem[1].size);
+			else if(scriptva)
+				vunmap(scriptva, p->mem[ba].size);
+			if(regva)
+				vunmap(regva, p->mem[1].size);
 			continue;
 		}
 
-		ctlr->n = KADDR(regpa);
+		if(dsaend == nil)
+			dsaend = xalloc(sizeof *dsaend);
+		lesetl(&dsaend->stateb, A_STATE_END);
+	//	lesetl(dsaend->next, DMASEG(dsaend));
+		coherence();
+		lesetl(ctlr->dsalist.head, DMASEG(dsaend));
+		coherence();
+		ctlr->dsalist.freechain = 0;
+
+		ctlr->n = regva;
 		ctlr->v = v;
 		ctlr->script = script;
 		memmove(ctlr->script, na_script, sizeof(na_script));
@@ -1987,10 +2182,11 @@ buggery:
 		/*
 		 * Because we don't yet have an abstraction for the
 		 * addresses as seen from the controller side (and on
-		 * the 386 it doesn't matter), the following two lines
+		 * the 386 it doesn't matter), the following three lines
 		 * are different between the 386 and alpha copies of
 		 * this driver.
 		 */
+		USED(scriptpa);
 		ctlr->scriptpa = p->mem[ba].bar & ~0x0F;
 		if(!na_fixup(ctlr, p->mem[1].bar & ~0x0F, na_patches, NA_PATCHES, xfunc)){
 			print("script fixup failed\n");
@@ -1998,19 +2194,17 @@ buggery:
 		}
 		swabl(ctlr->script, ctlr->script, sizeof(na_script));
 
-		ctlr->dsalist.freechain = 0;
-		lesetl(ctlr->dsalist.head, 0);
-
 		ctlr->pcidev = p;
 
 		sdev->ifc = &sd53c8xxifc;
 		sdev->ctlr = ctlr;
+		sdev->idno = '0';
 		if(!(v->feature & Wide))
 			sdev->nunit = 8;
 		else
 			sdev->nunit = MAXTARGET;
 		ctlr->sdev = sdev;
-
+		
 		if(head != nil)
 			tail->next = sdev;
 		else
@@ -2023,12 +2217,6 @@ buggery:
 	return head;
 }
 
-static SDev*
-sd53c8xxid(SDev* sdev)
-{
-	return scsiid(sdev, &sd53c8xxifc);
-}
-
 static int
 sd53c8xxenable(SDev* sdev)
 {
@@ -2040,13 +2228,13 @@ sd53c8xxenable(SDev* sdev)
 	pcidev = ctlr->pcidev;
 
 	pcisetbme(pcidev);
-	snprint(name, sizeof(name), "%s (%s)", sdev->name, sdev->ifc->name);
-	intrenable(pcidev->intl, sd53c8xxinterrupt, ctlr, pcidev->tbdf, name);
 
 	ilock(ctlr);
 	synctabinit(ctlr);
 	cribbios(ctlr);
 	reset(ctlr);
+	snprint(name, sizeof(name), "%s (%s)", sdev->name, sdev->ifc->name);
+	intrenable(pcidev->intl, sd53c8xxinterrupt, ctlr, pcidev->tbdf, name);
 	iunlock(ctlr);
 
 	return 1;
@@ -2057,7 +2245,6 @@ SDifc sd53c8xxifc = {
 
 	sd53c8xxpnp,			/* pnp */
 	nil,				/* legacy */
-	sd53c8xxid,			/* id */
 	sd53c8xxenable,			/* enable */
 	nil,				/* disable */
 

+ 11 - 10
sys/src/boot/alphapc/l.s

@@ -1,4 +1,5 @@
 #include "mem.h"
+#include "vmspal.h"
 
 #define SP		R30
 
@@ -17,7 +18,7 @@ loop2:
 TEXT	firmware(SB), $-8
 	CALL_PAL $PALhalt
 	MOVQ	$_divq(SB), R31		/* touch _divq etc.; doesn't need to execute */
-	MOVQ	$_divl(SB), R31			/* touch _divl etc.; doesn't need to execute */
+	MOVQ	$_divl(SB), R31		/* touch _divl etc.; doesn't need to execute */
 	RET
 
 TEXT	mb(SB), $-8
@@ -39,7 +40,7 @@ TEXT	gendispatch(SB), $-8
 	MOVQ	32(FP), R19
 	MOVQ	40(FP), R20
 	MOVQ	R26, R1
-	JSR		(R0)
+	JSR	(R0)
 	MOVQ	R1, R26
 	RET					/* 7a bug: should be RET (R1) */
 
@@ -53,41 +54,41 @@ TEXT	wrv(SB), $-8
 	RET
 
 TEXT	ipl(SB), $-8
-	CALL_PAL	$PALmfpr_ipl
+	CALL_PAL $PALmfpr_ipl
 	RET
 
 TEXT	mces(SB), $-8
-	CALL_PAL	$PALmfpr_mces
+	CALL_PAL $PALmfpr_mces
 	RET
 
 TEXT	setipl(SB), $-8
 	MOVQ	R0, R16
-	CALL_PAL	$PALmtpr_ipl
+	CALL_PAL $PALmtpr_ipl
 	RET
 
 TEXT	setmces(SB), $-8
 	MOVQ	R0, R16
-	CALL_PAL	$PALmtpr_mces
+	CALL_PAL $PALmtpr_mces
 	RET
 
 TEXT	ldqp(SB), $-8
 	MOVQ	R0, R16
-	CALL_PAL	$PALldqp
+	CALL_PAL $PALldqp
 	RET
 
 TEXT	stqp(SB), $-8
 	MOVQ	R0, R16
 	MOVQ	8(FP), R17
-	CALL_PAL	$PALstqp
+	CALL_PAL $PALstqp
 	RET
 
 TEXT	getptbr(SB), $-8
-	CALL_PAL	$PALmfpr_ptbr
+	CALL_PAL $PALmfpr_ptbr
 	RET
 
 TEXT	swppal(SB), $-8
 	MOVQ	R0, R16			/* which PALcode */
-	MOVQ	8(FP), R17			/* new PC */
+	MOVQ	8(FP), R17		/* new PC */
 	MOVQ	16(FP), R18		/* PCBB (physical) */
 	MOVQ	24(FP), R19		/* VPTB */
 	MOVQ	32(FP), R20		/* new KSP */

+ 3 - 24
sys/src/boot/alphapc/mem.h

@@ -5,32 +5,11 @@
 #define	BI2BY		8			/* bits per byte */
 #define	BI2WD		32			/* bits per word */
 #define	BY2WD		4			/* bytes per word */
-#define 	BY2V		8			/* bytes per vlong */
+#define BY2V		8			/* bytes per vlong */
 
 #define	KZERO		0x80000000
 
-#define	PTEVALID		0xff01
+#define	PTEVALID	0xff01
 #define	PTEKVALID	0x1101
 #define	PTEASM		0x0010
-#define	PTEGH(s)		((s)<<5)
-
-/*
- * VMS Palcode instructions (incomplete and possibly incorrect)
- */
-#define	PALimb		0x86
-#define	PALhalt		0x00
-#define	PALdraina	0x02
-#define	PALcserve	0x09
-
-#define	PALmfpr_pcbb	0x12
-#define	PALmfpr_ptbr	0x15
-#define	PALmfpr_vptb	0x29
-#define	PALldqp		0x03
-#define	PALstqp		0x04
-#define	PALswppal	0x0a
-
-#define	PALmtpr_tbia	0x1b
-#define	PALmtpr_mces	0x17
-#define	PALmfpr_mces	0x16
-#define	PALmtpr_ipl	0x15
-#define	PALmfpr_ipl	0x14
+#define	PTEGH(s)	((s)<<5)

+ 105 - 0
sys/src/boot/alphapc/vmspal.h

@@ -0,0 +1,105 @@
+/*
+ * VMS PALcode instructions, in numerical order.
+ */
+
+#define	PALhalt		0x00	/* required per Alpha architecture */
+#define	PALcflush	0x01
+#define	PALdraina	0x02	/* required per Alpha architecture */
+#define	PALldqp		0x03
+
+#define	PALstqp		0x04
+#define	PALswpctx	0x05
+#define	PALmfpr_asn	0x06
+#define	PALmtpr_asten	0x07
+#define	PALmtpr_astsr	0x08
+#define	PALcserve	0x09
+#define	PALswppal	0x0a
+#define	PALmfpr_fen	0x0b
+#define	PALmtpr_fen	0x0c
+#define	PALmtpr_ipir	0x0d
+#define	PALmfpr_ipl	0x0e
+#define	PALmtpr_ipl	0x0f
+#define	PALmfpr_mces	0x10
+#define	PALmtpr_mces	0x11
+#define	PALmfpr_pcbb	0x12
+#define	PALmfpr_prbr	0x13
+#define	PALmtpr_prbr	0x14
+#define	PALmfpr_ptbr	0x15
+#define	PALmfpr_scbb	0x16
+#define	PALmtpr_scbb	0x17
+#define	PALmtpr_sirr	0x18
+#define	PALmfpr_sisr	0x19
+#define	PALmfpr_tbchk	0x1a
+#define	PALmtpr_tbia	0x1b
+#define	PALmtpr_tbiap	0x1c
+#define	PALmtpr_tbis	0x1d
+#define	PALmfpr_esp	0x1e
+#define	PALmtpr_esp	0x1f
+#define	PALmfpr_ssp	0x20
+#define	PALmtpr_ssp	0x21
+#define	PALmfpr_usp	0x22
+#define	PALmtpr_usp	0x23
+#define	PALmtpr_tbisd	0x24
+#define	PALmtpr_tbisi	0x25
+#define	PALmfpr_asten	0x26
+#define	PALmfpr_astsr	0x27
+				/* where is instruction 0x28 ? */
+#define	PALmfpr_vptb	0x29
+#define	PALmtpr_vptb	0x2a
+#define	PALmtpr_perfmon	0x2b
+				/* where is instruction 0x2c ? */
+				/* where is instruction 0x2d ? */
+#define	PALmtpr_datfx	0x2e
+/*
+ * ... 0x2f to 0x3e ??
+ */
+#define	PALmfpr_whami	0x3f
+/*
+ * ... 0x40 to 0x7f ??
+ */
+#define	PALbpt		0x80
+#define	PALbugchk	0x81
+#define	PALchime	0x82
+#define	PALchmk		0x83
+#define	PALchms		0x84
+#define	PALchmu		0x85
+#define	PALimb		0x86	/* required per Alpha architecture */
+#define	PALinsqhil	0x87
+#define	PALinsqtil	0x88
+#define	PALinsqhiq	0x89
+#define	PALinsqtiq	0x8a
+#define	PALinsquel	0x8b
+#define	PALinsqueq	0x8c
+#define	PALinsqueld	0x8d	/* INSQUEL/D */
+#define	PALinsqueqd	0x8e	/* INSQUEQ/D */
+#define	PALprober	0x8f
+#define	PALprobew	0x90
+#define	PALrd_ps	0x91
+#define	PALrei		0x92
+#define	PALremqhil	0x93
+#define	PALremqtil	0x94
+#define	PALremqhiq	0x95
+#define	PALremqtiq	0x96
+#define	PALremquel	0x97
+#define	PALremqueq	0x98
+#define	PALremqueld	0x99	/* REMQUEL/D */
+#define	PALremqueqd	0x9a	/* REMQUEQ/D */
+#define	PALswasten	0x9b
+#define	PALwr_ps_sw	0x9c
+#define	PALrscc		0x9d
+#define	PALread_unq	0x9e
+#define	PALwrite_unq	0x9f
+#define	PALamovrr	0xa0
+#define	PALamovrm	0xa1
+#define	PALinsqhilr	0xa2
+#define	PALinsqtilr	0xa3
+
+#define	PALinsqhiqr	0xa4
+#define	PALinsqtiqr	0xa5
+#define	PALremqhilr	0xa6
+
+#define	PALremqtilr	0xa7
+#define	PALremqhiqr	0xa8
+#define	PALremqtiqr	0xa9
+#define	PALgentrap	0xaa
+