diff options
author | Mats O Jansson <maja@cvs.openbsd.org> | 1997-01-15 23:25:34 +0000 |
---|---|---|
committer | Mats O Jansson <maja@cvs.openbsd.org> | 1997-01-15 23:25:34 +0000 |
commit | bf6413046b73005ecca3f5352c8711d00a6d00b9 (patch) | |
tree | fcd2c64f80b1be68d962f84a1e34da0a02d5385f /sys/arch/vax/boot | |
parent | 957078809571dbe61aac81705145fa4cee6bfda8 (diff) |
sync with NetBSD 970112 -moj
Diffstat (limited to 'sys/arch/vax/boot')
-rw-r--r-- | sys/arch/vax/boot/Makefile | 52 | ||||
-rw-r--r-- | sys/arch/vax/boot/autoconf.c | 20 | ||||
-rw-r--r-- | sys/arch/vax/boot/boot.c | 12 | ||||
-rw-r--r-- | sys/arch/vax/boot/bootxx.c | 121 | ||||
-rw-r--r-- | sys/arch/vax/boot/conf.c | 36 | ||||
-rw-r--r-- | sys/arch/vax/boot/consio.c | 169 | ||||
-rw-r--r-- | sys/arch/vax/boot/copy.c | 6 | ||||
-rw-r--r-- | sys/arch/vax/boot/devopen.c | 52 | ||||
-rw-r--r-- | sys/arch/vax/boot/edlabel.c | 8 | ||||
-rw-r--r-- | sys/arch/vax/boot/init.c | 82 | ||||
-rw-r--r-- | sys/arch/vax/boot/ka410.h | 82 | ||||
-rw-r--r-- | sys/arch/vax/boot/mfm.c | 640 | ||||
-rw-r--r-- | sys/arch/vax/boot/ra.c | 147 | ||||
-rw-r--r-- | sys/arch/vax/boot/rom.c | 123 | ||||
-rw-r--r-- | sys/arch/vax/boot/romread.s | 38 | ||||
-rw-r--r-- | sys/arch/vax/boot/samachdep.h | 42 | ||||
-rw-r--r-- | sys/arch/vax/boot/scsi_hi.c | 297 | ||||
-rw-r--r-- | sys/arch/vax/boot/scsi_low.c | 479 | ||||
-rw-r--r-- | sys/arch/vax/boot/sd.c | 247 | ||||
-rw-r--r-- | sys/arch/vax/boot/so.h | 57 | ||||
-rw-r--r-- | sys/arch/vax/boot/srt0.s | 6 | ||||
-rw-r--r-- | sys/arch/vax/boot/start.s | 5 | ||||
-rw-r--r-- | sys/arch/vax/boot/str.s | 70 | ||||
-rw-r--r-- | sys/arch/vax/boot/tmscp.c | 15 | ||||
-rw-r--r-- | sys/arch/vax/boot/vaxstand.h | 21 |
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 |