summaryrefslogtreecommitdiff
path: root/sys/arch/vax/boot
diff options
context:
space:
mode:
authorMats O Jansson <maja@cvs.openbsd.org>1997-01-15 23:25:34 +0000
committerMats O Jansson <maja@cvs.openbsd.org>1997-01-15 23:25:34 +0000
commitbf6413046b73005ecca3f5352c8711d00a6d00b9 (patch)
treefcd2c64f80b1be68d962f84a1e34da0a02d5385f /sys/arch/vax/boot
parent957078809571dbe61aac81705145fa4cee6bfda8 (diff)
sync with NetBSD 970112 -moj
Diffstat (limited to 'sys/arch/vax/boot')
-rw-r--r--sys/arch/vax/boot/Makefile52
-rw-r--r--sys/arch/vax/boot/autoconf.c20
-rw-r--r--sys/arch/vax/boot/boot.c12
-rw-r--r--sys/arch/vax/boot/bootxx.c121
-rw-r--r--sys/arch/vax/boot/conf.c36
-rw-r--r--sys/arch/vax/boot/consio.c169
-rw-r--r--sys/arch/vax/boot/copy.c6
-rw-r--r--sys/arch/vax/boot/devopen.c52
-rw-r--r--sys/arch/vax/boot/edlabel.c8
-rw-r--r--sys/arch/vax/boot/init.c82
-rw-r--r--sys/arch/vax/boot/ka410.h82
-rw-r--r--sys/arch/vax/boot/mfm.c640
-rw-r--r--sys/arch/vax/boot/ra.c147
-rw-r--r--sys/arch/vax/boot/rom.c123
-rw-r--r--sys/arch/vax/boot/romread.s38
-rw-r--r--sys/arch/vax/boot/samachdep.h42
-rw-r--r--sys/arch/vax/boot/scsi_hi.c297
-rw-r--r--sys/arch/vax/boot/scsi_low.c479
-rw-r--r--sys/arch/vax/boot/sd.c247
-rw-r--r--sys/arch/vax/boot/so.h57
-rw-r--r--sys/arch/vax/boot/srt0.s6
-rw-r--r--sys/arch/vax/boot/start.s5
-rw-r--r--sys/arch/vax/boot/str.s70
-rw-r--r--sys/arch/vax/boot/tmscp.c15
-rw-r--r--sys/arch/vax/boot/vaxstand.h21
25 files changed, 2516 insertions, 311 deletions
diff --git a/sys/arch/vax/boot/Makefile b/sys/arch/vax/boot/Makefile
index f2ac372bc2d..b9a0cb46e9f 100644
--- a/sys/arch/vax/boot/Makefile
+++ b/sys/arch/vax/boot/Makefile
@@ -1,28 +1,29 @@
-# $OpenBSD: Makefile,v 1.6 1996/09/27 18:38:04 maja Exp $
-# $NetBSD: Makefile,v 1.9 1996/03/16 11:03:12 ragge Exp $
+# $OpenBSD: Makefile,v 1.7 1997/01/15 23:24:15 maja Exp $
+# $NetBSD: Makefile,v 1.11 1996/10/18 06:10:18 thorpej Exp $
#
INCPATH=-I. -I../../.. -I../.. -I../../../lib/libsa
-.PATH: ${.CURDIR}/../../../lib/libkern
CC= cc
AS= as
S= ../../..
RELOC= 100000
-CFLAGS+=-O ${INCPATH} -DSTANDALONE -DRELOC=0x${RELOC} -D_VAX_INLINE_
+XXRPB= 0F4240
+CFLAGS+=-O ${INCPATH} -DSTANDALONE -DRELOC=0x${RELOC} \
+ -D_VAX_INLINE_ -DXXRPB=0x$(XXRPB)
-DEVS= autoconf.o hp.o ra.o tmscp.o ctu.o
-
-LIBKERN=libkern.a
-KERNOBJ=__main.o strlen.o strcmp.o strncmp.o strncpy.o min.o strcpy.o
+DEVS= autoconf.o hp.o ra.o tmscp.o ctu.o mfm.o rom.o romread.o \
+ scsi_low.o scsi_hi.o sd.o
.include "$S/lib/libsa/Makefile.inc"
LIBSA= ${SALIB}
-all: xxboot boot copy edlabel
+SVAX= consio.o urem.o udiv.o str.o
+
+all: ${LIBSA} xxboot boot copy edlabel
-libsvax.a: consio.o urem.o udiv.o
+libsvax.a: ${SVAX}
ar crv $@ $?
ranlib $@
@@ -32,6 +33,9 @@ urem.o: ../vax/urem.s
udiv.o: ../vax/udiv.s
${CC} -x assembler-with-cpp -E ../vax/udiv.s | as -o udiv.o
+str.o: str.s
+ ${CC} -x assembler-with-cpp -E str.s | as -o str.o
+
# startups
start.o: start.s
@@ -42,29 +46,29 @@ srt0.o: srt0.s
#
-xxboot: start.o bootxx.o romread.o ${LIBSA} ${LIBKERN} libsvax.a
+xxboot: start.o bootxx.o romread.o libsvax.a
ld -N -Ttext ${RELOC} -o a.out start.o bootxx.o romread.o \
- ${LIBSA} ${LIBKERN} libsvax.a
+ ${LIBSA} libsvax.a
@strip a.out
@size a.out
@dd if=a.out of=xxboot bs=32 skip=1
@rm -f a.out
-boot: boot.o srt0.o devopen.o conf.o ${DEVS} ${LIBKERN} ${LIBSA} libsvax.a
+boot: boot.o srt0.o devopen.o conf.o ${DEVS} libsvax.a
ld -N -Ttext ${RELOC} -e nisse -o $@ srt0.o devopen.o boot.o \
- conf.o ${DEVS} ${LIBSA} ${LIBKERN} libsvax.a
+ conf.o ${DEVS} ${LIBSA} libsvax.a
@strip boot
@size boot
-edlabel: edlabel.o srt0.o devopen.o conf.o ${DEVS} ${LIBKERN} ${LIBSA} libsvax.a
+edlabel: edlabel.o srt0.o devopen.o conf.o ${DEVS} libsvax.a
ld -N -Ttext ${RELOC} -e nisse -o $@ srt0.o devopen.o edlabel.o\
- conf.o ${DEVS} ${LIBSA} ${LIBKERN} libsvax.a
+ conf.o ${DEVS} ${LIBSA} libsvax.a
@strip edlabel
@size edlabel
-copy: copy.o srt0.o devopen.o conf.o ${DEVS} ${LIBKERN} ${LIBSA} libsvax.a
+copy: copy.o srt0.o devopen.o conf.o ${DEVS} libsvax.a
ld -N -Ttext ${RELOC} -e nisse -o $@ srt0.o devopen.o copy.o \
- conf.o ${DEVS} ${LIBSA} ${LIBKERN} libsvax.a
+ conf.o ${DEVS} ${LIBSA} libsvax.a
@strip copy
@size copy
@@ -98,14 +102,10 @@ bootxx.o: bootxx.c
${CC} -c ${CFLAGS} $*.c
#
-libkern.a: ${KERNOBJ}
- @echo Creating standalone kern library
- @ar rv libkern.a `lorder ${KERNOBJ} | tsort`
-
-#
install: boot xxboot
- install -c -o ${BINOWN} -g ${BINGRP} -m 444 boot ${DESTDIR}/
- install -c -o ${BINOWN} -g ${BINGRP} -m 444 xxboot ${DESTDIR}/usr/mdec
+ ${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m 444 boot ${DESTDIR}/
+ ${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m 444 xxboot \
+ ${DESTDIR}/usr/mdec
rm -f ${DESTDIR}/usr/mdec/raboot
ln ${DESTDIR}/usr/mdec/xxboot ${DESTDIR}/usr/mdec/raboot
rm -f ${DESTDIR}/usr/mdec/hpboot
@@ -115,7 +115,7 @@ clean::
rm -f start.o romread.o bootxx.o init.o xxboot boot racopy \
libsvax.a udiv.o urem.o consio.o ${DEVS} edlabel edlabel.o
rm -f conf.o boot.o rom.o racopy.o srt0.o devopen.o rootcopy.o \
- copy copy.o
+ copy copy.o init.o
.include <bsd.prog.mk>
diff --git a/sys/arch/vax/boot/autoconf.c b/sys/arch/vax/boot/autoconf.c
index ca08f01214a..d3b2d2b67fd 100644
--- a/sys/arch/vax/boot/autoconf.c
+++ b/sys/arch/vax/boot/autoconf.c
@@ -1,4 +1,4 @@
-/* $NetBSD: autoconf.c,v 1.5 1996/03/07 23:27:06 ragge Exp $ */
+/* $NetBSD: autoconf.c,v 1.6 1996/08/02 11:21:46 ragge Exp $ */
/*
* Copyright (c) 1994 Ludd, University of Lule}, Sweden.
* All rights reserved.
@@ -39,8 +39,8 @@
#include "vaxstand.h"
int nmba=0, nuba=0, nbi=0,nsbi=0,nuda=0;
-int *mbaaddr, *ubaaddr;
-int *udaaddr, *uioaddr, tmsaddr;
+int *mbaaddr, *ubaaddr, *biaddr;
+int *udaaddr, *uioaddr, tmsaddr, *bioaddr;
static int mba750[]={0xf28000,0xf2a000,0xf2c000};
static int uba750[]={0xf30000,0xf32000};
@@ -55,6 +55,10 @@ static int uba780[]={0x20006000,0x20008000,0x2000a000,0x2000c000,
static int uio780[]={0x20100000,0x20140000,0x20180000,0x201c0000,
0x22100000,0x22140000,0x22180000,0x221c0000};
+static int bi8200[]={0x20000000, 0x22000000, 0x24000000, 0x26000000,
+ 0x28000000, 0x2a000000};
+static int bio8200[]={0x20400000};
+
static int uba630[]={0x20087800};
static int uio630[]={0x30000000};
#define qbdev(csr) (((csr) & 017777)-0x10000000)
@@ -67,12 +71,11 @@ static int uda630[]={qbdev(0772150),qbdev(0760334)};
autoconf()
{
- int i = MACHID(mfpr(PR_SID));
- switch (i) {
+ switch (vax_cputype) {
default:
- printf("CPU type %d not supported by boot\n",i);
+ printf("CPU type %d not supported by boot\n",vax_cputype);
asm("halt");
case VAX_8600:
@@ -117,6 +120,11 @@ autoconf()
uioaddr = uio630;
tmsaddr = qbdev(0774500);
break;
+
+ case VAX_8200:
+ nbi = 1;
+ biaddr = bi8200;
+ bioaddr = bio8200;
}
}
diff --git a/sys/arch/vax/boot/boot.c b/sys/arch/vax/boot/boot.c
index 206db3dcf7a..7fd54220f49 100644
--- a/sys/arch/vax/boot/boot.c
+++ b/sys/arch/vax/boot/boot.c
@@ -1,4 +1,5 @@
-/* $NetBSD: boot.c,v 1.4 1995/09/16 15:54:20 ragge Exp $ */
+/* $OpenBSD: boot.c,v 1.3 1997/01/15 23:24:16 maja Exp $ */
+/* $NetBSD: boot.c,v 1.5 1996/08/02 11:21:49 ragge Exp $ */
/*-
* Copyright (c) 1982, 1986 The Regents of the University of California.
* All rights reserved.
@@ -38,6 +39,8 @@
#include "sys/reboot.h"
#include "lib/libsa/stand.h"
+#define V750UCODE(x) ((x>>8)&255)
+
#include <a.out.h>
/*
@@ -49,8 +52,9 @@
char line[100];
volatile u_int devtype, bootdev;
extern unsigned opendev;
+extern unsigned *bootregs;
-main()
+Xmain()
{
register howto asm("r11");
register bdev asm("r10");
@@ -149,7 +153,7 @@ copyunix(howto, devtype, aio)
hoppabort((x.a_entry&0x7fffffff),howto, devtype, esym);
return;
shread:
- printf("Short read\n");
+ printf("\nShort read\n\n");
return;
}
@@ -191,7 +195,7 @@ loadpcs()
if (*cp == ')' || *cp == ':')
break;
if (*cp) {
- strncpy(pcs, line, 99);
+ bcopy(line, pcs, 99);
pcs[99] = 0;
i = cp - line + 1;
} else
diff --git a/sys/arch/vax/boot/bootxx.c b/sys/arch/vax/boot/bootxx.c
index 4a1b34f83d6..e7464b87273 100644
--- a/sys/arch/vax/boot/bootxx.c
+++ b/sys/arch/vax/boot/bootxx.c
@@ -1,4 +1,4 @@
-/* $NetBSD: bootxx.c,v 1.5 1996/02/17 18:23:21 ragge Exp $ */
+/* $NetBSD: bootxx.c,v 1.7 1996/08/02 11:21:53 ragge Exp $ */
/*-
* Copyright (c) 1982, 1986 The Regents of the University of California.
* All rights reserved.
@@ -50,18 +50,21 @@
#include "../mba/mbareg.h"
#include "../mba/hpreg.h"
-#define NRSP 0 /* Kludge */
-#define NCMD 0 /* Kludge */
+#define NRSP 1 /* Kludge */
+#define NCMD 1 /* Kludge */
+
#include "../uba/ubareg.h"
#include "../uba/udareg.h"
-#include "../vax/mscp.h"
+
+#include "../mscp/mscp.h"
+#include "../mscp/mscpreg.h"
#include "data.h"
#include "vaxstand.h"
#include <a.out.h>
-int romstrategy(), romopen();
+int romstrategy(), romopen();
int command(int, int);
/*
@@ -71,39 +74,45 @@ int command(int, int);
volatile u_int devtype, bootdev;
unsigned opendev, boothowto, bootset;
-int cpu_type, cpunumber;
-unsigned *bootregs;
-int is_750 = 0, is_mvax = 0, is_tmscp = 0;
-struct rpb *rpb;
-main()
+extern unsigned *bootregs;
+extern struct rpb *rpb;
+
+Xmain()
{
int io;
+ char *scbb;
+ char *new;
char *hej = "/boot";
- cpu_type = mfpr(PR_SID);
- cpunumber = (mfpr(PR_SID) >> 24) & 0xFF;
-
- switch (cpunumber) {
+ switch (vax_cputype) {
case VAX_78032:
case VAX_650:
- {
- int cpu_sie; /* sid-extension */
-
- is_mvax = 1;
- cpu_sie = *((int *) 0x20040004) >> 24;
- cpu_type |= cpu_sie;
- rpb = (struct rpb *)bootregs[11];
bootdev = rpb->devtyp;
+ /*
+ * now relocate rpb/bqo (which are used by ROM-routines)
+ */
+ rpb = (void*)XXRPB;
+ bcopy ((void*)bootregs[11], rpb, 512);
+ rpb->rpb_base = rpb;
+ bqo = (void*)(512+(int)rpb);
+ bcopy ((void*)rpb->iovec, bqo, rpb->iovecsz);
+ rpb->iovec = (int)bqo;
+ bootregs[11] = (int)rpb;
+
break;
- }
+ case VAX_8200:
case VAX_750:
- is_750 = 1;
bootdev = bootregs[10];
break;
+ default:
+ printf("unknown cpu type %d\nRegister dump:\n", vax_cputype);
+ for (io = 0; io < 16; io++)
+ printf("r%d 0x%x\n", io, bootregs[io]);
+ asm("halt");
}
bootset = getbootdev();
@@ -114,7 +123,7 @@ main()
if (io >= 0 && io < SOPEN_MAX) {
copyunix(io);
} else {
- printf("Boot failed. errno %d (%s)\n", errno, strerror(errno));
+ printf("Boot failed, saerrno %d\n", errno);
}
}
@@ -127,7 +136,7 @@ copyunix(aio)
i = read(io, (char *) &x, sizeof(x));
if (i != sizeof(x) || N_BADMAG(x)) {
- printf("Bad format: errno %s\n", strerror(errno));
+ printf("Bad format\n");
return;
}
printf("%d", x.a_text);
@@ -163,7 +172,7 @@ getbootdev()
int i, major, adaptor, controller, unit, partition;
- switch (cpunumber) {
+ switch (vax_cputype) {
case VAX_78032:
case VAX_650:
adaptor = 0;
@@ -172,6 +181,7 @@ getbootdev()
break;
+ case VAX_8200:
case VAX_750:
controller = 0; /* XXX Actually massbuss can be on 3 ctlr's */
unit = bootregs[3];
@@ -181,23 +191,28 @@ getbootdev()
partition = 0;
switch (bootdev) {
- case 0: /* massbuss boot */
+ case BDEV_MBA: /* massbuss boot */
major = 0; /* hp / ... */
adaptor = (bootregs[1] & 0x6000) >> 17;
break;
- case 17: /* UDA50 boot */
+ case BDEV_UDA: /* UDA50 boot */
major = 9; /* ra / mscp */
- if (is_750)
+ if (vax_cputype == VAX_750)
adaptor = (bootregs[1] & 0x40000 ? 0 : 1);
break;
- case 18: /* TK50 boot */
+ case BDEV_TK50: /* TK50 boot */
major = 15; /* tms / tmscp */
- is_tmscp = 1; /* use tape spec in mscp routines */
break;
- case 64:
+ case 36: /* VS2000/KA410 ST506 disk */
+ case 37: /* VS2000/KA410 SCSI tape */
+ case 42: /* VS3100/76 SCSI-floppy(?) */
+ major = 17; /* 17 is assigned to the ROM-drivers */
+ break;
+
+ case BDEV_CONSOLE:
major = 8;
break;
@@ -224,7 +239,7 @@ struct disklabel lp;
int part_off = 0; /* offset into partition holding /boot */
char io_buf[MAXBSIZE];
volatile struct uda {
- struct uda1ca uda_ca; /* communications area */
+ struct mscp_1ca uda_ca; /* communications area */
struct mscp uda_rsp; /* response packets */
struct mscp uda_cmd; /* command packets */
} uda;
@@ -245,27 +260,27 @@ devopen(f, fname, file)
/*
* On uVAX we need to init [T]MSCP ctlr to be able to use it.
*/
- if (is_mvax) {
+ if (vax_cputype == VAX_78032 || vax_cputype == VAX_650) {
switch (bootdev) {
- case 17: /* MSCP */
- case 18: /* TMSCP */
+ case BDEV_UDA: /* MSCP */
+ case BDEV_TK50: /* TMSCP */
csr = (struct udadevice *)rpb->csrphy;
csr->udaip = 0; /* Start init */
- while((csr->udasa & UDA_STEP1) == 0);
+ while((csr->udasa & MP_STEP1) == 0);
csr->udasa = 0x8000;
- while((csr->udasa & UDA_STEP2) == 0);
+ while((csr->udasa & MP_STEP2) == 0);
csr->udasa = (short)(((u_int)&uda)&0xffff) + 8;
- while((csr->udasa & UDA_STEP3) == 0);
+ while((csr->udasa & MP_STEP3) == 0);
csr->udasa = 0x10;
- while((csr->udasa & UDA_STEP4) == 0);
+ while((csr->udasa & MP_STEP4) == 0);
csr->udasa = 0x0001;
uda.uda_ca.ca_rspdsc =
(int) &uda.uda_rsp.mscp_cmdref;
uda.uda_ca.ca_cmddsc =
(int) &uda.uda_cmd.mscp_cmdref;
- if (is_tmscp)
+ if (bootdev == BDEV_TK50)
uda.uda_cmd.mscp_vcid = 1;
command(M_OP_SETCTLRC, 0);
uda.uda_cmd.mscp_unit = rpb->unit;
@@ -279,11 +294,10 @@ devopen(f, fname, file)
* Actually disklabel is only needed when using hp disks,
* but it doesn't hurt to always get it.
*/
- if (!is_tmscp) {
+ if ((bootdev != BDEV_TK50) && (bootdev != BDEV_CONSOLE)) {
msg = getdisklabel((void *)LABELOFFSET + RELOC, &lp);
- if (msg) {
+ if (msg)
printf("getdisklabel: %s\n", msg);
- }
}
return 0;
}
@@ -317,13 +331,13 @@ romstrategy(sc, func, dblk, size, buf, rsize)
int block = dblk;
int nsize = size;
- switch (cpunumber) {
+ switch (vax_cputype) {
case VAX_650:
case VAX_78032:
switch (bootdev) {
- case 17: /* MSCP */
+ case BDEV_UDA: /* MSCP */
uda.uda_cmd.mscp_seq.seq_lbn = dblk;
uda.uda_cmd.mscp_seq.seq_bytecount = size;
uda.uda_cmd.mscp_seq.seq_buffer = (int)buf;
@@ -331,7 +345,7 @@ romstrategy(sc, func, dblk, size, buf, rsize)
command(M_OP_READ, 0);
break;
- case 18: /* TMSCP */
+ case BDEV_TK50: /* TMSCP */
if (dblk < curblock) {
uda.uda_cmd.mscp_seq.seq_bytecount =
curblock - dblk;
@@ -351,16 +365,21 @@ romstrategy(sc, func, dblk, size, buf, rsize)
command(M_OP_READ, 0);
}
break;
+ case 36:
+ case 37:
+ default:
+ romread_uvax(block, size, buf, bootregs);
+ break;
}
break;
+ case VAX_8200:
case VAX_750:
- if (bootdev) {
+ if (bootdev != BDEV_MBA) {
while (size > 0) {
- if ((read750(block, bootregs) & 0x01) == 0)
- return 1;
-
+ while ((read750(block, bootregs) & 0x01) == 0)
+ printf("Retrying read bn# %d\n", block);
bcopy(0, buf, 512);
size -= 512;
buf += 512;
diff --git a/sys/arch/vax/boot/conf.c b/sys/arch/vax/boot/conf.c
index f516c4d2c3a..72b7f44faf0 100644
--- a/sys/arch/vax/boot/conf.c
+++ b/sys/arch/vax/boot/conf.c
@@ -1,4 +1,4 @@
-/* $NetBSD: conf.c,v 1.5 1996/02/17 18:23:18 ragge Exp $ */
+/* $NetBSD: conf.c,v 1.6 1996/08/02 11:21:56 ragge Exp $ */
/*
* Copyright (c) 1994 Ludd, University of Lule}, Sweden.
* All rights reserved.
@@ -42,25 +42,33 @@ int raopen(), rastrategy();
int hpopen(), hpstrategy();
int ctuopen(), ctustrategy();
int tmscpopen(), tmscpstrategy();
+int romopen(), romstrategy();
+int mfmopen(), mfmstrategy();
+int sdopen(), sdstrategy();
+
struct devsw devsw[]={
SADEV("hp",hpstrategy, hpopen, nullsys, noioctl),
- SADEV("ht",nullsys, nodev, nullsys, noioctl),
- SADEV("up",nullsys, nodev, nullsys, noioctl),
- SADEV("hk",nullsys, nodev, nullsys, noioctl),
+ SADEV(0 ,nullsys, nodev, nullsys, noioctl), /* ht */
+ SADEV(0 ,nullsys, nodev, nullsys, noioctl), /* up */
+ SADEV(0 ,nullsys, nodev, nullsys, noioctl), /* hk */
SADEV( 0 ,nullsys, nodev, nullsys, noioctl),
- SADEV("tm",nullsys, nodev, nullsys, noioctl),
- SADEV("ts",nullsys, nodev, nullsys, noioctl),
- SADEV("mt",nullsys, nodev, nullsys, noioctl),
+ SADEV(0 ,nullsys, nodev, nullsys, noioctl), /* tm */
+ SADEV(0 ,nullsys, nodev, nullsys, noioctl), /* ts */
+ SADEV(0 ,nullsys, nodev, nullsys, noioctl), /* mt */
SADEV("ctu",ctustrategy, ctuopen, nullsys, noioctl),
SADEV("ra",rastrategy, raopen, nullsys, noioctl),
- SADEV("ut",nullsys, nodev, nullsys, noioctl),
- SADEV("id",nullsys, nodev, nullsys, noioctl),
- SADEV("rx",nullsys, nodev, nullsys, noioctl),
- SADEV("uu",nullsys, nodev, nullsys, noioctl),
- SADEV("rl",nullsys, nodev, nullsys, noioctl),
- SADEV("tms",tmscpstrategy, tmscpopen, nullsys, noioctl),
- SADEV("kra",nullsys, nodev, nullsys, noioctl),
+ SADEV(0 ,nullsys, nodev, nullsys, noioctl), /* ut */
+ SADEV(0 ,nullsys, nodev, nullsys, noioctl), /* id */
+ SADEV(0 ,nullsys, nodev, nullsys, noioctl), /* rx */
+ SADEV(0 ,nullsys, nodev, nullsys, noioctl), /* uu */
+ SADEV(0 ,nullsys, nodev, nullsys, noioctl), /* rl */
+ SADEV("mt",tmscpstrategy, tmscpopen, nullsys, noioctl),
+ SADEV(0 ,nullsys, nodev, nullsys, noioctl), /* crx */
+ SADEV("rom",romstrategy, romopen, nullsys, noioctl), /* 17 */
+ SADEV("mfm",mfmstrategy, mfmopen, nullsys, noioctl), /* 18 */
+ SADEV("sd",sdstrategy, sdopen, nullsys, noioctl), /* 18 */
+ SADEV("st",sdstrategy, sdopen, nullsys, noioctl),
};
int ndevs = (sizeof(devsw)/sizeof(devsw[0]));
diff --git a/sys/arch/vax/boot/consio.c b/sys/arch/vax/boot/consio.c
index 39402cc1d44..94db46d0262 100644
--- a/sys/arch/vax/boot/consio.c
+++ b/sys/arch/vax/boot/consio.c
@@ -1,4 +1,4 @@
-/* $NetBSD: consio.c,v 1.3 1995/09/16 15:48:49 ragge Exp $ */
+/* $NetBSD: consio.c,v 1.4 1996/08/02 11:22:00 ragge Exp $ */
/*
* Copyright (c) 1994 Ludd, University of Lule}, Sweden.
* All rights reserved.
@@ -38,24 +38,165 @@
#include "../vax/gencons.h"
#include "../include/mtpr.h"
+#include "../include/sid.h"
+#include "../include/rpb.h"
-putchar(ch)
- int ch;
+#include "data.h"
+
+void setup __P((void));
+
+int vax_cputype;
+int vax_boardtype;
+
+int is_750;
+int is_mvax;
+
+unsigned *bootregs;
+struct rpb *rpb;
+struct bqo *bqo;
+
+static int (*put_fp) __P((int)) = NULL;
+static int (*get_fp) __P((void)) = NULL;
+
+int pr_putchar __P((int c)); /* putchar() using mtpr/mfpr */
+int pr_getchar __P((void));
+
+int rom_putchar __P((int c)); /* putchar() using ROM routines */
+int rom_getchar __P((void));
+
+static int rom_putc; /* ROM-address of put-routine */
+static int rom_getc; /* ROM-address of get-routine */
+
+putchar(c)
+ int c;
+{
+ (*put_fp)(c);
+ if (c == 10)
+ (*put_fp)(13); /* CR/LF */
+}
+
+getchar()
+{
+ int c;
+
+ do
+ c = (*get_fp)() & 0177;
+ while (c == 17 || c == 19); /* ignore XON/XOFF */
+ return c;
+}
+
+
+/*
+ * setup() is called out of the startup files (start.s, srt0.s) and
+ * initializes data which are globally used and is called before main().
+ */
+void
+setup()
{
- while ((mfpr(PR_TXCS) & GC_RDY) == 0); /* Wait until xmit ready */
- mtpr(ch, PR_TXDB); /* xmit character */
- if (ch == 10)
- putchar(13); /* CR/LF */
+ vax_cputype = (mfpr(PR_SID) >> 24) & 0xFF;
+
+ put_fp = pr_putchar;
+ get_fp = pr_getchar;
+ /*
+ * according to vax_cputype we initialize vax_boardtype.
+ */
+ switch (vax_cputype) {
+ case VAX_650:
+ case VAX_78032:
+ is_mvax = 1;
+ vax_boardtype = (vax_cputype << 24) |
+ ((*(int*)0x20040004 >> 24) & 0377);
+ rpb = (struct rpb *)bootregs[11]; /* bertram: ??? */
+ break;
+ }
+
+ /*
+ * According to the vax_boardtype (vax_cputype is not specific
+ * enough to do that) we decide which method/routines to use
+ * for console I/O.
+ * mtpr/mfpr are restricted to serial consoles, ROM-based routines
+ * support both serial and graphical consoles, thus we use that
+ * as fallthrough/default.
+ */
+ switch (vax_boardtype) { /* ROM-based is default !!! */
+
+ case VAX_BTYP_650:
+ case VAX_BTYP_660:
+ case VAX_BTYP_670:
+ case VAX_BTYP_690:
+ case VAX_BTYP_1303:
+ put_fp = rom_putchar;
+ get_fp = rom_getchar;
+ rom_putc = 0x20040058; /* 537133144 */
+ rom_getc = 0x20040008; /* 537133064 */
+ break;
+
+ case VAX_BTYP_43:
+ case VAX_BTYP_46:
+ case VAX_BTYP_49:
+ case VAX_BTYP_410:
+ put_fp = rom_putchar;
+ get_fp = rom_getchar;
+ rom_putc = 0x20040058; /* 537133144 */
+ rom_getc = 0x20040044; /* 537133124 */
+ break;
+
+ default:
+ break;
+ }
+
+ return;
}
-getchar()
+/*
+ * putchar() using MTPR
+ */
+pr_putchar(c)
+ int c;
{
- int ch;
+ int timeout = 1<<15; /* don't hang the machine! */
+ while ((mfpr(PR_TXCS) & GC_RDY) == 0) /* Wait until xmit ready */
+ if (--timeout < 0)
+ break;
+ mtpr(c, PR_TXDB); /* xmit character */
+}
- do {
- while ((mfpr(PR_RXCS) & GC_DON) == 0); /* wait for char */
- ch = mfpr(PR_RXDB); /* now get it */
- } while (ch == 17 || ch == 19);
- return ch;
+/*
+ * getchar() using MFPR
+ */
+pr_getchar()
+{
+ while ((mfpr(PR_RXCS) & GC_DON) == 0); /* wait for char */
+ return (mfpr(PR_RXDB)); /* now get it */
}
+
+/*
+ * int rom_putchar (int c) ==> putchar() using ROM-routines
+ */
+asm("
+ .globl _rom_putchar
+ _rom_putchar:
+ .word 0x04 # save-mask: R2
+ movl 4(ap), r2 # move argument to R2
+ jsb *_rom_putc # write it
+ ret # that's all
+");
+
+
+/*
+ * int rom_getchar (void) ==> getchar() using ROM-routines
+ */
+asm("
+ .globl _rom_getchar
+ _rom_getchar:
+ .word 0x02 # save-mask: R1
+ loop: # do {
+ jsb *_rom_getc # call the getc-routine
+ tstl r0 # check if char ready
+ beql loop # } while (R0 == 0)
+ movl r1, r0 # R1 holds char
+ ret # we're done
+");
+
+
diff --git a/sys/arch/vax/boot/copy.c b/sys/arch/vax/boot/copy.c
index a67721d7458..c46ba5674e3 100644
--- a/sys/arch/vax/boot/copy.c
+++ b/sys/arch/vax/boot/copy.c
@@ -1,4 +1,4 @@
-/* $NetBSD: copy.c,v 1.2 1995/09/29 16:35:00 ragge Exp $ */
+/* $NetBSD: copy.c,v 1.3 1996/08/02 11:22:03 ragge Exp $ */
/*-
* Copyright (c) 1982, 1986 The Regents of the University of California.
* All rights reserved.
@@ -38,6 +38,8 @@
#include "sys/reboot.h"
#include "lib/libsa/stand.h"
+#include "vaxstand.h"
+
#include <a.out.h>
char line[100];
@@ -53,7 +55,7 @@ static int partlist[8];
int fill_buffer (void);
int write_disk (void);
-main()
+Xmain()
{
int adapt, ctlr, unit, part;
int res, i, loops;
diff --git a/sys/arch/vax/boot/devopen.c b/sys/arch/vax/boot/devopen.c
index d3468b427dd..8d58b778998 100644
--- a/sys/arch/vax/boot/devopen.c
+++ b/sys/arch/vax/boot/devopen.c
@@ -1,4 +1,4 @@
-/* $NetBSD: devopen.c,v 1.4 1996/03/16 11:02:28 ragge Exp $ */
+/* $NetBSD: devopen.c,v 1.6 1996/08/02 16:18:39 ragge Exp $ */
/*-
* Copyright (c) 1993 John Brezak
* All rights reserved.
@@ -52,7 +52,7 @@ usage()
{
printf("\
Usage: device(adaptor, controller, drive, partition)file\n\
- <device><unit><partitonletter>:file\n\
+ <device><unit><partitonletter>:file\n\
");
}
@@ -62,15 +62,15 @@ devlookup(d,len)
{
struct devsw *dp = devsw;
int i;
-
+
for (i = 0; i < ndevs; i++, dp++)
if (dp->dv_name && strncmp(dp->dv_name, d, len) == 0)
- return(i);
+ return(i);
printf("No such device - Configured devices are:\n");
for (dp = devsw, i = 0; i < ndevs; i++, dp++)
if (dp->dv_name)
- printf(" %s", dp->dv_name);
+ printf(" %s", dp->dv_name);
printf("\n");
errno = ENODEV;
return(-1);
@@ -90,7 +90,7 @@ devparse(fname, dev, adapt, ctlr, unit, part, file)
{
int *argp, i;
char *s, *args[4];
-
+
/* get device name and make lower case */
for(s = fname; *s && *s != '/' && *s != ':' && *s != '('; s++)
if(isupper(*s))
@@ -117,19 +117,19 @@ devparse(fname, dev, adapt, ctlr, unit, part, file)
*part = atoi(args[3]);
break;
case 3:
- *ctlr = atoi(args[0]);
- *unit = atoi(args[1]);
- *part = atoi(args[2]);
- break;
+ *ctlr = atoi(args[0]);
+ *unit = atoi(args[1]);
+ *part = atoi(args[2]);
+ break;
case 2:
- *unit = atoi(args[0]);
- *part = atoi(args[1]);
- break;
+ *unit = atoi(args[0]);
+ *part = atoi(args[1]);
+ break;
case 1:
- *part = atoi(args[0]);
- break;
+ *part = atoi(args[0]);
+ break;
case 0:
- break;
+ break;
}
*file = ++s;
@@ -142,25 +142,25 @@ devparse(fname, dev, adapt, ctlr, unit, part, file)
/* lookup device and get index */
if ((*dev = devlookup(fname, s - fname)) < 0)
- goto baddev;
+ goto baddev;
/* isolate unit */
if ((*unit = atoi(s)) > sizeof(char))
- goto bad;
+ goto bad;
for (; isdigit(*s); s++)
;
/* translate partition */
if(!ispart(*s))
- goto bad;
+ goto bad;
*part = *s++ - 'a';
if(*s != ':')
- goto bad;
+ goto bad;
*file = ++s;
/* no device present */
- } else
+ } else
*file = fname;
/* return the remaining unparsed part as the file to boot */
@@ -176,8 +176,8 @@ bad:
extern int bootdev;
devopen(f, fname, file)
- struct open_file *f;
- const char *fname;
+ struct open_file *f;
+ const char *fname;
char **file;
{
int n, error;
@@ -190,12 +190,12 @@ devopen(f, fname, file)
unit = B_UNIT(bootdev);
part = B_PARTITION(bootdev);
adapt = B_ADAPTOR(bootdev);
-
+
if (error = devparse(fname, &dev, &adapt, &ctlr, &unit, &part, file))
return(error);
-
+
dp = &devsw[dev];
-
+
if (!dp->dv_open)
return(ENODEV);
diff --git a/sys/arch/vax/boot/edlabel.c b/sys/arch/vax/boot/edlabel.c
index 09844183bef..a5af6abe894 100644
--- a/sys/arch/vax/boot/edlabel.c
+++ b/sys/arch/vax/boot/edlabel.c
@@ -1,4 +1,4 @@
-/* $NetBSD: edlabel.c,v 1.1 1995/09/16 12:56:03 ragge Exp $ */
+/* $NetBSD: edlabel.c,v 1.2 1996/08/02 11:22:11 ragge Exp $ */
/*
* Copyright (c) 1995 Ludd, University of Lule}, Sweden.
* All rights reserved.
@@ -88,7 +88,7 @@ setdefaultlabel()
#define GETNUM2(out, num1, num) printf(out, num1, num);gets(store); \
if (*store) num = atoi(store);
#define GETSTR(out, str) printf(out, str);gets(store); \
- if (*store) strcpy(str, store);
+ if (*store) bcopy(store, str, strlen(store));
#define FLAGS(out, flag) printf(out, lp->d_flags & flag?'y':'n');gets(store); \
if (*store == 'y' || *store == 'Y') lp->d_flags |= flag; \
else lp->d_flags &= ~flag;
@@ -121,9 +121,11 @@ editlabel()
GETNUM("drivedata 2? [%d] ", lp->d_drivedata[2]);
GETNUM("drivedata 3? [%d] ", lp->d_drivedata[3]);
GETNUM("drivedata 4? [%d] ", lp->d_drivedata[4]);
+ lp->d_secsize = 512;
GETNUM("\nbytes/sector? [%d] ", lp->d_secsize);
GETNUM("sectors/track? [%d] ", lp->d_nsectors);
GETNUM("tracks/cylinder? [%d] ", lp->d_ntracks);
+ lp->d_secpercyl = lp->d_nsectors * lp->d_ntracks;
GETNUM("sectors/cylinder? [%d] ", lp->d_secpercyl);
GETNUM("cylinders? [%d] ", lp->d_ncylinders);
lp->d_npartitions = MAXPARTITIONS;
@@ -137,7 +139,7 @@ editlabel()
int bootdev;
void
-main()
+Xmain()
{
register bdev asm("r10");
diff --git a/sys/arch/vax/boot/init.c b/sys/arch/vax/boot/init.c
deleted file mode 100644
index 94c7ad6276a..00000000000
--- a/sys/arch/vax/boot/init.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/* $NetBSD: init.c,v 1.3 1995/09/16 13:34:21 ragge Exp $ */
-/*
- * Copyright (c) 1995 Ludd, University of Lule}, Sweden. All rights reserved.
- *
- * This code is derived from software contributed to Ludd by Bertram Barth.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer. 2.
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution. 3. All advertising
- * materials mentioning features or use of this software must display the
- * following acknowledgement: This product includes software developed at
- * Ludd, University of Lule}, Sweden and its contributors. 4. The name of the
- * author may not be used to endorse or promote products derived from this
- * software without specific prior written permission
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* All bugs are subject to removal without further notice */
-
-
-
-#include "lib/libsa/stand.h"
-
-#include "../include/mtpr.h" /* mfpr(), mtpr() */
-#include "../include/sid.h" /* cpu_type, cpu_number */
-
-#define NRSP 0 /* Kludge, must be done before udareg.h */
-#define NCMD 0 /* includes */
-
-#include "../uba/udareg.h" /* struct udadevice */
-
-#include "data.h" /* bootregs[], rpb, bqo */
-
-struct rpb *rpb;
-struct bqo *bqo;
-
-int is_750 = 0, is_mvax = 0;
-
-/*
- * initdata() sets up data gotten from start routines, mostly for uVAX.
- */
-int
-initdata()
-{
- int i, *tmp;
-
- cpu_type = mfpr(PR_SID);
- cpunumber = (mfpr(PR_SID) >> 24) & 0xFF;
-
- switch (cpunumber) {
-
- case VAX_78032:
- case VAX_650:
- {
- int cpu_sie; /* sid-extension */
-
- is_mvax = 1;
- cpu_sie = *((int *) 0x20040004) >> 24;
- cpu_type |= cpu_sie;
-
- break;
- }
- case VAX_750:
- is_750 = 1;
- break;
- }
- return 0;
-}
diff --git a/sys/arch/vax/boot/ka410.h b/sys/arch/vax/boot/ka410.h
new file mode 100644
index 00000000000..a022362c08f
--- /dev/null
+++ b/sys/arch/vax/boot/ka410.h
@@ -0,0 +1,82 @@
+/* $NetBSD: ka410.h,v 1.1 1996/08/02 11:22:13 ragge Exp $ */
+/*
+ * Copyright (c) 1996 Ludd, University of Lule}, Sweden.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Ludd by
+ * Bertram Barth.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed at Ludd, University of
+ * Lule}, Sweden and its contributors.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+
+/*
+ * interrupt request-, clear-, and mask register
+ */
+extern volatile unsigned char *ka410_intreq;
+extern volatile unsigned char *ka410_intclr;
+extern volatile unsigned char *ka410_intmsk;
+
+#define INTR_SR (1<<7) /* Serial line receiver or silo full */
+#define INTR_ST (1<<6) /* Serial line transmitter done */
+#define INTR_NP (1<<5) /* Network controller primary */
+#define INTR_NS (1<<4) /* Network controller secondary */
+#define INTR_VF (1<<3) /* Video end of frame */
+#define INTR_VS (1<<2) /* Video secondary */
+#define INTR_SC (1<<1) /* SCSI controller */
+#define INTR_DC (1<<0) /* Disk controller */
+
+/*
+ * interrupt vector numbers
+ */
+#define IVEC_BASE 0x20040020
+#define IVEC_SR 0x000002C0
+#define IVEC_ST 0x000002C4
+#define IVEC_NP 0x00000250
+#define IVEC_NS 0x00000254
+#define IVEC_VF 0x00000244
+#define IVEC_VS 0x00000248
+#define IVEC_SC 0x000003F8
+#define IVEC_DC 0x000003FC
+
+/*
+ * Clock-Chip data in NVRAM
+ */
+#define KA410_CPMBX 0x200B0038 /* Console Mailbox (1 byte) */
+#define KA410_CPFLG 0x200B003C /* Console Program Flags (1 byte) */
+#define KA410_LK201_ID 0x200B0040 /* Keyboard Variation (1 byte) */
+#define KA410_CONS_ID 0x200B0044 /* Console Device Type (1 byte) */
+#define KA410_SCR 0x200B0048 /* Console Scratch RAM */
+#define KA410_TEMP 0x200B0058 /* Used by System Firmware */
+#define KA410_BAT_CHK 0x200B0088 /* Battery Check Data */
+#define KA410_BOOTDEV 0x200B0098 /* Default Boot Device (4 bytes) */
+#define KA410_BOOTFLG 0x200B00A8 /* Default Boot Flags (4 bytes) */
+#define KA410_SCRLEN 0x200B00B8 /* Number of pages of SCR (1 byte) */
+#define KA410_SCSIPORT 0x200B00BC /* Tape Controller Port Data */
+#define KA410_RESERVED 0x200B00C0 /* Reserved (16 bytes) */
+
diff --git a/sys/arch/vax/boot/mfm.c b/sys/arch/vax/boot/mfm.c
new file mode 100644
index 00000000000..bd271530ea4
--- /dev/null
+++ b/sys/arch/vax/boot/mfm.c
@@ -0,0 +1,640 @@
+/* $NetBSD: mfm.c,v 1.1 1996/08/02 11:22:16 ragge Exp $ */
+/*
+ * Copyright (c) 1996 Ludd, University of Lule}, Sweden.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Ludd by
+ * Bertram Barth.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed at Ludd, University of
+ * Lule}, Sweden and its contributors.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * ToDo:
+ *
+ * - insert appropriate delays for diskette-drive where needed
+ * - allow more than one sector per diskette-read
+ * - check for and handle bad sectors
+ * - ???
+ */
+
+#include "sys/param.h"
+#include "sys/reboot.h"
+#include "sys/disklabel.h"
+
+#include "lib/libsa/stand.h"
+#include "lib/libsa/ufs.h"
+
+#include "../include/pte.h"
+#include "../include/sid.h"
+#include "../include/mtpr.h"
+#include "../include/reg.h"
+#include "../include/rpb.h"
+
+#include "ka410.h"
+#include "../vsa/hdc9224.h"
+
+#include "data.h"
+#include "vaxstand.h"
+
+#define MAX_WAIT (1000*1000) /* # of loop-instructions in seconds */
+
+struct mfm_softc {
+ int part;
+ int unit;
+};
+
+int mfmstrategy(), mfmopen();
+struct disklabel mfmlabel;
+struct mfm_softc mfm_softc;
+char io_buf[MAXBSIZE];
+
+/*
+ * These should probably be somewhere else, but ka410 is the only
+ * one with mfm disks anyway...
+ */
+volatile unsigned char *ka410_intreq = (void*)0x2008000f;
+volatile unsigned char *ka410_intclr = (void*)0x2008000f;
+volatile unsigned char *ka410_intmsk = (void*)0x2008000c;
+
+static volatile struct hdc9224_DKCreg *dkc = (void *) 0x200c0000;
+static volatile struct hdc9224_UDCreg sreg; /* input */
+static volatile struct hdc9224_UDCreg creg; /* output */
+
+/*
+ * we have to wait 0.7 usec between two accesses to any of the
+ * dkc-registers, on a VS2000 with 1 MIPS, this is roughly one
+ * instruction. Thus the loop-overhead will be enough...
+ */
+static int
+sreg_read()
+{
+ int i;
+ char *p;
+
+ dkc->dkc_cmd = 0x40; /* set internal counter to zero */
+ p = (void *) &sreg;
+ for (i = 0; i < 10; i++)
+ *p++ = dkc->dkc_reg; /* dkc_reg auto-increments */
+}
+
+static int
+creg_write()
+{
+ int i;
+ char *p;
+
+ dkc->dkc_cmd = 0x40; /* set internal counter to zero */
+ p = (void *) &creg;
+ for (i = 0; i < 10; i++)
+ dkc->dkc_reg = *p++; /* dkc_reg auto-increments */
+}
+
+/*
+ * floppies are handled in a quite strange way by this controller...
+ *
+ * before reading/writing a sector from/to floppy, we use the SEEK/READ_ID
+ * command to place the head at the desired location. Then we wait some
+ * time before issueing the real command in order to let the drive become
+ * ready...
+ */
+int
+mfm_rxprepare()
+{
+ int error;
+
+ error = mfm_command(DKC_CMD_SEEKREADID | 0x04); /* step=1, verify=0 */
+ if (error) {
+ printf("error while stepping to position %d/%d/%x. Retry...\n",
+ creg.udc_dsect, creg.udc_dhead, creg.udc_dcyl);
+ error = mfm_command(DKC_CMD_SEEKREADID | 0x04);
+ }
+ return error;
+}
+
+int
+mfm_rxselect(unit)
+ int unit;
+{
+ int error;
+
+ /*
+ * bring "creg" in some known-to-work state and
+ * select the drive with the DRIVE SELECT command.
+ */
+ creg.udc_dma7 = 0;
+ creg.udc_dma15 = 0;
+ creg.udc_dma23 = 0;
+ creg.udc_dsect = 1; /* sectors are numbered 1..15 !!! */
+ creg.udc_dhead = 0;
+ creg.udc_dcyl = 0;
+ creg.udc_scnt = 0;
+
+ creg.udc_rtcnt = UDC_RC_RX33READ;
+ creg.udc_mode = UDC_MD_RX33;
+ creg.udc_term = UDC_TC_FDD;
+
+ /*
+ * this is ...
+ */
+ error = mfm_command(DKC_CMD_DRSEL_RX33 | unit);
+
+ if ((error != 0) || (sreg.udc_dstat & UDC_DS_READY == 0)) {
+ printf("\nfloppy-drive not ready (new floppy inserted?)\n\n");
+
+ creg.udc_rtcnt &= ~UDC_RC_INVRDY; /* clear INVRDY-flag */
+ error = mfm_command(DKC_CMD_DRSEL_RX33 | unit);
+ if ((error != 0) || (sreg.udc_dstat & UDC_DS_READY == 0)) {
+ printf("diskette not ready(1): %x/%x\n",
+ error, sreg.udc_dstat);
+ printf("floppy-drive offline?\n");
+ return (-1);
+ }
+ if (sreg.udc_dstat & UDC_DS_TRK00)
+ error = mfm_command(DKC_CMD_STEPIN_FDD);
+ else
+ error = mfm_command(DKC_CMD_STEPOUT_FDD);
+
+ /*
+ * now ready should be 0, cause INVRDY is not set
+ * (retrying a command makes this fail...)
+ */
+ if ((error != 0) || (sreg.udc_dstat & UDC_DS_READY == 1)) {
+ printf("diskette not ready(2): %x/%x\n",
+ error, sreg.udc_dstat);
+ }
+ creg.udc_rtcnt |= UDC_RC_INVRDY;
+ error = mfm_command(DKC_CMD_DRSEL_RX33 | unit);
+
+ if ((error != 0) || (sreg.udc_dstat & UDC_DS_READY == 0)) {
+ printf("diskette not ready(3): %x/%x\n",
+ error, sreg.udc_dstat);
+ printf("no floppy inserted or floppy-door open\n");
+ return (-1);
+ }
+ printf("floppy-drive reselected.\n");
+ }
+ return (error);
+}
+
+int
+mfm_rdselect(unit)
+ int unit;
+{
+ int error;
+
+ /*
+ * bring "creg" in some known-to-work state and
+ * select the drive with the DRIVE SELECT command.
+ */
+ creg.udc_dma7 = 0;
+ creg.udc_dma15 = 0;
+ creg.udc_dma23 = 0;
+ creg.udc_dsect = 0; /* sectors are numbered 0..16 */
+ creg.udc_dhead = 0;
+ creg.udc_dcyl = 0;
+ creg.udc_scnt = 0;
+
+ creg.udc_rtcnt = UDC_RC_HDD_READ;
+ creg.udc_mode = UDC_MD_HDD;
+ creg.udc_term = UDC_TC_HDD;
+
+ error = mfm_command(DKC_CMD_DRSEL_HDD | unit);
+
+ return (error);
+}
+
+static int mfm_retry = 0;
+
+int
+mfm_command(cmd)
+ int cmd;
+{
+ int termcode, ready, i;
+
+ creg_write(); /* write command-registers */
+ *ka410_intclr = INTR_DC;
+ dkc->dkc_cmd = cmd; /* issue command */
+ for (i = 0; i < MAX_WAIT; i++) {
+ if (*ka410_intreq & INTR_DC) /* wait for interrupt */
+ break;
+ }
+ if ((*ka410_intreq & INTR_DC) == 0)
+ printf("timeout in mfm_command...\n");
+
+ sreg_read(); /* read status-registers */
+
+ if (dkc->dkc_stat == (DKC_ST_DONE | DKC_TC_SUCCESS))
+ return (0);
+
+ if (sreg.udc_cstat & UDC_CS_ECCERR) {
+ printf(
+"\nspurious(?) ECC/CRC error at s%d/t%d/c%d [s%d/t%d/c%d(%d)]\n",
+ sreg.udc_csect, sreg.udc_chead, sreg.udc_ccyl,
+ creg.udc_dsect, creg.udc_dhead, creg.udc_dcyl,creg.udc_scnt);
+ if (sreg.udc_csect != creg.udc_dsect + creg.udc_scnt - 1) {
+ printf("DMA: %x %x %x [%x]\n",
+ sreg.udc_dma23, sreg.udc_dma15,
+ sreg.udc_dma7, 512 * (sreg.udc_csect -
+ creg.udc_dsect));
+ creg.udc_scnt = creg.udc_scnt -
+ (sreg.udc_csect - creg.udc_dsect) - 1;
+ creg.udc_dsect = sreg.udc_csect + 1;
+ creg.udc_dma23 = sreg.udc_dma23;
+ creg.udc_dma15 = sreg.udc_dma15 + 2;
+ creg.udc_dma7 = 0;
+ printf("Retry starting from s%d/t%d/c%d (%d). ",
+ creg.udc_dsect, creg.udc_dhead, creg.udc_dcyl,
+ creg.udc_scnt);
+ }
+ goto retry;
+ }
+ termcode = (dkc->dkc_stat & DKC_ST_TERMCOD) >> 3;
+ ready = sreg.udc_dstat & UDC_DS_READY;
+
+ printf("cmd:0x%x: termcode=0x%x, status=0x%x, cstat=0x%x, dstat=0x%x\n",
+ cmd, termcode, dkc->dkc_stat, sreg.udc_cstat, sreg.udc_dstat);
+
+ if (dkc->dkc_stat & DKC_ST_BADSECT)
+ printf("bad sector found: s%d/t%d/c%d\n", creg.udc_dsect,
+ creg.udc_dhead, creg.udc_dcyl);
+retry:
+ if ((mfm_retry == 0) && (sreg.udc_cstat & UDC_CS_RETREQ)) {
+ mfm_retry = 1;
+ printf("Retrying... ");
+ mfm_command(cmd);
+ printf("Retry done.\n");
+ mfm_retry = 0;
+ }
+ return ((dkc->dkc_stat & DKC_ST_TERMCOD) >> 3);
+}
+
+/*
+ * on-disk geometry block
+ */
+#define _aP __attribute__ ((packed)) /* force byte-alignment */
+
+volatile struct mfm_xbn {
+ char mbz[10];/* 10 bytes of zero */
+ long xbn_count _aP; /* number of XBNs */
+ long dbn_count _aP; /* number of DBNs */
+ long lbn_count _aP; /* number of LBNs (Logical-Block-Numbers) */
+ long rbn_count _aP; /* number of RBNs (Replacement-Block-Numbers) */
+ short nspt; /* number of sectors per track */
+ short ntracks;/* number of tracks */
+ short ncylinders; /* number of cylinders */
+ short precomp;/* first cylinder for write precompensation */
+ short reduced;/* first cylinder for reduced write current */
+ short seek_rate; /* seek rate or zero for buffered
+ * seeks */
+ short crc_eec;/* 0 if CRC is being used or 1 if ECC is
+ * being used */
+ short rct; /* "replacement control table" (RCT) */
+ short rct_ncopies; /* number of copies of the RCT */
+ long media_id _aP; /* media identifier */
+ short interleave; /* sector-to-sector interleave */
+ short headskew; /* head-to-head skew */
+ short cylskew;/* cylinder-to-cylinder skew */
+ short gap0_size; /* size of GAP 0 in the MFM format */
+ short gap1_size; /* size of GAP 1 in the MFM format */
+ short gap2_size; /* size of GAP 2 in the MFM format */
+ short gap3_size; /* size of GAP 3 in the MFM format */
+ short sync_value; /* sync value used to start a track
+ * when formatting */
+ char reserved[32]; /* reserved for use by the RQDX1/2/3
+ * formatter */
+ short serial_number; /* serial number */
+ char fill[412]; /* Filler bytes to the end of the
+ * block */
+ short checksum; /* checksum over the XBN */
+} mfm_xbn;
+
+display_xbn(p)
+ struct mfm_xbn *p;
+{
+ printf("**DiskData** XBNs: %d, DBNs: %d, LBNs: %d, RBNs: %d\n",
+ p->xbn_count, p->dbn_count, p->lbn_count, p->rbn_count);
+ printf("sect/track: %d, tracks: %d, cyl: %d, precomp/reduced: %d/%d\n",
+ p->nspt, p->ntracks, p->ncylinders, p->precomp, p->reduced);
+ printf("seek-rate: %d, crc/eec: %s, RCT: %d, RCT-copies: %d\n",
+ p->seek_rate, p->crc_eec ? "EEC" : "CRC", p->rct, p->rct_ncopies);
+ printf("media-ID: 0x%x, interleave: %d, headskew: %d, cylskew: %d\n",
+ &p->media_id, p->interleave, p->headskew, p->cylskew);
+ printf("gap0: %d, gap1: %d, gap2: %d, gap3: %d, sync-value: %d\n",
+ p->gap0_size, p->gap1_size, p->gap2_size, p->gap3_size,
+ p->sync_value);
+ printf("serial: %d, checksum: %d, size: %d, reserved: %32c\n",
+ p->serial_number, p->checksum, sizeof(*p), p->reserved);
+}
+
+mfmopen(f, adapt, ctlr, unit, part)
+ struct open_file *f;
+ int ctlr, unit, part;
+{
+ char *msg;
+ struct disklabel *lp = &mfmlabel;
+ volatile struct mfm_softc *msc = &mfm_softc;
+ int i, err;
+
+ bzero(lp, sizeof(struct disklabel));
+ msc->unit = unit;
+ msc->part = part;
+
+ err = mfmstrategy(msc, F_READ, LABELSECTOR, DEV_BSIZE, io_buf, &i);
+ if (err) {
+ printf("reading disklabel: %s\n", strerror(err));
+ return 0;
+ }
+ msg = getdisklabel(io_buf + LABELOFFSET, lp);
+ if (msg)
+ printf("getdisklabel: %s\n", msg);
+
+ f->f_devdata = (void *) msc;
+
+ {
+ int k;
+ unsigned char *ucp;
+ struct mfm_xbn *xp;
+
+ /* mfmstrategy(msc, F_READ, -16, 8192, io_buf, &i); */
+ mfmstrategy(msc, F_READ, -16, 512, io_buf, &i);
+ printf("dumping raw disk-block #0:\n");
+ ucp = io_buf;
+ for (k = 0; k < 128; k++) {
+ if (ucp[k] < 0x10)
+ printf("0");
+ printf("%x ", ucp[k]);
+ if (k % 8 == 7)
+ printf(" ");
+ if (k % 16 == 15)
+ printf("\n");
+ }
+ printf("\n");
+
+ xp = (void *) io_buf;
+ display_xbn(xp);
+ printf("\n");
+
+ }
+
+ if (unit == 2) { /* floppy! */
+ if (lp->d_ntracks != 2) {
+ printf("changing number of tracks from %d to %d.\n",
+ lp->d_ntracks, 2);
+ lp->d_ntracks = 2;
+ }
+ } else { /* hard-disk */
+ unsigned short *usp = (void *) io_buf;
+ printf("label says: s/t/c = %d/%d/%d\n",
+ lp->d_nsectors, lp->d_ntracks, lp->d_ncylinders);
+
+ if (lp->d_nsectors != usp[13]) {
+ printf("changing number of sectors from %d to %d.\n",
+ lp->d_nsectors, usp[13]);
+ lp->d_nsectors = usp[13];
+ }
+ if (lp->d_ntracks != usp[14]) {
+ printf("changing number of heads/tracks from %d to %d.\n",
+ lp->d_ntracks, usp[14]);
+ lp->d_ntracks = usp[14];
+ }
+ if (lp->d_ncylinders != usp[15]) {
+ printf("changing number of cylinders from %d to %d.\n",
+ lp->d_ncylinders, usp[15]);
+ lp->d_ncylinders = usp[15];
+ }
+ lp->d_secpercyl = lp->d_nsectors * lp->d_ntracks;
+ }
+
+ return (0);
+}
+
+mfm_rxstrategy(msc, func, dblk, size, buf, rsize)
+ struct mfm_softc *msc;
+ int func;
+ daddr_t dblk;
+ char *buf;
+ int size, *rsize;
+{
+ struct disklabel *lp;
+ int block, sect, head, cyl, scount, i, cmd, res, sval;
+
+ lp = &mfmlabel;
+ block = (dblk < 0 ? 0 : dblk + lp->d_partitions[msc->part].p_offset);
+
+ mfm_rxselect(msc->unit);
+
+ /*
+ * if label is empty, assume RX33
+ */
+ if (lp->d_nsectors == 0)
+ lp->d_nsectors = 15;
+ if (lp->d_ntracks == 0)
+ lp->d_ntracks = 2;
+ if (lp->d_secpercyl == 0)
+ lp->d_secpercyl = 30;
+
+ bzero((void *) 0x200D0000, size);
+ scount = size / 512;
+
+ while (scount) {
+ /*
+ * prepare drive/operation parameter
+ */
+ cyl = block / lp->d_secpercyl;
+ sect = block % lp->d_secpercyl;
+ head = sect / lp->d_nsectors;
+ sect = sect % lp->d_nsectors;
+
+ /*
+ * *rsize = 512; /* one sector after the other
+ * ...
+ */
+ *rsize = 512 * min(scount, lp->d_nsectors - sect);
+
+ /*
+ * now initialize the register values ...
+ */
+ creg.udc_dma7 = 0;
+ creg.udc_dma15 = 0;
+ creg.udc_dma23 = 0;
+
+ creg.udc_dsect = sect + 1; /* sectors are numbered 1..15
+ * !!! */
+ head |= (cyl >> 4) & 0x70;
+ creg.udc_dhead = head;
+ creg.udc_dcyl = cyl;
+
+ creg.udc_scnt = *rsize / 512;
+
+ if (func == F_WRITE) {
+ creg.udc_rtcnt = UDC_RC_RX33WRT;
+ creg.udc_mode = UDC_MD_RX33;
+ creg.udc_term = UDC_TC_FDD;
+
+ mfm_rxprepare();
+ /* copy from buf */
+ bcopy(buf, (void *) 0x200D0000, *rsize);
+ res = mfm_command(DKC_CMD_WRITE_RX33);
+ } else {
+ creg.udc_rtcnt = UDC_RC_RX33READ;
+ creg.udc_mode = UDC_MD_RX33;
+ creg.udc_term = UDC_TC_FDD;
+
+ mfm_rxprepare();
+ /* clear disk buffer */
+ bzero((void *) 0x200D0000, *rsize);
+ res = mfm_command(DKC_CMD_READ_RX33);
+ /* copy to buf */
+ bcopy((void *) 0x200D0000, buf, *rsize);
+ }
+
+ scount -= *rsize / 512;
+ block += *rsize / 512;
+ buf += *rsize;
+ }
+
+ *rsize = size;
+ return 0;
+}
+
+mfm_rdstrategy(msc, func, dblk, size, buf, rsize)
+ struct mfm_softc *msc;
+ int func;
+ daddr_t dblk;
+ char *buf;
+ int size, *rsize;
+{
+ struct disklabel *lp;
+ int block, sect, head, cyl, scount, i, cmd, res, sval;
+
+ lp = &mfmlabel;
+ block = (dblk < 0 ? 0 : dblk + lp->d_partitions[msc->part].p_offset);
+
+ /*
+ * if label is empty, assume RD32 (XXX this must go away!!!)
+ */
+ if (lp->d_nsectors == 0)
+ lp->d_nsectors = 17;
+ if (lp->d_ntracks == 0)
+ lp->d_ntracks = 6;
+ if (lp->d_secpercyl == 0)
+ lp->d_secpercyl = 102;
+
+ mfm_rdselect(msc->unit);
+
+ bzero((void *) 0x200D0000, size);
+ scount = size / 512;
+
+ while (scount) {
+ /*
+ * prepare drive/operation parameter
+ */
+ cyl = block / lp->d_secpercyl;
+ sect = block % lp->d_secpercyl;
+ head = sect / lp->d_nsectors;
+ sect = sect % lp->d_nsectors;
+
+ if (dblk < 0) {
+ printf("using raw diskblock-data!\n");
+ printf("block %d, dblk %d ==> cyl %d, head %d, sect %d\n",
+ block, dblk, cyl, sect, head);
+ } else
+ cyl += 1; /* first cylinder is reserved for
+ * controller! */
+
+ *rsize = 512 * min(scount, lp->d_nsectors - sect);
+ /*
+ * now re-initialize the register values ...
+ */
+ creg.udc_dma7 = 0;
+ creg.udc_dma15 = 0;
+ creg.udc_dma23 = 0;
+
+ creg.udc_dsect = sect;
+ head |= (cyl >> 4) & 0x70;
+ creg.udc_dhead = head;
+ creg.udc_dcyl = cyl;
+
+ creg.udc_scnt = *rsize / 512;
+
+ if (func == F_WRITE) {
+ creg.udc_rtcnt = UDC_RC_HDD_WRT;
+ creg.udc_mode = UDC_MD_HDD;
+ creg.udc_term = UDC_TC_HDD;
+ cmd = DKC_CMD_WRITE_HDD;
+
+ bcopy(buf, (void *) 0x200D0000, *rsize);
+ res = mfm_command(cmd);
+ } else {
+ creg.udc_rtcnt = UDC_RC_HDD_READ;
+ creg.udc_mode = UDC_MD_HDD;
+ creg.udc_term = UDC_TC_HDD;
+ cmd = DKC_CMD_READ_HDD;
+
+ bzero((void *) 0x200D0000, *rsize);
+ res = mfm_command(cmd);
+ bcopy((void *) 0x200D0000, buf, *rsize);
+ }
+
+ scount -= *rsize / 512;
+ block += *rsize / 512;
+ buf += *rsize;
+ }
+
+ /*
+ * unselect the drive ...
+ */
+ mfm_command(DKC_CMD_DRDESELECT);
+
+ *rsize = size;
+ return 0;
+}
+
+int
+mfmstrategy(msc, func, dblk, size, buf, rsize)
+ struct mfm_softc *msc;
+ int func;
+ daddr_t dblk;
+ char *buf;
+ int size, *rsize;
+{
+ int res = -1;
+
+ switch (msc->unit) {
+ case 0:
+ case 1:
+ res = mfm_rdstrategy(msc, func, dblk, size, buf, rsize);
+ break;
+ case 2:
+ res = mfm_rxstrategy(msc, func, dblk, size, buf, rsize);
+ break;
+ default:
+ printf("invalid unit %d in mfmstrategy()\n");
+ }
+ return (res);
+}
diff --git a/sys/arch/vax/boot/ra.c b/sys/arch/vax/boot/ra.c
index 43e368fe098..722b19d99cd 100644
--- a/sys/arch/vax/boot/ra.c
+++ b/sys/arch/vax/boot/ra.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ra.c,v 1.4 1996/02/17 18:23:23 ragge Exp $ */
+/* $NetBSD: ra.c,v 1.5 1996/08/02 11:22:18 ragge Exp $ */
/*
* Copyright (c) 1995 Ludd, University of Lule}, Sweden.
* All rights reserved.
@@ -31,8 +31,8 @@
/* All bugs are subject to removal without further notice */
-#define NRSP 0 /* Kludge */
-#define NCMD 0 /* Kludge */
+#define NRSP 1 /* Kludge */
+#define NCMD 1 /* Kludge */
#include "sys/param.h"
#include "sys/disklabel.h"
@@ -41,9 +41,16 @@
#include "../include/pte.h"
#include "../include/macros.h"
+#include "../include/sid.h"
+
#include "../uba/ubareg.h"
#include "../uba/udareg.h"
-#include "../vax/mscp.h"
+
+#include "../mscp/mscp.h"
+#include "../mscp/mscpreg.h"
+
+#include "../bi/bireg.h"
+#include "../bi/kdbreg.h"
#include "vaxstand.h"
@@ -62,10 +69,13 @@ struct ra_softc {
int ubaddr;
int part;
int unit;
+ unsigned short *ra_ip;
+ unsigned short *ra_sa;
+ unsigned short *ra_sw;
};
volatile struct uda {
- struct uda1ca uda_ca; /* communications area */
+ struct mscp_1ca uda_ca; /* communications area */
struct mscp uda_rsp; /* response packets */
struct mscp uda_cmd; /* command packets */
} uda;
@@ -81,53 +91,84 @@ raopen(f, adapt, ctlr, unit, part)
int ctlr, unit, part;
{
char *msg;
- struct disklabel *lp=&ralabel;
- volatile struct ra_softc *ra=&ra_softc;
- volatile struct uba_regs *mr=(void *)ubaaddr[adapt];
+ struct disklabel *lp = &ralabel;
+ volatile struct ra_softc *ra = &ra_softc;
+ volatile struct uba_regs *mr = (void *)ubaaddr[adapt];
volatile u_int *nisse;
- unsigned short johan;
+ unsigned short johan, johan2;
int i,err;
- if(adapt>nuba) return(EADAPT);
- if(ctlr>nuda) return(ECTLR);
bzero(lp, sizeof(struct disklabel));
- ra->udaddr=uioaddr[adapt]+udaaddr[ctlr];
- ra->ubaddr=(int)mr;
- ra->unit=unit;
+ ra->unit = unit;
ra->part = part;
- udacsr=(void*)ra->udaddr;
- nisse=(u_int *)&mr->uba_map[0];
- nisse[494]=PG_V|(((u_int)&uda)>>9);
- nisse[495]=nisse[494]+1;
- ubauda=(void*)0x3dc00+(((u_int)(&uda))&0x1ff);
+ if (vax_cputype != VAX_8200) {
+ if (adapt > nuba)
+ return(EADAPT);
+ if (ctlr > nuda)
+ return(ECTLR);
+ nisse = (u_int *)&mr->uba_map[0];
+ nisse[494] = PG_V | (((u_int)&uda) >> 9);
+ nisse[495] = nisse[494] + 1;
+ udacsr = (void*)uioaddr[adapt] + udaaddr[ctlr];
+ ubauda = (void*)0x3dc00 + (((u_int)(&uda))&0x1ff);
+ johan = (((u_int)ubauda) & 0xffff) + 8;
+ johan2 = 3;
+ ra->ra_ip = (short *)&udacsr->udaip;
+ ra->ra_sa = ra->ra_sw = (short *)&udacsr->udasa;
+ ra->udaddr = uioaddr[adapt] + udaaddr[ctlr];
+ ra->ubaddr = (int)mr;
+ *ra->ra_ip = 0; /* Start init */
+ } else {
+ struct bi_node *bi = (void *)biaddr[adapt];
+ struct kdb_regs *kb = (void *)&bi[ctlr];
+ volatile int i = 10000;
+
+ ra->ra_ip = &kb->kdb_ip;
+ ra->ra_sa = &kb->kdb_sa;
+ ra->ra_sw = &kb->kdb_sw;
+ johan = ((u_int)&uda.uda_ca.ca_rspdsc) & 0xffff;
+ johan2 = (((u_int)&uda.uda_ca.ca_rspdsc) & 0xffff0000) >> 16;
+ kb->kdb_bi.bi_csr |= BICSR_NRST;
+ while (i--) /* Need delay??? */
+ ;
+ kb->kdb_bi.bi_ber = ~(BIBER_MBZ|BIBER_NMR|BIBER_UPEN);/* ??? */
+ ubauda = &uda;
+ }
+
/* Init of this uda */
- udacsr->udaip=0; /* Start init */
- while((udacsr->udasa&UDA_STEP1) == 0);
- udacsr->udasa=0x8000;
- while((udacsr->udasa&UDA_STEP2) == 0);
- johan=(((u_int)ubauda)&0xffff)+8;
- udacsr->udasa=johan;
- while((udacsr->udasa&UDA_STEP3) == 0);
- udacsr->udasa=3;
- while((udacsr->udasa&UDA_STEP4) == 0);
- udacsr->udasa=0x0001;
- uda.uda_ca.ca_rspdsc=(int)&ubauda->uda_rsp.mscp_cmdref;
- uda.uda_ca.ca_cmddsc=(int)&ubauda->uda_cmd.mscp_cmdref;
+ while ((*ra->ra_sa & MP_STEP1) == 0)
+ ;
+
+ *ra->ra_sw = 0x8000;
+ while ((*ra->ra_sa & MP_STEP2) == 0)
+ ;
+
+ *ra->ra_sw = johan;
+ while ((*ra->ra_sa & MP_STEP3) == 0)
+ ;
+
+ *ra->ra_sw = johan2;
+ while ((*ra->ra_sa & MP_STEP4) == 0)
+ ;
+
+ *ra->ra_sw = 0x0001;
+ uda.uda_ca.ca_rspdsc = (int)&ubauda->uda_rsp.mscp_cmdref;
+ uda.uda_ca.ca_cmddsc = (int)&ubauda->uda_cmd.mscp_cmdref;
+
command(M_OP_SETCTLRC);
- uda.uda_cmd.mscp_unit=ra->unit;
+ uda.uda_cmd.mscp_unit = ra->unit;
command(M_OP_ONLINE);
- err=rastrategy(ra,F_READ, LABELSECTOR, DEV_BSIZE, io_buf, &i);
+ err = rastrategy(ra,F_READ, LABELSECTOR, DEV_BSIZE, io_buf, &i);
if(err){
printf("reading disklabel: %s\n",strerror(err));
return 0;
}
- msg=getdisklabel(io_buf+LABELOFFSET, lp);
- if(msg) {
- printf("getdisklabel: %s\n",msg);
- }
- f->f_devdata=(void *)ra;
+ msg = getdisklabel(io_buf+LABELOFFSET, lp);
+ if (msg)
+ printf("getdisklabel: %s\n", msg);
+ f->f_devdata = (void *)ra;
return(0);
}
@@ -136,13 +177,14 @@ command(cmd)
{
volatile int hej;
- uda.uda_cmd.mscp_opcode=cmd;
- uda.uda_cmd.mscp_msglen=MSCP_MSGLEN;
- uda.uda_rsp.mscp_msglen=MSCP_MSGLEN;
+ uda.uda_cmd.mscp_opcode = cmd;
+ uda.uda_cmd.mscp_msglen = MSCP_MSGLEN;
+ uda.uda_rsp.mscp_msglen = MSCP_MSGLEN;
uda.uda_ca.ca_rspdsc |= MSCP_OWN|MSCP_INT;
uda.uda_ca.ca_cmddsc |= MSCP_OWN|MSCP_INT;
- hej=udacsr->udaip;
- while(uda.uda_ca.ca_rspdsc<0);
+ hej = *ra_softc.ra_ip;
+ while(uda.uda_ca.ca_rspdsc<0)
+ ;
}
@@ -161,20 +203,23 @@ rastrategy(ra, func, dblk, size, buf, rsize)
volatile int hej;
- ur = (void *)ra->ubaddr;
- udadev = (void*)ra->udaddr;
- ptmapp = (u_int *)&ur->uba_map[0];
- lp = &ralabel;
+ if (vax_cputype != VAX_8200) {
+ ur = (void *)ra->ubaddr;
+ udadev = (void*)ra->udaddr;
+ ptmapp = (u_int *)&ur->uba_map[0];
- pfnum = (u_int)buf >> PGSHIFT;
+ pfnum = (u_int)buf >> PGSHIFT;
- for(mapnr = 0, nsize = size; (nsize + NBPG) > 0; nsize -= NBPG)
- ptmapp[mapnr++] = PG_V | pfnum++;
+ for(mapnr = 0, nsize = size; (nsize + NBPG) > 0; nsize -= NBPG)
+ ptmapp[mapnr++] = PG_V | pfnum++;
+ uda.uda_cmd.mscp_seq.seq_buffer = ((u_int)buf) & 0x1ff;
+ } else
+ uda.uda_cmd.mscp_seq.seq_buffer = ((u_int)buf);
+ lp = &ralabel;
uda.uda_cmd.mscp_seq.seq_lbn =
dblk + lp->d_partitions[ra->part].p_offset;
uda.uda_cmd.mscp_seq.seq_bytecount = size;
- uda.uda_cmd.mscp_seq.seq_buffer = ((u_int)buf) & 0x1ff;
uda.uda_cmd.mscp_unit = ra->unit;
if (func == F_WRITE)
command(M_OP_WRITE);
diff --git a/sys/arch/vax/boot/rom.c b/sys/arch/vax/boot/rom.c
new file mode 100644
index 00000000000..f299f506350
--- /dev/null
+++ b/sys/arch/vax/boot/rom.c
@@ -0,0 +1,123 @@
+/* $NetBSD: rom.c,v 1.1 1996/08/02 11:22:21 ragge Exp $ */
+/*
+ * Copyright (c) 1996 Ludd, University of Lule}, Sweden.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Ludd by
+ * Bertram Barth.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed at Ludd, University of
+ * Lule}, Sweden and its contributors.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "sys/param.h"
+#include "sys/reboot.h"
+#include "sys/disklabel.h"
+
+#include "lib/libsa/stand.h"
+#include "lib/libsa/ufs.h"
+
+#include "../include/pte.h"
+#include "../include/sid.h"
+#include "../include/mtpr.h"
+#include "../include/reg.h"
+#include "../include/rpb.h"
+
+#include "data.h"
+#include "vaxstand.h"
+
+extern unsigned *bootregs;
+extern struct rpb *rpb;
+
+struct rom_softc {
+ int part;
+ int unit;
+};
+
+int romstrategy(), romopen();
+struct disklabel romlabel;
+struct rom_softc rom_softc;
+char io_buf[MAXBSIZE];
+
+romopen(f, adapt, ctlr, unit, part)
+ struct open_file *f;
+ int ctlr, unit, part;
+{
+ char *msg;
+ struct disklabel *lp = &romlabel;
+ volatile struct rom_softc *rsc = &rom_softc;
+ int i,err;
+
+ bootregs[11] = XXRPB;
+ rpb = (void*)XXRPB;
+ bqo = (void*)rpb->iovec;
+
+ if (rpb->unit > 0 && (rpb->unit % 100) == 0) {
+ printf ("changing rpb->unit from %d ", rpb->unit);
+ rpb->unit /= 100;
+ printf ("to %d\n", rpb->unit);
+ }
+
+ bzero(lp, sizeof(struct disklabel));
+ rsc->unit = unit;
+ rsc->part = part;
+
+ err = romstrategy(rsc, F_READ, LABELSECTOR, DEV_BSIZE, io_buf, &i);
+ if (err) {
+ printf("reading disklabel: %s\n",strerror(err));
+ return 0;
+ }
+ msg = getdisklabel(io_buf+LABELOFFSET, lp);
+ if (msg)
+ printf("getdisklabel: %s\n",msg);
+ f->f_devdata = (void*)rsc;
+ return(0);
+}
+
+romstrategy (rsc, func, dblk, size, buf, rsize)
+ struct rom_softc *rsc;
+ int func;
+ daddr_t dblk;
+ char *buf;
+ int size, *rsize;
+{
+ struct disklabel *lp;
+ int block;
+
+ lp = &romlabel;
+ block = dblk + lp->d_partitions[rsc->part].p_offset;
+ if (rsc->unit >= 0 && rsc->unit < 10)
+ rpb->unit = rsc->unit;
+
+ if (func == F_WRITE)
+ romwrite_uvax(block, size, buf, bootregs);
+ else
+ romread_uvax(block, size, buf, bootregs);
+
+ *rsize = size;
+ return 0;
+}
+
diff --git a/sys/arch/vax/boot/romread.s b/sys/arch/vax/boot/romread.s
index 966280792fb..ff893c4b6d9 100644
--- a/sys/arch/vax/boot/romread.s
+++ b/sys/arch/vax/boot/romread.s
@@ -1,4 +1,4 @@
-/* $NetBSD: romread.s,v 1.3 1995/09/16 16:20:18 ragge Exp $ */
+/* $NetBSD: romread.s,v 1.4 1996/08/02 11:22:24 ragge Exp $ */
/*
* Copyright (c) 1995 Ludd, University of Lule}, Sweden.
* All rights reserved.
@@ -40,20 +40,6 @@
#include "../include/asm.h"
/*
- * read630 (int block, int *regs)
- */
-ENTRY(read630, 0xFFE)
- pushl $0 # base of rpb
- pushl $0 # virtual-flag
- pushl $33 # read-logical-block
- pushl 12(ap) # lbn to start reading
- pushl 8(ap) # number of bytes to read
- pushl 4(ap) # buffer-address
- calls $6, (r6) # call the qio-routine
- halt
- ret # r0 holds the result
-
-/*
* read750 (int block, int *regs)
*/
ENTRY(read750, 0xFFE)
@@ -72,9 +58,9 @@ ENTRY(read750, 0xFFE)
ret
/*
- * bulkread630 (int lbn, int size, void *buf, int *regs)
+ * romread_uvax (int lbn, int size, void *buf, int *regs)
*/
-ENTRY(bulkread630, 0xFFE)
+ENTRY(romread_uvax, 0xFFE)
movl 16(ap), r11 # array of bootregs
movl 44(r11), r11 # restore boot-contents of r11 (rpb)
movl 52(r11), r7 # load iovec/bqo into r7
@@ -87,3 +73,21 @@ ENTRY(bulkread630, 0xFFE)
pushl 12(ap) # buffer-address
calls $6, (r6) # call the qio-routine
ret # r0 holds the result
+
+/*
+ * romwrite_uvax (int lbn, int size, void *buf, int *regs)
+ */
+ENTRY(romwrite_uvax, 0xFFE)
+ movl 16(ap), r11 # array of bootregs
+ movl 44(r11), r11 # restore boot-contents of r11 (rpb)
+ movl 52(r11), r7 # load iovec/bqo into r7
+ addl3 (r7), r7, r6 # load qio into r6
+ pushl r11 # base of rpb
+ pushl $0 # virtual-flag
+ pushl $32 # write-logical-block
+ pushl 4(ap) # lbn to start reading
+ pushl 8(ap) # number of bytes to read
+ pushl 12(ap) # buffer-address
+ calls $6, (r6) # call the qio-routine
+ ret # r0 holds the result
+
diff --git a/sys/arch/vax/boot/samachdep.h b/sys/arch/vax/boot/samachdep.h
new file mode 100644
index 00000000000..829a17d2b49
--- /dev/null
+++ b/sys/arch/vax/boot/samachdep.h
@@ -0,0 +1,42 @@
+/* $NetBSD: samachdep.h,v 1.1 1996/08/02 11:22:28 ragge Exp $ */
+
+/*
+ * Copyright (c) 1982, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)samachdep.h 8.1 (Berkeley) 6/10/93
+ */
+
+#define NSCSI 1
+#define NSD 8
+
+extern int howto;
+extern unsigned int bootdev;
diff --git a/sys/arch/vax/boot/scsi_hi.c b/sys/arch/vax/boot/scsi_hi.c
new file mode 100644
index 00000000000..0102123cc32
--- /dev/null
+++ b/sys/arch/vax/boot/scsi_hi.c
@@ -0,0 +1,297 @@
+/* $NetBSD: scsi_hi.c,v 1.1 1996/08/02 11:22:31 ragge Exp $ */
+
+/****************************************************************************
+ * NS32K Monitor SCSI high-level driver
+ * Bruce Culbertson
+ * 8 March 1990
+ * (This source is public domain source)
+ *
+ * There are three monitor SCSI commands. "Read" and "write" I think are
+ * fairly self explanatory once you read the help messages. They, in fact,
+ * execute the "extended read", "extended write", and "request sense"
+ * commands from the SCSI standard.
+ *
+ * "Raw" lets you execute any SCSI command but you need a SCSI reference to
+ * know what the commands are and what their formats are. The SCSI
+ * standard specifies that there are six buffers which, for example, hold a
+ * SCSI command or are the source or destination for data. You provide
+ * "raw" with an array of pointers to the six buffers. Using "edit", you
+ * can enter a SCSI command somewhere in memory and you can create the
+ * array of pointers. The array must actually be eight entries long; two
+ * entries are not used. By typing "raw <array address>", the SCSI command
+ * is executed.
+ *
+ * By the way, "read", "write", and "raw" talk only to the DP8490 SCSI
+ * controller. I have not had time to read the Adaptec data sheet and
+ * write a driver for it.
+ ****************************************************************************/
+#include "so.h"
+
+#define OK 0
+#define NOT_OK OK+1
+#define PRIVATE
+#define PUBLIC
+#define U8 unsigned char
+
+long scsiAdr = DEFAULT_SCSI_ADR, /* default SCSI address */
+ scsiLun = DEFAULT_SCSI_LUN;
+
+struct cmd_desc { /* SCSI command description */
+ const U8 *cmd; /* command string */
+ const U8 *odata; /* data to output, if any */
+ const struct cmd_desc *chain; /* next command */
+};
+
+struct drive { /* SCSI drive description */
+ U8 adr, lun; /* SCSI address and LUN */
+ U8 flags; /* drive characteristics */
+ U8 stat; /* drive state */
+ const struct cmd_desc *init; /* list of initialize commands */
+};
+/* for drive.flags */
+#define EXTENDED_RDWR 1 /* device does extended read, write */
+#define EXTENDED_SENSE 2 /* device does extended sense */
+/* for drive.stat */
+#define INITIALIZED 1 /* device is initialized */
+
+PRIVATE struct drive drive_tbl[] = {
+#if 1
+ {0, 0, 0, 1, 0},
+ {1, 0, 0, 1, 0},
+ {2, 0, 0, 1, 0},
+ {3, 0, 0, 1, 0},
+ {4, 0, 0, 1, 0},
+ {5, 0, 0, 1, 0},
+ {6, 0, 0, 1, 0},
+ {7, 0, 0, 1, 0},
+#else
+ {0, 0, EXTENDED_RDWR | EXTENDED_SENSE, 1, 0},
+ {1, 0, EXTENDED_RDWR | EXTENDED_SENSE, 1, 0},
+ {2, 0, EXTENDED_RDWR | EXTENDED_SENSE, 1, 0},
+ {3, 0, EXTENDED_RDWR | EXTENDED_SENSE, 1, 0},
+ {4, 0, EXTENDED_RDWR | EXTENDED_SENSE, 1, 0},
+ {5, 0, EXTENDED_RDWR | EXTENDED_SENSE, 1, 0},
+ {6, 0, EXTENDED_RDWR | EXTENDED_SENSE, 1, 0},
+ {7, 0, EXTENDED_RDWR | EXTENDED_SENSE, 1, 0},
+#endif
+};
+#define DRV_TBL_SZ (sizeof (drive_tbl) / sizeof (struct drive))
+
+/* Round up to multiple of four since SCSI transfers are always multiples
+ * of four bytes.
+ */
+#define CMD_LEN 12 /* longest SCSI command */
+#define SENSE_LEN 24 /* extended sense length */
+#define MSG_LEN 4
+#define STAT_LEN 4
+
+#define MAX_SCSI_RETRIES 6
+#define CMD_IX 2
+#define CMD_SENSE 0x03
+#define CMD_READ 0x08
+#define CMD_WRITE 0x0a
+#define CMD_XREAD 0x28
+#define CMD_XWRITE 0x2a
+PRIVATE U8 cmd_buf[CMD_LEN];
+
+#define SENSE_KEY 2
+#define NO_SENSE 0
+#define RECOVERY_ERR 1
+#define UNIT_ATTN 6
+#define ADD_SENSE_CODE 12
+#define SENSE_RST 0x29
+PRIVATE U8 sense_buf[SENSE_LEN];
+
+#define CHECK_CONDITION 2
+#define STAT_IX 3
+#define STAT_MASK 0x1f
+PRIVATE U8 stat_buf[STAT_LEN];
+#define IMSG_IX 7
+PRIVATE U8 msg_buf[MSG_LEN];
+
+#define ODATA_IX 0
+#define IDATA_IX 1
+PRIVATE struct scsi_args scsi_args;
+
+/*===========================================================================*
+ * sc_rdwt *
+ *===========================================================================*/
+/* Carry out a read or write request for the SCSI disk. */
+PRIVATE int
+sc_rdwt(op, block, ram_adr, len, sc_adr, lun)
+long block, ram_adr, len, sc_adr, lun;
+{
+ int retries, ret;
+ U8 *p;
+ struct drive *dp;
+
+ printf ("sc_rdwt: op %x, block %d, ram %x, len %d, sc_adr %d, lun %d\n",
+ op, block, ram_adr, len, sc_adr, lun);
+
+ /* get drive characteristics */
+ for (dp = drive_tbl; dp < drive_tbl + DRV_TBL_SZ - 1; ++dp)
+ if (dp->adr == sc_adr && dp->lun == lun) break;
+ if (dp == drive_tbl + DRV_TBL_SZ - 1) {
+ dp->adr = sc_adr; /* have default, set adr, lun */
+ dp->lun = lun;
+ }
+ for (retries = 0; retries < MAX_SCSI_RETRIES; ++retries) {
+ if (dp->init && !(dp->stat & INITIALIZED))
+ if (OK != sc_initialize (dp)) {
+ printf("SCSI cannot initialize device\n");
+ return NOT_OK;
+ }
+ p = cmd_buf; /* build SCSI command */
+ if (dp->flags & EXTENDED_RDWR) { /* use extended commands */
+ *p++ = (op == DISK_READ)? CMD_XREAD: CMD_XWRITE;
+ *p++ = lun << 5;
+ *p++ = (block >> 24) & 0xff;
+ *p++ = (block >> 16) & 0xff;
+ *p++ = (block >> 8) & 0xff;
+ *p++ = (block >> 0) & 0xff;
+ *p++ = 0;
+ *p++ = (len >> 8) & 0xff;
+ *p++ = (len >> 0) & 0xff;
+ *p = 0;
+ } else { /* use short (SASI) commands */
+ *p++ = (op == DISK_READ)? CMD_READ: CMD_WRITE;
+ *p++ = (lun << 5) | ((block >> 16) & 0x1f);
+ *p++ = (block >> 8) & 0xff;
+ *p++ = (block >> 0) & 0xff;
+ *p++ = len;
+ *p = 0;
+ }
+ if (op == DISK_READ)
+ ret = exec_scsi_hi (cmd_buf, (U8 *)ram_adr, (U8 *)0, dp);
+ else
+ ret = exec_scsi_hi (cmd_buf, (U8 *)0, (U8 *)ram_adr, dp);
+ if (OK == ret) return OK;
+ dp->stat &= ~INITIALIZED;
+ }
+ printf("SCSI %s, block %d failed even after retries\n",
+ op == DISK_READ? "READ": "WRITE", block);
+ return NOT_OK;
+}
+
+/*===========================================================================*
+ * sc_initialize *
+ *===========================================================================*/
+/* Execute the list of initialization commands for the given drive.
+ */
+int
+sc_initialize (dp)
+struct drive *dp;
+{
+ const struct cmd_desc *cp;
+
+ for (cp = dp->init; cp != 0; cp = cp->chain)
+ if (OK != exec_scsi_hi (cp->cmd, 0, cp->odata, dp)) {
+ dp->stat &= ~INITIALIZED;
+ return NOT_OK;
+ }
+ dp->stat |= INITIALIZED;
+ return OK;
+}
+
+/*===========================================================================*
+ * exec_scsi_hi *
+ *===========================================================================*/
+/* Execute a "high-level" SCSI command. This means execute a low level
+ * command and, if it fails, execute a request sense to find out why.
+ */
+PRIVATE int
+exec_scsi_hi(cmd, data_in, data_out, dp)
+U8 *cmd, *data_out, *data_in;
+struct drive *dp;
+{
+ scsi_args.ptr[CMD_IX] = (long)cmd;
+ scsi_args.ptr[STAT_IX] = (long)stat_buf;
+ scsi_args.ptr[IMSG_IX] = (long)msg_buf;
+ scsi_args.ptr[IDATA_IX] = (long)data_in;
+ scsi_args.ptr[ODATA_IX] = (long)data_out;
+ if (OK != exec_scsi_low (&scsi_args, dp->adr))
+ return NOT_OK;
+ *stat_buf &= STAT_MASK; /* strip off lun */
+ if (*stat_buf == 0)
+ /* Success -- this should be the usual case */
+ return OK;
+ if (*stat_buf != CHECK_CONDITION) {
+ /* do not know how to handle this so return error */
+ printf("SCSI device returned unknown status: %d\n", *stat_buf);
+ return NOT_OK;
+ }
+ /* Something funny happened, need to execute request-sense command
+ * to learn more.
+ */
+ if (OK == get_sense(dp))
+ /* Something funny happened, but the device recovered from it and
+ * the command succeeded.
+ */
+ return OK;
+ return NOT_OK;
+}
+
+/*===========================================================================*
+ * get_sense *
+ *===========================================================================*/
+/* Execute a "request sense" SCSI command and check results. When a SCSI
+ * command returns CHECK_CONDITION, a request-sense command must be executed.
+ * A request-sense command provides information about the original command.
+ * The original command might have succeeded, in which case it does not
+ * need to be retried and OK is returned. Examples: read error corrected
+ * with error correction code, or error corrected by retries performed by
+ * the SCSI device. The original command also could have failed, in
+ * which case NOT_OK is returned.
+ */
+#define XLOGICAL_ADR \
+ (sense_buf[3]<<24 | sense_buf[4]<<16 | sense_buf[5]<<8 | sense_buf[6])
+#define LOGICAL_ADR \
+ (sense_buf[1]<<16 | sense_buf[2]<<8 | sense_buf[3])
+
+PRIVATE int
+get_sense (dp)
+struct drive *dp;
+{
+ U8 *p;
+
+ p = cmd_buf; /* build SCSI command */
+ *p++ = CMD_SENSE;
+ *p++ = dp->lun << 5;
+ *p++ = 0;
+ *p++ = 0;
+ *p++ = (dp->flags & EXTENDED_SENSE)? SENSE_LEN: 0;
+ *p = 0;
+ scsi_args.ptr[IDATA_IX] = (long)sense_buf;
+ scsi_args.ptr[ODATA_IX] = 0;
+ scsi_args.ptr[CMD_IX] = (long)cmd_buf;
+ scsi_args.ptr[STAT_IX] = (long)stat_buf;
+ scsi_args.ptr[IMSG_IX] = (long)msg_buf;
+ if (OK != exec_scsi_low (&scsi_args, dp->adr)) {
+ printf("SCSI SENSE command failed\n");
+ return NOT_OK;
+ }
+ if ((*stat_buf & STAT_MASK) != 0) {
+ printf("SCSI SENSE returned wrong status %d\n", *stat_buf);
+ return NOT_OK;
+ }
+ if (0 == (dp->flags & EXTENDED_SENSE)) {
+ printf("SCSI request sense, code 0x%x, log_adr 0x%x\n",
+ sense_buf[0], LOGICAL_ADR);
+ return NOT_OK;
+ }
+ switch (sense_buf[SENSE_KEY] & 0xf) {
+ case NO_SENSE:
+ case UNIT_ATTN: /* reset */
+ return NOT_OK; /* must retry command */
+ case RECOVERY_ERR:
+ /* eventually, we probably do not want to hear about these. */
+ printf("SCSI ok with recovery, code 0x%x, logical address 0x%x\n",
+ sense_buf[ADD_SENSE_CODE], XLOGICAL_ADR);
+ return OK; /* orig command was ok with recovery */
+ default:
+ printf("SCSI failure: key 0x%x code 0x%x log adr 0x%x sense buf 0x%x\n",
+ sense_buf[SENSE_KEY], sense_buf[ADD_SENSE_CODE],
+ XLOGICAL_ADR, sense_buf);
+ return NOT_OK; /* orig command failed */
+ }
+}
diff --git a/sys/arch/vax/boot/scsi_low.c b/sys/arch/vax/boot/scsi_low.c
new file mode 100644
index 00000000000..a86a82de7c9
--- /dev/null
+++ b/sys/arch/vax/boot/scsi_low.c
@@ -0,0 +1,479 @@
+/* $NetBSD: scsi_low.c,v 1.1 1996/08/02 11:22:34 ragge Exp $ */
+
+/****************************************************************************
+ * NS32K Monitor SCSI low-level driver
+ * Bruce Culbertson
+ * 8 March 1990
+ * (This source is public domain source.)
+ *
+ * Originally written by Bruce Culbertson for a ns32016 port of Minix.
+ * Adapted from that for the pc532 (ns32632) monitor.
+ * Adapted from that for NetBSD/pc532 by Philip L. Bunde.
+ *
+ * Do not use DMA -- makes 32016 and pc532 versions compatible.
+ * Do not use interrupts -- makes it harder for the user code to bomb
+ * this code.
+ ****************************************************************************/
+
+#include "so.h"
+#include "ka410.h"
+
+#define BB_DEBUG(x) printf x
+#define CLEAR_INTR() *ka410_intclr=INTR_SC
+#define CHECK_INTR() *ka410_intreq&INTR_SC
+
+#define OK 0
+#define NOT_OK OK+1
+#define PRIVATE
+#define PUBLIC
+#define WR_ADR(adr,val) (*((volatile unsigned char *)(adr))=(val))
+#define RD_ADR(adr) (*((volatile unsigned char *)(adr)))
+/* #define AIC6250 0 */
+/* #define DP8490 1 */
+#define MAX_CACHE 0x4000
+
+/* SCSI bus phases
+ */
+#define PH_ODATA 0
+#define PH_IDATA 1
+#define PH_CMD 2
+#define PH_STAT 3
+#define PH_IMSG 7
+#define PH_NONE 8
+#define PH_IN(phase) ((phase) & 1)
+
+/* NCR5380 SCSI controller registers
+ */
+#define SC_CTL 0x200C0080 /* base for control registers */
+#define SC_DMA 0x200D0000 /* base for data registers (8/16K) */
+#define SC_CURDATA SC_CTL+(4*0)
+#define SC_OUTDATA SC_CTL+(4*0)
+#define SC_ICMD SC_CTL+(4*1)
+#define SC_MODE SC_CTL+(4*2)
+#define SC_TCMD SC_CTL+(4*3)
+#define SC_STAT1 SC_CTL+(4*4)
+#define SC_STAT2 SC_CTL+(4*5)
+#define SC_START_SEND SC_CTL+(4*5)
+#define SC_INDATA SC_CTL+(4*6)
+#define SC_RESETIP SC_CTL+(4*7)
+#define SC_START_RCV SC_CTL+(4*7)
+
+/* Bits in NCR5380 registers
+ */
+#define SC_A_RST 0x80
+#define SC_A_SEL 0x04
+#define SC_S_SEL 0x02
+#define SC_S_REQ 0x20
+#define SC_S_BSY 0x40
+#define SC_S_BSYERR 0x04
+#define SC_S_PHASE 0x08
+#define SC_S_IRQ 0x10
+#define SC_S_DRQ 0x40
+#define SC_M_DMA 0x02
+#define SC_M_BSY 0x04
+#define SC_ENABLE_DB 0x01
+
+/* Status of interrupt routine, returned in m1_i1 field of message.
+ */
+#define ISR_NOTDONE 0
+#define ISR_OK 1
+#define ISR_BSYERR 2
+#define ISR_RSTERR 3
+#define ISR_BADPHASE 4
+#define ISR_TIMEOUT 5
+
+#define ICU_ADR 0xfffffe00
+#define ICU_IO (ICU_ADR+20)
+#define ICU_DIR (ICU_ADR+21)
+#define ICU_DATA (ICU_ADR+19)
+#define ICU_SCSI_BIT 0x80
+
+/* Miscellaneous
+ */
+#define MAX_WAIT (1000*1000)
+#define SC_LOG_LEN 32
+
+PRIVATE struct scsi_args *sc_ptrs;
+PRIVATE char sc_cur_phase,
+ sc_reset_done = 1,
+ sc_have_msg,
+ sc_accept_int,
+ sc_dma_dir;
+
+long sc_dma_port = SC_DMA,
+ sc_dma_adr;
+
+#ifdef DEBUG
+struct sc_log {
+ unsigned char stat1, stat2;
+} sc_log [SC_LOG_LEN],
+ *sc_log_head = sc_log;
+int sc_spurious_int;
+#endif
+unsigned char
+ sc_watchdog_error; /* watch dog error */
+
+/* error messages */
+char *scsi_errors[] = {
+ 0, /* ISR_NOTDONE */
+ 0, /* ISR_OK */
+ "busy error", /* ISR_BSYERR */
+ "reset error", /* ISR_RSTERR */
+ "NULL pointer for current phase", /* ISR_BADPHASE */
+ "timeout", /* ISR_TIMEOUT */
+};
+
+/*===========================================================================*
+ * exec_scsi_low *
+ *===========================================================================*/
+/* Execute a generic SCSI command. Passed pointers to eight buffers:
+ * data-out, data-in, command, status, dummy, dummy, message-out, message-in.
+ */
+PUBLIC
+int
+exec_scsi_low (args, scsi_adr)
+struct scsi_args *args;
+long scsi_adr;
+{
+ int ret;
+
+ BB_DEBUG (("exec_scsi_low(0x%x, %d)\n", args, scsi_adr));
+
+ sc_ptrs = args; /* make pointers globally accessible */
+ /* bertram ??? scCtlrSelect (DP8490); */
+ if (!sc_reset_done) sc_reset();
+ /* TCMD has some undocumented behavior in initiator mode. I think the
+ * data bus cannot be enabled if i/o is asserted.
+ */
+ WR_ADR (SC_TCMD, 0);
+ if (OK != sc_wait_bus_free ()) { /* bus-free phase */
+ printf("SCSI: bus not free\n");
+ return NOT_OK;
+ }
+ sc_cur_phase = PH_NONE;
+ sc_have_msg = 0;
+ if (OK != sc_select (scsi_adr)) /* select phase */
+ return NOT_OK;
+ sc_watchdog_error = 0;
+ ret = sc_receive (); /* isr does the rest */
+ if (ret == ISR_OK) return OK;
+ else {
+ sc_reset();
+ printf("SCSI: %s\n", scsi_errors[ret]);
+ return NOT_OK;
+ }
+}
+
+/*===========================================================================*
+ * sc_reset *
+ *===========================================================================*/
+/*
+ * Reset SCSI bus.
+ */
+PRIVATE
+sc_reset()
+{
+ volatile int i;
+
+ BB_DEBUG (("sc_reset()\n"));
+
+ WR_ADR (SC_MODE, 0); /* get into harmless state */
+ WR_ADR (SC_OUTDATA, 0);
+ WR_ADR (SC_ICMD, SC_A_RST); /* assert RST on SCSI bus */
+ i = 200; /* wait 25 usec */
+ while (i--);
+ WR_ADR (SC_ICMD, 0); /* deassert RST, get off bus */
+ sc_reset_done = 1;
+}
+
+/*===========================================================================*
+ * sc_wait_bus_free *
+ *===========================================================================*/
+PRIVATE int
+sc_wait_bus_free()
+{
+ int i = MAX_WAIT;
+ volatile int j;
+
+ BB_DEBUG (("sc_wait_bus_free()\n"));
+
+ while (i--) {
+ /* Must be clear for 2 usec, so read twice */
+ if (RD_ADR (SC_STAT1) & (SC_S_BSY | SC_S_SEL)) continue;
+ for (j = 0; j < 25; ++j);
+ if (RD_ADR (SC_STAT1) & (SC_S_BSY | SC_S_SEL)) continue;
+ return OK;
+ }
+ sc_reset_done = 0;
+ return NOT_OK;
+}
+
+/*===========================================================================*
+ * sc_select *
+ *===========================================================================*/
+/* This duplicates much of the work that the interrupt routine would do on a
+ * phase mismatch and, in fact, the original plan was to just do the select,
+ * let a phase mismatch occur, and let the interrupt routine do the rest.
+ * That didn't work because the 5380 did not reliably generate the phase
+ * mismatch interrupt after selection.
+ */
+PRIVATE int
+sc_select(adr)
+long adr;
+{
+ int i, stat1;
+ long new_ptr;
+
+ BB_DEBUG (("sc_select(%d)\n", adr));
+
+ CLEAR_INTR();
+ WR_ADR (SC_OUTDATA, adr); /* SCSI bus address */
+ WR_ADR (SC_ICMD, SC_A_SEL | SC_ENABLE_DB);
+ for (i = 0;; ++i) { /* wait for target to assert SEL */
+ if (CHECK_INTR() == 0)
+ continue;
+ stat1 = RD_ADR (SC_STAT1);
+ if (stat1 & SC_S_BSY) break; /* select successful */
+ if (i > MAX_WAIT) { /* timeout */
+ printf("SCSI: SELECT timeout\n");
+ sc_reset();
+ return NOT_OK;
+ }
+ }
+ CLEAR_INTR();
+ WR_ADR (SC_ICMD, 0); /* clear SEL, disable data out */
+ WR_ADR (SC_OUTDATA, 0);
+ for (i = 0;; ++i) { /* wait for target to assert REQ */
+ if (CHECK_INTR() == 0)
+ continue;
+ if (stat1 & SC_S_REQ) break; /* target requesting transfer */
+ if (i > MAX_WAIT) { /* timeout */
+ printf("SCSI: REQ timeout\n");
+ sc_reset();
+ return NOT_OK;
+ }
+ stat1 = RD_ADR (SC_STAT1);
+ }
+ sc_cur_phase = (stat1 >> 2) & 7; /* get new phase from controller */
+ if (sc_cur_phase != PH_CMD) {
+ printf("SCSI: bad phase = %d\n", sc_cur_phase);
+ sc_reset();
+ return NOT_OK;
+ }
+ new_ptr = sc_ptrs->ptr[PH_CMD];
+ if (new_ptr == 0) {
+ printf("SCSI: NULL command pointer\n");
+ sc_reset();
+ return NOT_OK;
+ }
+ sc_accept_int = 1;
+ sc_dma_setup (DISK_WRITE, new_ptr);
+ CLEAR_INTR();
+ WR_ADR (SC_TCMD, PH_CMD);
+ WR_ADR (SC_ICMD, SC_ENABLE_DB);
+ WR_ADR (SC_MODE, SC_M_BSY | SC_M_DMA);
+ WR_ADR (SC_START_SEND, 0);
+ return OK;
+}
+
+/*===========================================================================*
+ * scsi_interrupt *
+ *===========================================================================*/
+/* SCSI interrupt handler.
+ */
+PUBLIC
+int
+scsi_interrupt()
+{
+ unsigned char stat2, dummy;
+ long new_ptr;
+ int ret = ISR_NOTDONE;
+
+ BB_DEBUG (("scsi_interrupt()\n"));
+
+ stat2 = RD_ADR (SC_STAT2); /* get status before clearing request */
+
+# ifdef DEBUG /* debugging log of interrupts */
+ sc_log_head->stat1 = RD_ADR (SC_STAT1);
+ sc_log_head->stat2 = stat2;
+ if (++sc_log_head >= sc_log + SC_LOG_LEN) sc_log_head = sc_log;
+ sc_log_head->stat1 = sc_log_head->stat2 = 0xff;
+# endif
+
+ for (;;) {
+ dummy = RD_ADR (SC_RESETIP); /* clear interrupt request */
+ if (!sc_accept_int || /* return if spurious interrupt */
+ (!sc_watchdog_error &&
+ (stat2 & SC_S_BSYERR) == 0 && (stat2 & SC_S_PHASE) != 0))
+ {
+# ifdef DEBUG
+ ++sc_spurious_int;
+# endif
+ printf ("sc_spurious_int\n");
+ return ret;
+ }
+ RD_ADR (SC_MODE) &= ~SC_M_DMA; /* clear DMA mode */
+ WR_ADR (SC_ICMD, 0); /* disable data bus */
+ if (sc_cur_phase != PH_NONE) { /* if did DMA, save the new pointer */
+ new_ptr = sc_dma_adr; /* fetch new pointer from DMA cntlr */
+ if (sc_cur_phase == PH_IMSG && /* have message? */
+ new_ptr != sc_ptrs->ptr[PH_IMSG]) sc_have_msg = 1;
+ sc_ptrs->ptr[sc_cur_phase] = /* save pointer */
+ new_ptr;
+ }
+ if (sc_watchdog_error) ret = ISR_TIMEOUT;
+ else if (stat2 & SC_S_BSYERR) { /* target deasserted BSY? */
+ printf ("target deasserted BSY?\n");
+ if (sc_have_msg) ret = ISR_OK;
+ else ret = ISR_BSYERR;
+ } else if (!(stat2 & SC_S_PHASE)) {/* if phase mismatch, setup new phase */
+ printf ("phase mismatch\n");
+ sc_cur_phase = /* get new phase from controller */
+ (RD_ADR (SC_STAT1) >> 2) & 7;
+ new_ptr = sc_ptrs->ptr[sc_cur_phase];
+ if (new_ptr == 0) ret = ISR_BADPHASE;
+ else {
+ WR_ADR (SC_TCMD, sc_cur_phase); /* write new phase into TCMD */
+ if (PH_IN (sc_cur_phase)) { /* set DMA controller */
+ sc_dma_setup (DISK_READ, new_ptr);
+ RD_ADR (SC_MODE) |= SC_M_DMA;
+ CLEAR_INTR();
+ WR_ADR (SC_START_RCV, 0); /* tell SCSI to start DMA */
+ } else {
+ sc_dma_setup (DISK_WRITE, new_ptr);
+ RD_ADR (SC_MODE) |= SC_M_DMA;
+ WR_ADR (SC_ICMD, SC_ENABLE_DB);
+ CLEAR_INTR();
+ WR_ADR (SC_START_SEND, 0);
+ }
+ }
+ } else ret = ISR_RSTERR;
+ if (ret != ISR_NOTDONE) { /* if done, send message to task */
+ sc_watchdog_error = 0;
+ sc_accept_int = 0;
+ WR_ADR (SC_MODE, 0); /* clear monbsy, dma */
+ break; /* reti re-enables ints */
+ }
+ if (0 == ((stat2 = /* check for another interrupt */
+ RD_ADR (SC_STAT2)) & SC_S_IRQ))
+ {
+ break;
+ }
+ }
+ return ret;
+}
+
+/*===========================================================================*
+ * sc_dma_setup *
+ *===========================================================================*/
+/* Fake DMA setup. Just store pointers and direction in global variables.
+ *
+ * The pseudo-DMA is subtler than it looks because of the cache.
+ *
+ * 1) When accessing I/O devices through a cache, some mechanism is
+ * necessary to ensure you access the device rather than the cache.
+ * On the 32532, the IODEC signal is supposed to be asserted for I/O
+ * addresses to accomplish this. However, a bug makes this much
+ * slower than necessary and severely hurts pseudo-DMA performance.
+ * Hence, IODEC is not asserted for the SCSI DMA port.
+ *
+ * 2) Because of (1), we must devise our own method of forcing the
+ * SCSI DMA port to be read. 0x8000000 addresses have been decoded
+ * to all access this port. By always using new addresses to access
+ * the DMA port (wrapping only after reading MAX_CACHE bytes), we
+ * force cache misses and, hence, device reads. Since the cache
+ * is write-through, we do not need to worry about writes.
+ *
+ * 3) It is possible to miss the last few bytes of a transfer if
+ * bus transfer size is not considered. The loop in sc_receive()
+ * transfers data until the interrupt signal is asserted. If
+ * bytes are transferred, the attempt to move the first byte of a
+ * double word causes the whole word to be read into the cache.
+ * Then the byte is transferred. If reading the double word
+ * completed the SCSI transfer, then the loop exits since
+ * interrupt is asserted. However, the last few bytes have only
+ * been moved into the cache -- they have not been moved to the
+ * DMA destination.
+ *
+ * 4) It is also possible to miss the first few bytes of a transfer.
+ * If the address used to access pseudo-dma port is not double word
+ * aligned, the whole double word is read into the cache, and then
+ * data is moved from the middle of the word (i.e. something other
+ * than the first bytes read from the SCSI controller) by the
+ * pseudo-dma loop in sc_receive().
+ */
+sc_dma_setup (dir, adr)
+int dir;
+long adr;
+{
+ BB_DEBUG (("sc_dma_setup(%d, %d)\n", dir, adr));
+
+ CLEAR_INTR();
+ /* if (sc_dma_port > SC_DMA + MAX_CACHE) */
+ sc_dma_port = SC_DMA;
+ sc_dma_dir = dir;
+ sc_dma_adr = adr;
+}
+
+/*===========================================================================*
+ * sc_receive *
+ *===========================================================================*/
+/* Replacement for Minix receive(), which waits for a message. This code
+ * spins, waiting for data to transfer or interrupt requests to handle.
+ * See sc_dma_setup for details.
+ */
+int
+sc_receive()
+{
+ int stat2, isr_ret;
+ int i, c;
+
+ BB_DEBUG (("sc_receive()\n"));
+
+ /*
+ * check the interrupt-flag and wait if it reappears...
+ */
+ c = *ka410_intreq;
+ printf ("begin: %x/%x ", c, *ka410_intreq);
+ for (i=0; i<100; i++) {
+ if ((c = *ka410_intreq) & INTR_SC)
+ break;
+ printf (" %x ", c);
+ }
+ if (i==100)
+ printf ("timeout in sc_receive.\n");
+
+#if 1
+ for (;;) {
+ stat2 = RD_ADR (SC_STAT2);
+ if (stat2 & SC_S_IRQ) {
+ if (ISR_NOTDONE != (isr_ret = scsi_interrupt())) break;
+ } else if (stat2 & SC_S_DRQ) { /* test really not necessary on pc532 */
+ if (sc_dma_dir == DISK_READ)
+ *((long *)sc_dma_adr)++ = *((volatile long *)sc_dma_port)++;
+ else *((volatile long *)sc_dma_port)++ = *((long *)sc_dma_adr)++;
+ }
+ }
+#endif
+ printf ("isr_ret: %d (ISR_NOTDONE: %d)\n", isr_ret, ISR_NOTDONE);
+ return isr_ret;
+}
+
+/*===========================================================================*
+ * scCtlrSelect
+ *===========================================================================*/
+/* Select a SCSI device.
+ */
+scCtlrSelect (ctlr)
+int ctlr;
+{
+ BB_DEBUG (("scCtlrSelect()\n"));
+#if 0
+ RD_ADR (ICU_IO) &= ~ICU_SCSI_BIT; /* i/o, not port */
+ RD_ADR (ICU_DIR) &= ~ICU_SCSI_BIT; /* output */
+ if (ctlr == DP8490)
+ RD_ADR (ICU_DATA) &= ~ICU_SCSI_BIT; /* select = 0 for 8490 */
+ else
+ RD_ADR (ICU_DATA) |= ICU_SCSI_BIT; /* select = 1 for AIC6250 */
+#endif
+}
diff --git a/sys/arch/vax/boot/sd.c b/sys/arch/vax/boot/sd.c
new file mode 100644
index 00000000000..30b08c3ff57
--- /dev/null
+++ b/sys/arch/vax/boot/sd.c
@@ -0,0 +1,247 @@
+/* $NetBSD: sd.c,v 1.1 1996/08/02 11:22:36 ragge Exp $ */
+
+/*
+ * Copyright (c) 1988 University of Utah.
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Van Jacobson of Lawrence Berkeley Laboratory and the Systems
+ * Programming Group of the University of Utah Computer Science Department.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: Utah $Hdr: sd.c 1.9 92/12/21$
+ *
+ * @(#)sd.c 8.1 (Berkeley) 6/10/93
+ */
+
+/*
+ * SCSI CCS disk driver
+ */
+
+#include <sys/param.h>
+#include <sys/disklabel.h>
+#include "stand.h"
+#include "samachdep.h"
+
+#define SC_DEBUG 1 /* bertram */
+#define SD_DEBUG 1 /* bertram */
+
+/*----------------------------------------------------------------------*/
+int
+scsialive(int ctlr)
+{
+ return 1; /* controller always alive! */
+}
+
+/* call functions in scsi_hi.c */
+#include "so.h"
+
+int
+scsi_tt_read(ctlr, slave, buf, len, blk, nblk)
+ int ctlr, slave;
+ u_char *buf;
+ u_int len;
+ daddr_t blk;
+ u_int nblk;
+{
+#ifdef SC_DEBUG
+printf("scsi_tt_read: ctlr %d, slave %d, len %d, blk %d, nblk %d\n",
+ ctlr, slave, len, blk, nblk );
+#endif
+ if (sc_rdwt(DISK_READ, blk, buf, nblk, 1<<slave, 0) == 0)
+ return 0;
+ return -2;
+}
+
+int
+scsi_tt_write(ctlr, slave, buf, len, blk, nblk)
+ int ctlr, slave;
+ u_char *buf;
+ u_int len;
+ daddr_t blk;
+ u_int nblk;
+{
+#ifdef SC_DEBUG
+printf("scsi_tt_write: ctlr %d, slave %d, len %d, blk %d, nblk %d\n",
+ ctlr, slave, len, blk, nblk );
+#endif
+#if 0
+ if (sc_rdwt(DISK_WRITE, blk, buf, nblk, 1<<slave, 0) == 0)
+ return 0;
+#endif
+ return -2;
+}
+
+/*----------------------------------------------------------------------*/
+
+struct sd_softc {
+ int sc_ctlr;
+ int sc_unit;
+ int sc_part;
+ char sc_retry;
+ char sc_alive;
+ struct disklabel sc_label;
+} sd_softc[NSCSI][NSD];
+
+#ifdef SD_DEBUG
+int debug = SD_DEBUG;
+#endif
+
+#define SDRETRY 2
+
+sdinit(ctlr, unit)
+ int ctlr, unit;
+{
+ register struct sd_softc *ss = &sd_softc[ctlr][unit];
+
+ /* HP version does test_unit_ready
+ * followed by read_capacity to get blocksize
+ */
+ ss->sc_alive = 1;
+ return (1);
+}
+
+sdreset(ctlr, unit)
+ int ctlr, unit;
+{
+}
+
+char io_buf[MAXBSIZE];
+
+sdgetinfo(ss)
+ register struct sd_softc *ss;
+{
+ register struct disklabel *lp;
+ char *msg, *getdisklabel();
+ int sdstrategy(), i, err;
+
+ lp = &sd_softc[ss->sc_ctlr][ss->sc_unit].sc_label;
+ bzero((caddr_t)lp, sizeof *lp);
+ lp->d_secsize = DEV_BSIZE;
+ lp->d_secpercyl = 1;
+ lp->d_npartitions = MAXPARTITIONS;
+ lp->d_partitions[ss->sc_part].p_offset = 0;
+ lp->d_partitions[ss->sc_part].p_size = 0x7fffffff;
+
+ if (err = sdstrategy(ss, F_READ,
+ LABELSECTOR, DEV_BSIZE, io_buf, &i) < 0) {
+ printf("sdgetinfo: sdstrategy error %d\n", err);
+ return 0;
+ }
+
+ msg = getdisklabel(io_buf, lp);
+ if (msg) {
+ printf("sd(%d,%d,%d): %s\n",
+ ss->sc_ctlr, ss->sc_unit, ss->sc_part, msg);
+ return 0;
+ }
+ return(1);
+}
+
+sdopen(f, ctlr, unit, part)
+ struct open_file *f;
+ int ctlr, unit, part;
+{
+ register struct sd_softc *ss;
+ register struct disklabel *lp;
+
+#ifdef SD_DEBUG
+ if (debug)
+ printf("sdopen: ctlr=%d unit=%d part=%d\n",
+ ctlr, unit, part);
+#endif
+
+ if (ctlr >= NSCSI || !scsialive(ctlr))
+ return (EADAPT);
+ if (unit >= NSD)
+ return (ECTLR);
+ ss = &sd_softc[ctlr][unit]; /* XXX alloc()? keep pointers? */
+ ss->sc_part = part;
+ ss->sc_unit = unit;
+ ss->sc_ctlr = ctlr;
+ if (!ss->sc_alive) {
+ if (!sdinit(ctlr, unit))
+ return (ENXIO);
+ if (!sdgetinfo(ss))
+ return (ERDLAB);
+ }
+ lp = &sd_softc[ctlr][unit].sc_label;
+ if (part >= lp->d_npartitions || lp->d_partitions[part].p_size == 0)
+ return (EPART);
+
+ f->f_devdata = (void *)ss;
+ return (0);
+}
+
+int
+sdstrategy(ss, func, dblk, size, buf, rsize)
+ register struct sd_softc *ss;
+ int func;
+ daddr_t dblk; /* block number */
+ u_int size; /* request size in bytes */
+ char *buf;
+ u_int *rsize; /* out: bytes transferred */
+{
+ register int ctlr = ss->sc_ctlr;
+ register int unit = ss->sc_unit;
+ register int part = ss->sc_part;
+ register struct partition *pp = &ss->sc_label.d_partitions[part];
+ u_int nblk = size >> DEV_BSHIFT;
+ u_int blk = dblk + pp->p_offset;
+ char stat;
+
+ if (size == 0)
+ return(0);
+
+ ss->sc_retry = 0;
+
+#ifdef SD_DEBUG
+ if (debug)
+ printf("sdstrategy(%d,%d): size=%d blk=%d nblk=%d\n",
+ ctlr, unit, size, blk, nblk);
+#endif
+
+retry:
+ if (func == F_READ)
+ stat = scsi_tt_read(ctlr, unit, buf, size, blk, nblk);
+ else
+ stat = scsi_tt_write(ctlr, unit, buf, size, blk, nblk);
+ if (stat) {
+ printf("sd(%d,%d,%d): block=%x, error=0x%x\n",
+ ctlr, unit, ss->sc_part, blk, stat);
+ if (++ss->sc_retry > SDRETRY)
+ return(EIO);
+ goto retry;
+ }
+ *rsize = size;
+
+ return(0);
+}
diff --git a/sys/arch/vax/boot/so.h b/sys/arch/vax/boot/so.h
new file mode 100644
index 00000000000..3ead2c8e14b
--- /dev/null
+++ b/sys/arch/vax/boot/so.h
@@ -0,0 +1,57 @@
+/* $NetBSD: so.h,v 1.1 1996/08/02 11:22:41 ragge Exp $ */
+
+#ifndef _SO_H_INCLUDE
+#define _SO_H_INCLUDE
+
+/* Definitions for standalone I/O lib */
+
+/* #define SCSI_POLLED 0x200C0080 */
+#define SCSI_DMA 0x200D0000
+
+/* Which SCSI device to use by default */
+#define DEFAULT_SCSI_ADR 1
+#define DEFAULT_SCSI_LUN 0
+
+/* Low level scsi operation codes */
+#define DISK_READ 3
+#define DISK_WRITE 4
+
+/* The size of a disk block */
+#define DBLKSIZE 512
+
+/* Some disk address that will never be used */
+#define INSANE_BADDR 0x800000
+
+struct scsi_args {
+ long ptr [8];
+};
+
+#ifndef NULL
+#define NULL 0L
+#endif
+
+/*
+ * The next macro defines where the "break" area in memory ends for
+ * malloc() and friends. The area between edata and this address will
+ * then be reserved and should not be used for anything else (or you will
+ * no doubt have big problems). Depending on where your program's end-of-data
+ * is, you may wish to locate this in such a way as to usurp a minimum
+ * amount of memory.
+ */
+#define BREAK_END_ADDR ((char *)0x400000) /* to 4MB */
+
+/* Selectivly enable inline functions */
+#ifndef NO_INLINE
+#define Inline inline
+#else
+#define Inline
+#endif
+
+extern void fatal(), warn();
+extern long ulimit(int, long);
+extern int brk(char *);
+extern char *sbrk(int);
+
+extern int sc_rdwt();
+
+#endif /* _SO_H_INCLUDE */
diff --git a/sys/arch/vax/boot/srt0.s b/sys/arch/vax/boot/srt0.s
index 1fc8dfca8e3..bfe5acafe34 100644
--- a/sys/arch/vax/boot/srt0.s
+++ b/sys/arch/vax/boot/srt0.s
@@ -1,4 +1,4 @@
-/* $NetBSD: srt0.s,v 1.5 1996/03/07 23:27:10 ragge Exp $ */
+/* $NetBSD: srt0.s,v 1.6 1996/08/02 11:22:44 ragge Exp $ */
/*
* Copyright (c) 1994 Ludd, University of Lule}, Sweden.
* All rights reserved.
@@ -58,7 +58,9 @@ _start: .globl _start
1: movl $relocated, (sp) # return-address on top of stack
rsb # can be replaced with new address
relocated: # now relocation is done !!!
- calls $0,_main # Were here!
+ movl sp, _bootregs
+ calls $0, _setup
+ calls $0, _Xmain # Were here!
halt # no return
diff --git a/sys/arch/vax/boot/start.s b/sys/arch/vax/boot/start.s
index 55b2fc0438a..51edf004a88 100644
--- a/sys/arch/vax/boot/start.s
+++ b/sys/arch/vax/boot/start.s
@@ -1,4 +1,4 @@
-/* $NetBSD: start.s,v 1.7 1996/02/02 19:08:33 mycroft Exp $ */
+/* $NetBSD: start.s,v 1.8 1996/08/02 11:22:47 ragge Exp $ */
/*
* Copyright (c) 1995 Ludd, University of Lule}, Sweden.
* All rights reserved.
@@ -172,7 +172,8 @@ start_all:
relocated: # now relocation is done !!!
movl sp, _bootregs
movl ap, _boothowto
- calls $0, _main # call main() which is
+ calls $0, _setup
+ calls $0, _Xmain # call Xmain (gcc workaround)which is
halt # not intended to return ...
/*
diff --git a/sys/arch/vax/boot/str.s b/sys/arch/vax/boot/str.s
new file mode 100644
index 00000000000..685574e0371
--- /dev/null
+++ b/sys/arch/vax/boot/str.s
@@ -0,0 +1,70 @@
+/* $NetBSD: str.s,v 1.2 1996/08/02 16:18:40 ragge Exp $ */
+/*
+ * Copyright (c) 1996 Ludd, University of Lule}, Sweden.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed at Ludd, University of
+ * Lule}, Sweden and its contributors.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Small versions of the most common string functions not using any
+ * emulated instructions.
+ */
+
+#include "../include/asm.h"
+
+ENTRY(strlen, 0);
+ movl 4(ap), r0
+1: tstb (r0)+
+ bneq 1b
+ decl r0
+ subl2 4(ap), r0
+ ret
+
+ENTRY(strncmp, 0)
+ movl 12(ap), r3
+ brb 5f
+
+ENTRY(strcmp, 0)
+ movl $250, r3 # max string len to compare
+5: movl 4(ap), r2
+ movl 8(ap), r1
+ movl $1, r0
+
+2: cmpb (r2),(r1)+
+ bneq 1f # something differ
+ tstb (r2)+
+ beql 4f # continue, strings unequal
+ decl r3 # max string len encountered?
+ bneq 2b
+
+4: clrl r0 # We are done, strings equal.
+ ret
+
+1: bgtr 3f
+ mnegl r0, r0
+3: ret
diff --git a/sys/arch/vax/boot/tmscp.c b/sys/arch/vax/boot/tmscp.c
index f5d0fe11879..b63022212f7 100644
--- a/sys/arch/vax/boot/tmscp.c
+++ b/sys/arch/vax/boot/tmscp.c
@@ -1,4 +1,4 @@
-/* $NetBSD: tmscp.c,v 1.2 1996/02/17 18:23:24 ragge Exp $ */
+/* $NetBSD: tmscp.c,v 1.3 1996/08/02 11:22:53 ragge Exp $ */
/*
* Copyright (c) 1995 Ludd, University of Lule}, Sweden.
* All rights reserved.
@@ -43,7 +43,8 @@
#include "../include/macros.h"
#include "../uba/ubareg.h"
#include "../uba/udareg.h"
-#include "../vax/mscp.h"
+#include "../mscp/mscp.h"
+#include "../mscp/mscpreg.h"
#include "vaxstand.h"
@@ -63,7 +64,7 @@ struct ra_softc {
};
static volatile struct uda {
- struct uda1ca uda_ca; /* communications area */
+ struct mscp_1ca uda_ca; /* communications area */
struct mscp uda_rsp; /* response packets */
struct mscp uda_cmd; /* command packets */
} uda;
@@ -100,14 +101,14 @@ tmscpopen(f, adapt, ctlr, unit, part)
* Init of this tmscp ctlr.
*/
udacsr->udaip=0; /* Start init */
- while((udacsr->udasa&UDA_STEP1) == 0);
+ while((udacsr->udasa&MP_STEP1) == 0);
udacsr->udasa=0x8000;
- while((udacsr->udasa&UDA_STEP2) == 0);
+ while((udacsr->udasa&MP_STEP2) == 0);
johan=(((u_int)ubauda)&0xffff)+8;
udacsr->udasa=johan;
- while((udacsr->udasa&UDA_STEP3) == 0);
+ while((udacsr->udasa&MP_STEP3) == 0);
udacsr->udasa=3;
- while((udacsr->udasa&UDA_STEP4) == 0);
+ while((udacsr->udasa&MP_STEP4) == 0);
udacsr->udasa=0x0001;
uda.uda_ca.ca_rspdsc=(int)&ubauda->uda_rsp.mscp_cmdref;
diff --git a/sys/arch/vax/boot/vaxstand.h b/sys/arch/vax/boot/vaxstand.h
index f3217fdb235..2d068b9d6d9 100644
--- a/sys/arch/vax/boot/vaxstand.h
+++ b/sys/arch/vax/boot/vaxstand.h
@@ -1,4 +1,4 @@
-/* $NetBSD: vaxstand.h,v 1.4 1996/02/17 18:23:25 ragge Exp $ */
+/* $NetBSD: vaxstand.h,v 1.5 1996/08/02 11:22:56 ragge Exp $ */
/*
* Copyright (c) 1994 Ludd, University of Lule}, Sweden.
* All rights reserved.
@@ -34,13 +34,12 @@
#define MAXNMBA 8 /* Massbussadapters */
#define MAXNUBA 8 /* Unibusadapters */
-#define MAXNBI 4 /* Bi-bussadapters */
#define MAXMBAU 8 /* Units on an mba */
-#define MAXBIN 16 /* Bi-nodes */
/* Variables used in autoconf */
extern int nmba, nuba, nbi, nsbi, nuda;
-extern int *ubaaddr, *mbaaddr, *udaaddr, *uioaddr;
+extern int *ubaaddr, *mbaaddr, *udaaddr, *uioaddr, *biaddr;
+extern int cpunumber;
/* devsw type definitions, used in bootxx and conf */
#define SADEV(name,strategy,open,close,ioctl) \
@@ -50,3 +49,17 @@ extern int *ubaaddr, *mbaaddr, *udaaddr, *uioaddr;
(int(*)(struct open_file *))close, \
(int(*)(struct open_file *,u_long, void *))ioctl}
+/*
+ * Easy-to-use definitions
+ */
+#define min(x,y) (x < y ? x : y)
+
+/*
+ * Device numbers gotten from boot prom.
+ */
+#define BDEV_MBA 0
+#define BDEV_RK06 1
+#define BDEV_RL02 2
+#define BDEV_UDA 17
+#define BDEV_TK50 18
+#define BDEV_CONSOLE 64