summaryrefslogtreecommitdiff
path: root/sys/arch/vax
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/vax')
-rw-r--r--sys/arch/vax/BUGS_MISSINGS10
-rw-r--r--sys/arch/vax/INSTALL145
-rw-r--r--sys/arch/vax/README50
-rw-r--r--sys/arch/vax/README.copy80
-rw-r--r--sys/arch/vax/README.edlabel137
-rw-r--r--sys/arch/vax/boot/Makefile103
-rw-r--r--sys/arch/vax/boot/autoconf.c92
-rw-r--r--sys/arch/vax/boot/boot.c249
-rw-r--r--sys/arch/vax/boot/bootxx.c399
-rw-r--r--sys/arch/vax/boot/conf.c72
-rw-r--r--sys/arch/vax/boot/consio.c61
-rw-r--r--sys/arch/vax/boot/copy.c243
-rw-r--r--sys/arch/vax/boot/data.h74
-rw-r--r--sys/arch/vax/boot/devopen.c212
-rw-r--r--sys/arch/vax/boot/edlabel.c222
-rw-r--r--sys/arch/vax/boot/hp.c165
-rw-r--r--sys/arch/vax/boot/init.c82
-rw-r--r--sys/arch/vax/boot/ra.c186
-rw-r--r--sys/arch/vax/boot/romread.s89
-rw-r--r--sys/arch/vax/boot/srt0.s70
-rw-r--r--sys/arch/vax/boot/start.s188
-rw-r--r--sys/arch/vax/boot/tmscp.c202
-rw-r--r--sys/arch/vax/boot/vaxstand.h52
-rw-r--r--sys/arch/vax/compile/.keep_me3
-rw-r--r--sys/arch/vax/conf/EVERYTHING92
-rw-r--r--sys/arch/vax/conf/GENERIC103
-rw-r--r--sys/arch/vax/conf/Makefile.vax125
-rw-r--r--sys/arch/vax/conf/files.vax252
-rw-r--r--sys/arch/vax/conf/mkoldconf.awk155
-rw-r--r--sys/arch/vax/conf/std.vax10
-rw-r--r--sys/arch/vax/if/if_de.c723
-rw-r--r--sys/arch/vax/if/if_dereg.h220
-rw-r--r--sys/arch/vax/if/if_qe.c975
-rw-r--r--sys/arch/vax/if/if_qereg.h172
-rw-r--r--sys/arch/vax/if/if_uba.c390
-rw-r--r--sys/arch/vax/if/if_uba.h136
-rw-r--r--sys/arch/vax/include/ansi.h60
-rw-r--r--sys/arch/vax/include/asm.h76
-rw-r--r--sys/arch/vax/include/cdefs.h35
-rw-r--r--sys/arch/vax/include/cpu.h88
-rw-r--r--sys/arch/vax/include/db_machdep.h73
-rw-r--r--sys/arch/vax/include/disklabel.h47
-rw-r--r--sys/arch/vax/include/endian.h112
-rw-r--r--sys/arch/vax/include/exec.h49
-rw-r--r--sys/arch/vax/include/float.h69
-rw-r--r--sys/arch/vax/include/ioa.h36
-rw-r--r--sys/arch/vax/include/ka750.h41
-rw-r--r--sys/arch/vax/include/kg.h36
-rw-r--r--sys/arch/vax/include/limits.h85
-rw-r--r--sys/arch/vax/include/loconf.h57
-rw-r--r--sys/arch/vax/include/macros.h220
-rw-r--r--sys/arch/vax/include/mtpr.h129
-rw-r--r--sys/arch/vax/include/nexus.h179
-rw-r--r--sys/arch/vax/include/param.h195
-rw-r--r--sys/arch/vax/include/pcb.h72
-rw-r--r--sys/arch/vax/include/pmap.h107
-rw-r--r--sys/arch/vax/include/proc.h49
-rw-r--r--sys/arch/vax/include/profile.h49
-rw-r--r--sys/arch/vax/include/psl.h113
-rw-r--r--sys/arch/vax/include/pte.h95
-rw-r--r--sys/arch/vax/include/ptrace.h39
-rw-r--r--sys/arch/vax/include/reg.h55
-rw-r--r--sys/arch/vax/include/rpb.h100
-rw-r--r--sys/arch/vax/include/scb.h39
-rw-r--r--sys/arch/vax/include/setjmp.h7
-rw-r--r--sys/arch/vax/include/sid.h63
-rw-r--r--sys/arch/vax/include/signal.h64
-rw-r--r--sys/arch/vax/include/stdarg.h62
-rw-r--r--sys/arch/vax/include/trap.h109
-rw-r--r--sys/arch/vax/include/types.h77
-rw-r--r--sys/arch/vax/include/uvaxII.h125
-rw-r--r--sys/arch/vax/include/varargs.h61
-rw-r--r--sys/arch/vax/include/vmparam.h188
-rw-r--r--sys/arch/vax/mba/hp.c366
-rw-r--r--sys/arch/vax/mba/hpdefs.h81
-rw-r--r--sys/arch/vax/mba/hpreg.h86
-rw-r--r--sys/arch/vax/mba/mba.c99
-rw-r--r--sys/arch/vax/mba/mbareg.h80
-rw-r--r--sys/arch/vax/mba/mbavar.h94
-rw-r--r--sys/arch/vax/stand/Makefile103
-rw-r--r--sys/arch/vax/stand/autoconf.c92
-rw-r--r--sys/arch/vax/stand/boot.c249
-rw-r--r--sys/arch/vax/stand/bootxx.c399
-rw-r--r--sys/arch/vax/stand/conf.c72
-rw-r--r--sys/arch/vax/stand/consio.c61
-rw-r--r--sys/arch/vax/stand/copy.c243
-rw-r--r--sys/arch/vax/stand/data.h74
-rw-r--r--sys/arch/vax/stand/devopen.c212
-rw-r--r--sys/arch/vax/stand/edlabel.c222
-rw-r--r--sys/arch/vax/stand/hp.c165
-rw-r--r--sys/arch/vax/stand/init.c82
-rw-r--r--sys/arch/vax/stand/ra.c186
-rw-r--r--sys/arch/vax/stand/romread.s89
-rw-r--r--sys/arch/vax/stand/srt0.s70
-rw-r--r--sys/arch/vax/stand/start.s188
-rw-r--r--sys/arch/vax/stand/tmscp.c202
-rw-r--r--sys/arch/vax/stand/vaxstand.h52
-rw-r--r--sys/arch/vax/uba/tmscp.c2136
-rw-r--r--sys/arch/vax/uba/tmscpreg.h120
-rw-r--r--sys/arch/vax/uba/uba.c1294
-rw-r--r--sys/arch/vax/uba/ubareg.h327
-rw-r--r--sys/arch/vax/uba/ubavar.h266
-rw-r--r--sys/arch/vax/uba/ubavec.s112
-rw-r--r--sys/arch/vax/uba/uda.c2424
-rw-r--r--sys/arch/vax/uba/udareg.h107
-rw-r--r--sys/arch/vax/vax/autoconf.c339
-rw-r--r--sys/arch/vax/vax/clock.c210
-rw-r--r--sys/arch/vax/vax/conf.c469
-rw-r--r--sys/arch/vax/vax/db_disasm.c347
-rw-r--r--sys/arch/vax/vax/db_machdep.c216
-rw-r--r--sys/arch/vax/vax/disksubr.c293
-rw-r--r--sys/arch/vax/vax/emulate.s1297
-rw-r--r--sys/arch/vax/vax/gencons.c292
-rw-r--r--sys/arch/vax/vax/gencons.h55
-rw-r--r--sys/arch/vax/vax/intvec.s398
-rw-r--r--sys/arch/vax/vax/ka750.c236
-rw-r--r--sys/arch/vax/vax/locore.c149
-rw-r--r--sys/arch/vax/vax/machdep.c715
-rw-r--r--sys/arch/vax/vax/mem.c191
-rw-r--r--sys/arch/vax/vax/mscp.c962
-rw-r--r--sys/arch/vax/vax/mscp.h472
-rw-r--r--sys/arch/vax/vax/mscpvar.h219
-rw-r--r--sys/arch/vax/vax/pmap.c916
-rw-r--r--sys/arch/vax/vax/random.s83
-rw-r--r--sys/arch/vax/vax/rootfil.c229
-rw-r--r--sys/arch/vax/vax/sbi.c178
-rw-r--r--sys/arch/vax/vax/subr.s279
-rw-r--r--sys/arch/vax/vax/swapgeneric.c212
-rw-r--r--sys/arch/vax/vax/tmscpinf.h321
-rw-r--r--sys/arch/vax/vax/trap.c468
-rw-r--r--sys/arch/vax/vax/udiv.s71
-rw-r--r--sys/arch/vax/vax/urem.s69
-rw-r--r--sys/arch/vax/vax/uvaxII.c262
-rw-r--r--sys/arch/vax/vax/vm_machdep.c521
134 files changed, 30422 insertions, 0 deletions
diff --git a/sys/arch/vax/BUGS_MISSINGS b/sys/arch/vax/BUGS_MISSINGS
new file mode 100644
index 00000000000..cc39325f8bd
--- /dev/null
+++ b/sys/arch/vax/BUGS_MISSINGS
@@ -0,0 +1,10 @@
+Programs may be hanging with the D flag set, even if they (HIGH)
+don't do I/O at all. (ps, ...) User PTE problem?
+950304/Ragge
+
+Uba & devices should be converted to use new style config (MEDIUM)
+instead of emulating it. MSCP routines should also be
+fixed so that they can support both uda and kdb disks
+as device ra?.
+/Ragge
+
diff --git a/sys/arch/vax/INSTALL b/sys/arch/vax/INSTALL
new file mode 100644
index 00000000000..635034c26d6
--- /dev/null
+++ b/sys/arch/vax/INSTALL
@@ -0,0 +1,145 @@
+ $NetBSD: INSTALL,v 1.1 1995/09/16 12:00:21 ragge Exp $
+
+
+How to install NetBSD/vax
+-------------------------
+
+1. Device conventions.
+ NetBSD standalone system addresses devices like
+ 'devicename(adapter, controller, unit, partition)'
+ Known devicenames are:
+ tms - TMSCP tape.
+ ts - TSV05/TS11 tape.
+ ra - RA??/RD?? disks/floppies.
+ hp - RP??/RM?? disks.
+
+ You can omit parameters; ra(0,0) refers to disk 0 partition a
+ on default controller. On tapes partition refers to file #
+ on the tape.
+
+ Example: DUB1 (DEC syntax) swap partition will be referred as
+ ra(1,0,1), DRA2 root partition is hp(2,0).
+
+
+
+2. Installation.
+ This document only covers installation of a miniroot
+ filesystem on the swap partition of a disk. Installation
+ of the remaining system is best done over network or
+ from tape, but this is your own decision.
+ The installation principle is to label the root disk,
+ copy a miniroot filesystem onto the swap partition,
+ boot up from that miniroot filesystem, then create
+ root and the other wanted partitions and put system
+ to it.
+ You will have to deal with 2 files, one is just a boot
+ filesystem containing 3 files: boot, copy and edlabel,
+ the other is an image of a miniroot filesystem and can
+ be split into several pieces depending of what you are
+ going to install from.
+
+
+
+2.1 INSTALLATION
+
+2.1.1 Installation from TK50. (MicroVAX II)
+ You will need a file called tk50-file1-???.fs and a
+ file called tk50-file2-???.fs, where ??? is the
+ revision og NetBSD. These files must be written on tape
+ in sequential order; file 1 first and then file2.
+ _Blocksize_must_be_512!_ Otherwise the tape will not be
+ bootable. Then type:
+
+ >>> B/3 MUA0
+
+ This means that you will bring upp boot for asking
+ from TK50. (MUA0 is DEC naming). It will come up
+ something like
+
+ 2..1..0..
+
+
+ howto 0x3, bdev 0x12, booting...
+ 9852+456+34916 start 0x0
+
+ Nboot
+ :
+
+
+ At the prompt you type edlabel to label the disk, see
+ README.edlabel about how to use it.
+ When labeling is finished, halt the computer, bring up
+ the Nboot prompt again and this time load copy, see
+ README.copy about how to use it. Remember that you are
+ copying from file 1 on the tape.
+
+ Now go to step 3.
+
+
+2.2 Installation from RX33/RX50. (MicroVAX II)
+ The difference between RX33 and RX50 is its size. RX50
+ is 400k and RX33 is 1200k.
+ You will need a file called rxDD-bootdisk-???.fs and
+ a couple of files called rxDD-copy?-???.fs, where DD
+ is 33 or 50 and ??? is the revision of NetBSD.
+ The RX33 installation will be 3 floppies and RX50
+ installation will be 7 floppies.
+
+ To boot from floppy type:
+
+ >>> B/3 DUxy
+
+ where x is the controller number and y is device number.
+ You will now get up a prompt like
+
+ Nboot
+ :
+
+ At the prompt you type edlabel to label the disk, see
+ README.edlabel about how to use it.
+ When labeling is finished, halt the computer, bring up
+ the Nboot prompt again and this time load copy, see
+ README.copy about how to use it. Remember that you are
+ copying from partition 0 when using floppies.
+
+ Now go to step 3.
+
+
+2.3 Installation from TU58. (VAX 11/750).
+
+ Not yet :-( But will be...
+
+
+3. Booting up miniroot.
+ When copying is ready, bring the boot program up a third
+ time, and this time bring up a real system by telling
+ boot where you put your miniroot _and_ also the generic
+ kernel name. Example: ra(0,1)gennetbsd, boots gennetbsd
+ from swap partition on ra0.
+
+ When kernel is loaded, you will after a while get a
+ question about Root device?. Respond to this with
+ xx?*, where xx is the device name, ? is the unit
+ number and * tells that the system shall use the swap
+ partition as root partition. Example:
+
+ Root device? ra0*
+
+ After that a second question:
+
+ Enter pathname of shell or RETURN for sh:
+
+ Just type return. Now you will be in a normal single-user
+ shell, and it's just to newfs your partitions, and start
+ installation.
+
+ A few things that you must remember to do from miniroot:
+ disklabel -B <diskname> to install boot blocks.
+ MAKEDEV devices in the newly created root filesystem.
+ Copy gennetbsd and boot from miniroot filesystem
+ to the newly created root filesystem.
+
+
+ Good luck! (You may need it)
+ Ragge
+
diff --git a/sys/arch/vax/README b/sys/arch/vax/README
new file mode 100644
index 00000000000..1dc4199312c
--- /dev/null
+++ b/sys/arch/vax/README
@@ -0,0 +1,50 @@
+ $NetBSD: README,v 1.9 1995/09/16 12:00:21 ragge Exp $
+
+Devices supported in kernel and _known_ to work:
+CPU: VAX 11/750 with 2-14MB of memory.
+ KA630 (MicroVAX II) with 2-16 MB memory.
+
+Net: DEUNA/DELUA Unibus ethernet cards.
+ DEQNA/DELQA Q22 bus ethernet cards.
+
+Disks: UDA50 Unibus MSCP controller.
+ KDA50/RQDX3 Q22 bus MSCP controller.
+ RA??-disks on UDA50 or KDA50.
+ RD??-disks on RQDX3. (known as RA?? by system).
+
+Tapes: DILOG Q22 bus tape ctlr w/ Exabyte. (TMSCP emulating)
+ TSV05 Q22 bus tape ctlr.
+ TK50 (TMSCP) on Q22 bus.
+ Other TMSCP ctlrs may also work, but haven't tried.
+
+
+To install and run NetBSD/vax you need a MicroVAX II or VAX 11/750
+with at least 4MB of memory, and a usable install media. Supported
+install media is TK50 tape and RX33/RX50 floppy. If you do initial
+installation from floppy then you need a way to load the rest of
+the system, like tape or ethernet.
+NOTE! TU58 INSTALLATION IS NOT YET SUPPORTED, BUT WILL BE.
+
+Actually, the system will run fine on only 2MB of memory, but
+installation program needs 4MB. If this causes trouble for someone
+tell me and I'll fix it.
+
+Differences between the NetBSD/vax port and other ports:
+ * It uses gcc 2.7.0 as default compiler.
+ * libm is not the same as the other ports; instead it is 4.4BSD libm.
+ * No dynamic linked libraries, all binaries is statically linked.
+These things will be fixed in the future.
+
+
+We who have done parts of the VAX port is:
+ Joachim Isaksson, first pmap and lots of help with gcc functionality.
+ Mattias Gr|nlund, locore assembler and interrupt handling.
+ Mattias ]slund, lots of help and ideas everywhere.
+ Bertram Barth, bootblocks and boot routines for MicroVAX.
+ Rick Macklem, fixed all MicroVAX II, TMSCP and DEQNA support.
+ Anders Magnusson (ragge), that's me, who put things together
+ and wrote the rest.
+
+Have fun with it,
+ ragge@ludd.luth.se
+
diff --git a/sys/arch/vax/README.copy b/sys/arch/vax/README.copy
new file mode 100644
index 00000000000..610ea12e6ea
--- /dev/null
+++ b/sys/arch/vax/README.copy
@@ -0,0 +1,80 @@
+ $NetBSD: README.copy,v 1.2 1995/09/29 16:33:38 ragge Exp $
+
+ How to use copy
+ ------------------
+
+
+Edlabel is a standalone program that can copy multiple volumes
+from disk/tape to disk/tape. Mostly it is used to copy the
+miniroot filesystem onto the swap partition during initial
+installation.
+You will here be guided through a session, things with ^^^^ under
+is typed in by the user, comments are within /* */.
+This is an installation from TK50.
+
+
+Nboot
+: copy
+ ^^^^
+10480+468+34868 start 0x0
+
+copy:
+This program will read miniroot from tape/floppy/disk
+and install this miniroot onto disk.
+
+Specify the device to read from as xx(N,0), where
+xx is the device-name and N is the unit-number, e.g.
+"tms(0,1)" for the first TMSCP-tape (TK50),
+"ra(2,0)" for the third MSCP-disk/floppy (RX33/RX50)
+
+device to read from ? tms(0,1) /* Tape 0, file 1 */
+ ^^^^^^^^
+Specify number of blocks to transfer. Usually this is
+sizeof(miniroot) / 512.
+It's safe to transfer more blocks than just the miniroot.
+
+number of blocks ? 4096 /* Miniroot size is 4096 block */
+ ^^^^
+If your miniroot is split into volumes, then you must
+specify the number of blocks per volume.
+(e.g. 800 blocks per RX50, 2400 blocks per RX33)
+
+number of blocks per volume ? [4096]
+
+Make sure unit tms(0,1) is online and holds the proper volume.
+Then type 'g' to Go or 'a' to Abort.
+
+OK to go on ? [g/a] g /* g == go, a == abort */
+ ^
+Reading ... Reading of miniroot done. (4096 blocks read)
+
+
+Now specify the device to write miniroot to as xx(N,1)
+where xx is the drive type and N is the drive number.
+For example: ra(0,1) refers to MSCP drive #0, b partition
+
+Root disk ? : ra(0,1) /* Actually DUA0, partition b (swap) */
+ ^^^^^^^^^
+Initializing partition ... done.
+(4096 blocks written.)
+
+Halt the machine and reboot from distribution media,
+giving second partition as part to mount as root. Ex:
+: ra(0,1) for ra disk 0, hp(2,1) for massbuss disk 2
+
+Halt/Reboot the machine NOW.
+?02 EXT HLT
+ PC = 001005F3
+>>>
+
+
+
+
+-- Ragge
+
+
+
+
+
+
+
diff --git a/sys/arch/vax/README.edlabel b/sys/arch/vax/README.edlabel
new file mode 100644
index 00000000000..1a6c3d92746
--- /dev/null
+++ b/sys/arch/vax/README.edlabel
@@ -0,0 +1,137 @@
+ $NetBSD: README.edlabel,v 1.1 1995/09/16 12:00:19 ragge Exp $
+
+
+ How to use edlabel
+ ------------------
+
+
+Edlabel is a program to edit disklabels on any disks in a standalone
+environment. Mostly it is used to set labels when doing initial
+installation procedure. It is started from boot program prompt.
+You will here be guided through a session, things with ^^^^ under
+is typed in by the user, comments are within /* */.
+
+Nboot
+: edlabel
+ ^^^^^^^
+11700+576+43200 start 0x0
+With this program you can modify everything in the on-disk
+disklabel. To do something useful you must know the exact
+geometry of your disk, and have ideas about how you want
+your partitions to be placed on disk. Some hints:
+The a partition should be at least ~20000 blocks, the
+b (swap) is depending on your use of the machine but it
+should almost never be less than ~32000 blocks.
+
+Disk geometry for most DEC disks can be found in the disktab
+file, and disknames is listed in the installation notes.
+
+Remember that disk names is given as disk(adapt, ctrl, disk, part)
+when using the installation tools.
+
+Label which disk? ra(1,0,0) /* See INSTALL text for device types */
+ ^^^^^^^^^
+getdisklabel: no disk label
+ra(1,0,0): no disk label
+(E)dit, (S)how, (D)efaults, (W)rite, (Q)uit) : e
+ ^
+First set disk type. Valid types are:
+0 unknown
+1 SMD
+2 MSCP
+3 old DEC
+4 SCSI
+5 ESDI
+6 ST506
+7 HP-IB
+8 HP-FL
+9 type 9
+10 floppy
+11 ccd
+12 vnd
+
+Numeric disk type? [0] 2 /* All disks supported this far is MSCP */
+Disk name? [] rd54 ^ /* You must know what type your disk is */
+badsect? [n] ^^^^ /* No badsectoring yet */
+ecc? [n] /* ECC is automatic, don't care */
+removable? [n] /* Removable or not, like RA60 */
+Interleave? [0] 1 /* All MSCP disks is seen like 1 interleave */
+rpm? [0] 3600 ^ /* 3600 rpm is normal */
+trackskew? [0] /* don't care */
+cylinderskew? [0] /* don't care */
+headswitch? [0] /* don't care */
+track-to-track? [0] /* don't care */
+drivedata 0? [0] /* don't care */
+drivedata 1? [0] /* don't care */
+drivedata 2? [0] /* don't care */
+drivedata 3? [0] /* don't care */
+drivedata 4? [0] /* don't care */
+
+bytes/sector? [0] 512 /* Probably only sive on VAX systems */
+ ^^^
+sectors/track? [0] 17 /* You must know this, check disktab file */
+ ^^
+tracks/cylinder? [0] 15 /* You must know this, check disktab file */
+ ^^
+sectors/cylinder? [0] 255 /* sectors/track * tracks/cylinder */
+ ^^^
+cylinders? [0] 1221 /* You must know this, check disktab file */
+ ^^^^
+a partition: offset? [0] /* Partition sizes are set by you. */
+ size? [0] 20000 /* Take default sizes from disktab or */
+b partition: offset? [0] 20000 /* calculate your own partition sizes */
+ size? [0] 20000
+c partition: offset? [0]
+ size? [0] 311200
+d partition: offset? [0]
+ size? [0]
+e partition: offset? [0] 40000
+ size? [0] 271200
+f partition: offset? [0]
+ size? [0]
+g partition: offset? [0]
+ size? [0]
+h partition: offset? [0]
+ size? [0]
+
+(E)dit, (S)how, (D)efaults, (W)rite, (Q)uit) : s /* Show what you've typed */
+ ^
+
+disk type 2 (MSCP), rd54:
+interleave 1, rpm 3600, trackskew 0, cylinderskew 0
+headswitch 0, track-to-track 0, drivedata: 0 0 0 0 0
+
+bytes/sector: 512
+sectors/track: 17
+tracks/cylinder: 15
+sectors/cylinder: 255
+cylinders: 1221
+
+8 partitions:
+ size offset
+a: 20000, 0
+b: 20000, 20000
+c: 311200, 0
+d: 0, 0
+e: 271200, 40000
+f: 0, 0
+g: 0, 0
+h: 0, 0
+
+(E)dit, (S)how, (D)efaults, (W)rite, (Q)uit) : w /* Write label to disk */
+
+This program does not (yet) write bootblocks, only disklabel.
+Remember to write the bootblocks from the miniroot later with the
+command "disklabel -B <diskname>".
+(E)dit, (S)how, (D)efaults, (W)rite, (Q)uit) : q
+
+
+
+-- Ragge
+
+
+
+
+
+
+
diff --git a/sys/arch/vax/boot/Makefile b/sys/arch/vax/boot/Makefile
new file mode 100644
index 00000000000..b54fa987f1f
--- /dev/null
+++ b/sys/arch/vax/boot/Makefile
@@ -0,0 +1,103 @@
+# $NetBSD: Makefile,v 1.4 1995/09/16 13:18:27 ragge Exp $
+#
+
+INCPATH=-I. -I../../.. -I../.. -I../../../lib/libsa
+
+CC= cc
+AS= as
+
+S= ../../..
+RELOC= 100000
+CFLAGS+=-O ${INCPATH} -DSTANDALONE -DRELOC=0x${RELOC} -D_VAX_INLINE_
+
+DEVS= autoconf.o hp.o ra.o tmscp.o
+
+.include "$S/lib/libkern/Makefile.inc"
+LIBKERN= ${KERNLIB}
+
+.include "$S/lib/libsa/Makefile.inc"
+LIBSA= ${SA_LIB}
+
+all: xxboot boot copy edlabel
+
+libsvax.a: consio.o urem.o udiv.o
+ ar crv $@ $?
+ ranlib $@
+
+urem.o: ../vax/urem.s
+ ${CC} -x assembler-with-cpp -E ../vax/urem.s | as -o urem.o
+
+udiv.o: ../vax/udiv.s
+ ${CC} -x assembler-with-cpp -E ../vax/udiv.s | as -o udiv.o
+
+# startups
+
+start.o: start.s
+ ${CC} -x assembler-with-cpp -E start.s | as -o start.o
+
+srt0.o: srt0.s
+ ${CC} -x assembler-with-cpp -E srt0.s | as -o srt0.o
+
+#
+
+xxboot: start.o bootxx.o romread.o ${LIBSA} ${LIBKERN} libsvax.a
+ ld -N -Ttext ${RELOC} -o a.out start.o bootxx.o romread.o \
+ ${LIBSA} ${LIBKERN} 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
+ ld -N -Ttext ${RELOC} -e nisse -o $@ srt0.o devopen.o boot.o \
+ conf.o ${DEVS} ${LIBSA} ${LIBKERN} libsvax.a
+ @strip boot
+ @size boot
+
+edlabel: edlabel.o srt0.o devopen.o conf.o ${DEVS} ${LIBKERN} ${LIBSA} libsvax.a
+ ld -N -Ttext ${RELOC} -e nisse -o $@ srt0.o devopen.o edlabel.o\
+ conf.o ${DEVS} ${LIBSA} ${LIBKERN} libsvax.a
+ @strip edlabel
+ @size edlabel
+
+copy: copy.o srt0.o devopen.o conf.o ${DEVS} ${LIBKERN} ${LIBSA} libsvax.a
+ ld -N -Ttext ${RELOC} -e nisse -o $@ srt0.o devopen.o copy.o \
+ conf.o ${DEVS} ${LIBSA} ${LIBKERN} libsvax.a
+ @strip copy
+ @size copy
+
+#
+
+hp.o: hp.c
+ ${CC} -c ${CFLAGS} $*.c
+
+ra.o: ra.c
+ ${CC} -c ${CFLAGS} $*.c
+
+autoconf.o: autoconf.c
+ ${CC} -c ${CFLAGS} $*.c
+
+conf.o: conf.c
+ ${CC} -c ${CFLAGS} $*.c
+
+boot.o: boot.c
+ ${CC} -c ${CFLAGS} $*.c
+
+copy.o: copy.c
+ ${CC} -c ${CFLAGS} $*.c
+
+romread.o: romread.s
+ ${CC} -x assembler-with-cpp -E romread.s | as -o romread.o
+
+init.o: init.c
+ ${CC} -c ${CFLAGS} $*.c
+
+bootxx.o: bootxx.c
+ ${CC} -c ${CFLAGS} $*.c
+
+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
+
diff --git a/sys/arch/vax/boot/autoconf.c b/sys/arch/vax/boot/autoconf.c
new file mode 100644
index 00000000000..654d6a68680
--- /dev/null
+++ b/sys/arch/vax/boot/autoconf.c
@@ -0,0 +1,92 @@
+/* $NetBSD: autoconf.c,v 1.3 1995/09/16 13:34:20 ragge Exp $ */
+/*
+ * Copyright (c) 1994 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}.
+ * 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 "sys/param.h"
+#include "../include/mtpr.h"
+#include "../include/sid.h"
+#include "vaxstand.h"
+
+int nmba=0, nuba=0, nbi=0,nsbi=0,nuda=0;
+int *mbaaddr, *ubaaddr;
+int *udaaddr, *uioaddr, tmsaddr;
+
+static int mba750[]={0xf28000,0xf2a000,0xf2c000};
+static int uba750[]={0xf30000,0xf32000};
+static int uio750[]={0xfc0000,0xf80000};
+static int uda750[]={0772150};
+
+static int uba630[]={0x20087800};
+static int uio630[]={0x30000000};
+#define qbdev(csr) (((csr) & 017777)-0x10000000)
+static int uda630[]={qbdev(0772150),qbdev(0760334)};
+/*
+ * Autoconf routine is really stupid; but it actually don't
+ * need any intelligence. We just assume that all possible
+ * devices exists on each cpu. Fast & easy.
+ */
+
+autoconf()
+{
+ int i = MACHID(mfpr(PR_SID));
+
+ switch (i) {
+
+ default:
+ printf("CPU type %d not supported by boot\n",i);
+ asm("halt");
+
+ case VAX_750:
+ nmba = 3;
+ nuba = 2;
+ nuda = 1;
+ mbaaddr = mba750;
+ ubaaddr = uba750;
+ udaaddr = uda750;
+ uioaddr = uio750;
+ tmsaddr = 0774500;
+ break;
+
+ case VAX_650: /* the same for uvaxIII */
+ case VAX_78032:
+ nuba = 1;
+ nuda = 2;
+ ubaaddr = uba630;
+ udaaddr = uda630;
+ uioaddr = uio630;
+ tmsaddr = qbdev(0774500);
+ break;
+ }
+}
+
diff --git a/sys/arch/vax/boot/boot.c b/sys/arch/vax/boot/boot.c
new file mode 100644
index 00000000000..d85ddabdf5d
--- /dev/null
+++ b/sys/arch/vax/boot/boot.c
@@ -0,0 +1,249 @@
+/* $NetBSD: boot.c,v 1.4 1995/09/16 15:54:20 ragge Exp $ */
+/*-
+ * Copyright (c) 1982, 1986 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.
+ *
+ * @(#)boot.c 7.15 (Berkeley) 5/4/91
+ */
+
+#include "sys/param.h"
+#include "sys/reboot.h"
+#include "lib/libsa/stand.h"
+
+#include <a.out.h>
+
+/*
+ * Boot program... arguments passed in r10 and r11 determine
+ * whether boot stops to ask for system name and which device
+ * boot comes from.
+ */
+
+char line[100];
+volatile u_int devtype, bootdev;
+extern unsigned opendev;
+
+main()
+{
+ register howto asm("r11");
+ register bdev asm("r10");
+ int io, retry, type;
+
+ io=0;
+ bootdev=bdev;
+ autoconf();
+
+ if ((howto & RB_ASKNAME) == 0) {
+ type = (devtype >> B_TYPESHIFT) & B_TYPEMASK;
+ if ((unsigned)type < ndevs && devsw[type].dv_name)
+ strcpy(line, "/netbsd");
+ else
+ howto |= RB_SINGLE|RB_ASKNAME;
+ }
+
+ for (retry = 0;;) {
+ if (io >= 0)
+ printf("\nNboot\n");
+ if (howto & RB_ASKNAME) {
+ printf(": ");
+ gets(line);
+ if (line[0] == 0) {
+ strcpy(line, "/netbsd");
+ printf(": %s\n", line);
+ }
+ } else
+ printf(": %s\n", line);
+ io = open(line, 0);
+ if (io >= 0) {
+ loadpcs();
+ copyunix(howto, opendev, io);
+ close(io);
+ howto |= RB_SINGLE|RB_ASKNAME;
+ } else {
+ printf("%s\n",strerror(errno));
+ }
+ if (++retry > 2)
+ howto |= RB_SINGLE|RB_ASKNAME;
+ }
+}
+
+/*ARGSUSED*/
+copyunix(howto, devtype, aio)
+ register howto, devtype; /* howto=r11, devtype=r10 */
+ int aio;
+{
+ register int esym; /* must be r9 */
+ struct exec x;
+ register int io = aio, i;
+ char *addr;
+
+ if (read(io, (char *)&x, sizeof(x)) != sizeof(x) || N_BADMAG(x)) {
+ printf("Bad format\n");
+ return;
+ }
+ printf("%d", x.a_text);
+ if (N_GETMAGIC(x) == ZMAGIC && lseek(io, 0x400, SEEK_SET) == -1)
+ goto shread;
+ if (read(io, (char *)0, x.a_text) != x.a_text)
+ goto shread;
+ addr = (char *)x.a_text;
+ if (N_GETMAGIC(x) == ZMAGIC || N_GETMAGIC(x) == NMAGIC)
+ while ((int)addr & CLOFSET)
+ *addr++ = 0;
+ printf("+%d", x.a_data);
+ if (read(io, addr, x.a_data) != x.a_data)
+ goto shread;
+ addr += x.a_data;
+ printf("+%d", x.a_bss);
+ for (i = 0; i < x.a_bss; i++)
+ *addr++ = 0;
+ if (howto & RB_KDB && x.a_syms) {
+ *(int *)addr = x.a_syms; /* symbol table size */
+ addr += sizeof (int);
+ printf("[+%d", x.a_syms);
+ if (read(io, addr, x.a_syms) != x.a_syms)
+ goto shread;
+ addr += x.a_syms;
+ if (read(io, addr, sizeof (int)) != sizeof (int))
+ goto shread;
+ i = *(int *)addr - sizeof (int); /* string table size */
+ addr += sizeof (int);
+ printf("+%d]", i);
+ if (read(io, addr, i) != i)
+ goto shread;
+ addr += i;
+ esym = roundup((int)addr, sizeof (int));
+ x.a_bss = 0;
+ } else
+ howto &= ~RB_KDB;
+ for (i = 0; i < 128*512; i++) /* slop */
+ *addr++ = 0;
+ printf(" start 0x%x\n", (x.a_entry&0x7fffffff));
+ hoppabort((x.a_entry&0x7fffffff),howto, devtype, esym);
+ return;
+shread:
+ printf("Short read\n");
+ return;
+}
+
+/* 750 Patchable Control Store magic */
+
+#include "../include/mtpr.h"
+#include "../include/cpu.h"
+#include "../include/sid.h"
+#define PCS_BITCNT 0x2000 /* number of patchbits */
+#define PCS_MICRONUM 0x400 /* number of ucode locs */
+#define PCS_PATCHADDR 0xf00000 /* start addr of patchbits */
+#define PCS_PCSADDR (PCS_PATCHADDR+0x8000) /* start addr of pcs */
+#define PCS_PATCHBIT (PCS_PATCHADDR+0xc000) /* patchbits enable reg */
+#define PCS_ENABLE 0xfff00000 /* enable bits for pcs */
+
+#define extzv(one, two, three,four) \
+({ \
+ asm __volatile (" extzv %0,%3,(%1),(%2)+" \
+ : \
+ : "g"(one),"g"(two),"g"(three),"g"(four)); \
+})
+
+
+loadpcs()
+{
+ register int *ip; /* known to be r11 below */
+ register int i; /* known to be r10 below */
+ register int *jp; /* known to be r9 below */
+ register int j;
+ static int pcsdone = 0;
+ int mid = mfpr(PR_SID);
+ char pcs[100];
+ char *cp;
+
+ if ((mid >> 24) != VAX_750 || ((mid >> 8) & 255) < 95 || pcsdone)
+ return;
+ printf("Updating 11/750 microcode: ");
+ for (cp = line; *cp; cp++)
+ if (*cp == ')' || *cp == ':')
+ break;
+ if (*cp) {
+ strncpy(pcs, line, 99);
+ pcs[99] = 0;
+ i = cp - line + 1;
+ } else
+ i = 0;
+ strcpy(pcs + i, "pcs750.bin");
+ i = open(pcs, 0);
+ if (i < 0) {
+ printf("bad luck - missing pcs750.bin :-(\n");
+ return;
+ }
+ /*
+ * We ask for more than we need to be sure we get only what we expect.
+ * After read:
+ * locs 0 - 1023 packed patchbits
+ * 1024 - 11264 packed microcode
+ */
+ if (read(i, (char *)0, 23*512) != 22*512) {
+ printf("Error reading %s\n", pcs);
+ close(i);
+ return;
+ }
+ close(i);
+
+ /*
+ * Enable patchbit loading and load the bits one at a time.
+ */
+ *((int *)PCS_PATCHBIT) = 1;
+ ip = (int *)PCS_PATCHADDR;
+ jp = (int *)0;
+ for (i=0; i < PCS_BITCNT; i++) {
+ extzv(i,jp,ip,1);
+ }
+ *((int *)PCS_PATCHBIT) = 0;
+
+ /*
+ * Load PCS microcode 20 bits at a time.
+ */
+ ip = (int *)PCS_PCSADDR;
+ jp = (int *)1024;
+ for (i=j=0; j < PCS_MICRONUM * 4; i+=20, j++) {
+ extzv(i,jp,ip,20);
+ }
+
+ /*
+ * Enable PCS.
+ */
+ i = *jp; /* get 1st 20 bits of microcode again */
+ i &= 0xfffff;
+ i |= PCS_ENABLE; /* reload these bits with PCS enable set */
+ *((int *)PCS_PCSADDR) = i;
+
+ mid = mfpr(PR_SID);
+ printf("new rev level=%d\n", V750UCODE(mid));
+ pcsdone = 1;
+}
diff --git a/sys/arch/vax/boot/bootxx.c b/sys/arch/vax/boot/bootxx.c
new file mode 100644
index 00000000000..b2f01417c95
--- /dev/null
+++ b/sys/arch/vax/boot/bootxx.c
@@ -0,0 +1,399 @@
+/* $NetBSD: bootxx.c,v 1.3 1995/09/16 13:01:06 ragge Exp $ */
+/*-
+ * Copyright (c) 1982, 1986 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.
+ *
+ * @(#)boot.c 7.15 (Berkeley) 5/4/91
+ */
+
+#include "sys/param.h"
+#include "sys/reboot.h"
+#include "sys/disklabel.h"
+
+#include "lib/libsa/stand.h"
+#include "lib/libsa/ufs.h"
+
+#include "../mba/mbareg.h"
+#include "../mba/hpreg.h"
+
+#include "../include/pte.h"
+#include "../include/sid.h"
+#include "../include/mtpr.h"
+#include "../include/reg.h"
+
+#define NRSP 0 /* Kludge */
+#define NCMD 0 /* Kludge */
+#include "../uba/ubareg.h"
+#include "../uba/udareg.h"
+#include "../vax/mscp.h"
+
+#include "data.h"
+#include "vaxstand.h"
+
+#include <a.out.h>
+
+int romstrategy(), romopen();
+int command(int, int);
+
+/*
+ * Boot program... argume passed in r10 and r11 determine whether boot
+ * stops to ask for system name and which device boot comes from.
+ */
+
+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()
+{
+ int io;
+ char *hej = "/boot";
+
+ 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;
+ rpb = bootregs[11];
+ bootdev = rpb->devtyp;
+
+ break;
+ }
+ case VAX_750:
+ is_750 = 1;
+ bootdev = bootregs[10];
+
+ break;
+ }
+
+ bootset = getbootdev();
+
+ printf("\nhowto 0x%x, bdev 0x%x, booting...\n", boothowto, bootdev);
+ io = open(hej, 0);
+
+ if (io >= 0 && io < SOPEN_MAX) {
+ copyunix(io);
+ } else {
+ printf("Boot failed. errno %d (%s)\n", errno, strerror(errno));
+ }
+}
+
+/* ARGSUSED */
+copyunix(aio)
+{
+ struct exec x;
+ register int io = aio, i;
+ char *addr;
+
+ i = read(io, (char *) &x, sizeof(x));
+ if (i != sizeof(x) || N_BADMAG(x)) {
+ printf("Bad format: errno %s\n", strerror(errno));
+ return;
+ }
+ printf("%d", x.a_text);
+ if (N_GETMAGIC(x) == ZMAGIC && lseek(io, N_TXTADDR(x), SEEK_SET) == -1)
+ goto shread;
+ if (read(io, (char *) 0x10000, x.a_text) != x.a_text)
+ goto shread;
+ addr = (char *) x.a_text;
+ if (N_GETMAGIC(x) == ZMAGIC || N_GETMAGIC(x) == NMAGIC)
+ while ((int) addr & CLOFSET)
+ *addr++ = 0;
+ printf("+%d", x.a_data);
+ if (read(io, addr + 0x10000, x.a_data) != x.a_data)
+ goto shread;
+ addr += x.a_data;
+ bcopy((void *) 0x10000, 0, (int) addr);
+ printf("+%d", x.a_bss);
+ for (i = 0; i < x.a_bss; i++)
+ *addr++ = 0;
+ for (i = 0; i < 128 * 512; i++) /* slop */
+ *addr++ = 0;
+ printf(" start 0x%x\n", x.a_entry);
+ hoppabort(x.a_entry, boothowto, bootset);
+ (*((int (*) ()) x.a_entry)) ();
+ return;
+shread:
+ printf("Short read\n");
+ return;
+}
+
+getbootdev()
+{
+ int i, major, adaptor, controller, unit, partition;
+
+
+ switch (cpunumber) {
+ case VAX_78032:
+ case VAX_650:
+ adaptor = 0;
+ controller = ((rpb->csrphy & 017777) == 0xDC)?1:0;
+ unit = rpb->unit; /* DUC, DUD? */
+
+ break;
+
+ case VAX_750:
+ controller = 0; /* XXX Actually massbuss can be on 3 ctlr's */
+ unit = bootregs[3];
+ break;
+ }
+
+ partition = 0;
+
+ switch (bootdev) {
+ case 0: /* massbuss boot */
+ major = 0; /* hp / ... */
+ adaptor = (bootregs[1] & 0x6000) >> 17;
+ break;
+
+ case 17: /* UDA50 boot */
+ major = 9; /* ra / mscp */
+ if (is_750)
+ adaptor = (bootregs[1] & 0x40000 ? 0 : 1);
+ break;
+
+ case 18: /* TK50 boot */
+ major = 15; /* tms / tmscp */
+ is_tmscp = 1; /* use tape spec in mscp routines */
+ break;
+
+ default:
+ printf("Unsupported boot device %d, trying anyway.\n", bootdev);
+ boothowto |= (RB_SINGLE | RB_ASKNAME);
+ }
+ return MAKEBOOTDEV(major, adaptor, controller, unit, partition);
+}
+
+struct devsw devsw[] = {
+ SADEV("rom", romstrategy,nullsys,nullsys, noioctl),
+};
+
+int ndevs = (sizeof(devsw) / sizeof(devsw[0]));
+
+struct fs_ops file_system[] = {
+ {ufs_open, ufs_close, ufs_read, ufs_write, ufs_seek, ufs_stat}
+};
+
+int nfsys = (sizeof(file_system) / sizeof(struct fs_ops));
+
+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 uda_rsp; /* response packets */
+ struct mscp uda_cmd; /* command packets */
+} uda;
+volatile struct udadevice *csr;
+
+devopen(f, fname, file)
+ struct open_file *f;
+ const char *fname;
+ char **file;
+{
+ char *msg;
+ int i, err, off;
+ char line[64];
+
+ f->f_dev = &devsw[0];
+ *file = fname;
+
+ /*
+ * On uVAX we need to init [T]MSCP ctlr to be able to use it.
+ */
+ if (is_mvax) {
+ switch (bootdev) {
+ case 17: /* MSCP */
+ case 18: /* TMSCP */
+ csr = (struct udadevice *)rpb->csrphy;
+
+ csr->udaip = 0; /* Start init */
+ while((csr->udasa & UDA_STEP1) == 0);
+ csr->udasa = 0x8000;
+ while((csr->udasa & UDA_STEP2) == 0);
+ csr->udasa = (short)(((u_int)&uda)&0xffff) + 8;
+ while((csr->udasa & UDA_STEP3) == 0);
+ csr->udasa = 0x10;
+ while((csr->udasa & UDA_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)
+ uda.uda_cmd.mscp_vcid = 1;
+ command(M_OP_SETCTLRC, 0);
+ uda.uda_cmd.mscp_unit = rpb->unit;
+ command(M_OP_ONLINE, 0);
+ }
+ }
+
+ /*
+ * the disklabel _shall_ be at address LABELOFFSET + RELOC in
+ * phys memory now, no need at all to reread it again.
+ * Actually disklabel is only needed when using hp disks,
+ * but it doesn't hurt to always get it.
+ */
+ if (!is_tmscp) {
+ msg = getdisklabel(LABELOFFSET + RELOC, &lp);
+ if (msg) {
+ printf("getdisklabel: %s\n", msg);
+ }
+ }
+ return 0;
+}
+
+command(cmd, arg)
+{
+ volatile int hej;
+
+ uda.uda_cmd.mscp_opcode = cmd;
+ uda.uda_cmd.mscp_modifier = arg;
+
+ 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 = csr->udaip;
+ while (uda.uda_ca.ca_rspdsc < 0);
+
+}
+
+int curblock = 0;
+
+romstrategy(sc, func, dblk, size, buf, rsize)
+ void *sc;
+ int func;
+ daddr_t dblk;
+ char *buf;
+ int size, *rsize;
+{
+ int i;
+ int block = dblk;
+ int nsize = size;
+
+ switch (cpunumber) {
+
+ case VAX_650:
+ case VAX_78032:
+ switch (bootdev) {
+
+ case 17: /* MSCP */
+ uda.uda_cmd.mscp_seq.seq_lbn = dblk;
+ uda.uda_cmd.mscp_seq.seq_bytecount = size;
+ uda.uda_cmd.mscp_seq.seq_buffer = buf;
+ uda.uda_cmd.mscp_unit = rpb->unit;
+ command(M_OP_READ, 0);
+ break;
+
+ case 18: /* TMSCP */
+ if (dblk < curblock) {
+ uda.uda_cmd.mscp_seq.seq_bytecount =
+ curblock - dblk;
+ command(M_OP_POS, 12);
+ } else {
+ uda.uda_cmd.mscp_seq.seq_bytecount =
+ dblk - curblock;
+ command(M_OP_POS, 4);
+ }
+ curblock = size/512 + dblk;
+ for (i = 0 ; i < size/512 ; i++) {
+ uda.uda_cmd.mscp_seq.seq_lbn = 1;
+ uda.uda_cmd.mscp_seq.seq_bytecount = 512;
+ uda.uda_cmd.mscp_seq.seq_buffer = buf + i * 512;
+ uda.uda_cmd.mscp_unit = rpb->unit;
+ command(M_OP_READ, 0);
+ }
+ break;
+
+ }
+ break;
+
+ case VAX_750:
+ if (bootdev) {
+ while (size > 0) {
+ if ((read750(block, bootregs) & 0x01) == 0)
+ return 1;
+
+ bcopy(0, buf, 512);
+ size -= 512;
+ buf += 512;
+ block++;
+ }
+ } else
+ hpread(block, size, buf);
+ break;
+ }
+
+ *rsize = nsize;
+ return 0;
+}
+
+hpread(block, size, buf)
+ char *buf;
+{
+ volatile struct mba_regs *mr = (void *) bootregs[1];
+ volatile struct hp_drv *hd = (void*)&mr->mba_md[bootregs[3]];
+ struct disklabel *dp = &lp;
+ u_int pfnum, nsize, mapnr, bn, cn, sn, tn;
+
+ pfnum = (u_int) buf >> PGSHIFT;
+
+ for (mapnr = 0, nsize = size; (nsize + NBPG) > 0; nsize -= NBPG)
+ mr->mba_map[mapnr++] = PG_V | pfnum++;
+ mr->mba_var = ((u_int) buf & PGOFSET);
+ mr->mba_bc = (~size) + 1;
+ bn = block;
+ cn = bn / dp->d_secpercyl;
+ sn = bn % dp->d_secpercyl;
+ tn = sn / dp->d_nsectors;
+ sn = sn % dp->d_nsectors;
+ hd->hp_dc = cn;
+ hd->hp_da = (tn << 8) | sn;
+ hd->hp_cs1 = HPCS_READ;
+ while (mr->mba_sr & MBASR_DTBUSY);
+ if (mr->mba_sr & MBACR_ABORT){
+ return 1;
+ }
+ return 0;
+}
diff --git a/sys/arch/vax/boot/conf.c b/sys/arch/vax/boot/conf.c
new file mode 100644
index 00000000000..15236d763df
--- /dev/null
+++ b/sys/arch/vax/boot/conf.c
@@ -0,0 +1,72 @@
+/* $NetBSD: conf.c,v 1.4 1995/09/16 13:18:28 ragge Exp $ */
+/*
+ * Copyright (c) 1994 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}.
+ * 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 "sys/param.h"
+
+#include "lib/libsa/stand.h"
+#include "lib/libsa/ufs.h"
+
+#include "vaxstand.h"
+
+int raopen(), rastrategy();
+int hpopen(), hpstrategy();
+int tmscpopen(), tmscpstrategy();
+
+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),
+ SADEV("tm",nullsys, nodev, nullsys, noioctl),
+ SADEV("ts",nullsys, nodev, nullsys, noioctl),
+ SADEV("mt",nullsys, nodev, nullsys, noioctl),
+ SADEV("tu",nullsys, nodev, 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),
+};
+
+int ndevs = (sizeof(devsw)/sizeof(devsw[0]));
+
+struct fs_ops file_system[] = {
+ { ufs_open, ufs_close, ufs_read, ufs_write, ufs_seek, ufs_stat }
+};
+
+int nfsys = (sizeof(file_system) / sizeof(struct fs_ops));
+
diff --git a/sys/arch/vax/boot/consio.c b/sys/arch/vax/boot/consio.c
new file mode 100644
index 00000000000..39402cc1d44
--- /dev/null
+++ b/sys/arch/vax/boot/consio.c
@@ -0,0 +1,61 @@
+/* $NetBSD: consio.c,v 1.3 1995/09/16 15:48:49 ragge Exp $ */
+/*
+ * Copyright (c) 1994 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}.
+ * 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 "sys/param.h"
+
+#include "../vax/gencons.h"
+
+#include "../include/mtpr.h"
+
+putchar(ch)
+ int ch;
+{
+ while ((mfpr(PR_TXCS) & GC_RDY) == 0); /* Wait until xmit ready */
+ mtpr(ch, PR_TXDB); /* xmit character */
+ if (ch == 10)
+ putchar(13); /* CR/LF */
+
+}
+
+getchar()
+{
+ int ch;
+
+ 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;
+}
diff --git a/sys/arch/vax/boot/copy.c b/sys/arch/vax/boot/copy.c
new file mode 100644
index 00000000000..a67721d7458
--- /dev/null
+++ b/sys/arch/vax/boot/copy.c
@@ -0,0 +1,243 @@
+/* $NetBSD: copy.c,v 1.2 1995/09/29 16:35:00 ragge Exp $ */
+/*-
+ * Copyright (c) 1982, 1986 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.
+ *
+ * @(#)boot.c 7.15 (Berkeley) 5/4/91
+ */
+
+#include "sys/param.h"
+#include "sys/reboot.h"
+#include "lib/libsa/stand.h"
+
+#include <a.out.h>
+
+char line[100];
+volatile u_int devtype, bootdev;
+extern unsigned opendev;
+
+static char *progname = "copy";
+static char *iobuf = NULL;
+static char *bufp = NULL;
+static int bufsize = 0;
+static int partlist[8];
+
+int fill_buffer (void);
+int write_disk (void);
+
+main()
+{
+ int adapt, ctlr, unit, part;
+ int res, i, loops;
+ char line[64];
+
+ autoconf ();
+
+ printf ("\n");
+ printf ("%s: \n", progname);
+ printf ("This program will read miniroot from tape/floppy/disk \n");
+ printf ("and install this miniroot onto disk.\n");
+ printf ("\n");
+
+ res = fill_buffer ();
+ if (res < 0) {
+ printf ("errors occured during read. Continue at your own risk.\n");
+ printf ("Do you want to continue ? [y/n] ");
+ gets (line);
+ if (*line != 'y' && *line != 'Y') {
+ printf ("bye.\n");
+ return (-1);
+ }
+ }
+
+ printf ("\n");
+ res = write_disk ();
+
+ printf ("\n");
+ printf ("Halt/Reboot the machine NOW.\n");
+ for (;;)
+ ;
+ /* NOTREACHED */
+}
+
+int
+fill_buffer (void)
+{
+ char devname[64];
+ int numblocks;
+ int blocksize = 512;
+ int bpv = 0; /* blocks per volume */
+ int bpt = 8; /* blocks per transfer */
+ struct open_file file;
+ char *filename;
+ int i, loops;
+ int size, rsize;
+ int res, errors = 0;
+
+again:
+ printf("\n");
+ printf("Specify the device to read from as xx(N,?), where\n");
+ printf("xx is the device-name, ? is file/partition number\n");
+ printf("and N is the unit-number, e.g.\n");
+ printf("\"tms(0,1)\" for the first TMSCP-tape (TK50),\n");
+ printf("\"ra(2,0)\" for the third MSCP-disk/floppy (RX33/RX50)\n");
+ printf("\n");
+ printf("device to read from ? ");
+ gets(devname);
+
+ printf("\n");
+ printf("Specify number of blocks to transfer. Usually this is\n");
+ printf("sizeof(miniroot) / 512.\n");
+ printf("It's safe to transfer more blocks than just the miniroot.\n");
+ printf("\n");
+ while (1) {
+ printf ("number of blocks ? ");
+ gets (line);
+ if (atoi(line) > 0) {
+ if (iobuf && bufsize)
+ free (iobuf, bufsize);
+ numblocks = atoi (line);
+ bufsize = 512 * numblocks;
+ iobuf = alloc (bufsize);
+ bufp = iobuf;
+ if (iobuf == NULL) {
+ printf ("cannot allocate this much memory.\n");
+ continue;
+ }
+ break;
+ }
+ printf ("invalid number %d.\n", atoi(line));
+ }
+
+ printf ("\n");
+ printf ("If your miniroot is split into volumes, then you must\n");
+ printf ("specify the number of blocks per volume.\n");
+ printf ("(e.g. 800 blocks per RX50, 2400 blocks per RX33)\n");
+ printf ("\n");
+ while (1) {
+ printf ("number of blocks per volume ? [%d] ", numblocks);
+ gets (line);
+ if (!*line || atoi(line) > 0) {
+ bpv = (atoi(line) > 0 ? atoi(line) : numblocks);
+ break;
+ }
+ printf ("invalid number %d.\n", atoi(line));
+ }
+
+ printf ("\n");
+ do {
+ printf ("Make sure unit %s is online and holds the proper volume.\n", devname);
+ printf ("Then type \'g\' to Go or \'a\' to Abort.\n");
+ printf ("\n");
+ printf ("OK to go on ? [g/a] ");
+ gets (line);
+ if (*line == 'g' || *line == 'G') {
+ printf ("Reading ... ");
+ if (devopen (&file, devname, &filename)) {
+ printf ("cannot open unit %s.\n", devname);
+ goto again;
+ }
+ loops = bpv / bpt + (bpv % bpt != 0);
+ for (i=0; i<loops; i++) {
+ twiddle ();
+ size = 512 * min (bpt, bpv - (i*bpt));
+ res = (*file.f_dev->dv_strategy)
+ (file.f_devdata, F_READ,
+ (daddr_t)i*bpt, size, bufp, &rsize);
+ if (res != 0) {
+ printf ("error %d in read.\n", res);
+ errors++;
+ /* continue ? halt ??? */
+ }
+ bufp += size;
+ }
+ numblocks -= bpv;
+ }
+ if (numblocks > 0) {
+ int vn = ((bufp - iobuf) / 512) / bpv;
+ printf ("\n");
+ printf ("volume #%d done. Now insert volume #%d\n",
+ vn - 1, vn);
+ }
+ } while (numblocks > 0);
+ printf ("Reading of miniroot done. (%d blocks read)\n",
+ (bufp - iobuf) / 512);
+
+ return (-errors);
+}
+
+int
+write_disk (void)
+{
+ char line[64];
+ char devname[64];
+ struct open_file file;
+ char *fname;
+ int rsize, res;
+ int i, errors = 0;
+
+ printf ("\n");
+ printf ("Now specify the device to write miniroot to as xx(N,1)\n");
+ printf ("where xx is the drive type and N is the drive number.\n");
+ printf ("For example: ra(0,1) refers to MSCP drive #0, b partition\n");
+ printf ("\n");
+ do {
+ printf ("Root disk ? : ");
+ gets (devname);
+ } while (devopen (&file, devname, &fname));
+
+ /*
+ * next: initialize the partition
+ */
+ printf ("Initializing partition ... ");
+ bufp = iobuf + (16 * 512);
+ for (i=16; i<bufsize/512; i++) {
+ twiddle ();
+ res = (*file.f_dev->dv_strategy) (file.f_devdata, F_WRITE,
+ (daddr_t)i, 512, bufp, &rsize);
+ if (res != 0) {
+ errors++;
+ printf ("error writing block %d.\n");
+ printf ("trying to continue ...\n");
+ }
+ bufp += 512;
+ }
+ printf ("done.\n");
+ printf ("(%d blocks written.)\n", bufsize/512);
+
+ printf ("\n");
+ printf ("Halt the machine and reboot from distribution media,\n");
+ printf ("giving second partition as part to mount as root. Ex:\n");
+ printf (": ra(0,1) for ra disk 0, hp(2,1) for massbuss disk 2\n");
+
+ return (-errors);
+}
+
diff --git a/sys/arch/vax/boot/data.h b/sys/arch/vax/boot/data.h
new file mode 100644
index 00000000000..d63b5496fbc
--- /dev/null
+++ b/sys/arch/vax/boot/data.h
@@ -0,0 +1,74 @@
+/* $NetBSD: data.h,v 1.4 1995/09/16 15:58:57 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 */
+
+
+
+extern unsigned *bootregs;
+
+/*
+ * rpb->iovec gives pointer to this structure.
+ *
+ * bqo->unit_init() is used to initialize the controller,
+ * bqo->qio() is used to read from boot-device
+ */
+
+struct bqo {
+ long qio; /* 4 QIO entry */
+ long map; /* 4 Mapping entry */
+ long select; /* 4 Selection entry */
+ long drivrname; /* 4 Offset to driver name */
+ short version; /* 2 Version number of VMB */
+ short vercheck; /* 2 Check field */
+ /* offset: 20 */
+ long reselect; /* 4 Reselection entry */
+ long move; /* 4 Move driver entry */
+ long unit_init; /* 4 Unit initialization entry */
+ long auxdrname; /* 4 Offset to auxiliary driver name */
+ long umr_dis; /* 4 UNIBUS Map Registers to disable */
+ /* offset: 40 */
+ long ucode; /* 4 Absolute address of booting microcode */
+ long unit_disc; /* 4 Unit disconnecting entry */
+ long devname; /* 4 Offset to boot device name */
+ long umr_tmpl; /* 4 UNIBUS map register template */
+ /* offset: 60 */
+ /*
+ * the rest is unknown / unneccessary ...
+ */
+ long xxx[6]; /* 24 -- total: 84 bytes */
+};
+
+extern struct bqo *bqo;
diff --git a/sys/arch/vax/boot/devopen.c b/sys/arch/vax/boot/devopen.c
new file mode 100644
index 00000000000..6200f477f49
--- /dev/null
+++ b/sys/arch/vax/boot/devopen.c
@@ -0,0 +1,212 @@
+/* $NetBSD: devopen.c,v 1.3 1995/09/16 13:18:29 ragge Exp $ */
+/*-
+ * Copyright (c) 1993 John Brezak
+ * 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. 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 "lib/libsa/stand.h"
+/* #include "samachdep.h" */
+
+u_int opendev;
+
+#define ispart(c) ((c) >= 'a' && (c) <= 'h')
+
+int
+atoi(cp)
+ char *cp;
+{
+ int val = 0;
+ while(isdigit(*cp))
+ val = val * 10 + (*cp++ - '0');
+ return(val);
+}
+
+usage()
+{
+ printf("\
+ Usage: device(adaptor, controller, drive, partition)file\n\
+ <device><unit><partitonletter>:file\n\
+ ");
+}
+
+devlookup(d,len)
+ char *d;
+ int 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);
+
+ 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("\n");
+ errno = ENODEV;
+ return(-1);
+}
+
+/*
+ * Parse a device spec in one of two forms.
+ *
+ * dev(adapt, ctlr, unit, part)file
+ * [A-Za-z]*[0-9]*[A-Za-z]:file
+ * dev unit part
+ */
+devparse(fname, dev, adapt, ctlr, unit, part, file)
+ char *fname;
+ int *dev, *adapt, *ctlr, *unit, *part;
+ char **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))
+ *s = tolower(*s);
+
+ /* first form */
+ if(*s == '('){
+ /* lookup device and get index */
+ if ((*dev = devlookup(fname, s - fname)) < 0)
+ goto baddev;
+
+ /* tokenize device ident */
+ args[0] = ++s;
+ for (args[0] = s, i = 1; *s && *s != ')'; s++)
+ if (*s == ',')
+ args[i++] = ++s;
+
+
+ switch(i) {
+ case 4:
+ *adapt = atoi(args[0]);
+ *ctlr = atoi(args[1]);
+ *unit = atoi(args[2]);
+ *part = atoi(args[3]);
+ break;
+ case 3:
+ *ctlr = atoi(args[0]);
+ *unit = atoi(args[1]);
+ *part = atoi(args[2]);
+ break;
+ case 2:
+ *unit = atoi(args[0]);
+ *part = atoi(args[1]);
+ break;
+ case 1:
+ *part = atoi(args[0]);
+ break;
+ case 0:
+ break;
+ }
+ *file = ++s;
+
+ /* second form */
+ } else if (*s == ':') {
+
+ /* isolate device */
+ for(s = fname; *s != ':' && !isdigit(*s); s++)
+ ;
+
+ /* lookup device and get index */
+ if ((*dev = devlookup(fname, s - fname)) < 0)
+ goto baddev;
+
+ /* isolate unit */
+ if ((*unit = atoi(s)) > sizeof(char))
+ goto bad;
+ for (; isdigit(*s); s++)
+ ;
+
+ /* translate partition */
+ if(!ispart(*s))
+ goto bad;
+
+ *part = *s++ - 'a';
+ if(*s != ':')
+ goto bad;
+ *file = ++s;
+
+ /* no device present */
+ } else
+ *file = fname;
+
+ /* return the remaining unparsed part as the file to boot */
+ return(0);
+
+bad:
+ usage();
+
+ baddev:
+ return(-1);
+}
+
+extern int bootdev;
+
+devopen(f, fname, file)
+ struct open_file *f;
+ const char *fname;
+ char **file;
+{
+ int n, error;
+ int dev, ctlr, unit, part;
+ int adapt = 0; /* XXX not used on HP */
+ struct devsw *dp = &devsw[0];
+
+ dev = B_TYPE(bootdev);
+ ctlr = B_CONTROLLER(bootdev);
+ unit = B_UNIT(bootdev);
+ part = B_PARTITION(bootdev);
+
+ if (error = devparse(fname, &dev, &adapt, &ctlr, &unit, &part, file))
+ return(error);
+
+ dp = &devsw[dev];
+
+ if (!dp->dv_open)
+ return(ENODEV);
+
+ opendev = MAKEBOOTDEV(dev, adapt, ctlr, unit, part);
+
+ f->f_dev = dp;
+
+ if ((error = (*dp->dv_open)(f, adapt, ctlr, unit, part)) == 0)
+ return(0);
+
+ printf("%s(%d,%d,%d,%d): %s\n", devsw[dev].dv_name,
+ adapt, ctlr, unit, part, strerror(error));
+
+ return(error);
+}
diff --git a/sys/arch/vax/boot/edlabel.c b/sys/arch/vax/boot/edlabel.c
new file mode 100644
index 00000000000..09844183bef
--- /dev/null
+++ b/sys/arch/vax/boot/edlabel.c
@@ -0,0 +1,222 @@
+/* $NetBSD: edlabel.c,v 1.1 1995/09/16 12:56:03 ragge Exp $ */
+/*
+ * Copyright (c) 1995 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.
+ */
+
+#define DKTYPENAMES
+
+#include "sys/param.h"
+#include "sys/disklabel.h"
+
+#include "lib/libsa/stand.h"
+#include "ufs/ffs/fs.h"
+
+struct disklabel dlabel;
+char bootblock[8192];
+
+void
+showlabel()
+{
+ struct disklabel *lp;
+ struct partition *pp;
+ int i, j;
+
+ lp = &dlabel;
+
+ printf("\n\ndisk type %d (%s), %s: %s%s%s\n", lp->d_type, lp->d_type
+ <DKMAXTYPES?dktypenames[lp->d_type]:dktypenames[0], lp->d_typename,
+ lp->d_flags & D_REMOVABLE?" removable":"", lp->d_flags & D_ECC?
+ " ecc":"", lp->d_flags & D_BADSECT?" badsect":"");
+
+ printf("interleave %d, rpm %d, trackskew %d, cylinderskew %d\n",
+ lp->d_interleave, lp->d_rpm, lp->d_trackskew, lp->d_cylskew);
+ printf("headswitch %d, track-to-track %d, drivedata: %d %d %d %d %d\n",
+ lp->d_headswitch, lp->d_trkseek, lp->d_drivedata[0],
+ lp->d_drivedata[1], lp->d_drivedata[2], lp->d_drivedata[3],
+ lp->d_drivedata[4]);
+
+ printf("\nbytes/sector: %d\n", lp->d_secsize);
+ printf("sectors/track: %d\n", lp->d_nsectors);
+ printf("tracks/cylinder: %d\n", lp->d_ntracks);
+ printf("sectors/cylinder: %d\n", lp->d_secpercyl);
+ printf("cylinders: %d\n", lp->d_ncylinders);
+
+ printf("\n%d partitions:\n", lp->d_npartitions);
+ printf(" size offset\n");
+ pp = lp->d_partitions;
+ for (i = 0; i < lp->d_npartitions; i++) {
+ printf("%c: %d, %d\n", 97 + i, lp->d_partitions[i].p_size,
+ lp->d_partitions[i].p_offset);
+ }
+ printf("\n");
+}
+
+setdefaultlabel()
+{
+ printf("Sorry, not implemented yet. Later...\n\n");
+}
+
+#define GETNUM(out, num) printf(out, num);gets(store); \
+ if (*store) num = atoi(store);
+#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);
+#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;
+
+editlabel()
+{
+ struct disklabel *lp;
+ char store[256];
+ int i;
+
+ lp = &dlabel;
+ printf("\nFirst set disk type. Valid types are:\n");
+ for (i = 0; i < DKMAXTYPES; i++)
+ printf("%d %s\n", i, dktypenames[i]);
+
+ GETNUM("\nNumeric disk type? [%d] ", lp->d_type);
+ GETSTR("Disk name? [%s] ", lp->d_typename);
+ FLAGS("badsectoring? [%c] ", D_BADSECT);
+ FLAGS("ecc? [%c] ", D_ECC);
+ FLAGS("removable? [%c] ", D_REMOVABLE);
+
+ GETNUM("Interleave? [%d] ", lp->d_interleave);
+ GETNUM("rpm? [%d] ", lp->d_rpm);
+ GETNUM("trackskew? [%d] ", lp->d_trackskew);
+ GETNUM("cylinderskew? [%d] ", lp->d_cylskew);
+ GETNUM("headswitch? [%d] ", lp->d_headswitch);
+ GETNUM("track-to-track? [%d] ", lp->d_trkseek);
+ GETNUM("drivedata 0? [%d] ", lp->d_drivedata[0]);
+ GETNUM("drivedata 1? [%d] ", lp->d_drivedata[1]);
+ GETNUM("drivedata 2? [%d] ", lp->d_drivedata[2]);
+ GETNUM("drivedata 3? [%d] ", lp->d_drivedata[3]);
+ GETNUM("drivedata 4? [%d] ", lp->d_drivedata[4]);
+ GETNUM("\nbytes/sector? [%d] ", lp->d_secsize);
+ GETNUM("sectors/track? [%d] ", lp->d_nsectors);
+ GETNUM("tracks/cylinder? [%d] ", lp->d_ntracks);
+ GETNUM("sectors/cylinder? [%d] ", lp->d_secpercyl);
+ GETNUM("cylinders? [%d] ", lp->d_ncylinders);
+ lp->d_npartitions = MAXPARTITIONS;
+ for (i = 0; i < 8; i++) {
+ GETNUM2("%c partition: offset? [%d] ", 97 + i,
+ lp->d_partitions[i].p_offset);
+ GETNUM(" size? [%d] ", lp->d_partitions[i].p_size);
+ }
+}
+
+int bootdev;
+
+void
+main()
+{
+ register bdev asm("r10");
+
+ struct open_file file;
+ char diskname[64], *msg, *filename, indata[64];
+ int i, rsize;
+
+ bootdev = bdev;
+ printf("With this program you can modify everything in the on-disk\n");
+ printf("disklabel. To do something useful you must know the exact\n");
+ printf("geometry of your disk, and have ideas about how you want\n");
+ printf("your partitions to be placed on disk. Some hints:\n");
+ printf("The a partition should be at least ~20000 blocks, the\n");
+ printf("b (swap) is depending on your use of the machine but it\n");
+ printf("should almost never be less than ~32000 blocks.\n\n");
+ printf("Disk geometry for most DEC disks can be found in the disktab");
+ printf("\nfile, and disknames is listed in the installation notes.\n");
+ printf("\nRemember that disk names is given as disk(adapt, ctrl, ");
+ printf("disk, part)\nwhen using the installation tools.\n\n");
+
+ autoconf();
+igen:
+ printf("Label which disk? ");
+ gets(diskname);
+ if (*diskname == 0) goto igen;
+ if (devopen(&file, diskname, &filename)) {
+ printf("cannot open %s\n", diskname);
+ goto igen;
+ }
+ if ((*file.f_dev->dv_strategy)(file.f_devdata, F_READ,
+ (daddr_t)0, 8192, bootblock, &rsize)) {
+ printf("cannot read label block\n");
+ goto igen;
+ }
+ if (msg = (char *) getdisklabel(LABELOFFSET + bootblock, &dlabel))
+ printf("%s: %s\n", diskname, msg);
+
+ do {
+ printf("(E)dit, (S)how, (D)efaults, (W)rite, (Q)uit) : ");
+ gets(indata);
+ switch (*indata) {
+ case ('e'):
+ case ('E'):
+ editlabel();
+ break;
+ case ('s'):
+ case ('S'):
+ showlabel();
+ break;
+ case ('d'):
+ case ('D'):
+ setdefaultlabel();
+ break;
+ case ('w'):
+ case ('W'):
+ dlabel.d_magic = DISKMAGIC;
+ dlabel.d_magic2 = DISKMAGIC;
+ dlabel.d_bbsize = BBSIZE;
+ dlabel.d_sbsize = SBSIZE;
+ dlabel.d_checksum = 0;
+ dlabel.d_checksum = dkcksum(&dlabel);
+ bcopy(&dlabel, LABELOFFSET + bootblock,
+ sizeof(struct disklabel));
+ if ((*file.f_dev->dv_strategy)(file.f_devdata, F_WRITE,
+ (daddr_t)0, 8192, bootblock, &rsize)) {
+ printf("cannot write label sectors.\n");
+ break;
+ }
+ printf("\nThis program does not (yet) write");
+ printf(" bootblocks, only disklabel.\n");
+ printf("Remember to write the bootblocks from the ");
+ printf("miniroot later with the\ncommand ");
+ printf("\"disklabel -B <diskname>\".\n\n");
+ break;
+ case ('q'):
+ case ('Q'):
+ default:
+ break;
+ }
+ } while (*indata != 'q' && *indata != 'Q');
+ goto igen;
+}
diff --git a/sys/arch/vax/boot/hp.c b/sys/arch/vax/boot/hp.c
new file mode 100644
index 00000000000..c7019a3527d
--- /dev/null
+++ b/sys/arch/vax/boot/hp.c
@@ -0,0 +1,165 @@
+/* $NetBSD: hp.c,v 1.4 1995/09/16 15:43:25 ragge Exp $ */
+/*
+ * Copyright (c) 1994 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}.
+ * 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 "sys/param.h"
+#include "sys/disklabel.h"
+
+#include "lib/libsa/stand.h"
+
+#include "../mba/mbareg.h"
+#include "../mba/hpreg.h"
+
+#include "../include/pte.h"
+#include "../include/macros.h"
+
+#include "vaxstand.h"
+
+/*
+ * These routines for HP disk standalone boot is wery simple,
+ * assuming a lots of thing like that we only working at one hp disk
+ * a time, no separate routines for mba driver etc..
+ * But it works :)
+ */
+
+struct hp_softc {
+ int adapt;
+ int ctlr;
+ int unit;
+ int part;
+};
+
+struct disklabel hplabel;
+struct hp_softc hp_softc;
+char io_buf[MAXBSIZE];
+daddr_t part_offset;
+
+hpopen(f, adapt, ctlr, unit, part)
+ struct open_file *f;
+ int ctlr, unit, part;
+{
+ struct disklabel *lp;
+ struct hp_softc *hs;
+ volatile struct mba_regs *mr;
+ volatile struct hp_drv *hd;
+ char *msg;
+ int i,err;
+
+ lp = &hplabel;
+ hs = &hp_softc;
+ mr = (void *)mbaaddr[ctlr];
+ hd = (void *)&mr->mba_md[unit];
+
+ if (adapt > nsbi) return(EADAPT);
+ if (ctlr > nmba) return(ECTLR);
+ if (unit > MAXMBAU) return(EUNIT);
+
+ bzero(lp, sizeof(struct disklabel));
+
+ lp->d_secpercyl = 32;
+ lp->d_nsectors = 32;
+ hs->adapt = adapt;
+ hs->ctlr = ctlr;
+ hs->unit = unit;
+ hs->part = part;
+
+ /* Set volume valid and 16 bit format; only done once */
+ mr->mba_cr = MBACR_INIT;
+ hd->hp_cs1 = HPCS_PA;
+ hd->hp_of = HPOF_FMT;
+
+ err = hpstrategy(hs, 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 *)hs;
+ return 0;
+}
+
+hpstrategy(hs, func, dblk, size, buf, rsize)
+ struct hp_softc *hs;
+ daddr_t dblk;
+ u_int size, *rsize;
+ char *buf;
+ int func;
+{
+ volatile struct mba_regs *mr;
+ volatile struct hp_drv *hd;
+ struct disklabel *lp;
+ unsigned int i, pfnum, mapnr, nsize, bn, cn, sn, tn;
+
+ mr = (void *)mbaaddr[hs->ctlr];
+ hd = (void *)&mr->mba_md[hs->unit];
+ lp = &hplabel;
+
+ pfnum = (u_int)buf >> PGSHIFT;
+
+ for(mapnr = 0, nsize = size; (nsize + NBPG) > 0; nsize -= NBPG)
+ mr->mba_map[mapnr++] = PG_V | pfnum++;
+
+ mr->mba_var = ((u_int)buf & PGOFSET);
+ mr->mba_bc = (~size) + 1;
+ bn = dblk + lp->d_partitions[hs->part].p_offset;
+
+ if (bn) {
+ cn = bn / lp->d_secpercyl;
+ sn = bn % lp->d_secpercyl;
+ tn = sn / lp->d_nsectors;
+ sn = sn % lp->d_nsectors;
+ } else
+ cn = sn = tn = 0;
+
+ hd->hp_dc = cn;
+ hd->hp_da = (tn << 8) | sn;
+ if (func == F_WRITE)
+ hd->hp_cs1 = HPCS_WRITE;
+ else
+ hd->hp_cs1 = HPCS_READ;
+
+ while (mr->mba_sr & MBASR_DTBUSY)
+ ;
+
+ if (mr->mba_sr & MBACR_ABORT)
+ return 1;
+
+ *rsize = size;
+
+ return 0;
+}
diff --git a/sys/arch/vax/boot/init.c b/sys/arch/vax/boot/init.c
new file mode 100644
index 00000000000..94c7ad6276a
--- /dev/null
+++ b/sys/arch/vax/boot/init.c
@@ -0,0 +1,82 @@
+/* $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/ra.c b/sys/arch/vax/boot/ra.c
new file mode 100644
index 00000000000..a0ecefc1a1b
--- /dev/null
+++ b/sys/arch/vax/boot/ra.c
@@ -0,0 +1,186 @@
+/* $NetBSD: ra.c,v 1.3 1995/09/16 13:34:22 ragge Exp $ */
+/*
+ * Copyright (c) 1995 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}.
+ * 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 */
+
+#define NRSP 0 /* Kludge */
+#define NCMD 0 /* Kludge */
+
+#include "sys/param.h"
+#include "sys/disklabel.h"
+
+#include "lib/libsa/stand.h"
+
+#include "../include/pte.h"
+#include "../include/macros.h"
+#include "../uba/ubareg.h"
+#include "../uba/udareg.h"
+#include "../vax/mscp.h"
+
+#include "vaxstand.h"
+
+static command(int);
+
+/*
+ * These routines for RA disk standalone boot is wery simple,
+ * assuming a lots of thing like that we only working at one ra disk
+ * a time, no separate routines for uba driver etc..
+ * This code is foolish and should need a cleanup.
+ * But it works :)
+ */
+
+struct ra_softc {
+ int udaddr;
+ int ubaddr;
+ int part;
+ int unit;
+};
+
+volatile struct uda {
+ struct uda1ca uda_ca; /* communications area */
+ struct mscp uda_rsp; /* response packets */
+ struct mscp uda_cmd; /* command packets */
+} uda;
+
+volatile struct uda *ubauda;
+volatile struct udadevice *udacsr;
+struct disklabel ralabel;
+struct ra_softc ra_softc;
+char io_buf[MAXBSIZE];
+
+raopen(f, adapt, ctlr, unit, part)
+ struct open_file *f;
+ 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];
+ volatile u_int *nisse;
+ unsigned short johan;
+ 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->part = part;
+ udacsr=(void*)ra->udaddr;
+ nisse=&mr->uba_map[0];
+ nisse[494]=PG_V|(((u_int)&uda)>>9);
+ nisse[495]=nisse[494]+1;
+ ubauda=(void*)0x3dc00+(((u_int)(&uda))&0x1ff);
+ /* 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;
+ command(M_OP_SETCTLRC);
+ uda.uda_cmd.mscp_unit=ra->unit;
+ command(M_OP_ONLINE);
+
+ 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;
+ return(0);
+}
+
+static
+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_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);
+
+}
+
+rastrategy(ra, func, dblk, size, buf, rsize)
+ struct ra_softc *ra;
+ int func;
+ daddr_t dblk;
+ char *buf;
+ u_int size, *rsize;
+{
+ volatile struct uba_regs *ur;
+ volatile struct udadevice *udadev;
+ volatile u_int *ptmapp;
+ struct disklabel *lp;
+ u_int i, j, pfnum, mapnr, nsize;
+ volatile int hej;
+
+
+ ur = (void *)ra->ubaddr;
+ udadev = (void*)ra->udaddr;
+ ptmapp = &ur->uba_map[0];
+ lp = &ralabel;
+
+ pfnum = (u_int)buf >> PGSHIFT;
+
+ for(mapnr = 0, nsize = size; (nsize + NBPG) > 0; nsize -= NBPG)
+ ptmapp[mapnr++] = PG_V | pfnum++;
+
+ 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);
+ else
+ command(M_OP_READ);
+
+ *rsize = size;
+ return 0;
+}
diff --git a/sys/arch/vax/boot/romread.s b/sys/arch/vax/boot/romread.s
new file mode 100644
index 00000000000..966280792fb
--- /dev/null
+++ b/sys/arch/vax/boot/romread.s
@@ -0,0 +1,89 @@
+/* $NetBSD: romread.s,v 1.3 1995/09/16 16:20:18 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 "../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)
+ movl 8(ap), r8
+ movl 4(r8), r1
+ movl 8(r8), r2
+ movl 12(r8), r3
+ movl 24(r8), r6
+ clrl r5
+ movl 4(ap), r8
+ pushl $0
+ movl $0, 4(sp)
+ movl fp, 0xf0000 # ragge ???
+ jsb (r6)
+ movl 0xf0000, fp
+ ret
+
+/*
+ * bulkread630 (int lbn, int size, void *buf, int *regs)
+ */
+ENTRY(bulkread630, 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 $33 # read-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/srt0.s b/sys/arch/vax/boot/srt0.s
new file mode 100644
index 00000000000..a85d02538ba
--- /dev/null
+++ b/sys/arch/vax/boot/srt0.s
@@ -0,0 +1,70 @@
+/* $NetBSD: srt0.s,v 1.4 1995/09/16 16:20:20 ragge Exp $ */
+/*
+ * Copyright (c) 1994 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}.
+ * 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 */
+
+
+/*
+ * Auto-moving startup code for standalone programs. Can be loaded
+ * (almost) anywhere in memory but moves itself to the position
+ * it is linked for. Must be started at first position, recommended
+ * is phys addr 0 (boot loads programs at 0, but starts them at the
+ * position set in a.out header.
+ */
+
+nisse: .set nisse,0 # pass -e nisse to ld gives OK start addr
+ .globl nisse
+
+_start: .globl _start
+ nop;nop; # If we get called by calls, or something
+ movl $_start, sp # Probably safe place for stack
+ subl2 $52, sp # do not overwrite saved boot-registers
+
+ subl3 $_start, $_end, r0
+ moval _start, r1
+ movl $_start, r2
+ movc3 r0, (r1), (r2) # should use movc5 instead, to clear bss.
+
+ jsb 1f
+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!
+ halt # no return
+
+
+ .globl _hoppabort
+_hoppabort: .word 0x0
+ movl 4(ap), r6
+ movl 8(ap), r11
+ movl 0xc(ap), r10
+ movl 16(ap), r9
+ calls $0,(r6)
diff --git a/sys/arch/vax/boot/start.s b/sys/arch/vax/boot/start.s
new file mode 100644
index 00000000000..45a9c56169d
--- /dev/null
+++ b/sys/arch/vax/boot/start.s
@@ -0,0 +1,188 @@
+/* $NetBSD: start.s,v 1.4 1995/09/16 16:20: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 */
+
+
+#define LOCORE
+#include "sys/disklabel.h"
+#undef LOCORE
+
+#define ASSEMBLER
+#include "../include/mtpr.h"
+#include "../include/asm.h"
+#include "bootdefs.h"
+
+_start: .globl _start # this is the symbolic name for the start
+ # of code to be relocated. We can use this
+ # to get the actual/real adress (pc-rel)
+ # or to get the relocated address (abs).
+
+.org 0x00 # uVAX booted from TK50 starts here
+ brb from_0x00 # continue behind dispatch-block
+
+.org 0x02 # information used by uVAX-ROM
+ .byte (LABELOFFSET + d_end_)/2 # offset in words to identification area
+ .byte 1 # this byte must be 1
+ .word 0 # logical block number (word swapped)
+ .word 0 # of the secondary image
+
+.org 0x08 #
+ brb from_0x08 # skip ...
+
+.org 0x0A # uVAX booted from disk starts here
+ brb from_0x0A # skip ...
+
+.org 0x0C # 11/750 & 8200 starts here
+ brw cont_750
+
+
+from_0x00: # uVAX from TK50
+from_0x0A: # uVAX from disk
+ brw start_uvax # all(?) uVAXen continue there
+
+from_0x08: # What comes here???
+ halt
+
+.org LABELOFFSET - 6
+regmask: .word 0x0fff # using a variable saves 3 bytes !!!
+bootinfo: .long 0x0 # another 3 bytes if within byte-offset
+
+# the complete area reserved for label
+# must be empty (i.e. filled with zeroes).
+# disklabel(8) checks that before installing
+# the bootblocks over existing label.
+
+/*
+ * Parameter block for uVAX boot.
+ */
+#define VOLINFO 0 /* 1=single-sided 81=double-sided volumes */
+#define SISIZE 16 /* size in blocks of secondary image */
+#define SILOAD 0 /* load offset (usually 0) from the default */
+#define SIOFF 0x0A /* byte offset into secondary image */
+
+.org LABELOFFSET + d_end_
+ .byte 0x18 # must be 0x18
+ .byte 0x00 # must be 0x00 (MBZ)
+ .byte 0x00 # any value
+ .byte 0xFF - (0x18 + 0x00 + 0x00)
+ /* 4th byte holds 1s' complement of sum of previous 3 bytes */
+
+ .byte 0x00 # must be 0x00 (MBZ)
+ .byte VOLINFO
+ .byte 0x00 # any value
+ .byte 0x00 # any value
+
+ .long SISIZE # size in blocks of secondary image
+ .long SILOAD # load offset (usually 0)
+ .long SIOFF # byte offset into secondary image
+ .long (SISIZE + SILOAD + SIOFF) # sum of previous 3
+
+/*
+ * After bootblock (LBN0) has been loaded into the first page
+ * of good memory by 11/750's ROM-code (transfer address
+ * of bootblock-code is: base of good memory + 0x0C) registers
+ * are initialized as:
+ * R0: type of boot-device
+ * 0: Massbus device
+ * 1: RK06/RK07
+ * 2: RL02
+ * 17: UDA50
+ * 35: TK50
+ * 64: TU58
+ * R1: (UBA) address of UNIBUS I/O-page
+ * (MBA) address of boot device's adapter
+ * R2: (UBA) address of the boot device's CSR
+ * (MBA) controller number of boot device
+ * R6: address of driver subroutine in ROM
+ *
+ * cont_750 reads in LBN1-15 for further execution.
+ */
+ .align 2
+cont_750:
+ movl r0,r10
+ movl r5, ap # ap not used here
+ clrl r5
+ clrl r4
+ movl $_start,sp
+1: incl r4
+ movl r4,r8
+ addl2 $0x200,r5
+ cmpl $16,r4
+ beql 2f
+ pushl r5
+ jsb (r6)
+ blbs r0,1b
+2: movl r10, r0
+ movl r11, r5
+ brw start_all
+
+
+start_uvax:
+ mtpr $0, $PR_MAPEN # Turn off MM, please.
+ movl $_start, sp
+ movl 48(r11), ap
+ brb start_all
+
+/*
+ * start_all: stack already at RELOC, we save registers, move ourself
+ * to RELOC and loads boot.
+ */
+start_all:
+ pushr $0xfff # save all regs, used later.
+
+ subl3 $_start, $_edata, r0 # get size of text+data (w/o bss)
+ moval _start, r1 # get actual base-address of code
+ subl3 $_start, $_end, r2 # get complete size (incl. bss)
+ movl $_start, r3 # get relocated base-address of code
+ movc5 r0, (r1), $0, r2, (r3) # copy code to new location
+
+ movl $relocated, -(sp) # return-address on top of stack
+ rsb # can be replaced with new address
+relocated: # now relocation is done !!!
+ movl sp, _bootregs
+ movl ap, _boothowto
+ calls $0, _main # call main() which is
+ halt # not intended to return ...
+
+/*
+ * hoppabort() is called when jumping to the newly loaded program.
+ */
+ENTRY(hoppabort, 0)
+ movl 4(ap),r6
+ movl 8(ap),r11
+ movl 0xc(ap),r10
+ calls $0,(r6)
+ halt
diff --git a/sys/arch/vax/boot/tmscp.c b/sys/arch/vax/boot/tmscp.c
new file mode 100644
index 00000000000..eb143e61426
--- /dev/null
+++ b/sys/arch/vax/boot/tmscp.c
@@ -0,0 +1,202 @@
+/* $NetBSD: tmscp.c,v 1.1 1995/09/16 12:57:35 ragge Exp $ */
+/*
+ * Copyright (c) 1995 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}.
+ * 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 */
+
+#define NRSP 0 /* Kludge */
+#define NCMD 0 /* Kludge */
+
+#include "sys/param.h"
+#include "sys/disklabel.h"
+
+#include "lib/libsa/stand.h"
+
+#include "../include/pte.h"
+#include "../include/macros.h"
+#include "../uba/ubareg.h"
+#include "../uba/udareg.h"
+#include "../vax/mscp.h"
+
+#include "vaxstand.h"
+
+static command(int,int);
+
+/*
+ * These routines for TMSCP tape standalone boot is very simple,
+ * assuming a lots of thing like that we only working at one tape at
+ * a time, no separate routines for uba driver etc..
+ * This code is directly copied from ra disk driver.
+ */
+
+struct ra_softc {
+ int udaddr;
+ int ubaddr;
+ int unit;
+};
+
+static volatile struct uda {
+ struct uda1ca uda_ca; /* communications area */
+ struct mscp uda_rsp; /* response packets */
+ struct mscp uda_cmd; /* command packets */
+} uda;
+
+static volatile struct uda *ubauda;
+static volatile struct udadevice *udacsr;
+static struct ra_softc ra_softc;
+static char io_buf[MAXBSIZE];
+
+tmscpopen(f, adapt, ctlr, unit, part)
+ struct open_file *f;
+ int ctlr, unit, part;
+{
+ char *msg;
+ extern u_int tmsaddr;
+ volatile struct ra_softc *ra=&ra_softc;
+ volatile struct uba_regs *mr=(void *)ubaaddr[adapt];
+ volatile u_int *nisse;
+ unsigned short johan;
+ int i,err;
+
+ if(adapt>nuba) return(EADAPT);
+ if(ctlr>nuda) return(ECTLR);
+ ra->udaddr=uioaddr[adapt]+tmsaddr;
+ ra->ubaddr=(int)mr;
+ ra->unit=unit;
+ udacsr=(void*)ra->udaddr;
+ nisse=&mr->uba_map[0];
+ nisse[494]=PG_V|(((u_int)&uda)>>9);
+ nisse[495]=nisse[494]+1;
+ ubauda=(void*)0x3dc00+(((u_int)(&uda))&0x1ff);
+
+ /*
+ * Init of this tmscp ctlr.
+ */
+ 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;
+ uda.uda_cmd.mscp_un.un_seq.seq_addr = &uda.uda_ca.ca_cmddsc;
+ uda.uda_rsp.mscp_un.un_seq.seq_addr = &uda.uda_ca.ca_rspdsc;
+ uda.uda_cmd.mscp_vcid = 1;
+ uda.uda_cmd.mscp_un.un_sccc.sccc_ctlrflags = 0;
+
+ command(M_OP_SETCTLRC, 0);
+ uda.uda_cmd.mscp_unit=ra->unit;
+ command(M_OP_ONLINE, 0);
+
+ if (part) {
+ uda.uda_cmd.mscp_un.un_seq.seq_buffer = part;
+ command(M_OP_POS, 0);
+ uda.uda_cmd.mscp_un.un_seq.seq_buffer = 0;
+ }
+
+ f->f_devdata=(void *)ra;
+ return(0);
+}
+
+static
+command(cmd, arg)
+{
+ volatile int hej;
+
+ uda.uda_cmd.mscp_opcode = cmd;
+ uda.uda_cmd.mscp_modifier = arg;
+
+ 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) {
+ if (uda.uda_ca.ca_cmdint)
+ uda.uda_ca.ca_cmdint = 0;
+ }
+
+}
+
+static int curblock = 0;
+
+tmscpstrategy(ra, func, dblk, size, buf, rsize)
+ struct ra_softc *ra;
+ int func;
+ daddr_t dblk;
+ char *buf;
+ u_int size, *rsize;
+{
+ u_int i,j,pfnum, mapnr, nsize, bn, cn, sn, tn;
+ volatile struct uba_regs *ur=(void *)ra->ubaddr;
+ volatile struct udadevice *udadev=(void*)ra->udaddr;
+ volatile u_int *ptmapp=&ur->uba_map[0];
+ volatile int hej;
+
+ pfnum=(u_int)buf>>PGSHIFT;
+
+ for(mapnr=0, nsize=size;(nsize+NBPG)>0;nsize-=NBPG)
+ ptmapp[mapnr++]=PG_V|pfnum++;
+
+ /*
+ * First position tape. Remember where we are.
+ */
+ if (dblk < curblock) {
+ uda.uda_cmd.mscp_seq.seq_bytecount = curblock - dblk;
+ command(M_OP_POS, 12); /* 12 == step block backward */
+ } else {
+ uda.uda_cmd.mscp_seq.seq_bytecount = dblk - curblock;
+ command(M_OP_POS, 4); /* 4 == step block forward */
+ }
+ curblock = size/512 + dblk;
+
+ /*
+ * Read in the number of blocks we need.
+ * Why doesn't read of multiple blocks work?????
+ */
+ for (i = 0 ; i < size/512 ; i++) {
+ uda.uda_cmd.mscp_seq.seq_lbn = 1;
+ uda.uda_cmd.mscp_seq.seq_bytecount = 512;
+ uda.uda_cmd.mscp_seq.seq_buffer =
+ (((u_int)buf) & 0x1ff) + i * 512;
+ uda.uda_cmd.mscp_unit = ra->unit;
+ command(M_OP_READ, 0);
+ }
+
+ *rsize=size;
+ return 0;
+}
diff --git a/sys/arch/vax/boot/vaxstand.h b/sys/arch/vax/boot/vaxstand.h
new file mode 100644
index 00000000000..17ec1cbcd03
--- /dev/null
+++ b/sys/arch/vax/boot/vaxstand.h
@@ -0,0 +1,52 @@
+/* $NetBSD: vaxstand.h,v 1.3 1995/04/25 14:14:34 ragge Exp $ */
+/*
+ * Copyright (c) 1994 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}.
+ * 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 */
+
+
+#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;
+
+/* devsw type definitions, used in bootxx and conf */
+#define SADEV(name,strategy,open,close,ioctl) \
+ { name, \
+ (int(*)(void *, int ,daddr_t , u_int , char *, u_int *))strategy, \
+ (int(*)(struct open_file *, ...))open, \
+ (int(*)(struct open_file *))close, \
+ (int(*)(struct open_file *,u_long, void *))ioctl}
+
diff --git a/sys/arch/vax/compile/.keep_me b/sys/arch/vax/compile/.keep_me
new file mode 100644
index 00000000000..e018447add3
--- /dev/null
+++ b/sys/arch/vax/compile/.keep_me
@@ -0,0 +1,3 @@
+$NetBSD: .keep_me,v 1.3 1994/10/26 08:06:10 cgd Exp $
+
+This normally empty directory needs to be kept in the distribution.
diff --git a/sys/arch/vax/conf/EVERYTHING b/sys/arch/vax/conf/EVERYTHING
new file mode 100644
index 00000000000..97703691c5c
--- /dev/null
+++ b/sys/arch/vax/conf/EVERYTHING
@@ -0,0 +1,92 @@
+# $NetBSD: EVERYTHING,v 1.1 1995/03/29 22:54:02 ragge Exp $
+#
+# This file contains everything that is known to be compiled
+# without errors. Some things may not be tested, like NETISO.
+#
+
+include "std.vax"
+
+# Here are all different supported CPU types listed.
+options "VAX750"
+options "VAX630"
+
+# Kernel identification
+options EVERYTHING
+
+# Max users on system; this is just a hint
+maxusers 16
+
+# Paging system, we always have them all.
+options SWAPPAGER, DEVPAGER, VNODEPAGER
+
+# Kernel compiled-in symbolic debugger
+#options DDB
+
+# System V shared memory
+options SYSVMSG # Message passing
+options SYSVSEM # Semaphores
+options SYSVSHM # Shared memory
+options SHMMAXPGS=1024
+
+# Network support
+options INET # Internet protocol, (almost) mandatory
+options ETHER # Ethernet, probably needed
+options NS # Xerox Network system, untested
+options ISO,TPIP # ISO network, untested
+options EON
+options CCITT,LLC,HDLC
+
+# All supported filesystem types
+options FFS,QUOTA # Normal fast filesystem, mandatory
+options LFS # Log-structured file system
+options MFS # Memory filesystem
+options NFSCLIENT # Network filesystem client
+options NFSSERVER # Network filesystem server
+options CD9660 # CDRom filesystem
+options FDESC # Filedescriptors, /dev/fd
+options FIFO
+options KERNFS # Kernel info filesystems
+options NULLFS
+options PORTAL
+options PROCFS # Process filesystem
+options UMAPFS
+options UNION
+
+# Old compat stuff; needed to run 4.3BSD Reno programs
+options COMPAT_43
+options COMPAT_09
+options COMPAT_10
+options COMPAT_RENO
+options TCP_COMPAT_42 # Bug compat with 4.2BSD systems (like NDIX)
+
+# loadable kernel modules.
+options LKM
+
+
+# Kernel(s) to compile
+config vmunix root on hp0 swap on hp0
+
+# All supported CPU:s
+cpu0 at backplane0
+
+# Main buses at backplane
+sbi* at backplane0
+
+# Devices connected at sbi
+mem* at sbi? tr? # Memory subsystems
+uba0 at sbi? tr? # Unibus adapters
+
+# Disk controllers at Unibus
+uda0 at uba? csr 0172150 # UDA50/KDA50/RQDX3
+ra0 at uda0 drive 0 # RA??/RD??
+
+# Ethernet cards
+de0 at uba? csr 0174510 # DEUNA/DELUA
+qe0 at uba? csr 0174440 # DEQNA/DELQA
+
+# Tape drivers
+tmscp0 at uba? csr 0174500
+tms0 at tmscp0 drive ? # TK50/TU81
+
+pseudo-device loop
+pseudo-device pty 48
diff --git a/sys/arch/vax/conf/GENERIC b/sys/arch/vax/conf/GENERIC
new file mode 100644
index 00000000000..b187a85c1e8
--- /dev/null
+++ b/sys/arch/vax/conf/GENERIC
@@ -0,0 +1,103 @@
+# $NetBSD: GENERIC,v 1.7.2.1 1995/10/15 13:52:58 ragge Exp $
+#
+# GENERIC VAX, currently only supports 11/750 anyway.
+#
+
+include "std.vax"
+
+# Here are all different supported CPU types listed.
+options "VAX750"
+options "VAX630"
+
+# Kernel identification
+options GENERIC
+
+# Max users on system; this is just a hint
+maxusers 16
+
+# Paging system, we always have them all.
+options SWAPPAGER, DEVPAGER, VNODEPAGER
+
+# Kernel compiled-in symbolic debugger & system call tracer
+#options DDB
+options KTRACE
+
+# Network support
+#options GATEWAY
+options INET
+options ETHER
+
+# All supported filesystem types
+options FFS,QUOTA
+options LFS
+options MFS
+options NFSSERVER
+options NFSCLIENT
+options FDESC
+options FIFO
+options KERNFS
+options NULLFS
+options PROCFS
+options UMAPFS
+options UNION
+
+# System V shared memory & semaphores support.
+options SYSVMSG
+options SYSVSEM
+options SYSVSHM
+
+# Old compat stuff; needed to run 4.3BSD Reno programs
+options COMPAT_43
+options COMPAT_09
+options COMPAT_10
+options COMPAT_RENO
+options TCP_COMPAT_42
+
+options LKM
+
+
+# Kernel(s) to compile
+config netbsd swap generic
+
+# All supported CPU:s
+cpu0 at backplane0
+
+# Main buses at backplane
+sbi* at backplane0
+
+# Devices connected at sbi
+mem* at sbi? tr? # Memory subsystems
+uba0 at sbi? tr? # Unibus adapters
+uba1 at sbi? tr? # Unibus adapters
+uba2 at sbi? tr? # Unibus adapters
+uba3 at sbi? tr? # Unibus adapters
+
+# Disk controllers at Unibus
+uda0 at uba? csr 0172150
+ra0 at uda0 drive 0
+ra1 at uda0 drive 1
+ra2 at uda0 drive 2
+ra3 at uda0 drive 3
+
+uda1 at uba? csr 0160334
+ra4 at uda1 drive 0
+ra5 at uda1 drive 1
+ra6 at uda1 drive 2
+ra7 at uda1 drive 3
+
+# Ethernet cards
+de0 at uba? csr 0174510
+qe0 at uba? csr 0174440
+
+# Tape drivers
+tmscp0 at uba? csr 0174500
+tms0 at tmscp0 drive ?
+
+pseudo-device loop 1
+pseudo-device pty 48
+pseudo-device bpfilter 8
+pseudo-device sl 2
+pseudo-device ppp 2
+pseudo-device tun 2
+pseudo-device tb 1
+pseudo-device vnd 4
diff --git a/sys/arch/vax/conf/Makefile.vax b/sys/arch/vax/conf/Makefile.vax
new file mode 100644
index 00000000000..ba04c06ccb5
--- /dev/null
+++ b/sys/arch/vax/conf/Makefile.vax
@@ -0,0 +1,125 @@
+# $NetBSD: Makefile.vax,v 1.12 1995/09/19 23:57:55 thorpej Exp $
+
+# @(#)Makefile.vax 7.18 (Berkeley) 12/16/90
+#
+# This makefile is constructed from a machine description:
+# config machineid
+# Most changes should be made in the machine description
+# /sys/vax/conf/``machineid''
+# after which you should do
+# config machineid
+# Machine generic makefile changes should be made in
+# /sys/conf/Makefile.``machinetype''
+# after which config should be rerun for all machines of that type.
+#
+# N.B.: NO DEPENDENCIES ON FOLLOWING FLAGS ARE VISIBLE TO MAKEFILE
+# IF YOU CHANGE THE DEFINITION OF ANY OF THESE RECOMPILE EVERYTHING
+#
+# -DTRACE compile in kernel tracing hooks
+# -DQUOTA compile in file system quotas
+# -DUUDMA compile in unibus tu58 pseudo-dma code
+#
+CC= cc
+CPP= cpp
+LD= /usr/bin/ld
+AWK= awk
+
+S= ../../../..
+VAX= ../..
+
+INCLUDES= -I. -I$S/arch -I$S -I$S/sys
+COPTS= ${INCLUDES} ${IDENT} -D_KERNEL -D_VAX_INLINE_
+AOPTS= ${COPTS} -DASSEMBLER
+CFLAGS= -Werror -fno-builtin ${COPTS}
+LOAD_ADDRESS=80000000
+
+### find out what to use for libkern
+.include "$S/lib/libkern/Makefile.inc"
+.ifndef PROF
+LIBKERN= ${KERNLIB}
+.else
+LIBKERN= ${KERNLIB_PROF}
+.endif
+
+### find out what to use for libcompat
+.include "$S/compat/common/Makefile.inc"
+.ifndef PROF
+LIBCOMPAT= ${COMPATLIB}
+.else
+LIBCOMPAT= ${COMPATLIB_PROF}
+.endif
+
+NORMAL_C= ${CC} -O -c ${CFLAGS} ${PROF} $<
+NORMAL_C_C= ${CC} -c ${CFLAGS} ${PROF} ${PARAM} $<
+NORMAL_S= ${CC} -x assembler-with-cpp -E -I. -DLOCORE ${COPTS} $< | \
+ ${AS} ${ASFLAGS} -o $*.o
+DRIVER_C= ${CC} -c ${CFLAGS} ${PROF} $<
+DRIVER_C_C= ${CC} -c ${CFLAGS} ${PROF} ${PARAM} $<
+SYSTEM_ASMS=intvec.o subr.o
+SYSTEM_OBJS=${SYSTEM_ASMS} lim.o vnode_if.o ${OBJS} param.o ioconf.o \
+ ${LIBKERN} ${LIBCOMPAT}
+#SYSTEM_DEP=${SYSTEM_ASMS} lovm.o pmap.o
+SYSTEM_DEP=${SYSTEM_ASMS} ${SYSTEM_OBJS}
+SYSTEM_LD_HEAD= @echo loading $@; rm -f $@
+SYSTEM_LD= ${LD} -Z -e _start -T ${LOAD_ADDRESS} -o $@ ${SYSTEM_OBJS} vers.o
+#SYSTEM_LD_TAIL= @echo rearranging symbols; symorder symbols.sort $@; ${DBSYM} -f
+SYSTEM_LD_TAIL=@echo Nu {r k{rnan klar!!!!
+
+
+%OBJS
+
+%CFILES
+
+%LOAD
+
+clean::
+ rm -f eddep *vmunix tags *.o subr.i [a-tv-z]*.s \
+ Errs errs linterrs makelinks vnode_if.* genassym
+
+lint: /tmp param.c
+ @lint -hbxn -DGENERIC ${COPTS} ${PARAM} \
+ ${VAX}/vax/Locore.c ${CFILES} ioconf.c param.c | \
+ grep -v 'struct/union .* never defined' | \
+ grep -v 'possible pointer alignment problem'
+
+symbols.sort: ${VAX}/vax/symbols.raw
+ grep -v '^#' ${VAX}/vax/symbols.raw \
+ | sed 's/^ //' | sort -u > symbols.sort
+
+intvec.o: ${VAX}/vax/intvec.s
+ ${CC} -x assembler-with-cpp -E ${AOPTS} ${VAX}/vax/intvec.s| as -o intvec.o
+
+subr.o: ${VAX}/vax/subr.s
+ ${CC} -x assembler-with-cpp -E ${AOPTS} ${VAX}/vax/subr.s| as -o subr.o
+
+
+depend: ${CFILES}
+ mkdep ${COPTS} ${.ALLSRC:M*.c} ioconf.c
+ mkdep -a -p ${INCLUDES} ${IDENT} ${PARAM}
+
+ioconf.o:
+ ${CC} -c ${CFLAGS} ${PARAM} ioconf.c
+
+lim.o: Makefile
+ ../../conf/mkoldconf.awk < ioconf.c > lim.c
+ ${CC} -O -c ${CFLAGS} ${PARAM} lim.c
+
+param.c: $S/conf/param.c
+ rm -f param.c
+ cp $S/conf/param.c .
+
+param.o: param.c Makefile
+ ${CC} -O -c ${CFLAGS} ${PARAM} param.c
+
+conf.o: ${VAX}/vax/conf.c
+ ${CC} -O -c ${CFLAGS} ${PARAM} ${VAX}/vax/conf.c
+
+newvers:
+ sh $S/conf/newvers.sh
+ ${CC} ${CFLAGS} -c vers.c
+
+vnode_if.c vnode_if.h : $S/kern/vnode_if.sh $S/kern/vnode_if.src
+ AWK="${AWK}" sh $S/kern/vnode_if.sh $S/kern/vnode_if.src
+
+
+%RULES
diff --git a/sys/arch/vax/conf/files.vax b/sys/arch/vax/conf/files.vax
new file mode 100644
index 00000000000..52c4ac00ac3
--- /dev/null
+++ b/sys/arch/vax/conf/files.vax
@@ -0,0 +1,252 @@
+# $NetBSD: files.vax,v 1.13 1995/07/24 18:58:36 ragge Exp $
+#
+# new style config file for vax architecture
+#
+
+# maxpartitions must be first item in files.${ARCH}.newconf
+maxpartitions 8
+
+maxusers 8 32 64
+
+device backplane at root { }
+device sbi at backplane { tr=-1 }
+device bi at backplane { node=-1 }
+
+device cpu at backplane, bi, sbi
+device mem at backplane, bi, sbi
+
+file arch/vax/vax/sbi.c sbi needs-flag
+file arch/vax/vax/bi.c bi needs-flag
+
+device mba at sbi { drive = -1 }
+file arch/vax/mba/mba.c mba needs-flag
+
+device hp at mba
+file arch/vax/mba/hp.c hp needs-flag
+major {hp = 0}
+
+device ht at mba
+file arch/vax/mba/ht.c ht needs-flag
+
+device uba at sbi, bi { csr }
+file arch/vax/uba/uba.c uba needs-count
+
+device uda at uba { drive=-1 }
+file arch/vax/uba/uda.c uda needs-count
+
+device de at uba:ifnet, ether
+file arch/vax/if/if_de.c de needs-count
+
+device ra at uda
+file arch/vax/vax/mscp.c ra needs-count
+major {ra = 9}
+
+# TK50/TU81 at UBA
+device tmscp at uba {drive = -1}
+device tms at tmscp
+file arch/vax/uba/tmscp.c tmscp needs-count
+
+# DEQNA/DELQA used on Qbus
+device qe at uba:ifnet, ether
+file arch/vax/if/if_qe.c qe needs-count
+
+# These devices aren't tested (or even compiled!)
+# They are just included here to make some files happy ;)
+#
+
+# Ikonas framebuffer
+device ik at uba
+file arch/vax/uba/ik.c ik needs-count
+
+device vs at uba
+file arch/vax/uba/vs.c vs needs-count
+
+# TU58 on 750/730
+device tu at root
+file arch/vax/vax/tu.c tu needs-count
+
+# RK06/07 on UBA
+device rk at uba
+file arch/vax/uba/rk.c rk needs-count
+
+# TM11/TE10 at UBA
+device te at uba
+file arch/vax/uba/tm.c te needs-count
+
+# TS11 at UBA
+device ts at uba
+file arch/vax/uba/ts.c ts needs-count
+
+# TU78 at MBA
+device mu at mba
+file arch/vax/mba/mt.c mu needs-count
+
+# KDB50 on BI
+device kdb at bi { drive=-1 }
+file arch/vax/bi/kdb.c kdb needs-count
+
+
+# DMF32 on UBA
+device dmf at uba
+file arch/vax/uba/dmf.c dmf needs-count
+file arch/vax/uba/dmz.c dmf needs-count
+
+# DMZ32 on UBA
+device dmz at uba
+file arch/vax/uba/dmx.c dmz needs-count
+
+# DN-11 on UBA
+device dn at uba
+file arch/vax/uba/dn.c dn needs-count
+
+# DZ11 at UBA
+device dz at uba
+file arch/vax/uba/dz.c dz needs-count
+
+# IDC (RB730) on UBA (VAX 11/730)
+device idc at uba { drive=-1 }
+device rb at idc
+file arch/vax/uba/idc.c rb needs-count
+
+# LP-11 at UBA
+device lp at uba
+file arch/vax/uba/lp.c lp needs-count
+
+# ???? at UBA
+device lpa at uba
+file arch/vax/uba/lpa.c lpa needs-count
+
+# PS2 at UBA
+device ps at uba
+file arch/vax/uba/ps.c ps needs-count
+
+# RL02/RL11 at UBA
+device hl at uba { drive=-1 }
+device rl at hl
+file arch/vax/uba/rl.c rl needs-count
+
+# RX211/RX02 at UBA
+device fx at uba { drive=-1 }
+device rx at fx
+file arch/vax/uba/rx.c rx needs-count
+
+# SC-21/SC-31 at UBA
+device sc at uba { drive=-1 }
+device up at sc
+file arch/vax/uba/up.c up needs-count
+
+# TU45 at UBA
+device ut at uba { drive=-1}
+device tj at ut
+file arch/vax/uba/ut.c tj needs-count
+
+# TU58/DECtape II
+device uu at uba
+file arch/vax/uba/uu.c uu needs-count
+
+# Benson-Varian plotter at UBA
+device va at uba { drive=-1}
+device vz at va
+file arch/vax/uba/va.c va needs-count
+
+# Versatec plotter at UBA
+device vp at uba
+file arch/vax/uba/vp.c vp needs-count
+
+# QVSS at UBA
+device qv at uba
+file arch/vax/uba/qv.c qv needs-count
+file arch/vax/uba/qfont.c qv needs-count
+
+# QDSS at UBA
+device qd at uba
+file arch/vax/uba/qd.c qd needs-count
+
+# Interlan NP100 at UBA
+device np at uba
+file arch/vax/if/if_ix.c np needs-count
+file arch/vax/uba/np.c np needs-count
+
+# ACC LH/DH IMP on UBA
+device acc at uba
+file arch/vax/if/if_acc.c acc needs-count
+
+# DR11C at UBA
+device ct at uba
+file arch/vax/uba/ct.c ct needs-count
+
+# A/D-converter on UBA
+device ad at uba
+file arch/vax/uba/ad.c ad needs-count
+
+# DH-11/DM-11 on UBA
+device dh at uba
+file arch/vax/uba/dh.c dh needs-count
+
+# DHU-11 at UBA
+device dhu at uba
+file arch/vax/uba/dhu.c dhu needs-count
+
+# These are general files needed for compilation.
+file dev/cons.c
+file dev/cninit.c
+file arch/vax/vax/locore.c
+file arch/vax/vax/mem.c
+file arch/vax/vax/clock.c
+file arch/vax/vax/gencons.c
+file arch/vax/vax/pmap.c
+file arch/vax/vax/machdep.c
+file arch/vax/vax/ka750.c vax750
+file arch/vax/vax/uvaxII.c vax630
+file arch/vax/vax/emulate.s vax630
+file arch/vax/vax/conf.c
+file arch/vax/vax/urem.s
+file arch/vax/vax/udiv.s
+file arch/vax/vax/rootfil.c
+file arch/vax/vax/trap.c
+
+file arch/vax/vax/vm_machdep.c
+file arch/vax/vax/autoconf.c
+#file arch/vax/vax/cpu_machdep.c
+#file arch/vax/vax/in_cksum.c inet
+file netinet/in_cksum.c inet
+file arch/vax/vax/random.s inet
+file arch/vax/vax/disksubr.c ffs
+file arch/vax/if/if_uba.c de qe
+file arch/vax/vax/db_machdep.c ddb
+file arch/vax/vax/db_disasm.c ddb
+
+# Dom h{ra f}r vara kvar s} l{nge f}r vi se vilka vi beh|ver...
+#arch/vax/vax/crl.c standard
+#arch/vax/vax/dkbad.c standard
+#arch/vax/vax/flp.c standard
+#arch/vax/vax/ka650.c standard
+#arch/vax/vax/ka630.c standard
+#arch/vax/vax/ka730.c standard
+#arch/vax/vax/ka750.c standard
+#arch/vax/vax/ka780.c standard
+#arch/vax/vax/ka820.c standard
+#arch/vax/vax/ka860.c standard
+#arch/vax/vax/kdb_machdep.c optional kadb
+#arch/vax/vax/kdb_opset.c optional kadb
+#arch/vax/vax/ns_cksum.c optional ns
+#arch/vax/vax/rx50.c standard
+#arch/vax/vax/sys_machdep.c standard
+#arch/vax/vax/iidr.o optional ii
+#arch/vax/vax/iidrsys.o optional ii
+#arch/vax/vax/iidr_glob.o optional ii
+#arch/vax/if/if_css.c optional css imp device-driver
+#arch/vax/if/if_dp.c optional dp device-driver
+#arch/vax/if/if_ddn.c optional ddn device-driver
+#arch/vax/if/if_dmc.c optional dmc device-driver
+#arch/vax/if/if_dmv.c optional dmv device-driver
+#arch/vax/if/if_ec.c optional ec device-driver
+#arch/vax/if/if_en.c optional en device-driver
+#arch/vax/if/if_ex.c optional ex device-driver
+#arch/vax/if/if_hdh.c optional hdh device-driver
+#arch/vax/if/if_hy.c optional hy device-driver
+#arch/vax/if/if_il.c optional il device-driver
+#arch/vax/if/if_pcl.c optional pcl device-driver
+##arch/vax/if/if_uba.c optional ns device-driver
+#arch/vax/if/if_vv.c optional vv device-driver
+#arch/vax/if/raw_hy.c optional hy device-driver
diff --git a/sys/arch/vax/conf/mkoldconf.awk b/sys/arch/vax/conf/mkoldconf.awk
new file mode 100644
index 00000000000..2212b4e2103
--- /dev/null
+++ b/sys/arch/vax/conf/mkoldconf.awk
@@ -0,0 +1,155 @@
+#!/usr/bin/awk -f
+#
+# $NetBSD: mkoldconf.awk,v 1.3 1995/03/29 22:50:51 ragge Exp $
+#
+
+/tmscd/{
+ tmsplats[ntms]=$2;
+ tmsaddr[ntms]=$5;
+ ntms++;
+}
+
+/racd/{
+ raplats[nra]=$2;
+ raaddr[nra]=$5;
+ nra++;
+}
+
+/decd/{
+ deplats[nde]=$2;
+ deaddr[nde]=$5;
+ nde++;
+}
+
+/qecd/{
+ qeplats[nqe]=$2;
+ qeaddr[nqe]=$5;
+ nqe++;
+}
+
+{
+ if(savenext==1){
+ l=sprintf("%d",$2)
+ udanummer[l-1]=nuda-1
+ savenext=0;
+ }
+}
+
+
+{
+ if(tmssavenext==1){
+ l=sprintf("%d",$2)
+ tmsnummer[l-1]=ntmscp-1
+ tmssavenext=0;
+ }
+}
+
+/tmscpcd/{
+ tmscpplats[ntmscp]=$2;
+ tmscpaddr[ntmscp]=$5;
+ ntmscp++;
+ tmssavenext=1;
+}
+
+/udacd/{
+ udaplats[nuda]=$2;
+ udaddr[nuda]=$5;
+ nuda++;
+ savenext=1;
+}
+
+
+/};/{
+ k=0;
+ m=0;
+}
+
+{
+ if (k==1){
+ for(i=1;i<NF+1;i++){
+ loc[loccnt+i]=$i;
+ }
+ loccnt+=NF;
+ }
+}
+
+/static int loc/{
+ k=1;
+ loccnt=0;
+}
+
+{
+ if(m==1){
+ for(i=1;i<NF+1;i++){
+ pv[i]=$i;
+ }
+ }
+}
+
+/static short pv/{
+ m=1;
+}
+
+END{
+
+printf "#include \"sys/param.h\"\n"
+printf "#include \"machine/pte.h\"\n"
+printf "#include \"sys/buf.h\"\n"
+printf "#include \"sys/map.h\"\n"
+
+printf "#include \"vax/uba/ubavar.h\"\n"
+
+printf "int antal_ra=%d;\n",nra-1
+printf "int antal_de=%d;\n",nde-1
+printf "int antal_uda=%d;\n",nuda-1
+printf "int antal_tms=%d;\n",ntms-1
+printf "int antal_tmscp=%d;\n",ntmscp-1
+
+printf "extern struct uba_driver udadriver;\n"
+printf "extern struct uba_driver dedriver;\n"
+printf "extern struct uba_driver qedriver;\n"
+if(ntms) printf "extern struct uba_driver tmscpdriver;\n"
+if(ntms) printf "int tmscpintr();\n"
+printf "int deintr();\n"
+printf "int qeintr();\n"
+printf "int udaintr();\n"
+printf "int udacd=0, racd=0, tmscpcd=0, tmscd=0;\n"
+printf "#define C (caddr_t)\n"
+
+printf "struct uba_ctlr ubminit[]={\n"
+for(i=1;i<nuda;i++){
+ k=sprintf("%d",udaddr[i])
+ printf " { &udadriver, %d,0,0,udaintr,C %s},\n",
+ udaplats[i],loc[k+1]
+}
+for(i=1;i<ntmscp;i++){
+ k=sprintf("%d",tmscpaddr[i])
+if(ntms)printf " { &tmscpdriver, %d,'?',0,tmscpintr,C %s},\n",
+ tmscpplats[i],loc[k+1]
+}
+printf "0};\n"
+
+printf "struct uba_device ubdinit[]={\n"
+for(i=1;i<nra;i++){
+ k=sprintf("%d",raaddr[i])
+ printf " { &udadriver,%d,%d,0,%d,0,0,1,0},\n",raplats[i],
+ rr++/4,loc[k+1]
+}
+for(i=1;i<nde;i++){
+ k=sprintf("%d",deaddr[i])
+ printf " {&dedriver,%d,-1,0,-1,deintr,C %s0,0},\n",deplats[i],
+ loc[k+1]
+}
+for(i=1;i<nqe;i++){
+ k=sprintf("%d",qeaddr[i])
+ printf " {&qedriver,%d,-1,0,-1,qeintr,C %s0,0},\n",qeplats[i],
+ loc[k+1]
+}
+for(i=1;i<ntms;i++){
+ k=sprintf("%d",tmsaddr[i])
+ printf " {&tmscpdriver,%d,0,'?',0,0,C 0,1,0},\n",tmsplats[i]
+}
+printf "0};\n"
+
+}
+
diff --git a/sys/arch/vax/conf/std.vax b/sys/arch/vax/conf/std.vax
new file mode 100644
index 00000000000..ba605d9b4c6
--- /dev/null
+++ b/sys/arch/vax/conf/std.vax
@@ -0,0 +1,10 @@
+# $NetBSD: std.vax,v 1.3 1995/02/13 00:41:59 ragge Exp $
+#
+# Std vaxfiles
+#
+machine vax
+
+backplane0 at root
+
+options MAXFDESCS=2048
+options TIMEZONE=-60, DST=1
diff --git a/sys/arch/vax/if/if_de.c b/sys/arch/vax/if/if_de.c
new file mode 100644
index 00000000000..18f01217787
--- /dev/null
+++ b/sys/arch/vax/if/if_de.c
@@ -0,0 +1,723 @@
+/* $NetBSD: if_de.c,v 1.7.2.1 1995/10/15 13:56:24 ragge Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1989 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.
+ *
+ * @(#)if_de.c 7.12 (Berkeley) 12/16/90
+ */
+
+#include "de.h"
+#if NDE > 0
+
+/*
+ * DEC DEUNA interface
+ *
+ * Lou Salkind
+ * New York University
+ *
+ * TODO:
+ * timeout routine (get statistics)
+ */
+
+#include "sys/param.h"
+#include "sys/systm.h"
+#include "sys/mbuf.h"
+#include "sys/buf.h"
+#include "sys/protosw.h"
+#include "sys/socket.h"
+/* #include "sys/vmmac.h" */
+#include "sys/ioctl.h"
+#include "sys/errno.h"
+#include "sys/syslog.h"
+#include "sys/device.h"
+
+#include "vax/include/pte.h"
+#include "vax/include/sid.h"
+
+#include "net/if.h"
+#include "net/netisr.h"
+#include "net/route.h"
+
+#ifdef INET
+#include "netinet/in.h"
+#include "netinet/in_systm.h"
+#include "netinet/in_var.h"
+#include "netinet/ip.h"
+#include "netinet/if_ether.h"
+#endif
+
+#ifdef NS
+#include "netns/ns.h"
+#include "netns/ns_if.h"
+#endif
+
+#ifdef ISO
+#include "netiso/iso.h"
+#include "netiso/iso_var.h"
+extern char all_es_snpa[], all_is_snpa[];
+#endif
+
+#include "../include/cpu.h"
+#include "../include/mtpr.h"
+#include "if_dereg.h"
+#include "if_uba.h"
+#include "../uba/ubareg.h"
+#include "../uba/ubavar.h"
+
+#define NXMT 3 /* number of transmit buffers */
+#define NRCV 7 /* number of receive buffers (must be > 1) */
+
+int dedebug = 0;
+
+
+int deprobe(), deattach(), deintr();
+struct uba_device *deinfo[NDE];
+u_short destd[] = { 0 };
+struct uba_driver dedriver =
+ { deprobe, 0, deattach, 0, destd, "de", deinfo };
+int deinit(),deioctl(),dereset();
+void destart();
+
+
+/*
+ * Ethernet software status per interface.
+ *
+ * Each interface is referenced by a network interface structure,
+ * ds_if, which the routing code uses to locate the interface.
+ * This structure contains the output queue for the interface, its address, ...
+ * We also have, for each interface, a UBA interface structure, which
+ * contains information about the UNIBUS resources held by the interface:
+ * map registers, buffered data paths, etc. Information is cached in this
+ * structure for use by the if_uba.c routines in running the interface
+ * efficiently.
+ */
+struct de_softc {
+ struct arpcom ds_ac; /* Ethernet common part */
+#define ds_if ds_ac.ac_if /* network-visible interface */
+#define ds_addr ds_ac.ac_enaddr /* hardware Ethernet address */
+ int ds_flags;
+#define DSF_RUNNING 2 /* board is enabled */
+#define DSF_SETADDR 4 /* physical address is changed */
+ int ds_ubaddr; /* map info for incore structs */
+ struct ifubinfo ds_deuba; /* unibus resource structure */
+ struct ifrw ds_ifr[NRCV]; /* unibus receive maps */
+ struct ifxmt ds_ifw[NXMT]; /* unibus xmt maps */
+ /* the following structures are always mapped in */
+ struct de_pcbb ds_pcbb; /* port control block */
+ struct de_ring ds_xrent[NXMT]; /* transmit ring entrys */
+ struct de_ring ds_rrent[NRCV]; /* receive ring entrys */
+ struct de_udbbuf ds_udbbuf; /* UNIBUS data buffer */
+ /* end mapped area */
+#define INCORE_BASE(p) ((char *)&(p)->ds_pcbb)
+#define RVAL_OFF(n) ((char *)&de_softc[0].n - INCORE_BASE(&de_softc[0]))
+#define LVAL_OFF(n) ((char *)de_softc[0].n - INCORE_BASE(&de_softc[0]))
+#define PCBB_OFFSET RVAL_OFF(ds_pcbb)
+#define XRENT_OFFSET LVAL_OFF(ds_xrent)
+#define RRENT_OFFSET LVAL_OFF(ds_rrent)
+#define UDBBUF_OFFSET RVAL_OFF(ds_udbbuf)
+#define INCORE_SIZE RVAL_OFF(ds_xindex)
+ int ds_xindex; /* UNA index into transmit chain */
+ int ds_rindex; /* UNA index into receive chain */
+ int ds_xfree; /* index for next transmit buffer */
+ int ds_nxmit; /* # of transmits in progress */
+} de_softc[NDE];
+
+deprobe(reg)
+ caddr_t reg;
+{
+ register int br, cvec; /* r11, r10 value-result */
+ volatile struct dedevice *addr = (struct dedevice *)reg;
+ register i;
+
+#ifdef lint
+ br = 0; cvec = br; br = cvec;
+ i = 0; derint(i); deintr(i);
+#endif
+
+ /*
+ * Make sure self-test is finished before we screw with the board.
+ * Self-test on a DELUA can take 15 seconds (argh).
+ */
+ for (i = 0;
+ i < 160 &&
+ (addr->pcsr0 & PCSR0_FATI) == 0 &&
+ (addr->pcsr1 & PCSR1_STMASK) == STAT_RESET;
+ ++i)
+ waitabit(10);
+ if ((addr->pcsr0 & PCSR0_FATI) != 0 ||
+ (addr->pcsr1 & PCSR1_STMASK) != STAT_READY &&
+ (addr->pcsr1 & PCSR1_STMASK) != STAT_RUN)
+ return(0);
+
+ addr->pcsr0 = 0;
+ waitabit(1);
+ addr->pcsr0 = PCSR0_RSET;
+ while ((addr->pcsr0 & PCSR0_INTR) == 0)
+ ;
+ /* make board interrupt by executing a GETPCBB command */
+ addr->pcsr0 = PCSR0_INTE;
+ addr->pcsr2 = 0;
+ addr->pcsr3 = 0;
+ addr->pcsr0 = PCSR0_INTE|CMD_GETPCBB;
+ waitabit(10);
+ return(1);
+}
+
+/*
+ * Interface exists: make available by filling in network interface
+ * record. System will initialize the interface when it is ready
+ * to accept packets. We get the ethernet address here.
+ */
+deattach(ui)
+ struct uba_device *ui;
+{
+ register struct de_softc *ds = &de_softc[ui->ui_unit];
+ register struct ifnet *ifp = &ds->ds_if;
+ volatile struct dedevice *addr = (struct dedevice *)ui->ui_addr;
+ int csr1;
+
+ ifp->if_unit = ui->ui_unit;
+ ifp->if_name = "de";
+ ifp->if_flags = IFF_BROADCAST | IFF_NOTRAILERS;
+
+ /*
+ * What kind of a board is this?
+ * The error bits 4-6 in pcsr1 are a device id as long as
+ * the high byte is zero.
+ */
+ csr1 = addr->pcsr1;
+ if (csr1 & 0xff60)
+ printf("de%d: broken\n", ui->ui_unit);
+ else if (csr1 & 0x10)
+ printf("de%d: delua\n", ui->ui_unit);
+ else
+ printf("de%d: deuna\n", ui->ui_unit);
+
+ /*
+ * Reset the board and temporarily map
+ * the pcbb buffer onto the Unibus.
+ */
+ addr->pcsr0 = 0; /* reset INTE */
+ waitabit(1);
+ addr->pcsr0 = PCSR0_RSET;
+ (void)dewait(ui, "reset");
+
+ ds->ds_ubaddr = uballoc(ui->ui_ubanum, (char *)&ds->ds_pcbb,
+ sizeof (struct de_pcbb), 0);
+ addr->pcsr2 = ds->ds_ubaddr & 0xffff;
+ addr->pcsr3 = (ds->ds_ubaddr >> 16) & 0x3;
+ addr->pclow = CMD_GETPCBB;
+ (void)dewait(ui, "pcbb");
+
+ ds->ds_pcbb.pcbb0 = FC_RDPHYAD;
+ addr->pclow = CMD_GETCMD;
+ (void)dewait(ui, "read addr ");
+
+ ubarelse(ui->ui_ubanum, &ds->ds_ubaddr);
+ bcopy((caddr_t)&ds->ds_pcbb.pcbb2, (caddr_t)ds->ds_addr,
+ sizeof (ds->ds_addr));
+ printf("de%d: hardware address %s\n", ui->ui_unit,
+ ether_sprintf(ds->ds_addr));
+ ifp->if_ioctl = deioctl;
+ ifp->if_reset = dereset;
+ ifp->if_start = destart;
+ ds->ds_deuba.iff_flags = UBA_CANTWAIT;
+#ifdef notdef
+ /* CAN WE USE BDP's ??? */
+ ds->ds_deuba.iff_flags |= UBA_NEEDBDP;
+#endif
+ if_attach(ifp);
+ ether_ifattach(ifp);
+}
+
+/*
+ * Reset of interface after UNIBUS reset.
+ * If interface is on specified uba, reset its state.
+ */
+dereset(unit, uban)
+ int unit, uban;
+{
+ register struct uba_device *ui;
+
+ if (unit >= NDE || (ui = deinfo[unit]) == 0 || ui->ui_alive == 0 ||
+ ui->ui_ubanum != uban)
+ return;
+ printf(" de%d", unit);
+ de_softc[unit].ds_if.if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
+ de_softc[unit].ds_flags &= ~DSF_RUNNING;
+ ((struct dedevice *)ui->ui_addr)->pcsr0 = PCSR0_RSET;
+ (void)dewait(ui, "reset");
+ deinit(unit);
+}
+
+/*
+ * Initialization of interface; clear recorded pending
+ * operations, and reinitialize UNIBUS usage.
+ */
+deinit(unit)
+ int unit;
+{
+ struct de_softc *ds;
+ struct uba_device *ui;
+ volatile struct dedevice *addr;
+ struct ifrw *ifrw;
+ struct ifxmt *ifxp;
+ struct ifnet *ifp;
+ struct de_ring *rp;
+ int s,incaddr;
+
+ ds = &de_softc[unit];
+ ui = deinfo[unit];
+ ifp = &ds->ds_if;
+
+ /* not yet, if address still unknown */
+ if (ifp->if_addrlist.tqh_first == (struct ifaddr *)0)
+ return;
+
+ if (ds->ds_flags & DSF_RUNNING)
+ return;
+ if ((ifp->if_flags & IFF_RUNNING) == 0) {
+ if (if_ubaminit(&ds->ds_deuba, ui->ui_ubanum,
+ sizeof (struct ether_header), (int)btoc(ETHERMTU),
+ ds->ds_ifr, NRCV, ds->ds_ifw, NXMT) == 0) {
+ printf("de%d: can't initialize\n", unit);
+ ds->ds_if.if_flags &= ~IFF_UP;
+ return;
+ }
+ ds->ds_ubaddr = uballoc(ui->ui_ubanum, INCORE_BASE(ds),
+ INCORE_SIZE, 0);
+ }
+ addr = (struct dedevice *)ui->ui_addr;
+
+ /* set the pcbb block address */
+ incaddr = ds->ds_ubaddr + PCBB_OFFSET;
+ addr->pcsr2 = incaddr & 0xffff;
+ addr->pcsr3 = (incaddr >> 16) & 0x3;
+ addr->pclow = 0; /* reset INTE */
+ waitabit(1);
+ addr->pclow = CMD_GETPCBB;
+ (void)dewait(ui, "pcbb");
+
+ /* set the transmit and receive ring header addresses */
+ incaddr = ds->ds_ubaddr + UDBBUF_OFFSET;
+ ds->ds_pcbb.pcbb0 = FC_WTRING;
+ ds->ds_pcbb.pcbb2 = incaddr & 0xffff;
+ ds->ds_pcbb.pcbb4 = (incaddr >> 16) & 0x3;
+
+ incaddr = ds->ds_ubaddr + XRENT_OFFSET;
+ ds->ds_udbbuf.b_tdrbl = incaddr & 0xffff;
+ ds->ds_udbbuf.b_tdrbh = (incaddr >> 16) & 0x3;
+ ds->ds_udbbuf.b_telen = sizeof (struct de_ring) / sizeof (short);
+ ds->ds_udbbuf.b_trlen = NXMT;
+ incaddr = ds->ds_ubaddr + RRENT_OFFSET;
+ ds->ds_udbbuf.b_rdrbl = incaddr & 0xffff;
+ ds->ds_udbbuf.b_rdrbh = (incaddr >> 16) & 0x3;
+ ds->ds_udbbuf.b_relen = sizeof (struct de_ring) / sizeof (short);
+ ds->ds_udbbuf.b_rrlen = NRCV;
+
+ addr->pclow = CMD_GETCMD;
+ (void)dewait(ui, "wtring");
+
+ /* initialize the mode - enable hardware padding */
+ ds->ds_pcbb.pcbb0 = FC_WTMODE;
+ /* let hardware do padding - set MTCH bit on broadcast */
+ ds->ds_pcbb.pcbb2 = MOD_TPAD|MOD_HDX;
+ addr->pclow = CMD_GETCMD;
+ (void)dewait(ui, "wtmode");
+
+ /* set up the receive and transmit ring entries */
+ ifxp = &ds->ds_ifw[0];
+ for (rp = &ds->ds_xrent[0]; rp < &ds->ds_xrent[NXMT]; rp++) {
+ rp->r_segbl = ifxp->ifw_info & 0xffff;
+ rp->r_segbh = (ifxp->ifw_info >> 16) & 0x3;
+ rp->r_flags = 0;
+ ifxp++;
+ }
+ ifrw = &ds->ds_ifr[0];
+ for (rp = &ds->ds_rrent[0]; rp < &ds->ds_rrent[NRCV]; rp++) {
+ rp->r_slen = sizeof (struct de_buf);
+ rp->r_segbl = ifrw->ifrw_info & 0xffff;
+ rp->r_segbh = (ifrw->ifrw_info >> 16) & 0x3;
+ rp->r_flags = RFLG_OWN; /* hang receive */
+ ifrw++;
+ }
+
+ /* start up the board (rah rah) */
+ s = splimp();
+ ds->ds_rindex = ds->ds_xindex = ds->ds_xfree = ds->ds_nxmit = 0;
+ ds->ds_if.if_flags |= IFF_RUNNING;
+ addr->pclow = PCSR0_INTE; /* avoid interlock */
+ destart(&ds->ds_if); /* queue output packets */
+ ds->ds_flags |= DSF_RUNNING; /* need before de_setaddr */
+ if (ds->ds_flags & DSF_SETADDR)
+ de_setaddr(ds->ds_addr, unit);
+ addr->pclow = CMD_START | PCSR0_INTE;
+ splx(s);
+}
+
+/*
+ * Setup output on interface.
+ * Get another datagram to send off of the interface queue,
+ * and map it to the interface before starting the output.
+ * Must be called from ipl >= our interrupt level.
+ */
+void
+destart(ifp)
+ struct ifnet *ifp;
+{
+ int len;
+ int unit = ifp->if_unit;
+ struct uba_device *ui = deinfo[unit];
+ volatile struct dedevice *addr = (struct dedevice *)ui->ui_addr;
+ register struct de_softc *ds = &de_softc[unit];
+ register struct de_ring *rp;
+ struct mbuf *m;
+ register int nxmit;
+
+ /*
+ * the following test is necessary, since
+ * the code is not reentrant and we have
+ * multiple transmission buffers.
+ */
+ if (ds->ds_if.if_flags & IFF_OACTIVE)
+ return;
+ for (nxmit = ds->ds_nxmit; nxmit < NXMT; nxmit++) {
+ IF_DEQUEUE(&ds->ds_if.if_snd, m);
+ if (m == 0)
+ break;
+ rp = &ds->ds_xrent[ds->ds_xfree];
+ if (rp->r_flags & XFLG_OWN)
+ panic("deuna xmit in progress");
+ len = if_ubaput(&ds->ds_deuba, &ds->ds_ifw[ds->ds_xfree], m);
+ if (ds->ds_deuba.iff_flags & UBA_NEEDBDP)
+ UBAPURGE(ds->ds_deuba.iff_uba,
+ ds->ds_ifw[ds->ds_xfree].ifw_bdp);
+ rp->r_slen = len;
+ rp->r_tdrerr = 0;
+ rp->r_flags = XFLG_STP|XFLG_ENP|XFLG_OWN;
+
+ ds->ds_xfree++;
+ if (ds->ds_xfree == NXMT)
+ ds->ds_xfree = 0;
+ }
+ if (ds->ds_nxmit != nxmit) {
+ ds->ds_nxmit = nxmit;
+ if (ds->ds_flags & DSF_RUNNING)
+ addr->pclow = PCSR0_INTE|CMD_PDMD;
+ }
+}
+
+/*
+ * Command done interrupt.
+ */
+deintr(uba,vector,level,unit)
+{
+ struct uba_device *ui;
+ volatile struct dedevice *addr;
+ register struct de_softc *ds;
+ register struct de_ring *rp;
+ register struct ifxmt *ifxp;
+ short csr0;
+
+ ui = deinfo[unit];
+ addr = (struct dedevice *)ui->ui_addr;
+ ds = &de_softc[unit];
+
+
+ /* save flags right away - clear out interrupt bits */
+ csr0 = addr->pcsr0;
+ addr->pchigh = csr0 >> 8;
+
+
+ ds->ds_if.if_flags |= IFF_OACTIVE; /* prevent entering destart */
+ /*
+ * if receive, put receive buffer on mbuf
+ * and hang the request again
+ */
+ derecv(unit);
+
+ /*
+ * Poll transmit ring and check status.
+ * Be careful about loopback requests.
+ * Then free buffer space and check for
+ * more transmit requests.
+ */
+ for ( ; ds->ds_nxmit > 0; ds->ds_nxmit--) {
+ rp = &ds->ds_xrent[ds->ds_xindex];
+ if (rp->r_flags & XFLG_OWN)
+ break;
+ ds->ds_if.if_opackets++;
+ ifxp = &ds->ds_ifw[ds->ds_xindex];
+ /* check for unusual conditions */
+ if (rp->r_flags & (XFLG_ERRS|XFLG_MTCH|XFLG_ONE|XFLG_MORE)) {
+ if (rp->r_flags & XFLG_ERRS) {
+ /* output error */
+ ds->ds_if.if_oerrors++;
+ if (dedebug)
+ printf("de%d: oerror, flags=%b tdrerr=%b (len=%d)\n",
+ unit, rp->r_flags, XFLG_BITS,
+ rp->r_tdrerr, XERR_BITS, rp->r_slen);
+ } else if (rp->r_flags & XFLG_ONE) {
+ /* one collision */
+ ds->ds_if.if_collisions++;
+ } else if (rp->r_flags & XFLG_MORE) {
+ /* more than one collision */
+ ds->ds_if.if_collisions += 2; /* guess */
+ } else if (rp->r_flags & XFLG_MTCH) {
+ /* received our own packet */
+ ds->ds_if.if_ipackets++;
+ deread(ds, &ifxp->ifrw,
+ rp->r_slen - sizeof (struct ether_header));
+ }
+ }
+ if (ifxp->ifw_xtofree) {
+ m_freem(ifxp->ifw_xtofree);
+ ifxp->ifw_xtofree = 0;
+ }
+ /* check if next transmit buffer also finished */
+ ds->ds_xindex++;
+ if (ds->ds_xindex == NXMT)
+ ds->ds_xindex = 0;
+ }
+ ds->ds_if.if_flags &= ~IFF_OACTIVE;
+ destart(&ds->ds_if);
+
+ if (csr0 & PCSR0_RCBI) {
+ if (dedebug)
+ log(LOG_WARNING, "de%d: buffer unavailable\n", unit);
+ addr->pclow = PCSR0_INTE|CMD_PDMD;
+ }
+}
+
+/*
+ * Ethernet interface receiver interface.
+ * If input error just drop packet.
+ * Otherwise purge input buffered data path and examine
+ * packet to determine type. If can't determine length
+ * from type, then have to drop packet. Othewise decapsulate
+ * packet based on type and pass to type specific higher-level
+ * input routine.
+ */
+derecv(unit)
+ int unit;
+{
+ register struct de_softc *ds = &de_softc[unit];
+ register struct de_ring *rp;
+ int len;
+
+ rp = &ds->ds_rrent[ds->ds_rindex];
+ while ((rp->r_flags & RFLG_OWN) == 0) {
+ ds->ds_if.if_ipackets++;
+ if (ds->ds_deuba.iff_flags & UBA_NEEDBDP)
+ UBAPURGE(ds->ds_deuba.iff_uba,
+ ds->ds_ifr[ds->ds_rindex].ifrw_bdp);
+ len = (rp->r_lenerr&RERR_MLEN) - sizeof (struct ether_header)
+ - 4; /* don't forget checksum! */
+ /* check for errors */
+ if ((rp->r_flags & (RFLG_ERRS|RFLG_FRAM|RFLG_OFLO|RFLG_CRC)) ||
+ (rp->r_flags&(RFLG_STP|RFLG_ENP)) != (RFLG_STP|RFLG_ENP) ||
+ (rp->r_lenerr & (RERR_BUFL|RERR_UBTO|RERR_NCHN)) ||
+ len < ETHERMIN || len > ETHERMTU) {
+ ds->ds_if.if_ierrors++;
+ if (dedebug)
+ printf("de%d: ierror, flags=%b lenerr=%b (len=%d)\n",
+ unit, rp->r_flags, RFLG_BITS, rp->r_lenerr,
+ RERR_BITS, len);
+ } else
+ deread(ds, &ds->ds_ifr[ds->ds_rindex], len);
+
+ /* hang the receive buffer again */
+ rp->r_lenerr = 0;
+ rp->r_flags = RFLG_OWN;
+
+ /* check next receive buffer */
+ ds->ds_rindex++;
+ if (ds->ds_rindex == NRCV)
+ ds->ds_rindex = 0;
+ rp = &ds->ds_rrent[ds->ds_rindex];
+ }
+}
+
+/*
+ * Pass a packet to the higher levels.
+ * We deal with the trailer protocol here.
+ */
+deread(ds, ifrw, len)
+ register struct de_softc *ds;
+ struct ifrw *ifrw;
+ int len;
+{
+ struct ether_header *eh;
+ struct mbuf *m;
+ int s;
+ register struct ifqueue *inq;
+
+ /*
+ * Deal with trailer protocol: if type is trailer type
+ * get true type from first 16-bit word past data.
+ * Remember that type was trailer by setting off.
+ */
+ eh = (struct ether_header *)ifrw->ifrw_addr;
+/* eh->ether_type = ntohs((u_short)eh->ether_type); */
+ if (len == 0)
+ return;
+
+ /*
+ * Pull packet off interface. Off is nonzero if packet
+ * has trailing header; if_ubaget will then force this header
+ * information to be at the front.
+ */
+ m = if_ubaget(&ds->ds_deuba, ifrw, len, &ds->ds_if);
+ if (m)
+ ether_input(&ds->ds_if, eh, m);
+}
+/*
+ * Process an ioctl request.
+ */
+deioctl(ifp, cmd, data)
+ register struct ifnet *ifp;
+ int cmd;
+ caddr_t data;
+{
+ register struct ifaddr *ifa = (struct ifaddr *)data;
+ register struct de_softc *ds = &de_softc[ifp->if_unit];
+ int s = splimp(), error = 0;
+
+ switch (cmd) {
+
+ case SIOCSIFADDR:
+ ifp->if_flags |= IFF_UP;
+ deinit(ifp->if_unit);
+
+ switch (ifa->ifa_addr->sa_family) {
+#ifdef INET
+ case AF_INET:
+ arp_ifinit(&ds->ds_ac, ifa);
+ break;
+#endif
+#ifdef NS
+ case AF_NS:
+ {
+ register struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr);
+
+ if (ns_nullhost(*ina))
+ ina->x_host = *(union ns_host *)(ds->ds_addr);
+ else
+ de_setaddr(ina->x_host.c_host,ifp->if_unit);
+ break;
+ }
+#endif
+ }
+ break;
+
+ case SIOCSIFFLAGS:
+ if ((ifp->if_flags & IFF_UP) == 0 &&
+ ds->ds_flags & DSF_RUNNING) {
+ ((struct dedevice *)
+ (deinfo[ifp->if_unit]->ui_addr))->pclow = 0;
+ waitabit(1);
+ ((struct dedevice *)
+ (deinfo[ifp->if_unit]->ui_addr))->pclow = PCSR0_RSET;
+ ds->ds_flags &= ~DSF_RUNNING;
+ ds->ds_if.if_flags &= ~IFF_OACTIVE;
+ } else if (ifp->if_flags & IFF_UP &&
+ (ds->ds_flags & DSF_RUNNING) == 0)
+ deinit(ifp->if_unit);
+ break;
+
+ default:
+ error = EINVAL;
+ }
+ splx(s);
+ return (error);
+}
+
+/*
+ * set ethernet address for unit
+ */
+de_setaddr(physaddr, unit)
+ u_char *physaddr;
+ int unit;
+{
+ register struct de_softc *ds = &de_softc[unit];
+ struct uba_device *ui = deinfo[unit];
+ volatile struct dedevice *addr= (struct dedevice *)ui->ui_addr;
+
+ if (! (ds->ds_flags & DSF_RUNNING))
+ return;
+
+ bcopy((caddr_t) physaddr, (caddr_t) &ds->ds_pcbb.pcbb2, 6);
+ ds->ds_pcbb.pcbb0 = FC_WTPHYAD;
+ addr->pclow = PCSR0_INTE|CMD_GETCMD;
+ if (dewait(ui, "address change") == 0) {
+ ds->ds_flags |= DSF_SETADDR;
+ bcopy((caddr_t) physaddr, (caddr_t) ds->ds_addr, 6);
+ }
+}
+
+/*
+ * Await completion of the named function
+ * and check for errors.
+ */
+dewait(ui, fn)
+ register struct uba_device *ui;
+ char *fn;
+{
+ volatile struct dedevice *addr = (struct dedevice *)ui->ui_addr;
+ register csr0;
+
+ while ((addr->pcsr0 & PCSR0_INTR) == 0)
+ ;
+ csr0 = addr->pcsr0;
+ addr->pchigh = csr0 >> 8;
+ if (csr0 & PCSR0_PCEI)
+ printf("de%d: %s failed, csr0=%b csr1=%b\n",
+ ui->ui_unit, fn, csr0, PCSR0_BITS,
+ addr->pcsr1, PCSR1_BITS);
+ return (csr0 & PCSR0_PCEI);
+}
+
+de_match(){
+ printf("de_match\n");
+ return 0;
+}
+
+void
+de_attach(){
+ printf("de_attach\n");
+}
+
+struct cfdriver decd =
+ { NULL,"de",de_match, de_attach, DV_IFNET, sizeof(struct uba_driver) };
+
+
+#endif
diff --git a/sys/arch/vax/if/if_dereg.h b/sys/arch/vax/if/if_dereg.h
new file mode 100644
index 00000000000..2f2b48c9796
--- /dev/null
+++ b/sys/arch/vax/if/if_dereg.h
@@ -0,0 +1,220 @@
+/* $NetBSD: if_dereg.h,v 1.2 1994/10/26 08:01:51 cgd Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986 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.
+ *
+ * @(#)if_dereg.h 7.3 (Berkeley) 6/28/90
+ */
+
+/*
+ * DEC DEUNA interface
+ */
+struct dedevice {
+ union {
+ short p0_w;
+ char p0_b[2];
+ } u_p0;
+#define pcsr0 u_p0.p0_w
+#define pclow u_p0.p0_b[0]
+#define pchigh u_p0.p0_b[1]
+ short pcsr1;
+ short pcsr2;
+ short pcsr3;
+};
+
+/*
+ * PCSR 0 bit descriptions
+ */
+#define PCSR0_SERI 0x8000 /* Status error interrupt */
+#define PCSR0_PCEI 0x4000 /* Port command error interrupt */
+#define PCSR0_RXI 0x2000 /* Receive done interrupt */
+#define PCSR0_TXI 0x1000 /* Transmit done interrupt */
+#define PCSR0_DNI 0x0800 /* Done interrupt */
+#define PCSR0_RCBI 0x0400 /* Receive buffer unavail intrpt */
+#define PCSR0_FATI 0x0100 /* Fatal error interrupt */
+#define PCSR0_INTR 0x0080 /* Interrupt summary */
+#define PCSR0_INTE 0x0040 /* Interrupt enable */
+#define PCSR0_RSET 0x0020 /* DEUNA reset */
+#define PCSR0_CMASK 0x000f /* command mask */
+
+#define PCSR0_BITS "\20\20SERI\17PCEI\16RXI\15TXI\14DNI\13RCBI\11FATI\10INTR\7INTE\6RSET"
+
+/* bits 0-3 are for the PORT_COMMAND */
+#define CMD_NOOP 0x0
+#define CMD_GETPCBB 0x1 /* Get PCB Block */
+#define CMD_GETCMD 0x2 /* Execute command in PCB */
+#define CMD_STEST 0x3 /* Self test mode */
+#define CMD_START 0x4 /* Reset xmit and receive ring ptrs */
+#define CMD_BOOT 0x5 /* Boot DEUNA */
+#define CMD_PDMD 0x8 /* Polling demand */
+#define CMD_TMRO 0x9 /* Sanity timer on */
+#define CMD_TMRF 0xa /* Sanity timer off */
+#define CMD_RSTT 0xb /* Reset sanity timer */
+#define CMD_STOP 0xf /* Suspend operation */
+
+/*
+ * PCSR 1 bit descriptions
+ */
+#define PCSR1_XPWR 0x8000 /* Transceiver power BAD */
+#define PCSR1_ICAB 0x4000 /* Interconnect cabling BAD */
+#define PCSR1_STCODE 0x3f00 /* Self test error code */
+#define PCSR1_PCTO 0x0080 /* Port command timed out */
+#define PCSR1_ILLINT 0x0040 /* Illegal interrupt */
+#define PCSR1_TIMEOUT 0x0020 /* Timeout */
+#define PCSR1_POWER 0x0010 /* Power fail */
+#define PCSR1_RMTC 0x0008 /* Remote console reserved */
+#define PCSR1_STMASK 0x0007 /* State */
+
+/* bit 0-3 are for STATE */
+#define STAT_RESET 0x0
+#define STAT_PRIMLD 0x1 /* Primary load */
+#define STAT_READY 0x2
+#define STAT_RUN 0x3
+#define STAT_UHALT 0x5 /* UNIBUS halted */
+#define STAT_NIHALT 0x6 /* NI halted */
+#define STAT_NIUHALT 0x7 /* NI and UNIBUS Halted */
+
+#define PCSR1_BITS "\20\20XPWR\17ICAB\10PCTO\7ILLINT\6TIMEOUT\5POWER\4RMTC"
+
+/*
+ * Port Control Block Base
+ */
+struct de_pcbb {
+ short pcbb0; /* function */
+ short pcbb2; /* command specific */
+ short pcbb4;
+ short pcbb6;
+};
+
+/* PCBB function codes */
+#define FC_NOOP 0x00 /* NO-OP */
+#define FC_LSUADDR 0x01 /* Load and start microaddress */
+#define FC_RDDEFAULT 0x02 /* Read default physical address */
+#define FC_RDPHYAD 0x04 /* Read physical address */
+#define FC_WTPHYAD 0x05 /* Write physical address */
+#define FC_RDMULTI 0x06 /* Read multicast address list */
+#define FC_WTMULTI 0x07 /* Read multicast address list */
+#define FC_RDRING 0x08 /* Read ring format */
+#define FC_WTRING 0x09 /* Write ring format */
+#define FC_RDCNTS 0x0a /* Read counters */
+#define FC_RCCNTS 0x0b /* Read and clear counters */
+#define FC_RDMODE 0x0c /* Read mode */
+#define FC_WTMODE 0x0d /* Write mode */
+#define FC_RDSTATUS 0x0e /* Read port status */
+#define FC_RCSTATUS 0x0f /* Read and clear port status */
+#define FC_DUMPMEM 0x10 /* Dump internal memory */
+#define FC_LOADMEM 0x11 /* Load internal memory */
+#define FC_RDSYSID 0x12 /* Read system ID parameters */
+#define FC_WTSYSID 0x13 /* Write system ID parameters */
+#define FC_RDSERAD 0x14 /* Read load server address */
+#define FC_WTSERAD 0x15 /* Write load server address */
+
+/*
+ * Unibus Data Block Base (UDBB) for ring buffers
+ */
+struct de_udbbuf {
+ short b_tdrbl; /* Transmit desc ring base low 16 bits */
+ char b_tdrbh; /* Transmit desc ring base high 2 bits */
+ char b_telen; /* Length of each transmit entry */
+ short b_trlen; /* Number of entries in the XMIT desc ring */
+ short b_rdrbl; /* Receive desc ring base low 16 bits */
+ char b_rdrbh; /* Receive desc ring base high 2 bits */
+ char b_relen; /* Length of each receive entry */
+ short b_rrlen; /* Number of entries in the RECV desc ring */
+};
+
+/*
+ * Transmit/Receive Ring Entry
+ */
+struct de_ring {
+ short r_slen; /* Segment length */
+ short r_segbl; /* Segment address (low 16 bits) */
+ char r_segbh; /* Segment address (hi 2 bits) */
+ u_char r_flags; /* Status flags */
+ u_short r_tdrerr; /* Errors */
+#define r_lenerr r_tdrerr
+ short r_rid; /* Request ID */
+};
+
+#define XFLG_OWN 0x80 /* If 0 then owned by driver */
+#define XFLG_ERRS 0x40 /* Error summary */
+#define XFLG_MTCH 0x20 /* Address match on xmit request */
+#define XFLG_MORE 0x10 /* More than one entry required */
+#define XFLG_ONE 0x08 /* One collision encountered */
+#define XFLG_DEF 0x04 /* Transmit deferred */
+#define XFLG_STP 0x02 /* Start of packet */
+#define XFLG_ENP 0x01 /* End of packet */
+
+#define XFLG_BITS "\10\10OWN\7ERRS\6MTCH\5MORE\4ONE\3DEF\2STP\1ENP"
+
+#define XERR_BUFL 0x8000 /* Buffer length error */
+#define XERR_UBTO 0x4000 /* UNIBUS tiemout
+#define XERR_LCOL 0x1000 /* Late collision */
+#define XERR_LCAR 0x0800 /* Loss of carrier */
+#define XERR_RTRY 0x0400 /* Failed after 16 retries */
+#define XERR_TDR 0x03ff /* TDR value */
+
+#define XERR_BITS "\20\20BUFL\17UBTO\15LCOL\14LCAR\13RTRY"
+
+#define RFLG_OWN 0x80 /* If 0 then owned by driver */
+#define RFLG_ERRS 0x40 /* Error summary */
+#define RFLG_FRAM 0x20 /* Framing error */
+#define RFLG_OFLO 0x10 /* Message overflow */
+#define RFLG_CRC 0x08 /* CRC error */
+#define RFLG_STP 0x02 /* Start of packet */
+#define RFLG_ENP 0x01 /* End of packet */
+
+#define RFLG_BITS "\10\10OWN\7ERRS\6FRAM\5OFLO\4CRC\2STP\1ENP"
+
+#define RERR_BUFL 0x8000 /* Buffer length error */
+#define RERR_UBTO 0x4000 /* UNIBUS tiemout */
+#define RERR_NCHN 0x2000 /* No data chaining */
+#define RERR_MLEN 0x0fff /* Message length */
+
+#define RERR_BITS "\20\20BUFL\17UBTO\16NCHN"
+
+/* mode description bits */
+#define MOD_HDX 0x0001 /* Half duplex mode */
+#define MOD_LOOP 0x0004 /* Enable internal loopback */
+#define MOD_DTCR 0x0008 /* Disables CRC generation */
+#define MOD_DMNT 0x0200 /* Disable maintenance features */
+#define MOD_ECT 0x0400 /* Enable collision test */
+#define MOD_TPAD 0x1000 /* Transmit message pad enable */
+#define MOD_DRDC 0x2000 /* Disable data chaining */
+#define MOD_ENAL 0x4000 /* Enable all multicast */
+#define MOD_PROM 0x8000 /* Enable promiscuous mode */
+
+struct de_buf {
+ struct ether_header db_head; /* header */
+ char db_data[ETHERMTU]; /* packet data */
+ int db_crc; /* CRC - on receive only */
+};
diff --git a/sys/arch/vax/if/if_qe.c b/sys/arch/vax/if/if_qe.c
new file mode 100644
index 00000000000..fbf584fd09e
--- /dev/null
+++ b/sys/arch/vax/if/if_qe.c
@@ -0,0 +1,975 @@
+/* $NetBSD: if_qe.c,v 1.4.2.1 1995/10/15 13:56:26 ragge Exp $ */
+/*
+ * Copyright (c) 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Digital Equipment Corp.
+ *
+ * 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.
+ *
+ * @(#)if_qe.c 7.20 (Berkeley) 3/28/91
+ */
+
+/* from @(#)if_qe.c 1.15 (ULTRIX) 4/16/86 */
+
+/****************************************************************
+ * *
+ * Licensed from Digital Equipment Corporation *
+ * Copyright (c) *
+ * Digital Equipment Corporation *
+ * Maynard, Massachusetts *
+ * 1985, 1986 *
+ * All rights reserved. *
+ * *
+ * The Information in this software is subject to change *
+ * without notice and should not be construed as a commitment *
+ * by Digital Equipment Corporation. Digital makes no *
+ * representations about the suitability of this software for *
+ * any purpose. It is supplied "As Is" without expressed or *
+ * implied warranty. *
+ * *
+ * If the Regents of the University of California or its *
+ * licensees modify the software in a manner creating *
+ * derivative copyright rights, appropriate copyright *
+ * legends may be placed on the derivative work in addition *
+ * to that set forth above. *
+ * *
+ ****************************************************************/
+/* ---------------------------------------------------------------------
+ * Modification History
+ *
+ * 15-Apr-86 -- afd
+ * Rename "unused_multi" to "qunused_multi" for extending Generic
+ * kernel to MicroVAXen.
+ *
+ * 18-mar-86 -- jaw br/cvec changed to NOT use registers.
+ *
+ * 12 March 86 -- Jeff Chase
+ * Modified to handle the new MCLGET macro
+ * Changed if_qe_data.c to use more receive buffers
+ * Added a flag to poke with adb to log qe_restarts on console
+ *
+ * 19 Oct 85 -- rjl
+ * Changed the watch dog timer from 30 seconds to 3. VMS is using
+ * less than 1 second in their's. Also turned the printf into an
+ * mprintf.
+ *
+ * 09/16/85 -- Larry Cohen
+ * Add 43bsd alpha tape changes for subnet routing
+ *
+ * 1 Aug 85 -- rjl
+ * Panic on a non-existent memory interrupt and the case where a packet
+ * was chained. The first should never happen because non-existant
+ * memory interrupts cause a bus reset. The second should never happen
+ * because we hang 2k input buffers on the device.
+ *
+ * 1 Aug 85 -- rich
+ * Fixed the broadcast loopback code to handle Clusters without
+ * wedging the system.
+ *
+ * 27 Feb. 85 -- ejf
+ * Return default hardware address on ioctl request.
+ *
+ * 12 Feb. 85 -- ejf
+ * Added internal extended loopback capability.
+ *
+ * 27 Dec. 84 -- rjl
+ * Fixed bug that caused every other transmit descriptor to be used
+ * instead of every descriptor.
+ *
+ * 21 Dec. 84 -- rjl
+ * Added watchdog timer to mask hardware bug that causes device lockup.
+ *
+ * 18 Dec. 84 -- rjl
+ * Reworked driver to use q-bus mapping routines. MicroVAX-I now does
+ * copying instead of m-buf shuffleing.
+ * A number of deficencies in the hardware/firmware were compensated
+ * for. See comments in qestart and qerint.
+ *
+ * 14 Nov. 84 -- jf
+ * Added usage counts for multicast addresses.
+ * Updated general protocol support to allow access to the Ethernet
+ * header.
+ *
+ * 04 Oct. 84 -- jf
+ * Added support for new ioctls to add and delete multicast addresses
+ * and set the physical address.
+ * Add support for general protocols.
+ *
+ * 14 Aug. 84 -- rjl
+ * Integrated Shannon changes. (allow arp above 1024 and ? )
+ *
+ * 13 Feb. 84 -- rjl
+ *
+ * Initial version of driver. derived from IL driver.
+ *
+ * ---------------------------------------------------------------------
+ */
+
+#include "qe.h"
+#if NQE > 0
+/*
+ * Digital Q-BUS to NI Adapter
+ */
+#include "sys/param.h"
+#include "sys/systm.h"
+#include "sys/mbuf.h"
+#include "sys/buf.h"
+#include "sys/protosw.h"
+#include "sys/socket.h"
+#include "sys/ioctl.h"
+#include "sys/errno.h"
+#include "sys/syslog.h"
+#include "sys/device.h"
+#include "sys/time.h"
+#include "sys/kernel.h"
+
+#include "net/if.h"
+#include "net/netisr.h"
+#include "net/route.h"
+
+#ifdef INET
+#include "netinet/in.h"
+#include "netinet/in_systm.h"
+#include "netinet/in_var.h"
+#include "netinet/ip.h"
+#include "netinet/if_ether.h"
+#endif
+
+#ifdef NS
+#include "netns/ns.h"
+#include "netns/ns_if.h"
+#endif
+
+#ifdef ISO
+#include "netiso/iso.h"
+#include "netiso/iso_var.h"
+extern char all_es_snpa[], all_is_snpa[], all_l1is_snpa[], all_l2is_snpa[];
+#endif
+
+#include "vax/include/pte.h"
+#include "vax/include/cpu.h"
+#include "vax/include/mtpr.h"
+#include "if_qereg.h"
+#include "if_uba.h"
+#include "vax/uba/ubareg.h"
+#include "vax/uba/ubavar.h"
+
+#if NQE == 1 && !defined(QNIVERT)
+#define NRCV 15 /* Receive descriptors */
+#else
+#define NRCV 10 /* Receive descriptors */
+#endif
+#define NXMT 5 /* Transmit descriptors */
+#define NTOT (NXMT + NRCV)
+
+#define QETIMEOUT 2 /* transmit timeout, must be > 1 */
+#define QESLOWTIMEOUT 40 /* timeout when no xmits in progress */
+
+#define MINDATA 60
+
+void qetimeout(int);
+
+/*
+ * Ethernet software status per interface.
+ *
+ * Each interface is referenced by a network interface structure,
+ * qe_if, which the routing code uses to locate the interface.
+ * This structure contains the output queue for the interface, its address, ...
+ */
+struct qe_softc {
+ struct arpcom qe_ac; /* Ethernet common part */
+#define qe_if qe_ac.ac_if /* network-visible interface */
+#define qe_addr qe_ac.ac_enaddr /* hardware Ethernet address */
+ struct ifubinfo qe_uba; /* Q-bus resources */
+ volatile struct ifrw qe_ifr[NRCV]; /* for receive buffers; */
+ volatile struct ifxmt qe_ifw[NXMT]; /* for xmit buffers; */
+ int qe_flags; /* software state */
+#define QEF_RUNNING 0x01
+#define QEF_SETADDR 0x02
+#define QEF_FASTTIMEO 0x04
+ int setupaddr; /* mapping info for setup pkts */
+ int ipl; /* interrupt priority */
+ struct qe_ring *rringaddr; /* mapping info for rings */
+ struct qe_ring *tringaddr; /* "" */
+ volatile struct qe_ring rring[NRCV+1]; /* Receive ring descriptors */
+ volatile struct qe_ring tring[NXMT+1]; /* Xmit ring descriptors */
+ u_char setup_pkt[16][8]; /* Setup packet */
+ int rindex; /* Receive index */
+ int tindex; /* Transmit index */
+ int otindex; /* Old transmit index */
+ int qe_intvec; /* Interrupt vector */
+ volatile struct qedevice *addr; /* device addr */
+ int setupqueued; /* setup packet queued */
+ int nxmit; /* Transmits in progress */
+ int qe_restarts; /* timeouts */
+} qe_softc[NQE];
+
+struct uba_device *qeinfo[NQE];
+
+extern struct timeval time;
+
+int qeprobe(), qeattach(), qeintr();
+int qeinit(), qeioctl(), qereset();
+void qestart();
+
+u_short qestd[] = { 0 };
+struct uba_driver qedriver =
+ { qeprobe, 0, qeattach, 0, qestd, "qe", qeinfo };
+
+#define QEUNIT(x) minor(x)
+/*
+ * The deqna shouldn't receive more than ETHERMTU + sizeof(struct ether_header)
+ * but will actually take in up to 2048 bytes. To guard against the receiver
+ * chaining buffers (which we aren't prepared to handle) we allocate 2kb
+ * size buffers.
+ */
+#define MAXPACKETSIZE 2048 /* Should really be ETHERMTU */
+/*
+ * Probe the QNA to see if it's there
+ */
+qeprobe(reg, ui)
+ caddr_t reg;
+ struct uba_device *ui;
+{
+ /* register int br, cvec; r11, r10 value-result */
+ register volatile struct qedevice *addr = (struct qedevice *)reg;
+ register volatile struct qe_ring *rp;
+ register struct qe_ring *prp; /* physical rp */
+ register int i;
+ register volatile struct qe_softc *sc = &qe_softc[ui->ui_unit];
+
+#ifdef lint
+ br = 0; cvec = br; br = cvec;
+ qeintr(0);
+#endif
+
+ /*
+ * The QNA interrupts on i/o operations. To do an I/O operation
+ * we have to setup the interface by transmitting a setup packet.
+ */
+ addr->qe_csr = QE_RESET;
+ addr->qe_csr &= ~QE_RESET;
+ addr->qe_vector = (uba_hd[numuba].uh_lastiv -= 4);
+
+ /*
+ * Map the communications area and the setup packet.
+ */
+ sc->setupaddr =
+ uballoc(0, (caddr_t)sc->setup_pkt, sizeof(sc->setup_pkt), 0);
+ sc->rringaddr = (struct qe_ring *) uballoc(0, (caddr_t)sc->rring,
+ sizeof(struct qe_ring) * (NTOT+2), 0);
+ prp = (struct qe_ring *)UBAI_ADDR((int)sc->rringaddr);
+
+ /*
+ * The QNA will loop the setup packet back to the receive ring
+ * for verification, therefore we initialize the first
+ * receive & transmit ring descriptors and link the setup packet
+ * to them.
+ */
+ qeinitdesc(sc->tring, (caddr_t)UBAI_ADDR(sc->setupaddr),
+ sizeof(sc->setup_pkt));
+ qeinitdesc(sc->rring, (caddr_t)UBAI_ADDR(sc->setupaddr),
+ sizeof(sc->setup_pkt));
+
+ rp = (struct qe_ring *)sc->tring;
+ rp->qe_setup = 1;
+ rp->qe_eomsg = 1;
+ rp->qe_flag = rp->qe_status1 = QE_NOTYET;
+ rp->qe_valid = 1;
+
+ rp = (struct qe_ring *)sc->rring;
+ rp->qe_flag = rp->qe_status1 = QE_NOTYET;
+ rp->qe_valid = 1;
+
+ /*
+ * Get the addr off of the interface and place it into the setup
+ * packet. This code looks strange due to the fact that the address
+ * is placed in the setup packet in col. major order.
+ */
+ for( i = 0 ; i < 6 ; i++ )
+ sc->setup_pkt[i][1] = addr->qe_sta_addr[i];
+
+ qesetup( sc );
+ /*
+ * Start the interface and wait for the packet.
+ */
+ addr->qe_csr = QE_INT_ENABLE | QE_XMIT_INT | QE_RCV_INT;
+ addr->qe_rcvlist_lo = (short)((int)prp);
+ addr->qe_rcvlist_hi = (short)((int)prp >> 16);
+ prp += NRCV+1;
+ addr->qe_xmtlist_lo = (short)((int)prp);
+ addr->qe_xmtlist_hi = (short)((int)prp >> 16);
+ DELAY(10000);
+ /*
+ * All done with the bus resources.
+ */
+ ubarelse(0, &sc->setupaddr);
+ ubarelse(0, (int *)&sc->rringaddr);
+ sc->ipl = 0x15;
+ return( sizeof(struct qedevice) );
+}
+
+/*
+ * Interface exists: make available by filling in network interface
+ * record. System will initialize the interface when it is ready
+ * to accept packets.
+ */
+qeattach(ui)
+ struct uba_device *ui;
+{
+ struct qe_softc *sc = &qe_softc[ui->ui_unit];
+ struct ifnet *ifp = (struct ifnet *)&sc->qe_if;
+ volatile struct qedevice *addr=(struct qedevice *)ui->ui_addr;
+ int i;
+
+ ifp->if_unit = ui->ui_unit;
+ ifp->if_name = "qe";
+ /*
+ * The Deqna is cable of transmitting broadcasts, but
+ * doesn't listen to its own.
+ */
+ ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS;
+
+ /*
+ * Read the address from the prom and save it.
+ */
+ for( i=0 ; i<6 ; i++ )
+ sc->setup_pkt[i][1] = sc->qe_addr[i] = addr->qe_sta_addr[i] & 0xff;
+ addr->qe_vector |= 1;
+ printf("qe%d: %s, hardware address %s\n", ui->ui_unit,
+ addr->qe_vector&01 ? "delqa":"deqna",
+ ether_sprintf(sc->qe_addr));
+ addr->qe_vector &= ~1;
+
+ /*
+ * Save the vector for initialization at reset time.
+ */
+ sc->qe_intvec = addr->qe_vector;
+
+ ifp->if_start = qestart;
+ ifp->if_ioctl = qeioctl;
+ ifp->if_reset = qereset;
+ ifp->if_watchdog = qetimeout;
+ sc->qe_uba.iff_flags = UBA_CANTWAIT;
+ if_attach(ifp);
+ ether_ifattach(ifp);
+}
+
+/*
+ * Reset of interface after UNIBUS reset.
+ * If interface is on specified uba, reset its state.
+ */
+qereset(unit, uban)
+ int unit, uban;
+{
+ register struct uba_device *ui;
+
+ if (unit >= NQE || (ui = qeinfo[unit]) == 0 || ui->ui_alive == 0 ||
+ ui->ui_ubanum != uban)
+ return;
+ printf(" qe%d", unit);
+ qe_softc[unit].qe_if.if_flags &= ~IFF_RUNNING;
+ qeinit(unit);
+}
+
+/*
+ * Initialization of interface.
+ */
+qeinit(unit)
+ int unit;
+{
+ volatile struct qe_softc *sc = &qe_softc[unit];
+ struct uba_device *ui = qeinfo[unit];
+ volatile struct qedevice *addr=(struct qedevice *)ui->ui_addr;
+ struct ifnet *ifp = (struct ifnet *)&sc->qe_if;
+ int i;
+ int s;
+
+ /* address not known */
+ if (ifp->if_addrlist.tqh_first == (struct ifaddr *)0)
+ return;
+ if (sc->qe_flags & QEF_RUNNING)
+ return;
+
+ if ((ifp->if_flags & IFF_RUNNING) == 0) {
+ /*
+ * map the communications area onto the device
+ */
+ i = uballoc(0, (caddr_t)sc->rring,
+ sizeof(struct qe_ring) * (NTOT+2), 0);
+ if (i == 0)
+ goto fail;
+ sc->rringaddr = (struct qe_ring *)UBAI_ADDR(i);
+ sc->tringaddr = sc->rringaddr + NRCV + 1;
+ i = uballoc(0, (caddr_t)sc->setup_pkt,
+ sizeof(sc->setup_pkt), 0);
+ if (i == 0)
+ goto fail;
+ sc->setupaddr = UBAI_ADDR(i);
+ /*
+ * init buffers and maps
+ */
+ if (if_ubaminit(&sc->qe_uba, ui->ui_ubanum,
+ sizeof (struct ether_header), (int)btoc(MAXPACKETSIZE),
+ sc->qe_ifr, NRCV, sc->qe_ifw, NXMT) == 0) {
+ fail:
+ printf("qe%d: can't allocate uba resources\n", unit);
+ sc->qe_if.if_flags &= ~IFF_UP;
+ return;
+ }
+ }
+ /*
+ * Init the buffer descriptors and indexes for each of the lists and
+ * loop them back to form a ring.
+ */
+ for (i = 0; i < NRCV; i++) {
+ qeinitdesc( &sc->rring[i],
+ (caddr_t)UBAI_ADDR(sc->qe_ifr[i].ifrw_info), MAXPACKETSIZE);
+ sc->rring[i].qe_flag = sc->rring[i].qe_status1 = QE_NOTYET;
+ sc->rring[i].qe_valid = 1;
+ }
+ qeinitdesc(&sc->rring[i], (caddr_t)NULL, 0);
+
+ sc->rring[i].qe_addr_lo = (short)((int)sc->rringaddr);
+ sc->rring[i].qe_addr_hi = (short)((int)sc->rringaddr >> 16);
+ sc->rring[i].qe_chain = 1;
+ sc->rring[i].qe_flag = sc->rring[i].qe_status1 = QE_NOTYET;
+ sc->rring[i].qe_valid = 1;
+
+ for( i = 0 ; i <= NXMT ; i++ )
+ qeinitdesc(&sc->tring[i], (caddr_t)NULL, 0);
+ i--;
+
+ sc->tring[i].qe_addr_lo = (short)((int)sc->tringaddr);
+ sc->tring[i].qe_addr_hi = (short)((int)sc->tringaddr >> 16);
+ sc->tring[i].qe_chain = 1;
+ sc->tring[i].qe_flag = sc->tring[i].qe_status1 = QE_NOTYET;
+ sc->tring[i].qe_valid = 1;
+
+ sc->nxmit = sc->otindex = sc->tindex = sc->rindex = 0;
+
+ /*
+ * Take the interface out of reset, program the vector,
+ * enable interrupts, and tell the world we are up.
+ */
+ s = splimp();
+ addr->qe_vector = sc->qe_intvec;
+ sc->addr = addr;
+ addr->qe_csr = QE_RCV_ENABLE | QE_INT_ENABLE | QE_XMIT_INT |
+ QE_RCV_INT | QE_ILOOP;
+ addr->qe_rcvlist_lo = (short)((int)sc->rringaddr);
+ addr->qe_rcvlist_hi = (short)((int)sc->rringaddr >> 16);
+ ifp->if_flags |= IFF_UP | IFF_RUNNING;
+ sc->qe_flags |= QEF_RUNNING;
+ qesetup( sc );
+ qestart( ifp );
+ sc->qe_if.if_timer = QESLOWTIMEOUT; /* Start watchdog */
+ splx( s );
+}
+
+/*
+ * Start output on interface.
+ *
+ */
+void
+qestart(ifp)
+ struct ifnet *ifp;
+{
+ int unit = ifp->if_unit;
+ struct uba_device *ui = qeinfo[unit];
+ register volatile struct qe_softc *sc = &qe_softc[unit];
+ register volatile struct qedevice *addr;
+ register volatile struct qe_ring *rp;
+ register index;
+ struct mbuf *m;
+ int buf_addr, len, s;
+
+
+ s = splimp();
+ addr = (struct qedevice *)ui->ui_addr;
+ /*
+ * The deqna doesn't look at anything but the valid bit
+ * to determine if it should transmit this packet. If you have
+ * a ring and fill it the device will loop indefinately on the
+ * packet and continue to flood the net with packets until you
+ * break the ring. For this reason we never queue more than n-1
+ * packets in the transmit ring.
+ *
+ * The microcoders should have obeyed their own defination of the
+ * flag and status words, but instead we have to compensate.
+ */
+ for( index = sc->tindex;
+ sc->tring[index].qe_valid == 0 && sc->nxmit < (NXMT-1) ;
+ sc->tindex = index = ++index % NXMT){
+ rp = &sc->tring[index];
+ if( sc->setupqueued ) {
+ buf_addr = sc->setupaddr;
+ len = 128;
+ rp->qe_setup = 1;
+ sc->setupqueued = 0;
+ } else {
+ IF_DEQUEUE(&sc->qe_if.if_snd, m);
+ if( m == 0 ){
+ splx(s);
+ return;
+ }
+ buf_addr = sc->qe_ifw[index].ifw_info;
+ len = if_ubaput(&sc->qe_uba, &sc->qe_ifw[index], m);
+ }
+ if( len < MINDATA )
+ len = MINDATA;
+ /*
+ * Does buffer end on odd byte ?
+ */
+ if( len & 1 ) {
+ len++;
+ rp->qe_odd_end = 1;
+ }
+ rp->qe_buf_len = -(len/2);
+ buf_addr = UBAI_ADDR(buf_addr);
+ rp->qe_flag = rp->qe_status1 = QE_NOTYET;
+ rp->qe_addr_lo = (short)buf_addr;
+ rp->qe_addr_hi = (short)(buf_addr >> 16);
+ rp->qe_eomsg = 1;
+ rp->qe_flag = rp->qe_status1 = QE_NOTYET;
+ rp->qe_valid = 1;
+ if (sc->nxmit++ == 0) {
+ sc->qe_flags |= QEF_FASTTIMEO;
+ sc->qe_if.if_timer = QETIMEOUT;
+ }
+
+ /*
+ * See if the xmit list is invalid.
+ */
+ if( addr->qe_csr & QE_XL_INVALID ) {
+ buf_addr = (int)(sc->tringaddr+index);
+ addr->qe_xmtlist_lo = (short)buf_addr;
+ addr->qe_xmtlist_hi = (short)(buf_addr >> 16);
+ }
+ }
+ splx(s);
+ return;
+}
+
+/*
+ * Ethernet interface interrupt processor
+ */
+qeintr(uba, vector, level, unit)
+{
+ register volatile struct qe_softc *sc = &qe_softc[unit];
+ volatile struct qedevice *addr =
+ (struct qedevice *)qeinfo[unit]->ui_addr;
+ int buf_addr, csr;
+
+ splx(sc->ipl);
+ if (!(sc->qe_flags & QEF_FASTTIMEO))
+ sc->qe_if.if_timer = QESLOWTIMEOUT; /* Restart timer clock */
+ csr = addr->qe_csr;
+ addr->qe_csr = QE_RCV_ENABLE | QE_INT_ENABLE | QE_XMIT_INT | QE_RCV_INT | QE_ILOOP;
+ if( csr & QE_RCV_INT )
+ qerint( unit );
+ if( csr & QE_XMIT_INT )
+ qetint( unit );
+ if( csr & QE_NEX_MEM_INT )
+ printf("qe%d: Nonexistent memory interrupt\n", unit);
+
+ if( addr->qe_csr & QE_RL_INVALID && sc->rring[sc->rindex].qe_status1 == QE_NOTYET ) {
+ buf_addr = (int)&sc->rringaddr[sc->rindex];
+ addr->qe_rcvlist_lo = (short)buf_addr;
+ addr->qe_rcvlist_hi = (short)(buf_addr >> 16);
+ }
+}
+
+/*
+ * Ethernet interface transmit interrupt.
+ */
+
+qetint(unit)
+ int unit;
+{
+ register volatile struct qe_softc *sc = &qe_softc[unit];
+ register volatile struct qe_ring *rp;
+ register volatile struct ifxmt *ifxp;
+ int status1, setupflag;
+ short len;
+
+
+ while( sc->otindex != sc->tindex && sc->tring[sc->otindex].qe_status1 != QE_NOTYET && sc->nxmit > 0 ) {
+ /*
+ * Save the status words from the descriptor so that it can
+ * be released.
+ */
+ rp = &sc->tring[sc->otindex];
+ status1 = rp->qe_status1;
+ setupflag = rp->qe_setup;
+ len = (-rp->qe_buf_len) * 2;
+ if( rp->qe_odd_end )
+ len++;
+ /*
+ * Init the buffer descriptor
+ */
+ bzero((caddr_t)rp, sizeof(struct qe_ring));
+ if( --sc->nxmit == 0 ) {
+ sc->qe_flags &= ~QEF_FASTTIMEO;
+ sc->qe_if.if_timer = QESLOWTIMEOUT;
+ }
+ if( !setupflag ) {
+ /*
+ * Do some statistics.
+ */
+ sc->qe_if.if_opackets++;
+ sc->qe_if.if_collisions += ( status1 & QE_CCNT ) >> 4;
+ if (status1 & QE_ERROR)
+ sc->qe_if.if_oerrors++;
+ ifxp = &sc->qe_ifw[sc->otindex];
+ if (ifxp->ifw_xtofree) {
+ m_freem(ifxp->ifw_xtofree);
+ ifxp->ifw_xtofree = 0;
+ }
+ }
+ sc->otindex = ++sc->otindex % NXMT;
+ }
+ qestart( &sc->qe_if );
+}
+
+/*
+ * Ethernet interface receiver interrupt.
+ * If can't determine length from type, then have to drop packet.
+ * Othewise decapsulate packet based on type and pass to type specific
+ * higher-level input routine.
+ */
+qerint(unit)
+ int unit;
+{
+ register volatile struct qe_softc *sc = &qe_softc[unit];
+ register volatile struct qe_ring *rp;
+ register int nrcv = 0;
+ int len, status1, status2;
+ int bufaddr;
+
+ /*
+ * Traverse the receive ring looking for packets to pass back.
+ * The search is complete when we find a descriptor not in use.
+ *
+ * As in the transmit case the deqna doesn't honor it's own protocols
+ * so there exists the possibility that the device can beat us around
+ * the ring. The proper way to guard against this is to insure that
+ * there is always at least one invalid descriptor. We chose instead
+ * to make the ring large enough to minimize the problem. With a ring
+ * size of 4 we haven't been able to see the problem. To be safe we
+ * doubled that to 8.
+ *
+ */
+ while (sc->rring[sc->rindex].qe_status1 == QE_NOTYET && nrcv < NRCV) {
+ /*
+ * We got an interrupt but did not find an input packet
+ * where we expected one to be, probably because the ring
+ * was overrun.
+ * We search forward to find a valid packet and start
+ * processing from there. If no valid packet is found it
+ * means we processed all the packets during a previous
+ * interrupt and that the QE_RCV_INT bit was set while
+ * we were processing one of these earlier packets. In
+ * this case we can safely ignore the interrupt (by dropping
+ * through the code below).
+ */
+ sc->rindex = (sc->rindex + 1) % NRCV;
+ nrcv++;
+ }
+ if (nrcv && nrcv < NRCV)
+ log(LOG_ERR, "qe%d: ring overrun, resync'd by skipping %d\n",
+ unit, nrcv);
+
+ for( ; sc->rring[sc->rindex].qe_status1 != QE_NOTYET ; sc->rindex = ++sc->rindex % NRCV ){
+ rp = &sc->rring[sc->rindex];
+ status1 = rp->qe_status1;
+ status2 = rp->qe_status2;
+ bzero((caddr_t)rp, sizeof(struct qe_ring));
+ if( (status1 & QE_MASK) == QE_MASK )
+ panic("qe: chained packet");
+ len = ((status1 & QE_RBL_HI) | (status2 & QE_RBL_LO)) + 60;
+ sc->qe_if.if_ipackets++;
+
+ if (status1 & QE_ERROR) {
+ if ((status1 & QE_RUNT) == 0)
+ sc->qe_if.if_ierrors++;
+ } else {
+ /*
+ * We don't process setup packets.
+ */
+ if( !(status1 & QE_ESETUP) )
+ qeread(sc, &sc->qe_ifr[sc->rindex],
+ len - sizeof(struct ether_header));
+ }
+ /*
+ * Return the buffer to the ring
+ */
+ bufaddr = (int)UBAI_ADDR(sc->qe_ifr[sc->rindex].ifrw_info);
+ rp->qe_buf_len = -((MAXPACKETSIZE)/2);
+ rp->qe_addr_lo = (short)bufaddr;
+ rp->qe_addr_hi = (short)((int)bufaddr >> 16);
+ rp->qe_flag = rp->qe_status1 = QE_NOTYET;
+ rp->qe_valid = 1;
+ }
+}
+
+/*
+ * Process an ioctl request.
+ */
+qeioctl(ifp, cmd, data)
+ register struct ifnet *ifp;
+ int cmd;
+ caddr_t data;
+{
+ struct qe_softc *sc = &qe_softc[ifp->if_unit];
+ struct ifaddr *ifa = (struct ifaddr *)data;
+ int s = splimp(), error = 0;
+
+ switch (cmd) {
+
+ case SIOCSIFADDR:
+ ifp->if_flags |= IFF_UP;
+ qeinit(ifp->if_unit);
+ switch(ifa->ifa_addr->sa_family) {
+#ifdef INET
+ case AF_INET:
+ arp_ifinit(&sc->qe_ac, ifa);
+ break;
+#endif
+#ifdef NS
+ case AF_NS:
+ {
+ register struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr);
+
+ if (ns_nullhost(*ina))
+ ina->x_host = *(union ns_host *)(sc->qe_addr);
+ else
+ qe_setaddr(ina->x_host.c_host, ifp->if_unit);
+ break;
+ }
+#endif
+ }
+ break;
+
+ case SIOCSIFFLAGS:
+ if ((ifp->if_flags & IFF_UP) == 0 &&
+ sc->qe_flags & QEF_RUNNING) {
+ ((volatile struct qedevice *)
+ (qeinfo[ifp->if_unit]->ui_addr))->qe_csr = QE_RESET;
+ sc->qe_flags &= ~QEF_RUNNING;
+ } else if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) ==
+ IFF_RUNNING && (sc->qe_flags & QEF_RUNNING) == 0)
+ qerestart(sc);
+ break;
+
+ default:
+ error = EINVAL;
+
+ }
+ splx(s);
+ return (error);
+}
+
+/*
+ * set ethernet address for unit
+ */
+qe_setaddr(physaddr, unit)
+ u_char *physaddr;
+ int unit;
+{
+ register volatile struct qe_softc *sc = &qe_softc[unit];
+ register int i;
+
+ for (i = 0; i < 6; i++)
+ sc->setup_pkt[i][1] = sc->qe_addr[i] = physaddr[i];
+ sc->qe_flags |= QEF_SETADDR;
+ if (sc->qe_if.if_flags & IFF_RUNNING)
+ qesetup(sc);
+ qeinit(unit);
+}
+
+
+/*
+ * Initialize a ring descriptor with mbuf allocation side effects
+ */
+qeinitdesc(rp, addr, len)
+ register volatile struct qe_ring *rp;
+ caddr_t addr; /* mapped address */
+ int len;
+{
+ /*
+ * clear the entire descriptor
+ */
+ bzero((caddr_t)rp, sizeof(struct qe_ring));
+
+ if( len ) {
+ rp->qe_buf_len = -(len/2);
+ rp->qe_addr_lo = (short)((int)addr);
+ rp->qe_addr_hi = (short)((int)addr >> 16);
+ }
+}
+/*
+ * Build a setup packet - the physical address will already be present
+ * in first column.
+ */
+qesetup( sc )
+ volatile struct qe_softc *sc;
+{
+ register i, j;
+
+ /*
+ * Copy the target address to the rest of the entries in this row.
+ */
+ for ( j = 0; j < 6 ; j++ )
+ for ( i = 2 ; i < 8 ; i++ )
+ sc->setup_pkt[j][i] = sc->setup_pkt[j][1];
+ /*
+ * Duplicate the first half.
+ */
+ bcopy((caddr_t)sc->setup_pkt[0], (caddr_t)sc->setup_pkt[8], 64);
+ /*
+ * Fill in the broadcast (and ISO multicast) address(es).
+ */
+ for ( i = 0; i < 6 ; i++ ) {
+ sc->setup_pkt[i][2] = 0xff;
+#ifdef ISO
+ sc->setup_pkt[i][3] = all_es_snpa[i];
+ sc->setup_pkt[i][4] = all_is_snpa[i];
+ sc->setup_pkt[i][5] = all_l1is_snpa[i];
+ sc->setup_pkt[i][6] = all_l2is_snpa[i];
+#endif
+ }
+ sc->setupqueued++;
+}
+
+/*
+ * Pass a packet to the higher levels.
+ * We deal with the trailer protocol here.
+ */
+qeread(sc, ifrw, len)
+ register volatile struct qe_softc *sc;
+ volatile struct ifrw *ifrw;
+ int len;
+{
+ struct ether_header *eh;
+ struct mbuf *m;
+ int s;
+ struct ifqueue *inq;
+
+ /*
+ * Deal with trailer protocol: if type is INET trailer
+ * get true type from first 16-bit word past data.
+ * Remember that type was trailer by setting off.
+ */
+
+ eh = (struct ether_header *)ifrw->ifrw_addr;
+ if (len == 0)
+ return;
+
+ /*
+ * Pull packet off interface. Off is nonzero if packet
+ * has trailing header; qeget will then force this header
+ * information to be at the front, but we still have to drop
+ * the type and length which are at the front of any trailer data.
+ */
+ m = if_ubaget(&sc->qe_uba, ifrw, len, &sc->qe_if);
+#ifdef notdef
+if (m) {
+*(((u_long *)m->m_data)+0),
+*(((u_long *)m->m_data)+1),
+*(((u_long *)m->m_data)+2),
+*(((u_long *)m->m_data)+3)
+); }
+#endif
+
+ if (m)
+ ether_input((struct ifnet *)&sc->qe_if, eh, m);
+}
+
+/*
+ * Watchdog timeout routine. There is a condition in the hardware that
+ * causes the board to lock up under heavy load. This routine detects
+ * the hang up and restarts the device.
+ */
+void
+qetimeout(unit)
+ int unit;
+{
+ register volatile struct qe_softc *sc;
+
+ sc = &qe_softc[unit];
+#ifdef notdef
+ log(LOG_ERR, "qe%d: transmit timeout, restarted %d\n",
+ unit, sc->qe_restarts++);
+#endif
+ qerestart(sc);
+}
+/*
+ * Restart for board lockup problem.
+ */
+qerestart(sc)
+ register volatile struct qe_softc *sc;
+{
+ register struct ifnet *ifp = (struct ifnet *)&sc->qe_if;
+ register volatile struct qedevice *addr = sc->addr;
+ register volatile struct qe_ring *rp;
+ register i;
+
+ addr->qe_csr = QE_RESET;
+ addr->qe_csr &= ~QE_RESET;
+ qesetup( sc );
+ for (i = 0, rp = sc->tring; i < NXMT; rp++, i++) {
+ rp->qe_flag = rp->qe_status1 = QE_NOTYET;
+ rp->qe_valid = 0;
+ }
+ sc->nxmit = sc->otindex = sc->tindex = sc->rindex = 0;
+ addr->qe_csr = QE_RCV_ENABLE | QE_INT_ENABLE | QE_XMIT_INT |
+ QE_RCV_INT | QE_ILOOP;
+ addr->qe_rcvlist_lo = (short)((int)sc->rringaddr);
+ addr->qe_rcvlist_hi = (short)((int)sc->rringaddr >> 16);
+ sc->qe_flags |= QEF_RUNNING;
+ qestart(ifp);
+}
+
+qe_match(){
+ printf("qe_match\n");
+ return 0;
+}
+
+void
+qe_attach(){
+ printf("qe_attach\n");
+}
+
+struct cfdriver qecd =
+ { 0,"qe",qe_match, qe_attach, DV_IFNET, sizeof(struct uba_driver) };
+
+#endif
diff --git a/sys/arch/vax/if/if_qereg.h b/sys/arch/vax/if/if_qereg.h
new file mode 100644
index 00000000000..fe608daa42a
--- /dev/null
+++ b/sys/arch/vax/if/if_qereg.h
@@ -0,0 +1,172 @@
+/* $NetBSD: if_qereg.h,v 1.1 1995/03/30 20:26:41 ragge Exp $ */
+/*
+ * Copyright (c) 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Digital Equipment Corp.
+ *
+ * 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.
+ *
+ * @(#)if_qereg.h 7.3 (Berkeley) 6/28/90
+ */
+
+/* @(#)if_qereg.h 1.2 (ULTRIX) 1/3/85 */
+
+/****************************************************************
+ * *
+ * Licensed from Digital Equipment Corporation *
+ * Copyright (c) *
+ * Digital Equipment Corporation *
+ * Maynard, Massachusetts *
+ * 1985, 1986 *
+ * All rights reserved. *
+ * *
+ * The Information in this software is subject to change *
+ * without notice and should not be construed as a commitment *
+ * by Digital Equipment Corporation. Digital makes no *
+ * representations about the suitability of this software for *
+ * any purpose. It is supplied "As Is" without expressed or *
+ * implied warranty. *
+ * *
+ * If the Regents of the University of California or its *
+ * licensees modify the software in a manner creating *
+ * diriviative copyright rights, appropriate copyright *
+ * legends may be placed on the drivative work in addition *
+ * to that set forth above. *
+ * *
+ ****************************************************************/
+/* ---------------------------------------------------------------------
+ * Modification History
+ *
+ * 13 Feb. 84 -- rjl
+ *
+ * Initial version of driver. derived from IL driver.
+ *
+ * ---------------------------------------------------------------------
+ */
+
+/*
+ * Digital Q-BUS to NI Adapter
+ */
+struct qedevice {
+ u_short qe_sta_addr[2]; /* Station address (actually 6 */
+ u_short qe_rcvlist_lo; /* Receive list lo address */
+ u_short qe_rcvlist_hi; /* Receive list hi address */
+ u_short qe_xmtlist_lo; /* Transmit list lo address */
+ u_short qe_xmtlist_hi; /* Transmit list hi address */
+ u_short qe_vector; /* Interrupt vector */
+ u_short qe_csr; /* Command and Status Register */
+};
+
+/*
+ * Command and status bits (csr)
+ */
+#define QE_RCV_ENABLE 0x0001 /* Receiver enable */
+#define QE_RESET 0x0002 /* Software reset */
+#define QE_NEX_MEM_INT 0x0004 /* Non existant mem interrupt */
+#define QE_LOAD_ROM 0x0008 /* Load boot/diag from rom */
+#define QE_XL_INVALID 0x0010 /* Transmit list invalid */
+#define QE_RL_INVALID 0x0020 /* Receive list invalid */
+#define QE_INT_ENABLE 0x0040 /* Interrupt enable */
+#define QE_XMIT_INT 0x0080 /* Transmit interrupt */
+#define QE_ILOOP 0x0100 /* Internal loopback */
+#define QE_ELOOP 0x0200 /* External loopback */
+#define QE_STIM_ENABLE 0x0400 /* Sanity timer enable */
+#define QE_POWERUP 0x1000 /* Tranceiver power on */
+#define QE_CARRIER 0x2000 /* Carrier detect */
+#define QE_RCV_INT 0x8000 /* Receiver interrupt */
+
+/*
+ * Transmit and receive ring discriptor ---------------------------
+ *
+ * The QNA uses the flag, status1 and the valid bit as a handshake/semiphore
+ * mechinism.
+ *
+ * The flag word is written on ( bits 15,15 set to 1 ) when it reads the
+ * descriptor. If the valid bit is set it considers the address to be valid.
+ * When it uses the buffer pointed to by the valid address it sets status word
+ * one.
+ */
+struct qe_ring {
+ u_short qe_flag; /* Buffer utilization flags */
+ u_short qe_addr_hi:6, /* Hi order bits of buffer addr */
+ qe_odd_begin:1, /* Odd byte begin and end (xmit)*/
+ qe_odd_end:1,
+ qe_fill1:4,
+ qe_setup:1, /* Setup packet */
+ qe_eomsg:1, /* End of message flag */
+ qe_chain:1, /* Chain address instead of buf */
+ qe_valid:1; /* Address field is valid */
+ u_short qe_addr_lo; /* Low order bits of address */
+ short qe_buf_len; /* Negative buffer length */
+ u_short qe_status1; /* Status word one */
+ u_short qe_status2; /* Status word two */
+};
+
+/*
+ * Status word definations (receive)
+ * word1
+ */
+#define QE_OVF 0x0001 /* Receiver overflow */
+#define QE_CRCERR 0x0002 /* CRC error */
+#define QE_FRAME 0x0004 /* Framing alignment error */
+#define QE_SHORT 0x0008 /* Packet size < 10 bytes */
+#define QE_RBL_HI 0x0700 /* Hi bits of receive len */
+#define QE_RUNT 0x0800 /* Runt packet */
+#define QE_DISCARD 0x1000 /* Discard the packet */
+#define QE_ESETUP 0x2000 /* Looped back setup or eloop */
+#define QE_ERROR 0x4000 /* Receiver error */
+#define QE_LASTNOT 0x8000 /* Not the last in the packet */
+/* word2 */
+#define QE_RBL_LO 0x00ff /* Low bits of receive len */
+
+/*
+ * Status word definations (transmit)
+ * word1
+ */
+#define QE_CCNT 0x00f0 /* Collision count this packet */
+#define QE_FAIL 0x0100 /* Heart beat check failure */
+#define QE_ABORT 0x0200 /* Transmission abort */
+#define QE_STE16 0x0400 /* Sanity timer default on */
+#define QE_NOCAR 0x0800 /* No carrier */
+#define QE_LOSS 0x1000 /* Loss of carrier while xmit */
+/* word2 */
+#define QE_TDR 0x3fff /* Time domain reflectometry */
+
+/*
+ * General constant definations
+ */
+#define QEALLOC 0 /* Allocate an mbuf */
+#define QENOALLOC 1 /* No mbuf allocation */
+#define QEDEALLOC 2 /* Release an mbuf chain */
+
+#define QE_NOTYET 0x8000 /* Descriptor not in use yet */
+#define QE_INUSE 0x4000 /* Descriptor being used by QNA */
+#define QE_MASK 0xc000 /* Lastnot/error/used mask */
diff --git a/sys/arch/vax/if/if_uba.c b/sys/arch/vax/if/if_uba.c
new file mode 100644
index 00000000000..1ef5b3f8179
--- /dev/null
+++ b/sys/arch/vax/if/if_uba.c
@@ -0,0 +1,390 @@
+/* $NetBSD: if_uba.c,v 1.6 1995/04/11 06:19:09 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988 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.
+ *
+ * @(#)if_uba.c 7.16 (Berkeley) 12/16/90
+ */
+
+#include "sys/param.h"
+#include "sys/systm.h"
+#include "sys/malloc.h"
+#include "sys/mbuf.h"
+#include "sys/map.h"
+#include "sys/buf.h"
+#include "sys/socket.h"
+#include "sys/syslog.h"
+
+#include "net/if.h"
+
+#include "vax/include/pte.h"
+#include "vax/include/mtpr.h"
+#include "if_uba.h"
+#include "vax/include/vmparam.h"
+#include "vax/uba/ubareg.h"
+#include "vax/uba/ubavar.h"
+#include "machine/macros.h"
+
+static if_ubaalloc(struct ifubinfo *, struct ifrw *, int);
+static rcv_xmtbuf(struct ifxmt *);
+static restor_xmtbuf(struct ifxmt *);
+
+/*
+ * Routines supporting UNIBUS network interfaces.
+ *
+ * TODO:
+ * Support interfaces using only one BDP statically.
+ */
+
+/*
+ * Init UNIBUS for interface on uban whose headers of size hlen are to
+ * end on a page boundary. We allocate a UNIBUS map register for the page
+ * with the header, and nmr more UNIBUS map registers for i/o on the adapter,
+ * doing this once for each read and once for each write buffer. We also
+ * allocate page frames in the mbuffer pool for these pages.
+ */
+if_ubaminit(ifu, uban, hlen, nmr, ifr, nr, ifw, nw)
+ register struct ifubinfo *ifu;
+ int uban, hlen, nmr, nr, nw;
+ register struct ifrw *ifr;
+ register struct ifxmt *ifw;
+{
+ register caddr_t p;
+ caddr_t cp;
+ int i, nclbytes, off;
+
+ if (hlen)
+ off = MCLBYTES - hlen;
+ else
+ off = 0;
+ nclbytes = roundup(nmr * NBPG, MCLBYTES);
+ if (hlen)
+ nclbytes += MCLBYTES;
+ if (ifr[0].ifrw_addr)
+ cp = ifr[0].ifrw_addr - off;
+ else {
+ cp = (caddr_t)malloc((u_long)((nr + nw) * nclbytes), M_DEVBUF,
+ M_NOWAIT);
+ if (cp == 0)
+ return (0);
+ p = cp;
+ for (i = 0; i < nr; i++) {
+ ifr[i].ifrw_addr = p + off;
+ p += nclbytes;
+ }
+ for (i = 0; i < nw; i++) {
+ ifw[i].ifw_base = p;
+ ifw[i].ifw_addr = p + off;
+ p += nclbytes;
+ }
+ ifu->iff_hlen = hlen;
+ ifu->iff_uban = uban;
+ ifu->iff_uba = uba_hd[uban].uh_uba;
+ ifu->iff_ubamr = uba_hd[uban].uh_mr;
+ }
+ for (i = 0; i < nr; i++)
+ if (if_ubaalloc(ifu, &ifr[i], nmr) == 0) {
+ nr = i;
+ nw = 0;
+ goto bad;
+ }
+ for (i = 0; i < nw; i++)
+ if (if_ubaalloc(ifu, &ifw[i].ifrw, nmr) == 0) {
+ nw = i;
+ goto bad;
+ }
+ while (--nw >= 0) {
+ for (i = 0; i < nmr; i++)
+ ifw[nw].ifw_wmap[i] = ifw[nw].ifw_mr[i];
+ ifw[nw].ifw_xswapd = 0;
+ ifw[nw].ifw_flags = IFRW_W;
+ ifw[nw].ifw_nmr = nmr;
+ }
+ return (1);
+bad:
+ while (--nw >= 0)
+ ubarelse(ifu->iff_uban, &ifw[nw].ifw_info);
+ while (--nr >= 0)
+ ubarelse(ifu->iff_uban, &ifr[nr].ifrw_info);
+ free(cp, M_DEVBUF);
+ ifr[0].ifrw_addr = 0;
+ return (0);
+}
+
+/*
+ * Setup an ifrw structure by allocating UNIBUS map registers,
+ * possibly a buffered data path, and initializing the fields of
+ * the ifrw structure to minimize run-time overhead.
+ */
+static
+if_ubaalloc(ifu, ifrw, nmr)
+ struct ifubinfo *ifu;
+ register struct ifrw *ifrw;
+ int nmr;
+{
+ register int info;
+
+ info =
+ uballoc(ifu->iff_uban, ifrw->ifrw_addr, nmr*NBPG + ifu->iff_hlen,
+ ifu->iff_flags);
+ if (info == 0)
+ return (0);
+ ifrw->ifrw_info = info;
+ ifrw->ifrw_bdp = UBAI_BDP(info);
+ ifrw->ifrw_proto = UBAMR_MRV | (UBAI_BDP(info) << UBAMR_DPSHIFT);
+ ifrw->ifrw_mr = &ifu->iff_ubamr[UBAI_MR(info) + (ifu->iff_hlen? 1 : 0)];
+ return (1);
+}
+
+/*
+ * Pull read data off a interface.
+ * Totlen is length of data, with local net header stripped.
+ * When full cluster sized units are present
+ * on the interface on cluster boundaries we can get them more
+ * easily by remapping, and take advantage of this here.
+ * Save a pointer to the interface structure and the total length,
+ * so that protocols can determine where incoming packets arrived.
+ * Note: we may be called to receive from a transmit buffer by some
+ * devices. In that case, we must force normal mapping of the buffer,
+ * so that the correct data will appear (only unibus maps are
+ * changed when remapping the transmit buffers).
+ */
+struct mbuf *
+if_ubaget(ifu, ifr, totlen, ifp)
+ struct ifubinfo *ifu;
+ register struct ifrw *ifr;
+ register int totlen;
+ struct ifnet *ifp;
+{
+ struct mbuf *top, **mp;
+ register struct mbuf *m;
+ register caddr_t cp = ifr->ifrw_addr + ifu->iff_hlen, pp;
+ register int len;
+ top = 0;
+ mp = &top;
+ MGETHDR(m, M_DONTWAIT, MT_DATA);
+ if (m == 0){
+ return ((struct mbuf *)NULL);
+ }
+ m->m_pkthdr.rcvif = ifp;
+ m->m_pkthdr.len = totlen;
+ m->m_len = MHLEN;
+
+ if (ifr->ifrw_flags & IFRW_W){
+ rcv_xmtbuf((struct ifxmt *)ifr);
+ }
+ while (totlen > 0) {
+ if (top) {
+ MGET(m, M_DONTWAIT, MT_DATA);
+ if (m == 0) {
+ m_freem(top);
+ top = 0;
+ goto out;
+ }
+ m->m_len = MLEN;
+ }
+ len = totlen;
+ if (len >= MINCLSIZE) {
+ struct pte *cpte, *ppte;
+ int x, *ip, i;
+
+ MCLGET(m, M_DONTWAIT);
+ if ((m->m_flags & M_EXT) == 0){
+ goto nopage;
+ }
+ len = min(len, MCLBYTES);
+ m->m_len = len;
+ if (!claligned(cp)){
+ goto copy;
+ }
+ /*
+ * Switch pages mapped to UNIBUS with new page pp,
+ * as quick form of copy. Remap UNIBUS and invalidate.
+ */
+ pp = mtod(m, char *);
+ cpte = (struct pte *)kvtopte(cp);
+ ppte = (struct pte *)kvtopte(pp);
+ x = vax_btop(cp - ifr->ifrw_addr);
+ ip = (int *)&ifr->ifrw_mr[x];
+ for (i = 0; i < MCLBYTES/NBPG; i++) {
+ struct pte t;
+ t = *ppte; *ppte++ = *cpte; *cpte = t;
+ *ip++ = cpte++->pg_pfn|ifr->ifrw_proto;
+ mtpr(cp,PR_TBIS);
+ cp += NBPG;
+ mtpr((caddr_t)pp,PR_TBIS);
+ pp += NBPG;
+ }
+ goto nocopy;
+ }
+nopage:
+ if (len < m->m_len) {
+ /*
+ * Place initial small packet/header at end of mbuf.
+ */
+ if (top == 0 && len + max_linkhdr <= m->m_len)
+ m->m_data += max_linkhdr;
+ m->m_len = len;
+ } else
+ len = m->m_len;
+copy:
+ bcopy(cp, mtod(m, caddr_t), (unsigned)len);
+ cp += len;
+nocopy:
+ *mp = m;
+ mp = &m->m_next;
+ totlen -= len;
+ }
+out:
+ if (ifr->ifrw_flags & IFRW_W){
+ restor_xmtbuf((struct ifxmt *)ifr);
+ }
+ return (top);
+}
+
+/*
+ * Change the mapping on a transmit buffer so that if_ubaget may
+ * receive from that buffer. Copy data from any pages mapped to Unibus
+ * into the pages mapped to normal kernel virtual memory, so that
+ * they can be accessed and swapped as usual. We take advantage
+ * of the fact that clusters are placed on the xtofree list
+ * in inverse order, finding the last one.
+ */
+static
+rcv_xmtbuf(ifw)
+ register struct ifxmt *ifw;
+{
+ register struct mbuf *m;
+ struct mbuf **mprev;
+ register i;
+ char *cp;
+
+ while (i = ffs((long)ifw->ifw_xswapd)) {
+ cp = ifw->ifw_base + i * MCLBYTES;
+ i--;
+ ifw->ifw_xswapd &= ~(1<<i);
+ mprev = &ifw->ifw_xtofree;
+ for (m = ifw->ifw_xtofree; m && m->m_next; m = m->m_next)
+ mprev = &m->m_next;
+ if (m == NULL)
+ break;
+ bcopy(mtod(m, caddr_t), cp, MCLBYTES);
+ (void) m_free(m);
+ *mprev = NULL;
+ }
+ ifw->ifw_xswapd = 0;
+ for (i = 0; i < ifw->ifw_nmr; i++)
+ ifw->ifw_mr[i] = ifw->ifw_wmap[i];
+}
+
+/*
+ * Put a transmit buffer back together after doing an if_ubaget on it,
+ * which may have swapped pages.
+ */
+static
+restor_xmtbuf(ifw)
+ register struct ifxmt *ifw;
+{
+ register i;
+
+ for (i = 0; i < ifw->ifw_nmr; i++)
+ ifw->ifw_wmap[i] = ifw->ifw_mr[i];
+}
+
+/*
+ * Map a chain of mbufs onto a network interface
+ * in preparation for an i/o operation.
+ * The argument chain of mbufs includes the local network
+ * header which is copied to be in the mapped, aligned
+ * i/o space.
+ */
+if_ubaput(ifu, ifw, m)
+ struct ifubinfo *ifu;
+ register struct ifxmt *ifw;
+ register struct mbuf *m;
+{
+ register struct mbuf *mp;
+ register caddr_t cp, dp;
+ register int i;
+ int xswapd = 0;
+ int x, cc, t;
+
+ cp = ifw->ifw_addr;
+ while (m) {
+ dp = mtod(m, char *);
+ if (claligned(cp) && claligned(dp) &&
+ (m->m_len == MCLBYTES || m->m_next == (struct mbuf *)0)) {
+ struct pte *pte;
+ int *ip;
+
+ pte = (struct pte *)kvtopte(dp);
+ x = vax_btop(cp - ifw->ifw_addr);
+ ip = (int *)&ifw->ifw_mr[x];
+ for (i = 0; i < MCLBYTES/NBPG; i++)
+ *ip++ = ifw->ifw_proto | pte++->pg_pfn;
+ xswapd |= 1 << (x>>(MCLSHIFT-PGSHIFT));
+ mp = m->m_next;
+ m->m_next = ifw->ifw_xtofree;
+ ifw->ifw_xtofree = m;
+ cp += m->m_len;
+ } else {
+ bcopy(mtod(m, caddr_t), cp, (unsigned)m->m_len);
+ cp += m->m_len;
+ MFREE(m, mp);
+ }
+ m = mp;
+ }
+
+ /*
+ * Xswapd is the set of clusters we just mapped out. Ifu->iff_xswapd
+ * is the set of clusters mapped out from before. We compute
+ * the number of clusters involved in this operation in x.
+ * Clusters mapped out before and involved in this operation
+ * should be unmapped so original pages will be accessed by the device.
+ */
+ cc = cp - ifw->ifw_addr;
+ x = ((cc - ifu->iff_hlen) + MCLBYTES - 1) >> MCLSHIFT;
+ ifw->ifw_xswapd &= ~xswapd;
+ while (i = ffs((long)ifw->ifw_xswapd)) {
+ i--;
+ if (i >= x)
+ break;
+ ifw->ifw_xswapd &= ~(1<<i);
+ i *= MCLBYTES/NBPG;
+ for (t = 0; t < MCLBYTES/NBPG; t++) {
+ ifw->ifw_mr[i] = ifw->ifw_wmap[i];
+ i++;
+ }
+ }
+ ifw->ifw_xswapd |= xswapd;
+ return (cc);
+}
diff --git a/sys/arch/vax/if/if_uba.h b/sys/arch/vax/if/if_uba.h
new file mode 100644
index 00000000000..b1d6a2a203f
--- /dev/null
+++ b/sys/arch/vax/if/if_uba.h
@@ -0,0 +1,136 @@
+/* $NetBSD: if_uba.h,v 1.3 1995/05/11 16:53:12 jtc Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986 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.
+ *
+ * @(#)if_uba.h 7.4 (Berkeley) 6/28/90
+ */
+
+/*
+ * Structure and routine definitions
+ * for UNIBUS network interfaces.
+ */
+
+#define IF_MAXNUBAMR 10
+/*
+ * Each interface has structures giving information
+ * about UNIBUS resources held by the interface
+ * for each send and receive buffer.
+ *
+ * We hold IF_NUBAMR map registers for datagram data, starting
+ * at ifr_mr. Map register ifr_mr[-1] maps the local network header
+ * ending on the page boundary. Bdp's are reserved for read and for
+ * write, given by ifr_bdp. The prototype of the map register for
+ * read and for write is saved in ifr_proto.
+ *
+ * When write transfers are not full pages on page boundaries we just
+ * copy the data into the pages mapped on the UNIBUS and start the
+ * transfer. If a write transfer is of a (1024 byte) page on a page
+ * boundary, we swap in UNIBUS pte's to reference the pages, and then
+ * remap the initial pages (from ifu_wmap) when the transfer completes.
+ *
+ * When read transfers give whole pages of data to be input, we
+ * allocate page frames from a network page list and trade them
+ * with the pages already containing the data, mapping the allocated
+ * pages to replace the input pages for the next UNIBUS data input.
+ */
+
+/*
+ * Information per interface.
+ */
+struct ifubinfo {
+ short iff_uban; /* uba number */
+ short iff_hlen; /* local net header length */
+ struct uba_regs *iff_uba; /* uba adaptor regs, in vm */
+ struct pte *iff_ubamr; /* uba map regs, in vm */
+ short iff_flags; /* used during uballoc's */
+};
+
+/*
+ * Information per buffer.
+ */
+struct ifrw {
+ caddr_t ifrw_addr; /* virt addr of header */
+ short ifrw_bdp; /* unibus bdp */
+ short ifrw_flags; /* type, etc. */
+#define IFRW_W 0x01 /* is a transmit buffer */
+ int ifrw_info; /* value from ubaalloc */
+ int ifrw_proto; /* map register prototype */
+ struct pte *ifrw_mr; /* base of map registers */
+};
+
+/*
+ * Information per transmit buffer, including the above.
+ */
+struct ifxmt {
+ struct ifrw ifrw;
+ caddr_t ifw_base; /* virt addr of buffer */
+ struct pte ifw_wmap[IF_MAXNUBAMR]; /* base pages for output */
+ struct mbuf *ifw_xtofree; /* pages being dma'd out */
+ short ifw_xswapd; /* mask of clusters swapped */
+ short ifw_nmr; /* number of entries in wmap */
+};
+#define ifw_addr ifrw.ifrw_addr
+#define ifw_bdp ifrw.ifrw_bdp
+#define ifw_flags ifrw.ifrw_flags
+#define ifw_info ifrw.ifrw_info
+#define ifw_proto ifrw.ifrw_proto
+#define ifw_mr ifrw.ifrw_mr
+
+/*
+ * Most interfaces have a single receive and a single transmit buffer,
+ * and use struct ifuba to store all of the unibus information.
+ */
+struct ifuba {
+ struct ifubinfo ifu_info;
+ struct ifrw ifu_r;
+ struct ifxmt ifu_xmt;
+};
+
+#define ifu_uban ifu_info.iff_uban
+#define ifu_hlen ifu_info.iff_hlen
+#define ifu_uba ifu_info.iff_uba
+#define ifu_ubamr ifu_info.iff_ubamr
+#define ifu_flags ifu_info.iff_flags
+#define ifu_w ifu_xmt.ifrw
+#define ifu_xtofree ifu_xmt.ifw_xtofree
+
+#ifdef _KERNEL
+#define if_ubainit(ifuba, uban, hlen, nmr) \
+ if_ubaminit(&(ifuba)->ifu_info, uban, hlen, nmr, \
+ &(ifuba)->ifu_r, 1, &(ifuba)->ifu_xmt, 1)
+#define if_rubaget(ifu, totlen, off0, ifp) \
+ if_ubaget(&(ifu)->ifu_info, &(ifu)->ifu_r, totlen, off0, ifp)
+#define if_wubaput(ifu, m) \
+ if_ubaput(&(ifu)->ifu_info, &(ifu)->ifu_xmt, m)
+struct mbuf *if_ubaget();
+#endif
diff --git a/sys/arch/vax/include/ansi.h b/sys/arch/vax/include/ansi.h
new file mode 100644
index 00000000000..5af1f55f91a
--- /dev/null
+++ b/sys/arch/vax/include/ansi.h
@@ -0,0 +1,60 @@
+/* $NetBSD: ansi.h,v 1.3 1994/10/26 08:01:59 cgd Exp $ */
+
+/*-
+ * Copyright (c) 1990 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.
+ *
+ * @(#)ansi.h 7.1 (Berkeley) 3/9/91
+ */
+
+#ifndef _ANSI_H_
+#define _ANSI_H_
+
+/*
+ * Types which are fundamental to the implementation and may appear in
+ * more than one standard header are defined here. Standard headers
+ * then use:
+ * #ifdef _SIZE_T_
+ * typedef _SIZE_T_ size_t;
+ * #undef _SIZE_T_
+ * #endif
+ *
+ * Thanks, ANSI!
+ */
+#define _BSD_CLOCK_T_ unsigned long /* clock() */
+#define _BSD_PTRDIFF_T_ int /* ptr1 - ptr2 */
+#define _BSD_SIZE_T_ unsigned int /* sizeof() */
+#define _BSD_SSIZE_T_ int /* byte count or error */
+#define _BSD_TIME_T_ long /* time() */
+#define _BSD_VA_LIST_ char * /* va_list */
+#define _BSD_WCHAR_T_ int /* wchar_t */
+
+#endif /* _ANSI_H_ */
diff --git a/sys/arch/vax/include/asm.h b/sys/arch/vax/include/asm.h
new file mode 100644
index 00000000000..e175b77bdc2
--- /dev/null
+++ b/sys/arch/vax/include/asm.h
@@ -0,0 +1,76 @@
+/* $NetBSD: asm.h,v 1.3 1995/05/03 19:53:40 ragge Exp $ */
+
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * 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.
+ *
+ * @(#)asm.h 5.5 (Berkeley) 5/7/91
+ * @(#)DEFS.h 5.3 (Berkeley) 6/1/90
+ */
+
+#ifndef _MACHINE_ASM_H_
+#define _MACHINE_ASM_H_
+
+#define R0 0x001
+#define R1 0x002
+#define R2 0x004
+#define R3 0x008
+#define R4 0x010
+#define R5 0x020
+#define R6 0x040
+#define R7 0x080
+#define R8 0x100
+#define R9 0x200
+#define R10 0x400
+#define R11 0x800
+
+#ifdef __STDC__
+# define _FUNC(x) _ ## x ## :
+# define _GLOB(x) .globl _ ## x
+#else
+# define _FUNC(x) _/**/x:
+# define _GLOB(x) .globl _/**/x
+#endif
+
+#ifdef PROF
+#define ENTRY(x,regs) \
+ _GLOB(x);.align 2;_FUNC(x);.word regs;jsb mcount;
+#else
+#define ENTRY(x,regs) \
+ _GLOB(x);.align 2;_FUNC(x);.word regs;
+#endif
+
+#define ASMSTR .asciz
+
+#endif /* !_MACHINE_ASM_H_ */
diff --git a/sys/arch/vax/include/cdefs.h b/sys/arch/vax/include/cdefs.h
new file mode 100644
index 00000000000..0468cc9e196
--- /dev/null
+++ b/sys/arch/vax/include/cdefs.h
@@ -0,0 +1,35 @@
+/* $NetBSD: cdefs.h,v 1.2 1995/03/23 20:10:53 jtc Exp $ */
+
+/*
+ * Written by J.T. Conklin <jtc@wimsey.com> 01/17/95.
+ * Public domain.
+ */
+
+#ifndef _MACHINE_CDEFS_H_
+#define _MACHINE_CDEFS_H_
+
+#ifdef __STDC__
+#define _C_LABEL(x) _STRING(_ ## x)
+#else
+#define _C_LABEL(x) _STRING(_/**/x)
+#endif
+
+#ifdef __GNUC__
+#ifdef __STDC__
+#define __indr_reference(sym,alias) \
+ __asm__(".stabs \"_" #alias "\",11,0,0,0"); \
+ __asm__(".stabs \"_" #sym "\",1,0,0,0")
+#define __warn_references(sym,msg) \
+ __asm__(".stabs \"" msg "\",30,0,0,0"); \
+ __asm__(".stabs \"_" #sym "\",1,0,0,0")
+#else
+#define __indr_reference(sym,alias) \
+ __asm__(".stabs \"_/**/alias\",11,0,0,0"); \
+ __asm__(".stabs \"_/**/sym\",1,0,0,0")
+#define __warn_references(sym,msg) \
+ __asm__(".stabs msg,30,0,0,0"); \
+ __asm__(".stabs \"_/**/sym\",1,0,0,0")
+#endif
+#endif
+
+#endif /* !_MACHINE_CDEFS_H_ */
diff --git a/sys/arch/vax/include/cpu.h b/sys/arch/vax/include/cpu.h
new file mode 100644
index 00000000000..b7cdd1855a1
--- /dev/null
+++ b/sys/arch/vax/include/cpu.h
@@ -0,0 +1,88 @@
+/* $NetBSD: cpu.h,v 1.12 1995/06/05 17:17:57 ragge Exp $ */
+
+/*
+ * Copyright (c) 1994 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}
+ * 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 "sys/cdefs.h"
+#include "machine/mtpr.h"
+#include "machine/pcb.h"
+
+#define enablertclock()
+#define cpu_wait(p)
+#define cpu_swapout(p)
+
+
+extern volatile int cpunumber;
+extern struct cpu_dep cpu_calls[];
+
+struct cpu_dep {
+ int (*cpu_loinit)(); /* Locore init before everything else */
+ int (*cpu_clock)(); /* CPU dependent clock handling */
+ int (*cpu_mchk)(); /* Machine check handling */
+ int (*cpu_memerr)(); /* Memory subsystem errors */
+ int (*cpu_conf)(); /* Autoconfiguration */
+};
+
+struct clockframe {
+ int pc;
+ int ps;
+};
+
+#define setsoftnet() mtpr(12,PR_SIRR)
+#define setsoftclock() mtpr(8,PR_SIRR)
+
+/*
+ * Preempt the current process if in interrupt from user mode,
+ * or after the current trap/syscall if in system mode.
+ */
+
+#define need_resched(){ \
+ want_resched++; \
+ mtpr(AST_OK,PR_ASTLVL); \
+ }
+
+/*
+ * Notify the current process (p) that it has a signal pending,
+ * process as soon as possible.
+ */
+
+#define signotify(p) mtpr(AST_OK,PR_ASTLVL);
+
+extern int want_resched; /* resched() was called */
+
+/*
+ * Give a profiling tick to the current process when the user profiling
+ * buffer pages are invalid. On the hp300, request an ast to send us
+ * through trap, marking the proc as needing a profiling tick.
+ */
+#define need_proftick(p) {(p)->p_flag |= P_OWEUPC; mtpr(AST_OK,PR_ASTLVL); }
+
diff --git a/sys/arch/vax/include/db_machdep.h b/sys/arch/vax/include/db_machdep.h
new file mode 100644
index 00000000000..b2a9fd68642
--- /dev/null
+++ b/sys/arch/vax/include/db_machdep.h
@@ -0,0 +1,73 @@
+/* $NetBSD: db_machdep.h,v 1.1 1995/06/16 15:17:27 ragge Exp $ */
+
+/*
+ * Mach Operating System
+ * Copyright (c) 1991,1990 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+
+#ifndef _VAX_DB_MACHDEP_H_
+#define _VAX_DB_MACHDEP_H_
+
+/*
+ * Machine-dependent defines for new kernel debugger.
+ * Modified for vax out of i386 code.
+ */
+
+#include <sys/param.h>
+#include <vm/vm.h>
+#include <machine/trap.h>
+
+typedef vm_offset_t db_addr_t; /* address - unsigned */
+typedef int db_expr_t; /* expression - signed */
+
+typedef struct trapframe db_regs_t;
+db_regs_t ddb_regs; /* register state */
+#define DDB_REGS (&ddb_regs)
+
+#define PC_REGS(regs) ((db_addr_t)(regs)->pc)
+
+#define BKPT_INST 0x03 /* breakpoint instruction */
+#define BKPT_SIZE (1) /* size of breakpoint inst */
+#define BKPT_SET(inst) (BKPT_INST)
+
+#define FIXUP_PC_AFTER_BREAK ddb_regs.pc -= BKPT_SIZE;
+
+#define db_clear_single_step(regs) ((regs)->psl &= ~PSL_T)
+#define db_set_single_step(regs) ((regs)->psl |= PSL_T)
+
+#define IS_BREAKPOINT_TRAP(type, code) ((type) == T_BPTFLT)
+#define IS_WATCHPOINT_TRAP(type, code) ((type) == T_TRCTRAP)
+
+#define I_CALL 0xfb
+#define I_RET 0x04
+#define I_IRET 0x02
+
+#define inst_trap_return(ins) (((ins)&0xff) == I_IRET)
+#define inst_return(ins) (((ins)&0xff) == I_RET)
+#define inst_call(ins) (((ins)&0xff) == I_CALL)
+
+#define inst_load(ins) 0
+#define inst_store(ins) 0
+
+#endif /* _VAX_DB_MACHDEP_H_ */
diff --git a/sys/arch/vax/include/disklabel.h b/sys/arch/vax/include/disklabel.h
new file mode 100644
index 00000000000..e1505c58f6c
--- /dev/null
+++ b/sys/arch/vax/include/disklabel.h
@@ -0,0 +1,47 @@
+/* $NetBSD: disklabel.h,v 1.2 1995/05/03 19:53:44 ragge Exp $ */
+
+/*
+ * Copyright (c) 1994 Christopher G. Demetriou
+ * 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 Christopher G. Demetriou.
+ * 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.
+ */
+
+#ifndef _MACHINE_DISKLABEL_H_
+#define _MACHINE_DISKLABEL_H_
+
+#define LABELSECTOR 0 /* sector containing label */
+#define LABELOFFSET 64 /* offset of label in sector */
+#define MAXPARTITIONS 8 /* number of partitions */
+#define RAW_PART 3 /* raw partition: xx?c (XXX) */
+
+/* Just a dummy */
+#ifndef LOCORE
+struct cpu_disklabel {
+ int cd_dummy; /* must have one element. */
+};
+#endif
+#endif /* _MACHINE_DISKLABEL_H_ */
diff --git a/sys/arch/vax/include/endian.h b/sys/arch/vax/include/endian.h
new file mode 100644
index 00000000000..05e1526909c
--- /dev/null
+++ b/sys/arch/vax/include/endian.h
@@ -0,0 +1,112 @@
+/* $NetBSD: endian.h,v 1.6 1995/08/21 16:36:32 ragge Exp $ */
+
+/*
+ * Copyright (c) 1987, 1991 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.
+ *
+ * @(#)endian.h 7.8 (Berkeley) 4/3/91
+ */
+
+#ifndef _VAX_ENDIAN_H_
+#define _VAX_ENDIAN_H_
+
+#define _QUAD_HIGHWORD 1
+#define _QUAD_LOWWORD 0
+
+#ifndef _POSIX_SOURCE
+
+/*
+ * Definitions for byte order, according to byte significance from low
+ * address to high.
+ */
+#define LITTLE_ENDIAN 1234 /* LSB first: i386, vax */
+#define BIG_ENDIAN 4321 /* MSB first: 68000, ibm, net */
+#define PDP_ENDIAN 3412 /* LSB first in word, MSW first in long */
+
+#define BYTE_ORDER LITTLE_ENDIAN
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+unsigned long htonl __P((unsigned long));
+unsigned short htons __P((unsigned short));
+unsigned long ntohl __P((unsigned long));
+unsigned short ntohs __P((unsigned short));
+__END_DECLS
+
+#ifdef __GNUC__
+
+#define __byte_swap_long_variable(x) \
+({ register unsigned long __y, __x = (x); \
+ \
+ __asm ("rotl $-8, %1, %0; \
+ insv %0, $16, $8, %0; \
+ rotl $8, %1, r1; \
+ movb r1, %0" \
+ : "&=r" (__y) \
+ : "r" (__x) \
+ : "r1", "cc" ); \
+ __y; })
+
+#define __byte_swap_word_variable(x) \
+({ register unsigned short __y, __x = (x); \
+ \
+ __asm ("rotl $8, %1, %0; \
+ rotl $-8, %1, r1; \
+ movb r1, %0; \
+ movzwl %0, %0" \
+ : "&=r" (__y) \
+ : "r" (__x) \
+ : "r1", "cc" ); \
+ __y; })
+
+
+#define __byte_swap_long(x) __byte_swap_long_variable(x)
+#define __byte_swap_word(x) __byte_swap_word_variable(x)
+
+#define ntohl(x) __byte_swap_long(x)
+#define ntohs(x) __byte_swap_word(x)
+#define htonl(x) __byte_swap_long(x)
+#define htons(x) __byte_swap_word(x)
+
+#endif /* __GNUC__ */
+
+/*
+ * Macros for network/external number representation conversion.
+ */
+#define NTOHL(x) (x) = ntohl((unsigned long)(x))
+#define NTOHS(x) (x) = ntohs((unsigned long)(x))
+#define HTONL(x) (x) = htonl((unsigned long)(x))
+#define HTONS(x) (x) = htons((unsigned long)(x))
+
+#endif /* _POSIX_SOURCE */
+
+#endif /* _VAX_ENDIAN_H_ */
diff --git a/sys/arch/vax/include/exec.h b/sys/arch/vax/include/exec.h
new file mode 100644
index 00000000000..3493e317afa
--- /dev/null
+++ b/sys/arch/vax/include/exec.h
@@ -0,0 +1,49 @@
+/* $NetBSD: exec.h,v 1.4 1995/09/23 14:57:40 ragge Exp $ */
+
+/*
+ * Copyright (c) 1993 Christopher G. Demetriou
+ * 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. 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.
+ */
+
+#ifndef _VAX_EXEC_H_
+#define _VAX_EXEC_H_
+
+#define __LDPGSZ 1024
+
+/* Relocation format. */
+struct relocation_info_vax {
+ int r_address; /* offset in text or data segment */
+ unsigned int r_symbolnum : 24, /* ordinal number of add symbol */
+ r_pcrel : 1, /* 1 if value should be pc-relative */
+ r_length : 2, /* log base 2 of value's width */
+ r_extern : 1, /* 1 if need to add symbol to value */
+ r_baserel : 1, /* linkage table relative */
+ r_jmptable : 1, /* relocate to jump table */
+ r_relative : 1, /* load address relative */
+ r_copy : 1; /* run time copy */
+};
+#define relocation_info relocation_info_vax
+
+#endif /* _VAX_EXEC_H_ */
diff --git a/sys/arch/vax/include/float.h b/sys/arch/vax/include/float.h
new file mode 100644
index 00000000000..4ec3fa86baf
--- /dev/null
+++ b/sys/arch/vax/include/float.h
@@ -0,0 +1,69 @@
+/* $NetBSD: float.h,v 1.2 1994/10/26 08:02:08 cgd Exp $ */
+
+/*
+ * Copyright (c) 1989 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.
+ *
+ * @(#)float.h 7.2 (Berkeley) 6/28/90
+ */
+
+#define FLT_RADIX 2 /* b */
+#define FLT_ROUNDS 1 /* FP addition rounds to nearest */
+
+#define FLT_MANT_DIG 24 /* p */
+#define FLT_EPSILON 1.19209290E-07F /* b**(1-p) */
+#define FLT_DIG 6 /* floor((p-1)*log10(b))+(b == 10) */
+#define FLT_MIN_EXP -127 /* emin */
+#define FLT_MIN 2.93873588E-39F /* b**(emin-1) */
+#define FLT_MIN_10_EXP -38 /* ceil(log10(b**(emin-1))) */
+#define FLT_MAX_EXP 127 /* emax */
+#define FLT_MAX 1.70141173E+38F /* (1-b**(-p))*b**emax */
+#define FLT_MAX_10_EXP 38 /* floor(log10((1-b**(-p))*b**emax)) */
+
+#define DBL_MANT_DIG 56
+#define DBL_EPSILON 2.775557561562891351E-17
+#define DBL_DIG 16
+#define DBL_MIN_EXP -127
+#define DBL_MIN 2.938735877055718770E-39
+#define DBL_MIN_10_EXP -38
+#define DBL_MAX_EXP 127
+#define DBL_MAX 1.701411834604692294E+38
+#define DBL_MAX_10_EXP 38
+
+#define LDBL_MANT_DIG DBL_MANT_DIG
+#define LDBL_EPSILON DBL_EPSILON
+#define LDBL_DIG DBL_DIG
+#define LDBL_MIN_EXP DBL_MIN_EXP
+#define LDBL_MIN DBL_MIN
+#define LDBL_MIN_10_EXP DBL_MIN_10_EXP
+#define LDBL_MAX_EXP DBL_MAX_EXP
+#define LDBL_MAX DBL_MAX
+#define LDBL_MAX_10_EXP DBL_MAX_10_EXP
diff --git a/sys/arch/vax/include/ioa.h b/sys/arch/vax/include/ioa.h
new file mode 100644
index 00000000000..b09da95056f
--- /dev/null
+++ b/sys/arch/vax/include/ioa.h
@@ -0,0 +1,36 @@
+/* $NetBSD: ioa.h,v 1.2 1994/10/26 08:02:09 cgd Exp $ */
+
+/*
+ * Copyright (c) 1994 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}.
+ * 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 */
+
+
+
diff --git a/sys/arch/vax/include/ka750.h b/sys/arch/vax/include/ka750.h
new file mode 100644
index 00000000000..c6c0b494fa4
--- /dev/null
+++ b/sys/arch/vax/include/ka750.h
@@ -0,0 +1,41 @@
+/* $NetBSD: ka750.h,v 1.2 1994/10/26 08:02:10 cgd Exp $ */
+
+/*
+ * Copyright (c) 1994 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}.
+ * 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 */
+
+
+
+/* ka750.h - definitioner enbart f|r VAX 750 940328/ragge */
+
+#define V750UCODE(x) ((x>>8)&255)
+#define V750HARDW(x) (x&255)
+
diff --git a/sys/arch/vax/include/kg.h b/sys/arch/vax/include/kg.h
new file mode 100644
index 00000000000..e37e6f94c2c
--- /dev/null
+++ b/sys/arch/vax/include/kg.h
@@ -0,0 +1,36 @@
+/* $NetBSD: kg.h,v 1.2 1994/10/26 08:02:11 cgd Exp $ */
+
+/*
+ * Copyright (c) 1994 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}.
+ * 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 */
+
+
+
diff --git a/sys/arch/vax/include/limits.h b/sys/arch/vax/include/limits.h
new file mode 100644
index 00000000000..06d3f52e852
--- /dev/null
+++ b/sys/arch/vax/include/limits.h
@@ -0,0 +1,85 @@
+/* $NetBSD: limits.h,v 1.5 1995/05/28 18:38:30 ragge Exp $ */
+
+/*
+ * Copyright (c) 1988 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.
+ *
+ * @(#)limits.h 7.2 (Berkeley) 6/28/90
+ */
+
+#define CHAR_BIT 8 /* number of bits in a char */
+/* #define CLK_TCK 60 /* ticks per second */
+#define MB_LEN_MAX 1 /* no multibyte characters */
+
+#define SCHAR_MIN (-0x7f-1) /* min value for a signed char */
+#define SCHAR_MAX 0x7f /* max value for a signed char */
+
+#define UCHAR_MAX 0xff /* max value for an unsigned char */
+#define CHAR_MAX 0x7f /* max value for a char */
+#define CHAR_MIN (-0x7f-1) /* min value for a char */
+
+#define USHRT_MAX 0xffff /* max value for an unsigned short */
+#define SHRT_MAX 0x7fff /* max value for a short */
+#define SHRT_MIN (-0x7fff-1) /* min value for a short */
+
+#define UINT_MAX 0xffffffffU /* max value for an unsigned int */
+#define INT_MAX 0x7fffffff /* max value for an int */
+#define INT_MIN (-0x7fffffff-1) /* min value for an int */
+
+#define ULONG_MAX 0xffffffffUL /* max value for an unsigned long */
+#define LONG_MAX 0x7fffffffL /* max value for a long */
+#define LONG_MIN (-0x7fffffffL-1)/* min value for a long */
+
+#if !defined(_ANSI_SOURCE)
+#define SSIZE_MAX INT_MAX /* max value for a ssize_t */
+
+#if !defined(_POSIX_SOURCE) && !defined(_XOPEN_SOURCE)
+#define SIZE_T_MAX UINT_MAX /* max value for a size_t */
+
+#define UQUAD_MAX 0xffffffffffffffffULL /* max unsigned quad */
+#define QUAD_MAX 0x7fffffffffffffffLL /* max signed quad */
+#define QUAD_MIN (-0x7fffffffffffffffLL-1) /* min signed quad */
+
+#endif /* !_POSIX_SOURCE && !_XOPEN_SOURCE */
+#endif /* !_ANSI_SOURCE */
+
+#if (!defined(_ANSI_SOURCE)&&!defined(_POSIX_SOURCE)) || defined(_XOPEN_SOURCE)
+#define LONG_BIT 32
+#define WORD_BIT 32
+
+#define DBL_DIG 16
+#define DBL_MAX 1.701411834604692294E+38
+#define DBL_MIN 2.938735877055718770E-39
+
+#define FLT_DIG 6
+#define FLT_MAX 1.70141173E+38F
+#define FLT_MIN 2.93873588E-39F
+#endif
diff --git a/sys/arch/vax/include/loconf.h b/sys/arch/vax/include/loconf.h
new file mode 100644
index 00000000000..62fb2f2b802
--- /dev/null
+++ b/sys/arch/vax/include/loconf.h
@@ -0,0 +1,57 @@
+/* $NetBSD: loconf.h,v 1.2 1994/10/26 08:02:13 cgd Exp $ */
+
+/*
+ * Copyright (c) 1994 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}.
+ * 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 */
+
+
+
+
+
+#define ISTACK_SIZE 4*NBPG
+
+/* XXX If kernel never crashes with kernel stack overflow trap
+ * kstack can be removed altogether. (Was 4*NBPG)
+ */
+
+#define PROC_PAGES 0
+
+#define MAX_UCODE 1024*1024*6
+#define MAX_UDATA 1024*1024*32
+#define MAX_USTCK 1024*1024*8
+
+#define MAX_PROCESSES 32
+
+#define PROCOFFSET (MAX_UCODE+MAX_UDATA+MAX_USTCK)/16384
+
+/* Add 1 to USERPAGES if (MAX_PROCESSES mod 8) != 0 */
+
+#define USERPAGES (MAX_UCODE+MAX_UDATA+MAX_USTCK)*MAX_PROCESSES/(512*128*128)
diff --git a/sys/arch/vax/include/macros.h b/sys/arch/vax/include/macros.h
new file mode 100644
index 00000000000..eb2dc2b9fd1
--- /dev/null
+++ b/sys/arch/vax/include/macros.h
@@ -0,0 +1,220 @@
+/* $NetBSD: macros.h,v 1.4 1995/07/05 08:22:21 ragge Exp $ */
+
+/*
+ * Copyright (c) 1994 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}.
+ * 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 */
+
+#if !defined(_VAX_MACROS_H_)&&!defined(ASSEMBLER)&&defined(_VAX_INLINE_)
+#define _VAX_MACROS_H_
+
+/* Here general macros are supposed to be stored */
+
+static __inline__ int ffs(int reg){
+ register int val;
+
+ asm __volatile ("ffs $0,$32,%1,%0
+ bneq 1f
+ mnegl $1,%0
+ 1: incl %0"
+ : "&=r" (val)
+ : "r" (reg) );
+ return val;
+}
+
+static __inline__ void _remque(void*p){
+ asm __volatile ("remque (%0),%0;clrl 4(%0)"
+ :
+ : "r" (p)
+ : "memory" );
+}
+
+static __inline__ void _insque(void*p, void*q) {
+ asm __volatile ("insque (%0), (%1)"
+ :
+ : "r" (p),"r" (q)
+ : "memory" );
+}
+
+#define bitset(bitnr,var) \
+({ asm __volatile ("bbss %0,%1,1f;1:;" \
+ : \
+ : "g" (bitnr), "g" (var)); \
+})
+
+#define bitclear(bitnr,var) \
+({ asm __volatile ("bbsc %0,%1,1f;1:;" \
+ : \
+ : "g" (bitnr), "g" (var)); \
+})
+
+#define bitisset(bitnr,var) \
+({ \
+ register int val; \
+ asm __volatile ("clrl %0;bbc %1,%2,1f;incl %0;1:;" \
+ : "=g" (val) \
+ : "g" (bitnr), "g" (var)); \
+ val; \
+})
+
+#define bitisclear(bitnr,var) \
+({ \
+ register int val; \
+ asm __volatile ("clrl %0;bbs %1,%2,1f;incl %0;1:;" \
+ : "=g" (val) \
+ : "g" (bitnr), "g" (var)); \
+ val; \
+})
+static __inline__ void bcopy(const void*from, void*toe, u_int len) {
+ asm __volatile ("movc3 %0,(%1),(%2)"
+ :
+ : "r" (len),"r" (from),"r"(toe)
+ :"r0","r1","r2","r3","r4","r5");
+}
+
+static __inline__ void bzero(void*block, u_int len){
+ asm __volatile ("movc5 $0,(%0),$0,%1,(%0)"
+ :
+ : "r" (block), "r" (len)
+ :"r0","r1","r2","r3","r4","r5");
+}
+
+static __inline__ int bcmp(const void *b1, const void *b2, size_t len){
+ register ret;
+
+ asm __volatile("cmpc3 %3,(%1),(%2);movl r0,%0"
+ : "=r" (ret)
+ : "r" (b1), "r" (b2), "r" (len)
+ : "r0","r1","r2","r3" );
+ return ret;
+}
+
+static __inline__ int locc(int mask, char *cp,u_int size){
+ register ret;
+
+ asm __volatile("locc %1,%2,(%3);movl r0,%0"
+ : "=r" (ret)
+ : "r" (mask),"r"(size),"r"(cp)
+ : "r0","r1" );
+ return ret;
+}
+
+static __inline__ int scanc(u_int size, u_char *cp,u_char *table, int mask){
+ register ret;
+
+ asm __volatile("scanc %1,(%2),(%3),%4;movl r0,%0"
+ : "=g"(ret)
+ : "r"(size),"r"(cp),"r"(table),"r"(mask)
+ : "r0","r1","r2","r3" );
+ return ret;
+}
+
+static __inline__ int skpc(int mask, int size, char *cp){
+ register ret;
+
+ asm __volatile("skpc %1,%2,(%3);movl r0,%0"
+ : "=g"(ret)
+ : "r"(mask),"r"(size),"r"(cp)
+ : "r0","r1" );
+ return ret;
+}
+#if 0
+static __inline__ int imin(int a, int b){
+ asm __volatile("cmpl %0,%2;bleq 1f;movl %2,%0;1:"
+ : "=r"(a)
+ : "r"(a),"r"(b) );
+ return a;
+}
+
+static __inline__ int imax(int a, int b){
+ asm __volatile("cmpl %0,%2;bgeq 1f;movl %2,%0;1:"
+ : "=r"(a)
+ : "r"(a),"r"(b) );
+ return a;
+}
+
+static __inline__ int min(int a, int b){
+ asm __volatile("cmpl %0,%2;bleq 1f;movl %2,%0;1:"
+ : "=r"(a)
+ : "r"(a),"r"(b) );
+ return a;
+}
+
+static __inline__ int max(int a, int b){
+ asm __volatile("cmpl %0,%2;bgeq 1f;movl %2,%0;1:"
+ : "=r"(a)
+ : "r"(a),"r"(b) );
+ return a;
+}
+#endif
+
+#define waitabit(tid) \
+({ \
+ asm __volatile ("mfpr $27,r0;addl2 %0,r0;1:;mfpr $27,r1; \
+ cmpl r0,r1;bneq 1b;" \
+ : \
+ : "g"(tid) \
+ : "r0","r1"); \
+})
+
+static __inline__ void blkcpy(const void*from, void*to, u_int len) {
+ asm __volatile("
+ movl %0,r1
+ movl %1,r3
+ movl %2,r6
+ jbr 2f
+ 1: subl2 r0,r6
+ movc3 r0,(r1),(r3)
+ 2: movzwl $65535,r0
+ cmpl r6,r0
+ jgtr 1b
+ movc3 r6,(r1),(r3)"
+ :
+ : "g" (from), "g" (to), "g" (len)
+ : "r0","r1","r2","r3","r4","r5", "r6" );
+}
+
+static __inline__ void blkclr(void *blk, int len) {
+ asm __volatile("
+ movl %0, r3
+ movl %1, r6
+ jbr 2f
+ 1: subl2 r0, r6
+ movc5 $0,(r3),$0,r0,(r3)
+ 2: movzwl $65535,r0
+ cmpl r6, r0
+ jgtr 1b
+ movc5 $0,(r3),$0,r6,(r3)"
+ :
+ : "g" (blk), "g" (len)
+ : "r0","r1","r2","r3","r4","r5", "r6" );
+}
+
+#endif /* _VAX_MACROS_H_ */
diff --git a/sys/arch/vax/include/mtpr.h b/sys/arch/vax/include/mtpr.h
new file mode 100644
index 00000000000..6da155b2f69
--- /dev/null
+++ b/sys/arch/vax/include/mtpr.h
@@ -0,0 +1,129 @@
+/* $NetBSD: mtpr.h,v 1.5 1995/05/03 19:53:45 ragge Exp $ */
+
+/*
+ * Copyright (c) 1994 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}.
+ * 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 */
+
+#ifndef _VAX_MTPR_H_
+#define _VAX_MTPR_H_
+
+#include "machine/macros.h"
+
+/******************************************************************************
+
+ Processor register numbers in the VAX /IC
+
+******************************************************************************/
+
+
+#define PR_KSP 0 /* Kernel Stack Pointer */
+#define PR_ESP 1 /* Executive Stack Pointer */
+#define PR_SSP 2 /* Supervisor Stack Pointer */
+#define PR_USP 3 /* User Stack Pointer */
+#define PR_ISP 4 /* Interrupt Stack Pointer */
+
+#define PR_P0BR 8 /* P0 Base Register */
+#define PR_P0LR 9 /* P0 Length Register */
+#define PR_P1BR 10 /* P1 Base Register */
+#define PR_P1LR 11 /* P1 Length Register */
+#define PR_SBR 12 /* System Base Register */
+#define PR_SLR 13 /* System Limit Register */
+#define PR_PCBB 16 /* Process Control Block Base */
+#define PR_SCBB 17 /* System Control Block Base */
+#define PR_IPL 18 /* Interrupt Priority Level */
+#define PR_ASTLVL 19 /* AST Level */
+#define PR_SIRR 20 /* Software Interrupt Request */
+#define PR_SISR 21 /* Software Interrupt Summary */
+#define PR_IPIR 22 /* KA820 Interprocessor register */
+#define PR_MCSR 23 /* Machine Check Status Register 11/750 */
+#define PR_ICCS 24 /* Interval Clock Control */
+#define PR_NICR 25 /* Next Interval Count */
+#define PR_ICR 26 /* Interval Count */
+#define PR_TODR 27 /* Time Of Year (optional) */
+#define PR_CSRS 28 /* Console Storage R/S */
+#define PR_CSRD 29 /* Console Storage R/D */
+#define PR_CSTS 30 /* Console Storage T/S */
+#define PR_CSTD 31 /* Console Storage T/D */
+#define PR_RXCS 32 /* Console Receiver C/S */
+#define PR_RXDB 33 /* Console Receiver D/B */
+#define PR_TXCS 34 /* Console Transmit C/S */
+#define PR_TXDB 35 /* Console Transmit D/B */
+#define PR_TBDR 36 /* Translation Buffer Group Disable Register 11/750 */
+#define PR_CADR 37 /* Cache Disable Register 11/750 */
+#define PR_MCESR 38 /* Machiune Check Error Summary Register 11/750 */
+#define PR_CAER 39 /* Cache Error Register 11/750 */
+#define PR_ACCS 40 /* Accelerator control register */
+#define PR_SAVISP 41 /* Console Saved ISP */
+#define PR_SAVPC 42 /* Console Saved PC */
+#define PR_SAVPSL 43 /* Console Saved PSL */
+#define PR_WCSA 44 /* WCS Address */
+#define PR_WCSB 45 /* WCS Data */
+#define PR_SBIFS 48 /* SBI Fault/Status */
+#define PR_SBIS 49 /* SBI Silo */
+#define PR_SBISC 50 /* SBI Silo Comparator */
+#define PR_SBIMT 51 /* SBI Silo Maintenance */
+#define PR_SBIER 52 /* SBI Error Register */
+#define PR_SBITA 53 /* SBI Timeout Address Register */
+#define PR_SBIQC 54 /* SBI Quadword Clear */
+#define PR_IUR 55 /* Initialize Unibus Register 11/750 */
+#define PR_MAPEN 56 /* Memory Management Enable */
+#define PR_TBIA 57 /* Trans. Buf. Invalidate All */
+#define PR_TBIS 58 /* Trans. Buf. Invalidate Single */
+#define PR_TBDATA 59 /* Translation Buffer Data */
+#define PR_MBRK 60 /* Microprogram Break */
+#define PR_PMR 61 /* Performance Monnitor Enable */
+#define PR_SID 62 /* System ID Register */
+#define PR_TBCHK 63 /* Translation Buffer Check */
+
+/* Definitions for AST */
+#define AST_NO 4
+#define AST_OK 3
+
+#ifndef ASSEMBLER
+
+#define mtpr(val,reg) \
+{ \
+ asm __volatile ("mtpr %0,%1" \
+ : /* No output */ \
+ : "g" (val), "g" (reg)); \
+}
+
+#define mfpr(reg) \
+({ \
+ register int val; \
+ asm __volatile ("mfpr %1,%0" \
+ : "=g" (val) \
+ : "g" (reg)); \
+ val; \
+})
+#endif /* ASSEMBLER */
+
+#endif /* _VAX_MTPR_H_ */
diff --git a/sys/arch/vax/include/nexus.h b/sys/arch/vax/include/nexus.h
new file mode 100644
index 00000000000..a4c9a8ce678
--- /dev/null
+++ b/sys/arch/vax/include/nexus.h
@@ -0,0 +1,179 @@
+/* $NetBSD: nexus.h,v 1.4 1995/02/23 17:51:42 ragge Exp $ */
+
+/*-
+ * Copyright (c) 1982, 1986 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.
+ *
+ * @(#)nexus.h 7.3 (Berkeley) 5/9/91
+ */
+
+/*
+ * Information about nexus's.
+ *
+ * Each machine has an address of backplane slots (nexi).
+ * Each nexus is some type of adapter, whose code is the low
+ * byte of the first word of the adapter address space.
+ * At boot time the system looks through the array of available
+ * slots and finds the interconnects for the machine.
+ */
+#define IO_CMI750 2
+#define MAXNMCR 1
+
+#define NNEXSBI 16
+#if VAX8600
+#define NNEX8600 NNEXSBI
+#define NEXA8600 ((struct nexus *)(0x20000000))
+#define NEXB8600 ((struct nexus *)(0x22000000))
+#endif
+#if VAX780
+#define NNEX780 NNEXSBI
+#define NEX780 ((struct nexus *)0x20000000)
+#endif
+#if VAX750
+#define NNEX750 NNEXSBI
+#ifndef ASSEMBLER
+#define NEX750 ((struct nexus*)0xf20000)
+#else
+#define NEX750 (0xF20000)
+#endif
+#endif
+#if VAX730
+#define NNEX730 NNEXSBI
+#define NEX730 ((struct nexus *)0xf20000)
+#endif
+#if VAX630
+#define NNEX630 1
+#define NEX630 ((struct nexus *)0x20088000)
+#endif
+#define NEXSIZE 0x2000
+
+#if VAX8600
+#define MAXNNEXUS (2 * NNEXSBI)
+#else
+#define MAXNNEXUS NNEXSBI
+#endif
+
+#ifndef ASSEMBLER
+
+#include "sys/types.h"
+
+struct nexus {
+ union nexcsr {
+ long nex_csr;
+ u_char nex_type;
+ } nexcsr;
+ long nex_pad[NEXSIZE / sizeof (long) - 1];
+};
+
+struct sbi_attach_args {
+ u_int nexnum;
+ u_int type;
+ void *nexaddr;
+};
+
+struct iobus {
+ int io_type;
+ int io_addr;
+ int io_size;
+ int io_details;
+};
+
+struct nexusconnect {
+ int psb_nnexus;
+ struct nexus *psb_nexbase;
+ int psb_ubatype;
+ int psb_nubabdp;
+ caddr_t *psb_umaddr;
+ int *psb_nextype;
+};
+
+extern caddr_t *nex_vec;
+#define nex_vec_num(ipl, nexnum) nex_vec[(ipl-14)*16+nexnum]
+
+#endif
+
+/*
+ * Bits in high word of nexus's.
+ */
+#define SBI_PARFLT (1<<31) /* sbi parity fault */
+#define SBI_WSQFLT (1<<30) /* write sequence fault */
+#define SBI_URDFLT (1<<29) /* unexpected read data fault */
+#define SBI_ISQFLT (1<<28) /* interlock sequence fault */
+#define SBI_MXTFLT (1<<27) /* multiple transmitter fault */
+#define SBI_XMTFLT (1<<26) /* transmit fault */
+
+#define NEX_CFGFLT (0xfc000000)
+
+#ifndef LOCORE
+#if defined(VAX780) || defined(VAX8600)
+#define NEXFLT_BITS \
+"\20\40PARFLT\37WSQFLT\36URDFLT\35ISQFLT\34MXTFLT\33XMTFLT"
+#endif
+#endif
+
+#define NEX_APD (1<<23) /* adaptor power down */
+#define NEX_APU (1<<22) /* adaptor power up */
+
+#define MBA_OT (1<<21) /* overtemperature */
+
+#define UBA_UBINIT (1<<18) /* unibus init */
+#define UBA_UBPDN (1<<17) /* unibus power down */
+#define UBA_UBIC (1<<16) /* unibus initialization complete */
+
+/*
+ * Types for nex_type.
+ */
+#define NEX_ANY 0 /* pseudo for handling 11/750 */
+#define NEX_MEM4 0x08 /* 4K chips, non-interleaved mem */
+#define NEX_MEM4I 0x09 /* 4K chips, interleaved mem */
+#define NEX_MEM16 0x10 /* 16K chips, non-interleaved mem */
+#define NEX_MEM16I 0x11 /* 16K chips, interleaved mem */
+#define NEX_MBA 0x20 /* Massbus adaptor */
+#define NEX_UBA0 0x28 /* Unibus adaptor */
+#define NEX_UBA1 0x29 /* 4 flavours for 4 addr spaces */
+#define NEX_UBA2 0x2a
+#define NEX_UBA3 0x2b
+#define NEX_DR32 0x30 /* DR32 user i'face to SBI */
+#define NEX_CI 0x38 /* CI adaptor */
+#define NEX_MPM0 0x40 /* Multi-port mem */
+#define NEX_MPM1 0x41 /* Who knows why 4 different ones ? */
+#define NEX_MPM2 0x42
+#define NEX_MPM3 0x43
+#define NEX_MEM64L 0x68 /* 64K chips, non-interleaved, lower */
+#define NEX_MEM64LI 0x69 /* 64K chips, ext-interleaved, lower */
+#define NEX_MEM64U 0x6a /* 64K chips, non-interleaved, upper */
+#define NEX_MEM64UI 0x6b /* 64K chips, ext-interleaved, upper */
+#define NEX_MEM64I 0x6c /* 64K chips, interleaved */
+#define NEX_MEM256L 0x70 /* 256K chips, non-interleaved, lower */
+#define NEX_MEM256LI 0x71 /* 256K chips, ext-interleaved, lower */
+#define NEX_MEM256U 0x72 /* 256K chips, non-interleaved, upper */
+#define NEX_MEM256UI 0x73 /* 256K chips, ext-interleaved, upper */
+#define NEX_MEM256I 0x74 /* 256K chips, interleaved */
diff --git a/sys/arch/vax/include/param.h b/sys/arch/vax/include/param.h
new file mode 100644
index 00000000000..208a254711a
--- /dev/null
+++ b/sys/arch/vax/include/param.h
@@ -0,0 +1,195 @@
+/* $NetBSD: param.h,v 1.12 1995/08/13 00:45:21 mycroft Exp $ */
+
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Modified for VAX 940213/Ragge
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * 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.
+ *
+ * @(#)param.h 5.8 (Berkeley) 6/28/91
+ */
+
+#ifndef _VAX_PARAM_H_
+#define _VAX_PARAM_H_
+
+#include "machine/macros.h"
+#include "psl.h"
+
+/*
+ * Machine dependent constants for VAX.
+ */
+
+#define MACHINE "vax"
+#define MID_MACHINE MID_VAX
+#define UNIX "vmunix"
+
+/*
+ * Round p (pointer or byte index) up to a correctly-aligned value
+ * for all data types (int, long, ...). The result is u_int and
+ * must be cast to any desired pointer type.
+ */
+
+#define ALIGNBYTES (sizeof(int) - 1)
+#define ALIGN(p) (((u_int)(p) + ALIGNBYTES) &~ ALIGNBYTES)
+
+#define PGSHIFT 9 /* LOG2(NBPG) */
+#define NBPG (1<<PGSHIFT) /* (1 << PGSHIFT) bytes/page */
+#define PGOFSET (NBPG-1) /* byte offset into page */
+#define NPTEPG (NBPG/(sizeof (struct pte)))
+
+#define KERNBASE 0x80000000 /* start of kernel virtual */
+#define BTOPKERNBASE ((u_long)KERNBASE >> PGSHIFT)
+
+#define DEV_BSHIFT 9 /* log2(DEV_BSIZE) */
+#define DEV_BSIZE (1 << DEV_BSHIFT)
+
+#define BLKDEV_IOSIZE 2048
+#define MAXPHYS (63 * 1024) /* max raw I/O transfer size */
+
+#define CLSIZELOG2 1
+#define CLSIZE 2
+
+/* NOTE: SSIZE, SINCR and UPAGES must be multiples of CLSIZE */
+#define SSIZE 4 /* initial stack size/NBPG */
+#define SINCR 4 /* increment of stack/NBPG */
+
+#define UPAGES 16 /* pages of u-area */
+#define USPACE (NBPG*UPAGES)
+
+/*
+ * Constants related to network buffer management.
+ * MCLBYTES must be no larger than CLBYTES (the software page size), and,
+ * on machines that exchange pages of input or output buffers with mbuf
+ * clusters (MAPPED_MBUFS), MCLBYTES must also be an integral multiple
+ * of the hardware page size.
+ */
+
+#ifndef MSIZE
+#define MSIZE 128 /* size of an mbuf */
+#endif /* MSIZE */
+
+#ifndef MCLSHIFT
+#define MCLSHIFT 10 /* convert bytes to m_buf clusters */
+#endif /* MCLSHIFT */
+#define MCLBYTES (1 << MCLSHIFT) /* size of an m_buf cluster */
+#define MCLOFSET (MCLBYTES - 1) /* offset within an m_buf cluster */
+
+#ifndef NMBCLUSTERS
+#ifdef GATEWAY
+#define NMBCLUSTERS 512 /* map size, max cluster allocation */
+#else
+#define NMBCLUSTERS 256 /* map size, max cluster allocation */
+#endif /* GATEWAY */
+#endif /* NMBCLUSTERS */
+
+/*
+ * Size of kernel malloc arena in CLBYTES-sized logical pages
+ */
+
+#ifndef NKMEMCLUSTERS
+#define NKMEMCLUSTERS (2048*1024/CLBYTES)
+#endif
+
+/*
+ * Some macros for units conversion
+ */
+
+/* pages ("clicks") to disk blocks */
+#define ctod(x) ((x) << (PGSHIFT - DEV_BSHIFT))
+#define dtoc(x) ((x) >> (PGSHIFT - DEV_BSHIFT))
+
+/* clicks to bytes */
+#define ctob(x) ((x) << PGSHIFT)
+#define btoc(x) (((x) + PGOFSET) >> PGSHIFT)
+
+/* bytes to disk blocks */
+#define btodb(x) ((x) >> DEV_BSHIFT)
+#define dbtob(x) ((x) << DEV_BSHIFT)
+
+/*
+ * Map a ``block device block'' to a file system block.
+ * This should be device dependent, and will be if we
+ * add an entry to cdevsw/bdevsw for that purpose.
+ * For now though just use DEV_BSIZE.
+ */
+
+#define bdbtofsb(bn) ((bn) / (BLKDEV_IOSIZE/DEV_BSIZE))
+
+/*
+ * Mach derived conversion macros
+ */
+
+#define vax_round_pdr(x) ((((unsigned)(x)) + NBPDR - 1) & ~(NBPDR-1))
+#define vax_trunc_pdr(x) ((unsigned)(x) & ~(NBPDR-1))
+#define vax_round_page(x) ((((unsigned)(x)) + NBPG - 1) & ~(NBPG-1))
+#define vax_trunc_page(x) ((unsigned)(x) & ~(NBPG-1))
+#define vax_btod(x) ((unsigned)(x) >> PDRSHIFT)
+#define vax_dtob(x) ((unsigned)(x) << PDRSHIFT)
+#define vax_btop(x) ((unsigned)(x) >> PGSHIFT)
+#define vax_ptob(x) ((unsigned)(x) << PGSHIFT)
+
+#define splx(reg) \
+({ \
+ register int val; \
+ asm __volatile ("mfpr $0x12,%0;mtpr %1,$0x12" \
+ : "=g" (val) \
+ : "g" (reg)); \
+ val; \
+})
+
+
+#define spl0() splx(0) /* IPL0 */
+#define splsoftclock() splx(8) /* IPL08 */
+#define splsoftnet() splx(0xc) /* IPL0C */
+#define splddb() splx(0xf) /* IPL0F */
+#define spl4() splx(0x14) /* IPL14 */
+#define splbio() splx(0x15) /* IPL15 */
+#define splnet() splx(0x15) /* IPL15 */
+#define spltty() splx(0x15) /* IPL15 */
+#define splimp() splx(0x16) /* IPL16 */
+#define splclock() splx(0x18) /* IPL18 */
+#define splhigh() splx(0x1f) /* IPL1F */
+#define splstatclock() splclock()
+
+#define ovbcopy(x,y,z) bcopy(x,y,z) /* This should work i hope... */
+
+#define vmapbuf(p,q)
+#define vunmapbuf(p,q)
+
+#if !defined(VAX630) && !defined(VAX410)
+#define todr() mfpr(PR_TODR)
+#endif
+#define DELAY(x) {int N=todr()+(x/1000)+1;while(todr()!=N);}
+
+#endif /* _VAX_PARAM_H_ */
diff --git a/sys/arch/vax/include/pcb.h b/sys/arch/vax/include/pcb.h
new file mode 100644
index 00000000000..a92831c81e4
--- /dev/null
+++ b/sys/arch/vax/include/pcb.h
@@ -0,0 +1,72 @@
+/* $NetBSD: pcb.h,v 1.8 1995/05/07 16:43:34 ragge Exp $ */
+
+/*
+ * Copyright (c) 1994 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}.
+ * 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 */
+
+#ifndef _VAX_PCB_H_
+#define _VAX_PCB_H_
+
+#include "machine/trap.h"
+
+struct pcb {
+
+ /* Hardware registers, based on VAX special instructions */
+
+ long KSP; /* Kernel Stack Pointer */
+ long ESP; /* Executive Stack Pointer */
+ long SSP; /* Supervisor Stack Pointer */
+ long USP; /* User Stack Pointer */
+ long R[12]; /* Register 0-11 */
+ long AP; /* Argument Pointer */
+ long FP; /* Frame Pointer */
+ long PC; /* Program Counter */
+ long PSL; /* Program Status Longword */
+ void *P0BR; /* Page 0 Base Register */
+ long P0LR; /* Page 0 Length Register */
+ void *P1BR; /* Page 1 Base Register */
+ long P1LR; /* Page 1 Length Register */
+
+ /* Software registers, only used by kernel software */
+ void *framep; /* Pointer to syscall frame */
+ void *iftrap; /* Tells whether fault copy */
+};
+
+#define AST_MASK 0x07000000
+#define AST_PCB 0x04000000
+
+/* machine-specific core dump; save trapframe */
+struct md_coredump {
+ struct trapframe md_tf;
+};
+
+#endif /* _VAX_PCB_H_ */
+
diff --git a/sys/arch/vax/include/pmap.h b/sys/arch/vax/include/pmap.h
new file mode 100644
index 00000000000..a753c873e51
--- /dev/null
+++ b/sys/arch/vax/include/pmap.h
@@ -0,0 +1,107 @@
+/* $NetBSD: pmap.h,v 1.10 1995/05/11 16:53:14 jtc Exp $ */
+
+/*
+ * Copyright (c) 1987 Carnegie-Mellon University
+ * Copyright (c) 1991 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Changed for the VAX port. /IC
+ *
+ * This code is derived from software contributed to Berkeley by
+ * 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.
+ *
+ * @(#)pmap.h 7.6 (Berkeley) 5/10/91
+ */
+
+
+#ifndef PMAP_H
+#define PMAP_H
+
+#include "machine/mtpr.h"
+
+
+#define VAX_PAGE_SIZE NBPG
+#define VAX_SEG_SIZE NBSEG
+
+/*
+ * Pmap structure
+ *
+ * p0br == PR_P0BR in user struct, p0br is also == SBR in pmap_kernel()
+ * p1br is the same for stack space, stack is base of alloced pte mem
+ */
+
+typedef struct pmap {
+ vm_offset_t pm_stack; /* Base of alloced p1 pte space */
+ struct pcb *pm_pcb; /* Pointer to PCB for this pmap */
+ int ref_count; /* reference count */
+ struct pmap_statistics stats; /* statistics */
+ simple_lock_data_t lock; /* lock on pmap */
+} *pmap_t;
+
+/*
+ * For each vm_page_t, there is a list of all currently valid virtual
+ * mappings of that page. An entry is a pv_entry_t, the list is pv_table.
+ */
+
+typedef struct pv_entry {
+ struct pv_entry *pv_next; /* next pv_entry */
+ struct pmap *pv_pmap;/* if not NULL, pmap where mapping lies */
+ vm_offset_t pv_va; /* virtual address for mapping */
+ int pv_flags; /* flags */
+} *pv_entry_t;
+
+#define PV_REF 0x00000001 /* Simulated phys ref bit */
+
+#define PHYS_TO_PV(phys_page) (&pv_table[((phys_page)>>PAGE_SHIFT)])
+
+#ifdef _KERNEL
+pv_entry_t pv_table; /* array of entries,
+ one per LOGICAL page */
+struct pmap kernel_pmap_store;
+
+#define pa_index(pa) atop(pa)
+#define pa_to_pvh(pa) (&pv_table[atop(pa)])
+
+#define pmap_kernel() (&kernel_pmap_store)
+
+#endif /* _KERNEL */
+
+/* Routines that are best to define as macros */
+#define pmap_copy(a,b,c,d,e) /* Dont do anything */
+#define pmap_update() mtpr(0,PR_TBIA) /* Update buffes */
+#define pmap_pageable(a,b,c,d) /* Dont do anything */
+#define pmap_collect(pmap) /* No need so far */
+#define pmap_reference(pmap) if(pmap) (pmap)->ref_count++
+#define pmap_pinit(pmap) (pmap)->ref_count=1;
+#define pmap_phys_address(phys) ((u_int)(phys)<<PAGE_SIZE)
+
+#endif PMAP_H
diff --git a/sys/arch/vax/include/proc.h b/sys/arch/vax/include/proc.h
new file mode 100644
index 00000000000..07559a36d24
--- /dev/null
+++ b/sys/arch/vax/include/proc.h
@@ -0,0 +1,49 @@
+/* $NetBSD: proc.h,v 1.2 1994/10/26 08:02:21 cgd Exp $ */
+
+/*
+ * Copyright (c) 1991 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.
+ *
+ * @(#)proc.h 7.1 (Berkeley) 5/15/91
+ */
+
+/*
+ * Machine-dependent part of the proc structure for hp300.
+ */
+struct mdproc {
+ int md_flags; /* machine-dependent flags */
+#if 0
+ int *md_regs; /* registers on current frame */
+#endif
+};
+
+/* md_flags */
+#define MDP_AST 0x0001 /* async trap pending */
diff --git a/sys/arch/vax/include/profile.h b/sys/arch/vax/include/profile.h
new file mode 100644
index 00000000000..2bb0ab25d14
--- /dev/null
+++ b/sys/arch/vax/include/profile.h
@@ -0,0 +1,49 @@
+/* $NetBSD: profile.h,v 1.4 1995/05/11 16:53:15 jtc Exp $ */
+/*
+ * Copyright (c) 1992 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.
+ *
+ * @(#)profile.h 7.1 (Berkeley) 7/16/92
+ */
+
+#define _MCOUNT_DECL static inline void _mcount
+
+#define MCOUNT \
+asm(".text; .globl mcount; mcount: pushl 16(fp); calls $1,__mcount; rsb");
+
+#ifdef _KERNEL
+/*
+ * Note that we assume splhigh() and splx() cannot call mcount()
+ * recursively.
+ */
+#define MCOUNT_ENTER s = splhigh()
+#define MCOUNT_EXIT splx(s)
+#endif /* _KERNEL */
diff --git a/sys/arch/vax/include/psl.h b/sys/arch/vax/include/psl.h
new file mode 100644
index 00000000000..6ebc47683ee
--- /dev/null
+++ b/sys/arch/vax/include/psl.h
@@ -0,0 +1,113 @@
+/* $NetBSD: psl.h,v 1.4 1994/11/25 19:08:58 ragge Exp $ */
+
+/*
+ * Rewritten for the VAX port. Based on Berkeley code. /IC
+ *
+ * Copyright (c) 1982, 1986 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.
+ *
+ * @(#)psl.h 7.2 (Berkeley) 5/4/91
+ */
+
+#ifndef PSL_C
+
+/*
+ * VAX program status longword
+ */
+
+#define PSL_C 0x00000001 /* carry bit */
+#define PSL_V 0x00000002 /* overflow bit */
+#define PSL_Z 0x00000004 /* zero bit */
+#define PSL_N 0x00000008 /* negative bit */
+/* #define PSL_ALLCC 0x0000000F /* all cc bits - unlikely */
+#define PSL_T 0x00000010 /* trace enable bit */
+#define PSL_IPL00 0x00000000 /* interrupt priority level 0 */
+#define PSL_IPL01 0x00010000 /* interrupt priority level 1 */
+#define PSL_IPL02 0x00020000 /* interrupt priority level 2 */
+#define PSL_IPL03 0x00030000 /* interrupt priority level 3 */
+#define PSL_IPL04 0x00040000 /* interrupt priority level 4 */
+#define PSL_IPL05 0x00050000 /* interrupt priority level 5 */
+#define PSL_IPL06 0x00060000 /* interrupt priority level 6 */
+#define PSL_IPL07 0x00070000 /* interrupt priority level 7 */
+#define PSL_IPL08 0x00080000 /* interrupt priority level 8 */
+#define PSL_IPL09 0x00090000 /* interrupt priority level 9 */
+#define PSL_IPL0A 0x000a0000 /* interrupt priority level 10 */
+#define PSL_IPL0B 0x000b0000 /* interrupt priority level 11 */
+#define PSL_IPL0C 0x000c0000 /* interrupt priority level 12 */
+#define PSL_IPL0D 0x000d0000 /* interrupt priority level 13 */
+#define PSL_IPL0E 0x000e0000 /* interrupt priority level 14 */
+#define PSL_IPL0F 0x000f0000 /* interrupt priority level 15 */
+#define PSL_IPL10 0x00100000 /* interrupt priority level 16 */
+#define PSL_IPL11 0x00110000 /* interrupt priority level 17 */
+#define PSL_IPL12 0x00120000 /* interrupt priority level 18 */
+#define PSL_IPL13 0x00130000 /* interrupt priority level 19 */
+#define PSL_IPL14 0x00140000 /* interrupt priority level 20 */
+#define PSL_IPL15 0x00150000 /* interrupt priority level 21 */
+#define PSL_IPL16 0x00160000 /* interrupt priority level 22 */
+#define PSL_IPL17 0x00170000 /* interrupt priority level 23 */
+#define PSL_IPL18 0x00180000 /* interrupt priority level 24 */
+#define PSL_IPL19 0x00190000 /* interrupt priority level 25 */
+#define PSL_IPL1A 0x001a0000 /* interrupt priority level 26 */
+#define PSL_IPL1B 0x001b0000 /* interrupt priority level 27 */
+#define PSL_IPL1C 0x001c0000 /* interrupt priority level 28 */
+#define PSL_IPL1D 0x001d0000 /* interrupt priority level 29 */
+#define PSL_IPL1E 0x001e0000 /* interrupt priority level 30 */
+#define PSL_IPL1F 0x001f0000 /* interrupt priority level 31 */
+#define PSL_PREVU 0x00c00000 /* Previous user mode */
+#define PSL_K 0x00000000 /* kernel mode */
+#define PSL_E 0x01000000 /* executive mode */
+#define PSL_S 0x02000000 /* executive mode */
+#define PSL_U 0x03000000 /* user mode */
+#define PSL_IS 0x04000000 /* interrupt stack select */
+#define PSL_FPD 0x04000000 /* first part done flag */
+#define PSL_TP 0x40000000 /* trace pending */
+#define PSL_CM 0x80000000 /* compatibility mode */
+
+#define PSL_LOWIPL (PSL_K)
+#define PSL_HIGHIPL (PSL_K | PSL_IPL1F)
+#define PSL_IPL (PSL_IPL1F)
+#define PSL_USER (0)
+
+#define PSL_MBZ 0x3020ff00 /* must be zero bits */
+
+#define PSL_USERSET (0)
+#define PSL_USERCLR (PSL_S | PSL_IPL1F | PSL_MBZ)
+
+/*
+ * Macros to decode processor status word.
+ */
+#define CLKF_USERMODE(framep) ((((framep)->ps) & (PSL_U)) == PSL_U)
+#define CLKF_BASEPRI(framep) ((((framep)->ps) & (PSL_IPL1F)) == 0)
+#define CLKF_PC(framep) ((framep)->pc)
+#define CLKF_INTR(framep) 0
+#define PSL2IPL(ps) ((ps) >> 16)
+
+#endif
diff --git a/sys/arch/vax/include/pte.h b/sys/arch/vax/include/pte.h
new file mode 100644
index 00000000000..f99839e1931
--- /dev/null
+++ b/sys/arch/vax/include/pte.h
@@ -0,0 +1,95 @@
+/* $NetBSD: pte.h,v 1.5 1995/08/21 03:28:50 ragge Exp $ */
+
+/*
+ * Copyright (c) 1994 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}.
+ * 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 "vax/include/param.h"
+
+#ifndef ASSEMBLER
+
+/*
+ * VAX page table entries
+ */
+struct pte {
+ unsigned int pg_pfn:21; /* Page Frame Number or 0 */
+ unsigned int pg_u:1; /* Uniform bit, does WHAT?? XXX */
+ unsigned int pg_w:1; /* Wired bit */
+ unsigned int pg_sref:1; /* Help for ref simulation */
+ unsigned int pg_ref:1; /* Simulated reference bit */
+ unsigned int pg_z:1; /* Zero DIGITAL = 0 */
+ unsigned int pg_m:1; /* Modify DIGITAL */
+ unsigned int pg_prot:4; /* reserved at zero */
+ unsigned int pg_v:1; /* valid bit */
+};
+
+
+typedef unsigned int pt_entry_t; /* Mach page table entry */
+
+#endif ASSEMBLER
+
+#define PT_ENTRY_NULL ((pt_entry_t *) 0)
+
+#define PG_V 0x80000000
+#define PG_NV 0x00000000
+#define PG_PROT 0x78000000
+#define PG_RW 0x20000000
+#define PG_KW 0x10000000
+#define PG_KR 0x18000000
+#define PG_URKW 0x70000000
+#define PG_RO 0x78000000
+#define PG_NONE 0x00000000
+#define PG_M 0x04000000
+#define PG_REF 0x01000000
+#define PG_SREF 0x00800000
+#define PG_W 0x00400000
+#define PG_U 0x00200000
+#define PG_FRAME 0x001fffff
+#define PG_SHIFT 9
+#define PG_PFNUM(x) ((x) >> PG_SHIFT)
+
+
+#define VAX_MAX_KPTSIZE VM_KERNEL_PT_PAGES
+
+#ifndef ASSEMBLER
+extern pt_entry_t *Sysmap;
+/*
+ * Kernel virtual address to page table entry and to physical address.
+ */
+#endif
+
+#define kvtopte(va) \
+ (&Sysmap[((unsigned)(va) - KERNBASE) >> PGSHIFT])
+#define ptetokv(pt) \
+ ((((pt_entry_t *)(pt) - Sysmap) << PGSHIFT) + 0x80000000)
+#define kvtophys(va) \
+ ((kvtopte(va)->pg_pfnum << PGSHIFT) | ((int)(va) & PGOFSET))
diff --git a/sys/arch/vax/include/ptrace.h b/sys/arch/vax/include/ptrace.h
new file mode 100644
index 00000000000..d62d017d036
--- /dev/null
+++ b/sys/arch/vax/include/ptrace.h
@@ -0,0 +1,39 @@
+/* $NetBSD: ptrace.h,v 1.3 1995/04/12 15:26:49 ragge Exp $ */
+
+/*
+ * Copyright (c) 1994 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}.
+ * 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 */
+
+
+#define PT_STEP (PT_FIRSTMACH + 0)
+#define PT_GETREGS (PT_FIRSTMACH + 1)
+#define PT_SETREGS (PT_FIRSTMACH + 2)
+
diff --git a/sys/arch/vax/include/reg.h b/sys/arch/vax/include/reg.h
new file mode 100644
index 00000000000..9555794d510
--- /dev/null
+++ b/sys/arch/vax/include/reg.h
@@ -0,0 +1,55 @@
+/* $NetBSD: reg.h,v 1.3 1995/04/12 15:26:52 ragge Exp $ */
+
+/*
+ * Copyright (c) 1994 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}.
+ * 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 */
+
+
+struct reg {
+ int r0; /* General registers saved upon trap/syscall */
+ int r1;
+ int r2;
+ int r3;
+ int r4;
+ int r5;
+ int r6;
+ int r7;
+ int r8;
+ int r9;
+ int r10;
+ int r11;
+ int ap; /* Argument pointer on user stack */
+ int fp; /* Stack frame pointer */
+ int sp;
+ int pc; /* User pc */
+ int psl; /* User psl */
+};
+
diff --git a/sys/arch/vax/include/rpb.h b/sys/arch/vax/include/rpb.h
new file mode 100644
index 00000000000..de7aec72007
--- /dev/null
+++ b/sys/arch/vax/include/rpb.h
@@ -0,0 +1,100 @@
+/* $NetBSD: rpb.h,v 1.1 1995/06/05 17:17:59 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.
+ */
+
+/*
+ * Look at "VAX/VMS Internals and Data Structures" around page 907
+ * to get more info about RPB.
+ */
+
+struct rpb { /* size description */
+ struct rpb *rpb_base; /* 4 physical base address of block */
+ void (*rpb_restart)();/* 4 physical address of restart routine */
+ long rpb_chksum;/* 4 checksum of first 31 longwords of restart */
+ long rpb_rstflg; /* 4 Restart in progress flag */
+ long rpb_haltpc; /* 4 PC at HALT/restart */
+ /* offset: 20 */
+ long rpb_haltpsl;/* 4 PSL at HALT/restart */
+ long rpb_haltcode;/* 4 reason for restart */
+ long rpb_bootr0;/* 24 Saved bootstrap parameters (R0 through R5) */
+ long rpb_bootr1;
+ long rpb_bootr2;
+ long rpb_bootr3;
+ long rpb_bootr4;
+ long rpb_bootr5;
+ long iovec; /* 4 Address of bootstrap driver */
+ long iovecsz;/* 4 Size (in bytes) of bootstrap driver */
+ /* offset: 60 */
+ long fillbn; /* 4 LBN of seconday bootstrap file */
+ long filsiz; /* 4 Size (in blocks) of seconday bootstrap file */
+ long pfnmap[2]; /* 8 Descriptor of PFN bitmap */
+ long pfncnt; /* 4 Count of physical pages */
+ /* offset: 80 */
+ long svaspt; /* 4 system virtual address of system page table */
+ long csrphy; /* 4 Physical Address of UBA device CSR */
+ long csrvir; /* 4 Virtual Address of UBA device CSR */
+ long adpphy; /* 4 Physical Address of adapter configurate reg. */
+ long adpvir; /* 4 Virtual Address of adapter configurate reg. */
+ /* offset: 100 */
+ short unit; /* 2 Bootstrap device unit number */
+ u_char devtyp; /* 1 Bootstrap device type code */
+ u_char slave; /* 1 Bootstrap device slave unit number */
+ char file[40]; /* 40 Secondary bootstrap file name */
+ u_char confreg[16]; /* 16 Byte array of adapter types */
+ /* offset: 160 */
+#if 0
+ u_char hdrpgcnt; /* 1 Count of header pages in 2nd bootstrap image */
+ short bootndt;/* 2 Type of boot adapter */
+ u_char flags; /* 1 Miscellaneous flag bits */
+#else
+ long align; /* if the compiler doesnt proper alignment */
+#endif
+ long max_pfn;/* 4 Absolute highest PFN */
+ long sptep; /* 4 System space PTE prototype register */
+ long sbr; /* 4 Saved system base register */
+ long cpudbvec;/* 4 Physical address of per-CPU database vector */
+ /* offset: 180 */
+ long cca_addr; /* 4 Physical address of CCA */
+ long slr; /* 4 Saved system length register */
+ long memdesc[16]; /* 64 Longword array of memory descriptors */
+ long smp_pc; /* 4 SMP boot page physical address */
+ long wait; /* 4 Bugcheck loop code for attached processor */
+ /* offset: 260 */
+ long badpgs; /* 4 Number of bad pages found in memory scan */
+ u_char ctrlltr;/* 1 Controller letter designation */
+ u_char scbpagct; /* 1 SCB page count */
+ u_char reserved[6]; /* 6 -- */
+ long vmb_revision; /* 4 VMB revision label */
+};
+
+extern struct rpb rpb;
diff --git a/sys/arch/vax/include/scb.h b/sys/arch/vax/include/scb.h
new file mode 100644
index 00000000000..f5663183149
--- /dev/null
+++ b/sys/arch/vax/include/scb.h
@@ -0,0 +1,39 @@
+/* $NetBSD: scb.h,v 1.2 1994/10/26 08:02:26 cgd Exp $ */
+
+/*
+ * Copyright (c) 1994 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}.
+ * 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 */
+
+
+
+struct scb {
+};
+
diff --git a/sys/arch/vax/include/setjmp.h b/sys/arch/vax/include/setjmp.h
new file mode 100644
index 00000000000..251569b9c05
--- /dev/null
+++ b/sys/arch/vax/include/setjmp.h
@@ -0,0 +1,7 @@
+/* $NetBSD: setjmp.h,v 1.1 1994/12/20 10:37:18 cgd Exp $ */
+
+/*
+ * machine/setjmp.h: machine dependent setjmp-related information.
+ */
+
+#define _JBLEN 10 /* size, in longs, of a jmp_buf */
diff --git a/sys/arch/vax/include/sid.h b/sys/arch/vax/include/sid.h
new file mode 100644
index 00000000000..91f89399156
--- /dev/null
+++ b/sys/arch/vax/include/sid.h
@@ -0,0 +1,63 @@
+/* $NetBSD: sid.h,v 1.5 1995/02/23 17:51:44 ragge Exp $ */
+
+/*
+ * Copyright (c) 1994 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}.
+ * 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 */
+
+
+
+#define VAX_780 1
+#define VAX_750 2
+#define VAX_730 3
+#define VAX_8600 4
+#define VAX_8200 5
+#define VAX_8800 6
+#define VAX_610 7
+#define VAX_78032 8
+#define VAX_650 10
+#define VAX_MAX 10
+
+#define MACHID(x) ((x>>24)&255)
+
+#define V750UCODE(x) ((x>>8)&255)
+#define V750HARDW(x) (cpu_type&255)
+
+/*
+ * The MicroVAXII CPU chip (78032) is used on more than one type of system
+ * that are differentiated by the low order 8 bits of cpu_type. (Filled in
+ * from the System Identification Extension Register.) To test for the cpu
+ * chip, compare cpunumber == VAX_78032, but to test for a Qbus MicroVAXII
+ * compare cpu_type == VAX_630.
+ */
+#define VAX_630 0x8000001
+#define VAX_410 0x8000002
+
+extern int cpu_type, cpunumber;
diff --git a/sys/arch/vax/include/signal.h b/sys/arch/vax/include/signal.h
new file mode 100644
index 00000000000..5c4fa439947
--- /dev/null
+++ b/sys/arch/vax/include/signal.h
@@ -0,0 +1,64 @@
+/* $NetBSD: signal.h,v 1.4 1995/01/10 19:01:52 jtc Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1989, 1991 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.
+ *
+ * @(#)signal.h 7.16 (Berkeley) 3/17/91
+ */
+
+ /* All bugs are subject to removal without further notice */
+
+#ifndef _VAX_SIGNAL_H_
+#define _VAX_SIGNAL_H_
+
+typedef int sig_atomic_t;
+
+#ifndef _ANSI_SOURCE
+/*
+ * Information pushed on stack when a signal is delivered.
+ * This is used by the kernel to restore state following
+ * execution of the signal handler. It is also made available
+ * to the handler to allow it to restore state properly if
+ * a non-standard exit is performed.
+ */
+struct sigcontext {
+ int sc_onstack; /* sigstack state to restore */
+ int sc_mask; /* signal mask to restore */
+ int sc_sp; /* sp to restore */
+ int sc_fp; /* fp to restore */
+ int sc_ap; /* ap to restore */
+ int sc_pc; /* pc to restore */
+ int sc_ps; /* psl to restore */
+};
+
+#endif /* !_ANSI_SOURCE */
+#endif /* !_VAX_SIGNAL_H_ */
diff --git a/sys/arch/vax/include/stdarg.h b/sys/arch/vax/include/stdarg.h
new file mode 100644
index 00000000000..a6cb75347bb
--- /dev/null
+++ b/sys/arch/vax/include/stdarg.h
@@ -0,0 +1,62 @@
+/* $NetBSD: stdarg.h,v 1.5 1995/03/28 18:21:25 jtc Exp $ */
+
+/*-
+ * Copyright (c) 1991 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.
+ *
+ * @(#)stdarg.h 7.2 (Berkeley) 5/4/91
+ */
+
+#ifndef _VAX_STDARG_H_
+#define _VAX_STDARG_H_
+
+#include <machine/ansi.h>
+
+typedef _BSD_VA_LIST_ va_list;
+
+#define __va_promote(type) \
+ (((sizeof(type) + sizeof(int) - 1) / sizeof(int)) * sizeof(int))
+
+#define va_start(ap, last) \
+ (ap = ((char *)&(last) + __va_promote(last)))
+
+#ifdef _KERNEL
+#define va_arg(ap, type) \
+ ((type *)(ap += sizeof(type)))[-1]
+#else
+#define va_arg(ap, type) \
+ ((type *)(ap += sizeof(type) < sizeof(int) ? \
+ (abort(), 0) : sizeof(type)))[-1]
+#endif
+
+#define va_end(ap) ((void) 0)
+
+#endif /* !_VAX_STDARG_H_ */
diff --git a/sys/arch/vax/include/trap.h b/sys/arch/vax/include/trap.h
new file mode 100644
index 00000000000..b1cafc13785
--- /dev/null
+++ b/sys/arch/vax/include/trap.h
@@ -0,0 +1,109 @@
+/* $NetBSD: trap.h,v 1.8 1995/06/16 15:17:40 ragge Exp $ */
+
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * 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.
+ *
+ * @(#)trap.h 5.4 (Berkeley) 5/9/91
+ */
+
+/*
+ * Trap type values
+ * also known in trap.c for name strings
+ */
+#ifndef _VAX_TRAP_H_
+#define _VAX_TRAP_H_
+
+#define T_RESADFLT 0 /* reserved addressing */
+#define T_PRIVINFLT 1 /* privileged instruction */
+#define T_RESOPFLT 2 /* reserved operand */
+#define T_BPTFLT 3 /* breakpoint instruction */
+#define T_SYSCALL 5 /* system call (kcall) */
+#define T_ARITHFLT 6 /* arithmetic trap */
+#define T_ASTFLT 7 /* system forced exception */
+#define T_PTELEN 8 /* Page table length exceeded */
+#define T_TRANSFLT 9 /* translation fault */
+#define T_TRCTRAP 10 /* trace trap */
+/* #define T_COMPAT 11 /* compatibility mode fault on VAX */
+#define T_ACCFLT 12 /* Access violation fault */
+/* #define T_TABLEFLT 13 /* page table fault */
+/* #define T_ALIGNFLT 14 /* alignment fault */
+#define T_KSPNOTVAL 15 /* kernel stack pointer not valid */
+/* #define T_BUSERR 16 /* bus error */
+#define T_KDBTRAP 17 /* kernel debugger trap */
+
+/* #define T_DIVIDE 18 /* integer divide fault */
+/* #define T_NMI 19 /* non-maskable trap */
+/* #define T_OFLOW 20 /* overflow trap */
+/* #define T_BOUND 21 /* bound instruction fault */
+/* #define T_DNA 22 /* device not available fault */
+/* #define T_DOUBLEFLT 23 /* double fault */
+/* #define T_FPOPFLT 24 /* fp coprocessor operand fetch fault */
+/* #define T_TSSFLT 25 /* invalid tss fault */
+/* #define T_SEGNPFLT 26 /* segment not present fault */
+/* #define T_STKFLT 27 /* stack fault */
+/* #define T_RESERVED 28 /* reserved fault base */
+
+/* These gets ORed with the word for page handling routines */
+#define T_WRITE 0x80
+#define T_PTEFETCH 0x40
+
+/* Trap's coming from user mode */
+#define T_USER 0x100
+
+#ifndef ASSEMBLER
+/* If we want to alter USP in some syscall, we do it with mtpr */
+struct trapframe {
+ int fp; /* Stack frame pointer */
+ int ap; /* Argument pointer on user stack */
+ int r0; /* General registers saved upon trap/syscall */
+ int r1;
+ int r2;
+ int r3;
+ int r4;
+ int r5;
+ int r6;
+ int r7;
+ int r8;
+ int r9;
+ int r10;
+ int r11;
+ int trap; /* Type of trap */
+ u_int code; /* Trap specific code */
+ u_int pc; /* User pc */
+ u_int psl; /* User psl */
+};
+#endif /* ASSEMBLER */
+
+#endif _VAX_TRAP_H_
diff --git a/sys/arch/vax/include/types.h b/sys/arch/vax/include/types.h
new file mode 100644
index 00000000000..dbf36014062
--- /dev/null
+++ b/sys/arch/vax/include/types.h
@@ -0,0 +1,77 @@
+/* $NetBSD: types.h,v 1.5 1995/07/06 03:39:45 cgd Exp $ */
+
+/*-
+ * Copyright (c) 1990 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.
+ *
+ * @(#)types.h 7.5 (Berkeley) 3/9/91
+ */
+
+#ifndef _MACHTYPES_H_
+#define _MACHTYPES_H_
+
+#include <sys/cdefs.h>
+
+#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
+#if 0
+typedef struct _physadr {
+ int r[1];
+} *physadr;
+
+
+typedef struct label_t {
+ int val[6];
+} label_t;
+#endif /* 0 */
+#endif
+
+typedef unsigned long vm_offset_t;
+typedef unsigned long vm_size_t;
+
+/*
+ * Basic integral types. Omit the typedef if
+ * not possible for a machine/compiler combination.
+ */
+#define __BIT_TYPES_DEFINED__
+typedef __signed char int8_t;
+typedef unsigned char u_int8_t;
+typedef short int16_t;
+typedef unsigned short u_int16_t;
+typedef int int32_t;
+typedef unsigned int u_int32_t;
+typedef long long int64_t;
+typedef unsigned long long u_int64_t;
+
+typedef int32_t register_t;
+
+#define __BDEVSW_DUMP_OLD_TYPE
+
+#endif /* _MACHTYPES_H_ */
diff --git a/sys/arch/vax/include/uvaxII.h b/sys/arch/vax/include/uvaxII.h
new file mode 100644
index 00000000000..c5376d0ee80
--- /dev/null
+++ b/sys/arch/vax/include/uvaxII.h
@@ -0,0 +1,125 @@
+/* $NetBSD: uvaxII.h,v 1.1 1995/02/23 17:51:45 ragge Exp $ */
+/*-
+ * Copyright (c) 1986, 1988 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.
+ *
+ * @(#)uvaxII.h 7.4 (Berkeley) 5/9/91
+ */
+
+#if VAX630 || VAX410
+#define UVAXIISID ((u_long *)0x20040004)
+#define UVAXIICPU ((struct uvaxIIcpu *)0x20080000)
+
+struct uvaxIIcpu {
+ u_short uvaxII_bdr;
+ u_short uvaxII_xxx;
+ u_long uvaxII_mser;
+ u_long uvaxII_cear;
+ u_long uvaxII_dear;
+};
+
+/* Memory system err reg. */
+#define UVAXIIMSER_CD 0x00000300
+#define UVAXIIMSER_NXM 0x00000080
+#define UVAXIIMSER_LPE 0x00000040
+#define UVAXIIMSER_QPE 0x00000020
+#define UVAXIIMSER_MERR 0x000000f0
+#define UVAXIIMSER_CPUE 0x00000060
+#define UVAXIIMSER_DQPE 0x00000010
+#define UVAXIIMSER_LEB 0x00000008
+#define UVAXIIMSER_WRWP 0x00000002
+#define UVAXIIMSER_PEN 0x00000001
+
+/* Mem. error address regs. */
+#define UVAXIICEAR_PG 0x00007fff
+#define UVAXIIDEAR_PG 0x00007fff
+
+u_long uvaxII_gettodr();
+void uvaxII_settodr();
+#endif
+
+/*
+ * Definitions specific to the ka630 MicroVAXII Q22 bus cpu card. Includes the
+ * tod clock chip and the cpu registers.
+ */
+#if VAX630
+#define KA630CLK ((struct ka630clock *)0x200b8000)
+
+/* Bdr register bits */
+#define KA630BDR_PWROK 0x8000
+#define KA630BDR_HLTENB 0x4000
+#define KA630BDR_CPU 0x0c00
+#define KA630BDR_BDG 0x0300
+#define KA630BDR_DSPL 0x000f
+
+/* Clock registers and constants */
+#define MINSEC 60
+#define HRSEC 3600
+#define DAYSEC (HRSEC * 24)
+#define YEARSEC (DAYSEC * 365)
+
+#define KA630CLK_VRT 0200
+#define KA630CLK_UIP 0200
+#define KA630CLK_RATE 040
+#define KA630CLK_ENABLE 06
+#define KA630CLK_SET 0206
+/* cpmbx bits */
+#define KA630CLK_HLTACT 03
+/* halt action values */
+#define KA630CLK_RESTRT 01
+#define KA630CLK_REBOOT 02
+#define KA630CLK_HALT 03
+/* in progress flags */
+#define KA630CLK_BOOT 04
+#define KA630CLK_RSTRT 010
+#define KA630CLK_LANG 0360
+
+#ifndef LOCORE
+struct ka630clock {
+ u_short sec;
+ u_short secalrm;
+ u_short min;
+ u_short minalrm;
+ u_short hr;
+ u_short hralrm;
+ u_short dayofwk;
+ u_short day;
+ u_short mon;
+ u_short yr;
+ u_short csr0;
+ u_short csr1;
+ u_short csr2;
+ u_short csr3;
+ u_short cpmbx; /* CPMBX is used by the boot rom. see ka630-ug-3.3.3 */
+};
+
+#endif
+#endif
diff --git a/sys/arch/vax/include/varargs.h b/sys/arch/vax/include/varargs.h
new file mode 100644
index 00000000000..ec7a9e31b50
--- /dev/null
+++ b/sys/arch/vax/include/varargs.h
@@ -0,0 +1,61 @@
+/* $NetBSD: varargs.h,v 1.5 1995/03/28 18:21:27 jtc Exp $ */
+
+/*-
+ * Copyright (c) 1990 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.
+ *
+ * @(#)varargs.h 5.3 (Berkeley) 4/3/91
+ */
+
+#ifndef _VAX_VARARGS_H_
+#define _VAX_VARARGS_H_
+
+#include <machine/ansi.h>
+
+typedef _BSD_VA_LIST_ va_list;
+
+#define va_dcl int va_alist;
+
+#define va_start(ap) \
+ ap = (char *)&va_alist
+
+#ifdef _KERNEL
+#define va_arg(ap, type) \
+ ((type *)(ap += sizeof(type)))[-1]
+#else
+#define va_arg(ap, type) \
+ ((type *)(ap += sizeof(type) < sizeof(int) ? \
+ (abort(), 0) : sizeof(type)))[-1]
+#endif
+
+#define va_end(ap) ((void) 0)
+
+#endif /* !_VAX_VARARGS_H_ */
diff --git a/sys/arch/vax/include/vmparam.h b/sys/arch/vax/include/vmparam.h
new file mode 100644
index 00000000000..41b7e2d30d7
--- /dev/null
+++ b/sys/arch/vax/include/vmparam.h
@@ -0,0 +1,188 @@
+/* $NetBSD: vmparam.h,v 1.9 1995/08/22 04:28:20 ragge Exp $ */
+
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Slightly modified for the VAX port /IC
+ *
+ * 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.
+ *
+ * @(#)vmparam.h 5.9 (Berkeley) 5/12/91
+ */
+#ifndef ASSEMBLER
+#include <vm/vm_param.h>
+#endif
+
+/*
+ * Machine dependent constants for VAX.
+ */
+
+/*
+ * Virtual address space arrangement. On 386, both user and kernel
+ * share the address space, not unlike the vax.
+ * USRTEXT is the start of the user text/data space, while USRSTACK
+ * is the top (end) of the user stack. Immediately above the user stack
+ * resides the user structure, which is UPAGES long and contains the
+ * kernel stack.
+ *
+ */
+
+#define USRTEXT 0x400
+#define USRSTACK 0x7fffe000 /* XXX */
+
+/*
+ * Virtual memory related constants, all in bytes
+ */
+
+#ifndef MAXTSIZ
+#define MAXTSIZ (6*1024*1024) /* max text size */
+#endif
+#ifndef MAXDSIZ
+#define MAXDSIZ (16*1024*1024) /* max data size */
+#endif
+#ifndef MAXSSIZ
+#define MAXSSIZ (16*1024*1024) /* max stack size */
+#endif
+#ifndef DFLDSIZ
+#define DFLDSIZ (6*1024*1024) /* initial data size limit */
+#endif
+#ifndef DFLSSIZ
+#define DFLSSIZ (512*1024) /* initial stack size limit */
+#endif
+
+/*
+ * Default sizes of swap allocation chunks (see dmap.h).
+ * The actual values may be changed in vminit() based on MAXDSIZ.
+ * With MAXDSIZ of 16Mb and NDMAP of 38, dmmax will be 1024.
+ */
+
+#define DMMIN 32 /* smallest swap allocation */
+#define DMMAX 4096 /* largest potential swap allocation */
+#define DMTEXT 1024 /* swap allocation for text */
+
+/*
+ * Size of shared memory map
+ */
+
+#ifndef SHMMAXPGS
+#define SHMMAXPGS 64 /* XXXX should be 1024 */
+#endif
+
+/*
+ * Sizes of the system and user portions of the system page table.
+ * USRPTSIZE is maximum possible user virtual memory to be used.
+ * KALLOCMEM is kernel malloc area size. How much needed for each process?
+ * SYSPTSIZE is total size of statically allocated pte. (in physmem)
+ * Ptsizes are in PTEs.
+ */
+
+#define USRPTSIZE ((MAXDSIZ >> PG_SHIFT) * maxproc)
+#define KALLOCMEM (((1*1024*1024*maxproc)>>PG_SHIFT)/4)
+#define SYSPTSIZE (((USRPTSIZE * 4) >> PG_SHIFT) + UPAGES * maxproc + \
+ KALLOCMEM)
+
+/*
+ * The time for a process to be blocked before being very swappable.
+ * This is a number of seconds which the system takes as being a non-trivial
+ * amount of real time. You probably shouldn't change this;
+ * it is used in subtle ways (fractions and multiples of it are, that is, like
+ * half of a ``long time'', almost a long time, etc.)
+ * It is related to human patience and other factors which don't really
+ * change over time.
+ */
+
+#define MAXSLP 20
+
+/*
+ * A swapped in process is given a small amount of core without being bothered
+ * by the page replacement algorithm. Basically this says that if you are
+ * swapped in you deserve some resources. We protect the last SAFERSS
+ * pages against paging and will just swap you out rather than paging you.
+ * Note that each process has at least UPAGES+CLSIZE pages which are not
+ * paged anyways (this is currently 8+2=10 pages or 5k bytes), so this
+ * number just means a swapped in process is given around 25k bytes.
+ * Just for fun: current memory prices are 4600$ a megabyte on VAX (4/22/81),
+ * so we loan each swapped in process memory worth 100$, or just admit
+ * that we don't consider it worthwhile and swap it out to disk which costs
+ * $30/mb or about $0.75.
+ */
+
+#define SAFERSS 8 /* nominal ``small'' resident set size
+ protected against replacement */
+
+/*
+ * There are two clock hands, initially separated by HANDSPREAD bytes
+ * (but at most all of user memory). The amount of time to reclaim
+ * a page once the pageout process examines it increases with this
+ * distance and decreases as the scan rate rises.
+ */
+
+#define HANDSPREAD (2 * 1024 * 1024)
+
+/*
+ * The number of times per second to recompute the desired paging rate
+ * and poke the pagedaemon.
+ */
+
+#define RATETOSCHEDPAGING 4
+
+/*
+ * Believed threshold (in megabytes) for which interleaved
+ * swapping area is desirable.
+ */
+
+#define LOTSOFMEM 2
+
+#define mapin(pte, v, pfnum, prot) \
+ {(*(int *)(pte) = ((pfnum)<<PGSHIFT) | (prot)) ; }
+
+/*
+ * Mach derived constants
+ */
+
+/* user/kernel map constants */
+#define VM_MIN_ADDRESS ((vm_offset_t)0)
+#define VM_MAXUSER_ADDRESS ((vm_offset_t)0x7FFFE000)
+#define VM_MAX_ADDRESS ((vm_offset_t)0xC0000000)
+#define VM_MIN_KERNEL_ADDRESS ((vm_offset_t)0x80000000)
+#define VM_MAX_KERNEL_ADDRESS ((vm_offset_t)(VM_MIN_KERNEL_ADDRESS+\
+ (VM_KERNEL_PT_PAGES*0x10000)))
+
+/* virtual sizes (bytes) for various kernel submaps */
+#define VM_MBUF_SIZE (NMBCLUSTERS*MCLBYTES)
+#define VM_KMEM_SIZE (NKMEMCLUSTERS*CLBYTES)
+#define VM_PHYS_SIZE (USRIOSIZE*CLBYTES)
+
+/* pcb base */
+#define pcbb(p) ((u_int)(p)->p_addr)
+
diff --git a/sys/arch/vax/mba/hp.c b/sys/arch/vax/mba/hp.c
new file mode 100644
index 00000000000..4220d547acb
--- /dev/null
+++ b/sys/arch/vax/mba/hp.c
@@ -0,0 +1,366 @@
+/* $NetBSD: hp.c,v 1.1 1995/02/13 00:43:59 ragge Exp $ */
+/*
+ * Copyright (c) 1994 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}.
+ * 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 */
+
+
+
+/* hp.c - drivrutiner f|r massbussdiskar 940325/ragge */
+
+#include "param.h"
+#include "types.h"
+#include "fcntl.h"
+#include "syslog.h"
+#include "disklabel.h"
+#include "buf.h"
+#include "vax/mba/mbareg.h"
+#include "vax/mba/mbavar.h"
+#include "vax/mba/hpdefs.h"
+#include "hp.h"
+
+struct mba_device *hpinfo[NHP];
+struct hp_info hp_info[NHP];
+struct disklabel hplabel[NHP];
+int hpslave(), hpattach();
+
+char hptypes[]={
+ 0x22,0
+};
+
+struct mba_driver hpdriver={
+ hpslave, 0, "hp", hptypes, hpattach, hpinfo
+};
+
+hpslave(){
+ printf("Hpslave.\n");
+ asm("halt");
+};
+
+hpopen(){
+ printf("hpopen");
+ asm("halt");
+};
+
+hpclose(){
+ printf("hpclose\n");
+ asm("halt");
+};
+
+hpioctl(){
+ printf("hpioctl\n");
+ asm("halt");
+}
+
+hpdump(){
+ printf("hpdump\n");
+ asm("halt");
+};
+
+hpsize(){
+ printf("hpsize");
+ asm("halt");
+};
+
+
+
+hpattach(mi)
+ struct mba_device *mi;
+{
+ struct mba_drv *md;
+
+/*
+ * We check status of the drive first; to see if there is any idea
+ * to try to read the label.
+ */
+ md=&(mi->mi_mba->mba_drv[mi->drive]);
+ if(!md->rmcs1&HPCS1_DVA){
+ printf(": Drive not available");
+ return;
+ }
+ if(!md->rmds&HPDS_MOL){
+ printf(": Drive offline");
+ return;
+ }
+ if (hpinit(mi, 0))
+ printf(": offline");
+/* else if (ra_info[unit].ra_state == OPEN) {
+ printf(": %s, size = %d sectors",
+ udalabel[unit].d_typename, ra_info[unit].ra_dsize);
+*/
+ printf("rmcs1: %x, rmds: %x, rmdt: %x rmsn: %x\n",
+ md->rmcs1, md->rmds, md->rmdt, md->rmsn);
+
+
+/* asm("halt"); */
+/*
+ if (MSCP_MID_ECH(1, ra_info[unit].ra_mediaid) == 'X' - '@') {
+ printf(": floppy");
+ return;
+ }
+ if (ui->ui_dk >= 0)
+ dk_wpms[ui->ui_dk] = (60 * 31 * 256);
+ udaip[ui->ui_ctlr][ui->ui_slave] = ui;
+
+ if (uda_rainit(ui, 0))
+ printf(": offline");
+ else if (ra_info[unit].ra_state == OPEN) {
+ printf(": %s, size = %d sectors",
+ udalabel[unit].d_typename, ra_info[unit].ra_dsize);
+ }*/
+}
+
+
+/*
+ * Initialise a drive. If it is not already, bring it on line,
+ * and set a timeout on it in case it fails to respond.
+ * When on line, read in the pack label.
+ */
+hpinit(mi, flags)
+ struct mba_device *mi;
+{
+/* struct uda_softc *sc = &uda_softc[ui->ui_ctlr]; */
+ struct disklabel *lp;
+ struct hp_info *hp;
+/* struct mscp *mp; */
+ int unit = mi->unit;
+ char *msg, *readdisklabel();
+ int s, i, hpstrategy();
+ extern int cold;
+
+ hp = &hp_info[unit];
+/*
+ if ((ui->ui_flags & UNIT_ONLINE) == 0) {
+ mp = mscp_getcp(&sc->sc_mi, MSCP_WAIT);
+ mp->mscp_opcode = M_OP_ONLINE;
+ mp->mscp_unit = ui->ui_slave;
+ mp->mscp_cmdref = (long)&ui->ui_flags;
+ *mp->mscp_addr |= MSCP_OWN | MSCP_INT;
+ ra->ra_state = WANTOPEN;
+ if (!cold)
+ s = spl5();
+ i = ((struct udadevice *)ui->ui_addr)->udaip;
+
+ if (cold) {
+ i = todr() + 1000;
+ while ((ui->ui_flags & UNIT_ONLINE) == 0)
+ if (todr() > i)
+ break;
+ } else {
+ timeout(wakeup, (caddr_t)&ui->ui_flags, 10 * hz);
+ sleep((caddr_t)&ui->ui_flags, PSWP + 1);
+ splx(s);
+ untimeout(wakeup, (caddr_t)&ui->ui_flags);
+ }
+ if (ra->ra_state != OPENRAW) {
+ ra->ra_state = CLOSED;
+ wakeup((caddr_t)ra);
+ return (EIO);
+ }
+ }
+*/
+ lp = &hplabel[unit];
+ lp->d_secsize = DEV_BSIZE;
+
+ lp->d_secsize = DEV_BSIZE;
+ lp->d_secperunit = 15 /*ra->ra_dsize*/;
+
+ if (flags & O_NDELAY)
+ return (0);
+ hp->hp_state = RDLABEL;
+ /*
+ * Set up default sizes until we have the label, or longer
+ * if there is none. Set secpercyl, as readdisklabel wants
+ * to compute b_cylin (although we do not need it), and set
+ * nsectors in case diskerr is called.
+ */
+ lp->d_secpercyl = 1;
+ lp->d_npartitions = 1;
+ lp->d_secsize = 512;
+/* lp->d_secperunit = ra->ra_dsize; */
+ lp->d_nsectors = 15 /*ra->ra_geom.rg_nsectors*/;
+ lp->d_partitions[0].p_size = lp->d_secperunit;
+ lp->d_partitions[0].p_offset = 0;
+
+ /*
+ * Read pack label.
+ */
+ if ((msg = readdisklabel(hpminor(unit, 0), hpstrategy, lp)) != NULL) {
+ if (cold)
+ printf(": %s", msg);
+ else
+ log(LOG_ERR, "hp%d: %s", unit, msg);
+/* ra->ra_state = OPENRAW; */
+/* uda_makefakelabel(ra, lp); */
+ } else
+/* ra->ra_state = OPEN; */
+/* wakeup((caddr_t)hp); */
+ return (0);
+}
+
+/*
+ * Queue a transfer request, and if possible, hand it to the controller.
+ *
+ * This routine is broken into two so that the internal version
+ * udastrat1() can be called by the (nonexistent, as yet) bad block
+ * revectoring routine.
+ */
+hpstrategy(bp)
+ register struct buf *bp;
+{
+ register int unit;
+ register struct uba_device *ui;
+ register struct hp_info *hp;
+ struct partition *pp;
+ int p;
+ daddr_t sz, maxsz;
+
+ /*
+ * Make sure this is a reasonable drive to use.
+ */
+/* bp->b_error = ENXIO;
+ goto bad;
+*/
+ unit = hpunit(bp->b_dev);
+
+ /*
+ * If drive is open `raw' or reading label, let it at it.
+ */
+
+ if (hp->hp_state < OPEN) {
+ hpstrat1(bp);
+ return;
+ }
+
+
+/* if ((unit = udaunit(bp->b_dev)) >= NRA ||
+ (ui = udadinfo[unit]) == NULL || ui->ui_alive == 0 ||
+ (ra = &ra_info[unit])->ra_state == CLOSED) {
+ bp->b_error = ENXIO;
+ goto bad;
+ }
+*/
+ /*
+ * If drive is open `raw' or reading label, let it at it.
+ */
+/*
+ if (ra->ra_state < OPEN) {
+ udastrat1(bp);
+ return;
+ }
+ p = udapart(bp->b_dev);
+ if ((ra->ra_openpart & (1 << p)) == 0) {
+ bp->b_error = ENODEV;
+ goto bad;
+ }
+*/
+ /*
+ * Determine the size of the transfer, and make sure it is
+ * within the boundaries of the partition.
+ */
+/*
+ pp = &udalabel[unit].d_partitions[p];
+ maxsz = pp->p_size;
+ if (pp->p_offset + pp->p_size > ra->ra_dsize)
+ maxsz = ra->ra_dsize - pp->p_offset;
+ sz = (bp->b_bcount + DEV_BSIZE - 1) >> DEV_BSHIFT;
+ if (bp->b_blkno + pp->p_offset <= LABELSECTOR &&
+#if LABELSECTOR != 0
+ bp->b_blkno + pp->p_offset + sz > LABELSECTOR &&
+#endif
+ (bp->b_flags & B_READ) == 0 && ra->ra_wlabel == 0) {
+ bp->b_error = EROFS;
+ goto bad;
+ }
+ if (bp->b_blkno < 0 || bp->b_blkno + sz > maxsz) {
+ /* if exactly at end of disk, return an EOF */
+/*
+ if (bp->b_blkno == maxsz) {
+ bp->b_resid = bp->b_bcount;
+ biodone(bp);
+ return;
+ }
+ /* or truncate if part of it fits */
+/*
+ sz = maxsz - bp->b_blkno;
+ if (sz <= 0) {
+ bp->b_error = EINVAL; /* or hang it up */
+/*
+ goto bad;
+ }
+ bp->b_bcount = sz << DEV_BSHIFT;
+ }
+ udastrat1(bp);
+ return;
+*/
+bad:
+ bp->b_flags |= B_ERROR;
+ biodone(bp);
+}
+
+/*
+ * Work routine for udastrategy.
+ */
+hpstrat1(bp)
+ register struct buf *bp;
+{
+ register int unit = hpunit(bp->b_dev);
+ register struct hp_ctlr *um;
+ register struct buf *dp;
+ struct hp_device *ui;
+/* int s = spl5(); */
+
+ asm("halt");
+ /*
+ * Append the buffer to the drive queue, and if it is not
+ * already there, the drive to the controller queue. (However,
+ * if the drive queue is marked to be requeued, we must be
+ * awaiting an on line or get unit status command; in this
+ * case, leave it off the controller queue.)
+ */
+/*
+ um = (ui = udadinfo[unit])->ui_mi;
+ dp = &udautab[unit];
+ APPEND(bp, dp, av_forw);
+ if (dp->b_active == 0 && (ui->ui_flags & UNIT_REQUEUE) == 0) {
+ APPEND(dp, &um->um_tab, b_forw);
+ dp->b_active++;
+ }
+
+ /*
+ * Start activity on the controller. Note that unlike other
+ * Unibus drivers, we must always do this, not just when the
+ * controller is not active.
+ */
+/*
+ udastart(um);
+ splx(s);
+*/
+}
diff --git a/sys/arch/vax/mba/hpdefs.h b/sys/arch/vax/mba/hpdefs.h
new file mode 100644
index 00000000000..251ce2b7923
--- /dev/null
+++ b/sys/arch/vax/mba/hpdefs.h
@@ -0,0 +1,81 @@
+/* $NetBSD: hpdefs.h,v 1.1 1995/02/13 00:44:00 ragge Exp $ */
+/*
+ * Copyright (c) 1994 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}.
+ * 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 */
+
+
+
+/* hpdefs.h - 940325/ragge */
+
+#define HPCS1_DVA 0x800 /* Drive avail, in dual-port config */
+#define HPDS_VV 0x40 /* Volume valid, not changed */
+#define HPDS_DRY 0x80 /* Drive ready to accept commands */
+#define HPDS_DPR 0x100 /* Drive present */
+#define HPDS_PGM 0x200 /* Programmable in dual-port config */
+#define HPDS_WRL 0x800 /* Write locked media */
+#define HPDS_MOL 0x1000 /* Medium on-line */
+#define HPDT_DRQ 0x800 /* Dual-port disk */
+
+/*
+ * Drive status, per drive
+ */
+struct hp_info {
+ daddr_t hp_dsize; /* size in sectors */
+/* u_long hp_type; /* drive type */
+ u_long hp_mediaid; /* media id */
+ int hp_state; /* open/closed state */
+ struct hp_geom { /* geometry information */
+ u_short rg_nsectors; /* sectors/track */
+ u_short rg_ngroups; /* track groups */
+ u_short rg_ngpc; /* groups/cylinder */
+ u_short rg_ntracks; /* ngroups*ngpc */
+ u_short rg_ncyl; /* ra_dsize/ntracks/nsectors */
+#ifdef notyet
+ u_short rg_rctsize; /* size of rct */
+ u_short rg_rbns; /* replacement blocks per track */
+ u_short rg_nrct; /* number of rct copies */
+#endif
+ } hp_geom;
+ int hp_wlabel; /* label sector is currently writable */
+ u_long hp_openpart; /* partitions open */
+ u_long hp_bopenpart; /* block partitions open */
+ u_long hp_copenpart; /* character partitions open */
+};
+
+/*
+ * Device to unit number and partition and back
+ */
+#define UNITSHIFT 3
+#define UNITMASK 7
+#define hpunit(dev) (minor(dev) >> UNITSHIFT)
+#define hppart(dev) (minor(dev) & UNITMASK)
+#define hpminor(u, p) (((u) << UNITSHIFT) | (p))
+
diff --git a/sys/arch/vax/mba/hpreg.h b/sys/arch/vax/mba/hpreg.h
new file mode 100644
index 00000000000..ddf2ed2eed3
--- /dev/null
+++ b/sys/arch/vax/mba/hpreg.h
@@ -0,0 +1,86 @@
+/* $NetBSD: hpreg.h,v 1.2 1995/06/16 15:20:11 ragge Exp $ */
+/*
+ * Copyright (c) 1994 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}.
+ * 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 */
+
+
+
+struct hp_regs {
+ int hp_cs1;
+ int hp_ds;
+ int hp_er1;
+ int hp_mr1;
+ int hp_as;
+ int hp_da;
+ int hp_dt;
+ int hp_la;
+ int hp_sn;
+ int hp_of;
+ int hp_dc;
+ int hp_hr;
+ int hp_mr2;
+ int hp_er2;
+ int hp_ec1;
+ int hp_ec2;
+ int utrymme[16];
+};
+
+#define hp_drv hp_regs
+
+#define HPCS_PA 0x13 /* Pack acknowledge */
+#define HPCS_SEEK 0x5
+#define HPCS_READ 0x39
+#define HPCS_DVA 0x800 /* Drive avail, in dual-port config */
+
+#define HPDS_VV 0x40 /* Volume valid, not changed */
+#define HPDS_DRY 0x80 /* Drive ready to accept commands */
+#define HPDS_DPR 0x100 /* Drive present */
+#define HPDS_PGM 0x200 /* Programmable in dual-port config */
+#define HPDS_WRL 0x800 /* Write locked media */
+#define HPDS_MOL 0x1000 /* Medium on-line */
+
+#define HPDT_DRQ 0x800 /* Dual-port disk */
+
+#define HPOF_FMT 0x1000 /* 16/18 bit data */
+
+#if 0
+#define HPCS_
+#define HPCS_
+#define HPCS_
+#define HPCS_
+#define HPCS_
+#define HPCS_
+#define HPCS_
+#define HPCS_
+#endif
+
+
+
diff --git a/sys/arch/vax/mba/mba.c b/sys/arch/vax/mba/mba.c
new file mode 100644
index 00000000000..4b2d13f7864
--- /dev/null
+++ b/sys/arch/vax/mba/mba.c
@@ -0,0 +1,99 @@
+
+/* $NetBSD: mba.c,v 1.1 1995/02/13 00:44:02 ragge Exp $ */
+/*
+ * Copyright (c) 1994 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}.
+ * 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 */
+
+
+
+/* mba.c - main mba routines, 930312/ragge */
+
+#include "mba.h"
+#include "nexus.h"
+#include "vax/mba/mbavar.h"
+#include "vax/mba/mbareg.h"
+
+struct mba_ctrl mba_ctrl[NMBA];
+
+extern mba_0(), mba_1(), mba_2(), mba_3();
+int (*mbaintv[4])() = { mba_0, mba_1, mba_2, mba_3 };
+#if NMBA > 4
+ Need to expand the table for more than 4 massbus adaptors
+#endif
+
+mbainterrupt(mba){
+
+ if(mba_hd[mba].mh_mba->mba_sr&MBA_NED){
+ printf("Adresserat icke existerande massbussenhet.\n");
+ mba_hd[mba].mh_mba->mba_sr=MBA_NED+MBA_MCPE;
+ return;
+ }
+ printf("Interrupt fr}n massbussadapter %d\n",mba);
+ printf("mba_hd[mba]->mba_sr: %x\n",mba_hd[mba].mh_mba->mba_sr);
+}
+
+/*
+ * mbafind() set up interrupt vectors for each found mba and calls
+ * config routines for hp disks, tu and mt tapes (currently only hp).
+ */
+
+mbafind(nexnum,nexaddr){
+ struct mba_regs *mbr;
+ struct mba_device *mi;
+
+ mba_ctrl[nmba].mba_regs= (struct mba_regs *)nexaddr;
+ mbr=&(mba_ctrl[nmba].mba_regs);
+/*
+ * Set up interruptvectors and enable interrupt
+ */
+ nex_vec_num(14,nexnum)=nex_vec_num(15,nexnum)=
+ nex_vec_num(16,nexnum)=nex_vec_num(17,nexnum)=
+ (caddr_t)mbaintv[nmba];
+ mbr->mba_cr=MBCR_INIT;
+ mbr->mba_cr=MBCR_IE;
+/*
+ * Loop thru all massbuss devices and check for existance
+ */
+
+ for(i=0;i<8;i++){
+ if(!mbr->mba_drv[i].rmds&MBDS_DPR) continue;
+/*
+ * Device found; check if generated
+ */
+ for(mi = mbdinit; mi->driver; mi++) {
+ if(mi->alive) continue; /* Already config'd */
+ }
+ }
+
+
+}
+
+
diff --git a/sys/arch/vax/mba/mbareg.h b/sys/arch/vax/mba/mbareg.h
new file mode 100644
index 00000000000..79e1acc4eba
--- /dev/null
+++ b/sys/arch/vax/mba/mbareg.h
@@ -0,0 +1,80 @@
+/* $NetBSD: mbareg.h,v 1.1 1995/02/13 00:44:03 ragge Exp $ */
+/*
+ * Copyright (c) 1994 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}.
+ * 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.
+ */
+
+/* mbareg.h - 940320/ragge */
+#include "vax/mba/hpreg.h"
+
+struct mba_regs {
+ u_int mba_csr;
+ u_int mba_cr;
+ u_int mba_sr;
+ u_int mba_var;
+ u_int mba_bc;
+ u_int mba_dr;
+ u_int mba_smr;
+ u_int mba_car;
+ u_int utrymme[248];
+ struct hp_drv hp_drv[8];
+ u_int mba_map[256];
+};
+
+/*
+ * Different states which can be on massbus.
+ */
+/* Write to mba_cr */
+#define MBACR_IBC 0x10
+#define MBACR_MMM 0x8
+#define MBACR_IE 0x4
+#define MBACR_ABORT 0x2
+#define MBACR_INIT 0x1
+
+/* Read from mba_sr: */
+#define MBASR_DTBUSY 0x80000000
+#define MBASR_CRD 0x20000000
+#define MBASR_CBHUNG 0x800000
+#define MBASR_PGE 0x80000
+#define MBASR_NED 0x40000 /* NonExistent Drive */
+#define MBASR_MCPE 0x20000 /* Massbuss Control Parity Error */
+#define MBASR_ATTN 0x10000 /* Attention from Massbus */
+#define MBASR_SPE 0x4000 /* Silo Parity Error */
+#define MBASR_DTCMP 0x2000 /* Data Transfer CoMPleted */
+#define MBASR_DTABT 0x1000 /* Data Transfer ABorTed */
+#define MBASR_DLT 0x800 /* Data LaTe */
+#define MBASR_WCKUE 0x400 /* Write check upper error */
+#define MBASR_WCKLE 0x200 /* Write check lower error */
+#define MBASR_MXE 0x100 /* Miss transfer error */
+#define MBASR_MBEXC 0x80 /* Massbuss exception */
+#define MBASR_MDPE 0x40 /* Massbuss data parity error */
+#define MBASR_MAPPE 0x20 /* Page frame map parity error */
+#define MBASR_INVMAP 0x10 /* Invalid map */
+#define MBASR_ERR_STAT 0x8 /* Error status */
+#define MBASR_NRSTAT 0x2 /* No Response status */
+
diff --git a/sys/arch/vax/mba/mbavar.h b/sys/arch/vax/mba/mbavar.h
new file mode 100644
index 00000000000..b020564bee6
--- /dev/null
+++ b/sys/arch/vax/mba/mbavar.h
@@ -0,0 +1,94 @@
+/* $NetBSD: mbavar.h,v 1.1 1995/02/13 00:44:04 ragge Exp $ */
+/*
+ * Copyright (c) 1994 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}.
+ * 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 */
+
+/* Mba n}nting... ragge 940311 */
+
+#define MBCR_INIT 1
+#define MBCR_IE (1<<2)
+#define MBDS_DPR (1<<8)
+#define MBSR_NED (1<<18)
+#define MBDT_MOH (1<<13)
+#define MBDT_TYPE 511
+#define MBDT_TAP (1<<14)
+
+#define CLOSED 0
+#define WANTOPEN 1
+#define RDLABEL 2
+#define OPEN 3
+#define OPENRAW 4
+
+struct mba_ctrl {
+ struct mba_regs *mba_regs;
+ struct mba_device *mba_device[8];
+};
+
+struct mba_device {
+ struct mba_driver *driver;
+ int unit;
+ int mbanum;
+ int drive;
+ int dk;
+ int alive;
+ int type;
+ struct mba_regs *mi_mba;
+ struct mba_hd *hd;
+ int drv;
+ int device;
+};
+
+struct mba_slave {
+ struct mba_driver *driver;
+ int ctlr;
+ int unit;
+ int slave;
+ int alive;
+};
+
+struct mba_driver {
+ int (*slave)();
+ char *sname;
+ char *dname;
+ short *type;
+ int (*attach)();
+ struct mba_device **info;
+};
+
+struct mba_hd {
+ struct mba_device *device[8]; /* XXX - Var tidigare mh_mbip */
+ int ndrive;
+ int mh_active;
+ struct mba_regs *mh_mba;
+ struct mba_regs *mh_physmba;
+ struct mba_device *mh_actf;
+ struct mba_device *mh_actl;
+};
diff --git a/sys/arch/vax/stand/Makefile b/sys/arch/vax/stand/Makefile
new file mode 100644
index 00000000000..b54fa987f1f
--- /dev/null
+++ b/sys/arch/vax/stand/Makefile
@@ -0,0 +1,103 @@
+# $NetBSD: Makefile,v 1.4 1995/09/16 13:18:27 ragge Exp $
+#
+
+INCPATH=-I. -I../../.. -I../.. -I../../../lib/libsa
+
+CC= cc
+AS= as
+
+S= ../../..
+RELOC= 100000
+CFLAGS+=-O ${INCPATH} -DSTANDALONE -DRELOC=0x${RELOC} -D_VAX_INLINE_
+
+DEVS= autoconf.o hp.o ra.o tmscp.o
+
+.include "$S/lib/libkern/Makefile.inc"
+LIBKERN= ${KERNLIB}
+
+.include "$S/lib/libsa/Makefile.inc"
+LIBSA= ${SA_LIB}
+
+all: xxboot boot copy edlabel
+
+libsvax.a: consio.o urem.o udiv.o
+ ar crv $@ $?
+ ranlib $@
+
+urem.o: ../vax/urem.s
+ ${CC} -x assembler-with-cpp -E ../vax/urem.s | as -o urem.o
+
+udiv.o: ../vax/udiv.s
+ ${CC} -x assembler-with-cpp -E ../vax/udiv.s | as -o udiv.o
+
+# startups
+
+start.o: start.s
+ ${CC} -x assembler-with-cpp -E start.s | as -o start.o
+
+srt0.o: srt0.s
+ ${CC} -x assembler-with-cpp -E srt0.s | as -o srt0.o
+
+#
+
+xxboot: start.o bootxx.o romread.o ${LIBSA} ${LIBKERN} libsvax.a
+ ld -N -Ttext ${RELOC} -o a.out start.o bootxx.o romread.o \
+ ${LIBSA} ${LIBKERN} 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
+ ld -N -Ttext ${RELOC} -e nisse -o $@ srt0.o devopen.o boot.o \
+ conf.o ${DEVS} ${LIBSA} ${LIBKERN} libsvax.a
+ @strip boot
+ @size boot
+
+edlabel: edlabel.o srt0.o devopen.o conf.o ${DEVS} ${LIBKERN} ${LIBSA} libsvax.a
+ ld -N -Ttext ${RELOC} -e nisse -o $@ srt0.o devopen.o edlabel.o\
+ conf.o ${DEVS} ${LIBSA} ${LIBKERN} libsvax.a
+ @strip edlabel
+ @size edlabel
+
+copy: copy.o srt0.o devopen.o conf.o ${DEVS} ${LIBKERN} ${LIBSA} libsvax.a
+ ld -N -Ttext ${RELOC} -e nisse -o $@ srt0.o devopen.o copy.o \
+ conf.o ${DEVS} ${LIBSA} ${LIBKERN} libsvax.a
+ @strip copy
+ @size copy
+
+#
+
+hp.o: hp.c
+ ${CC} -c ${CFLAGS} $*.c
+
+ra.o: ra.c
+ ${CC} -c ${CFLAGS} $*.c
+
+autoconf.o: autoconf.c
+ ${CC} -c ${CFLAGS} $*.c
+
+conf.o: conf.c
+ ${CC} -c ${CFLAGS} $*.c
+
+boot.o: boot.c
+ ${CC} -c ${CFLAGS} $*.c
+
+copy.o: copy.c
+ ${CC} -c ${CFLAGS} $*.c
+
+romread.o: romread.s
+ ${CC} -x assembler-with-cpp -E romread.s | as -o romread.o
+
+init.o: init.c
+ ${CC} -c ${CFLAGS} $*.c
+
+bootxx.o: bootxx.c
+ ${CC} -c ${CFLAGS} $*.c
+
+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
+
diff --git a/sys/arch/vax/stand/autoconf.c b/sys/arch/vax/stand/autoconf.c
new file mode 100644
index 00000000000..654d6a68680
--- /dev/null
+++ b/sys/arch/vax/stand/autoconf.c
@@ -0,0 +1,92 @@
+/* $NetBSD: autoconf.c,v 1.3 1995/09/16 13:34:20 ragge Exp $ */
+/*
+ * Copyright (c) 1994 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}.
+ * 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 "sys/param.h"
+#include "../include/mtpr.h"
+#include "../include/sid.h"
+#include "vaxstand.h"
+
+int nmba=0, nuba=0, nbi=0,nsbi=0,nuda=0;
+int *mbaaddr, *ubaaddr;
+int *udaaddr, *uioaddr, tmsaddr;
+
+static int mba750[]={0xf28000,0xf2a000,0xf2c000};
+static int uba750[]={0xf30000,0xf32000};
+static int uio750[]={0xfc0000,0xf80000};
+static int uda750[]={0772150};
+
+static int uba630[]={0x20087800};
+static int uio630[]={0x30000000};
+#define qbdev(csr) (((csr) & 017777)-0x10000000)
+static int uda630[]={qbdev(0772150),qbdev(0760334)};
+/*
+ * Autoconf routine is really stupid; but it actually don't
+ * need any intelligence. We just assume that all possible
+ * devices exists on each cpu. Fast & easy.
+ */
+
+autoconf()
+{
+ int i = MACHID(mfpr(PR_SID));
+
+ switch (i) {
+
+ default:
+ printf("CPU type %d not supported by boot\n",i);
+ asm("halt");
+
+ case VAX_750:
+ nmba = 3;
+ nuba = 2;
+ nuda = 1;
+ mbaaddr = mba750;
+ ubaaddr = uba750;
+ udaaddr = uda750;
+ uioaddr = uio750;
+ tmsaddr = 0774500;
+ break;
+
+ case VAX_650: /* the same for uvaxIII */
+ case VAX_78032:
+ nuba = 1;
+ nuda = 2;
+ ubaaddr = uba630;
+ udaaddr = uda630;
+ uioaddr = uio630;
+ tmsaddr = qbdev(0774500);
+ break;
+ }
+}
+
diff --git a/sys/arch/vax/stand/boot.c b/sys/arch/vax/stand/boot.c
new file mode 100644
index 00000000000..d85ddabdf5d
--- /dev/null
+++ b/sys/arch/vax/stand/boot.c
@@ -0,0 +1,249 @@
+/* $NetBSD: boot.c,v 1.4 1995/09/16 15:54:20 ragge Exp $ */
+/*-
+ * Copyright (c) 1982, 1986 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.
+ *
+ * @(#)boot.c 7.15 (Berkeley) 5/4/91
+ */
+
+#include "sys/param.h"
+#include "sys/reboot.h"
+#include "lib/libsa/stand.h"
+
+#include <a.out.h>
+
+/*
+ * Boot program... arguments passed in r10 and r11 determine
+ * whether boot stops to ask for system name and which device
+ * boot comes from.
+ */
+
+char line[100];
+volatile u_int devtype, bootdev;
+extern unsigned opendev;
+
+main()
+{
+ register howto asm("r11");
+ register bdev asm("r10");
+ int io, retry, type;
+
+ io=0;
+ bootdev=bdev;
+ autoconf();
+
+ if ((howto & RB_ASKNAME) == 0) {
+ type = (devtype >> B_TYPESHIFT) & B_TYPEMASK;
+ if ((unsigned)type < ndevs && devsw[type].dv_name)
+ strcpy(line, "/netbsd");
+ else
+ howto |= RB_SINGLE|RB_ASKNAME;
+ }
+
+ for (retry = 0;;) {
+ if (io >= 0)
+ printf("\nNboot\n");
+ if (howto & RB_ASKNAME) {
+ printf(": ");
+ gets(line);
+ if (line[0] == 0) {
+ strcpy(line, "/netbsd");
+ printf(": %s\n", line);
+ }
+ } else
+ printf(": %s\n", line);
+ io = open(line, 0);
+ if (io >= 0) {
+ loadpcs();
+ copyunix(howto, opendev, io);
+ close(io);
+ howto |= RB_SINGLE|RB_ASKNAME;
+ } else {
+ printf("%s\n",strerror(errno));
+ }
+ if (++retry > 2)
+ howto |= RB_SINGLE|RB_ASKNAME;
+ }
+}
+
+/*ARGSUSED*/
+copyunix(howto, devtype, aio)
+ register howto, devtype; /* howto=r11, devtype=r10 */
+ int aio;
+{
+ register int esym; /* must be r9 */
+ struct exec x;
+ register int io = aio, i;
+ char *addr;
+
+ if (read(io, (char *)&x, sizeof(x)) != sizeof(x) || N_BADMAG(x)) {
+ printf("Bad format\n");
+ return;
+ }
+ printf("%d", x.a_text);
+ if (N_GETMAGIC(x) == ZMAGIC && lseek(io, 0x400, SEEK_SET) == -1)
+ goto shread;
+ if (read(io, (char *)0, x.a_text) != x.a_text)
+ goto shread;
+ addr = (char *)x.a_text;
+ if (N_GETMAGIC(x) == ZMAGIC || N_GETMAGIC(x) == NMAGIC)
+ while ((int)addr & CLOFSET)
+ *addr++ = 0;
+ printf("+%d", x.a_data);
+ if (read(io, addr, x.a_data) != x.a_data)
+ goto shread;
+ addr += x.a_data;
+ printf("+%d", x.a_bss);
+ for (i = 0; i < x.a_bss; i++)
+ *addr++ = 0;
+ if (howto & RB_KDB && x.a_syms) {
+ *(int *)addr = x.a_syms; /* symbol table size */
+ addr += sizeof (int);
+ printf("[+%d", x.a_syms);
+ if (read(io, addr, x.a_syms) != x.a_syms)
+ goto shread;
+ addr += x.a_syms;
+ if (read(io, addr, sizeof (int)) != sizeof (int))
+ goto shread;
+ i = *(int *)addr - sizeof (int); /* string table size */
+ addr += sizeof (int);
+ printf("+%d]", i);
+ if (read(io, addr, i) != i)
+ goto shread;
+ addr += i;
+ esym = roundup((int)addr, sizeof (int));
+ x.a_bss = 0;
+ } else
+ howto &= ~RB_KDB;
+ for (i = 0; i < 128*512; i++) /* slop */
+ *addr++ = 0;
+ printf(" start 0x%x\n", (x.a_entry&0x7fffffff));
+ hoppabort((x.a_entry&0x7fffffff),howto, devtype, esym);
+ return;
+shread:
+ printf("Short read\n");
+ return;
+}
+
+/* 750 Patchable Control Store magic */
+
+#include "../include/mtpr.h"
+#include "../include/cpu.h"
+#include "../include/sid.h"
+#define PCS_BITCNT 0x2000 /* number of patchbits */
+#define PCS_MICRONUM 0x400 /* number of ucode locs */
+#define PCS_PATCHADDR 0xf00000 /* start addr of patchbits */
+#define PCS_PCSADDR (PCS_PATCHADDR+0x8000) /* start addr of pcs */
+#define PCS_PATCHBIT (PCS_PATCHADDR+0xc000) /* patchbits enable reg */
+#define PCS_ENABLE 0xfff00000 /* enable bits for pcs */
+
+#define extzv(one, two, three,four) \
+({ \
+ asm __volatile (" extzv %0,%3,(%1),(%2)+" \
+ : \
+ : "g"(one),"g"(two),"g"(three),"g"(four)); \
+})
+
+
+loadpcs()
+{
+ register int *ip; /* known to be r11 below */
+ register int i; /* known to be r10 below */
+ register int *jp; /* known to be r9 below */
+ register int j;
+ static int pcsdone = 0;
+ int mid = mfpr(PR_SID);
+ char pcs[100];
+ char *cp;
+
+ if ((mid >> 24) != VAX_750 || ((mid >> 8) & 255) < 95 || pcsdone)
+ return;
+ printf("Updating 11/750 microcode: ");
+ for (cp = line; *cp; cp++)
+ if (*cp == ')' || *cp == ':')
+ break;
+ if (*cp) {
+ strncpy(pcs, line, 99);
+ pcs[99] = 0;
+ i = cp - line + 1;
+ } else
+ i = 0;
+ strcpy(pcs + i, "pcs750.bin");
+ i = open(pcs, 0);
+ if (i < 0) {
+ printf("bad luck - missing pcs750.bin :-(\n");
+ return;
+ }
+ /*
+ * We ask for more than we need to be sure we get only what we expect.
+ * After read:
+ * locs 0 - 1023 packed patchbits
+ * 1024 - 11264 packed microcode
+ */
+ if (read(i, (char *)0, 23*512) != 22*512) {
+ printf("Error reading %s\n", pcs);
+ close(i);
+ return;
+ }
+ close(i);
+
+ /*
+ * Enable patchbit loading and load the bits one at a time.
+ */
+ *((int *)PCS_PATCHBIT) = 1;
+ ip = (int *)PCS_PATCHADDR;
+ jp = (int *)0;
+ for (i=0; i < PCS_BITCNT; i++) {
+ extzv(i,jp,ip,1);
+ }
+ *((int *)PCS_PATCHBIT) = 0;
+
+ /*
+ * Load PCS microcode 20 bits at a time.
+ */
+ ip = (int *)PCS_PCSADDR;
+ jp = (int *)1024;
+ for (i=j=0; j < PCS_MICRONUM * 4; i+=20, j++) {
+ extzv(i,jp,ip,20);
+ }
+
+ /*
+ * Enable PCS.
+ */
+ i = *jp; /* get 1st 20 bits of microcode again */
+ i &= 0xfffff;
+ i |= PCS_ENABLE; /* reload these bits with PCS enable set */
+ *((int *)PCS_PCSADDR) = i;
+
+ mid = mfpr(PR_SID);
+ printf("new rev level=%d\n", V750UCODE(mid));
+ pcsdone = 1;
+}
diff --git a/sys/arch/vax/stand/bootxx.c b/sys/arch/vax/stand/bootxx.c
new file mode 100644
index 00000000000..b2f01417c95
--- /dev/null
+++ b/sys/arch/vax/stand/bootxx.c
@@ -0,0 +1,399 @@
+/* $NetBSD: bootxx.c,v 1.3 1995/09/16 13:01:06 ragge Exp $ */
+/*-
+ * Copyright (c) 1982, 1986 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.
+ *
+ * @(#)boot.c 7.15 (Berkeley) 5/4/91
+ */
+
+#include "sys/param.h"
+#include "sys/reboot.h"
+#include "sys/disklabel.h"
+
+#include "lib/libsa/stand.h"
+#include "lib/libsa/ufs.h"
+
+#include "../mba/mbareg.h"
+#include "../mba/hpreg.h"
+
+#include "../include/pte.h"
+#include "../include/sid.h"
+#include "../include/mtpr.h"
+#include "../include/reg.h"
+
+#define NRSP 0 /* Kludge */
+#define NCMD 0 /* Kludge */
+#include "../uba/ubareg.h"
+#include "../uba/udareg.h"
+#include "../vax/mscp.h"
+
+#include "data.h"
+#include "vaxstand.h"
+
+#include <a.out.h>
+
+int romstrategy(), romopen();
+int command(int, int);
+
+/*
+ * Boot program... argume passed in r10 and r11 determine whether boot
+ * stops to ask for system name and which device boot comes from.
+ */
+
+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()
+{
+ int io;
+ char *hej = "/boot";
+
+ 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;
+ rpb = bootregs[11];
+ bootdev = rpb->devtyp;
+
+ break;
+ }
+ case VAX_750:
+ is_750 = 1;
+ bootdev = bootregs[10];
+
+ break;
+ }
+
+ bootset = getbootdev();
+
+ printf("\nhowto 0x%x, bdev 0x%x, booting...\n", boothowto, bootdev);
+ io = open(hej, 0);
+
+ if (io >= 0 && io < SOPEN_MAX) {
+ copyunix(io);
+ } else {
+ printf("Boot failed. errno %d (%s)\n", errno, strerror(errno));
+ }
+}
+
+/* ARGSUSED */
+copyunix(aio)
+{
+ struct exec x;
+ register int io = aio, i;
+ char *addr;
+
+ i = read(io, (char *) &x, sizeof(x));
+ if (i != sizeof(x) || N_BADMAG(x)) {
+ printf("Bad format: errno %s\n", strerror(errno));
+ return;
+ }
+ printf("%d", x.a_text);
+ if (N_GETMAGIC(x) == ZMAGIC && lseek(io, N_TXTADDR(x), SEEK_SET) == -1)
+ goto shread;
+ if (read(io, (char *) 0x10000, x.a_text) != x.a_text)
+ goto shread;
+ addr = (char *) x.a_text;
+ if (N_GETMAGIC(x) == ZMAGIC || N_GETMAGIC(x) == NMAGIC)
+ while ((int) addr & CLOFSET)
+ *addr++ = 0;
+ printf("+%d", x.a_data);
+ if (read(io, addr + 0x10000, x.a_data) != x.a_data)
+ goto shread;
+ addr += x.a_data;
+ bcopy((void *) 0x10000, 0, (int) addr);
+ printf("+%d", x.a_bss);
+ for (i = 0; i < x.a_bss; i++)
+ *addr++ = 0;
+ for (i = 0; i < 128 * 512; i++) /* slop */
+ *addr++ = 0;
+ printf(" start 0x%x\n", x.a_entry);
+ hoppabort(x.a_entry, boothowto, bootset);
+ (*((int (*) ()) x.a_entry)) ();
+ return;
+shread:
+ printf("Short read\n");
+ return;
+}
+
+getbootdev()
+{
+ int i, major, adaptor, controller, unit, partition;
+
+
+ switch (cpunumber) {
+ case VAX_78032:
+ case VAX_650:
+ adaptor = 0;
+ controller = ((rpb->csrphy & 017777) == 0xDC)?1:0;
+ unit = rpb->unit; /* DUC, DUD? */
+
+ break;
+
+ case VAX_750:
+ controller = 0; /* XXX Actually massbuss can be on 3 ctlr's */
+ unit = bootregs[3];
+ break;
+ }
+
+ partition = 0;
+
+ switch (bootdev) {
+ case 0: /* massbuss boot */
+ major = 0; /* hp / ... */
+ adaptor = (bootregs[1] & 0x6000) >> 17;
+ break;
+
+ case 17: /* UDA50 boot */
+ major = 9; /* ra / mscp */
+ if (is_750)
+ adaptor = (bootregs[1] & 0x40000 ? 0 : 1);
+ break;
+
+ case 18: /* TK50 boot */
+ major = 15; /* tms / tmscp */
+ is_tmscp = 1; /* use tape spec in mscp routines */
+ break;
+
+ default:
+ printf("Unsupported boot device %d, trying anyway.\n", bootdev);
+ boothowto |= (RB_SINGLE | RB_ASKNAME);
+ }
+ return MAKEBOOTDEV(major, adaptor, controller, unit, partition);
+}
+
+struct devsw devsw[] = {
+ SADEV("rom", romstrategy,nullsys,nullsys, noioctl),
+};
+
+int ndevs = (sizeof(devsw) / sizeof(devsw[0]));
+
+struct fs_ops file_system[] = {
+ {ufs_open, ufs_close, ufs_read, ufs_write, ufs_seek, ufs_stat}
+};
+
+int nfsys = (sizeof(file_system) / sizeof(struct fs_ops));
+
+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 uda_rsp; /* response packets */
+ struct mscp uda_cmd; /* command packets */
+} uda;
+volatile struct udadevice *csr;
+
+devopen(f, fname, file)
+ struct open_file *f;
+ const char *fname;
+ char **file;
+{
+ char *msg;
+ int i, err, off;
+ char line[64];
+
+ f->f_dev = &devsw[0];
+ *file = fname;
+
+ /*
+ * On uVAX we need to init [T]MSCP ctlr to be able to use it.
+ */
+ if (is_mvax) {
+ switch (bootdev) {
+ case 17: /* MSCP */
+ case 18: /* TMSCP */
+ csr = (struct udadevice *)rpb->csrphy;
+
+ csr->udaip = 0; /* Start init */
+ while((csr->udasa & UDA_STEP1) == 0);
+ csr->udasa = 0x8000;
+ while((csr->udasa & UDA_STEP2) == 0);
+ csr->udasa = (short)(((u_int)&uda)&0xffff) + 8;
+ while((csr->udasa & UDA_STEP3) == 0);
+ csr->udasa = 0x10;
+ while((csr->udasa & UDA_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)
+ uda.uda_cmd.mscp_vcid = 1;
+ command(M_OP_SETCTLRC, 0);
+ uda.uda_cmd.mscp_unit = rpb->unit;
+ command(M_OP_ONLINE, 0);
+ }
+ }
+
+ /*
+ * the disklabel _shall_ be at address LABELOFFSET + RELOC in
+ * phys memory now, no need at all to reread it again.
+ * Actually disklabel is only needed when using hp disks,
+ * but it doesn't hurt to always get it.
+ */
+ if (!is_tmscp) {
+ msg = getdisklabel(LABELOFFSET + RELOC, &lp);
+ if (msg) {
+ printf("getdisklabel: %s\n", msg);
+ }
+ }
+ return 0;
+}
+
+command(cmd, arg)
+{
+ volatile int hej;
+
+ uda.uda_cmd.mscp_opcode = cmd;
+ uda.uda_cmd.mscp_modifier = arg;
+
+ 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 = csr->udaip;
+ while (uda.uda_ca.ca_rspdsc < 0);
+
+}
+
+int curblock = 0;
+
+romstrategy(sc, func, dblk, size, buf, rsize)
+ void *sc;
+ int func;
+ daddr_t dblk;
+ char *buf;
+ int size, *rsize;
+{
+ int i;
+ int block = dblk;
+ int nsize = size;
+
+ switch (cpunumber) {
+
+ case VAX_650:
+ case VAX_78032:
+ switch (bootdev) {
+
+ case 17: /* MSCP */
+ uda.uda_cmd.mscp_seq.seq_lbn = dblk;
+ uda.uda_cmd.mscp_seq.seq_bytecount = size;
+ uda.uda_cmd.mscp_seq.seq_buffer = buf;
+ uda.uda_cmd.mscp_unit = rpb->unit;
+ command(M_OP_READ, 0);
+ break;
+
+ case 18: /* TMSCP */
+ if (dblk < curblock) {
+ uda.uda_cmd.mscp_seq.seq_bytecount =
+ curblock - dblk;
+ command(M_OP_POS, 12);
+ } else {
+ uda.uda_cmd.mscp_seq.seq_bytecount =
+ dblk - curblock;
+ command(M_OP_POS, 4);
+ }
+ curblock = size/512 + dblk;
+ for (i = 0 ; i < size/512 ; i++) {
+ uda.uda_cmd.mscp_seq.seq_lbn = 1;
+ uda.uda_cmd.mscp_seq.seq_bytecount = 512;
+ uda.uda_cmd.mscp_seq.seq_buffer = buf + i * 512;
+ uda.uda_cmd.mscp_unit = rpb->unit;
+ command(M_OP_READ, 0);
+ }
+ break;
+
+ }
+ break;
+
+ case VAX_750:
+ if (bootdev) {
+ while (size > 0) {
+ if ((read750(block, bootregs) & 0x01) == 0)
+ return 1;
+
+ bcopy(0, buf, 512);
+ size -= 512;
+ buf += 512;
+ block++;
+ }
+ } else
+ hpread(block, size, buf);
+ break;
+ }
+
+ *rsize = nsize;
+ return 0;
+}
+
+hpread(block, size, buf)
+ char *buf;
+{
+ volatile struct mba_regs *mr = (void *) bootregs[1];
+ volatile struct hp_drv *hd = (void*)&mr->mba_md[bootregs[3]];
+ struct disklabel *dp = &lp;
+ u_int pfnum, nsize, mapnr, bn, cn, sn, tn;
+
+ pfnum = (u_int) buf >> PGSHIFT;
+
+ for (mapnr = 0, nsize = size; (nsize + NBPG) > 0; nsize -= NBPG)
+ mr->mba_map[mapnr++] = PG_V | pfnum++;
+ mr->mba_var = ((u_int) buf & PGOFSET);
+ mr->mba_bc = (~size) + 1;
+ bn = block;
+ cn = bn / dp->d_secpercyl;
+ sn = bn % dp->d_secpercyl;
+ tn = sn / dp->d_nsectors;
+ sn = sn % dp->d_nsectors;
+ hd->hp_dc = cn;
+ hd->hp_da = (tn << 8) | sn;
+ hd->hp_cs1 = HPCS_READ;
+ while (mr->mba_sr & MBASR_DTBUSY);
+ if (mr->mba_sr & MBACR_ABORT){
+ return 1;
+ }
+ return 0;
+}
diff --git a/sys/arch/vax/stand/conf.c b/sys/arch/vax/stand/conf.c
new file mode 100644
index 00000000000..15236d763df
--- /dev/null
+++ b/sys/arch/vax/stand/conf.c
@@ -0,0 +1,72 @@
+/* $NetBSD: conf.c,v 1.4 1995/09/16 13:18:28 ragge Exp $ */
+/*
+ * Copyright (c) 1994 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}.
+ * 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 "sys/param.h"
+
+#include "lib/libsa/stand.h"
+#include "lib/libsa/ufs.h"
+
+#include "vaxstand.h"
+
+int raopen(), rastrategy();
+int hpopen(), hpstrategy();
+int tmscpopen(), tmscpstrategy();
+
+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),
+ SADEV("tm",nullsys, nodev, nullsys, noioctl),
+ SADEV("ts",nullsys, nodev, nullsys, noioctl),
+ SADEV("mt",nullsys, nodev, nullsys, noioctl),
+ SADEV("tu",nullsys, nodev, 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),
+};
+
+int ndevs = (sizeof(devsw)/sizeof(devsw[0]));
+
+struct fs_ops file_system[] = {
+ { ufs_open, ufs_close, ufs_read, ufs_write, ufs_seek, ufs_stat }
+};
+
+int nfsys = (sizeof(file_system) / sizeof(struct fs_ops));
+
diff --git a/sys/arch/vax/stand/consio.c b/sys/arch/vax/stand/consio.c
new file mode 100644
index 00000000000..39402cc1d44
--- /dev/null
+++ b/sys/arch/vax/stand/consio.c
@@ -0,0 +1,61 @@
+/* $NetBSD: consio.c,v 1.3 1995/09/16 15:48:49 ragge Exp $ */
+/*
+ * Copyright (c) 1994 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}.
+ * 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 "sys/param.h"
+
+#include "../vax/gencons.h"
+
+#include "../include/mtpr.h"
+
+putchar(ch)
+ int ch;
+{
+ while ((mfpr(PR_TXCS) & GC_RDY) == 0); /* Wait until xmit ready */
+ mtpr(ch, PR_TXDB); /* xmit character */
+ if (ch == 10)
+ putchar(13); /* CR/LF */
+
+}
+
+getchar()
+{
+ int ch;
+
+ 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;
+}
diff --git a/sys/arch/vax/stand/copy.c b/sys/arch/vax/stand/copy.c
new file mode 100644
index 00000000000..a67721d7458
--- /dev/null
+++ b/sys/arch/vax/stand/copy.c
@@ -0,0 +1,243 @@
+/* $NetBSD: copy.c,v 1.2 1995/09/29 16:35:00 ragge Exp $ */
+/*-
+ * Copyright (c) 1982, 1986 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.
+ *
+ * @(#)boot.c 7.15 (Berkeley) 5/4/91
+ */
+
+#include "sys/param.h"
+#include "sys/reboot.h"
+#include "lib/libsa/stand.h"
+
+#include <a.out.h>
+
+char line[100];
+volatile u_int devtype, bootdev;
+extern unsigned opendev;
+
+static char *progname = "copy";
+static char *iobuf = NULL;
+static char *bufp = NULL;
+static int bufsize = 0;
+static int partlist[8];
+
+int fill_buffer (void);
+int write_disk (void);
+
+main()
+{
+ int adapt, ctlr, unit, part;
+ int res, i, loops;
+ char line[64];
+
+ autoconf ();
+
+ printf ("\n");
+ printf ("%s: \n", progname);
+ printf ("This program will read miniroot from tape/floppy/disk \n");
+ printf ("and install this miniroot onto disk.\n");
+ printf ("\n");
+
+ res = fill_buffer ();
+ if (res < 0) {
+ printf ("errors occured during read. Continue at your own risk.\n");
+ printf ("Do you want to continue ? [y/n] ");
+ gets (line);
+ if (*line != 'y' && *line != 'Y') {
+ printf ("bye.\n");
+ return (-1);
+ }
+ }
+
+ printf ("\n");
+ res = write_disk ();
+
+ printf ("\n");
+ printf ("Halt/Reboot the machine NOW.\n");
+ for (;;)
+ ;
+ /* NOTREACHED */
+}
+
+int
+fill_buffer (void)
+{
+ char devname[64];
+ int numblocks;
+ int blocksize = 512;
+ int bpv = 0; /* blocks per volume */
+ int bpt = 8; /* blocks per transfer */
+ struct open_file file;
+ char *filename;
+ int i, loops;
+ int size, rsize;
+ int res, errors = 0;
+
+again:
+ printf("\n");
+ printf("Specify the device to read from as xx(N,?), where\n");
+ printf("xx is the device-name, ? is file/partition number\n");
+ printf("and N is the unit-number, e.g.\n");
+ printf("\"tms(0,1)\" for the first TMSCP-tape (TK50),\n");
+ printf("\"ra(2,0)\" for the third MSCP-disk/floppy (RX33/RX50)\n");
+ printf("\n");
+ printf("device to read from ? ");
+ gets(devname);
+
+ printf("\n");
+ printf("Specify number of blocks to transfer. Usually this is\n");
+ printf("sizeof(miniroot) / 512.\n");
+ printf("It's safe to transfer more blocks than just the miniroot.\n");
+ printf("\n");
+ while (1) {
+ printf ("number of blocks ? ");
+ gets (line);
+ if (atoi(line) > 0) {
+ if (iobuf && bufsize)
+ free (iobuf, bufsize);
+ numblocks = atoi (line);
+ bufsize = 512 * numblocks;
+ iobuf = alloc (bufsize);
+ bufp = iobuf;
+ if (iobuf == NULL) {
+ printf ("cannot allocate this much memory.\n");
+ continue;
+ }
+ break;
+ }
+ printf ("invalid number %d.\n", atoi(line));
+ }
+
+ printf ("\n");
+ printf ("If your miniroot is split into volumes, then you must\n");
+ printf ("specify the number of blocks per volume.\n");
+ printf ("(e.g. 800 blocks per RX50, 2400 blocks per RX33)\n");
+ printf ("\n");
+ while (1) {
+ printf ("number of blocks per volume ? [%d] ", numblocks);
+ gets (line);
+ if (!*line || atoi(line) > 0) {
+ bpv = (atoi(line) > 0 ? atoi(line) : numblocks);
+ break;
+ }
+ printf ("invalid number %d.\n", atoi(line));
+ }
+
+ printf ("\n");
+ do {
+ printf ("Make sure unit %s is online and holds the proper volume.\n", devname);
+ printf ("Then type \'g\' to Go or \'a\' to Abort.\n");
+ printf ("\n");
+ printf ("OK to go on ? [g/a] ");
+ gets (line);
+ if (*line == 'g' || *line == 'G') {
+ printf ("Reading ... ");
+ if (devopen (&file, devname, &filename)) {
+ printf ("cannot open unit %s.\n", devname);
+ goto again;
+ }
+ loops = bpv / bpt + (bpv % bpt != 0);
+ for (i=0; i<loops; i++) {
+ twiddle ();
+ size = 512 * min (bpt, bpv - (i*bpt));
+ res = (*file.f_dev->dv_strategy)
+ (file.f_devdata, F_READ,
+ (daddr_t)i*bpt, size, bufp, &rsize);
+ if (res != 0) {
+ printf ("error %d in read.\n", res);
+ errors++;
+ /* continue ? halt ??? */
+ }
+ bufp += size;
+ }
+ numblocks -= bpv;
+ }
+ if (numblocks > 0) {
+ int vn = ((bufp - iobuf) / 512) / bpv;
+ printf ("\n");
+ printf ("volume #%d done. Now insert volume #%d\n",
+ vn - 1, vn);
+ }
+ } while (numblocks > 0);
+ printf ("Reading of miniroot done. (%d blocks read)\n",
+ (bufp - iobuf) / 512);
+
+ return (-errors);
+}
+
+int
+write_disk (void)
+{
+ char line[64];
+ char devname[64];
+ struct open_file file;
+ char *fname;
+ int rsize, res;
+ int i, errors = 0;
+
+ printf ("\n");
+ printf ("Now specify the device to write miniroot to as xx(N,1)\n");
+ printf ("where xx is the drive type and N is the drive number.\n");
+ printf ("For example: ra(0,1) refers to MSCP drive #0, b partition\n");
+ printf ("\n");
+ do {
+ printf ("Root disk ? : ");
+ gets (devname);
+ } while (devopen (&file, devname, &fname));
+
+ /*
+ * next: initialize the partition
+ */
+ printf ("Initializing partition ... ");
+ bufp = iobuf + (16 * 512);
+ for (i=16; i<bufsize/512; i++) {
+ twiddle ();
+ res = (*file.f_dev->dv_strategy) (file.f_devdata, F_WRITE,
+ (daddr_t)i, 512, bufp, &rsize);
+ if (res != 0) {
+ errors++;
+ printf ("error writing block %d.\n");
+ printf ("trying to continue ...\n");
+ }
+ bufp += 512;
+ }
+ printf ("done.\n");
+ printf ("(%d blocks written.)\n", bufsize/512);
+
+ printf ("\n");
+ printf ("Halt the machine and reboot from distribution media,\n");
+ printf ("giving second partition as part to mount as root. Ex:\n");
+ printf (": ra(0,1) for ra disk 0, hp(2,1) for massbuss disk 2\n");
+
+ return (-errors);
+}
+
diff --git a/sys/arch/vax/stand/data.h b/sys/arch/vax/stand/data.h
new file mode 100644
index 00000000000..d63b5496fbc
--- /dev/null
+++ b/sys/arch/vax/stand/data.h
@@ -0,0 +1,74 @@
+/* $NetBSD: data.h,v 1.4 1995/09/16 15:58:57 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 */
+
+
+
+extern unsigned *bootregs;
+
+/*
+ * rpb->iovec gives pointer to this structure.
+ *
+ * bqo->unit_init() is used to initialize the controller,
+ * bqo->qio() is used to read from boot-device
+ */
+
+struct bqo {
+ long qio; /* 4 QIO entry */
+ long map; /* 4 Mapping entry */
+ long select; /* 4 Selection entry */
+ long drivrname; /* 4 Offset to driver name */
+ short version; /* 2 Version number of VMB */
+ short vercheck; /* 2 Check field */
+ /* offset: 20 */
+ long reselect; /* 4 Reselection entry */
+ long move; /* 4 Move driver entry */
+ long unit_init; /* 4 Unit initialization entry */
+ long auxdrname; /* 4 Offset to auxiliary driver name */
+ long umr_dis; /* 4 UNIBUS Map Registers to disable */
+ /* offset: 40 */
+ long ucode; /* 4 Absolute address of booting microcode */
+ long unit_disc; /* 4 Unit disconnecting entry */
+ long devname; /* 4 Offset to boot device name */
+ long umr_tmpl; /* 4 UNIBUS map register template */
+ /* offset: 60 */
+ /*
+ * the rest is unknown / unneccessary ...
+ */
+ long xxx[6]; /* 24 -- total: 84 bytes */
+};
+
+extern struct bqo *bqo;
diff --git a/sys/arch/vax/stand/devopen.c b/sys/arch/vax/stand/devopen.c
new file mode 100644
index 00000000000..6200f477f49
--- /dev/null
+++ b/sys/arch/vax/stand/devopen.c
@@ -0,0 +1,212 @@
+/* $NetBSD: devopen.c,v 1.3 1995/09/16 13:18:29 ragge Exp $ */
+/*-
+ * Copyright (c) 1993 John Brezak
+ * 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. 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 "lib/libsa/stand.h"
+/* #include "samachdep.h" */
+
+u_int opendev;
+
+#define ispart(c) ((c) >= 'a' && (c) <= 'h')
+
+int
+atoi(cp)
+ char *cp;
+{
+ int val = 0;
+ while(isdigit(*cp))
+ val = val * 10 + (*cp++ - '0');
+ return(val);
+}
+
+usage()
+{
+ printf("\
+ Usage: device(adaptor, controller, drive, partition)file\n\
+ <device><unit><partitonletter>:file\n\
+ ");
+}
+
+devlookup(d,len)
+ char *d;
+ int 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);
+
+ 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("\n");
+ errno = ENODEV;
+ return(-1);
+}
+
+/*
+ * Parse a device spec in one of two forms.
+ *
+ * dev(adapt, ctlr, unit, part)file
+ * [A-Za-z]*[0-9]*[A-Za-z]:file
+ * dev unit part
+ */
+devparse(fname, dev, adapt, ctlr, unit, part, file)
+ char *fname;
+ int *dev, *adapt, *ctlr, *unit, *part;
+ char **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))
+ *s = tolower(*s);
+
+ /* first form */
+ if(*s == '('){
+ /* lookup device and get index */
+ if ((*dev = devlookup(fname, s - fname)) < 0)
+ goto baddev;
+
+ /* tokenize device ident */
+ args[0] = ++s;
+ for (args[0] = s, i = 1; *s && *s != ')'; s++)
+ if (*s == ',')
+ args[i++] = ++s;
+
+
+ switch(i) {
+ case 4:
+ *adapt = atoi(args[0]);
+ *ctlr = atoi(args[1]);
+ *unit = atoi(args[2]);
+ *part = atoi(args[3]);
+ break;
+ case 3:
+ *ctlr = atoi(args[0]);
+ *unit = atoi(args[1]);
+ *part = atoi(args[2]);
+ break;
+ case 2:
+ *unit = atoi(args[0]);
+ *part = atoi(args[1]);
+ break;
+ case 1:
+ *part = atoi(args[0]);
+ break;
+ case 0:
+ break;
+ }
+ *file = ++s;
+
+ /* second form */
+ } else if (*s == ':') {
+
+ /* isolate device */
+ for(s = fname; *s != ':' && !isdigit(*s); s++)
+ ;
+
+ /* lookup device and get index */
+ if ((*dev = devlookup(fname, s - fname)) < 0)
+ goto baddev;
+
+ /* isolate unit */
+ if ((*unit = atoi(s)) > sizeof(char))
+ goto bad;
+ for (; isdigit(*s); s++)
+ ;
+
+ /* translate partition */
+ if(!ispart(*s))
+ goto bad;
+
+ *part = *s++ - 'a';
+ if(*s != ':')
+ goto bad;
+ *file = ++s;
+
+ /* no device present */
+ } else
+ *file = fname;
+
+ /* return the remaining unparsed part as the file to boot */
+ return(0);
+
+bad:
+ usage();
+
+ baddev:
+ return(-1);
+}
+
+extern int bootdev;
+
+devopen(f, fname, file)
+ struct open_file *f;
+ const char *fname;
+ char **file;
+{
+ int n, error;
+ int dev, ctlr, unit, part;
+ int adapt = 0; /* XXX not used on HP */
+ struct devsw *dp = &devsw[0];
+
+ dev = B_TYPE(bootdev);
+ ctlr = B_CONTROLLER(bootdev);
+ unit = B_UNIT(bootdev);
+ part = B_PARTITION(bootdev);
+
+ if (error = devparse(fname, &dev, &adapt, &ctlr, &unit, &part, file))
+ return(error);
+
+ dp = &devsw[dev];
+
+ if (!dp->dv_open)
+ return(ENODEV);
+
+ opendev = MAKEBOOTDEV(dev, adapt, ctlr, unit, part);
+
+ f->f_dev = dp;
+
+ if ((error = (*dp->dv_open)(f, adapt, ctlr, unit, part)) == 0)
+ return(0);
+
+ printf("%s(%d,%d,%d,%d): %s\n", devsw[dev].dv_name,
+ adapt, ctlr, unit, part, strerror(error));
+
+ return(error);
+}
diff --git a/sys/arch/vax/stand/edlabel.c b/sys/arch/vax/stand/edlabel.c
new file mode 100644
index 00000000000..09844183bef
--- /dev/null
+++ b/sys/arch/vax/stand/edlabel.c
@@ -0,0 +1,222 @@
+/* $NetBSD: edlabel.c,v 1.1 1995/09/16 12:56:03 ragge Exp $ */
+/*
+ * Copyright (c) 1995 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.
+ */
+
+#define DKTYPENAMES
+
+#include "sys/param.h"
+#include "sys/disklabel.h"
+
+#include "lib/libsa/stand.h"
+#include "ufs/ffs/fs.h"
+
+struct disklabel dlabel;
+char bootblock[8192];
+
+void
+showlabel()
+{
+ struct disklabel *lp;
+ struct partition *pp;
+ int i, j;
+
+ lp = &dlabel;
+
+ printf("\n\ndisk type %d (%s), %s: %s%s%s\n", lp->d_type, lp->d_type
+ <DKMAXTYPES?dktypenames[lp->d_type]:dktypenames[0], lp->d_typename,
+ lp->d_flags & D_REMOVABLE?" removable":"", lp->d_flags & D_ECC?
+ " ecc":"", lp->d_flags & D_BADSECT?" badsect":"");
+
+ printf("interleave %d, rpm %d, trackskew %d, cylinderskew %d\n",
+ lp->d_interleave, lp->d_rpm, lp->d_trackskew, lp->d_cylskew);
+ printf("headswitch %d, track-to-track %d, drivedata: %d %d %d %d %d\n",
+ lp->d_headswitch, lp->d_trkseek, lp->d_drivedata[0],
+ lp->d_drivedata[1], lp->d_drivedata[2], lp->d_drivedata[3],
+ lp->d_drivedata[4]);
+
+ printf("\nbytes/sector: %d\n", lp->d_secsize);
+ printf("sectors/track: %d\n", lp->d_nsectors);
+ printf("tracks/cylinder: %d\n", lp->d_ntracks);
+ printf("sectors/cylinder: %d\n", lp->d_secpercyl);
+ printf("cylinders: %d\n", lp->d_ncylinders);
+
+ printf("\n%d partitions:\n", lp->d_npartitions);
+ printf(" size offset\n");
+ pp = lp->d_partitions;
+ for (i = 0; i < lp->d_npartitions; i++) {
+ printf("%c: %d, %d\n", 97 + i, lp->d_partitions[i].p_size,
+ lp->d_partitions[i].p_offset);
+ }
+ printf("\n");
+}
+
+setdefaultlabel()
+{
+ printf("Sorry, not implemented yet. Later...\n\n");
+}
+
+#define GETNUM(out, num) printf(out, num);gets(store); \
+ if (*store) num = atoi(store);
+#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);
+#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;
+
+editlabel()
+{
+ struct disklabel *lp;
+ char store[256];
+ int i;
+
+ lp = &dlabel;
+ printf("\nFirst set disk type. Valid types are:\n");
+ for (i = 0; i < DKMAXTYPES; i++)
+ printf("%d %s\n", i, dktypenames[i]);
+
+ GETNUM("\nNumeric disk type? [%d] ", lp->d_type);
+ GETSTR("Disk name? [%s] ", lp->d_typename);
+ FLAGS("badsectoring? [%c] ", D_BADSECT);
+ FLAGS("ecc? [%c] ", D_ECC);
+ FLAGS("removable? [%c] ", D_REMOVABLE);
+
+ GETNUM("Interleave? [%d] ", lp->d_interleave);
+ GETNUM("rpm? [%d] ", lp->d_rpm);
+ GETNUM("trackskew? [%d] ", lp->d_trackskew);
+ GETNUM("cylinderskew? [%d] ", lp->d_cylskew);
+ GETNUM("headswitch? [%d] ", lp->d_headswitch);
+ GETNUM("track-to-track? [%d] ", lp->d_trkseek);
+ GETNUM("drivedata 0? [%d] ", lp->d_drivedata[0]);
+ GETNUM("drivedata 1? [%d] ", lp->d_drivedata[1]);
+ GETNUM("drivedata 2? [%d] ", lp->d_drivedata[2]);
+ GETNUM("drivedata 3? [%d] ", lp->d_drivedata[3]);
+ GETNUM("drivedata 4? [%d] ", lp->d_drivedata[4]);
+ GETNUM("\nbytes/sector? [%d] ", lp->d_secsize);
+ GETNUM("sectors/track? [%d] ", lp->d_nsectors);
+ GETNUM("tracks/cylinder? [%d] ", lp->d_ntracks);
+ GETNUM("sectors/cylinder? [%d] ", lp->d_secpercyl);
+ GETNUM("cylinders? [%d] ", lp->d_ncylinders);
+ lp->d_npartitions = MAXPARTITIONS;
+ for (i = 0; i < 8; i++) {
+ GETNUM2("%c partition: offset? [%d] ", 97 + i,
+ lp->d_partitions[i].p_offset);
+ GETNUM(" size? [%d] ", lp->d_partitions[i].p_size);
+ }
+}
+
+int bootdev;
+
+void
+main()
+{
+ register bdev asm("r10");
+
+ struct open_file file;
+ char diskname[64], *msg, *filename, indata[64];
+ int i, rsize;
+
+ bootdev = bdev;
+ printf("With this program you can modify everything in the on-disk\n");
+ printf("disklabel. To do something useful you must know the exact\n");
+ printf("geometry of your disk, and have ideas about how you want\n");
+ printf("your partitions to be placed on disk. Some hints:\n");
+ printf("The a partition should be at least ~20000 blocks, the\n");
+ printf("b (swap) is depending on your use of the machine but it\n");
+ printf("should almost never be less than ~32000 blocks.\n\n");
+ printf("Disk geometry for most DEC disks can be found in the disktab");
+ printf("\nfile, and disknames is listed in the installation notes.\n");
+ printf("\nRemember that disk names is given as disk(adapt, ctrl, ");
+ printf("disk, part)\nwhen using the installation tools.\n\n");
+
+ autoconf();
+igen:
+ printf("Label which disk? ");
+ gets(diskname);
+ if (*diskname == 0) goto igen;
+ if (devopen(&file, diskname, &filename)) {
+ printf("cannot open %s\n", diskname);
+ goto igen;
+ }
+ if ((*file.f_dev->dv_strategy)(file.f_devdata, F_READ,
+ (daddr_t)0, 8192, bootblock, &rsize)) {
+ printf("cannot read label block\n");
+ goto igen;
+ }
+ if (msg = (char *) getdisklabel(LABELOFFSET + bootblock, &dlabel))
+ printf("%s: %s\n", diskname, msg);
+
+ do {
+ printf("(E)dit, (S)how, (D)efaults, (W)rite, (Q)uit) : ");
+ gets(indata);
+ switch (*indata) {
+ case ('e'):
+ case ('E'):
+ editlabel();
+ break;
+ case ('s'):
+ case ('S'):
+ showlabel();
+ break;
+ case ('d'):
+ case ('D'):
+ setdefaultlabel();
+ break;
+ case ('w'):
+ case ('W'):
+ dlabel.d_magic = DISKMAGIC;
+ dlabel.d_magic2 = DISKMAGIC;
+ dlabel.d_bbsize = BBSIZE;
+ dlabel.d_sbsize = SBSIZE;
+ dlabel.d_checksum = 0;
+ dlabel.d_checksum = dkcksum(&dlabel);
+ bcopy(&dlabel, LABELOFFSET + bootblock,
+ sizeof(struct disklabel));
+ if ((*file.f_dev->dv_strategy)(file.f_devdata, F_WRITE,
+ (daddr_t)0, 8192, bootblock, &rsize)) {
+ printf("cannot write label sectors.\n");
+ break;
+ }
+ printf("\nThis program does not (yet) write");
+ printf(" bootblocks, only disklabel.\n");
+ printf("Remember to write the bootblocks from the ");
+ printf("miniroot later with the\ncommand ");
+ printf("\"disklabel -B <diskname>\".\n\n");
+ break;
+ case ('q'):
+ case ('Q'):
+ default:
+ break;
+ }
+ } while (*indata != 'q' && *indata != 'Q');
+ goto igen;
+}
diff --git a/sys/arch/vax/stand/hp.c b/sys/arch/vax/stand/hp.c
new file mode 100644
index 00000000000..c7019a3527d
--- /dev/null
+++ b/sys/arch/vax/stand/hp.c
@@ -0,0 +1,165 @@
+/* $NetBSD: hp.c,v 1.4 1995/09/16 15:43:25 ragge Exp $ */
+/*
+ * Copyright (c) 1994 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}.
+ * 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 "sys/param.h"
+#include "sys/disklabel.h"
+
+#include "lib/libsa/stand.h"
+
+#include "../mba/mbareg.h"
+#include "../mba/hpreg.h"
+
+#include "../include/pte.h"
+#include "../include/macros.h"
+
+#include "vaxstand.h"
+
+/*
+ * These routines for HP disk standalone boot is wery simple,
+ * assuming a lots of thing like that we only working at one hp disk
+ * a time, no separate routines for mba driver etc..
+ * But it works :)
+ */
+
+struct hp_softc {
+ int adapt;
+ int ctlr;
+ int unit;
+ int part;
+};
+
+struct disklabel hplabel;
+struct hp_softc hp_softc;
+char io_buf[MAXBSIZE];
+daddr_t part_offset;
+
+hpopen(f, adapt, ctlr, unit, part)
+ struct open_file *f;
+ int ctlr, unit, part;
+{
+ struct disklabel *lp;
+ struct hp_softc *hs;
+ volatile struct mba_regs *mr;
+ volatile struct hp_drv *hd;
+ char *msg;
+ int i,err;
+
+ lp = &hplabel;
+ hs = &hp_softc;
+ mr = (void *)mbaaddr[ctlr];
+ hd = (void *)&mr->mba_md[unit];
+
+ if (adapt > nsbi) return(EADAPT);
+ if (ctlr > nmba) return(ECTLR);
+ if (unit > MAXMBAU) return(EUNIT);
+
+ bzero(lp, sizeof(struct disklabel));
+
+ lp->d_secpercyl = 32;
+ lp->d_nsectors = 32;
+ hs->adapt = adapt;
+ hs->ctlr = ctlr;
+ hs->unit = unit;
+ hs->part = part;
+
+ /* Set volume valid and 16 bit format; only done once */
+ mr->mba_cr = MBACR_INIT;
+ hd->hp_cs1 = HPCS_PA;
+ hd->hp_of = HPOF_FMT;
+
+ err = hpstrategy(hs, 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 *)hs;
+ return 0;
+}
+
+hpstrategy(hs, func, dblk, size, buf, rsize)
+ struct hp_softc *hs;
+ daddr_t dblk;
+ u_int size, *rsize;
+ char *buf;
+ int func;
+{
+ volatile struct mba_regs *mr;
+ volatile struct hp_drv *hd;
+ struct disklabel *lp;
+ unsigned int i, pfnum, mapnr, nsize, bn, cn, sn, tn;
+
+ mr = (void *)mbaaddr[hs->ctlr];
+ hd = (void *)&mr->mba_md[hs->unit];
+ lp = &hplabel;
+
+ pfnum = (u_int)buf >> PGSHIFT;
+
+ for(mapnr = 0, nsize = size; (nsize + NBPG) > 0; nsize -= NBPG)
+ mr->mba_map[mapnr++] = PG_V | pfnum++;
+
+ mr->mba_var = ((u_int)buf & PGOFSET);
+ mr->mba_bc = (~size) + 1;
+ bn = dblk + lp->d_partitions[hs->part].p_offset;
+
+ if (bn) {
+ cn = bn / lp->d_secpercyl;
+ sn = bn % lp->d_secpercyl;
+ tn = sn / lp->d_nsectors;
+ sn = sn % lp->d_nsectors;
+ } else
+ cn = sn = tn = 0;
+
+ hd->hp_dc = cn;
+ hd->hp_da = (tn << 8) | sn;
+ if (func == F_WRITE)
+ hd->hp_cs1 = HPCS_WRITE;
+ else
+ hd->hp_cs1 = HPCS_READ;
+
+ while (mr->mba_sr & MBASR_DTBUSY)
+ ;
+
+ if (mr->mba_sr & MBACR_ABORT)
+ return 1;
+
+ *rsize = size;
+
+ return 0;
+}
diff --git a/sys/arch/vax/stand/init.c b/sys/arch/vax/stand/init.c
new file mode 100644
index 00000000000..94c7ad6276a
--- /dev/null
+++ b/sys/arch/vax/stand/init.c
@@ -0,0 +1,82 @@
+/* $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/stand/ra.c b/sys/arch/vax/stand/ra.c
new file mode 100644
index 00000000000..a0ecefc1a1b
--- /dev/null
+++ b/sys/arch/vax/stand/ra.c
@@ -0,0 +1,186 @@
+/* $NetBSD: ra.c,v 1.3 1995/09/16 13:34:22 ragge Exp $ */
+/*
+ * Copyright (c) 1995 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}.
+ * 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 */
+
+#define NRSP 0 /* Kludge */
+#define NCMD 0 /* Kludge */
+
+#include "sys/param.h"
+#include "sys/disklabel.h"
+
+#include "lib/libsa/stand.h"
+
+#include "../include/pte.h"
+#include "../include/macros.h"
+#include "../uba/ubareg.h"
+#include "../uba/udareg.h"
+#include "../vax/mscp.h"
+
+#include "vaxstand.h"
+
+static command(int);
+
+/*
+ * These routines for RA disk standalone boot is wery simple,
+ * assuming a lots of thing like that we only working at one ra disk
+ * a time, no separate routines for uba driver etc..
+ * This code is foolish and should need a cleanup.
+ * But it works :)
+ */
+
+struct ra_softc {
+ int udaddr;
+ int ubaddr;
+ int part;
+ int unit;
+};
+
+volatile struct uda {
+ struct uda1ca uda_ca; /* communications area */
+ struct mscp uda_rsp; /* response packets */
+ struct mscp uda_cmd; /* command packets */
+} uda;
+
+volatile struct uda *ubauda;
+volatile struct udadevice *udacsr;
+struct disklabel ralabel;
+struct ra_softc ra_softc;
+char io_buf[MAXBSIZE];
+
+raopen(f, adapt, ctlr, unit, part)
+ struct open_file *f;
+ 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];
+ volatile u_int *nisse;
+ unsigned short johan;
+ 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->part = part;
+ udacsr=(void*)ra->udaddr;
+ nisse=&mr->uba_map[0];
+ nisse[494]=PG_V|(((u_int)&uda)>>9);
+ nisse[495]=nisse[494]+1;
+ ubauda=(void*)0x3dc00+(((u_int)(&uda))&0x1ff);
+ /* 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;
+ command(M_OP_SETCTLRC);
+ uda.uda_cmd.mscp_unit=ra->unit;
+ command(M_OP_ONLINE);
+
+ 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;
+ return(0);
+}
+
+static
+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_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);
+
+}
+
+rastrategy(ra, func, dblk, size, buf, rsize)
+ struct ra_softc *ra;
+ int func;
+ daddr_t dblk;
+ char *buf;
+ u_int size, *rsize;
+{
+ volatile struct uba_regs *ur;
+ volatile struct udadevice *udadev;
+ volatile u_int *ptmapp;
+ struct disklabel *lp;
+ u_int i, j, pfnum, mapnr, nsize;
+ volatile int hej;
+
+
+ ur = (void *)ra->ubaddr;
+ udadev = (void*)ra->udaddr;
+ ptmapp = &ur->uba_map[0];
+ lp = &ralabel;
+
+ pfnum = (u_int)buf >> PGSHIFT;
+
+ for(mapnr = 0, nsize = size; (nsize + NBPG) > 0; nsize -= NBPG)
+ ptmapp[mapnr++] = PG_V | pfnum++;
+
+ 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);
+ else
+ command(M_OP_READ);
+
+ *rsize = size;
+ return 0;
+}
diff --git a/sys/arch/vax/stand/romread.s b/sys/arch/vax/stand/romread.s
new file mode 100644
index 00000000000..966280792fb
--- /dev/null
+++ b/sys/arch/vax/stand/romread.s
@@ -0,0 +1,89 @@
+/* $NetBSD: romread.s,v 1.3 1995/09/16 16:20:18 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 "../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)
+ movl 8(ap), r8
+ movl 4(r8), r1
+ movl 8(r8), r2
+ movl 12(r8), r3
+ movl 24(r8), r6
+ clrl r5
+ movl 4(ap), r8
+ pushl $0
+ movl $0, 4(sp)
+ movl fp, 0xf0000 # ragge ???
+ jsb (r6)
+ movl 0xf0000, fp
+ ret
+
+/*
+ * bulkread630 (int lbn, int size, void *buf, int *regs)
+ */
+ENTRY(bulkread630, 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 $33 # read-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/stand/srt0.s b/sys/arch/vax/stand/srt0.s
new file mode 100644
index 00000000000..a85d02538ba
--- /dev/null
+++ b/sys/arch/vax/stand/srt0.s
@@ -0,0 +1,70 @@
+/* $NetBSD: srt0.s,v 1.4 1995/09/16 16:20:20 ragge Exp $ */
+/*
+ * Copyright (c) 1994 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}.
+ * 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 */
+
+
+/*
+ * Auto-moving startup code for standalone programs. Can be loaded
+ * (almost) anywhere in memory but moves itself to the position
+ * it is linked for. Must be started at first position, recommended
+ * is phys addr 0 (boot loads programs at 0, but starts them at the
+ * position set in a.out header.
+ */
+
+nisse: .set nisse,0 # pass -e nisse to ld gives OK start addr
+ .globl nisse
+
+_start: .globl _start
+ nop;nop; # If we get called by calls, or something
+ movl $_start, sp # Probably safe place for stack
+ subl2 $52, sp # do not overwrite saved boot-registers
+
+ subl3 $_start, $_end, r0
+ moval _start, r1
+ movl $_start, r2
+ movc3 r0, (r1), (r2) # should use movc5 instead, to clear bss.
+
+ jsb 1f
+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!
+ halt # no return
+
+
+ .globl _hoppabort
+_hoppabort: .word 0x0
+ movl 4(ap), r6
+ movl 8(ap), r11
+ movl 0xc(ap), r10
+ movl 16(ap), r9
+ calls $0,(r6)
diff --git a/sys/arch/vax/stand/start.s b/sys/arch/vax/stand/start.s
new file mode 100644
index 00000000000..45a9c56169d
--- /dev/null
+++ b/sys/arch/vax/stand/start.s
@@ -0,0 +1,188 @@
+/* $NetBSD: start.s,v 1.4 1995/09/16 16:20: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 */
+
+
+#define LOCORE
+#include "sys/disklabel.h"
+#undef LOCORE
+
+#define ASSEMBLER
+#include "../include/mtpr.h"
+#include "../include/asm.h"
+#include "bootdefs.h"
+
+_start: .globl _start # this is the symbolic name for the start
+ # of code to be relocated. We can use this
+ # to get the actual/real adress (pc-rel)
+ # or to get the relocated address (abs).
+
+.org 0x00 # uVAX booted from TK50 starts here
+ brb from_0x00 # continue behind dispatch-block
+
+.org 0x02 # information used by uVAX-ROM
+ .byte (LABELOFFSET + d_end_)/2 # offset in words to identification area
+ .byte 1 # this byte must be 1
+ .word 0 # logical block number (word swapped)
+ .word 0 # of the secondary image
+
+.org 0x08 #
+ brb from_0x08 # skip ...
+
+.org 0x0A # uVAX booted from disk starts here
+ brb from_0x0A # skip ...
+
+.org 0x0C # 11/750 & 8200 starts here
+ brw cont_750
+
+
+from_0x00: # uVAX from TK50
+from_0x0A: # uVAX from disk
+ brw start_uvax # all(?) uVAXen continue there
+
+from_0x08: # What comes here???
+ halt
+
+.org LABELOFFSET - 6
+regmask: .word 0x0fff # using a variable saves 3 bytes !!!
+bootinfo: .long 0x0 # another 3 bytes if within byte-offset
+
+# the complete area reserved for label
+# must be empty (i.e. filled with zeroes).
+# disklabel(8) checks that before installing
+# the bootblocks over existing label.
+
+/*
+ * Parameter block for uVAX boot.
+ */
+#define VOLINFO 0 /* 1=single-sided 81=double-sided volumes */
+#define SISIZE 16 /* size in blocks of secondary image */
+#define SILOAD 0 /* load offset (usually 0) from the default */
+#define SIOFF 0x0A /* byte offset into secondary image */
+
+.org LABELOFFSET + d_end_
+ .byte 0x18 # must be 0x18
+ .byte 0x00 # must be 0x00 (MBZ)
+ .byte 0x00 # any value
+ .byte 0xFF - (0x18 + 0x00 + 0x00)
+ /* 4th byte holds 1s' complement of sum of previous 3 bytes */
+
+ .byte 0x00 # must be 0x00 (MBZ)
+ .byte VOLINFO
+ .byte 0x00 # any value
+ .byte 0x00 # any value
+
+ .long SISIZE # size in blocks of secondary image
+ .long SILOAD # load offset (usually 0)
+ .long SIOFF # byte offset into secondary image
+ .long (SISIZE + SILOAD + SIOFF) # sum of previous 3
+
+/*
+ * After bootblock (LBN0) has been loaded into the first page
+ * of good memory by 11/750's ROM-code (transfer address
+ * of bootblock-code is: base of good memory + 0x0C) registers
+ * are initialized as:
+ * R0: type of boot-device
+ * 0: Massbus device
+ * 1: RK06/RK07
+ * 2: RL02
+ * 17: UDA50
+ * 35: TK50
+ * 64: TU58
+ * R1: (UBA) address of UNIBUS I/O-page
+ * (MBA) address of boot device's adapter
+ * R2: (UBA) address of the boot device's CSR
+ * (MBA) controller number of boot device
+ * R6: address of driver subroutine in ROM
+ *
+ * cont_750 reads in LBN1-15 for further execution.
+ */
+ .align 2
+cont_750:
+ movl r0,r10
+ movl r5, ap # ap not used here
+ clrl r5
+ clrl r4
+ movl $_start,sp
+1: incl r4
+ movl r4,r8
+ addl2 $0x200,r5
+ cmpl $16,r4
+ beql 2f
+ pushl r5
+ jsb (r6)
+ blbs r0,1b
+2: movl r10, r0
+ movl r11, r5
+ brw start_all
+
+
+start_uvax:
+ mtpr $0, $PR_MAPEN # Turn off MM, please.
+ movl $_start, sp
+ movl 48(r11), ap
+ brb start_all
+
+/*
+ * start_all: stack already at RELOC, we save registers, move ourself
+ * to RELOC and loads boot.
+ */
+start_all:
+ pushr $0xfff # save all regs, used later.
+
+ subl3 $_start, $_edata, r0 # get size of text+data (w/o bss)
+ moval _start, r1 # get actual base-address of code
+ subl3 $_start, $_end, r2 # get complete size (incl. bss)
+ movl $_start, r3 # get relocated base-address of code
+ movc5 r0, (r1), $0, r2, (r3) # copy code to new location
+
+ movl $relocated, -(sp) # return-address on top of stack
+ rsb # can be replaced with new address
+relocated: # now relocation is done !!!
+ movl sp, _bootregs
+ movl ap, _boothowto
+ calls $0, _main # call main() which is
+ halt # not intended to return ...
+
+/*
+ * hoppabort() is called when jumping to the newly loaded program.
+ */
+ENTRY(hoppabort, 0)
+ movl 4(ap),r6
+ movl 8(ap),r11
+ movl 0xc(ap),r10
+ calls $0,(r6)
+ halt
diff --git a/sys/arch/vax/stand/tmscp.c b/sys/arch/vax/stand/tmscp.c
new file mode 100644
index 00000000000..eb143e61426
--- /dev/null
+++ b/sys/arch/vax/stand/tmscp.c
@@ -0,0 +1,202 @@
+/* $NetBSD: tmscp.c,v 1.1 1995/09/16 12:57:35 ragge Exp $ */
+/*
+ * Copyright (c) 1995 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}.
+ * 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 */
+
+#define NRSP 0 /* Kludge */
+#define NCMD 0 /* Kludge */
+
+#include "sys/param.h"
+#include "sys/disklabel.h"
+
+#include "lib/libsa/stand.h"
+
+#include "../include/pte.h"
+#include "../include/macros.h"
+#include "../uba/ubareg.h"
+#include "../uba/udareg.h"
+#include "../vax/mscp.h"
+
+#include "vaxstand.h"
+
+static command(int,int);
+
+/*
+ * These routines for TMSCP tape standalone boot is very simple,
+ * assuming a lots of thing like that we only working at one tape at
+ * a time, no separate routines for uba driver etc..
+ * This code is directly copied from ra disk driver.
+ */
+
+struct ra_softc {
+ int udaddr;
+ int ubaddr;
+ int unit;
+};
+
+static volatile struct uda {
+ struct uda1ca uda_ca; /* communications area */
+ struct mscp uda_rsp; /* response packets */
+ struct mscp uda_cmd; /* command packets */
+} uda;
+
+static volatile struct uda *ubauda;
+static volatile struct udadevice *udacsr;
+static struct ra_softc ra_softc;
+static char io_buf[MAXBSIZE];
+
+tmscpopen(f, adapt, ctlr, unit, part)
+ struct open_file *f;
+ int ctlr, unit, part;
+{
+ char *msg;
+ extern u_int tmsaddr;
+ volatile struct ra_softc *ra=&ra_softc;
+ volatile struct uba_regs *mr=(void *)ubaaddr[adapt];
+ volatile u_int *nisse;
+ unsigned short johan;
+ int i,err;
+
+ if(adapt>nuba) return(EADAPT);
+ if(ctlr>nuda) return(ECTLR);
+ ra->udaddr=uioaddr[adapt]+tmsaddr;
+ ra->ubaddr=(int)mr;
+ ra->unit=unit;
+ udacsr=(void*)ra->udaddr;
+ nisse=&mr->uba_map[0];
+ nisse[494]=PG_V|(((u_int)&uda)>>9);
+ nisse[495]=nisse[494]+1;
+ ubauda=(void*)0x3dc00+(((u_int)(&uda))&0x1ff);
+
+ /*
+ * Init of this tmscp ctlr.
+ */
+ 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;
+ uda.uda_cmd.mscp_un.un_seq.seq_addr = &uda.uda_ca.ca_cmddsc;
+ uda.uda_rsp.mscp_un.un_seq.seq_addr = &uda.uda_ca.ca_rspdsc;
+ uda.uda_cmd.mscp_vcid = 1;
+ uda.uda_cmd.mscp_un.un_sccc.sccc_ctlrflags = 0;
+
+ command(M_OP_SETCTLRC, 0);
+ uda.uda_cmd.mscp_unit=ra->unit;
+ command(M_OP_ONLINE, 0);
+
+ if (part) {
+ uda.uda_cmd.mscp_un.un_seq.seq_buffer = part;
+ command(M_OP_POS, 0);
+ uda.uda_cmd.mscp_un.un_seq.seq_buffer = 0;
+ }
+
+ f->f_devdata=(void *)ra;
+ return(0);
+}
+
+static
+command(cmd, arg)
+{
+ volatile int hej;
+
+ uda.uda_cmd.mscp_opcode = cmd;
+ uda.uda_cmd.mscp_modifier = arg;
+
+ 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) {
+ if (uda.uda_ca.ca_cmdint)
+ uda.uda_ca.ca_cmdint = 0;
+ }
+
+}
+
+static int curblock = 0;
+
+tmscpstrategy(ra, func, dblk, size, buf, rsize)
+ struct ra_softc *ra;
+ int func;
+ daddr_t dblk;
+ char *buf;
+ u_int size, *rsize;
+{
+ u_int i,j,pfnum, mapnr, nsize, bn, cn, sn, tn;
+ volatile struct uba_regs *ur=(void *)ra->ubaddr;
+ volatile struct udadevice *udadev=(void*)ra->udaddr;
+ volatile u_int *ptmapp=&ur->uba_map[0];
+ volatile int hej;
+
+ pfnum=(u_int)buf>>PGSHIFT;
+
+ for(mapnr=0, nsize=size;(nsize+NBPG)>0;nsize-=NBPG)
+ ptmapp[mapnr++]=PG_V|pfnum++;
+
+ /*
+ * First position tape. Remember where we are.
+ */
+ if (dblk < curblock) {
+ uda.uda_cmd.mscp_seq.seq_bytecount = curblock - dblk;
+ command(M_OP_POS, 12); /* 12 == step block backward */
+ } else {
+ uda.uda_cmd.mscp_seq.seq_bytecount = dblk - curblock;
+ command(M_OP_POS, 4); /* 4 == step block forward */
+ }
+ curblock = size/512 + dblk;
+
+ /*
+ * Read in the number of blocks we need.
+ * Why doesn't read of multiple blocks work?????
+ */
+ for (i = 0 ; i < size/512 ; i++) {
+ uda.uda_cmd.mscp_seq.seq_lbn = 1;
+ uda.uda_cmd.mscp_seq.seq_bytecount = 512;
+ uda.uda_cmd.mscp_seq.seq_buffer =
+ (((u_int)buf) & 0x1ff) + i * 512;
+ uda.uda_cmd.mscp_unit = ra->unit;
+ command(M_OP_READ, 0);
+ }
+
+ *rsize=size;
+ return 0;
+}
diff --git a/sys/arch/vax/stand/vaxstand.h b/sys/arch/vax/stand/vaxstand.h
new file mode 100644
index 00000000000..17ec1cbcd03
--- /dev/null
+++ b/sys/arch/vax/stand/vaxstand.h
@@ -0,0 +1,52 @@
+/* $NetBSD: vaxstand.h,v 1.3 1995/04/25 14:14:34 ragge Exp $ */
+/*
+ * Copyright (c) 1994 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}.
+ * 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 */
+
+
+#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;
+
+/* devsw type definitions, used in bootxx and conf */
+#define SADEV(name,strategy,open,close,ioctl) \
+ { name, \
+ (int(*)(void *, int ,daddr_t , u_int , char *, u_int *))strategy, \
+ (int(*)(struct open_file *, ...))open, \
+ (int(*)(struct open_file *))close, \
+ (int(*)(struct open_file *,u_long, void *))ioctl}
+
diff --git a/sys/arch/vax/uba/tmscp.c b/sys/arch/vax/uba/tmscp.c
new file mode 100644
index 00000000000..5a7cbb47d99
--- /dev/null
+++ b/sys/arch/vax/uba/tmscp.c
@@ -0,0 +1,2136 @@
+/* $NetBSD: tmscp.c,v 1.4.2.1 1995/10/15 13:57:40 ragge Exp $ */
+
+/*-
+ * Copyright (c) 1991 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.
+ *
+ * @(#)tmscp.c 7.16 (Berkeley) 5/9/91
+ */
+
+/*
+ * sccsid = "@(#)tmscp.c 1.24 (ULTRIX) 1/21/86";
+ */
+
+/************************************************************************
+ * *
+ * Licensed from Digital Equipment Corporation *
+ * Copyright (c) *
+ * Digital Equipment Corporation *
+ * Maynard, Massachusetts *
+ * 1985, 1986 *
+ * All rights reserved. *
+ * *
+ * The Information in this software is subject to change *
+ * without notice and should not be construed as a commitment *
+ * by Digital Equipment Corporation. Digital makes no *
+ * representations about the suitability of this software for *
+ * any purpose. It is supplied "As Is" without expressed or *
+ * implied warranty. *
+ * *
+ * If the Regents of the University of California or its *
+ * licensees modify the software in a manner creating *
+ * diriviative copyright rights, appropriate copyright *
+ * legends may be placed on the drivative work in addition *
+ * to that set forth above. *
+ * *
+ ************************************************************************
+ *
+ * tmscp.c - TMSCP (TK50/TU81) tape device driver
+ *
+ * Modification History:
+ *
+ * 06-Jan-86 - afd
+ * Changed the probe routine to use DELAY (not TODR). This now
+ * works for MicroVAXen as well. This eliminates the busy-wait
+ * for MicroVAXen so a dead TK50 controller will not hang autoconf.
+ *
+ * 06-Dec-85 - afd
+ * Fixed a bug in density selection. The "set unit characteristics"
+ * command to select density, was clearing the "unit flags" field
+ * where the CACHE bit was for TU81-E. Now the unit's "format" and
+ * "unitflgs" are saved in tms_info struct. And are used on STUNT
+ * commands.
+ *
+ * 19-Oct-85 - afd
+ * Added support to the open routine to allow drives to be opened
+ * for low density (800 or 1600 bpi) use. When the slave routine
+ * initiates a "get-unit-char" cmd, the format menu for the unit
+ * is saved in the tms_info structure. The format menu is used in the
+ * start routine to select the proper low density.
+ *
+ * 02-Oct-85 - afd
+ * When a tmscp-type controller is initializing, it is possible for
+ * the sa reg to become 0 between states. Thus the init code in
+ * the interrupt routine had to be modified to reflect this.
+ *
+ * 21-Sep-85 - afd
+ * The TK50 declares a serious exception when a tape mark is encountered.
+ * This causes problems to dd (& other UN*X utilities). So a flag
+ * is set in the rsp() routine when a tape mark is encountered. If
+ * this flag is set, the start() routine appends the Clear Serious
+ * Exception modifier to the next command.
+ *
+ * 03-Sep-85 -- jaw
+ * messed up previous edit..
+ *
+ * 29-Aug-85 - jaw
+ * fixed bugs in 8200 and 750 buffered datapath handling.
+ *
+ * 06-Aug-85 - afd
+ * 1. When repositioning records or files, the count of items skipped
+ * does NOT HAVE to be returned by controllers (& the TU81 doesn't).
+ * So tmscprsp() had to be modified to stop reporting
+ * residual count errors on reposition commands.
+ *
+ * 2. Fixed bug in the open routine which allowed multiple opens.
+ *
+ * 18-Jul-85 - afd
+ * 1. Need to return status when mt status (or corresponding ioctl) is done.
+ * Save resid, flags, endcode & status in tmscprsp() routine (except on
+ * clear serious exception no-op). Return these fields when status
+ * ioctl is done (in tmscpcommand()). How they are returned:
+ * mt_resid = resid
+ * mt_dsreg = flags|endcode
+ * mt_erreg = status
+ *
+ * 2. Added latent support for enabling/disabling caching. This is
+ * handled along with all other ioctl commands.
+ *
+ * 3. Need to issue a no-op on unrecognized ioctl in tmscpstart(), since
+ * we have already commited to issuing a command at that point.
+ *
+ * 4. In tmscprsp() routine if encode is 0200 (invalid command issued);
+ * We need to: Unlink the buffer from the I/O wait queue,
+ * and signal iodone, so the higher level command can exit!
+ * Just as if it were a valid command.
+ *
+ * 11-jul-85 -- jaw
+ * fix bua/bda map registers.
+ *
+ * 19-Jun-85 -- jaw
+ * VAX8200 name change.
+ *
+ * 06-Jun-85 - jaw
+ * fixes for 8200.
+ *
+ * 9-Apr-85 - afd
+ * Added timeout code to the probe routine, so if the controller
+ * fails to init in 10 seconds we return failed status.
+ *
+ * 13-Mar-85 -jaw
+ * Changes for support of the VAX8200 were merged in.
+ *
+ * 27-Feb-85 -tresvik
+ * Changes for support of the VAX8600 were merged in.
+ *
+ */
+
+#define NTMS 2 /* XXX - This is _wery_ kludgy! /ragge */
+
+#include "tmscp.h"
+#if NTMSCP > 0
+
+#include "sys/param.h"
+#include "sys/systm.h"
+#include "sys/buf.h"
+#include "sys/conf.h"
+#include "sys/errno.h"
+#include "sys/file.h"
+#include "sys/map.h"
+#include "sys/ioctl.h"
+#include "sys/syslog.h"
+#include "sys/mtio.h"
+/* #include "sys/cmap.h" */
+#include "sys/uio.h"
+#include "sys/proc.h"
+#include "sys/tprintf.h"
+
+#include "vax/include/pte.h"
+#include "vax/include/cpu.h"
+#include "vax/include/mtpr.h"
+#include "vax/include/sid.h"
+#include "vax/uba/ubareg.h"
+#include "vax/uba/ubavar.h"
+
+#define TENSEC (1000)
+#define TMS_PRI LOG_INFO
+
+#define NRSPL2 3 /* log2 number of response packets */
+#define NCMDL2 3 /* log2 number of command packets */
+#define NRSP (1<<NRSPL2)
+#define NCMD (1<<NCMDL2)
+
+#include "tmscpreg.h"
+#include "vax/vax/tmscpinf.h"
+#include "vax/vax/mscpvar.h"
+
+/* Software state per controller */
+
+struct tmscp_softc {
+ short sc_state; /* state of controller */
+ short sc_mapped; /* Unibus map allocated for tmscp struct? */
+ int sc_ubainfo; /* Unibus mapping info */
+ struct tmscp *sc_tmscp; /* Unibus address of tmscp struct */
+ int sc_ivec; /* interrupt vector address */
+ short sc_credits; /* transfer credits */
+ short sc_lastcmd; /* pointer into command ring */
+ short sc_lastrsp; /* pointer into response ring */
+ short sc_ipl; /* interrupt priority (Q-bus) */
+} tmscp_softc[NTMSCP];
+
+struct tmscp {
+ struct tmscpca tmscp_ca; /* communications area */
+ struct mscp tmscp_rsp[NRSP]; /* response packets */
+ struct mscp tmscp_cmd[NCMD]; /* command packets */
+} tmscp[NTMSCP];
+
+void tmscpstrategy(struct buf *);
+
+/*
+ * Per drive-unit info
+ */
+struct tms_info {
+ daddr_t tms_dsize; /* Max user size from online pkt */
+ unsigned tms_type; /* Drive type int field */
+ int tms_resid; /* residual from last xfer */
+ u_char tms_endcode; /* last command endcode */
+ u_char tms_flags; /* last command end flags */
+ unsigned tms_status; /* Command status from last command */
+ char tms_openf; /* lock against multiple opens */
+ char tms_lastiow; /* last op was a write */
+ char tms_serex; /* set when serious exception occurs */
+ char tms_clserex; /* set when serex being cleared by no-op */
+ short tms_fmtmenu; /* the unit's format (density) menu */
+ short tms_unitflgs; /* unit flag parameters */
+ short tms_format; /* the unit's current format (density) */
+ tpr_t tms_tpr; /* tprintf handle */
+} tms_info[NTMS];
+struct uba_ctlr *tmscpminfo[NTMSCP];
+struct uba_device *tmsdinfo[NTMS];
+/*
+ * ifdef other tmscp devices here if they allow more than 1 unit/controller
+ */
+struct uba_device *tmscpip[NTMSCP][1];
+struct buf ctmscpbuf[NTMSCP]; /* internal cmd buffer (for ioctls) */
+struct buf tmsutab[NTMS]; /* Drive queue */
+struct buf tmscpwtab[NTMSCP]; /* I/O wait queue, per controller */
+int tmscpmicro[NTMSCP]; /* to store microcode level */
+short utoctlr[NTMS]; /* Slave unit to controller mapping */
+ /* filled in by the slave routine */
+
+/* Bits in minor device */
+#define TMSUNIT(dev) (minor(dev)&03)
+#define T_HIDENSITY 010
+
+/* Slave unit to controller mapping */
+#define TMSCPCTLR(dev) (utoctlr[TMSUNIT(dev)])
+
+/*
+ * Internal (ioctl) command codes (these must also be declared in the
+ * tmscpioctl routine). These correspond to ioctls in mtio.h
+ */
+#define TMS_WRITM 0 /* write tape mark */
+#define TMS_FSF 1 /* forward space file */
+#define TMS_BSF 2 /* backward space file */
+#define TMS_FSR 3 /* forward space record */
+#define TMS_BSR 4 /* backward space record */
+#define TMS_REW 5 /* rewind tape */
+#define TMS_OFFL 6 /* rewind tape & mark unit offline */
+#define TMS_SENSE 7 /* noop - do a get unit status */
+#define TMS_CACHE 8 /* enable cache */
+#define TMS_NOCACHE 9 /* disable cache */
+/* These go last: after all real mt cmds, just bump the numbers up */
+#define TMS_CSE 10 /* clear serious exception */
+#define TMS_LOWDENSITY 11 /* set unit to low density */
+#define TMS_HIDENSITY 12 /* set unit to high density */
+
+/*
+ * Controller states
+ */
+#define S_IDLE 0 /* hasn't been initialized */
+#define S_STEP1 1 /* doing step 1 init */
+#define S_STEP2 2 /* doing step 2 init */
+#define S_STEP3 3 /* doing step 3 init */
+#define S_SCHAR 4 /* doing "set controller characteristics" */
+#define S_RUN 5 /* running */
+
+int tmscperror = 0; /* causes hex dump of packets */
+int tmscp_cp_wait = 0; /* Something to wait on for command */
+ /* packets and or credits. */
+void wakeup();
+extern int hz; /* Should find the right include */
+
+#ifdef DEBUG
+#define printd if (tmscpdebug) printf
+int tmscpdebug = 1;
+#define printd10 if(tmscpdebug >= 10) printf
+#endif
+
+int tmscpprobe(), tmscpslave(), tmscpattach(), tmscpintr();
+struct mscp *tmscpgetcp();
+
+#define DRVNAME "tms"
+#define CTRLNAME "tmscp"
+
+u_short tmscpstd[] = { 0174500, 0 };
+struct uba_driver tmscpdriver =
+{ tmscpprobe, tmscpslave, tmscpattach, 0, tmscpstd, DRVNAME, tmsdinfo, CTRLNAME
+, tmscpminfo, 0};
+
+#define b_qsize b_resid /* queue size per drive, in tmsutab */
+#define b_ubinfo b_resid /* Unibus mapping info, per buffer */
+
+
+/*************************************************************************/
+
+#define DELAYTEN 1000
+
+
+/*
+ * Unfortunately qbgetpri can't be used because the TK50 doesn't flip the
+ * TMSCP_STEP2 flag in the tmscpsa register until after the pending interrupt
+ * has been acknowledged by the cpu. If you are at spl6(), the TMSCP_STEP2
+ * flag never gets set and you return (0).
+ */
+tmscpprobe(reg, ctlr, um)
+ caddr_t reg; /* address of the IP register */
+ int ctlr; /* index of controller in the tmscp_softc array */
+ struct uba_ctlr *um;
+{
+ /* register int br, cvec; MUST be 1st (r11 & r10): IPL and intr vec */
+ register struct tmscp_softc *sc = &tmscp_softc[ctlr];
+ /* ptr to software controller structure */
+ volatile struct tmscpdevice *tmscpaddr;
+ int count; /* for probe delay time out */
+
+# ifdef lint
+ br = 0; cvec = br; br = cvec; reg = reg;
+ tmscpreset(0); tmscpintr(0);
+# endif
+
+ tmscpminfo[ctlr] = um;
+ tmscpaddr = (struct tmscpdevice *) reg;
+ /*
+ * Set host-settable interrupt vector.
+ * Assign 0 to the ip register to start the tmscp-device initialization.
+ * The device is not really initialized at this point, this is just to
+ * find out if the device exists.
+ */
+ sc->sc_ivec = (uba_hd[numuba].uh_lastiv -= 4);
+ tmscpaddr->tmscpip = 0;
+
+ count=0;
+ while(count < DELAYTEN)
+ { /* wait for at most 10 secs */
+ if((tmscpaddr->tmscpsa & TMSCP_STEP1) != 0)
+ break;
+ DELAY(10000);
+ count=count+1;
+ }
+ if (count == DELAYTEN)
+ return(0);
+
+ tmscpaddr->tmscpsa = TMSCP_ERR|(NCMDL2<<11)|(NRSPL2<<8)|TMSCP_IE|(sc->sc_ivec/4);
+
+ count=0;
+ while(count < DELAYTEN)
+ {
+ if((tmscpaddr->tmscpsa & TMSCP_STEP2) != 0)
+ break;
+ DELAY(10000);
+ count = count+1;
+ }
+ if (count == DELAYTEN)
+ return(0);
+
+#ifdef QBA
+ sc->sc_ipl = 0x15;
+#endif
+ return(sizeof (struct tmscpdevice));
+}
+
+/*
+ * Try to find a slave (a drive) on the controller.
+ * If the controller is not in the run state, call init to initialize it.
+ */
+tmscpslave (ui, reg)
+ struct uba_device *ui; /* ptr to the uba device structure */
+ caddr_t reg; /* addr of the device controller */
+{
+ register struct uba_ctlr *um = tmscpminfo[ui->ui_ctlr];
+ register struct tmscp_softc *sc = &tmscp_softc[ui->ui_ctlr];
+ register struct tms_info *tms = &tms_info[ui->ui_unit];
+ volatile struct tmscpdevice *tmscpaddr; /* ptr to IP & SA */
+ volatile struct mscp *mp;
+ volatile int i; /* Something to write into to start */
+ /* the tmscp polling */
+
+# ifdef lint
+ reg = reg;
+# endif
+ tmscpaddr = (struct tmscpdevice *)um->um_addr;
+ /*
+ * If its not in the run state, start the initialization process
+ * (tmscpintr will complete it); if the initialization doesn't start;
+ * then return.
+ */
+ if(sc->sc_state != S_RUN)
+ {
+# ifdef DEBUG
+ printd("tmscpslave: ctlr not running: calling init \n");
+# endif
+ if(!tmscpinit(ui->ui_ctlr))
+ return(0);
+ }
+ /*
+ * Wait for the controller to come into the run state or go idle.
+ * If it goes idle return.
+ */
+# ifdef DEBUG
+ i=1;
+# endif
+ while(sc->sc_state != S_RUN && sc->sc_state != S_IDLE)
+# ifdef DEBUG
+ if (tmscpaddr->tmscpsa & TMSCP_ERR && i)
+ {
+ printd("tmscp-device: fatal error (%o)\n", tmscpaddr->tmscpsa&0xffff);
+ i=0;
+ }
+# endif
+ ; /* wait */
+ if(sc->sc_state == S_IDLE)
+ { /* The tmscp device failed to initialize */
+ printf("tmscp controller failed to init\n");
+ return(0);
+ }
+ /* The controller is up so see if the drive is there */
+ if(0 == (mp = tmscpgetcp(um)))
+ {
+ printf("tmscp can't get command packet\n");
+ return(0);
+ }
+ /* Need to determine the drive type for generic driver */
+ mp->mscp_opcode = M_OP_GTUNT; /* This should give us the device type */
+ mp->mscp_unit = ui->ui_slave;
+ mp->mscp_cmdref = (long) ui->ui_slave;
+ tms->tms_status = 0; /* set to zero */
+ tmscpip[ui->ui_ctlr][ui->ui_slave] = ui;
+ *((long *) mp->mscp_dscptr ) |= TMSCP_OWN | TMSCP_INT;/* maybe we should poll*/
+ i = tmscpaddr->tmscpip;
+#ifdef lint
+ i = i;
+#endif
+ while(!tms->tms_status)
+ ; /* Wait for some status */
+# ifdef DEBUG
+ printd("tmscpslave: status = %o\n",tms->tms_status & M_ST_MASK);
+# endif
+ tmscpip[ui->ui_ctlr][ui->ui_slave] = 0;
+ if(!tms->tms_type) /* packet from a GTUNT */
+ return(0); /* Failed No such drive */
+ else
+ return(1); /* Got it and it is there */
+}
+
+
+/*
+ * Set ui flags to zero to show device is not online & set tmscpip.
+ * Unit to Controller mapping is set up here.
+ * Open routine will issue the online command, later.
+ */
+tmscpattach (ui)
+ register struct uba_device *ui; /* ptr to unibus dev struct */
+{
+
+ ui->ui_flags = 0;
+ tmscpip[ui->ui_ctlr][ui->ui_slave] = ui;
+# ifdef DEBUG
+ /*
+ * Check to see if the drive is available.
+ * If not then just print debug.
+ */
+ if(tms_info[ui->ui_unit].tms_status != M_ST_AVLBL)
+ printd("tmscpattach: unavailable \n");
+# endif
+ utoctlr[ui->ui_unit] = ui->ui_ctlr;
+}
+
+
+/*
+ * TMSCP interrupt routine.
+ */
+tmscpintr(uba,vector,level,d)
+{
+ volatile struct uba_ctlr *um = tmscpminfo[d];
+ volatile struct tmscpdevice *tmscpaddr =
+ (struct tmscpdevice *)um->um_addr;
+ struct buf *bp;
+ volatile int i;
+ volatile struct tmscp_softc *sc = &tmscp_softc[d];
+ struct tmscp *tm = &tmscp[d];
+ struct tmscp *ttm;
+ volatile struct mscp *mp;
+
+# ifdef DEBUG
+ printd10("tmscpintr: state %d, tmscpsa %o\n", sc->sc_state, tmscpaddr->tmscpsa);
+# endif
+
+#ifdef QBA
+ if (cpunumber == VAX_78032)
+ splx(sc->sc_ipl);
+#endif
+ /*
+ * How the interrupt is handled depends on the state of the controller.
+ */
+ switch (sc->sc_state) {
+
+ case S_IDLE:
+ printf("tmscp%d: random interrupt ignored\n", d);
+ return;
+
+ /* Controller was in step 1 last, see if its gone to step 2 */
+ case S_STEP1:
+# define STEP1MASK 0174377
+# define STEP1GOOD (TMSCP_STEP2|TMSCP_IE|(NCMDL2<<3)|NRSPL2)
+ for (i = 0; i < 150; i++)
+ {
+ if ((tmscpaddr->tmscpsa&STEP1MASK) != STEP1GOOD)
+ { /* still in step 1 (wait 1/100 sec) */
+ DELAY(10000);
+# ifdef DEBUG
+ printd("still in step 1, delaying\n");
+# endif DEBUG
+ }
+ else
+ break;
+ }
+ if (i > 149)
+ {
+ sc->sc_state = S_IDLE;
+ printf("failed to initialize, in step1: sa 0x%x", tmscpaddr->tmscpsa);
+ wakeup((caddr_t)um);
+ return;
+ }
+ tmscpaddr->tmscpsa = ((int)&sc->sc_tmscp->tmscp_ca.ca_ringbase)
+ | ((cpunumber == VAX_780 || cpunumber == VAX_8600) ?
+ TMSCP_PI : 0);
+ sc->sc_state = S_STEP2;
+ return;
+
+ /* Controller was in step 2 last, see if its gone to step 3 */
+ case S_STEP2:
+# define STEP2MASK 0174377
+# define STEP2GOOD (TMSCP_STEP3|TMSCP_IE|(sc->sc_ivec/4))
+ for (i = 0; i < 150; i++)
+ {
+ if ((tmscpaddr->tmscpsa&STEP2MASK) != STEP2GOOD)
+ { /* still in step 2 (wait 1/100 sec) */
+ DELAY(10000);
+# ifdef DEBUG
+ printd("still in step 2, delaying\n");
+# endif DEBUG
+ }
+ else
+ break;
+ }
+ if (i > 149)
+ {
+ sc->sc_state = S_IDLE;
+ printf("failed to initialize, in step2: sa 0x%x", tmscpaddr->tmscpsa);
+ wakeup((caddr_t)um);
+ return;
+ }
+ tmscpaddr->tmscpsa = ((int)&sc->sc_tmscp->tmscp_ca.ca_ringbase)>>16;
+ sc->sc_state = S_STEP3;
+ return;
+
+ /* Controller was in step 3 last, see if its gone to step 4 */
+ case S_STEP3:
+# define STEP3MASK 0174000
+# define STEP3GOOD TMSCP_STEP4
+ for (i = 0; i < 150; i++)
+ {
+ if ((tmscpaddr->tmscpsa&STEP3MASK) != STEP3GOOD)
+ { /* still in step 3 (wait 1/100 sec) */
+ DELAY(10000);
+# ifdef DEBUG
+ printd("still in step 3, delaying\n");
+# endif DEBUG
+ }
+ else
+ break;
+ }
+ if (i > 149)
+ {
+ sc->sc_state = S_IDLE;
+ printf("failed to initialize, in step3: sa 0x%x", tmscpaddr->tmscpsa);
+ wakeup((caddr_t)um);
+ return;
+ }
+ /*
+ * Get microcode version and model number of controller;
+ * Signal initialization complete (_GO) (to the controller);
+ * ask for Last Fail response if tmscperror is set;
+ * Set state to "set controller characteristics".
+ */
+ tmscpmicro[d] = tmscpaddr->tmscpsa;
+ tmscpaddr->tmscpsa = TMSCP_GO | (tmscperror? TMSCP_LF : 0);
+ sc->sc_state = S_SCHAR;
+# ifdef DEBUG
+ printd("tmscpintr: completed state %d \n", sc->sc_state);
+ printd("tmscp%d Version %d model %d\n",d,tmscpmicro[d]&0xF,
+ (tmscpmicro[d]>>4) & 0xF);
+# endif
+
+ /*
+ * Initialize the data structures (response and command queues).
+ */
+ ttm = sc->sc_tmscp;
+ for (i = 0; i < NRSP; i++)
+ {
+ tm->tmscp_ca.ca_rspdsc[i] = TMSCP_OWN | TMSCP_INT |
+ (long)&ttm->tmscp_rsp[i].mscp_cmdref;
+ tm->tmscp_rsp[i].mscp_dscptr = &tm->tmscp_ca.ca_rspdsc[i];
+ tm->tmscp_rsp[i].mscp_header.tmscp_msglen = mscp_msglen;
+ }
+ for (i = 0; i < NCMD; i++)
+ {
+ tm->tmscp_ca.ca_cmddsc[i] = TMSCP_INT |
+ (long)&ttm->tmscp_cmd[i].mscp_cmdref;
+ tm->tmscp_cmd[i].mscp_dscptr = &tm->tmscp_ca.ca_cmddsc[i];
+ tm->tmscp_cmd[i].mscp_header.tmscp_msglen = mscp_msglen;
+ tm->tmscp_cmd[i].mscp_header.tmscp_vcid = 1;
+ }
+ bp = &tmscpwtab[d];
+ bp->b_actf = NULL;
+ sc->sc_lastcmd = 1;
+ sc->sc_lastrsp = 0;
+ mp = &tmscp[d].tmscp_cmd[0];
+ mp->mscp_unit = mp->mscp_modifier = 0;
+ mp->mscp_flags = 0;
+ mp->mscp_version = 0;
+ mp->mscp_cntflgs = M_CF_ATTN|M_CF_MISC|M_CF_THIS;
+ /*
+ * A host time out value of 0 means that the controller will not
+ * time out. This is ok for the TK50.
+ */
+ mp->mscp_hsttmo = 0;
+ mp->mscp_time = 0;
+ mp->mscp_cntdep = 0;
+ mp->mscp_opcode = M_OP_STCON;
+ *((long *)mp->mscp_dscptr) |= TMSCP_OWN|TMSCP_INT;
+ i = tmscpaddr->tmscpip; /* initiate polling */
+ return;
+
+ case S_SCHAR:
+ case S_RUN:
+ break;
+
+ default:
+ printf("tmscp%d: interrupt in unknown state %d ignored\n",d,sc->sc_state);
+ return;
+ } /* end switch */
+
+ /*
+ * The controller state is S_SCHAR or S_RUN
+ */
+
+ /*
+ * If the error bit is set in the SA register then print an error
+ * message and reinitialize the controller.
+ */
+ if (tmscpaddr->tmscpsa&TMSCP_ERR)
+ {
+ printf("tmscp%d: fatal error (%o)\n", d, tmscpaddr->tmscpsa&0xffff);
+ tmscpaddr->tmscpip = 0;
+ wakeup((caddr_t)um);
+ }
+ /*
+ * Check for a buffer purge request. (Won't happen w/ TK50 on Q22 bus)
+ */
+ if (tm->tmscp_ca.ca_bdp)
+ {
+ UBAPURGE(um->um_hd->uh_uba, tm->tmscp_ca.ca_bdp);
+ tm->tmscp_ca.ca_bdp = 0;
+ tmscpaddr->tmscpsa = 0; /* signal purge complete */
+ }
+
+ /*
+ * Check for response ring transition.
+ */
+ if (tm->tmscp_ca.ca_rspint)
+ {
+ tm->tmscp_ca.ca_rspint = 0;
+ for (i = sc->sc_lastrsp;; i++)
+ {
+ i %= NRSP;
+ if (tm->tmscp_ca.ca_rspdsc[i]&TMSCP_OWN)
+ break;
+ tmscprsp(um, tm, sc, i);
+ tm->tmscp_ca.ca_rspdsc[i] |= TMSCP_OWN;
+ }
+ sc->sc_lastrsp = i;
+ }
+
+ /*
+ * Check for command ring transition.
+ */
+ if (tm->tmscp_ca.ca_cmdint)
+ {
+# ifdef DEBUG
+ printd("tmscpintr: command ring transition\n");
+# endif
+ tm->tmscp_ca.ca_cmdint = 0;
+ }
+ if(tmscp_cp_wait)
+ wakeup((caddr_t)&tmscp_cp_wait);
+ (void) tmscpstart(um);
+}
+
+
+/*
+ * Open a tmscp device and set the unit online. If the controller is not
+ * in the run state, call init to initialize the tmscp controller first.
+ */
+
+/* ARGSUSED */
+tmscpopen(dev, flag)
+ dev_t dev;
+ int flag;
+{
+ register int unit;
+ register struct uba_device *ui;
+ register struct tmscp_softc *sc;
+ register struct tms_info *tms;
+ register volatile struct mscp *mp;
+ register struct uba_ctlr *um;
+ volatile struct tmscpdevice *tmscpaddr;
+ volatile int i;
+ int s;
+
+ unit = TMSUNIT(dev);
+# ifdef DEBUG
+ printd("tmscpopen unit %d\n",unit);
+ if(tmscpdebug)DELAY(10000);
+# endif
+ if (unit >= NTMS || (ui = tmsdinfo[unit]) == 0 || ui->ui_alive == 0)
+ return (ENXIO);
+ tms = &tms_info[ui->ui_unit];
+ if (tms->tms_openf)
+ return (EBUSY);
+ sc = &tmscp_softc[ui->ui_ctlr];
+ tms->tms_openf = 1;
+ tms->tms_tpr = tprintf_open(curproc);
+ s = splbio();
+ if (sc->sc_state != S_RUN)
+ {
+ if (sc->sc_state == S_IDLE)
+ if(!tmscpinit(ui->ui_ctlr))
+ {
+ printf("tmscp controller failed to init\n");
+ (void) splx(s);
+ tms->tms_openf = 0;
+ return(ENXIO);
+ }
+ /*
+ * Wait for initialization to complete
+ */
+ timeout(wakeup,(caddr_t)ui->ui_mi,11*hz); /* to be sure*/
+ sleep((caddr_t)ui->ui_mi, 0);
+ if (sc->sc_state != S_RUN)
+ {
+ (void) splx(s);
+ tms->tms_openf = 0;
+ return (EIO);
+ }
+ }
+ /*
+ * Check to see if the device is really there.
+ * this code was taken from Fred Canters 11 driver
+ */
+ um = ui->ui_mi;
+ tmscpaddr = (struct tmscpdevice *) um->um_addr;
+ (void) splx(s);
+ if(ui->ui_flags == 0)
+ {
+ s = splbio();
+ while(0 ==(mp = tmscpgetcp(um)))
+ {
+ tmscp_cp_wait++;
+ sleep((caddr_t)&tmscp_cp_wait,PSWP+1);
+ tmscp_cp_wait--;
+ }
+ (void) splx(s);
+ mp->mscp_opcode = M_OP_ONLIN;
+ mp->mscp_unit = ui->ui_slave;
+ mp->mscp_cmdref = (long) & tms->tms_type;
+ /* need to sleep on something */
+# ifdef DEBUG
+ printd("tmscpopen: bring unit %d online\n",ui->ui_unit);
+# endif
+ *((long *) mp->mscp_dscptr ) |= TMSCP_OWN | TMSCP_INT;
+ i = tmscpaddr->tmscpip;
+#ifdef lint
+ i = i;
+#endif
+ /*
+ * To make sure we wake up, timeout in 240 seconds.
+ * Wakeup in tmscprsp routine.
+ * 240 seconds (4 minutes) is necessary since a rewind
+ * can take a few minutes.
+ */
+ timeout(wakeup,(caddr_t) mp->mscp_cmdref,240 * hz);
+ sleep((caddr_t) mp->mscp_cmdref,PSWP+1);
+ }
+ if(ui->ui_flags == 0) {
+ tms->tms_openf = 0;
+ return(ENXIO); /* Didn't go online */
+ }
+ tms->tms_lastiow = 0;
+ /*
+ * If the high density device is not specified, set unit to low
+ * density. This is done as an "internal" ioctl command so
+ * that the command setup and response handling
+ * is done thru "regular" command routines.
+ */
+ if ((minor(dev) & T_HIDENSITY) == 0)
+ tmscpcommand(dev, TMS_LOWDENSITY, 1);
+ else
+ tmscpcommand(dev, TMS_HIDENSITY, 1);
+ return (0);
+}
+
+
+/*
+ * Close tape device.
+ *
+ * If tape was open for writing or last operation was
+ * a write, then write two EOF's and backspace over the last one.
+ * Unless this is a non-rewinding special file, rewind the tape.
+ *
+ * NOTE:
+ * We want to be sure that any serious exception is cleared on the
+ * close. A Clear Serious Exception (CSE) modifier is always done on
+ * the rewind command. For the non-rewind case we check to see if the
+ * "serex" field is set in the softc struct; if it is then issue a noop
+ * command with the CSE modifier.
+ * Make the tape available to others, by clearing openf flag.
+ */
+tmscpclose(dev, flag)
+ register dev_t dev;
+ register flag;
+{
+ register struct tms_info *tms;
+ register struct uba_device *ui;
+
+ ui = tmsdinfo[TMSUNIT(dev)];
+# ifdef DEBUG
+ printd("tmscpclose: ctlr = %d\n",TMSCPCTLR(dev));
+ printd("tmscpclose: unit = %d\n",TMSUNIT(dev));
+ if(tmscpdebug)DELAY(10000);
+# endif
+ tms = &tms_info[ui->ui_unit];
+ if (flag == FWRITE || (flag&FWRITE) && tms->tms_lastiow)
+ {
+ /* device, command, count */
+ tmscpcommand (dev, TMS_WRITM, 1);
+ tmscpcommand (dev, TMS_WRITM, 1);
+ tmscpcommand (dev, TMS_BSR, 1);
+ }
+ if ((minor(dev)&T_NOREWIND) == 0)
+ /*
+ * Don't hang waiting for rewind complete.
+ */
+ tmscpcommand(dev, TMS_REW, 0);
+ else
+ if (tms->tms_serex)
+ {
+# ifdef DEBUG
+ printd("tmscpclose: clearing serex\n");
+ if(tmscpdebug)DELAY(10000);
+# endif
+ tmscpcommand(dev, TMS_CSE, 1);
+ }
+ tprintf_close(tms->tms_tpr);
+ tms->tms_openf = 0;
+ return (0);
+}
+
+
+/*
+ * Execute a command on the tape drive a specified number of times.
+ * This routine sets up a buffer and calls the strategy routine which
+ * links the buffer onto the drive's buffer queue.
+ * The start routine will take care of creating a tmscp command packet
+ * with the command. The start routine is called by the strategy or the
+ * interrupt routine.
+ */
+
+tmscpcommand (dev, com, count)
+ register dev_t dev;
+ int com, count;
+{
+ register struct uba_device *ui;
+ register struct buf *bp;
+ register int s;
+ int unit = TMSUNIT(dev);
+
+ ui = tmsdinfo[unit];
+ bp = &ctmscpbuf[ui->ui_ctlr];
+
+ s = splbio();
+ while (bp->b_flags&B_BUSY)
+ {
+ /*
+ * This special check is because B_BUSY never
+ * gets cleared in the non-waiting rewind case.
+ */
+ if (bp->b_bcount == 0 && (bp->b_flags&B_DONE))
+ break;
+ bp->b_flags |= B_WANTED;
+ sleep((caddr_t)bp, PRIBIO);
+ }
+ bp->b_flags = B_BUSY|B_READ;
+ splx(s);
+ /*
+ * Load the buffer. The b_count field gets used to hold the command
+ * count. the b_resid field gets used to hold the command mneumonic.
+ * These 2 fields are "known" to be "safe" to use for this purpose.
+ * (Most other drivers also use these fields in this way.)
+ */
+ bp->b_dev = dev;
+ bp->b_bcount = count;
+ bp->b_resid = com;
+ bp->b_blkno = 0;
+ tmscpstrategy(bp);
+ /*
+ * In case of rewind from close, don't wait.
+ * This is the only case where count can be 0.
+ */
+ if (count == 0)
+ return;
+ iowait(bp);
+ if (bp->b_flags&B_WANTED)
+ wakeup((caddr_t)bp);
+ bp->b_flags &= B_ERROR;
+}
+
+/*
+ * Find an unused command packet
+ */
+struct mscp *
+tmscpgetcp(um)
+ struct uba_ctlr *um;
+{
+ register volatile struct mscp *mp;
+ register volatile struct tmscpca *cp;
+ register struct tmscp_softc *sc;
+ register int i;
+ int s;
+
+ s = splbio();
+ cp = &tmscp[um->um_ctlr].tmscp_ca;
+ sc = &tmscp_softc[um->um_ctlr];
+ /*
+ * If no credits, can't issue any commands
+ * until some outstanding commands complete.
+ */
+ i = sc->sc_lastcmd;
+# ifdef DEBUG
+ printd10("tmscpgetcp: %d credits remain\n", sc->sc_credits);
+# endif
+ if(((cp->ca_cmddsc[i]&(TMSCP_OWN|TMSCP_INT))==TMSCP_INT) &&
+ (sc->sc_credits >= 2))
+ {
+ sc->sc_credits--; /* This commits to issuing a command */
+ cp->ca_cmddsc[i] &= ~TMSCP_INT;
+ mp = &tmscp[um->um_ctlr].tmscp_cmd[i];
+ mp->mscp_unit = mp->mscp_modifier = 0;
+ mp->mscp_opcode = mp->mscp_flags = 0;
+ mp->mscp_bytecnt = mp->mscp_buffer = 0;
+ sc->sc_lastcmd = (i + 1) % NCMD;
+ (void) splx(s);
+ return((struct mscp *)mp);
+ }
+ (void) splx(s);
+ return(NULL);
+}
+
+
+/*
+ * Initialize a TMSCP device. Set up UBA mapping registers,
+ * initialize data structures, and start hardware
+ * initialization sequence.
+ */
+tmscpinit (d)
+ int d; /* index to the controller */
+{
+ register struct tmscp_softc *sc;
+ register struct tmscp *t;
+ volatile struct tmscpdevice *tmscpaddr;
+ struct uba_ctlr *um;
+
+ sc = &tmscp_softc[d];
+ um = tmscpminfo[d];
+ um->um_tab.b_active++;
+ t = &tmscp[d];
+ tmscpaddr = (struct tmscpdevice *)um->um_addr;
+ if (sc->sc_mapped == 0)
+ {
+ /*
+ * Map the communications area and command
+ * and response packets into Unibus address
+ * space.
+ */
+ sc->sc_ubainfo = uballoc(um->um_ubanum, (caddr_t)t, sizeof (struct tmscp), 0);
+ sc->sc_tmscp = (struct tmscp *)(UBAI_ADDR(sc->sc_ubainfo));
+ sc->sc_mapped = 1;
+ }
+
+ /*
+ * Start the hardware initialization sequence.
+ */
+ tmscpaddr->tmscpip = 0; /* start initialization */
+
+ while((tmscpaddr->tmscpsa & TMSCP_STEP1) == 0)
+ {
+# ifdef DEBUG
+ printd("tmscpinit: tmscpsa = 0%o\n",tmscpaddr->tmscpsa);
+ DELAY(100000);
+# endif
+ if(tmscpaddr->tmscpsa & TMSCP_ERR)
+ return(0); /* CHECK */
+ }
+ tmscpaddr->tmscpsa=TMSCP_ERR|(NCMDL2<<11)|(NRSPL2<<8)|TMSCP_IE|(sc->sc_ivec/4);
+ /*
+ * Initialization continues in the interrupt routine.
+ */
+ sc->sc_state = S_STEP1;
+ sc->sc_credits = 0;
+ return(1);
+}
+
+
+/*
+ * Start I/O operation
+ * This code is convoluted. The majority of it was copied from the uda driver.
+ */
+
+tmscpstart(um)
+ register struct uba_ctlr *um;
+{
+ register struct buf *bp, *dp;
+ register volatile struct mscp *mp;
+ register struct tmscp_softc *sc;
+ register struct tms_info *tms;
+ register struct uba_device *ui;
+ volatile struct tmscpdevice *tmscpaddr;
+ volatile struct tmscp *tm = &tmscp[um->um_ctlr];
+ volatile int i;
+ int tempi;
+ char ioctl; /* flag: set true if its an IOCTL command */
+
+ sc = &tmscp_softc[um->um_ctlr];
+
+ for(;;)
+ {
+ if ((dp = um->um_tab.b_actf) == NULL)
+ {
+ /*
+ * Release unneeded UBA resources and return
+ * (drive was inactive)
+ */
+ um->um_tab.b_active = 0;
+ break;
+ }
+ if ((bp = dp->b_actf) == NULL)
+ {
+ /*
+ * No more requests for this drive, remove
+ * from controller queue and look at next drive.
+ * We know we're at the head of the controller queue.
+ */
+ dp->b_active = 0;
+ um->um_tab.b_actf = dp->b_hash.le_next;
+ continue; /* Need to check for loop */
+ }
+ um->um_tab.b_active++;
+ tmscpaddr = (struct tmscpdevice *)um->um_addr;
+ ui = tmsdinfo[(TMSUNIT(bp->b_dev))];
+ tms = &tms_info[ui->ui_unit];
+ if ((tmscpaddr->tmscpsa&TMSCP_ERR) || sc->sc_state != S_RUN)
+ {
+ tprintf(tms->tms_tpr,
+ "tms%d: hard error bn%d\n",
+ minor(bp->b_dev)&03, bp->b_blkno);
+ log(TMS_PRI, "tmscp%d: sa 0%o, state %d\n",um->um_ctlr,
+ tmscpaddr->tmscpsa&0xffff, sc->sc_state);
+ (void)tmscpinit(um->um_ctlr);
+ /* SHOULD REQUEUE OUTSTANDING REQUESTS, LIKE TMSCPRESET */
+ break;
+ }
+ /*
+ * Default is that last command was NOT a write command;
+ * if a write command is done it will be detected in tmscprsp.
+ */
+ tms->tms_lastiow = 0;
+ if (ui->ui_flags == 0)
+ { /* not online */
+ if ((mp = tmscpgetcp(um)) == NULL)
+ break;
+ mp->mscp_opcode = M_OP_ONLIN;
+ mp->mscp_unit = ui->ui_slave;
+ dp->b_active = 2;
+ um->um_tab.b_actf = dp->b_hash.le_next; /* remove from controller q */
+ *((long *)mp->mscp_dscptr) |= TMSCP_OWN|TMSCP_INT;
+ if (tmscpaddr->tmscpsa&TMSCP_ERR)
+ printf("tmscp%d fatal error (0%o)\n",um->um_ctlr,
+ tmscpaddr->tmscpsa&0xffff);
+ i = tmscpaddr->tmscpip;
+ continue;
+ }
+ switch (cpunumber) {
+
+ case VAX_8600:
+ case VAX_780:
+ i = UBA_NEEDBDP|UBA_CANTWAIT;
+ break;
+ case VAX_750:
+ i = um->um_ubinfo|UBA_HAVEBDP|UBA_CANTWAIT;
+ break;
+ case VAX_730:
+ case VAX_78032:
+ i = UBA_CANTWAIT;
+ break;
+ } /* end switch (cpunumber) */
+ /*
+ * If command is an ioctl command then set the ioctl flag for later use.
+ * If not (i.e. it is a read or write) then attempt
+ * to set up a buffer pointer.
+ */
+ ioctl = 0;
+ if (bp == &ctmscpbuf[um->um_ctlr])
+ ioctl = 1;
+ else
+ if ((i = ubasetup(um->um_ubanum, bp, i)) == 0)
+ {
+ if(dp->b_qsize != 0)
+ break; /* When a command completes and */
+ /* frees a bdp tmscpstart will be called */
+ if ((mp = tmscpgetcp(um)) == NULL)
+ break;
+# ifdef DEBUG
+ printd("tmscpstart: GTUNT %d ubasetup = %d\n",ui->ui_unit, i);
+ if(tmscpdebug)DELAY(10000);
+# endif
+ mp->mscp_opcode = M_OP_GTUNT;
+ mp->mscp_unit = ui->ui_slave;
+ *((long *)mp->mscp_dscptr) |= TMSCP_OWN|TMSCP_INT;
+ if (tmscpaddr->tmscpsa&TMSCP_ERR)
+ printf("tmscp%d: fatal error (0%o)\n",um->um_ctlr,
+ tmscpaddr->tmscpsa&0xffff);
+ i = tmscpaddr->tmscpip; /* initiate polling */
+ break;
+ }
+# if defined(VAX750)
+ if (cpunumber == VAX_750)
+ tempi = i & 0xfffffff; /* mask off bdp */
+ else
+# endif
+ tempi = i;
+ if ((mp = tmscpgetcp(um)) == NULL)
+ {
+ if (!ioctl) /* only need to release if NOT ioctl */
+ ubarelse(um->um_ubanum,&tempi);
+ break;
+ }
+ mp->mscp_cmdref = (long)bp; /* pointer to get back */
+ mp->mscp_unit = ui->ui_slave;
+ /*
+ * If its an ioctl-type command then set up the appropriate
+ * tmscp command; by doing a switch on the "b_resid" field where
+ * the command mneumonic is stored.
+ */
+ if (ioctl)
+ {
+# ifdef DEBUG
+ printd("tmscpstart: doing ioctl cmd %d\n", bp->b_resid);
+# endif
+ /*
+ * The reccnt and tmkcnt fields are set to zero by the getcp
+ * routine (as bytecnt and buffer fields). Thus reccnt and
+ * tmkcnt are only modified here if they need to be set to
+ * a non-zero value.
+ */
+ switch ((int)bp->b_resid) {
+
+ case TMS_WRITM:
+ mp->mscp_opcode = M_OP_WRITM;
+ break;
+ case TMS_FSF:
+ mp->mscp_opcode = M_OP_REPOS;
+ mp->mscp_tmkcnt = bp->b_bcount;
+ break;
+ case TMS_BSF:
+ mp->mscp_opcode = M_OP_REPOS;
+ mp->mscp_modifier = M_MD_REVRS;
+ mp->mscp_tmkcnt = bp->b_bcount;
+ break;
+ case TMS_FSR:
+ mp->mscp_opcode = M_OP_REPOS;
+ mp->mscp_modifier = M_MD_OBJCT;
+ mp->mscp_reccnt = bp->b_bcount;
+ break;
+ case TMS_BSR:
+ mp->mscp_opcode = M_OP_REPOS;
+ mp->mscp_modifier = M_MD_REVRS | M_MD_OBJCT;
+ mp->mscp_reccnt = bp->b_bcount;
+ break;
+ /*
+ * Clear serious exception is done for Rewind & Available cmds
+ */
+ case TMS_REW:
+ mp->mscp_opcode = M_OP_REPOS;
+ mp->mscp_modifier = M_MD_REWND | M_MD_CLSEX;
+ if (bp->b_bcount == 0)
+ mp->mscp_modifier |= M_MD_IMMED;
+ tms->tms_serex = 0;
+ break;
+ case TMS_OFFL:
+ mp->mscp_opcode = M_OP_AVAIL;
+ mp->mscp_modifier = M_MD_UNLOD | M_MD_CLSEX;
+ tms->tms_serex = 0;
+ break;
+ case TMS_SENSE:
+ mp->mscp_opcode = M_OP_GTUNT;
+ break;
+ case TMS_CACHE:
+ mp->mscp_opcode = M_OP_STUNT;
+ tms->tms_unitflgs |= M_UF_WBKNV;
+ mp->mscp_unitflgs = tms->tms_unitflgs;
+ mp->mscp_format = tms->tms_format;
+ /* default device dependant parameters */
+ mp->mscp_mediaid = 0;
+ break;
+ case TMS_NOCACHE:
+ mp->mscp_opcode = M_OP_STUNT;
+ tms->tms_unitflgs &= ~(M_UF_WBKNV);
+ mp->mscp_unitflgs = tms->tms_unitflgs;
+ mp->mscp_format = tms->tms_format;
+ /* default device dependant parameters */
+ mp->mscp_mediaid = 0;
+ break;
+ case TMS_CSE:
+ /*
+ * This is a no-op command. It performs a
+ * clear serious exception only. (Done on a
+ * non-rewinding close after a serious exception.)
+ */
+ mp->mscp_opcode = M_OP_REPOS;
+ mp->mscp_modifier = M_MD_CLSEX;
+ tms->tms_serex = 0;
+ tms->tms_clserex = 1;
+ break;
+ case TMS_LOWDENSITY:
+ /*
+ * Set the unit to low density
+ */
+ mp->mscp_opcode = M_OP_STUNT;
+ mp->mscp_unitflgs = tms->tms_unitflgs;
+ mp->mscp_mediaid = 0; /* default device dependant parameters */
+ if ((tms->tms_fmtmenu & M_TF_800) != 0)
+ mp->mscp_format = M_TF_800;
+ else
+ mp->mscp_format = M_TF_PE & tms->tms_fmtmenu;
+ tms->tms_format = mp->mscp_format;
+ break;
+ case TMS_HIDENSITY:
+ /*
+ * Set the unit to high density (format == 0)
+ */
+ mp->mscp_opcode = M_OP_STUNT;
+ mp->mscp_unitflgs = tms->tms_unitflgs;
+ mp->mscp_mediaid = 0; /* default device dependant parameters */
+ mp->mscp_format = 0;
+ tms->tms_format = 0;
+ break;
+ default:
+ printf("Bad ioctl on tms unit %d\n", ui->ui_unit);
+ /* Need a no-op. Reposition no amount */
+ mp->mscp_opcode = M_OP_REPOS;
+ break;
+ } /* end switch (bp->b_resid) */
+ }
+ else /* Its a read/write command (not an ioctl) */
+ {
+ mp->mscp_opcode = bp->b_flags&B_READ ? M_OP_READ : M_OP_WRITE;
+ mp->mscp_bytecnt = bp->b_bcount;
+ mp->mscp_buffer = UBAI_ADDR(i) | (UBAI_BDP(i) << 24);
+
+ bp->b_ubinfo = tempi; /* save mapping info */
+ }
+ if (tms->tms_serex == 2) /* if tape mark read */
+ {
+ mp->mscp_modifier |= M_MD_CLSEX; /* clear serious exc */
+ tms->tms_serex = 0;
+ }
+ *((long *)mp->mscp_dscptr) |= TMSCP_OWN|TMSCP_INT;
+# ifdef DEBUG
+ printd("tmscpstart: opcode 0%o mod %o unit %d cnt %d\n",mp->mscp_opcode,mp->mscp_modifier,mp->mscp_unit,mp->mscp_bytecnt);
+ if(tmscpdebug)DELAY(100000);
+# endif
+ i = tmscpaddr->tmscpip; /* initiate polling */
+ dp->b_qsize++;
+ /*
+ * Move drive to the end of the controller queue
+ */
+ if (dp->b_hash.le_next != NULL)
+ {
+ um->um_tab.b_actf = dp->b_hash.le_next;
+ MSCP_APPEND(dp, &um->um_tab, b_hash.le_next);
+ }
+ /*
+ * Move buffer to I/O wait queue
+ */
+ dp->b_actf = bp->b_actf;
+ dp = &tmscpwtab[um->um_ctlr];
+ MSCP_APPEND(bp, dp, b_actf);
+ if (tmscpaddr->tmscpsa&TMSCP_ERR)
+ {
+ printf("tmscp%d: fatal error (0%o)\n", um->um_ctlr, tmscpaddr->tmscpsa&0xffff);
+ (void)tmscpinit(um->um_ctlr);
+ break;
+ }
+ } /* end for */
+ /*
+ * Check for response ring transitions lost in the
+ * Race condition
+ */
+ for (i = sc->sc_lastrsp;; i++)
+ {
+ i %= NRSP;
+ if (tm->tmscp_ca.ca_rspdsc[i]&TMSCP_OWN)
+ break;
+ tmscprsp(um, tm, sc, i);
+ tm->tmscp_ca.ca_rspdsc[i] |= TMSCP_OWN;
+ }
+ sc->sc_lastrsp = i;
+}
+
+
+/*
+ * Process a response packet
+ */
+tmscprsp(um, tm, sc, i)
+ register struct uba_ctlr *um;
+ register volatile struct tmscp *tm;
+ register struct tmscp_softc *sc;
+ int i;
+{
+ register volatile struct mscp *mp;
+ register struct tms_info *tms;
+ struct uba_device *ui;
+ struct buf *dp, *bp;
+ int st;
+
+ mp = &tm->tmscp_rsp[i];
+ mp->mscp_header.tmscp_msglen = mscp_msglen;
+ sc->sc_credits += mp->mscp_header.tmscp_credits & 0xf; /* low 4 bits */
+ if ((mp->mscp_header.tmscp_credits & 0xf0) > 0x10) /* Check */
+ return;
+# ifdef DEBUG
+ printd("tmscprsp, opcode 0%o status 0%o\n",mp->mscp_opcode,mp->mscp_status&M_ST_MASK);
+# endif
+ /*
+ * If it's an error log message (datagram),
+ * pass it on for more extensive processing.
+ */
+ if ((mp->mscp_header.tmscp_credits & 0xf0) == 0x10)
+ { /* check */
+ tmserror(um, (struct mslg *)mp);
+ return;
+ }
+ st = mp->mscp_status&M_ST_MASK;
+ /*
+ * The controller interrupts as drive 0.
+ * This means that you must check for controller interrupts
+ * before you check to see if there is a drive 0.
+ */
+ if((M_OP_STCON|M_OP_END) == mp->mscp_opcode)
+ {
+ if (st == M_ST_SUCC)
+ {
+# ifdef DEBUG
+ printd("ctlr has %d credits\n", mp->mscp_header.tmscp_credits & 0xf);
+ printd("ctlr timeout = %d\n", mp->mscp_cnttmo);
+# endif
+ sc->sc_state = S_RUN;
+ }
+ else
+ sc->sc_state = S_IDLE;
+ um->um_tab.b_active = 0;
+ wakeup((caddr_t)um);
+ return;
+ }
+ if (mp->mscp_unit >= NTMS)
+ return;
+ if ((ui = tmscpip[um->um_ctlr][mp->mscp_unit]) == 0)
+ return;
+ tms = &tms_info[ui->ui_unit];
+ /*
+ * Save endcode, endflags, and status for mtioctl get unit status.
+ * NOTE: Don't do this on Clear serious exception (reposition no-op);
+ * which is done on close since this would
+ * overwrite the real status we want.
+ */
+ if (tms->tms_clserex != 1)
+ {
+ tms->tms_endcode = mp->mscp_opcode;
+ tms->tms_flags = mp->mscp_flags;
+ tms->tms_status = st;
+ }
+ else tms->tms_clserex = 0;
+
+ switch (mp->mscp_opcode) {
+ case M_OP_ONLIN|M_OP_END:
+ tms->tms_type = mp->mscp_mediaid;
+ dp = &tmsutab[ui->ui_unit];
+ if (st == M_ST_SUCC)
+ {
+ /*
+ * Link the drive onto the controller queue
+ */
+ MSCP_APPEND(dp, &um->um_tab, b_hash.le_next);
+ ui->ui_flags = 1; /* mark it online */
+ tms->tms_dsize=(daddr_t)mp->mscp_maxwrt;
+# ifdef DEBUG
+ printd("tmscprsp: unit %d online\n", mp->mscp_unit);
+# endif
+ /*
+ * This define decodes the Media type identifier
+ */
+# define F_to_C(x,i) ( ((x)->mscp_mediaid) >> (i*5+7) & 0x1f ? ( ( (((x)->mscp_mediaid) >>( i*5 + 7)) & 0x1f) + 'A' - 1): ' ')
+# ifdef DEBUG
+ printd("tmscprsp: unit %d online %x %c%c %c%c%c%d\n"
+ ,mp->mscp_unit, mp->mscp_mediaid ,F_to_C(mp,4)
+ ,F_to_C(mp,3), F_to_C(mp,2)
+ ,F_to_C(mp,1), F_to_C(mp,0), mp->mscp_mediaid & 0x7f);
+# endif
+ dp->b_active = 1;
+ } /* end if st == M_ST_SUCC */
+ else
+ {
+ if (bp = dp->b_actf)
+ tprintf(tms->tms_tpr,
+ "tms%d: hard error bn%d: OFFLINE\n",
+ minor(bp->b_dev)&03, bp->b_blkno);
+ else
+ tprintf(tms->tms_tpr,
+ "tms%d: hard error: OFFLINE\n",
+ ui->ui_unit);
+ while (bp = dp->b_actf)
+ {
+ dp->b_actf = bp->b_actf;
+ bp->b_flags |= B_ERROR;
+ iodone(bp);
+ }
+ }
+ if(mp->mscp_cmdref!=NULL)
+ /* Seems to get lost sometimes in uda */
+ wakeup((caddr_t)mp->mscp_cmdref);
+ break;
+ /*
+ * The AVAILABLE ATTENTION message occurs when the
+ * unit becomes available after loading,
+ * marking the unit offline (ui_flags = 0) will force an
+ * online command prior to using the unit.
+ */
+ case M_OP_AVATN:
+ ui->ui_flags = 0;
+ tms->tms_type = mp->mscp_mediaid;
+ break;
+ case M_OP_END:
+ /*
+ * An endcode without an opcode (0200) is an invalid command.
+ * The mscp specification states that this would be a protocol
+ * type error, such as illegal opcodes. The mscp spec. also
+ * states that parameter error type of invalid commands should
+ * return the normal end message for the command. This does not appear
+ * to be the case. An invalid logical block number returned an endcode
+ * of 0200 instead of the 0241 (read) that was expected.
+ */
+
+ printf("tmscp%d: invalid cmd, endcode = %o, status=%o\n",
+ um->um_ctlr, mp->mscp_opcode, st);
+ bp = (struct buf *)mp->mscp_cmdref;
+ /*
+ * Unlink buffer from I/O wait queue.
+ * And signal iodone, so the higher level command can exit!
+ *
+ */
+ dp = &tmscpwtab[um->um_ctlr];
+ while (dp && dp->b_actf != bp)
+ dp = dp->b_actf;
+ if (dp == NULL)
+ panic("tmscp: don't work1!");
+ dp->b_actf = bp->b_actf;
+ dp = &tmsutab[ui->ui_unit];
+ dp->b_qsize--;
+ iodone(bp);
+ break;
+ case M_OP_WRITE|M_OP_END:
+ /* mark the last io op as a write */
+ tms->tms_lastiow = 1;
+ case M_OP_READ|M_OP_END:
+ case M_OP_WRITM|M_OP_END:
+ case M_OP_REPOS|M_OP_END:
+ case M_OP_STUNT|M_OP_END:
+ /*
+ * The AVAILABLE message occurs when the mt ioctl "rewoffl" is
+ * issued. For the ioctl, "rewoffl", a tmscp AVAILABLE command is
+ * done with the UNLOAD modifier. This performs a rewind, followed
+ * by marking the unit offline. So mark the unit offline
+ * software wise as well (ui_flags = 0 and
+ * tms->tms_openf = 0).
+ */
+ case M_OP_AVAIL|M_OP_END:
+# ifdef DEBUG
+ printd("tmscprsp: position = %d\n", mp->mscp_lbn);
+# endif
+ bp = (struct buf *)mp->mscp_cmdref;
+ /*
+ * Only need to release buffer if the command was read or write.
+ * No ubasetup was done in "tmscpstart" if it was an ioctl cmd.
+ */
+ if (mp->mscp_opcode == (M_OP_READ|M_OP_END) ||
+ mp->mscp_opcode == (M_OP_WRITE|M_OP_END))
+ ubarelse(um->um_ubanum, (int *)&bp->b_ubinfo);
+ /*
+ * Unlink buffer from I/O wait queue.
+ */
+ dp = &tmscpwtab[um->um_ctlr];
+ while (dp && dp->b_actf != bp)
+ dp = dp->b_actf;
+ if (dp == NULL)
+ panic("tmscp: don't work2!");
+ dp->b_actf = bp->b_actf;
+# if defined(VAX750)
+ if (cpunumber == VAX_750) {
+ if ((tmscpwtab[um->um_ctlr].b_actf == NULL) &&
+ (um->um_ubinfo != 0)) {
+ ubarelse(um->um_ubanum, &um->um_ubinfo);
+ }
+ else {
+ if (mp->mscp_opcode == (M_OP_READ|M_OP_END) ||
+ mp->mscp_opcode == (M_OP_WRITE|M_OP_END))
+ UBAPURGE(uba_hd[um->um_ubanum].uh_uba,(um->um_ubinfo >>28) & 0x0f);
+ }
+ }
+# endif
+ dp = &tmsutab[ui->ui_unit];
+ dp->b_qsize--;
+ if (st == M_ST_OFFLN || st == M_ST_AVLBL)
+ {
+ ui->ui_flags = 0; /* mark unit offline */
+ tms->tms_openf = 0;
+ tms->tms_type = mp->mscp_mediaid;
+ /*
+ * Link the buffer onto the front of the drive queue
+ */
+ bp->b_actf = dp->b_actf;
+ dp->b_actf = bp;
+ /*
+ * Link the drive onto the controller queue
+ */
+ if (dp->b_active == 0)
+ {
+ MSCP_APPEND(dp, &um->um_tab, b_hash.le_next);
+ dp->b_active = 1;
+ }
+# if defined(VAX750)
+ if (cpunumber == VAX_750 && um->um_ubinfo == 0)
+ um->um_ubinfo = uballoc(um->um_ubanum, (caddr_t)0, 0, UBA_NEEDBDP);
+# endif
+ return;
+ }
+ if (st != M_ST_SUCC)
+ {
+ if (mp->mscp_flags & M_EF_SEREX)
+ tms->tms_serex = 1;
+ if (st != M_ST_TAPEM)
+ {
+ tprintf(tms->tms_tpr,
+ "tms%d: hard error bn%d\n",
+ minor(bp->b_dev)&03, bp->b_blkno);
+ errinfo(st); /* produces more info */
+# ifdef DEBUG
+ printd("tmscprsp: error; status sub-code = 0%o, flags = 0%o\n",
+ (mp->mscp_status & 177740)>>5, mp->mscp_flags);
+# endif
+ bp->b_flags |= B_ERROR;
+ }
+ else
+ /* Hit a tape mark - Set serex flag to
+ * a special value so we can clear the
+ * serious exception on the next command.
+ */
+ tms->tms_serex = 2;
+ }
+ /*
+ * The tmscp spec states that controllers do not have to
+ * report the number of records or files skipped. So on
+ * reposition commands we go strictly by cmd status.
+ */
+ if (mp->mscp_opcode != (M_OP_REPOS|M_OP_END))
+ bp->b_resid = bp->b_bcount - mp->mscp_bytecnt;
+ else
+ bp->b_resid = 0;
+ tms->tms_resid = bp->b_resid;
+ iodone(bp);
+ break;
+
+ case M_OP_GTUNT|M_OP_END:
+# ifdef DEBUG
+ printd("tmscprsp: GTUNT end packet status = 0%o\n",st);
+ printd("tmscprsp: unit %d mediaid %x %c%c %c%c%c%d %x %x t=%d\n"
+ ,mp->mscp_unit, mp->mscp_mediaid
+ ,F_to_C(mp,4),F_to_C(mp,3),F_to_C(mp,2)
+ ,F_to_C(mp,1),F_to_C(mp,0)
+ ,mp->mscp_mediaid & 0x7f
+ ,mp->mscp_unitid.val[0]
+ ,mp->mscp_unitid.val[1]
+ ,mp->mscp_format);
+# endif
+ tms->tms_type = mp->mscp_mediaid;
+ tms->tms_fmtmenu = mp->mscp_fmtmenu;
+ tms->tms_unitflgs = mp->mscp_unitflgs;
+ break;
+
+ default:
+ printf("tmscp unknown packet\n");
+ tmserror(um, (struct mslg *)mp);
+ } /* end switch mp->mscp_opcode */
+}
+
+
+/*
+ * Give a meaningful error when the mscp_status field returns an error code.
+ */
+
+errinfo(st)
+ int st; /* the status code */
+{
+ switch(st) {
+ case M_ST_ICMD:
+ printf("invalid command\n");
+ break;
+ case M_ST_ABRTD:
+ printf("command aborted\n");
+ break;
+ case M_ST_OFFLN:
+ printf("unit offline\n");
+ break;
+ case M_ST_WRTPR:
+ printf("unit write protected\n");
+ break;
+ case M_ST_COMP:
+ printf("compare error\n");
+ break;
+ case M_ST_DATA:
+ printf("data error\n");
+ break;
+ case M_ST_HSTBF:
+ printf("host buffer access error\n");
+ break;
+ case M_ST_CNTLR:
+ printf("controller error\n");
+ break;
+ case M_ST_DRIVE:
+ printf("drive error\n");
+ break;
+ case M_ST_FMTER:
+ printf("formatter error\n");
+ break;
+ case M_ST_BOT:
+ printf("BOT encountered\n");
+ break;
+ case M_ST_TAPEM:
+ printf("tape mark encountered\n");
+ break;
+ case M_ST_RDTRN:
+ printf("record data truncated\n");
+ break;
+ case M_ST_PLOST:
+ printf("position lost\n");
+ break;
+ case M_ST_SEX:
+ printf("serious exception\n");
+ break;
+ case M_ST_LED:
+ printf("LEOT detected\n");
+ break;
+ }
+}
+
+
+/*
+ * Manage buffers and perform block mode read and write operations.
+ */
+
+void
+tmscpstrategy (bp)
+ register struct buf *bp;
+{
+ register struct uba_device *ui;
+ register struct uba_ctlr *um;
+ register struct buf *dp;
+ register int unit = TMSUNIT(bp->b_dev);
+ int s;
+
+ if (unit >= NTMS)
+ {
+# ifdef DEBUG
+ printd ("tmscpstrategy: bad unit # %d\n",unit);
+# endif
+ bp->b_flags |= B_ERROR;
+ iodone(bp);
+ return;
+ }
+ ui = tmsdinfo[unit];
+ um = ui->ui_mi;
+ if (ui == 0 || ui->ui_alive == 0)
+ {
+ bp->b_flags |= B_ERROR;
+ iodone(bp);
+ return;
+ }
+ s = splbio();
+ /*
+ * Link the buffer onto the drive queue
+ */
+ dp = &tmsutab[ui->ui_unit];
+ MSCP_APPEND(bp, dp, b_actf);
+ /*
+ * Link the drive onto the controller queue
+ */
+ if (dp->b_active == 0)
+ {
+ MSCP_APPEND(dp, &um->um_tab, b_hash.le_next);
+ dp->b_active = 1;
+ }
+ /*
+ * If the controller is not active, start it.
+ */
+ if (um->um_tab.b_active == 0)
+ {
+# if defined(VAX750)
+ if (cpunumber == VAX_750
+ && tmscpwtab[um->um_ctlr].b_actf == NULL)
+ {
+ if (um->um_ubinfo != 0)
+ log(TMS_PRI, "tmscpstrategy: ubinfo 0x%x\n",
+ um->um_ubinfo);
+ else
+ um->um_ubinfo = uballoc(um->um_ubanum, (caddr_t)0, 0, UBA_NEEDBDP);
+ }
+# endif
+# ifdef DEBUG
+ printd10("tmscpstrategy: Controller not active, starting it\n");
+# endif
+ (void) tmscpstart(um);
+ }
+ splx(s);
+ return;
+}
+
+int
+tmscpread(dev, uio)
+ dev_t dev;
+ struct uio *uio;
+{
+
+ return (physio(tmscpstrategy, NULL, dev, B_READ, minphys, uio));
+}
+
+int
+tmscpwrite(dev, uio)
+ dev_t dev;
+ struct uio *uio;
+{
+
+ return (physio(tmscpstrategy, NULL, dev, B_WRITE, minphys, uio));
+}
+
+#define DBSIZE 32
+
+#define ca_Rspdsc ca_rspdsc[0]
+#define ca_Cmddsc ca_rspdsc[1]
+#define tmscp_Rsp tmscp_rsp[0]
+#define tmscp_Cmd tmscp_cmd[0]
+
+struct tmscp tmscpd[NTMSCP];
+
+tmscpdump(dev)
+ dev_t dev;
+{
+#ifdef notyet
+ volatile struct tmscpdevice *tmscpaddr;
+ volatile struct tmscp *tmscp_ubaddr;
+ char *start;
+ int num, blk, unit;
+ register struct uba_regs *uba;
+ register struct uba_device *ui;
+ register volatile struct tmscp *tmscpp;
+ register struct pte *io;
+ register int i;
+
+ unit = minor(dev) & 03;
+ if (unit >= NTMS)
+ return (ENXIO);
+# define phys(cast, addr) ((cast)((int)addr & 0x7fffffff))
+ ui = phys(struct uba_device *, tmsdinfo[unit]);
+ if (ui->ui_alive == 0)
+ return (ENXIO);
+ uba = phys(struct uba_hd *, ui->ui_hd)->uh_physuba;
+ ubainit(uba);
+ tmscpaddr = (struct tmscpdevice *)ui->ui_physaddr;
+ DELAY(2000000);
+ tmscpp = phys(struct tmscp *, &tmscpd[ui->ui_ctlr]);
+
+ num = btoc(sizeof(struct tmscp)) + 1;
+ io = (struct pte *)&uba->uba_map[NUBMREG-num];
+ for(i = 0; i<num; i++)
+ *(int *)io++ = UBAMR_MRV|(btop(tmscpp)+i);
+ tmscp_ubaddr = (struct tmscp *)(((int)tmscpp & PGOFSET)|((NUBMREG-num)<<9));
+
+ tmscpaddr->tmscpip = 0;
+ while ((tmscpaddr->tmscpsa & TMSCP_STEP1) == 0)
+ if(tmscpaddr->tmscpsa & TMSCP_ERR) return(EFAULT);
+ tmscpaddr->tmscpsa = TMSCP_ERR;
+ while ((tmscpaddr->tmscpsa & TMSCP_STEP2) == 0)
+ if(tmscpaddr->tmscpsa & TMSCP_ERR) return(EFAULT);
+ tmscpaddr->tmscpsa = (short)((int)&tmscp_ubaddr->tmscp_ca.ca_ringbase);
+ while ((tmscpaddr->tmscpsa & TMSCP_STEP3) == 0)
+ if(tmscpaddr->tmscpsa & TMSCP_ERR) return(EFAULT);
+ tmscpaddr->tmscpsa = (short)(((int)&tmscp_ubaddr->tmscp_ca.ca_ringbase) >> 16);
+ while ((tmscpaddr->tmscpsa & TMSCP_STEP4) == 0)
+ if(tmscpaddr->tmscpsa & TMSCP_ERR) return(EFAULT);
+ tmscpaddr->tmscpsa = TMSCP_GO;
+ tmscpp->tmscp_ca.ca_Rspdsc = (long)&tmscp_ubaddr->tmscp_Rsp.mscp_cmdref;
+ tmscpp->tmscp_ca.ca_Cmddsc = (long)&tmscp_ubaddr->tmscp_Cmd.mscp_cmdref;
+ tmscpp->tmscp_Cmd.mscp_header.tmscp_vcid = 1; /* for tape */
+ tmscpp->tmscp_Cmd.mscp_cntflgs = 0;
+ tmscpp->tmscp_Cmd.mscp_version = 0;
+ if (tmscpcmd(M_OP_STCON, tmscpp, tmscpaddr) == 0) {
+ return(EFAULT);
+ }
+ tmscpp->tmscp_Cmd.mscp_unit = ui->ui_slave;
+ if (tmscpcmd(M_OP_ONLIN, tmscpp, tmscpaddr) == 0) {
+ return(EFAULT);
+ }
+
+ num = maxfree;
+ start = 0;
+ while (num > 0)
+ {
+ blk = num > DBSIZE ? DBSIZE : num;
+ io = (struct pte *)uba->uba_map;
+ for (i = 0; i < blk; i++)
+ *(int *)io++ = (btop(start)+i) | UBAMR_MRV;
+ *(int *)io = 0;
+ tmscpp->tmscp_Cmd.mscp_lbn = btop(start);
+ tmscpp->tmscp_Cmd.mscp_unit = ui->ui_slave;
+ tmscpp->tmscp_Cmd.mscp_bytecnt = blk*NBPG;
+# ifdef MVAX
+ if( cpu == MVAX_I )
+ tmscpp->tmscp_Cmd.mscp_buffer = (long) start;
+ else
+# endif MVAX
+ tmscpp->tmscp_Cmd.mscp_buffer = 0;
+ if (tmscpcmd(M_OP_WRITE, tmscpp, tmscpaddr) == 0)
+ return(EIO);
+ start += blk*NBPG;
+ num -= blk;
+ }
+#endif
+ return (0);
+}
+
+
+/*
+ * Perform a standalone tmscp command. This routine is only used by tmscpdump.
+ */
+
+tmscpcmd(op, tmscpp, tmscpaddr)
+ int op;
+ register volatile struct tmscp *tmscpp;
+ volatile struct tmscpdevice *tmscpaddr;
+{
+ volatile int i;
+
+
+ tmscpp->tmscp_Cmd.mscp_opcode = op;
+ tmscpp->tmscp_Rsp.mscp_header.tmscp_msglen = mscp_msglen;
+ tmscpp->tmscp_Cmd.mscp_header.tmscp_msglen = mscp_msglen;
+ tmscpp->tmscp_ca.ca_Rspdsc |= TMSCP_OWN|TMSCP_INT;
+ tmscpp->tmscp_ca.ca_Cmddsc |= TMSCP_OWN|TMSCP_INT;
+ if (tmscpaddr->tmscpsa&TMSCP_ERR)
+ printf("tmscp fatal error (0%o)\n", tmscpaddr->tmscpsa&0xffff);
+ i = tmscpaddr->tmscpip;
+#ifdef lint
+ i = i;
+#endif
+ for (;;)
+ {
+ if (tmscpp->tmscp_ca.ca_cmdint)
+ tmscpp->tmscp_ca.ca_cmdint = 0;
+ if (tmscpp->tmscp_ca.ca_rspint)
+ break;
+ }
+ tmscpp->tmscp_ca.ca_rspint = 0;
+ if (tmscpp->tmscp_Rsp.mscp_opcode != (op|M_OP_END) ||
+ (tmscpp->tmscp_Rsp.mscp_status&M_ST_MASK) != M_ST_SUCC)
+ {
+ printf("error: com %d opc 0x%x stat 0x%x\ndump ", op,
+ tmscpp->tmscp_Rsp.mscp_opcode, tmscpp->tmscp_Rsp.mscp_status);
+ return(0);
+ }
+ return(1);
+}
+
+/*
+ * Catch ioctl commands, and call the "command" routine to do them.
+ */
+
+/* ARGSUSED */
+tmscpioctl(dev, cmd, data, flag)
+ dev_t dev;
+ int cmd;
+ caddr_t data;
+ int flag;
+{
+ register struct buf *bp = &ctmscpbuf[TMSCPCTLR(dev)];
+ register callcount; /* number of times to call cmd routine */
+ register struct uba_device *ui;
+ register struct tms_info *tms;
+ int fcount; /* number of files (or records) to space */
+ int error = 0;
+ register struct mtop *mtop; /* mag tape cmd op to perform */
+ register struct mtget *mtget; /* mag tape struct to get info in */
+
+ /* we depend of the values and order of the TMS ioctl codes here */
+ static tmsops[] =
+ {TMS_WRITM,TMS_FSF,TMS_BSF,TMS_FSR,TMS_BSR,TMS_REW,TMS_OFFL,TMS_SENSE,
+ TMS_CACHE,TMS_NOCACHE};
+
+ switch (cmd) {
+ case MTIOCTOP: /* tape operation */
+ mtop = (struct mtop *)data;
+ switch (mtop->mt_op) {
+
+ case MTWEOF:
+ callcount = mtop->mt_count;
+ fcount = 1;
+ break;
+ case MTFSF: case MTBSF:
+ case MTFSR: case MTBSR:
+ callcount = 1;
+ fcount = mtop->mt_count;
+ break;
+ case MTREW: case MTOFFL: case MTNOP:
+ case MTCACHE: case MTNOCACHE:
+ callcount = 1;
+ fcount = 1; /* wait for this rewind */
+ break;
+ default:
+ return (ENXIO);
+ } /* end switch mtop->mt_op */
+
+ if (callcount <= 0 || fcount <= 0)
+ return (EINVAL);
+ while (--callcount >= 0)
+ {
+ tmscpcommand(dev, tmsops[mtop->mt_op], fcount);
+ if ((mtop->mt_op == MTFSR || mtop->mt_op == MTBSR) &&
+ bp->b_resid)
+ return (EIO);
+ if (bp->b_flags & B_ERROR) /* like hitting BOT */
+ break;
+ }
+ if (bp->b_flags&B_ERROR)
+ if ((error = bp->b_error)==0)
+ return (EIO);
+ return (error);
+
+ case MTIOCGET:
+ /*
+ * Return status info associated with the particular UNIT.
+ */
+ ui = tmsdinfo[TMSUNIT(dev)];
+ tms = &tms_info[ui->ui_unit];
+ mtget = (struct mtget *)data;
+ mtget->mt_type = MT_ISTMSCP;
+ mtget->mt_dsreg = tms->tms_flags << 8;
+ mtget->mt_dsreg |= tms->tms_endcode;
+ mtget->mt_erreg = tms->tms_status;
+ mtget->mt_resid = tms->tms_resid;
+ break;
+
+ default:
+ return (ENXIO);
+ }
+ return (0);
+}
+
+
+/*
+ * Reset (for raw mode use only).
+ */
+
+tmscpreset (uban)
+ int uban;
+{
+ register struct uba_ctlr *um;
+ register struct uba_device *ui;
+ register struct buf *bp, *dp;
+ register int unit;
+ struct buf *nbp;
+ int d;
+
+ for (d = 0; d < NTMSCP; d++)
+ {
+ if ((um = tmscpminfo[d]) == 0 || um->um_ubanum != uban ||
+ um->um_alive == 0)
+ continue;
+ printf(" tmscp%d", d);
+ um->um_tab.b_active = 0;
+ um->um_tab.b_actf = 0;
+ tmscp_softc[d].sc_state = S_IDLE;
+ tmscp_softc[d].sc_mapped = 0;
+ for (unit = 0; unit < NTMS; unit++)
+ {
+ if ((ui = tmsdinfo[unit]) == 0)
+ continue;
+ if (ui->ui_alive == 0 || ui->ui_mi != um)
+ continue;
+ tmsutab[unit].b_active = 0;
+ tmsutab[unit].b_qsize = 0;
+ }
+ for (bp = tmscpwtab[d].b_actf; bp; bp = nbp)
+ {
+ nbp = bp->b_actf;
+ bp->b_ubinfo = 0;
+ /*
+ * Link the buffer onto the drive queue
+ */
+ dp = &tmsutab[TMSUNIT(bp->b_dev)];
+ MSCP_APPEND(bp, dp, b_actf);
+ /*
+ * Link the drive onto the controller queue
+ */
+ if (dp->b_active == 0)
+ {
+ MSCP_APPEND(dp, &um->um_tab, b_hash.le_next);
+ dp->b_active = 1;
+ }
+ }
+ (void)tmscpinit(d);
+ }
+}
+
+
+/*
+ * Process an error log message
+ *
+ * Only minimal decoding is done, only "useful"
+ * information is printed. Eventually should
+ * send message to an error logger.
+ */
+
+tmserror(um, mp)
+ register struct uba_ctlr *um;
+ register struct mslg *mp;
+{
+ register i;
+
+# ifdef DEBUG
+ printd("tmserror:\n");
+# endif
+ if(!(mp->mslg_flags & (M_LF_SUCC | M_LF_CONT)))
+ log(TMS_PRI, "tmscp%d: %s error, ", um->um_ctlr,
+ mp->mslg_flags & ( M_LF_SUCC | M_LF_CONT ) ? "soft" : "hard");
+
+ switch (mp->mslg_format) {
+
+ case M_FM_CNTERR:
+ log(TMS_PRI, "controller error, event 0%o\n", mp->mslg_event);
+ break;
+ case M_FM_BUSADDR:
+ log(TMS_PRI, "host memory access error, event 0%o, addr 0%o\n",
+ mp->mslg_event, mp->mslg_unitid & 0xffffffff);
+ break;
+ case M_FM_TAPETRN:
+ log(TMS_PRI, "tape transfer error, unit %d, grp 0x%x, event 0%o\n",
+ mp->mslg_unit, mp->mslg_group, mp->mslg_event);
+ break;
+ case M_FM_STIERR:
+ log(TMS_PRI, "STI error, unit %d, event 0%o\n",
+ mp->mslg_unit, mp->mslg_event);
+#ifdef notdef
+ /* too painful to do with log() */
+ for(i = 0; i < 62;i++)
+ mprintf("\t0x%x",mp->mslg_stiunsucc[i] & 0xff);
+ mprintf("\n");
+#endif
+ break;
+ case M_FM_STIDEL:
+ log(TMS_PRI, "STI Drive Error Log, unit %d, event 0%o\n",
+ mp->mslg_unit, mp->mslg_event);
+ break;
+ case M_FM_STIFEL:
+ log(TMS_PRI, "STI Formatter Error Log, unit %d, event 0%o\n",
+ mp->mslg_unit, mp->mslg_event);
+ break;
+ default:
+ log(TMS_PRI, "unknown error, unit %d, format 0%o, event 0%o\n",
+ mp->mslg_unit, mp->mslg_format, mp->mslg_event);
+ }
+
+ if (tmscperror)
+ {
+ register long *p = (long *)mp;
+
+ for (i = 0; i < mp->mslg_header.tmscp_msglen; i += sizeof(*p))
+ printf("%x ", *p++);
+ printf("\n");
+ }
+}
+#endif
diff --git a/sys/arch/vax/uba/tmscpreg.h b/sys/arch/vax/uba/tmscpreg.h
new file mode 100644
index 00000000000..de806fcdb53
--- /dev/null
+++ b/sys/arch/vax/uba/tmscpreg.h
@@ -0,0 +1,120 @@
+/* $NetBSD: tmscpreg.h,v 1.1 1995/02/23 17:53:19 ragge Exp $ */
+
+/*-
+ * Copyright (c) 1991 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.
+ *
+ * @(#)tmscpreg.h 7.2 (Berkeley) 5/9/91
+ */
+
+/* @(#)tmscpreg.h 1.1 11/2/84 84/09/25 */
+
+/****************************************************************
+ * *
+ * Licensed from Digital Equipment Corporation *
+ * Copyright (c) *
+ * Digital Equipment Corporation *
+ * Maynard, Massachusetts *
+ * 1985, 1986 *
+ * All rights reserved. *
+ * *
+ * The Information in this software is subject to change *
+ * without notice and should not be construed as a commitment *
+ * by Digital Equipment Corporation. Digital makes no *
+ * representations about the suitability of this software for *
+ * any purpose. It is supplied "As Is" without expressed or *
+ * implied warranty. *
+ * *
+ * If the Regents of the University of California or its *
+ * licensees modify the software in a manner creating *
+ * diriviative copyright rights, appropriate copyright *
+ * legends may be placed on the drivative work in addition *
+ * to that set forth above. *
+ * *
+ ****************************************************************/
+/*
+ * TMSCP registers and structures
+ */
+
+#ifndef _UBA_TMSCPREG_
+#define _UBA_TMSCPREG_
+struct tmscpdevice {
+ short tmscpip; /* initialization and polling */
+ short tmscpsa; /* status and address */
+};
+
+#define TMSCP_ERR 0100000 /* error bit */
+#define TMSCP_STEP4 0040000 /* step 4 has started */
+#define TMSCP_STEP3 0020000 /* step 3 has started */
+#define TMSCP_STEP2 0010000 /* step 2 has started */
+#define TMSCP_STEP1 0004000 /* step 1 has started */
+#define TMSCP_NV 0002000 /* no host settable interrupt vector */
+#define TMSCP_QB 0001000 /* controller supports Q22 bus */
+#define TMSCP_DI 0000400 /* controller implements diagnostics */
+#define TMSCP_OD 0000200 /* port allows odd host addr's in the buffer descriptor */
+#define TMSCP_IE 0000200 /* interrupt enable */
+#define TMSCP_MP 0000100 /* port supports address mapping */
+#define TMSCP_LF 0000002 /* host requests last fail response packet */
+#define TMSCP_PI 0000001 /* host requests adapter purge interrupts */
+#define TMSCP_GO 0000001 /* start operation, after init */
+
+
+/*
+ * TMSCP Communications Area
+ */
+
+struct tmscpca {
+ short ca_xxx1; /* unused */
+ char ca_xxx2; /* unused */
+ char ca_bdp; /* BDP to purge */
+ short ca_cmdint; /* command queue transition interrupt flag */
+ short ca_rspint; /* response queue transition interrupt flag */
+ long ca_rspdsc[NRSP];/* response descriptors */
+ long ca_cmddsc[NCMD];/* command descriptors */
+};
+
+#define ca_ringbase ca_rspdsc[0]
+
+#define TMSCP_OWN 0x80000000 /* port owns this descriptor (else host
+ owns it) */
+#define TMSCP_INT 0x40000000 /* allow interrupt on ring transition */
+
+#define TMSCP_MAP 0x80000000 /* modifier for mapped buffer descriptors */
+
+/*
+ * TMSCP packet info (same as MSCP)
+ */
+struct mscp_header {
+ short tmscp_msglen; /* length of MSCP packet */
+ char tmscp_credits; /* low 4 bits: credits, high 4 bits: msgtype */
+ char tmscp_vcid; /* virtual circuit id (connection id) */
+};
+#endif
diff --git a/sys/arch/vax/uba/uba.c b/sys/arch/vax/uba/uba.c
new file mode 100644
index 00000000000..6f3d9c9eb5e
--- /dev/null
+++ b/sys/arch/vax/uba/uba.c
@@ -0,0 +1,1294 @@
+/* $NetBSD: uba.c,v 1.8 1995/06/16 15:26:11 ragge Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986 The Regents of the University of California.
+ * Copyright (c) 1994 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 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.
+ *
+ * @(#)uba.c 7.10 (Berkeley) 12/16/90
+ * @(#)autoconf.c 7.20 (Berkeley) 5/9/91
+ */
+
+ /* All bugs are subject to removal without further notice */
+
+#include "sys/param.h"
+#include "sys/types.h"
+#include "sys/time.h"
+#include "sys/systm.h"
+#include "sys/map.h"
+#include "sys/buf.h"
+#include "sys/proc.h"
+#include "sys/user.h"
+#include "sys/conf.h"
+#include "sys/dkstat.h"
+#include "sys/kernel.h"
+#include "sys/malloc.h"
+#include "sys/device.h"
+
+#include "machine/pte.h"
+#include "machine/cpu.h"
+#include "machine/mtpr.h"
+#include "machine/nexus.h"
+#include "machine/sid.h"
+#if VAX630
+#include "machine/uvaxII.h"
+#endif
+#include "uba.h"
+#include "ubareg.h"
+#include "ubavar.h"
+
+int (*vekmatris[NUBA][128])();
+int interinfo[NUBA][128];
+int dkn;
+extern int cold;
+struct uba_hd uba_hd[NUBA];
+
+/* F|r att f} genom kompilatorn :( Nollpekare f|r interrupt... */
+int cvec=0;
+volatile int rbr,rcvec;
+#if VAX630 || VAX410
+extern struct uvaxIIcpu *uvaxIIcpu_ptr;
+#endif
+#if VAX630
+extern struct ka630clock *ka630clk_ptr;
+#endif
+
+/*
+ * Mark addresses starting at "addr" and continuing
+ * "size" bytes as allocated in the map "ualloc".
+ * Warn if the new allocation overlaps a previous allocation.
+ */
+static
+csralloc(ualloc, addr, size)
+ caddr_t ualloc;
+ u_short addr;
+ register int size;
+{
+ register caddr_t p;
+ int warned = 0;
+
+ p = &ualloc[ubdevreg(addr+size)];
+ while (--size >= 0) {
+ if (*--p && !warned) {
+ printf(
+ "WARNING: device registers overlap those for a previous device!\n");
+ warned = 1;
+ }
+ *p = 1;
+ }
+}
+
+/*
+ * Make an IO register area accessible at physical address physa
+ * by mapping kernel ptes starting at pte.
+ */
+ioaccess(physa, pte, size)
+ u_int physa;
+ u_int *pte;
+ u_int size;
+{
+ u_int i = (size>>PG_SHIFT);
+ u_int v = (physa>>PG_SHIFT);
+
+ do {
+ *pte = PG_V|PG_KW|v;
+ pte++;
+ v++;
+ } while (--i > 0);
+ mtpr(0, PR_TBIA);
+}
+
+/*
+ * General uba interrupt handler.
+ */
+ubainterrupt(level, uba,vektor){
+/*printf("ubainterrupt: level %x, uba %x, vektor %x\n",level, uba,vektor); */
+ (*vekmatris[uba][vektor])(vektor,level,uba,interinfo[uba][vektor]);
+}
+
+/*
+ * Stray interrupt vector handler, used when nowhere else to
+ * go to.
+ */
+ubastray(vektor, level,uba){
+ if(cold){
+ rbr=level;
+ rcvec=vektor;
+ } else {
+ printf("uba%d: unexpected interrupt at vector %d on level %d",
+ uba, vektor, level);
+ }
+}
+
+/*
+ * Find devices on a UNIBUS.
+ * Uses per-driver routine to set <br,cvec> into <r11,r10>,
+ * and then fills in the tables, with help from a per-driver
+ * slave initialization routine.
+ *
+ * Changed this ugly written code assuming special registers
+ * from the C compiler :( 940516/ragge
+ */
+
+unifind(uhp0, pumem)
+ struct uba_hd *uhp0;
+ caddr_t pumem;
+{
+ register struct uba_device *ui;
+ register struct uba_ctlr *um;
+ register struct uba_hd *uhp = uhp0;
+ u_short *reg, *ap, addr;
+ struct uba_driver *udp;
+ int i, (*ivec)();
+ caddr_t ualloc;
+ volatile extern int br, cvec;
+ volatile extern int rbr, rcvec;
+#if DW780 || DWBUA
+ struct uba_regs *vubp = uhp->uh_uba;
+#endif
+
+ /*
+ * Initialize the UNIBUS, by freeing the map
+ * registers and the buffered data path registers
+ */
+ uhp->uh_map = (struct map *)
+ malloc((u_long)(UAMSIZ * sizeof (struct map)), M_DEVBUF,
+ M_NOWAIT);
+ if (uhp->uh_map == 0)
+ panic("no mem for unibus map");
+ bzero((caddr_t)uhp->uh_map, (unsigned)(UAMSIZ * sizeof (struct map)));
+ ubainitmaps(uhp);
+
+ /*
+ * Initialize space for the UNIBUS interrupt vectors.
+ * On the 8600, can't use first slot in UNIvec
+ * (the vectors for the second SBI overlap it);
+ * move each set of vectors forward.
+ */
+#if VAX8600
+ if (cpu == VAX_8600)
+ uhp->uh_vec = UNIvec[numuba + 1];
+ else
+#endif
+ uhp->Nuh_vec = vekmatris[numuba];
+ for (i = 0; i < 128; i++)
+ uhp->Nuh_vec[i] = ubastray;
+
+ /*
+ * Set last free interrupt vector for devices with
+ * programmable interrupt vectors. Use is to decrement
+ * this number and use result as interrupt vector.
+ */
+ uhp->uh_lastiv = 0x200;
+
+#ifdef DWBUA
+ if (uhp->uh_type == DWBUA)
+ BUA(vubp)->bua_offset = (int)uhp->uh_vec - (int)&scb[0];
+#endif
+
+#ifdef DW780
+ if (uhp->uh_type == DW780) {
+ vubp->uba_sr = vubp->uba_sr;
+ vubp->uba_cr = UBACR_IFS|UBACR_BRIE;
+ }
+#endif
+ /*
+ * First configure devices that have unibus memory,
+ * allowing them to allocate the correct map registers.
+ */
+ ubameminit(numuba);
+ /*
+ * Grab some memory to record the umem address space we allocate,
+ * so we can be sure not to place two devices at the same address.
+ *
+ * We could use just 1/8 of this (we only want a 1 bit flag) but
+ * we are going to give it back anyway, and that would make the
+ * code here bigger (which we can't give back), so ...
+ *
+ * One day, someone will make a unibus with something other than
+ * an 8K i/o address space, & screw this totally.
+ */
+ ualloc = (caddr_t)malloc((u_long)(8 * 1024), M_TEMP, M_NOWAIT);
+ if (ualloc == (caddr_t)0)
+ panic("no mem for unifind");
+ bzero(ualloc, 8*1024);
+
+ /*
+ * Map the first page of UNIBUS i/o
+ * space to the first page of memory
+ * for devices which will need to dma
+ * output to produce an interrupt.
+ */
+ *(int *)(&uhp->uh_mr[0]) = UBAMR_MRV;
+
+#define ubaddr(uhp, off) (u_short *)((int)(uhp)->uh_iopage + ubdevreg(off))
+ /*
+ * Check each unibus mass storage controller.
+ * For each one which is potentially on this uba,
+ * see if it is really there, and if it is record it and
+ * then go looking for slaves.
+ */
+ for (um = ubminit; udp = um->um_driver; um++) {
+ if (um->um_ubanum != numuba && um->um_ubanum != '?' ||
+ um->um_alive)
+ continue;
+ addr = (u_short)(u_long)um->um_addr;
+ /*
+ * use the particular address specified first,
+ * or if it is given as "0", of there is no device
+ * at that address, try all the standard addresses
+ * in the driver til we find it
+ */
+ for (ap = udp->ud_addr; addr || (addr = *ap++); addr = 0) {
+
+ if (ualloc[ubdevreg(addr)])
+ continue;
+ reg = ubaddr(uhp, addr);
+
+ if (badaddr((caddr_t)reg, 2))
+ continue;
+
+#ifdef DW780
+ if (uhp->uh_type == DW780 && vubp->uba_sr) {
+ vubp->uba_sr = vubp->uba_sr;
+ continue;
+ }
+#endif
+ cvec = 0x200;
+ rcvec = 0x200;
+ i = (*udp->ud_probe)(reg, um->um_ctlr, um);
+#ifdef DW780
+ if (uhp->uh_type == DW780 && vubp->uba_sr) {
+ vubp->uba_sr = vubp->uba_sr;
+ continue;
+ }
+#endif
+ if (i == 0)
+ continue;
+ printf("%s%d at uba%d csr %o ",
+ udp->ud_mname, um->um_ctlr, numuba, addr);
+ if (rcvec == 0) {
+ printf("zero vector\n");
+ continue;
+ }
+ if (rcvec == 0x200) {
+ printf("didn't interrupt\n");
+ continue;
+ }
+ interinfo[numuba][rcvec]=um->um_ctlr;
+ printf("vec %o, ipl %x\n", rcvec, rbr);
+ csralloc(ualloc, addr, i);
+ um->um_alive = 1;
+ um->um_ubanum = numuba;
+ um->um_hd = uhp;
+ um->um_addr = (caddr_t)reg;
+ udp->ud_minfo[um->um_ctlr] = um;
+ uhp->Nuh_vec[rcvec] = um->um_intr;
+ for (ui = ubdinit; ui->ui_driver; ui++) {
+ int t;
+
+ if (ui->ui_driver != udp || ui->ui_alive ||
+ ui->ui_ctlr != um->um_ctlr && ui->ui_ctlr != '?' ||
+ ui->ui_ubanum != numuba && ui->ui_ubanum != '?')
+ continue;
+ t = ui->ui_ctlr;
+ ui->ui_ctlr = um->um_ctlr;
+ if ((*udp->ud_slave)(ui, reg) == 0)
+ ui->ui_ctlr = t;
+ else {
+ ui->ui_alive = 1;
+ ui->ui_ubanum = numuba;
+ ui->ui_hd = uhp;
+ ui->ui_addr = (caddr_t)reg;
+ ui->ui_physaddr = pumem + ubdevreg(addr);
+ if (ui->ui_dk && dkn < DK_NDRIVE)
+ ui->ui_dk = dkn++;
+ else
+ ui->ui_dk = -1;
+ ui->ui_mi = um;
+ /* ui_type comes from driver */
+ udp->ud_dinfo[ui->ui_unit] = ui;
+ printf("%s%d at %s%d slave %d",
+ udp->ud_dname, ui->ui_unit,
+ udp->ud_mname, um->um_ctlr, ui->ui_slave);
+ (*udp->ud_attach)(ui);
+ printf("\n");
+ }
+ }
+ break;
+ }
+ }
+ /*
+ * Now look for non-mass storage peripherals.
+ */
+ for (ui = ubdinit; udp = ui->ui_driver; ui++) {
+ if (ui->ui_ubanum != numuba && ui->ui_ubanum != '?' ||
+ ui->ui_alive || ui->ui_slave != -1)
+ continue;
+ addr = (u_short)(u_long)ui->ui_addr;
+
+ for (ap = udp->ud_addr; addr || (addr = *ap++); addr = 0) {
+
+ if (ualloc[ubdevreg(addr)])
+ continue;
+ reg = ubaddr(uhp, addr);
+ if (badaddr((caddr_t)reg, 2))
+ continue;
+#ifdef DW780
+ if (uhp->uh_type == DW780 && vubp->uba_sr) {
+ vubp->uba_sr = vubp->uba_sr;
+ continue;
+ }
+#endif
+ rcvec = 0x200;
+ cvec = 0x200;
+ i = (*udp->ud_probe)(reg, ui);
+#ifdef DW780
+ if (uhp->uh_type == DW780 && vubp->uba_sr) {
+ vubp->uba_sr = vubp->uba_sr;
+ continue;
+ }
+#endif
+ if (i == 0)
+ continue;
+ printf("%s%d at uba%d csr %o ",
+ ui->ui_driver->ud_dname, ui->ui_unit, numuba, addr);
+ if (rcvec == 0) {
+ printf("zero vector\n");
+ continue;
+ }
+ if (rcvec == 0x200) {
+ printf("didn't interrupt\n");
+ continue;
+ }
+ interinfo[numuba][rcvec]=ui->ui_unit;
+ printf("vec %o, ipl %x\n", rcvec, rbr);
+ csralloc(ualloc, addr, i);
+ ui->ui_hd = uhp;
+ uhp->Nuh_vec[rcvec] = ui->ui_intr;
+ ui->ui_alive = 1;
+ ui->ui_ubanum = numuba;
+ ui->ui_addr = (caddr_t)reg;
+ ui->ui_physaddr = pumem + ubdevreg(addr);
+ ui->ui_dk = -1;
+ /* ui_type comes from driver */
+ udp->ud_dinfo[ui->ui_unit] = ui;
+ (*udp->ud_attach)(ui);
+ break;
+ }
+ }
+
+#ifdef DW780
+ if (uhp->uh_type == DW780)
+ uhp->uh_uba->uba_cr = UBACR_IFS | UBACR_BRIE |
+ UBACR_USEFIE | UBACR_SUEFIE |
+ (uhp->uh_uba->uba_cr & 0x7c000000);
+#endif
+ numuba++;
+
+#ifdef AUTO_DEBUG
+ printf("Unibus allocation map");
+ for (i = 0; i < 8*1024; ) {
+ register n, m;
+
+ if ((i % 128) == 0) {
+ printf("\n%6o:", i);
+ for (n = 0; n < 128; n++)
+ if (ualloc[i+n])
+ break;
+ if (n == 128) {
+ i += 128;
+ continue;
+ }
+ }
+
+ for (n = m = 0; n < 16; n++) {
+ m <<= 1;
+ m |= ualloc[i++];
+ }
+
+ printf(" %4x", m);
+ }
+ printf("\n");
+#endif
+ free(ualloc, M_TEMP);
+}
+
+
+#ifdef DW780
+char ubasr_bits[] = UBASR_BITS;
+#endif
+
+#define spluba splbio /* IPL 17 */
+
+/*
+ * Do transfer on device argument. The controller
+ * and uba involved are implied by the device.
+ * We queue for resource wait in the uba code if necessary.
+ * We return 1 if the transfer was started, 0 if it was not.
+ *
+ * The onq argument must be zero iff the device is not on the
+ * queue for this UBA. If onq is set, the device must be at the
+ * head of the queue. In any case, if the transfer is started,
+ * the device will be off the queue, and if not, it will be on.
+ *
+ * Drivers that allocate one BDP and hold it for some time should
+ * set ud_keepbdp. In this case um_bdp tells which BDP is allocated
+ * to the controller, unless it is zero, indicating that the controller
+ * does not now have a BDP.
+ */
+ubaqueue(ui, onq)
+ register struct uba_device *ui;
+ int onq;
+{
+ register struct uba_ctlr *um = ui->ui_mi;
+ register struct uba_hd *uh;
+ register struct uba_driver *ud;
+ register int s, unit;
+
+ uh = &uba_hd[um->um_ubanum];
+ ud = um->um_driver;
+ s = spluba();
+ /*
+ * Honor exclusive BDP use requests.
+ */
+ if (ud->ud_xclu && uh->uh_users > 0 || uh->uh_xclu)
+ goto rwait;
+ if (ud->ud_keepbdp) {
+ /*
+ * First get just a BDP (though in fact it comes with
+ * one map register too).
+ */
+ if (um->um_bdp == 0) {
+ um->um_bdp = uballoc(um->um_ubanum,
+ (caddr_t)0, 0, UBA_NEEDBDP|UBA_CANTWAIT);
+ if (um->um_bdp == 0)
+ goto rwait;
+ }
+ /* now share it with this transfer */
+ um->um_ubinfo = ubasetup(um->um_ubanum,
+ um->um_tab.b_actf->b_actf,
+ um->um_bdp|UBA_HAVEBDP|UBA_CANTWAIT);
+ } else
+ um->um_ubinfo = ubasetup(um->um_ubanum,
+ um->um_tab.b_actf->b_actf, UBA_NEEDBDP|UBA_CANTWAIT);
+ if (um->um_ubinfo == 0)
+ goto rwait;
+ uh->uh_users++;
+ if (ud->ud_xclu)
+ uh->uh_xclu = 1;
+ splx(s);
+ if (ui->ui_dk >= 0) {
+ unit = ui->ui_dk;
+ dk_busy |= 1<<unit;
+ dk_xfer[unit]++;
+ dk_wds[unit] += um->um_tab.b_actf->b_actf->b_bcount>>6;
+ }
+ if (onq)
+ uh->uh_actf = ui->ui_forw;
+ (*ud->ud_dgo)(um);
+ return (1);
+rwait:
+ if (!onq) {
+ ui->ui_forw = NULL;
+ if (uh->uh_actf == NULL)
+ uh->uh_actf = ui;
+ else
+ uh->uh_actl->ui_forw = ui;
+ uh->uh_actl = ui;
+ }
+ splx(s);
+ return (0);
+}
+
+ubadone(um)
+ register struct uba_ctlr *um;
+{
+ register struct uba_hd *uh = &uba_hd[um->um_ubanum];
+
+ if (um->um_driver->ud_xclu)
+ uh->uh_xclu = 0;
+ uh->uh_users--;
+ if (um->um_driver->ud_keepbdp)
+ um->um_ubinfo &= ~BDPMASK; /* keep BDP for misers */
+ ubarelse(um->um_ubanum, &um->um_ubinfo);
+}
+
+/*
+ * Allocate and setup UBA map registers, and bdp's
+ * Flags says whether bdp is needed, whether the caller can't
+ * wait (e.g. if the caller is at interrupt level).
+ * Return value encodes map register plus page offset,
+ * bdp number and number of map registers.
+ */
+ubasetup(int uban,struct buf *bp,int flags) {
+ struct uba_hd *uh = &uba_hd[uban];
+ struct pte *pte, *io;
+ int npf;
+ int pfnum, temp;
+ int reg, bdp;
+ unsigned v;
+ struct proc *rp;
+ int a, o, ubinfo;
+
+#ifdef DW730
+ if (uh->uh_type == DW730)
+ flags &= ~UBA_NEEDBDP;
+#endif
+#ifdef QBA
+ if (uh->uh_type == QBA)
+ flags &= ~UBA_NEEDBDP;
+#endif
+ o = (int)bp->b_un.b_addr & PGOFSET;
+ npf = btoc(bp->b_bcount + o) + 1;
+ if (npf > UBA_MAXNMR)
+ panic("uba xfer too big");
+ a = spluba();
+ while ((reg = rmalloc(uh->uh_map, (long)npf)) == 0) {
+ if (flags & UBA_CANTWAIT) {
+ splx(a);
+ return (0);
+ }
+ uh->uh_mrwant++;
+ sleep((caddr_t)&uh->uh_mrwant, PSWP);
+ }
+ if ((flags & UBA_NEED16) && reg + npf > 128) {
+ /*
+ * Could hang around and try again (if we can ever succeed).
+ * Won't help any current device...
+ */
+ rmfree(uh->uh_map, (long)npf, (long)reg);
+ splx(a);
+ return (0);
+ }
+ bdp = 0;
+ if (flags & UBA_NEEDBDP) {
+ while ((bdp = ffs((long)uh->uh_bdpfree)) == 0) {
+ if (flags & UBA_CANTWAIT) {
+ rmfree(uh->uh_map, (long)npf, (long)reg);
+ splx(a);
+ return (0);
+ }
+ uh->uh_bdpwant++;
+ sleep((caddr_t)&uh->uh_bdpwant, PSWP);
+ }
+ uh->uh_bdpfree &= ~(1 << (bdp-1));
+ } else if (flags & UBA_HAVEBDP)
+ bdp = (flags >> 28) & 0xf;
+ splx(a);
+ reg--;
+ ubinfo = UBAI_INFO(o, reg, npf, bdp);
+ temp = (bdp << 21) | UBAMR_MRV;
+ if (bdp && (o & 01))
+ temp |= UBAMR_BO;
+ if ((bp->b_flags & B_PHYS) == 0)
+ pte = (struct pte *)kvtopte(bp->b_un.b_addr);
+ else if (bp->b_flags & B_PAGET) {
+ panic("ubasetup: B_PAGET");
+ } else {
+ if( bp->b_flags&B_DIRTY){
+ rp=&pageproc[2];
+ panic("ubasetup: B_DIRTY");
+ } else {
+ rp =bp->b_proc;
+ }
+ v = vax_btop((u_int)bp->b_un.b_addr&0x3fffffff);
+ if (bp->b_flags & B_UAREA){
+ panic("ubasetup: B_UAREA");
+ } else {
+/*
+ * It may be better to use pmap_extract() here somewhere,
+ * but so far we do it "the hard way" :)
+ */
+ u_int *hej;
+
+ if(((u_int)bp->b_un.b_addr<0x40000000)||
+ ((u_int)bp->b_un.b_addr>0x7fffffff)){
+ hej=rp->p_vmspace->vm_pmap.pm_pcb->P0BR;
+ } else {
+ hej=rp->p_vmspace->vm_pmap.pm_pcb->P1BR;
+ }
+ pte=(struct pte*)&hej[v];
+ }
+ }
+ io = &uh->uh_mr[reg];
+ while (--npf > 0) {
+ pfnum = pte->pg_pfn;
+ if (pfnum == 0)
+ panic("uba zero uentry");
+ pte++;
+ *(int *)io++ = pfnum | temp;
+ }
+ *(int *)io = 0;
+ return (ubinfo);
+}
+
+/*
+ * Non buffer setup interface... set up a buffer and call ubasetup.
+ */
+uballoc(int uban,caddr_t addr,int bcnt,int flags) {
+ struct buf ubabuf;
+
+ ubabuf.b_un.b_addr = addr;
+ ubabuf.b_flags = B_BUSY;
+ ubabuf.b_bcount = bcnt;
+ /* that's all the fields ubasetup() needs */
+ return (ubasetup(uban, &ubabuf, flags));
+}
+
+/*
+ * Release resources on uba uban, and then unblock resource waiters.
+ * The map register parameter is by value since we need to block
+ * against uba resets on 11/780's.
+ */
+ubarelse(uban, amr)
+ int *amr;
+{
+ register struct uba_hd *uh = &uba_hd[uban];
+ register int bdp, reg, npf, s;
+ int mr;
+
+ /*
+ * Carefully see if we should release the space, since
+ * it may be released asynchronously at uba reset time.
+ */
+ s = spluba();
+ mr = *amr;
+ if (mr == 0) {
+ /*
+ * A ubareset() occurred before we got around
+ * to releasing the space... no need to bother.
+ */
+ splx(s);
+ return;
+ }
+ *amr = 0;
+ bdp = UBAI_BDP(mr);
+ if (bdp) {
+ switch (uh->uh_type) {
+#ifdef DWBUA
+ case DWBUA:
+ BUA(uh->uh_uba)->bua_dpr[bdp] |= BUADPR_PURGE;
+ break;
+#endif
+#ifdef DW780
+sdjhfgsadjkfhgasj
+ case DW780:
+ uh->uh_uba->uba_dpr[bdp] |= UBADPR_BNE;
+ break;
+#endif
+#ifdef DW750
+ case DW750:
+ uh->uh_uba->uba_dpr[bdp] |=
+ UBADPR_PURGE|UBADPR_NXM|UBADPR_UCE;
+ break;
+#endif
+ default:
+ break;
+ }
+ uh->uh_bdpfree |= 1 << (bdp-1); /* atomic */
+ if (uh->uh_bdpwant) {
+ uh->uh_bdpwant = 0;
+ wakeup((caddr_t)&uh->uh_bdpwant);
+ }
+ }
+ /*
+ * Put back the registers in the resource map.
+ * The map code must not be reentered,
+ * nor can the registers be freed twice.
+ * Unblock interrupts once this is done.
+ */
+ npf = UBAI_NMR(mr);
+ reg = UBAI_MR(mr) + 1;
+ rmfree(uh->uh_map, (long)npf, (long)reg);
+ splx(s);
+
+ /*
+ * Wakeup sleepers for map registers,
+ * and also, if there are processes blocked in dgo(),
+ * give them a chance at the UNIBUS.
+ */
+ if (uh->uh_mrwant) {
+ uh->uh_mrwant = 0;
+ wakeup((caddr_t)&uh->uh_mrwant);
+ }
+ while (uh->uh_actf && ubaqueue(uh->uh_actf, 1))
+ ;
+}
+
+ubapurge(um)
+ register struct uba_ctlr *um;
+{
+ register struct uba_hd *uh = um->um_hd;
+ register int bdp = UBAI_BDP(um->um_ubinfo);
+
+ switch (uh->uh_type) {
+#ifdef DWBUA
+ case DWBUA:
+ BUA(uh->uh_uba)->bua_dpr[bdp] |= BUADPR_PURGE;
+ break;
+#endif
+#ifdef DW780
+ case DW780:
+ uh->uh_uba->uba_dpr[bdp] |= UBADPR_BNE;
+ break;
+#endif
+#ifdef DW750
+ case DW750:
+ uh->uh_uba->uba_dpr[bdp] |= UBADPR_PURGE|UBADPR_NXM|UBADPR_UCE;
+ break;
+#endif
+ default:
+ break;
+ }
+}
+
+ubainitmaps(uhp)
+ register struct uba_hd *uhp;
+{
+
+ if (uhp->uh_memsize > UBA_MAXMR)
+ uhp->uh_memsize = UBA_MAXMR;
+ rminit(uhp->uh_map, (long)uhp->uh_memsize, (long)1, "uba", UAMSIZ);
+ switch (uhp->uh_type) {
+#ifdef DWBUA
+ case DWBUA:
+ uhp->uh_bdpfree = (1<<NBDPBUA) - 1;
+ break;
+#endif
+#ifdef DW780
+ case DW780:
+ uhp->uh_bdpfree = (1<<NBDP780) - 1;
+ break;
+#endif
+#ifdef DW750
+ case DW750:
+ uhp->uh_bdpfree = (1<<NBDP750) - 1;
+ break;
+#endif
+ default:
+ break;
+ }
+}
+
+/*
+ * Generate a reset on uba number uban. Then
+ * call each device in the character device table,
+ * giving it a chance to clean up so as to be able to continue.
+ */
+ubareset(uban)
+ int uban;
+{
+ register struct cdevsw *cdp;
+ register struct uba_hd *uh = &uba_hd[uban];
+ int s;
+
+ s = spluba();
+ uh->uh_users = 0;
+ uh->uh_zvcnt = 0;
+ uh->uh_xclu = 0;
+ uh->uh_actf = uh->uh_actl = 0;
+ uh->uh_bdpwant = 0;
+ uh->uh_mrwant = 0;
+ ubainitmaps(uh);
+ wakeup((caddr_t)&uh->uh_bdpwant);
+ wakeup((caddr_t)&uh->uh_mrwant);
+ printf("uba%d: reset", uban);
+ ubainit(uh->uh_uba);
+ ubameminit(uban);
+/* XXX Intressant, vi m}ste l|sa det h{r med ubareset() p} n}t smart
+ * s{tt. En l{nkad lista som s{tts upp vid autoconfiggen? Kanske.
+ * N{r anv{nds dom? Jag vet faktiskt inte; det verkar vara en
+ * ren sm|rja den gamla koden. F}r peturba lite mer docs...
+ * 950428/Ragge
+ */
+/* for (cdp = cdevsw; cdp < cdevsw + nchrdev; cdp++)
+ (*cdp->d_reset)(uban);
+ ifubareset(uban);
+ */
+ printf("\n");
+ splx(s);
+}
+
+/*
+ * Init a uba. This is called with a pointer
+ * rather than a virtual address since it is called
+ * by code which runs with memory mapping disabled.
+ * In these cases we really don't need the interrupts
+ * enabled, but since we run with ipl high, we don't care
+ * if they are, they will never happen anyways.
+ * SHOULD GET POINTER TO UBA_HD INSTEAD OF UBA.
+ */
+ubainit(uba)
+ register struct uba_regs *uba;
+{
+ register struct uba_hd *uhp;
+#ifdef QBA
+ int isphys = 0;
+#endif
+
+ for (uhp = uba_hd; uhp < uba_hd + numuba; uhp++) {
+ if (uhp->uh_uba == uba)
+ break;
+ if (uhp->uh_physuba == uba) {
+#ifdef QBA
+ isphys++;
+#endif
+ break;
+ }
+ }
+ if (uhp >= uba_hd + numuba) {
+ printf("init unknown uba\n");
+ return;
+ }
+
+ switch (uhp->uh_type) {
+#ifdef DWBUA
+ case DWBUA:
+ BUA(uba)->bua_csr |= BUACSR_UPI;
+ /* give devices time to recover from power fail */
+ waitabit(500);
+ break;
+#endif
+#ifdef DW780
+ case DW780:
+ uba->uba_cr = UBACR_ADINIT;
+ uba->uba_cr = UBACR_IFS|UBACR_BRIE|UBACR_USEFIE|UBACR_SUEFIE;
+ while ((uba->uba_cnfgr & UBACNFGR_UBIC) == 0)
+ ;
+ break;
+#endif
+#ifdef DW750
+ case DW750:
+#endif
+#ifdef DW730
+ case DW730:
+#endif
+#ifdef QBA
+ case QBA:
+#endif
+#if DW750 || DW730 || QBA
+ mtpr(0, PR_IUR);
+ /* give devices time to recover from power fail */
+#if 0
+/* THIS IS PROBABLY UNNECESSARY */
+ waitabit(50);
+/* END PROBABLY UNNECESSARY */
+#endif
+#ifdef QBA
+ /*
+ * Re-enable local memory access
+ * from the Q-bus.
+ */
+ if (uhp->uh_type == QBA) {
+ if (isphys)
+ *((char *)QIOPAGE630 + QIPCR) = Q_LMEAE;
+ else
+ *(uhp->uh_iopage + QIPCR) = Q_LMEAE;
+ }
+#endif QBA
+ break;
+#endif DW750 || DW730 || QBA
+ }
+}
+
+#ifdef QBA
+/*
+ * Determine the interrupt priority of a Q-bus
+ * peripheral. The device probe routine must spl6(),
+ * attempt to make the device request an interrupt,
+ * delaying as necessary, then call this routine
+ * before resetting the device.
+ */
+qbgetpri()
+{
+ int pri;
+ extern int cvec;
+
+ for (pri = 0x17; pri > 0x14; ) {
+ if (cvec && cvec != 0x200) /* interrupted at pri */
+ break;
+ pri--;
+ splx(pri - 1);
+ }
+ (void) spl0();
+ return (pri);
+}
+#endif
+
+#ifdef DW780
+int ubawedgecnt = 10;
+int ubacrazy = 500;
+int zvcnt_max = 5000; /* in 8 sec */
+/*
+ * This routine is called by the locore code to process a UBA
+ * error on an 11/780 or 8600. The arguments are passed
+ * on the stack, and value-result (through some trickery).
+ * In particular, the uvec argument is used for further
+ * uba processing so the result aspect of it is very important.
+ * It must not be declared register.
+ */
+/*ARGSUSED*/
+ubaerror(uban, uh, ipl, uvec, uba)
+ register int uban;
+ register struct uba_hd *uh;
+ int ipl, uvec;
+ register struct uba_regs *uba;
+{
+ register sr, s;
+
+ if (uvec == 0) {
+ /*
+ * Declare dt as unsigned so that negative values
+ * are handled as >8 below, in case time was set back.
+ */
+ u_long dt = time.tv_sec - uh->uh_zvtime;
+
+ uh->uh_zvtotal++;
+ if (dt > 8) {
+ uh->uh_zvtime = time.tv_sec;
+ uh->uh_zvcnt = 0;
+ }
+ if (++uh->uh_zvcnt > zvcnt_max) {
+ printf("uba%d: too many zero vectors (%d in <%d sec)\n",
+ uban, uh->uh_zvcnt, dt + 1);
+ printf("\tIPL 0x%x\n\tcnfgr: %b Adapter Code: 0x%x\n",
+ ipl, uba->uba_cnfgr&(~0xff), UBACNFGR_BITS,
+ uba->uba_cnfgr&0xff);
+ printf("\tsr: %b\n\tdcr: %x (MIC %sOK)\n",
+ uba->uba_sr, ubasr_bits, uba->uba_dcr,
+ (uba->uba_dcr&0x8000000)?"":"NOT ");
+ ubareset(uban);
+ }
+ return;
+ }
+ if (uba->uba_cnfgr & NEX_CFGFLT) {
+ printf("uba%d: sbi fault sr=%b cnfgr=%b\n",
+ uban, uba->uba_sr, ubasr_bits,
+ uba->uba_cnfgr, NEXFLT_BITS);
+ ubareset(uban);
+ uvec = 0;
+ return;
+ }
+ sr = uba->uba_sr;
+ s = spluba();
+ printf("uba%d: uba error sr=%b fmer=%x fubar=%o\n",
+ uban, uba->uba_sr, ubasr_bits, uba->uba_fmer, 4*uba->uba_fubar);
+ splx(s);
+ uba->uba_sr = sr;
+ uvec &= UBABRRVR_DIV;
+ if (++uh->uh_errcnt % ubawedgecnt == 0) {
+ if (uh->uh_errcnt > ubacrazy)
+ panic("uba crazy");
+ printf("ERROR LIMIT ");
+ ubareset(uban);
+ uvec = 0;
+ return;
+ }
+ return;
+}
+#endif
+
+/*
+ * Look for devices with unibus memory, allow them to configure, then disable
+ * map registers as necessary. Called during autoconfiguration and ubareset.
+ * The device ubamem routine returns 0 on success, 1 on success if it is fully
+ * configured (has no csr or interrupt, so doesn't need to be probed),
+ * and -1 on failure.
+ */
+ubameminit(uban)
+{
+ register struct uba_device *ui;
+ register struct uba_hd *uh = &uba_hd[uban];
+ caddr_t umembase = Tumem(uban) + 0x3e000, addr;
+#define ubaoff(off) ((int)(off) & 0x1fff)
+
+ uh->uh_lastmem = 0;
+ for (ui = ubdinit; ui->ui_driver; ui++) {
+ if (ui->ui_ubanum != uban && ui->ui_ubanum != '?')
+ continue;
+ if (ui->ui_driver->ud_ubamem) {
+ /*
+ * During autoconfiguration, need to fudge ui_addr.
+ */
+ addr = ui->ui_addr;
+ ui->ui_addr = umembase + ubaoff(addr);
+ switch ((*ui->ui_driver->ud_ubamem)(ui, uban)) {
+ case 1:
+ ui->ui_alive = 1;
+ /* FALLTHROUGH */
+ case 0:
+ ui->ui_ubanum = uban;
+ break;
+ }
+ ui->ui_addr = addr;
+ }
+ }
+#ifdef DW780
+jdhfgsjdkfhgsdjkfghak
+ /*
+ * On a DW780, throw away any map registers disabled by rounding
+ * the map disable in the configuration register
+ * up to the next 8K boundary, or below the last unibus memory.
+ */
+ if (uh->uh_type == DW780) {
+ register i;
+
+ i = vax_btop(((uh->uh_lastmem + 8191) / 8192) * 8192);
+ while (i)
+ (void) rmget(uh->uh_map, 1, i--);
+ }
+#endif
+}
+
+rmget(){
+ showstate(curproc);
+ panic("rmget() not implemented. (in uba.c)");
+}
+
+/*
+ * Allocate UNIBUS memory. Allocates and initializes
+ * sufficient mapping registers for access. On a 780,
+ * the configuration register is setup to disable UBA
+ * response on DMA transfers to addresses controlled
+ * by the disabled mapping registers.
+ * On a DW780, should only be called from ubameminit, or in ascending order
+ * from 0 with 8K-sized and -aligned addresses; freeing memory that isn't
+ * the last unibus memory would free unusable map registers.
+ * Doalloc is 1 to allocate, 0 to deallocate.
+ */
+ubamem(uban, addr, npg, doalloc)
+ int uban, addr, npg, doalloc;
+{
+ register struct uba_hd *uh = &uba_hd[uban];
+ register int a;
+ int s;
+
+ a = (addr >> 9) + 1;
+ s = spluba();
+ if (doalloc)
+ a = rmget(uh->uh_map, npg, a);
+ else
+ rmfree(uh->uh_map, (long)npg, (long)a);
+ splx(s);
+ if (a) {
+ register int i, *m;
+
+ m = (int *)&uh->uh_mr[a - 1];
+ for (i = 0; i < npg; i++)
+ *m++ = 0; /* All off, especially 'valid' */
+ i = addr + npg * 512;
+ if (doalloc && i > uh->uh_lastmem)
+ uh->uh_lastmem = i;
+ else if (doalloc == 0 && i == uh->uh_lastmem)
+ uh->uh_lastmem = addr;
+#ifdef DW780
+ /*
+ * On a 780, set up the map register disable
+ * field in the configuration register. Beware
+ * of callers that request memory ``out of order''
+ * or in sections other than 8K multiples.
+ * Ubameminit handles such requests properly, however.
+ */
+ if (uh->uh_type == DW780) {
+ i = uh->uh_uba->uba_cr &~ 0x7c000000;
+ i |= ((uh->uh_lastmem + 8191) / 8192) << 26;
+ uh->uh_uba->uba_cr = i;
+ }
+#endif
+ }
+ return (a);
+}
+
+#include "ik.h"
+#include "vs.h"
+#if NIK > 0 || NVS > 0
+/*
+ * Map a virtual address into users address space. Actually all we
+ * do is turn on the user mode write protection bits for the particular
+ * page of memory involved.
+ */
+maptouser(vaddress)
+ caddr_t vaddress;
+{
+
+ kvtopte(vaddress)->pg_prot = (PG_UW >> 27);
+}
+
+unmaptouser(vaddress)
+ caddr_t vaddress;
+{
+
+ kvtopte(vaddress)->pg_prot = (PG_KW >> 27);
+}
+#endif
+
+resuba()
+{
+ showstate(curproc);
+ panic("resuba");
+}
+
+int
+uba_match(parent, cf, aux)
+ struct device *parent;
+ struct cfdata *cf;
+ void *aux;
+{
+ struct sbi_attach_args *sa=(struct sbi_attach_args *)aux;
+ extern int numuba;
+ int ubanr;
+
+#if VAX630
+ /*
+ * The MicroVAXII always has a single QBA.
+ */
+ if (cpu_type == VAX_630)
+ if (numuba == 0)
+ return 1;
+ else
+ return 0;
+#endif
+ if(numuba) return 0;
+ if((cf->cf_loc[0]!=sa->nexnum)&&(cf->cf_loc[0]>-1))
+ return 0; /* UBA doesn't match spec's */
+
+ switch(sa->type){
+ case NEX_UBA0:
+ case NEX_UBA1:
+ case NEX_UBA2:
+ case NEX_UBA3:
+ return 1;
+
+ default:
+ return 0;
+ }
+}
+
+void
+uba_attach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct sbi_attach_args *sa=(struct sbi_attach_args *)aux;
+ extern struct uba_hd uba_hd[];
+ struct uba_regs *ubar=(struct uba_regs *)sa->nexaddr;
+ struct uba_hd *uhp = &uba_hd[numuba];
+ void ubascan();
+
+ printf("\n");
+ switch (cpunumber) {
+#if VAX750
+ case VAX_750:
+ uhp->uh_mr = (void *)ubar->uba_map;
+ uhp->uh_type = DW750;
+ uhp->uh_uba = (void*)ubar;
+ uhp->uh_physuba = (void*)0xf20000+sa->nexnum*0x2000;
+ uhp->uh_memsize = UBAPAGES;
+ uhp->uh_mem = Tumem(numuba);
+ uhp->uh_iopage = Tumem(numuba) + (uhp->uh_memsize * NBPG);
+ ioaccess(UMEM750(numuba), UMEMmap[numuba], (UBAPAGES+UBAIOPAGES)*NBPG);
+/* Now everything should be set up (I hope...) */
+#ifdef notyet
+ config_scan(ubascan,self);
+
+#else
+ unifind(uhp, UMEM750(numuba) + (uhp->uh_memsize * NBPG));
+#endif
+ break;
+#endif
+#if VAX630 || VAX410
+ case VAX_78032:
+ switch (cpu_type) {
+#if VAX630
+ case VAX_630:
+ uhp->uh_mr = (void *)sa->nexaddr;
+ uhp->uh_type = QBA;
+ uhp->uh_uba = (void*)ubar;
+ uhp->uh_physuba = (void*)QBAMAP630;
+ uhp->uh_memsize = QBAPAGES;
+ uhp->uh_mem = Numem;
+ uhp->uh_iopage = Numem + (uhp->uh_memsize * NBPG);
+
+ /*
+ * For the MicroVAXII, the qbus address space is not contiguous
+ * in physical address space. I also map the page that has the
+ * memory error registers and the watch chip here and init them,
+ * for want of a better place to do it.
+ */
+ ioaccess(QMEM630, UMEMmap[0], QBAPAGES * NBPG);
+ ioaccess(QIOPAGE630, UMEMmap[0] + QBAPAGES, UBAIOPAGES * NBPG);
+ ioaccess(UVAXIICPU, UMEMmap[0] + QBAPAGES + UBAIOPAGES, NBPG);
+ uvaxIIcpu_ptr =
+ (struct uvaxIIcpu *)(Numem+(QBAPAGES+UBAIOPAGES)*NBPG);
+ ioaccess(KA630CLK,UMEMmap[0] + QBAPAGES + UBAIOPAGES + 1,NBPG);
+ ka630clk_ptr =
+ (struct ka630clock *)(Numem+(QBAPAGES+UBAIOPAGES+1)*NBPG);
+
+ /*
+ * Clear restart and boot in progress flags in the CPMBX.
+ */
+ ka630clk_ptr->cpmbx = (ka630clk_ptr->cpmbx & KA630CLK_LANG);
+
+ /*
+ * Enable memory parity error detection and clear error bits.
+ */
+ uvaxIIcpu_ptr->uvaxII_mser = (UVAXIIMSER_PEN|UVAXIIMSER_MERR|
+ UVAXIIMSER_LEB);
+
+ /*
+ * Now that QBus space is mapped, set the local memory external
+ * access enable.
+ */
+ *((u_short *)(uhp->uh_iopage + QIPCR)) = Q_LMEAE;
+/* Now everything should be set up (I hope...) */
+#ifdef notyet
+ config_scan(ubascan,self);
+
+#else
+ unifind(uhp, QIOPAGE630);
+#endif
+ break;
+#endif
+ };
+ break;
+#endif
+ };
+ numuba++;
+}
+
+
+
+struct cfdriver ubacd=
+ { NULL, "uba", uba_match, uba_attach, DV_CPU, sizeof(struct device),1,0};
+
+
+
diff --git a/sys/arch/vax/uba/ubareg.h b/sys/arch/vax/uba/ubareg.h
new file mode 100644
index 00000000000..dbd133554a6
--- /dev/null
+++ b/sys/arch/vax/uba/ubareg.h
@@ -0,0 +1,327 @@
+/* $NetBSD: ubareg.h,v 1.3 1995/02/13 00:44:23 ragge Exp $ */
+
+/*-
+ * Copyright (c) 1982, 1986 The Regents of the University of California.
+ * All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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.
+ *
+ * @(#)ubareg.h 7.8 (Berkeley) 5/9/91
+ */
+
+/*
+ * VAX UNIBUS adapter registers
+ */
+
+/*
+ * "UNIBUS" adaptor types.
+ * This code is used for both UNIBUSes and Q-buses
+ * with different types of adaptors.
+ * Definition of a type includes support code for that type.
+ */
+
+#if VAX780 || VAX8600
+#define DW780 1 /* has adaptor regs, sr: 780/785/8600 */
+#else
+#undef DW780
+#endif
+
+
+#if VAX750
+#define DW750 2 /* has adaptor regs, no sr: 750, 730 */
+#endif
+
+#if VAX730
+#define DW730 3 /* has adaptor regs, no sr: 750, 730 */
+#endif
+
+#if VAX630 || VAX650
+#define QBA 4 /* 22-bit Q-bus, no adaptor regs: uVAX II */
+#endif
+
+#if VAX8200 || VAX8500 || VAX8800
+#define DWBUA 5 /* BI UNIBUS adaptor: 8200/8500/8800 */
+#endif
+
+/*
+ * Size of unibus memory address space in pages
+ * (also number of map registers).
+ * QBAPAGES should be 8192, but we don't need nearly that much
+ * address space, and the return from the allocation routine
+ * can accommodate at most 2047 (ubavar.h: UBA_MAXMR);
+ * QBAPAGES must be at least UBAPAGES. Choose pragmatically.
+ */
+#define UBAPAGES 496
+#define NUBMREG 496
+#if defined(GATEWAY) && !defined(QNIVERT)
+#define QBAPAGES 1024
+#else
+#define QBAPAGES UBAPAGES
+#endif
+#define UBAIOADDR 0760000 /* start of I/O page */
+#define UBAIOPAGES 16
+
+#ifndef LOCORE
+/*
+ * DWBUA hardware registers.
+ */
+struct dwbua_regs {
+ int pad1[456]; /* actually bii regs + pad */
+ int bua_csr; /* control and status register */
+ int bua_offset; /* vector offset register */
+ int bua_fubar; /* failed UNIBUS address register */
+ int bua_bifar; /* BI failed address register */
+ int bua_udiag[5]; /* micro diagnostics (R/O) */
+ int pad2[3];
+/* dpr[0] is for DDP; dpr's 1 through 5 are for BPD's 1 through 5 */
+ int bua_dpr[6]; /* data path registers */
+ int pad3[10];
+ int bua_bdps[20]; /* buffered data path space *//*???*/
+ int pad4[8];
+ pt_entry_t bua_map[UBAPAGES]; /* unibus map registers */
+ int pad5[UBAIOPAGES]; /* no maps for device address space */
+};
+
+#ifdef DWBUA
+/* bua_csr */
+#define BUACSR_ERR 0x80000000 /* composite error */
+#define BUACSR_BIF 0x10000000 /* BI failure */
+#define BUACSR_SSYNTO 0x08000000 /* slave sync timeout */
+#define BUACSR_UIE 0x04000000 /* unibus interlock error */
+#define BUACSR_IVMR 0x02000000 /* invalid map register */
+#define BUACSR_BADBDP 0x01000000 /* bad BDP select */
+#define BUACSR_BUAEIE 0x00100000 /* bua error interrupt enable (?) */
+#define BUACSR_UPI 0x00020000 /* unibus power init */
+#define BUACSR_UREGDUMP 0x00010000 /* microdiag register dump */
+#define BUACSR_IERRNO 0x000000ff /* mask for internal errror number */
+
+/* bua_offset */
+#define BUAOFFSET_MASK 0x00003e00 /* hence max offset = 15872 */
+
+/* bua_dpr */
+#define BUADPR_DPSEL 0x00e00000 /* data path select (?) */
+#define BUADPR_PURGE 0x00000001 /* purge bdp */
+
+/* bua_map -- in particular, those bits that are not in DW780s & DW750s */
+#define BUAMR_IOADR 0x40000000 /* I/O address space */
+#define BUAMR_LAE 0x04000000 /* longword access enable */
+ /* I see no reason to use either one, though ... act 6 Aug 1987 */
+
+#define UBA_PURGEBUA(uba, bdp) \
+ (((struct dwbua_regs *)(uba))->bua_dpr[bdp] |= BUADPR_PURGE)
+#else
+#define UBA_PURGEBUA(uba, bdp)
+#endif
+
+/*
+ * DW780/DW750 hardware registers
+ */
+struct uba_regs {
+ int uba_cnfgr; /* configuration register */
+ int uba_cr; /* control register */
+ int uba_sr; /* status register */
+ int uba_dcr; /* diagnostic control register */
+ int uba_fmer; /* failed map entry register */
+ int uba_fubar; /* failed UNIBUS address register */
+ int pad1[2];
+ int uba_brsvr[4];
+ int uba_brrvr[4]; /* receive vector registers */
+ int uba_dpr[16]; /* buffered data path register */
+ int pad2[480];
+ pt_entry_t uba_map[UBAPAGES]; /* unibus map register */
+ int pad3[UBAIOPAGES]; /* no maps for device address space */
+};
+#endif
+
+#ifdef DW780
+/* uba_cnfgr */
+#define UBACNFGR_UBINIT 0x00040000 /* unibus init asserted */
+#define UBACNFGR_UBPDN 0x00020000 /* unibus power down */
+#define UBACNFGR_UBIC 0x00010000 /* unibus init complete */
+
+#define UBACNFGR_BITS \
+"\40\40PARFLT\37WSQFLT\36URDFLT\35ISQFLT\34MXTFLT\33XMTFLT\30ADPDN\27ADPUP\23UBINIT\22UBPDN\21UBIC"
+
+/* uba_cr */
+#define UBACR_MRD16 0x40000000 /* map reg disable bit 4 */
+#define UBACR_MRD8 0x20000000 /* map reg disable bit 3 */
+#define UBACR_MRD4 0x10000000 /* map reg disable bit 2 */
+#define UBACR_MRD2 0x08000000 /* map reg disable bit 1 */
+#define UBACR_MRD1 0x04000000 /* map reg disable bit 0 */
+#define UBACR_IFS 0x00000040 /* interrupt field switch */
+#define UBACR_BRIE 0x00000020 /* BR interrupt enable */
+#define UBACR_USEFIE 0x00000010 /* UNIBUS to SBI error field IE */
+#define UBACR_SUEFIE 0x00000008 /* SBI to UNIBUS error field IE */
+#define UBACR_CNFIE 0x00000004 /* configuration IE */
+#define UBACR_UPF 0x00000002 /* UNIBUS power fail */
+#define UBACR_ADINIT 0x00000001 /* adapter init */
+
+/* uba_sr */
+#define UBASR_BR7FULL 0x08000000 /* BR7 receive vector reg full */
+#define UBASR_BR6FULL 0x04000000 /* BR6 receive vector reg full */
+#define UBASR_BR5FULL 0x02000000 /* BR5 receive vector reg full */
+#define UBASR_BR4FULL 0x01000000 /* BR4 receive vector reg full */
+#define UBASR_RDTO 0x00000400 /* UNIBUS to SBI read data timeout */
+#define UBASR_RDS 0x00000200 /* read data substitute */
+#define UBASR_CRD 0x00000100 /* corrected read data */
+#define UBASR_CXTER 0x00000080 /* command transmit error */
+#define UBASR_CXTMO 0x00000040 /* command transmit timeout */
+#define UBASR_DPPE 0x00000020 /* data path parity error */
+#define UBASR_IVMR 0x00000010 /* invalid map register */
+#define UBASR_MRPF 0x00000008 /* map register parity failure */
+#define UBASR_LEB 0x00000004 /* lost error */
+#define UBASR_UBSTO 0x00000002 /* UNIBUS select timeout */
+#define UBASR_UBSSYNTO 0x00000001 /* UNIBUS slave sync timeout */
+
+#define UBASR_BITS \
+"\20\13RDTO\12RDS\11CRD\10CXTER\7CXTMO\6DPPE\5IVMR\4MRPF\3LEB\2UBSTO\1UBSSYNTO"
+
+/* uba_brrvr[] */
+#define UBABRRVR_AIRI 0x80000000 /* adapter interrupt request */
+#define UBABRRVR_DIV 0x0000ffff /* device interrupt vector field */
+#endif
+
+/* uba_dpr */
+#ifdef DW780
+#define UBADPR_BNE 0x80000000 /* buffer not empty - purge */
+#define UBADPR_BTE 0x40000000 /* buffer transfer error */
+#define UBADPR_DPF 0x20000000 /* DP function (RO) */
+#define UBADPR_BS 0x007f0000 /* buffer state field */
+#define UBADPR_BUBA 0x0000ffff /* buffered UNIBUS address */
+#define UBA_PURGE780(uba, bdp) \
+ ((uba)->uba_dpr[bdp] |= UBADPR_BNE)
+#else
+#define UBA_PURGE780(uba, bdp)
+#endif
+#ifdef DW750
+#define UBADPR_ERROR 0x80000000 /* error occurred */
+#define UBADPR_NXM 0x40000000 /* nxm from memory */
+#define UBADPR_UCE 0x20000000 /* uncorrectable error */
+#define UBADPR_PURGE 0x00000001 /* purge bdp */
+/* the DELAY is for a hardware problem */
+#define UBA_PURGE750(uba, bdp) { \
+ ((uba)->uba_dpr[bdp] |= (UBADPR_PURGE|UBADPR_NXM|UBADPR_UCE)); \
+ {int N=8;while(N--);} \
+}
+#else
+#define UBA_PURGE750(uba, bdp)
+#endif
+
+/*
+ * Macros for fast buffered data path purging in time-critical routines.
+ *
+ * Too bad C pre-processor doesn't have the power of LISP in macro
+ * expansion...
+ */
+
+/* THIS IS WRONG, should use pointer to uba_hd */
+#if DWBUA || DW780 || DW750
+#define UBAPURGE(uba, bdp) { \
+ switch (MACHID(cpu_type)) { \
+ case VAX_8200: UBA_PURGEBUA(uba, bdp); break; \
+ case VAX_8600: case VAX_780: UBA_PURGE780((uba), (bdp)); break; \
+ case VAX_750: UBA_PURGE750((uba), (bdp)); break; \
+ } \
+}
+#else
+#define UBAPURGE(uba, bdp)
+#endif
+
+
+
+/* uba_mr[] */
+#define UBAMR_MRV 0x80000000 /* map register valid */
+#define UBAMR_BO 0x02000000 /* byte offset bit */
+#define UBAMR_DPDB 0x01e00000 /* data path designator field */
+#define UBAMR_SBIPFN 0x001fffff /* SBI page address field */
+
+#define UBAMR_DPSHIFT 21 /* shift to data path designator */
+
+/*
+ * Number of unibus buffered data paths and possible uba's per cpu type.
+ */
+#define NBDP8600 15
+#define NBDP780 15
+#define NBDPBUA 5
+#define NBDP750 3
+#define NBDP730 0
+#define MAXNBDP 15
+
+/*
+ * Symbolic BUS addresses for UBAs.
+ */
+
+#if VAX630 || VAX650
+#define QBAMAP630 ((struct pte *)0x20088000)
+#define QMEM630 0x30000000
+#define QIOPAGE630 0x20000000
+/*
+ * Q-bus control registers
+ */
+#define QIPCR 0x1f40 /* from start of iopage */
+/* bits in QIPCR */
+#define Q_DBIRQ 0x0001 /* doorbell interrupt request */
+#define Q_LMEAE 0x0020 /* local mem external access enable */
+#define Q_DBIIE 0x0040 /* doorbell interrupt enable */
+#define Q_AUXHLT 0x0100 /* auxiliary processor halt */
+#define Q_DMAQPE 0x8000 /* Q22 bus address space parity error */
+#endif
+
+#if VAX730
+#define UMEM730 0xfc0000
+#endif
+
+#if VAX750
+#define UMEM750(i) (0xfc0000-(i)*0x40000)
+#endif
+
+#if VAX780
+#define UMEM780(i) (0x20100000+(i)*0x40000)
+#endif
+
+#if VAX8200 /* BEWARE, argument is node, not ubanum */
+#define UMEM8200(i) (0x20400000+(i)*0x40000)
+#endif
+
+#if VAX8600
+#define UMEMA8600(i) (0x20100000+(i)*0x40000)
+#define UMEMB8600(i) (0x22100000+(i)*0x40000)
+#endif
+
+/*
+ * Macro to offset a UNIBUS device address, often expressed as
+ * something like 0172520, by forcing it into the last 8K
+ * of UNIBUS memory space.
+ */
+#define ubdevreg(addr) ((addr) & 017777)
diff --git a/sys/arch/vax/uba/ubavar.h b/sys/arch/vax/uba/ubavar.h
new file mode 100644
index 00000000000..24052ad19b6
--- /dev/null
+++ b/sys/arch/vax/uba/ubavar.h
@@ -0,0 +1,266 @@
+/* $NetBSD: ubavar.h,v 1.6 1995/05/11 16:53:17 jtc Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986 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.
+ *
+ * @(#)ubavar.h 7.7 (Berkeley) 6/28/90
+ */
+
+/*
+ * This file contains definitions related to the kernel structures
+ * for dealing with the unibus adapters.
+ *
+ * Each uba has a uba_hd structure.
+ * Each unibus controller which is not a device has a uba_ctlr structure.
+ * Each unibus device has a uba_device structure.
+ */
+
+#ifndef LOCORE
+
+#include "sys/buf.h"
+/*
+ * Per-uba structure.
+ *
+ * This structure holds the interrupt vector for the uba,
+ * and its address in physical and virtual space. At boot time
+ * we determine the devices attached to the uba's and their
+ * interrupt vectors, filling in uh_vec. We free the map
+ * register and bdp resources of the uba into the structures
+ * defined here.
+ *
+ * During normal operation, resources are allocated and returned
+ * to the structures here. We watch the number of passive releases
+ * on each uba, and if the number is excessive may reset the uba.
+ *
+ * When uba resources are needed and not available, or if a device
+ * which can tolerate no other uba activity (rk07) gets on the bus,
+ * then device drivers may have to wait to get to the bus and are
+ * queued here. It is also possible for processes to block in
+ * the unibus driver in resource wait (mrwant, bdpwant); these
+ * wait states are also recorded here.
+ */
+struct uba_hd {
+ int uh_type; /* type of adaptor */
+ struct uba_regs *uh_uba; /* virt addr of uba adaptor regs */
+ struct uba_regs *uh_physuba; /* phys addr of uba adaptor regs */
+ struct pte *uh_mr; /* start of page map */
+ int uh_memsize; /* size of uba memory, pages */
+ caddr_t uh_mem; /* start of uba memory address space */
+ caddr_t uh_iopage; /* start of uba io page */
+ int (**Nuh_vec)(); /* interrupt vector */
+ struct uba_device *uh_actf; /* head of queue to transfer */
+ struct uba_device *uh_actl; /* tail of queue to transfer */
+ short uh_mrwant; /* someone is waiting for map reg */
+ short uh_bdpwant; /* someone awaits bdp's */
+ int uh_bdpfree; /* free bdp's */
+ int uh_hangcnt; /* number of ticks hung */
+ int uh_zvcnt; /* number of recent 0 vectors */
+ long uh_zvtime; /* time over which zvcnt accumulated */
+ int uh_zvtotal; /* total number of 0 vectors */
+ int uh_errcnt; /* number of errors */
+ int uh_lastiv; /* last free interrupt vector */
+ short uh_users; /* transient bdp use count */
+ short uh_xclu; /* an rk07 is using this uba! */
+ int uh_lastmem; /* limit of any unibus memory */
+#define UAMSIZ 100
+ struct map *uh_map; /* register free map */
+};
+
+/* given a pointer to uba_regs, find DWBUA registers */
+/* this should be replaced with a union in uba_hd */
+#define BUA(uba) ((struct dwbua_regs *)(uba))
+
+/*
+ * Per-controller structure.
+ * (E.g. one for each disk and tape controller, and other things
+ * which use and release buffered data paths.)
+ *
+ * If a controller has devices attached, then there are
+ * cross-referenced uba_drive structures.
+ * This structure is the one which is queued in unibus resource wait,
+ * and saves the information about unibus resources which are used.
+ * The queue of devices waiting to transfer is also attached here.
+ */
+struct uba_ctlr {
+ struct uba_driver *um_driver;
+ short um_ctlr; /* controller index in driver */
+ short um_ubanum; /* the uba it is on */
+ short um_alive; /* controller exists */
+ int (*um_intr)(); /* interrupt handler(s) */
+ caddr_t um_addr; /* address of device in i/o space */
+ struct uba_hd *um_hd;
+/* the driver saves the prototype command here for use in its go routine */
+ int um_cmd; /* communication to dgo() */
+ int um_ubinfo; /* save unibus registers, etc */
+ int um_bdp; /* for controllers that hang on to bdp's */
+ struct buf um_tab; /* queue of devices for this controller */
+};
+
+/*
+ * Per ``device'' structure.
+ * (A controller has devices or uses and releases buffered data paths).
+ * (Everything else is a ``device''.)
+ *
+ * If a controller has many drives attached, then there will
+ * be several uba_device structures associated with a single uba_ctlr
+ * structure.
+ *
+ * This structure contains all the information necessary to run
+ * a unibus device such as a dz or a dh. It also contains information
+ * for slaves of unibus controllers as to which device on the slave
+ * this is. A flags field here can also be given in the system specification
+ * and is used to tell which dz lines are hard wired or other device
+ * specific parameters.
+ */
+struct uba_device {
+ struct uba_driver *ui_driver;
+ short ui_unit; /* unit number on the system */
+ short ui_ctlr; /* mass ctlr number; -1 if none */
+ short ui_ubanum; /* the uba it is on */
+ short ui_slave; /* slave on controller */
+ int (*ui_intr)(); /* interrupt handler(s) */
+ caddr_t ui_addr; /* address of device in i/o space */
+ short ui_dk; /* if init 1 set to number for iostat */
+ int ui_flags; /* parameter from system specification */
+ short ui_alive; /* device exists */
+ short ui_type; /* driver specific type information */
+ caddr_t ui_physaddr; /* phys addr, for standalone (dump) code */
+/* this is the forward link in a list of devices on a controller */
+ struct uba_device *ui_forw;
+/* if the device is connected to a controller, this is the controller */
+ struct uba_ctlr *ui_mi;
+ struct uba_hd *ui_hd;
+};
+
+/*
+ * Per-driver structure.
+ *
+ * Each unibus driver defines entries for a set of routines
+ * as well as an array of types which are acceptable to it.
+ * These are used at boot time by the configuration program.
+ */
+struct uba_driver {
+ int (*ud_probe)(); /* see if a driver is really there */
+ int (*ud_slave)(); /* see if a slave is there */
+ int (*ud_attach)(); /* setup driver for a slave */
+ int (*ud_dgo)(); /* fill csr/ba to start transfer */
+ u_short *ud_addr; /* device csr addresses */
+ char *ud_dname; /* name of a device */
+ struct uba_device **ud_dinfo; /* backpointers to ubdinit structs */
+ char *ud_mname; /* name of a controller */
+ struct uba_ctlr **ud_minfo; /* backpointers to ubminit structs */
+ short ud_xclu; /* want exclusive use of bdp's */
+ short ud_keepbdp; /* hang on to bdp's once allocated */
+ int (*ud_ubamem)(); /* see if dedicated memory is present */
+};
+#endif
+
+/*
+ * Flags to UBA map/bdp allocation routines
+ */
+#define UBA_NEEDBDP 0x01 /* transfer needs a bdp */
+#define UBA_CANTWAIT 0x02 /* don't block me */
+#define UBA_NEED16 0x04 /* need 16 bit addresses only */
+#define UBA_HAVEBDP 0x08 /* use bdp specified in high bits */
+
+/*
+ * Macros to bust return word from map allocation routines.
+ * SHOULD USE STRUCTURE TO STORE UBA RESOURCE ALLOCATION:
+ */
+#ifdef notyet
+struct ubinfo {
+ long ub_addr; /* unibus address: mr + boff */
+ int ub_nmr; /* number of registers, 0 if empty */
+ int ub_bdp; /* bdp number, 0 if none */
+};
+#define UBAI_MR(i) (((i) >> 9) & 0x7ff) /* starting map register */
+#define UBAI_BOFF(i) ((i)&0x1ff) /* page offset */
+#else
+#define UBAI_BDP(i) ((int)(((unsigned)(i)) >> 28))
+#define BDPMASK 0xf0000000
+#define UBAI_NMR(i) ((int)((i) >> 20) & 0xff) /* max 255 (=127.5K) */
+#define UBA_MAXNMR 255
+#define UBAI_MR(i) ((int)((i) >> 9) & 0x7ff) /* max 2047 */
+#define UBA_MAXMR 2047
+#define UBAI_BOFF(i) ((int)((i) & 0x1ff))
+#define UBAI_ADDR(i) ((int)((i) & 0xfffff)) /* uba addr (boff+mr) */
+#define UBAI_INFO(off, mr, nmr, bdp) \
+ (((bdp) << 28) | ((nmr) << 20) | ((mr) << 9) | (off))
+#endif
+
+#ifndef LOCORE
+#ifdef _KERNEL
+#define ubago(ui) ubaqueue(ui, 0)
+
+/*
+ * UBA related kernel variables
+ */
+int numuba; /* number of uba's */
+struct uba_hd uba_hd[];
+
+/*
+ * Ubminit and ubdinit initialize the mass storage controller and
+ * device tables specifying possible devices.
+ */
+extern struct uba_ctlr ubminit[];
+extern struct uba_device ubdinit[];
+
+/*
+ * UNIBUS device address space is mapped by UMEMmap
+ * into virtual address umem[][].
+ * The IO page is mapped to the last 8K of each.
+ * This should be enlarged for the Q22 bus.
+ */
+extern struct pte *UMEMmap[]; /* uba device addr pte's */
+/* extern char umem[][512*NBPG]; /* uba device addr space */
+extern char *Numem;
+#define Tumem(x) (Numem+(UBAPAGES+UBAIOPAGES)*NBPG*x)
+
+/*
+ * Since some VAXen vector their unibus interrupts
+ * just adjacent to the system control block, we must
+ * allocate space there when running on ``any'' cpu. This space is
+ * used for the vectors for all ubas.
+ */
+extern int (*UNIvec[][128])(); /* unibus vec for ubas */
+extern int (*eUNIvec)(); /* end of unibus vec */
+
+#if defined(VAX780) || defined(VAX8600)
+/*
+ * On DW780's, we must set the scb vectors for the nexus of the
+ * UNIbus adaptors to vector to locore unibus adaptor interrupt dispatchers
+ * which make 780's look like the other VAXen.
+ */
+extern Xua0int(), Xua1int(), Xua2int(), Xua3int();
+#endif VAX780
+#endif /* _KERNEL */
+#endif !LOCORE
diff --git a/sys/arch/vax/uba/ubavec.s b/sys/arch/vax/uba/ubavec.s
new file mode 100644
index 00000000000..7d388d3f920
--- /dev/null
+++ b/sys/arch/vax/uba/ubavec.s
@@ -0,0 +1,112 @@
+/* $NetBSD: ubavec.s,v 1.2 1995/02/23 17:53:22 ragge Exp $ */
+/*
+ * Copyright (c) 1994 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}.
+ * 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 */
+
+
+/*
+ * Interrupt vectors for Unibus; already at the right place at boot.
+ * This allocation should be done in some other way, 8600 has its
+ * second SCB at the same place as 750's first UBA vector... foolish.
+ */
+
+#define UBAVEC(lab,off) .long lab+(off)*8+1;
+#define UBAVEC2(lab,off) UBAVEC(lab,off);UBAVEC(lab,off+1)
+#define UBAVEC4(lab,off) UBAVEC2(lab,off);UBAVEC2(lab,off+2)
+#define UBAVEC8(lab,off) UBAVEC4(lab,off);UBAVEC4(lab,off+4)
+#define UBAVEC16(lab,off) UBAVEC8(lab,off);UBAVEC8(lab,off+8)
+
+.globl _UNIvec, _eUNIvec, ubaett
+
+_UNIvec:
+ UBAVEC16(ubaett,0);UBAVEC16(ubaett,16);
+ UBAVEC16(ubaett,32);UBAVEC16(ubaett,48);
+ UBAVEC16(ubaett,64);UBAVEC16(ubaett,80);
+ UBAVEC16(ubaett,96);UBAVEC16(ubaett,112);
+ UBAVEC16(ubatva,0);UBAVEC16(ubatva,16);
+ UBAVEC16(ubatva,32);UBAVEC16(ubatva,48);
+ UBAVEC16(ubatva,64);UBAVEC16(ubatva,80);
+ UBAVEC16(ubatva,96);UBAVEC16(ubatva,112);
+ UBAVEC16(ubatre,0);UBAVEC16(ubatre,16);
+ UBAVEC16(ubatre,32);UBAVEC16(ubatre,48);
+ UBAVEC16(ubatre,64);UBAVEC16(ubatre,80);
+ UBAVEC16(ubatre,96);UBAVEC16(ubatre,112);
+ UBAVEC16(ubafyra,0);UBAVEC16(ubafyra,16);
+ UBAVEC16(ubafyra,32);UBAVEC16(ubafyra,48);
+ UBAVEC16(ubafyra,64);UBAVEC16(ubafyra,80);
+ UBAVEC16(ubafyra,96);UBAVEC16(ubafyra,112);
+_eUNIvec:
+
+#define PR(uba) .align 2;pushr $0x3f;jsb uba ;
+#define UBAJSB4(uba) PR(uba);PR(uba);PR(uba);PR(uba);
+#define UBAJSB16(uba) UBAJSB4(uba);UBAJSB4(uba);UBAJSB4(uba);UBAJSB4(uba);
+#define UBAJSB64(uba) UBAJSB16(uba);UBAJSB16(uba);UBAJSB16(uba);UBAJSB16(uba)
+
+ubaett:
+ UBAJSB64(ett);UBAJSB64(ett);UBAJSB64(ett);UBAJSB64(ett);
+ubatva:
+ UBAJSB64(tva);UBAJSB64(tva);UBAJSB64(tva);UBAJSB64(tva);
+ubatre:
+ UBAJSB64(tre);UBAJSB64(tre);UBAJSB64(tre);UBAJSB64(tre);
+ubafyra:
+ UBAJSB64(fyra);UBAJSB64(fyra);UBAJSB64(fyra);UBAJSB64(fyra);
+
+
+ett: subl3 $ubaett, (sp), r0
+ ashl $-3, r0, (sp)
+ pushl $0
+ brb 1f
+
+tva: subl3 $ubatva, (sp), r0
+ ashl $-3, r0, (sp)
+ pushl $1
+ brb 1f
+
+tre: subl3 $ubatre, (sp), r0
+ ashl $-3, r0, (sp)
+ pushl $2
+ brb 1f
+
+ .globl ett,tva,tre,fyra
+fyra: subl3 $ubafyra, (sp), r0
+ ashl $-3, r0, (sp)
+ pushl $3
+
+1: mfpr $PR_IPL, -(sp)
+ calls $3, _ubainterrupt
+ popr $0x3f
+ rei
+
+
+
+
+
+
diff --git a/sys/arch/vax/uba/uda.c b/sys/arch/vax/uba/uda.c
new file mode 100644
index 00000000000..fcf8f57e0ec
--- /dev/null
+++ b/sys/arch/vax/uba/uda.c
@@ -0,0 +1,2424 @@
+/* $NetBSD: uda.c,v 1.8 1995/08/31 22:24:39 ragge Exp $ */
+
+/*
+ * Copyright (c) 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * 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.
+ *
+ * @(#)uda.c 7.32 (Berkeley) 2/13/91
+ */
+
+/*
+ * UDA50/MSCP device driver
+ */
+
+#define POLLSTATS
+
+/*
+ * TODO
+ * write bad block forwarding code
+ */
+
+#include "uda.h"
+#include "ra.h"
+
+#if NUDA > 0
+
+/*
+ * CONFIGURATION OPTIONS. The next three defines are tunable -- tune away!
+ *
+ * COMPAT_42 enables 4.2/4.3 compatibility (label mapping)
+ *
+ * NRSPL2 and NCMDL2 control the number of response and command
+ * packets respectively. They may be any value from 0 to 7, though
+ * setting them higher than 5 is unlikely to be of any value.
+ * If you get warnings about your command ring being too small,
+ * try increasing the values by one.
+ *
+ * MAXUNIT controls the maximum unit number (number of drives per
+ * controller) we are prepared to handle.
+ *
+ * DEFAULT_BURST must be at least 1.
+ */
+#define COMPAT_42
+
+#define NRSPL2 5 /* log2 number of response packets */
+#define NCMDL2 5 /* log2 number of command packets */
+#define MAXUNIT 8 /* maximum allowed unit number */
+#define DEFAULT_BURST 4 /* default DMA burst size */
+
+#include "sys/param.h"
+#include "sys/systm.h"
+#include "sys/buf.h"
+#include "sys/conf.h"
+#include "sys/file.h"
+#include "sys/ioctl.h"
+#include "sys/proc.h"
+#include "sys/user.h"
+#include "sys/map.h"
+#include "sys/device.h"
+#include "sys/dkstat.h"
+#include "sys/disklabel.h"
+#include "sys/syslog.h"
+#include "sys/stat.h"
+
+#include "machine/pte.h"
+#include "machine/sid.h"
+#include "machine/cpu.h"
+
+#include "vax/uba/ubareg.h"
+#include "vax/uba/ubavar.h"
+
+#define NRSP (1 << NRSPL2)
+#define NCMD (1 << NCMDL2)
+
+#include "vax/uba/udareg.h"
+#include "vax/vax/mscp.h"
+#include "vax/vax/mscpvar.h"
+#include "machine/mtpr.h"
+
+extern int cold;
+
+/*
+ * This macro is for delay during init. Some MSCP clone card (Dilog)
+ * can't handle fast read from its registers, and therefore need
+ * a delay between them.
+ */
+#define DELAYTEN 1000
+#define Wait_step( mask, result, status ) { \
+ status = 1; \
+ if ((udaddr->udasa & mask) != result) { \
+ int count = 0; \
+ while ((udaddr->udasa & mask) != result) { \
+ DELAY(100); \
+ count += 1; \
+ if (count > DELAYTEN) \
+ break; \
+ } \
+ if (count > DELAYTEN) \
+ status = 0; \
+ } \
+ }
+
+/*
+ * UDA communications area and MSCP packet pools, per controller.
+ */
+struct uda {
+ struct udaca uda_ca; /* communications area */
+ struct mscp uda_rsp[NRSP]; /* response packets */
+ struct mscp uda_cmd[NCMD]; /* command packets */
+} uda[NUDA];
+
+/*
+ * Software status, per controller.
+ */
+struct uda_softc {
+ struct uda *sc_uda; /* Unibus address of uda struct */
+ short sc_state; /* UDA50 state; see below */
+ short sc_flags; /* flags; see below */
+ int sc_micro; /* microcode revision */
+ int sc_ivec; /* interrupt vector address */
+ short sc_ipl; /* interrupt priority, Q-bus */
+ struct mscp_info sc_mi;/* MSCP info (per mscpvar.h) */
+#ifndef POLLSTATS
+ int sc_wticks; /* watchdog timer ticks */
+#else
+ short sc_wticks;
+ short sc_ncmd;
+#endif
+} uda_softc[NUDA];
+
+#ifdef POLLSTATS
+struct udastats {
+ int ncmd;
+ int cmd[NCMD + 1];
+} udastats = { NCMD + 1 };
+#endif
+
+/*
+ * Controller states
+ */
+#define ST_IDLE 0 /* uninitialised */
+#define ST_STEP1 1 /* in `STEP 1' */
+#define ST_STEP2 2 /* in `STEP 2' */
+#define ST_STEP3 3 /* in `STEP 3' */
+#define ST_SETCHAR 4 /* in `Set Controller Characteristics' */
+#define ST_RUN 5 /* up and running */
+
+/*
+ * Flags
+ */
+#define SC_MAPPED 0x01 /* mapped in Unibus I/O space */
+#define SC_INSTART 0x02 /* inside udastart() */
+#define SC_GRIPED 0x04 /* griped about cmd ring too small */
+#define SC_INSLAVE 0x08 /* inside udaslave() */
+#define SC_DOWAKE 0x10 /* wakeup when ctlr init done */
+#define SC_STARTPOLL 0x20 /* need to initiate polling */
+
+/*
+ * Device to unit number and partition and back
+ */
+#define UNITSHIFT 3
+#define UNITMASK 7
+#define udaunit(dev) (minor(dev) >> UNITSHIFT)
+#define udapart(dev) (minor(dev) & UNITMASK)
+#define udaminor(u, p) (((u) << UNITSHIFT) | (p))
+
+/*
+ * Drive status, per drive
+ */
+struct ra_info {
+ daddr_t ra_dsize; /* size in sectors */
+/* u_long ra_type; /* drive type */
+ u_long ra_mediaid; /* media id */
+ int ra_state; /* open/closed state */
+ struct ra_geom { /* geometry information */
+ u_short rg_nsectors; /* sectors/track */
+ u_short rg_ngroups; /* track groups */
+ u_short rg_ngpc; /* groups/cylinder */
+ u_short rg_ntracks; /* ngroups*ngpc */
+ u_short rg_ncyl; /* ra_dsize/ntracks/nsectors */
+#ifdef notyet
+ u_short rg_rctsize; /* size of rct */
+ u_short rg_rbns; /* replacement blocks per track */
+ u_short rg_nrct; /* number of rct copies */
+#endif
+ } ra_geom;
+ int ra_wlabel; /* label sector is currently writable */
+ u_long ra_openpart; /* partitions open */
+ u_long ra_bopenpart; /* block partitions open */
+ u_long ra_copenpart; /* character partitions open */
+} ra_info[NRA];
+
+/*
+ * Software state, per drive
+ */
+#define CLOSED 0
+#define WANTOPEN 1
+#define RDLABEL 2
+#define OPEN 3
+#define OPENRAW 4
+
+/*
+ * Definition of the driver for autoconf.
+ */
+int udaprobe(), udaslave(), udaattach(), udadgo(), udaintr();
+struct uba_ctlr *udaminfo[NUDA];
+struct uba_device *udadinfo[NRA];
+struct disklabel udalabel[NRA];
+
+u_short udastd[] = { 0 };
+struct uba_driver udadriver =
+ { udaprobe, udaslave, udaattach, udadgo, udastd, "ra", udadinfo, "uda",
+ udaminfo };
+
+/*
+ * More driver definitions, for generic MSCP code.
+ */
+int udadgram(), udactlrdone(), udaunconf(), udaiodone();
+int udaonline(), udagotstatus(), udaioerror(), udareplace(), udabb();
+
+struct buf udautab[NRA]; /* per drive transfer queue */
+
+struct mscp_driver udamscpdriver =
+ { MAXUNIT, NRA, UNITSHIFT, udautab, udalabel, udadinfo,
+ udadgram, udactlrdone, udaunconf, udaiodone,
+ udaonline, udagotstatus, udareplace, udaioerror, udabb,
+ "uda", "ra" };
+
+/*
+ * Miscellaneous private variables.
+ */
+char udasr_bits[] = UDASR_BITS;
+
+struct uba_device *udaip[NUDA][MAXUNIT];
+ /* inverting pointers: ctlr & unit => Unibus
+ device pointer */
+
+int udaburst[NUDA] = { 0 }; /* burst size, per UDA50, zero => default;
+ in data space so patchable via adb */
+
+struct mscp udaslavereply; /* get unit status response packet, set
+ for udaslave by udaunconf, via udaintr */
+
+static struct uba_ctlr *probeum;/* this is a hack---autoconf should pass ctlr
+ info to slave routine; instead, we remember
+ the last ctlr argument to probe */
+
+int udawstart;
+void udawatch(); /* watchdog timer */
+
+/*
+ * Externals
+ */
+int hz;
+
+/*
+ * Poke at a supposed UDA50 to see if it is there.
+ * This routine duplicates some of the code in udainit() only
+ * because autoconf has not set up the right information yet.
+ * We have to do everything `by hand'.
+ */
+udaprobe(reg, ctlr, um)
+ caddr_t reg;
+ int ctlr;
+ struct uba_ctlr *um;
+{
+/* int br, cvec; */
+ struct uda_softc *sc;
+ volatile struct udadevice *udaddr;
+ struct mscp_info *mi;
+ extern int cpu_type;
+ int timeout, tries, count;
+#ifdef notyet
+ int s;
+#endif
+
+#ifdef VAX750
+ /*
+ * The UDA50 wants to share BDPs on 750s, but not on 780s or
+ * 8600s. (730s have no BDPs anyway.) Toward this end, we
+ * here set the `keep bdp' flag in the per-driver information
+ * if this is a 750. (We just need to do it once, but it is
+ * easiest to do it now, for each UDA50.)
+ */
+ if (MACHID(cpu_type) == VAX_750)
+ udadriver.ud_keepbdp = 1;
+#endif
+/* printf("udaprobe\n"); */
+ probeum = um; /* remember for udaslave() */
+ /*
+ * Set up the controller-specific generic MSCP driver info.
+ * Note that this should really be done in the (nonexistent)
+ * controller attach routine.
+ */
+ sc = &uda_softc[ctlr];
+ mi = &sc->sc_mi;
+ mi->mi_md = &udamscpdriver;
+ mi->mi_ctlr = um->um_ctlr;
+ mi->mi_tab = (void*)&um->um_tab;
+ mi->mi_ip = udaip[ctlr];
+ mi->mi_cmd.mri_size = NCMD;
+ mi->mi_cmd.mri_desc = uda[ctlr].uda_ca.ca_cmddsc;
+ mi->mi_cmd.mri_ring = uda[ctlr].uda_cmd;
+ mi->mi_rsp.mri_size = NRSP;
+ mi->mi_rsp.mri_desc = uda[ctlr].uda_ca.ca_rspdsc;
+ mi->mi_rsp.mri_ring = uda[ctlr].uda_rsp;
+#ifdef ragge
+ mi->mi_wtab.b_actf = NULL;
+#else
+ mi->mi_wtab.b_actf = &mi->mi_wtab;
+#endif
+/* Was: mi->mi_wtab.av_forw = mi->mi_wtab.av_back = &mi->mi_wtab; */
+
+ /*
+ * More controller specific variables. Again, this should
+ * be in the controller attach routine.
+ */
+ if (udaburst[ctlr] == 0)
+ udaburst[ctlr] = DEFAULT_BURST;
+
+ /*
+ * Get an interrupt vector. Note that even if the controller
+ * does not respond, we keep the vector. This is not a serious
+ * problem; but it would be easily fixed if we had a controller
+ * attach routine. Sigh.
+ */
+ sc->sc_ivec = (uba_hd[numuba].uh_lastiv -= 4);
+ udaddr = (struct udadevice *) reg;
+
+ /*
+ * Initialise the controller (partially). The UDA50 programmer's
+ * manual states that if initialisation fails, it should be retried
+ * at least once, but after a second failure the port should be
+ * considered `down'; it also mentions that the controller should
+ * initialise within ten seconds. Or so I hear; I have not seen
+ * this manual myself.
+ */
+#ifdef notyet
+ s = spl6();
+#endif
+ tries = 0;
+again:
+ udaddr->udaip = 0; /* start initialisation */
+
+ count = 0;
+ while ( count < DELAYTEN ) {
+ if ( (udaddr->udasa & UDA_STEP1) != 0 )
+ break;
+ DELAY(10000);
+ count += 1;
+ }
+
+ /* nothing there */
+ if ( count == DELAYTEN )
+ return(0);
+
+ udaddr->udasa = UDA_ERR | (NCMDL2 << 11) | (NRSPL2 << 8) | UDA_IE |
+ (sc->sc_ivec >> 2);
+
+ count = 0;
+ while (count < DELAYTEN) {
+ if ((udaddr->udasa & UDA_STEP2 ) != 0)
+ break;
+ DELAY(10000);
+ count += 1;
+ }
+
+ if (count == DELAYTEN) {
+ printf("udaprobe: uda%d: init step2 no change.\n",
+ um->um_ctlr);
+ goto bad;
+ }
+
+ /* should have interrupted by now */
+#ifdef notyet
+ sc->sc_ipl = br = qbgetpri();
+#else
+ sc->sc_ipl = 0x15;
+#endif
+ return (sizeof (struct udadevice));
+bad:
+ if (++tries < 2)
+ goto again;
+#ifdef notyet
+ splx(s);
+#endif
+ return (0);
+}
+
+/*
+ * Find a slave. We allow wildcard slave numbers (something autoconf
+ * is not really prepared to deal with); and we need to know the
+ * controller number to talk to the UDA. For the latter, we keep
+ * track of the last controller probed, since a controller probe
+ * immediately precedes all slave probes for that controller. For the
+ * former, we simply put the unit number into ui->ui_slave after we
+ * have found one.
+ *
+ * Note that by the time udaslave is called, the interrupt vector
+ * for the UDA50 has been set up (so that udaunconf() will be called).
+ */
+udaslave(ui, reg)
+ register struct uba_device *ui;
+ caddr_t reg;
+{
+ register struct uba_ctlr *um = probeum;
+ volatile struct mscp *mp;
+ volatile struct uda_softc *sc;
+ int next = 0, timeout, tries;
+ volatile int i;
+
+#ifdef lint
+ i = 0; i = i;
+#endif
+ /*
+ * Make sure the controller is fully initialised, by waiting
+ * for it if necessary.
+ */
+ sc = &uda_softc[um->um_ctlr];
+ if (sc->sc_state == ST_RUN)
+ goto findunit;
+ tries = 0;
+again:
+ if (udainit(ui->ui_ctlr))
+ return (0);
+ timeout = todr() + 1000; /* 10 seconds */
+ while (todr() < timeout) {
+ if (sc->sc_state == ST_RUN) /* made it */
+ goto findunit;
+ }
+ if (++tries < 2)
+ goto again;
+ printf("uda%d: controller hung\n", um->um_ctlr);
+ return (0);
+
+ /*
+ * The controller is all set; go find the unit. Grab an
+ * MSCP packet and send out a Get Unit Status command, with
+ * the `next unit' modifier if we are looking for a generic
+ * unit. We set the `in slave' flag so that udaunconf()
+ * knows to copy the response to `udaslavereply'.
+ */
+findunit:
+ udaslavereply.mscp_opcode = 0;
+ sc->sc_flags |= SC_INSLAVE;
+ if ((mp = mscp_getcp(&sc->sc_mi, MSCP_DONTWAIT)) == NULL)
+ panic("udaslave"); /* `cannot happen' */
+ mp->mscp_opcode = M_OP_GETUNITST;
+ if (ui->ui_slave == '?') {
+ mp->mscp_unit = next;
+ mp->mscp_modifier = M_GUM_NEXTUNIT;
+ } else {
+ mp->mscp_unit = ui->ui_slave;
+ mp->mscp_modifier = 0;
+ }
+ *mp->mscp_addr |= MSCP_OWN | MSCP_INT;
+ i = ((struct udadevice *) reg)->udaip; /* initiate polling */
+ mp = &udaslavereply;
+ timeout = todr() + 1000;
+ while (todr() < timeout)
+ if (mp->mscp_opcode)
+ goto gotit;
+ printf("uda%d: no response to Get Unit Status request\n",
+ um->um_ctlr);
+ sc->sc_flags &= ~SC_INSLAVE;
+ return (0);
+
+gotit:
+ sc->sc_flags &= ~SC_INSLAVE;
+
+ /*
+ * Got a slave response. If the unit is there, use it.
+ */
+ switch (mp->mscp_status & M_ST_MASK) {
+
+ case M_ST_SUCCESS: /* worked */
+ case M_ST_AVAILABLE: /* found another drive */
+ break; /* use it */
+
+ case M_ST_OFFLINE:
+ /*
+ * Figure out why it is off line. It may be because
+ * it is nonexistent, or because it is spun down, or
+ * for some other reason.
+ */
+ switch (mp->mscp_status & ~M_ST_MASK) {
+
+ case M_OFFLINE_UNKNOWN:
+ /*
+ * No such drive, and there are none with
+ * higher unit numbers either, if we are
+ * using M_GUM_NEXTUNIT.
+ */
+ return (0);
+
+ case M_OFFLINE_UNMOUNTED:
+ /*
+ * The drive is not spun up. Use it anyway.
+ *
+ * N.B.: this seems to be a common occurrance
+ * after a power failure. The first attempt
+ * to bring it on line seems to spin it up
+ * (and thus takes several minutes). Perhaps
+ * we should note here that the on-line may
+ * take longer than usual.
+ */
+ break;
+
+ default:
+ /*
+ * In service, or something else equally unusable.
+ */
+ printf("uda%d: unit %d off line: ", um->um_ctlr,
+ mp->mscp_unit);
+ mscp_printevent(mp);
+ goto try_another;
+ }
+ break;
+
+ default:
+ printf("uda%d: unable to get unit status: ", um->um_ctlr);
+ mscp_printevent(mp);
+ return (0);
+ }
+
+ /*
+ * Does this ever happen? What (if anything) does it mean?
+ */
+ if (mp->mscp_unit < next) {
+ printf("uda%d: unit %d, next %d\n",
+ um->um_ctlr, mp->mscp_unit, next);
+ return (0);
+ }
+
+ if (mp->mscp_unit >= MAXUNIT) {
+ printf("uda%d: cannot handle unit number %d (max is %d)\n",
+ um->um_ctlr, mp->mscp_unit, MAXUNIT - 1);
+ return (0);
+ }
+
+ /*
+ * See if we already handle this drive.
+ * (Only likely if ui->ui_slave=='?'.)
+ */
+ if (udaip[um->um_ctlr][mp->mscp_unit] != NULL) {
+try_another:
+ if (ui->ui_slave != '?')
+ return (0);
+ next = mp->mscp_unit + 1;
+ goto findunit;
+ }
+
+ /*
+ * Voila!
+ */
+ uda_rasave(ui->ui_unit, mp, 0);
+ ui->ui_flags = 0; /* not on line, nor anything else */
+ ui->ui_slave = mp->mscp_unit;
+ return (1);
+}
+
+/*
+ * Attach a found slave. Make sure the watchdog timer is running.
+ * If this disk is being profiled, fill in the `wpms' value (used by
+ * what?). Set up the inverting pointer, and attempt to bring the
+ * drive on line and read its label.
+ */
+udaattach(ui)
+ register struct uba_device *ui;
+{
+ register int unit = ui->ui_unit;
+
+ if (udawstart == 0) {
+ timeout(udawatch, (caddr_t) 0, hz);
+ udawstart++;
+ }
+
+ /*
+ * Floppies cannot be brought on line unless there is
+ * a disk in the drive. Since an ONLINE while cold
+ * takes ten seconds to fail, and (when notyet becomes now)
+ * no sensible person will swap to one, we just
+ * defer the ONLINE until someone tries to use the drive.
+ *
+ * THIS ASSUMES THAT DRIVE TYPES ?X? ARE FLOPPIES
+ */
+ if (MSCP_MID_ECH(1, ra_info[unit].ra_mediaid) == 'X' - '@') {
+ printf(": floppy");
+ return;
+ }
+ if (ui->ui_dk >= 0)
+ dk_wpms[ui->ui_dk] = (60 * 31 * 256); /* approx */
+ udaip[ui->ui_ctlr][ui->ui_slave] = ui;
+
+ if (uda_rainit(ui, 0))
+ printf(": offline");
+ else if (ra_info[unit].ra_state == OPEN) {
+ printf(": %s, size = %d sectors",
+ udalabel[unit].d_typename, ra_info[unit].ra_dsize);
+#ifdef notyet
+ addswap(makedev(UDADEVNUM, udaminor(unit, 0)), &udalabel[unit]);
+#endif
+ }
+}
+
+/*
+ * Initialise a UDA50. Return true iff something goes wrong.
+ */
+udainit(ctlr)
+ int ctlr;
+{
+ register struct uda_softc *sc;
+ register struct udadevice *udaddr;
+ struct uba_ctlr *um;
+ int timo, ubinfo, count;
+/* printf("udainit\n"); */
+ sc = &uda_softc[ctlr];
+ um = udaminfo[ctlr];
+ if ((sc->sc_flags & SC_MAPPED) == 0) {
+ /*
+ * Map the communication area and command and
+ * response packets into Unibus space.
+ */
+ ubinfo = uballoc(um->um_ubanum, (caddr_t) &uda[ctlr],
+ sizeof (struct uda), UBA_CANTWAIT);
+ if (ubinfo == 0) {
+ printf("uda%d: uballoc map failed\n", ctlr);
+ return (-1);
+ }
+ sc->sc_uda = (struct uda *) UBAI_ADDR(ubinfo);
+ sc->sc_flags |= SC_MAPPED;
+ }
+
+ /*
+ * While we are thinking about it, reset the next command
+ * and response indicies.
+ */
+ sc->sc_mi.mi_cmd.mri_next = 0;
+ sc->sc_mi.mi_rsp.mri_next = 0;
+
+ /*
+ * Start up the hardware initialisation sequence.
+ */
+#define STEP0MASK (UDA_ERR | UDA_STEP4 | UDA_STEP3 | UDA_STEP2 | \
+ UDA_STEP1 | UDA_NV)
+
+ sc->sc_state = ST_IDLE; /* in case init fails */
+ udaddr = (struct udadevice *)um->um_addr;
+ udaddr->udaip = 0;
+ count = 0;
+ while (count < DELAYTEN) {
+ if ((udaddr->udasa & UDA_STEP1) != 0)
+ break;
+ DELAY(10000);
+ count += 1;
+ }
+ if (count == DELAYTEN) {
+ printf("uda%d: timeout during init\n", ctlr);
+ return (-1);
+ }
+
+ if ((udaddr->udasa & STEP0MASK) != UDA_STEP1) {
+ printf("uda%d: init failed, sa=%b\n", ctlr,
+ udaddr->udasa, udasr_bits);
+ udasaerror(um, 0);
+ return (-1);
+ }
+
+ /*
+ * Success! Record new state, and start step 1 initialisation.
+ * The rest is done in the interrupt handler.
+ */
+ sc->sc_state = ST_STEP1;
+ udaddr->udasa = UDA_ERR | (NCMDL2 << 11) | (NRSPL2 << 8) | UDA_IE |
+ (sc->sc_ivec >> 2);
+ return (0);
+}
+
+/*
+ * Open a drive.
+ */
+/*ARGSUSED*/
+udaopen(dev, flag, fmt)
+ dev_t dev;
+ int flag, fmt;
+{
+ register int unit;
+ register struct uba_device *ui;
+ register struct uda_softc *sc;
+ register struct disklabel *lp;
+ register struct partition *pp;
+ register struct ra_info *ra;
+ int s, i, part, mask, error = 0;
+ daddr_t start, end;
+/* printf("udaopen\n"); */
+ /*
+ * Make sure this is a reasonable open request.
+ */
+ unit = udaunit(dev);
+ if (unit >= NRA || (ui = udadinfo[unit]) == 0 || ui->ui_alive == 0)
+ return (ENXIO);
+
+ /*
+ * Make sure the controller is running, by (re)initialising it if
+ * necessary.
+ */
+ sc = &uda_softc[ui->ui_ctlr];
+ s = splbio();
+ if (sc->sc_state != ST_RUN) {
+ if (sc->sc_state == ST_IDLE && udainit(ui->ui_ctlr)) {
+ splx(s);
+ return (EIO);
+ }
+ /*
+ * In case it does not come up, make sure we will be
+ * restarted in 10 seconds. This corresponds to the
+ * 10 second timeouts in udaprobe() and udaslave().
+ */
+ sc->sc_flags |= SC_DOWAKE;
+ timeout(wakeup, (caddr_t) sc, 10 * hz);
+ sleep((caddr_t) sc, PRIBIO);
+ if (sc->sc_state != ST_RUN) {
+ splx(s);
+ printf("uda%d: controller hung\n", ui->ui_ctlr);
+ return (EIO);
+ }
+ untimeout(wakeup, (caddr_t) sc);
+ }
+
+ /*
+ * Wait for the state to settle
+ */
+ ra = &ra_info[unit];
+ while (ra->ra_state != OPEN && ra->ra_state != OPENRAW &&
+ ra->ra_state != CLOSED)
+ if (error = tsleep((caddr_t)ra, (PZERO + 1) | PCATCH,
+ devopn, 0)) {
+ splx(s);
+ return (error);
+ }
+
+ /*
+ * If not on line, or we are not sure of the label, reinitialise
+ * the drive.
+ */
+ if ((ui->ui_flags & UNIT_ONLINE) == 0 ||
+ (ra->ra_state != OPEN && ra->ra_state != OPENRAW))
+ error = uda_rainit(ui, flag);
+ splx(s);
+ if (error)
+ return (error);
+
+ part = udapart(dev);
+ lp = &udalabel[unit];
+ if (part >= lp->d_npartitions)
+ return (ENXIO);
+ /*
+ * Warn if a partition is opened that overlaps another
+ * already open, unless either is the `raw' partition
+ * (whole disk).
+ */
+#define RAWPART 2 /* 'c' partition */ /* XXX */
+ mask = 1 << part;
+ if ((ra->ra_openpart & mask) == 0 && part != RAWPART) {
+ pp = &lp->d_partitions[part];
+ start = pp->p_offset;
+ end = pp->p_offset + pp->p_size;
+ for (pp = lp->d_partitions, i = 0;
+ i < lp->d_npartitions; pp++, i++) {
+ if (pp->p_offset + pp->p_size <= start ||
+ pp->p_offset >= end || i == RAWPART)
+ continue;
+ if (ra->ra_openpart & (1 << i))
+ log(LOG_WARNING,
+ "ra%d%c: overlaps open partition (%c)\n",
+ unit, part + 'a', i + 'a');
+ }
+ }
+ switch (fmt) {
+ case S_IFCHR:
+ ra->ra_copenpart |= mask;
+ break;
+ case S_IFBLK:
+ ra->ra_bopenpart |= mask;
+ break;
+ }
+ ra->ra_openpart |= mask;
+ return (0);
+}
+
+/* ARGSUSED */
+udaclose(dev, flags, fmt)
+ dev_t dev;
+ int flags, fmt;
+{
+ register int unit = udaunit(dev);
+ register struct ra_info *ra = &ra_info[unit];
+ int s, mask = (1 << udapart(dev));
+/* printf("udaclose\n"); */
+ switch (fmt) {
+ case S_IFCHR:
+ ra->ra_copenpart &= ~mask;
+ break;
+ case S_IFBLK:
+ ra->ra_bopenpart &= ~mask;
+ break;
+ }
+ ra->ra_openpart = ra->ra_copenpart | ra->ra_bopenpart;
+
+ /*
+ * Should wait for I/O to complete on this partition even if
+ * others are open, but wait for work on blkflush().
+ */
+ if (ra->ra_openpart == 0) {
+ s = splbio();
+ while (udautab[unit].b_actf)
+ sleep((caddr_t)&udautab[unit], PZERO - 1);
+ splx(s);
+ ra->ra_state = CLOSED;
+ ra->ra_wlabel = 0;
+ }
+ return (0);
+}
+
+/*
+ * Initialise a drive. If it is not already, bring it on line,
+ * and set a timeout on it in case it fails to respond.
+ * When on line, read in the pack label.
+ */
+uda_rainit(ui, flags)
+ volatile struct uba_device *ui;
+ int flags;
+{
+ register struct uda_softc *sc = &uda_softc[ui->ui_ctlr];
+ register struct disklabel *lp;
+ register struct mscp *mp;
+ register int unit = ui->ui_unit;
+ register struct ra_info *ra;
+ char *msg, *readdisklabel();
+ int s, i;
+ volatile int hej;
+ void udastrategy();
+ extern int cold;
+/* printf("uda_rainit\n"); */
+ ra = &ra_info[unit];
+ if ((ui->ui_flags & UNIT_ONLINE) == 0) {
+ mp = mscp_getcp(&sc->sc_mi, MSCP_WAIT);
+ mp->mscp_opcode = M_OP_ONLINE;
+ mp->mscp_unit = ui->ui_slave;
+ mp->mscp_cmdref = (long)&ui->ui_flags;
+ *mp->mscp_addr |= MSCP_OWN | MSCP_INT;
+ ra->ra_state = WANTOPEN;
+ if (!cold)
+ s = splbio();
+ hej = ((struct udadevice *)ui->ui_addr)->udaip;
+
+ if (cold) {
+ i = todr() + 1000;
+ while ((ui->ui_flags & UNIT_ONLINE) == 0)
+ if (todr() > i)
+ break;
+ } else {
+ timeout(wakeup, (caddr_t)&ui->ui_flags, 10 * hz);
+ sleep((caddr_t)&ui->ui_flags, PSWP + 1);
+ splx(s);
+ untimeout(wakeup, (caddr_t)&ui->ui_flags);
+ }
+ if (ra->ra_state != OPENRAW) {
+ ra->ra_state = CLOSED;
+ wakeup((caddr_t)ra);
+ return (EIO);
+ }
+ }
+
+ lp = &udalabel[unit];
+ lp->d_secsize = DEV_BSIZE;
+ lp->d_secperunit = ra->ra_dsize;
+
+ if (flags & O_NDELAY)
+ return (0);
+ ra->ra_state = RDLABEL;
+ /*
+ * Set up default sizes until we have the label, or longer
+ * if there is none. Set secpercyl, as readdisklabel wants
+ * to compute b_cylin (although we do not need it), and set
+ * nsectors in case diskerr is called.
+ */
+ lp->d_secpercyl = 1;
+ lp->d_npartitions = 1;
+ lp->d_secsize = 512;
+ lp->d_secperunit = ra->ra_dsize;
+ lp->d_nsectors = ra->ra_geom.rg_nsectors;
+ lp->d_partitions[0].p_size = lp->d_secperunit;
+ lp->d_partitions[0].p_offset = 0;
+
+ /*
+ * Read pack label.
+ */
+ if ((msg = readdisklabel(udaminor(unit, 0), udastrategy, lp,NULL))
+ != NULL) {
+ if (cold)
+ printf(": %s", msg);
+ else
+ log(LOG_ERR, "ra%d: %s", unit, msg);
+#ifdef COMPAT_42
+ if (udamaptype(unit, lp))
+ ra->ra_state = OPEN;
+ else
+ ra->ra_state = OPENRAW;
+#else
+ ra->ra_state = OPENRAW;
+ uda_makefakelabel(ra, lp);
+#endif
+ } else
+ ra->ra_state = OPEN;
+ wakeup((caddr_t)ra);
+ return (0);
+}
+
+/*
+ * Copy the geometry information for the given ra from a
+ * GET UNIT STATUS response. If check, see if it changed.
+ */
+uda_rasave(unit, mp, check)
+ int unit;
+ register struct mscp *mp;
+ int check;
+{
+ register struct ra_info *ra = &ra_info[unit];
+/* printf("uda_rasave\n"); */
+ if (check && ra->ra_mediaid != mp->mscp_guse.guse_mediaid) {
+ printf("ra%d: changed types! was %d now %d\n", unit,
+ ra->ra_mediaid, mp->mscp_guse.guse_mediaid);
+ ra->ra_state = CLOSED; /* ??? */
+ }
+ /* ra->ra_type = mp->mscp_guse.guse_drivetype; */
+ ra->ra_mediaid = mp->mscp_guse.guse_mediaid;
+ ra->ra_geom.rg_nsectors = mp->mscp_guse.guse_nspt;
+ ra->ra_geom.rg_ngroups = mp->mscp_guse.guse_group;
+ ra->ra_geom.rg_ngpc = mp->mscp_guse.guse_ngpc;
+ ra->ra_geom.rg_ntracks = ra->ra_geom.rg_ngroups * ra->ra_geom.rg_ngpc;
+ /* ra_geom.rg_ncyl cannot be computed until we have ra_dsize */
+#ifdef notyet
+ ra->ra_geom.rg_rctsize = mp->mscp_guse.guse_rctsize;
+ ra->ra_geom.rg_rbns = mp->mscp_guse.guse_nrpt;
+ ra->ra_geom.rg_nrct = mp->mscp_guse.guse_nrct;
+#endif
+}
+
+/*
+ * Queue a transfer request, and if possible, hand it to the controller.
+ *
+ * This routine is broken into two so that the internal version
+ * udastrat1() can be called by the (nonexistent, as yet) bad block
+ * revectoring routine.
+ */
+void
+udastrategy(bp)
+ register struct buf *bp;
+{
+ register int unit;
+ register struct uba_device *ui;
+ register struct ra_info *ra;
+ struct partition *pp;
+ int p;
+ daddr_t sz, maxsz;
+/* printf("udastrategy\n"); */
+ /*
+ * Make sure this is a reasonable drive to use.
+ */
+ if ((unit = udaunit(bp->b_dev)) >= NRA ||
+ (ui = udadinfo[unit]) == NULL || ui->ui_alive == 0 ||
+ (ra = &ra_info[unit])->ra_state == CLOSED) {
+ bp->b_error = ENXIO;
+ goto bad;
+ }
+
+ /*
+ * If drive is open `raw' or reading label, let it at it.
+ */
+ if (ra->ra_state < OPEN) {
+ udastrat1(bp);
+ return;
+ }
+ p = udapart(bp->b_dev);
+ if ((ra->ra_openpart & (1 << p)) == 0) {
+ bp->b_error = ENODEV;
+ goto bad;
+ }
+
+ /*
+ * Determine the size of the transfer, and make sure it is
+ * within the boundaries of the partition.
+ */
+ pp = &udalabel[unit].d_partitions[p];
+ maxsz = pp->p_size;
+ if (pp->p_offset + pp->p_size > ra->ra_dsize)
+ maxsz = ra->ra_dsize - pp->p_offset;
+ sz = (bp->b_bcount + DEV_BSIZE - 1) >> DEV_BSHIFT;
+ if (bp->b_blkno + pp->p_offset <= LABELSECTOR &&
+#if LABELSECTOR != 0
+ bp->b_blkno + pp->p_offset + sz > LABELSECTOR &&
+#endif
+ (bp->b_flags & B_READ) == 0 && ra->ra_wlabel == 0) {
+ bp->b_error = EROFS;
+ goto bad;
+ }
+ if (bp->b_blkno < 0 || bp->b_blkno + sz > maxsz) {
+ /* if exactly at end of disk, return an EOF */
+ if (bp->b_blkno == maxsz) {
+ bp->b_resid = bp->b_bcount;
+ biodone(bp);
+ return;
+ }
+ /* or truncate if part of it fits */
+ sz = maxsz - bp->b_blkno;
+ if (sz <= 0) {
+ bp->b_error = EINVAL; /* or hang it up */
+ goto bad;
+ }
+ bp->b_bcount = sz << DEV_BSHIFT;
+ }
+ udastrat1(bp);
+ return;
+bad:
+ bp->b_flags |= B_ERROR;
+ biodone(bp);
+}
+
+/*
+ * Work routine for udastrategy.
+ */
+udastrat1(bp)
+ register struct buf *bp;
+{
+ register int unit = udaunit(bp->b_dev);
+ register struct uba_ctlr *um;
+ register struct buf *dp;
+ struct uba_device *ui;
+ int s = splbio();
+/* printf("udastrat1\n"); */
+ /*
+ * Append the buffer to the drive queue, and if it is not
+ * already there, the drive to the controller queue. (However,
+ * if the drive queue is marked to be requeued, we must be
+ * awaiting an on line or get unit status command; in this
+ * case, leave it off the controller queue.)
+ */
+ um = (ui = udadinfo[unit])->ui_mi;
+ dp = &udautab[unit];
+ MSCP_APPEND(bp, dp, b_actf);
+ if (dp->b_active == 0 && (ui->ui_flags & UNIT_REQUEUE) == 0) {
+ MSCP_APPEND(dp, &um->um_tab, b_hash.le_next);
+ dp->b_active++;
+ }
+/* Was: MSCP_APPEND(bp, dp, av_forw);
+ if (dp->b_active == 0 && (ui->ui_flags & UNIT_REQUEUE) == 0) {
+ MSCP_APPEND(dp, &um->um_tab, b_forw);
+ dp->b_active++;
+ }
+*/
+ /*
+ * Start activity on the controller. Note that unlike other
+ * Unibus drivers, we must always do this, not just when the
+ * controller is not active.
+ */
+ udastart(um);
+ splx(s);
+}
+
+int
+udaread(dev, uio)
+ dev_t dev;
+ struct uio *uio;
+{
+
+ return (physio(udastrategy, NULL, dev, B_READ, minphys, uio));
+}
+
+int
+udawrite(dev, uio)
+ dev_t dev;
+ struct uio *uio;
+{
+
+ return (physio(udastrategy, NULL, dev, B_WRITE, minphys, uio));
+}
+
+/*
+ * Start up whatever transfers we can find.
+ * Note that udastart() must be called at splbio().
+ */
+udastart(um)
+ register struct uba_ctlr *um;
+{
+ volatile struct uda_softc *sc = &uda_softc[um->um_ctlr];
+ register struct buf *bp, *dp;
+ register struct mscp *mp;
+ struct uba_device *ui;
+ volatile struct udadevice *udaddr;
+ struct partition *pp;
+ int sz;
+ volatile int i;
+/* printf("udastart\n"); */
+#ifdef lint
+ i = 0; i = i;
+#endif
+ /*
+ * If it is not running, try (again and again...) to initialise
+ * it. If it is currently initialising just ignore it for now.
+ */
+ if (sc->sc_state != ST_RUN) {
+ if (sc->sc_state == ST_IDLE && udainit(um->um_ctlr))
+ printf("uda%d: still hung\n", um->um_ctlr);
+ return;
+ }
+
+ /*
+ * If um_cmd is nonzero, this controller is on the Unibus
+ * resource wait queue. It will not help to try more requests;
+ * instead, when the Unibus unblocks and calls udadgo(), we
+ * will call udastart() again.
+ */
+ if (um->um_cmd)
+ return;
+
+ sc->sc_flags |= SC_INSTART;
+ udaddr = (struct udadevice *) um->um_addr;
+
+loop:
+ /*
+ * Service the drive at the head of the queue. It may not
+ * need anything, in which case it might be shutting down
+ * in udaclose().
+ */
+ if ((dp = um->um_tab.b_actf) == NULL)
+ goto out;
+ if ((bp = dp->b_actf) == NULL) {
+ dp->b_active = 0;
+ um->um_tab.b_actf = dp->b_hash.le_next;
+/* Was: um->um_tab.b_actf = dp->b_forw; */
+ if (ra_info[dp - udautab].ra_openpart == 0)
+ wakeup((caddr_t)dp); /* finish close protocol */
+ goto loop;
+ }
+
+ if (udaddr->udasa & UDA_ERR) { /* ctlr fatal error */
+ udasaerror(um, 1);
+ goto out;
+ }
+
+ /*
+ * Get an MSCP packet, then figure out what to do. If
+ * we cannot get a command packet, the command ring may
+ * be too small: We should have at least as many command
+ * packets as credits, for best performance.
+ */
+ if ((mp = mscp_getcp(&sc->sc_mi, MSCP_DONTWAIT)) == NULL) {
+ if (sc->sc_mi.mi_credits > MSCP_MINCREDITS &&
+ (sc->sc_flags & SC_GRIPED) == 0) {
+ log(LOG_NOTICE, "uda%d: command ring too small\n",
+ um->um_ctlr);
+ sc->sc_flags |= SC_GRIPED;/* complain only once */
+ }
+ goto out;
+ }
+
+ /*
+ * Bring the drive on line if it is not already. Get its status
+ * if we do not already have it. Otherwise just start the transfer.
+ */
+ ui = udadinfo[udaunit(bp->b_dev)];
+ if ((ui->ui_flags & UNIT_ONLINE) == 0) {
+ mp->mscp_opcode = M_OP_ONLINE;
+ goto common;
+ }
+ if ((ui->ui_flags & UNIT_HAVESTATUS) == 0) {
+ mp->mscp_opcode = M_OP_GETUNITST;
+common:
+if (ui->ui_flags & UNIT_REQUEUE) panic("udastart");
+ /*
+ * Take the drive off the controller queue. When the
+ * command finishes, make sure the drive is requeued.
+ */
+ um->um_tab.b_actf = dp->b_hash.le_next;
+/* Was: um->um_tab.b_actf = dp->b_forw; */
+ dp->b_active = 0;
+ ui->ui_flags |= UNIT_REQUEUE;
+ mp->mscp_unit = ui->ui_slave;
+ *mp->mscp_addr |= MSCP_OWN | MSCP_INT;
+ sc->sc_flags |= SC_STARTPOLL;
+#ifdef POLLSTATS
+ sc->sc_ncmd++;
+#endif
+ goto loop;
+ }
+
+ pp = &udalabel[ui->ui_unit].d_partitions[udapart(bp->b_dev)];
+ mp->mscp_opcode = (bp->b_flags & B_READ) ? M_OP_READ : M_OP_WRITE;
+ mp->mscp_unit = ui->ui_slave;
+ mp->mscp_seq.seq_lbn = bp->b_blkno + pp->p_offset;
+ sz = (bp->b_bcount + DEV_BSIZE - 1) >> DEV_BSHIFT;
+ mp->mscp_seq.seq_bytecount = bp->b_blkno + sz > pp->p_size ?
+ (pp->p_size - bp->b_blkno) >> DEV_BSHIFT : bp->b_bcount;
+ /* mscp_cmdref is filled in by mscp_go() */
+
+ /*
+ * Drop the packet pointer into the `command' field so udadgo()
+ * can tell what to start. If ubago returns 1, we can do another
+ * transfer. If not, um_cmd will still point at mp, so we will
+ * know that we are waiting for resources.
+ */
+ um->um_cmd = (int)mp;
+ if (ubago(ui))
+ goto loop;
+
+ /*
+ * All done, or blocked in ubago(). If we managed to
+ * issue some commands, start up the beast.
+ */
+out:
+ if (sc->sc_flags & SC_STARTPOLL) {
+#ifdef POLLSTATS
+ udastats.cmd[sc->sc_ncmd]++;
+ sc->sc_ncmd = 0;
+#endif
+ i = ((struct udadevice *)um->um_addr)->udaip;
+ }
+ sc->sc_flags &= ~(SC_INSTART | SC_STARTPOLL);
+}
+
+/*
+ * Start a transfer.
+ *
+ * If we are not called from within udastart(), we must have been
+ * blocked, so call udastart to do more requests (if any). If
+ * this calls us again immediately we will not recurse, because
+ * that time we will be in udastart(). Clever....
+ */
+udadgo(um)
+ register struct uba_ctlr *um;
+{
+ struct uda_softc *sc = &uda_softc[um->um_ctlr];
+ struct mscp *mp = (struct mscp *)um->um_cmd;
+/* printf("udago\n"); */
+ um->um_tab.b_active++; /* another transfer going */
+
+ /*
+ * Fill in the MSCP packet and move the buffer to the
+ * I/O wait queue. Mark the controller as no longer on
+ * the resource queue, and remember to initiate polling.
+ */
+ mp->mscp_seq.seq_buffer = UBAI_ADDR(um->um_ubinfo) |
+ (UBAI_BDP(um->um_ubinfo) << 24);
+ mscp_go(&sc->sc_mi, mp, um->um_ubinfo);
+ um->um_cmd = 0;
+ um->um_ubinfo = 0; /* tyke it awye */
+ sc->sc_flags |= SC_STARTPOLL;
+#ifdef POLLSTATS
+ sc->sc_ncmd++;
+#endif
+ if ((sc->sc_flags & SC_INSTART) == 0)
+ udastart(um);
+}
+
+udaiodone(mi, bp, info)
+ register struct mscp_info *mi;
+ struct buf *bp;
+ int info;
+{
+ register struct uba_ctlr *um = udaminfo[mi->mi_ctlr];
+/* printf("udaiodone\n"); */
+ um->um_ubinfo = info;
+ ubadone(um);
+ biodone(bp);
+ if (um->um_bdp && mi->mi_wtab.b_actf == &mi->mi_wtab)
+ ubarelse(um->um_ubanum, &um->um_bdp);
+/* Was: if (um->um_bdp && mi->mi_wtab.av_forw == &mi->mi_wtab)
+ ubarelse(um->um_ubanum, &um->um_bdp); */
+ um->um_tab.b_active--; /* another transfer done */
+}
+
+static struct saerr {
+ int code; /* error code (including UDA_ERR) */
+ char *desc; /* what it means: Efoo => foo error */
+} saerr[] = {
+ { 0100001, "Eunibus packet read" },
+ { 0100002, "Eunibus packet write" },
+ { 0100003, "EUDA ROM and RAM parity" },
+ { 0100004, "EUDA RAM parity" },
+ { 0100005, "EUDA ROM parity" },
+ { 0100006, "Eunibus ring read" },
+ { 0100007, "Eunibus ring write" },
+ { 0100010, " unibus interrupt master failure" },
+ { 0100011, "Ehost access timeout" },
+ { 0100012, " host exceeded command limit" },
+ { 0100013, " unibus bus master failure" },
+ { 0100014, " DM XFC fatal error" },
+ { 0100015, " hardware timeout of instruction loop" },
+ { 0100016, " invalid virtual circuit id" },
+ { 0100017, "Eunibus interrupt write" },
+ { 0104000, "Efatal sequence" },
+ { 0104040, " D proc ALU" },
+ { 0104041, "ED proc control ROM parity" },
+ { 0105102, "ED proc w/no BD#2 or RAM parity" },
+ { 0105105, "ED proc RAM buffer" },
+ { 0105152, "ED proc SDI" },
+ { 0105153, "ED proc write mode wrap serdes" },
+ { 0105154, "ED proc read mode serdes, RSGEN & ECC" },
+ { 0106040, "EU proc ALU" },
+ { 0106041, "EU proc control reg" },
+ { 0106042, " U proc DFAIL/cntl ROM parity/BD #1 test CNT" },
+ { 0106047, " U proc const PROM err w/D proc running SDI test" },
+ { 0106055, " unexpected trap" },
+ { 0106071, "EU proc const PROM" },
+ { 0106072, "EU proc control ROM parity" },
+ { 0106200, "Estep 1 data" },
+ { 0107103, "EU proc RAM parity" },
+ { 0107107, "EU proc RAM buffer" },
+ { 0107115, " test count wrong (BD 12)" },
+ { 0112300, "Estep 2" },
+ { 0122240, "ENPR" },
+ { 0122300, "Estep 3" },
+ { 0142300, "Estep 4" },
+ { 0, " unknown error code" }
+};
+
+/*
+ * If the error bit was set in the controller status register, gripe,
+ * then (optionally) reset the controller and requeue pending transfers.
+ */
+udasaerror(um, doreset)
+ register struct uba_ctlr *um;
+ int doreset;
+{
+ register int code = ((struct udadevice *)um->um_addr)->udasa;
+ register struct saerr *e;
+/*printf("udasaerror\n"); */
+ if ((code & UDA_ERR) == 0)
+ return;
+ for (e = saerr; e->code; e++)
+ if (e->code == code)
+ break;
+ printf("uda%d: controller error, sa=0%o (%s%s)\n",
+ um->um_ctlr, code, e->desc + 1,
+ *e->desc == 'E' ? " error" : "");
+ if (doreset) {
+ mscp_requeue(&uda_softc[um->um_ctlr].sc_mi);
+ (void) udainit(um->um_ctlr);
+ }
+}
+
+/*
+ * Interrupt routine. Depending on the state of the controller,
+ * continue initialisation, or acknowledge command and response
+ * interrupts, and process responses.
+ */
+udaintr(vektor,level,uba,ctlr)
+{
+ struct uba_ctlr *um = udaminfo[ctlr];
+ volatile struct uda_softc *sc = &uda_softc[ctlr];
+ volatile struct udadevice *udaddr = (struct udadevice *)um->um_addr;
+ struct uda *ud;
+ struct mscp *mp;
+ volatile int i, wait_status;
+ extern int cpu_type;
+
+#ifdef QBA
+ if(cpunumber == VAX_78032)
+ splx(sc->sc_ipl); /* Qbus interrupt protocol is odd */
+#endif
+ sc->sc_wticks = 0; /* reset interrupt watchdog */
+
+ /*
+ * Combinations during steps 1, 2, and 3: STEPnMASK
+ * corresponds to which bits should be tested;
+ * STEPnGOOD corresponds to the pattern that should
+ * appear after the interrupt from STEPn initialisation.
+ * All steps test the bits in ALLSTEPS.
+ */
+#define ALLSTEPS (UDA_ERR|UDA_STEP4|UDA_STEP3|UDA_STEP2|UDA_STEP1)
+
+#define STEP1MASK (ALLSTEPS | UDA_IE | UDA_NCNRMASK)
+#define STEP1GOOD (UDA_STEP2 | UDA_IE | (NCMDL2 << 3) | NRSPL2)
+
+#define STEP2MASK (ALLSTEPS | UDA_IE | UDA_IVECMASK)
+#define STEP2GOOD (UDA_STEP3 | UDA_IE | (sc->sc_ivec >> 2))
+
+#define STEP3MASK ALLSTEPS
+#define STEP3GOOD UDA_STEP4
+
+ switch (sc->sc_state) {
+
+ case ST_IDLE:
+ /*
+ * Ignore unsolicited interrupts.
+ */
+ log(LOG_WARNING, "uda%d: stray intr\n", ctlr);
+ return;
+
+ case ST_STEP1:
+ /*
+ * Begin step two initialisation.
+ */
+ i = 0;
+ Wait_step(STEP1MASK, STEP1GOOD, wait_status);
+ if (!wait_status) {
+initfailed:
+ printf("uda%d: init step %d failed, sa=%b\n",
+ ctlr, i, udaddr->udasa, udasr_bits);
+ udasaerror(um, 0);
+ sc->sc_state = ST_IDLE;
+ if (sc->sc_flags & SC_DOWAKE) {
+ sc->sc_flags &= ~SC_DOWAKE;
+ wakeup((caddr_t)sc);
+ }
+ return;
+ }
+ udaddr->udasa = (int)&sc->sc_uda->uda_ca.ca_rspdsc[0] |
+ (MACHID(cpu_type) == VAX_780 || MACHID(cpu_type)
+ == VAX_8600 ? UDA_PI : 0);
+ sc->sc_state = ST_STEP2;
+ return;
+
+ case ST_STEP2:
+ /*
+ * Begin step 3 initialisation.
+ */
+ i = 2;
+ Wait_step(STEP2MASK, STEP2GOOD, wait_status);
+ if (!wait_status)
+ goto initfailed;
+
+ udaddr->udasa = ((int)&sc->sc_uda->uda_ca.ca_rspdsc[0]) >> 16;
+ sc->sc_state = ST_STEP3;
+ return;
+
+ case ST_STEP3:
+ /*
+ * Set controller characteristics (finish initialisation).
+ */
+ i = 3;
+ Wait_step(STEP3MASK, STEP3GOOD, wait_status);
+ if (!wait_status)
+ goto initfailed;
+
+ i = udaddr->udasa & 0xff;
+ if (i != sc->sc_micro) {
+ sc->sc_micro = i;
+ printf("uda%d: version %d model %d\n",
+ ctlr, i & 0xf, i >> 4);
+ }
+
+ /*
+ * Present the burst size, then remove it. Why this
+ * should be done this way, I have no idea.
+ *
+ * Note that this assumes udaburst[ctlr] > 0.
+ */
+ udaddr->udasa = UDA_GO | (udaburst[ctlr] - 1) << 2;
+ udaddr->udasa = UDA_GO;
+ printf("uda%d: DMA burst size set to %d\n",
+ ctlr, udaburst[ctlr]);
+
+ udainitds(ctlr); /* initialise data structures */
+
+ /*
+ * Before we can get a command packet, we need some
+ * credits. Fake some up to keep mscp_getcp() happy,
+ * get a packet, and cancel all credits (the right
+ * number should come back in the response to the
+ * SCC packet).
+ */
+ sc->sc_mi.mi_credits = MSCP_MINCREDITS + 1;
+ mp = mscp_getcp(&sc->sc_mi, MSCP_DONTWAIT);
+ if (mp == NULL) /* `cannot happen' */
+ panic("udaintr");
+ sc->sc_mi.mi_credits = 0;
+ mp->mscp_opcode = M_OP_SETCTLRC;
+ mp->mscp_unit = 0;
+ mp->mscp_sccc.sccc_ctlrflags = M_CF_ATTN | M_CF_MISC |
+ M_CF_THIS;
+ *mp->mscp_addr |= MSCP_OWN | MSCP_INT;
+ i = udaddr->udaip;
+ sc->sc_state = ST_SETCHAR;
+ return;
+
+ case ST_SETCHAR:
+ case ST_RUN:
+ /*
+ * Handle Set Ctlr Characteristics responses and operational
+ * responses (via mscp_dorsp).
+ */
+ break;
+
+ default:
+ printf("uda%d: driver bug, state %d\n", ctlr, sc->sc_state);
+ panic("udastate");
+ }
+
+ if (udaddr->udasa & UDA_ERR) { /* ctlr fatal error */
+ udasaerror(um, 1);
+ return;
+ }
+
+ ud = &uda[ctlr];
+
+ /*
+ * Handle buffer purge requests.
+ */
+ if (ud->uda_ca.ca_bdp) {
+ UBAPURGE(um->um_hd->uh_uba, ud->uda_ca.ca_bdp);
+ ud->uda_ca.ca_bdp = 0;
+ udaddr->udasa = 0; /* signal purge complete */
+ }
+
+ /*
+ * Check for response and command ring transitions.
+ */
+ if (ud->uda_ca.ca_rspint) {
+ ud->uda_ca.ca_rspint = 0;
+ mscp_dorsp(&sc->sc_mi);
+ }
+ if (ud->uda_ca.ca_cmdint) {
+ ud->uda_ca.ca_cmdint = 0;
+ MSCP_DOCMD(&sc->sc_mi);
+ }
+ udastart(um);
+}
+
+/*
+ * Initialise the various data structures that control the UDA50.
+ */
+udainitds(ctlr)
+ int ctlr;
+{
+ register struct uda *ud = &uda[ctlr];
+ register struct uda *uud = uda_softc[ctlr].sc_uda;
+ register struct mscp *mp;
+ register int i;
+/* printf("udainitds\n"); */
+ for (i = 0, mp = ud->uda_rsp; i < NRSP; i++, mp++) {
+ ud->uda_ca.ca_rspdsc[i] = MSCP_OWN | MSCP_INT |
+ (long)&uud->uda_rsp[i].mscp_cmdref;
+ mp->mscp_addr = &ud->uda_ca.ca_rspdsc[i];
+ mp->mscp_msglen = MSCP_MSGLEN;
+ }
+ for (i = 0, mp = ud->uda_cmd; i < NCMD; i++, mp++) {
+ ud->uda_ca.ca_cmddsc[i] = MSCP_INT |
+ (long)&uud->uda_cmd[i].mscp_cmdref;
+ mp->mscp_addr = &ud->uda_ca.ca_cmddsc[i];
+ mp->mscp_msglen = MSCP_MSGLEN;
+ }
+}
+
+/*
+ * Handle an error datagram.
+ */
+udadgram(mi, mp)
+ struct mscp_info *mi;
+ struct mscp *mp;
+{
+/* printf("udadgram\n"); */
+ mscp_decodeerror(mi->mi_md->md_mname, mi->mi_ctlr, mp);
+ /*
+ * SDI status information bytes 10 and 11 are the microprocessor
+ * error code and front panel code respectively. These vary per
+ * drive type and are printed purely for field service information.
+ */
+ if (mp->mscp_format == M_FM_SDI)
+ printf("\tsdi uproc error code 0x%x, front panel code 0x%x\n",
+ mp->mscp_erd.erd_sdistat[10],
+ mp->mscp_erd.erd_sdistat[11]);
+}
+
+/*
+ * The Set Controller Characteristics command finished.
+ * Record the new state of the controller.
+ */
+udactlrdone(mi, mp)
+ register struct mscp_info *mi;
+ struct mscp *mp;
+{
+ register struct uda_softc *sc = &uda_softc[mi->mi_ctlr];
+/* printf("udactlrdone\n"); */
+ if ((mp->mscp_status & M_ST_MASK) == M_ST_SUCCESS)
+ sc->sc_state = ST_RUN;
+ else {
+ printf("uda%d: SETCTLRC failed: ",
+ mi->mi_ctlr, mp->mscp_status);
+ mscp_printevent(mp);
+ sc->sc_state = ST_IDLE;
+ }
+ if (sc->sc_flags & SC_DOWAKE) {
+ sc->sc_flags &= ~SC_DOWAKE;
+ wakeup((caddr_t)sc);
+ }
+}
+
+/*
+ * Received a response from an as-yet unconfigured drive. Configure it
+ * in, if possible.
+ */
+udaunconf(mi, mp)
+ struct mscp_info *mi;
+ register struct mscp *mp;
+{
+/* printf("udaunconf\n"); */
+ /*
+ * If it is a slave response, copy it to udaslavereply for
+ * udaslave() to look at.
+ */
+ if (mp->mscp_opcode == (M_OP_GETUNITST | M_OP_END) &&
+ (uda_softc[mi->mi_ctlr].sc_flags & SC_INSLAVE) != 0) {
+ bcopy(mp, &udaslavereply, sizeof(struct mscp));
+/* udaslavereply = *mp; */
+ return (MSCP_DONE);
+ }
+
+ /*
+ * Otherwise, it had better be an available attention response.
+ */
+ if (mp->mscp_opcode != M_OP_AVAILATTN)
+ return (MSCP_FAILED);
+
+ /* do what autoconf does */
+ return (MSCP_FAILED); /* not yet, arwhite, not yet */
+}
+
+/*
+ * A drive came on line. Check its type and size. Return DONE if
+ * we think the drive is truly on line. In any case, awaken anyone
+ * sleeping on the drive on-line-ness.
+ */
+udaonline(ui, mp)
+ register struct uba_device *ui;
+ struct mscp *mp;
+{
+ register struct ra_info *ra = &ra_info[ui->ui_unit];
+/* printf("udaonline\n"); */
+ wakeup((caddr_t)&ui->ui_flags);
+ if ((mp->mscp_status & M_ST_MASK) != M_ST_SUCCESS) {
+ if (!cold)
+ printf("uda%d: ra%d", ui->ui_ctlr, ui->ui_unit);
+ printf(": attempt to bring on line failed: ");
+ mscp_printevent(mp);
+ ra->ra_state = CLOSED;
+ return (MSCP_FAILED);
+ }
+
+ ra->ra_state = OPENRAW;
+ ra->ra_dsize = (daddr_t)mp->mscp_onle.onle_unitsize;
+ if (!cold)
+ printf("ra%d: uda%d, unit %d, size = %d sectors\n", ui->ui_unit,
+ ui->ui_ctlr, mp->mscp_unit, ra->ra_dsize);
+ /* can now compute ncyl */
+ ra->ra_geom.rg_ncyl = ra->ra_dsize / ra->ra_geom.rg_ntracks /
+ ra->ra_geom.rg_nsectors;
+ return (MSCP_DONE);
+}
+
+/*
+ * We got some (configured) unit's status. Return DONE if it succeeded.
+ */
+udagotstatus(ui, mp)
+ register struct uba_device *ui;
+ register struct mscp *mp;
+{
+/* printf("udagotstatus\n"); */
+ if ((mp->mscp_status & M_ST_MASK) != M_ST_SUCCESS) {
+ printf("uda%d: attempt to get status for ra%d failed: ",
+ ui->ui_ctlr, ui->ui_unit);
+ mscp_printevent(mp);
+ return (MSCP_FAILED);
+ }
+ /* record for (future) bad block forwarding and whatever else */
+ uda_rasave(ui->ui_unit, mp, 1);
+ return (MSCP_DONE);
+}
+
+/*
+ * A transfer failed. We get a chance to fix or restart it.
+ * Need to write the bad block forwaring code first....
+ */
+/*ARGSUSED*/
+udaioerror(ui, mp, bp)
+ register struct uba_device *ui;
+ register struct mscp *mp;
+ struct buf *bp;
+{
+/* printf("udaioerror\n"); */
+ if (mp->mscp_flags & M_EF_BBLKR) {
+ /*
+ * A bad block report. Eventually we will
+ * restart this transfer, but for now, just
+ * log it and give up.
+ */
+ log(LOG_ERR, "ra%d: bad block report: %d%s\n",
+ ui->ui_unit, mp->mscp_seq.seq_lbn,
+ mp->mscp_flags & M_EF_BBLKU ? " + others" : "");
+ } else {
+ /*
+ * What the heck IS a `serious exception' anyway?
+ * IT SURE WOULD BE NICE IF DEC SOLD DOCUMENTATION
+ * FOR THEIR OWN CONTROLLERS.
+ */
+ if (mp->mscp_flags & M_EF_SEREX)
+ log(LOG_ERR, "ra%d: serious exception reported\n",
+ ui->ui_unit);
+ }
+ return (MSCP_FAILED);
+}
+
+/*
+ * A replace operation finished.
+ */
+/*ARGSUSED*/
+udareplace(ui, mp)
+ struct uba_device *ui;
+ struct mscp *mp;
+{
+
+ panic("udareplace");
+}
+
+/*
+ * A bad block related operation finished.
+ */
+/*ARGSUSED*/
+udabb(ui, mp, bp)
+ struct uba_device *ui;
+ struct mscp *mp;
+ struct buf *bp;
+{
+
+ panic("udabb");
+}
+
+
+/*
+ * I/O controls.
+ */
+udaioctl(dev, cmd, data, flag)
+ dev_t dev;
+ int cmd;
+ caddr_t data;
+ int flag;
+{
+ register int unit = udaunit(dev);
+ register struct disklabel *lp;
+ register struct ra_info *ra = &ra_info[unit];
+ int error = 0;
+/* printf("udaioctl\n"); */
+ lp = &udalabel[unit];
+
+ switch (cmd) {
+
+ case DIOCGDINFO:
+ *(struct disklabel *)data = *lp;
+ break;
+
+ case DIOCGPART:
+ ((struct partinfo *)data)->disklab = lp;
+ ((struct partinfo *)data)->part =
+ &lp->d_partitions[udapart(dev)];
+ break;
+
+ case DIOCSDINFO:
+ if ((flag & FWRITE) == 0)
+ error = EBADF;
+ else
+ error = setdisklabel(lp, (struct disklabel *)data,
+ (ra->ra_state == OPENRAW) ? 0 : ra->ra_openpart,0);
+ break;
+
+ case DIOCWLABEL:
+ if ((flag & FWRITE) == 0)
+ error = EBADF;
+ else
+ ra->ra_wlabel = *(int *)data;
+ break;
+
+ case DIOCWDINFO:
+ if ((flag & FWRITE) == 0)
+ error = EBADF;
+ else if ((error = setdisklabel(lp, (struct disklabel *)data,
+ (ra->ra_state == OPENRAW) ? 0 : ra->ra_openpart,0)) == 0) {
+ int wlab;
+
+ ra->ra_state = OPEN;
+ /* simulate opening partition 0 so write succeeds */
+ ra->ra_openpart |= (1 << 0); /* XXX */
+ wlab = ra->ra_wlabel;
+ ra->ra_wlabel = 1;
+ error = writedisklabel(dev, udastrategy, lp,0);
+ ra->ra_openpart = ra->ra_copenpart | ra->ra_bopenpart;
+ ra->ra_wlabel = wlab;
+ }
+ break;
+
+#ifdef notyet
+ case UDAIOCREPLACE:
+ /*
+ * Initiate bad block replacement for the given LBN.
+ * (Should we allow modifiers?)
+ */
+ error = EOPNOTSUPP;
+ break;
+
+ case UDAIOCGMICRO:
+ /*
+ * Return the microcode revision for the UDA50 running
+ * this drive.
+ */
+ *(int *)data = uda_softc[uddinfo[unit]->ui_ctlr].sc_micro;
+ break;
+#endif
+
+ default:
+ error = ENOTTY;
+ break;
+ }
+ return (error);
+}
+
+/*
+ * A Unibus reset has occurred on UBA uban. Reinitialise the controller(s)
+ * on that Unibus, and requeue outstanding I/O.
+ */
+udareset(uban)
+ int uban;
+{
+ register struct uba_ctlr *um;
+ register struct uda_softc *sc;
+ register int ctlr;
+/* printf("udareset\n"); */
+ for (ctlr = 0, sc = uda_softc; ctlr < NUDA; ctlr++, sc++) {
+ if ((um = udaminfo[ctlr]) == NULL || um->um_ubanum != uban ||
+ um->um_alive == 0)
+ continue;
+ printf(" uda%d", ctlr);
+
+ /*
+ * Our BDP (if any) is gone; our command (if any) is
+ * flushed; the device is no longer mapped; and the
+ * UDA50 is not yet initialised.
+ */
+ if (um->um_bdp) {
+ printf("<%d>", UBAI_BDP(um->um_bdp));
+ um->um_bdp = 0;
+ }
+ um->um_ubinfo = 0;
+ um->um_cmd = 0;
+ sc->sc_flags &= ~SC_MAPPED;
+ sc->sc_state = ST_IDLE;
+
+ /* reset queues and requeue pending transfers */
+ mscp_requeue(&sc->sc_mi);
+
+ /*
+ * If it fails to initialise we will notice later and
+ * try again (and again...). Do not call udastart()
+ * here; it will be done after the controller finishes
+ * initialisation.
+ */
+ if (udainit(ctlr))
+ printf(" (hung)");
+ }
+}
+
+/*
+ * Watchdog timer: If the controller is active, and no interrupts
+ * have occurred for 30 seconds, assume it has gone away.
+ */
+void
+udawatch()
+{
+ register int i;
+ register struct uba_ctlr *um;
+ register struct uda_softc *sc;
+ timeout(udawatch, (caddr_t) 0, hz); /* every second */
+ for (i = 0, sc = uda_softc; i < NUDA; i++, sc++) {
+ if ((um = udaminfo[i]) == 0 || !um->um_alive)
+ continue;
+ if (sc->sc_state == ST_IDLE)
+ continue;
+ if (sc->sc_state == ST_RUN && !um->um_tab.b_active)
+ sc->sc_wticks = 0;
+ else if (++sc->sc_wticks >= 30) {
+ sc->sc_wticks = 0;
+ printf("uda%d: lost interrupt\n", i);
+ ubareset(um->um_ubanum);
+ }
+ }
+}
+
+/*
+ * Do a panic dump. We set up the controller for one command packet
+ * and one response packet, for which we use `struct uda1'.
+ */
+struct uda1 {
+ struct uda1ca uda1_ca; /* communications area */
+ struct mscp uda1_rsp; /* response packet */
+ struct mscp uda1_cmd; /* command packet */
+} uda1;
+
+#define DBSIZE 32 /* dump 16K at a time */
+
+udadump(dev)
+ dev_t dev;
+{
+ struct udadevice *udaddr;
+ struct uda1 *ud_ubaddr;
+ char *start;
+ int num, blk, unit, maxsz, blkoff, reg;
+ struct partition *pp;
+ struct uba_regs *uba;
+ struct uba_device *ui;
+ struct uda1 *ud;
+ struct pte *io;
+ int i;
+
+ /*
+ * Make sure the device is a reasonable place on which to dump.
+ */
+ unit = udaunit(dev);
+ if (unit >= NRA)
+ return (ENXIO);
+#define phys(cast, addr) ((cast) ((int)addr & 0x7fffffff))
+ ui = phys(struct uba_device *, udadinfo[unit]);
+ if (ui == NULL || ui->ui_alive == 0)
+ return (ENXIO);
+
+ /*
+ * Find and initialise the UBA; get the physical address of the
+ * device registers, and of communications area and command and
+ * response packet.
+ */
+ uba = phys(struct uba_hd *, ui->ui_hd)->uh_physuba;
+ ubainit(uba);
+ udaddr = (struct udadevice *)ui->ui_physaddr;
+ ud = phys(struct uda1 *, &uda1);
+printf("H{r.\n");
+ /*
+ * Map the ca+packets into Unibus I/O space so the UDA50 can get
+ * at them. Use the registers at the end of the Unibus map (since
+ * we will use the registers at the beginning to map the memory
+ * we are dumping).
+ */
+ num = btoc(sizeof(struct uda1)) + 1;
+ reg = NUBMREG - num;
+ io = (void *)&uba->uba_map[reg];
+ for (i = 0; i < num; i++)
+ *(int *)io++ = UBAMR_MRV | (vax_btop(ud) + i);
+ ud_ubaddr = (struct uda1 *)(((int)ud & PGOFSET) | (reg << 9));
+
+ /*
+ * Initialise the controller, with one command and one response
+ * packet.
+ */
+ udaddr->udaip = 0;
+ if (udadumpwait(udaddr, UDA_STEP1))
+ return (EFAULT);
+ udaddr->udasa = UDA_ERR;
+ if (udadumpwait(udaddr, UDA_STEP2))
+ return (EFAULT);
+ udaddr->udasa = (int)&ud_ubaddr->uda1_ca.ca_rspdsc;
+ if (udadumpwait(udaddr, UDA_STEP3))
+ return (EFAULT);
+ udaddr->udasa = ((int)&ud_ubaddr->uda1_ca.ca_rspdsc) >> 16;
+ if (udadumpwait(udaddr, UDA_STEP4))
+ return (EFAULT);
+ uda_softc[ui->ui_ctlr].sc_micro = udaddr->udasa & 0xff;
+ udaddr->udasa = UDA_GO;
+
+ /*
+ * Set up the command and response descriptor, then set the
+ * controller characteristics and bring the drive on line.
+ * Note that all uninitialised locations in uda1_cmd are zero.
+ */
+ ud->uda1_ca.ca_rspdsc = (long)&ud_ubaddr->uda1_rsp.mscp_cmdref;
+ ud->uda1_ca.ca_cmddsc = (long)&ud_ubaddr->uda1_cmd.mscp_cmdref;
+ /* ud->uda1_cmd.mscp_sccc.sccc_ctlrflags = 0; */
+ /* ud->uda1_cmd.mscp_sccc.sccc_version = 0; */
+ if (udadumpcmd(M_OP_SETCTLRC, ud, ui))
+ return (EFAULT);
+ ud->uda1_cmd.mscp_unit = ui->ui_slave;
+ if (udadumpcmd(M_OP_ONLINE, ud, ui))
+ return (EFAULT);
+
+ pp = phys(struct partition *,
+ &udalabel[unit].d_partitions[udapart(dev)]);
+ maxsz = pp->p_size;
+ blkoff = pp->p_offset;
+
+ /*
+ * Dump all of physical memory, or as much as will fit in the
+ * space provided.
+ */
+ start = 0;
+ printf("Dumpar {r inte implementerade {n :) \n");
+ asm("halt");
+/* num = maxfree; */
+ if (dumplo + num >= maxsz)
+ num = maxsz - dumplo;
+ blkoff += dumplo;
+
+ /*
+ * Write out memory, DBSIZE pages at a time.
+ * N.B.: this code depends on the fact that the sector
+ * size == the page size.
+ */
+ while (num > 0) {
+ blk = num > DBSIZE ? DBSIZE : num;
+ io = (void *)uba->uba_map;
+ /*
+ * Map in the pages to write, leaving an invalid entry
+ * at the end to guard against wild Unibus transfers.
+ * Then do the write.
+ */
+ for (i = 0; i < blk; i++)
+ *(int *)io++ = UBAMR_MRV | (vax_btop(start) + i);
+ *(int *)io = 0;
+ ud->uda1_cmd.mscp_unit = ui->ui_slave;
+ ud->uda1_cmd.mscp_seq.seq_lbn = vax_btop(start) + blkoff;
+ ud->uda1_cmd.mscp_seq.seq_bytecount = blk << PGSHIFT;
+ if (udadumpcmd(M_OP_WRITE, ud, ui))
+ return (EIO);
+ start += blk << PGSHIFT;
+ num -= blk;
+ }
+ return (0); /* made it! */
+}
+
+/*
+ * Wait for some of the bits in `bits' to come on. If the error bit
+ * comes on, or ten seconds pass without response, return true (error).
+ */
+udadumpwait(udaddr, bits)
+ register struct udadevice *udaddr;
+ register int bits;
+{
+ register int timo = todr() + 1000;
+
+ while ((udaddr->udasa & bits) == 0) {
+ if (udaddr->udasa & UDA_ERR) {
+ printf("udasa=%b\ndump ", udaddr->udasa, udasr_bits);
+ return (1);
+ }
+ if (todr() >= timo) {
+ printf("timeout\ndump ");
+ return (1);
+ }
+ }
+ return (0);
+}
+
+/*
+ * Feed a command to the UDA50, wait for its response, and return
+ * true iff something went wrong.
+ */
+udadumpcmd(op, ud, ui)
+ int op;
+ register struct uda1 *ud;
+ struct uba_device *ui;
+{
+ volatile struct udadevice *udaddr;
+ volatile int n;
+#define mp (&ud->uda1_rsp)
+
+ udaddr = (struct udadevice *)ui->ui_physaddr;
+ ud->uda1_cmd.mscp_opcode = op;
+ ud->uda1_cmd.mscp_msglen = MSCP_MSGLEN;
+ ud->uda1_rsp.mscp_msglen = MSCP_MSGLEN;
+ ud->uda1_ca.ca_rspdsc |= MSCP_OWN | MSCP_INT;
+ ud->uda1_ca.ca_cmddsc |= MSCP_OWN | MSCP_INT;
+ if (udaddr->udasa & UDA_ERR) {
+ printf("udasa=%b\ndump ", udaddr->udasa, udasr_bits);
+ return (1);
+ }
+ n = udaddr->udaip;
+ n = todr() + 1000;
+ for (;;) {
+ if (todr() > n) {
+ printf("timeout\ndump ");
+ return (1);
+ }
+ if (ud->uda1_ca.ca_cmdint)
+ ud->uda1_ca.ca_cmdint = 0;
+ if (ud->uda1_ca.ca_rspint == 0)
+ continue;
+ ud->uda1_ca.ca_rspint = 0;
+ if (mp->mscp_opcode == (op | M_OP_END))
+ break;
+ printf("\n");
+ switch (MSCP_MSGTYPE(mp->mscp_msgtc)) {
+
+ case MSCPT_SEQ:
+ printf("sequential");
+ break;
+
+ case MSCPT_DATAGRAM:
+ mscp_decodeerror("uda", ui->ui_ctlr, mp);
+ printf("datagram");
+ break;
+
+ case MSCPT_CREDITS:
+ printf("credits");
+ break;
+
+ case MSCPT_MAINTENANCE:
+ printf("maintenance");
+ break;
+
+ default:
+ printf("unknown (type 0x%x)",
+ MSCP_MSGTYPE(mp->mscp_msgtc));
+ break;
+ }
+ printf(" ignored\ndump ");
+ ud->uda1_ca.ca_rspdsc |= MSCP_OWN | MSCP_INT;
+ }
+ if ((mp->mscp_status & M_ST_MASK) != M_ST_SUCCESS) {
+ printf("error: op 0x%x => 0x%x status 0x%x\ndump ", op,
+ mp->mscp_opcode, mp->mscp_status);
+ return (1);
+ }
+ return (0);
+#undef mp
+}
+
+/*
+ * Return the size of a partition, if known, or -1 if not.
+ */
+udasize(dev)
+ dev_t dev;
+{
+ register int unit = udaunit(dev);
+ register struct uba_device *ui;
+
+ if (unit >= NRA || (ui = udadinfo[unit]) == NULL ||
+ ui->ui_alive == 0 || (ui->ui_flags & UNIT_ONLINE) == 0 ||
+ ra_info[unit].ra_state != OPEN)
+ return (-1);
+ return ((int)udalabel[unit].d_partitions[udapart(dev)].p_size);
+}
+
+#ifdef COMPAT_42
+/*
+ * Tables mapping unlabelled drives.
+ */
+struct size {
+ daddr_t nblocks;
+ daddr_t blkoff;
+} ra60_sizes[8] = {
+ 15884, 0, /* A=sectors 0 thru 15883 */
+ 33440, 15884, /* B=sectors 15884 thru 49323 */
+ 400176, 0, /* C=sectors 0 thru 400175 */
+ 82080, 49324, /* 4.2 G => D=sectors 49324 thru 131403 */
+ 268772, 131404, /* 4.2 H => E=sectors 131404 thru 400175 */
+ 350852, 49324, /* F=sectors 49324 thru 400175 */
+ 157570, 242606, /* UCB G => G=sectors 242606 thru 400175 */
+ 193282, 49324, /* UCB H => H=sectors 49324 thru 242605 */
+}, ra70_sizes[8] = {
+ 15884, 0, /* A=blk 0 thru 15883 */
+ 33440, 15972, /* B=blk 15972 thru 49323 */
+ -1, 0, /* C=blk 0 thru end */
+ 15884, 341220, /* D=blk 341220 thru 357103 */
+ 55936, 357192, /* E=blk 357192 thru 413127 */
+ -1, 413457, /* F=blk 413457 thru end */
+ -1, 341220, /* G=blk 341220 thru end */
+ 291346, 49731, /* H=blk 49731 thru 341076 */
+}, ra80_sizes[8] = {
+ 15884, 0, /* A=sectors 0 thru 15883 */
+ 33440, 15884, /* B=sectors 15884 thru 49323 */
+ 242606, 0, /* C=sectors 0 thru 242605 */
+ 0, 0, /* D=unused */
+ 193282, 49324, /* UCB H => E=sectors 49324 thru 242605 */
+ 82080, 49324, /* 4.2 G => F=sectors 49324 thru 131403 */
+ 192696, 49910, /* G=sectors 49910 thru 242605 */
+ 111202, 131404, /* 4.2 H => H=sectors 131404 thru 242605 */
+}, ra81_sizes[8] ={
+/*
+ * These are the new standard partition sizes for ra81's.
+ * An RA_COMPAT system is compiled with D, E, and F corresponding
+ * to the 4.2 partitions for G, H, and F respectively.
+ */
+#ifndef UCBRA
+ 15884, 0, /* A=sectors 0 thru 15883 */
+ 66880, 16422, /* B=sectors 16422 thru 83301 */
+ 891072, 0, /* C=sectors 0 thru 891071 */
+#ifdef RA_COMPAT
+ 82080, 49324, /* 4.2 G => D=sectors 49324 thru 131403 */
+ 759668, 131404, /* 4.2 H => E=sectors 131404 thru 891071 */
+ 478582, 412490, /* 4.2 F => F=sectors 412490 thru 891071 */
+#else
+ 15884, 375564, /* D=sectors 375564 thru 391447 */
+ 307200, 391986, /* E=sectors 391986 thru 699185 */
+ 191352, 699720, /* F=sectors 699720 thru 891071 */
+#endif RA_COMPAT
+ 515508, 375564, /* G=sectors 375564 thru 891071 */
+ 291346, 83538, /* H=sectors 83538 thru 374883 */
+
+/*
+ * These partitions correspond to the sizes used by sites at Berkeley,
+ * and by those sites that have received copies of the Berkeley driver
+ * with deltas 6.2 or greater (11/15/83).
+ */
+#else UCBRA
+
+ 15884, 0, /* A=sectors 0 thru 15883 */
+ 33440, 15884, /* B=sectors 15884 thru 49323 */
+ 891072, 0, /* C=sectors 0 thru 891071 */
+ 15884, 242606, /* D=sectors 242606 thru 258489 */
+ 307200, 258490, /* E=sectors 258490 thru 565689 */
+ 325382, 565690, /* F=sectors 565690 thru 891071 */
+ 648466, 242606, /* G=sectors 242606 thru 891071 */
+ 193282, 49324, /* H=sectors 49324 thru 242605 */
+
+#endif UCBRA
+}, ra82_sizes[8] = {
+ 15884, 0, /* A=blk 0 thru 15883 */
+ 66880, 16245, /* B=blk 16245 thru 83124 */
+ -1, 0, /* C=blk 0 thru end */
+ 15884, 375345, /* D=blk 375345 thru 391228 */
+ 307200, 391590, /* E=blk 391590 thru 698789 */
+ -1, 699390, /* F=blk 699390 thru end */
+ -1, 375345, /* G=blk 375345 thru end */
+ 291346, 83790, /* H=blk 83790 thru 375135 */
+}, ra90_sizes[8] = {
+ 15884, 0, /* A=sectors 0 thru 15883 */
+ 66880, 16146, /* B=sectors 16146 thru 83025 */
+ 2376153,0, /* C=sectors 0 thru 2376152 */
+ 15884, 374946, /* D=sectors 374946 thru 390829 */
+ 307200, 391092, /* E=sectors 391092 thru 698291 */
+ 1677390,698763, /* F=sectors 698763 thru 2376152 */
+ 2001207,374946, /* G=sectors 374946 thru 2376152 */
+ 291346, 83421, /* H=sectors 83421 thru 374766 */
+}, ra92_sizes[8] = {
+ 15884, 0, /* A=sectors 0 thru 15883 */
+ 66880, 16146, /* B=sectors 16146 thru 83025 */
+ 2941263,0, /* C=sectors 0 thru 2941262 */
+ 15884, 374946, /* D=sectors 374946 thru 390829 */
+ 307200, 391092, /* E=sectors 391092 thru 698291 */
+ 2242500,698763, /* F=sectors 698763 thru 2941262 */
+ 2566317,374946, /* G=sectors 374946 thru 2941262 */
+ 291346, 83421, /* H=sectors 83421 thru 374766 */
+}, rc25_sizes[8] = {
+ 15884, 0, /* A=blk 0 thru 15883 */
+ 10032, 15884, /* B=blk 15884 thru 49323 */
+ -1, 0, /* C=blk 0 thru end */
+ 0, 0, /* D=blk 340670 thru 356553 */
+ 0, 0, /* E=blk 356554 thru 412489 */
+ 0, 0, /* F=blk 412490 thru end */
+ -1, 25916, /* G=blk 49324 thru 131403 */
+ 0, 0, /* H=blk 131404 thru end */
+}, rd52_sizes[8] = {
+ 15884, 0, /* A=blk 0 thru 15883 */
+ 9766, 15884, /* B=blk 15884 thru 25649 */
+ -1, 0, /* C=blk 0 thru end */
+ 0, 0, /* D=unused */
+ 0, 0, /* E=unused */
+ 0, 0, /* F=unused */
+ -1, 25650, /* G=blk 25650 thru end */
+ 0, 0, /* H=unused */
+}, rd53_sizes[8] = {
+ 15884, 0, /* A=blk 0 thru 15883 */
+ 33440, 15884, /* B=blk 15884 thru 49323 */
+ -1, 0, /* C=blk 0 thru end */
+ 0, 0, /* D=unused */
+ 33440, 0, /* E=blk 0 thru 33439 */
+ -1, 33440, /* F=blk 33440 thru end */
+ -1, 49324, /* G=blk 49324 thru end */
+ -1, 15884, /* H=blk 15884 thru end */
+}, rd54_sizes[8] = {
+ 15884, 0, /* A=blk 0 thru 15883 */
+ 33440, 15884, /* B=blk 15884 thru 49323 */
+ -1, 0, /* C=blk 0 thru end */
+ 130938, 49324, /* D=blk 49324 thru 180261 */
+ 130938, 180262, /* E=blk 180262 thru 311199 (end) */
+ 0, 0, /* F=unused */
+ 261876, 49324, /* G=blk 49324 thru 311199 (end) */
+ 0, 0, /* H=unused */
+}, rx50_sizes[8] = {
+ 800, 0, /* A=blk 0 thru 799 */
+ 0, 0,
+ -1, 0, /* C=blk 0 thru end */
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+};
+
+/*
+ * Media ID decoding table.
+ */
+struct udatypes {
+ u_long ut_id; /* media drive ID */
+ char *ut_name; /* drive type name */
+ struct size *ut_sizes; /* partition tables */
+ int ut_nsectors, ut_ntracks, ut_ncylinders;
+} udatypes[] = {
+ { MSCP_MKDRIVE2('R', 'A', 60), "ra60", ra60_sizes, 42, 4, 2382 },
+ { MSCP_MKDRIVE2('R', 'A', 70), "ra70", ra70_sizes, 33, 11, 1507 },
+ { MSCP_MKDRIVE2('R', 'A', 80), "ra80", ra80_sizes, 31, 14, 559 },
+ { MSCP_MKDRIVE2('R', 'A', 81), "ra81", ra81_sizes, 51, 14, 1248 },
+ { MSCP_MKDRIVE2('R', 'A', 82), "ra82", ra82_sizes, 57, 15, 1423 },
+ { MSCP_MKDRIVE2('R', 'A', 90), "ra90", ra90_sizes, 69, 13, 2649 },
+ { MSCP_MKDRIVE2('R', 'A', 92), "ra92", ra92_sizes, 69, 13, 3279 },
+ { MSCP_MKDRIVE2('R', 'C', 25), "rc25-removable",
+ rc25_sizes, 42, 4, 302 },
+ { MSCP_MKDRIVE3('R', 'C', 'F', 25), "rc25-fixed",
+ rc25_sizes, 42, 4, 302 },
+ { MSCP_MKDRIVE2('R', 'D', 52), "rd52", rd52_sizes, 18, 7, 480 },
+ { MSCP_MKDRIVE2('R', 'D', 53), "rd53", rd53_sizes, 17, 8, 1019 },
+ { MSCP_MKDRIVE2('R', 'D', 32), "rd54-from-rd32",
+ rd54_sizes, 17, 15, 1220 },
+ { MSCP_MKDRIVE2('R', 'D', 54), "rd54", rd54_sizes, 17, 15, 1220 },
+ { MSCP_MKDRIVE2('R', 'X', 50), "rx50", rx50_sizes, 10, 1, 80 },
+ 0
+};
+
+#define NTYPES (sizeof(udatypes) / sizeof(*udatypes))
+
+udamaptype(unit, lp)
+ int unit;
+ register struct disklabel *lp;
+{
+ register struct udatypes *ut;
+ register struct size *sz;
+ register struct partition *pp;
+ register char *p;
+ register int i;
+ register struct ra_info *ra = &ra_info[unit];
+
+ i = MSCP_MEDIA_DRIVE(ra->ra_mediaid);
+ for (ut = udatypes; ut->ut_id; ut++)
+ if (ut->ut_id == i &&
+ ut->ut_nsectors == ra->ra_geom.rg_nsectors &&
+ ut->ut_ntracks == ra->ra_geom.rg_ntracks &&
+ ut->ut_ncylinders == ra->ra_geom.rg_ncyl)
+ goto found;
+
+ /* not one we know; fake up a label for the whole drive */
+ uda_makefakelabel(ra, lp);
+ i = ra->ra_mediaid; /* print the port type too */
+ addlog(": no partition table for %c%c %c%c%c%d, size %d;\n\
+using (s,t,c)=(%d,%d,%d)",
+ MSCP_MID_CHAR(4, i), MSCP_MID_CHAR(3, i),
+ MSCP_MID_CHAR(2, i), MSCP_MID_CHAR(1, i),
+ MSCP_MID_CHAR(0, i), MSCP_MID_NUM(i), lp->d_secperunit,
+ lp->d_nsectors, lp->d_ntracks, lp->d_ncylinders);
+ if (!cold)
+ addlog("\n");
+ return (0);
+found:
+ p = ut->ut_name;
+ for (i = 0; i < sizeof(lp->d_typename) - 1 && *p; i++)
+ lp->d_typename[i] = *p++;
+ lp->d_typename[i] = 0;
+ sz = ut->ut_sizes;
+ lp->d_nsectors = ut->ut_nsectors;
+ lp->d_ntracks = ut->ut_ntracks;
+ lp->d_ncylinders = ut->ut_ncylinders;
+ lp->d_npartitions = 8;
+ lp->d_secpercyl = lp->d_nsectors * lp->d_ntracks;
+ for (pp = lp->d_partitions; pp < &lp->d_partitions[8]; pp++, sz++) {
+ pp->p_offset = sz->blkoff;
+ if ((pp->p_size = sz->nblocks) == (u_long)-1)
+ pp->p_size = ra->ra_dsize - sz->blkoff;
+ }
+ return (1);
+}
+#endif /* COMPAT_42 */
+
+/*
+ * Construct a label for a drive from geometry information
+ * if we have no better information.
+ */
+uda_makefakelabel(ra, lp)
+ register struct ra_info *ra;
+ register struct disklabel *lp;
+{
+ lp->d_nsectors = ra->ra_geom.rg_nsectors;
+ lp->d_ntracks = ra->ra_geom.rg_ntracks;
+ lp->d_ncylinders = ra->ra_geom.rg_ncyl;
+ lp->d_secpercyl = lp->d_nsectors * lp->d_ntracks;
+ bcopy("ra??", lp->d_typename, sizeof("ra??"));
+ lp->d_npartitions = 1;
+ lp->d_partitions[0].p_offset = 0;
+ lp->d_partitions[0].p_size = lp->d_secperunit;
+}
+#endif /* NUDA > 0 */
diff --git a/sys/arch/vax/uba/udareg.h b/sys/arch/vax/uba/udareg.h
new file mode 100644
index 00000000000..f6107a49605
--- /dev/null
+++ b/sys/arch/vax/uba/udareg.h
@@ -0,0 +1,107 @@
+/* $NetBSD: udareg.h,v 1.2 1994/10/26 08:02:51 cgd Exp $ */
+
+/*
+ * Copyright (c) 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * 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.
+ *
+ * @(#)udareg.h 7.3 (Berkeley) 5/8/91
+ */
+
+/*
+ * UDA50 registers and structures
+ */
+
+/*
+ * Writing any value to udaip starts initialisation. Reading from it
+ * when the UDA is running makes the UDA look through the command ring
+ * to find any new commands. Reading udasa gives status; writing it
+ * during initialisation sets things up.
+ */
+struct udadevice {
+ u_short udaip; /* initialisation and polling */
+ u_short udasa; /* status and address */
+};
+
+/*
+ * Bits in UDA status register during initialisation
+ */
+#define UDA_ERR 0x8000 /* error */
+#define UDA_STEP4 0x4000 /* step 4 has started */
+#define UDA_STEP3 0x2000 /* step 3 has started */
+#define UDA_STEP2 0x1000 /* step 2 has started */
+#define UDA_STEP1 0x0800 /* step 1 has started */
+#define UDA_NV 0x0400 /* no host settable interrupt vector */
+#define UDA_QB 0x0200 /* controller supports Q22 bus */
+#define UDA_DI 0x0100 /* controller implements diagnostics */
+#define UDA_IE 0x0080 /* interrupt enable */
+#define UDA_NCNRMASK 0x003f /* in STEP1, bits 0-2=NCMDL2, 3-5=NRSPL2 */
+#define UDA_IVECMASK 0x007f /* in STEP2, bits 0-6 are interruptvec / 4 */
+#define UDA_PI 0x0001 /* host requests adapter purge interrupts */
+
+/*
+ * Bits in UDA status register after initialisation
+ */
+#define UDA_GO 0x0001 /* run */
+
+#define UDASR_BITS \
+"\20\20ERR\17STEP4\16STEP3\15STEP2\14STEP1\13NV\12QB\11DI\10IE\1GO"
+
+/*
+ * UDA Communications Area. Note that this structure definition
+ * requires NRSP and NCMD to be defined already.
+ */
+struct udaca {
+ short ca_xxx1; /* unused */
+ char ca_xxx2; /* unused */
+ char ca_bdp; /* BDP to purge */
+ short ca_cmdint; /* command ring transition flag */
+ short ca_rspint; /* response ring transition flag */
+ long ca_rspdsc[NRSP];/* response descriptors */
+ long ca_cmddsc[NCMD];/* command descriptors */
+};
+
+/*
+ * Simplified routines (e.g., uddump) reprogram the UDA50 for one command
+ * and one response at a time; uda1ca is like udaca except that it provides
+ * exactly one command and response descriptor.
+ */
+struct uda1ca {
+ short ca_xxx1;
+ char ca_xxx2;
+ char ca_bdp;
+ short ca_cmdint;
+ short ca_rspint;
+ long ca_rspdsc;
+ long ca_cmddsc;
+};
diff --git a/sys/arch/vax/vax/autoconf.c b/sys/arch/vax/vax/autoconf.c
new file mode 100644
index 00000000000..9967b2de7ef
--- /dev/null
+++ b/sys/arch/vax/vax/autoconf.c
@@ -0,0 +1,339 @@
+/* $NetBSD: autoconf.c,v 1.4 1995/06/05 16:26:23 ragge Exp $ */
+
+/*
+ * Copyright (c) 1994 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}.
+ * 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 "sys/param.h"
+#include "machine/cpu.h"
+#include "machine/sid.h"
+#include "machine/loconf.h"
+#include "sys/types.h"
+#include "sys/device.h"
+#include "sys/reboot.h"
+#include "sys/conf.h"
+#include "machine/param.h"
+#include "machine/vmparam.h"
+#include "machine/nexus.h"
+#include "machine/../vax/gencons.h"
+#include "vm/vm.h"
+
+#define BACKPLANE 0
+#define BIBUSS 1
+#define SBIBUSS 2
+struct bp_conf {
+ char *type;
+ int num;
+ int partyp;
+};
+
+extern int cold;
+
+int cpu_notsupp(),cpu_notgen();
+#ifdef VAX750
+int ka750_mchk(),ka750_memerr(),ka750_clock(),ka750_conf();
+int nexty750[]={ NEX_MEM16, NEX_MEM16, NEX_MEM16, NEX_MEM16,
+ NEX_MBA, NEX_MBA, NEX_MBA, NEX_MBA,
+ NEX_UBA0, NEX_UBA1, NEX_ANY, NEX_ANY,
+ NEX_ANY, NEX_ANY, NEX_ANY, NEX_ANY};
+#endif
+#if VAX730
+int nexty730[NNEX730] = {
+ NEX_MEM16, NEX_ANY, NEX_ANY, NEX_ANY,
+ NEX_ANY, NEX_ANY, NEX_ANY, NEX_ANY,
+};
+#endif
+#if VAX630
+int uvaxII_mchk(), uvaxII_memerr(), uvaxII_clock(), uvaxII_conf();
+#endif
+
+struct cpu_dep cpu_calls[VAX_MAX+1]={
+ /* Type 0,noexist */
+ cpu_notsupp,cpu_notsupp,cpu_notsupp,cpu_notsupp,cpu_notsupp,
+#ifdef VAX780 /* Type 1, 11/{780,782,785} */
+ cpu_notsupp,cpu_notsupp,cpu_notsupp,cpu_notsupp,cpu_notsupp,
+#else
+ cpu_notsupp,cpu_notsupp,cpu_notsupp,cpu_notsupp,cpu_notsupp,
+#endif
+#ifdef VAX750 /* Type 2, 11/750 */
+ cpu_notgen,ka750_clock,ka750_mchk,ka750_memerr,ka750_conf,
+#else
+ cpu_notgen,cpu_notgen,cpu_notgen,cpu_notgen,cpu_notgen,
+#endif
+#ifdef VAX730 /* Type 3, 11/{730,725}, ceauciesco-vax */
+ cpu_notsupp,cpu_notsupp,cpu_notsupp,cpu_notsupp,cpu_notsupp,
+#else
+ cpu_notsupp,cpu_notsupp,cpu_notsupp,cpu_notsupp,cpu_notsupp,
+#endif
+#ifdef VAX8600 /* Type 4, 8600/8650 (11/{790,795}) */
+ cpu_notsupp,cpu_notsupp,cpu_notsupp,cpu_notsupp,cpu_notsupp,
+#else
+ cpu_notsupp,cpu_notsupp,cpu_notsupp,cpu_notsupp,cpu_notsupp,
+#endif
+#ifdef VAX8200 /* Type 5, 8200, 8300, 8350 */
+ cpu_notsupp,cpu_notsupp,cpu_notsupp,cpu_notsupp,cpu_notsupp,
+#else
+ cpu_notsupp,cpu_notsupp,cpu_notsupp,cpu_notsupp,cpu_notsupp,
+#endif
+#ifdef VAX8800 /* Type 6, 85X0, 8700, 88X0 */
+ cpu_notsupp,cpu_notsupp,cpu_notsupp,cpu_notsupp,cpu_notsupp,
+#else
+ cpu_notsupp,cpu_notsupp,cpu_notsupp,cpu_notsupp,cpu_notsupp,
+#endif
+#ifdef VAX610 /* Type 7, KA610 */
+ cpu_notsupp,cpu_notsupp,cpu_notsupp,cpu_notsupp,cpu_notsupp,
+#else
+ cpu_notsupp,cpu_notsupp,cpu_notsupp,cpu_notsupp,cpu_notsupp,
+#endif
+#ifdef VAX630 /* Type 8, KA630 or KA410 (uVAX II) */
+ cpu_notgen,uvaxII_clock,uvaxII_mchk,uvaxII_memerr,uvaxII_conf,
+#else
+ cpu_notsupp,cpu_notsupp,cpu_notsupp,cpu_notsupp,cpu_notsupp,
+#endif
+ /* Type 9, not used */
+ cpu_notsupp,cpu_notsupp,cpu_notsupp,cpu_notsupp,cpu_notsupp,
+#ifdef VAX650 /* Type 10, KA65X (uVAX III) */
+ cpu_notsupp,cpu_notsupp,cpu_notsupp,cpu_notsupp,cpu_notsupp,
+#else
+ cpu_notsupp,cpu_notsupp,cpu_notsupp,cpu_notsupp,cpu_notsupp,
+#endif
+};
+
+cpu_notgen()
+{
+ conout("This cputype not generated.\n");
+ asm("halt");
+}
+cpu_notsupp()
+{
+ conout("This cputype not supported.\n");
+ asm("halt");
+}
+
+configure()
+{
+ extern int boothowto;
+
+
+ if (!config_rootfound("backplane", NULL))
+ panic("backplane not configured");
+
+#if GENERIC
+ if ((boothowto & RB_ASKNAME) == 0)
+ setroot();
+ setconf();
+#else
+ setroot();
+#endif
+ /*
+ * Configure swap area and related system
+ * parameter based on device(s) used.
+ */
+ gencnslask(); /* XXX inte g|ras h{r */
+ swapconf();
+ cold=0;
+ mtpr(GC_CCF, PR_TXDB); /* Clear cold start flag in cpu */
+}
+
+
+int
+printut(aux, hej)
+ void *aux;
+ char *hej;
+{
+ if(hej) printf("printut %s\n",hej);
+ return(UNSUPP);
+}
+
+int
+backplane_match(parent, cf, aux)
+ struct device *parent;
+ struct cfdata *cf;
+ void *aux;
+{
+ if(cf->cf_unit==0&&strcmp(cf->cf_driver->cd_name,"backplane")==0)
+ return 1; /* First (and only) backplane */
+
+ return(0);
+}
+
+void
+backplane_attach(parent, self, hej)
+ struct device *parent, *self;
+ void *hej;
+{
+ struct bp_conf bp;
+ int i,ccpu,cmem,cbi,csbi;
+
+ printf("\n");
+
+ switch(cpunumber){
+ case VAX_750:
+ case VAX_78032:
+ cmem=cbi=0;
+ ccpu=csbi=1;
+ break;
+ }
+
+ bp.partyp=BACKPLANE;
+ bp.type="cpu";
+ for(i=0;i<ccpu;i++){
+ bp.num=i;
+ config_found(self, &bp, printut);
+ }
+ bp.type="mem";
+ for(i=0;i<cmem;i++){
+ bp.num=i;
+ config_found(self, &bp, printut);
+ }
+ bp.type="bi";
+ for(i=0;i<cbi;i++){
+ bp.num=i;
+ config_found(self, &bp, printut);
+ }
+ bp.type="sbi";
+ for(i=0;i<csbi;i++){
+ bp.num=i;
+ config_found(self, &bp, printut);
+ }
+}
+
+int
+cpu_match(parent, cf, aux)
+ struct device *parent;
+ struct cfdata *cf;
+ void *aux;
+{
+ struct bp_conf *bp=aux;
+
+ if(strcmp(cf->cf_driver->cd_name,"cpu"))
+ return 0;
+
+ switch (cpunumber) {
+#ifdef VAX750
+ case VAX_750:
+ if(cf->cf_unit==0&&bp->partyp==BACKPLANE)
+ return 1;
+ break;
+#endif
+#ifdef VAX630
+ case VAX_78032:
+ if(cf->cf_unit==0&&bp->partyp==BACKPLANE)
+ return 1;
+ break;
+#endif
+ };
+
+ return 0;
+}
+
+void
+cpu_attach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ extern int cpu_type;
+ extern char cpu_model[];
+
+ switch (cpunumber) {
+#ifdef VAX750
+ case VAX_750:
+ printf(": 11/750, hardware rev %d, ucode rev %d\n",
+ V750HARDW(cpu_type), V750UCODE(cpu_type));
+ printf("cpu0 at backplane0: ");
+ if(mfpr(PR_ACCS)&0xff){
+ printf("FPA present, enabling\n");
+ mtpr(0x8000,PR_ACCS);
+ } else printf("no FPA\n");
+ strcpy(cpu_model,"VAX 11/750");
+ break;
+#endif
+#if VAX630
+ case VAX_78032:
+ printf(": MicroVAXII CPU\n");
+ strcpy(cpu_model, "MicroVAX 78032/78132");
+ break;
+#endif
+ };
+}
+
+int nmcr=0;
+
+int
+mem_match(parent, cf, aux)
+ struct device *parent;
+ struct cfdata *cf;
+ void *aux;
+{
+ struct sbi_attach_args *sa=(struct sbi_attach_args *)aux;
+
+ if((cf->cf_loc[0]!=sa->nexnum)&&(cf->cf_loc[0]>-1))
+ return 0; /* memory doesn't match spec's */
+ switch(sa->type){
+ case NEX_MEM16:
+ return 1;
+ }
+ return 0;
+}
+
+void
+mem_attach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct sbi_attach_args *sa=(struct sbi_attach_args *)aux;
+
+ switch(cpunumber){
+#ifdef VAX750
+ case VAX_750:
+ ka750_memenable(sa,self);
+ break;
+#endif
+
+ default:
+ break;
+ }
+
+}
+
+struct cfdriver backplanecd =
+ { 0, "backplane", backplane_match, backplane_attach,
+ DV_DULL, sizeof(struct device) };
+
+struct cfdriver cpucd =
+ { 0, "cpu", cpu_match, cpu_attach, DV_CPU, sizeof(struct device) };
+
+
+struct cfdriver memcd =
+ { 0, "mem", mem_match, mem_attach, DV_CPU, sizeof(struct device) };
+
+
diff --git a/sys/arch/vax/vax/clock.c b/sys/arch/vax/vax/clock.c
new file mode 100644
index 00000000000..96539e5c4db
--- /dev/null
+++ b/sys/arch/vax/vax/clock.c
@@ -0,0 +1,210 @@
+/* $NetBSD: clock.c,v 1.7.2.1 1995/10/15 14:17:17 ragge Exp $ */
+/*
+ * Copyright (c) 1995 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}.
+ * 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/kernel.h>
+
+#include "machine/mtpr.h"
+#include "machine/sid.h"
+
+#define SEC_PER_DAY (60*60*24)
+
+extern int todrstopped;
+
+static unsigned long year; /* start of current year in seconds */
+static unsigned long year_len; /* length of current year in 100th of seconds */
+
+/*
+ * microtime() should return number of usecs in struct timeval.
+ * We may get wrap-arounds, but that will be fixed with lasttime
+ * check. This may fault within 10 msecs.
+ */
+void
+microtime(tvp)
+ struct timeval *tvp;
+{
+ u_int int_time, tmp_year;
+ int s, i;
+ static struct timeval lasttime;
+
+ s = splhigh();
+ int_time = mfpr(PR_TODR);
+
+ asm ("movc3 %0,(%1),(%2)"
+ :
+ : "r" (sizeof(struct timeval)),"r" (&time),"r"(tvp)
+ :"r0","r1","r2","r3","r4","r5");
+
+ i = mfpr(PR_ICR) + tick; /* Get current interval count */
+ tvp->tv_usec += i;
+ while (tvp->tv_usec > 1000000) {
+ tvp->tv_sec++;
+ tvp->tv_usec -= 1000000;
+ }
+ if (tvp->tv_sec == lasttime.tv_sec &&
+ tvp->tv_usec <= lasttime.tv_usec &&
+ (tvp->tv_usec = lasttime.tv_usec + 1) > 1000000) {
+ tvp->tv_sec++;
+ tvp->tv_usec -= 1000000;
+ }
+ bcopy(tvp, &lasttime, sizeof(struct timeval));
+ if (int_time > year_len) {
+ mtpr(mfpr(PR_TODR) - year_len, PR_TODR);
+ year += year_len / 100;
+ tmp_year = year / SEC_PER_DAY / 365 + 2;
+ year_len = 100 * SEC_PER_DAY *
+ ((tmp_year % 4 && tmp_year != 32) ? 365 : 366);
+ }
+ splx(s);
+}
+
+/*
+ * Sets year to the year in fs_time and then calculates the number of
+ * 100th of seconds in the current year and saves that info in year_len.
+ * fs_time contains the time set in the superblock in the root filesystem.
+ * If the clock is started, it then checks if the time is valid
+ * compared with the time in fs_time. If the clock is stopped, an
+ * alert is printed and the time is temporary set to the time in fs_time.
+ */
+
+void
+inittodr(fs_time)
+ time_t fs_time;
+{
+
+ unsigned long tmp_year, sluttid, year_ticks;
+ int clock_stopped;
+
+ sluttid = fs_time;
+ year = (fs_time / SEC_PER_DAY / 365) * 365 * SEC_PER_DAY;
+ tmp_year = year / SEC_PER_DAY / 365 + 2;
+ year_len = 100 * SEC_PER_DAY *
+ ((tmp_year % 4 && tmp_year != 32) ? 365 : 366);
+
+ switch (cpunumber) {
+#if VAX750
+ case VAX_750:
+ year_ticks = mfpr(PR_TODR);
+ clock_stopped = todrstopped;
+ break;
+#endif
+#if VAX630 || VAX410
+ case VAX_78032:
+ year_ticks = uvaxII_gettodr(&clock_stopped);
+ break;
+#endif
+ default:
+ year_ticks = 0;
+ clock_stopped = 1;
+ };
+
+ if (clock_stopped){
+ printf(
+ "Internal clock not started. Using time from file system.\n");
+ switch (cpunumber) {
+#if VAX750
+ case VAX_750:
+ /*+1 so the clock won't be stopped */
+ mtpr((fs_time - year) * 100 + 1, PR_TODR);
+ break;
+#endif
+#if VAX630 || VAX410
+ case VAX_78032:
+ uvaxII_settodr((fs_time - year) * 100 + 1);
+ break;
+#endif
+ };
+ todrstopped = 0;
+ } else if (year_ticks / 100 > fs_time - year + SEC_PER_DAY * 3) {
+ printf(
+ "WARNING: Clock has gained %d days - CHECK AND RESET THE DATE.\n",
+ (year_ticks / 100 - (fs_time - year)) / SEC_PER_DAY);
+ sluttid = year + (year_ticks / 100);
+ } else if (year_ticks / 100 < fs_time - year) {
+ printf(
+ "WARNING: Clock has lost time - CHECK AND RESET THE DATE.\n");
+ } else sluttid = year + (year_ticks / 100);
+ time.tv_sec = sluttid;
+}
+
+/*
+ * Resettodr restores the time of day hardware after a time change.
+ */
+
+void
+resettodr()
+{
+
+ unsigned long tmp_year;
+
+ year = (time.tv_sec / SEC_PER_DAY / 365) * 365 * SEC_PER_DAY;
+ tmp_year = year / SEC_PER_DAY / 365 + 2;
+ year_len = 100 * SEC_PER_DAY *
+ ((tmp_year % 4 && tmp_year != 32) ? 365 : 366);
+ switch (cpunumber) {
+#if VAX750
+ case VAX_750:
+ mtpr((time.tv_sec - year) * 100 + 1, PR_TODR);
+ break;
+#endif
+#if VAX630 || VAX410
+ case VAX_78032:
+ uvaxII_settodr((time.tv_sec - year) * 100 + 1);
+ break;
+#endif
+ };
+ todrstopped = 0;
+}
+
+/*
+ * Unfortunately the 78032 cpu chip (MicroVAXII cpu) does not have a functional
+ * todr register, so this function is necessary.
+ * (the x and y variables are used to confuse the optimizer enough to ensure
+ * that the code actually loops:-)
+ */
+int
+todr()
+{
+ int delaycnt, x = 4, y = 4;
+ static int todr_val;
+
+ if (cpunumber != VAX_78032)
+ return (mfpr(PR_TODR));
+
+ /*
+ * Loop for approximately 10msec and then return todr_val + 1.
+ */
+ delaycnt = 5000;
+ while (delaycnt > 0)
+ delaycnt = delaycnt - x + 3 + y - 4;
+ return (++todr_val);
+}
diff --git a/sys/arch/vax/vax/conf.c b/sys/arch/vax/vax/conf.c
new file mode 100644
index 00000000000..483a5848457
--- /dev/null
+++ b/sys/arch/vax/vax/conf.c
@@ -0,0 +1,469 @@
+/* $NetBSD: conf.c,v 1.14 1995/08/17 17:41:05 thorpej Exp $ */
+
+/*-
+ * Copyright (c) 1982, 1986 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.
+ *
+ * @(#)conf.c 7.18 (Berkeley) 5/9/91
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/buf.h>
+#include <sys/ioctl.h>
+#include <sys/tty.h>
+#include <sys/conf.h>
+#include <sys/vnode.h>
+
+int ttselect __P((dev_t, int, struct proc *));
+
+#ifndef LKM
+#define lkmenodev enodev
+#else
+int lkmenodev();
+#endif
+
+#include "hp.h" /* 0 */
+bdev_decl(hp);
+
+#include "tu.h"
+bdev_decl(ht);
+
+#include "rk.h"
+bdev_decl(rk);
+
+bdev_decl(sw);
+
+#include "te.h"
+bdev_decl(tm);
+
+#include "tmscp.h"
+bdev_decl(tmscp);
+
+#include "ts.h"
+bdev_decl(ts);
+
+#include "mu.h"
+bdev_decl(mt);
+
+#if 0 /* defined(VAX750) || defined(VAX730) */
+#define NCTU 1
+#else
+#define NCTU 0
+#endif
+bdev_decl(tu);
+
+#include "uda.h"
+bdev_decl(uda);
+
+#include "kdb.h"
+bdev_decl(kdb);
+
+#include "up.h"
+bdev_decl(up);
+
+#include "tj.h"
+bdev_decl(ut);
+
+#include "rb.h"
+bdev_decl(idc);
+
+#include "rx.h"
+bdev_decl(rx);
+
+#include "uu.h"
+bdev_decl(uu);
+
+#include "rl.h"
+bdev_decl(rl);
+
+#include "ccd.h"
+bdev_decl(ccd);
+
+struct bdevsw bdevsw[] =
+{
+ bdev_disk_init(NHP,hp), /* 0: RP0?/RM0? */
+ bdev_tape_init(NTU,ht), /* 1: TU77 w/ TM03 */
+ bdev_disk_init(NUP,up), /* 2: SC-21/SC-31 */
+ bdev_disk_init(NRK,rk), /* 3: RK06/07 */
+ bdev_swap_init(1,sw), /* 4: swap pseudo-device */
+ bdev_tape_init(NTE,tm), /* 5: TM11/TE10 */
+ bdev_tape_init(NTS,ts), /* 6: TS11 */
+ bdev_tape_init(NMU,mt), /* 7: TU78 */
+ bdev_tape_init(NCTU,tu), /* 8: Console TU58 on 730/750 */
+ bdev_disk_init(NUDA,uda), /* 9: UDA50/RA?? */
+ bdev_tape_init(NTJ,ut), /* 10: TU45 */
+ bdev_disk_init(NRB,idc), /* 11: IDC (RB730) */
+ bdev_disk_init(NRX,rx), /* 12: RX01/02 on unibus */
+ bdev_disk_init(NUU,uu), /* 13: TU58 on DL11 */
+ bdev_disk_init(NRL,rl), /* 14: RL01/02 */
+ bdev_tape_init(NTMSCP,tmscp), /* 15: TMSCP tape */
+ bdev_disk_init(NKDB,kdb), /* 16: KDB50/RA?? */
+ bdev_disk_init(NCCD,ccd), /* 17: concatenated disk driver */
+};
+int nblkdev = sizeof(bdevsw) / sizeof(bdevsw[0]);
+
+/*
+ * Console routines for VAX console. There are always an generic console,
+ * but maybe we should care about RD, QDSS etc?
+ */
+#include <dev/cons.h>
+
+#define gencnpollc nullcnpollc
+cons_decl(gen);
+
+struct consdev constab[]={
+/* Generic console, should always be present */
+ cons_init(gen),
+
+#ifdef notyet
+/* We may not always use builtin console, sometimes RD */
+ { rdcnprobe, rdcninit, rdcngetc, rdcnputc },
+#endif
+ { 0 }
+};
+
+/* Special for console storage */
+#define dev_type_rw(n) int n __P((dev_t, int, int, struct proc *))
+
+/* plotters - open, close, write, ioctl, select */
+#define cdev_plotter_init(c,n) { \
+ dev_init(c,n,open), dev_init(c,n,close), (dev_type_read((*))) enodev, \
+ dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) enodev, \
+ 0, dev_init(c,n,select), (dev_type_mmap((*))) enodev }
+
+/* console mass storage - open, close, read/write */
+#define cdev_cnstore_init(c,n) { \
+ dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \
+ dev_init(c,n,write), (dev_type_ioctl((*))) enodev, \
+ (dev_type_stop((*))) enodev, 0, (dev_type_select((*))) enodev, \
+ (dev_type_mmap((*))) enodev }
+
+#define cdev_lp_init(c,n) { \
+ dev_init(c,n,open), dev_init(c,n,close), (dev_type_read((*))) enodev, \
+ dev_init(c,n,write), (dev_type_ioctl((*))) enodev, \
+ (dev_type_stop((*))) enodev, 0, seltrue, (dev_type_mmap((*))) enodev }
+
+/* graphic display adapters */
+#define cdev_graph_init(c,n) { \
+ dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \
+ dev_init(c,n,write), dev_init(c,n,ioctl), dev_init(c,n,stop), \
+ 0, dev_init(c,n,select), (dev_type_mmap((*))) enodev }
+
+/* Ingres */
+#define cdev_ingres_init(c,n) { \
+ dev_init(c,n,open), dev_init(c,n,close), (dev_type_read((*))) nullop, \
+ (dev_type_write((*))) nullop, dev_init(c,n,ioctl), \
+ (dev_type_stop((*))) nullop, 0, (dev_type_select((*))) nullop, \
+ (dev_type_mmap((*))) enodev }
+
+
+
+cdev_decl(cn);
+cdev_decl(ctty);
+#define mmread mmrw
+#define mmwrite mmrw
+cdev_decl(mm);
+cdev_decl(sw);
+#include "pty.h"
+#define ptstty ptytty
+#define ptsioctl ptyioctl
+cdev_decl(pts);
+#define ptctty ptytty
+#define ptcioctl ptyioctl
+cdev_decl(ptc);
+cdev_decl(log);
+#ifdef LKM
+#define NLKM 1
+#else
+#define NLKM 0
+#endif
+cdev_decl(lkm);
+
+cdev_decl(hp);
+cdev_decl(rk);
+cdev_decl(tm);
+cdev_decl(tmscp);
+cdev_decl(ts);
+cdev_decl(mt);
+cdev_decl(uda);
+cdev_decl(up);
+cdev_decl(ut);
+cdev_decl(idc);
+cdev_decl(fd);
+cdev_decl(gencn);
+cdev_decl(rx);
+cdev_decl(rl);
+cdev_decl(kdb);
+cdev_decl(ccd);
+
+#include "ct.h"
+cdev_decl(ct);
+#include "dh.h"
+cdev_decl(dh);
+#include "dmf.h"
+cdev_decl(dmf);
+
+#include "np.h"
+cdev_decl(np);
+
+#if VAX8600
+#define NCRL 1
+#else
+#define NCRL 0
+#endif
+#define crlread crlrw
+#define crlwrite crlrw
+cdev_decl(crl);
+
+#if VAX8200
+#define NCRX 1
+#else
+#define NCRX 0
+#endif
+#define crxread crxrw
+#define crxwrite crxrw
+cdev_decl(crx);
+
+#if VAX780
+#define NFL 1
+#else
+#define NFL 0
+#endif
+#define flread flrw
+#define flwrite flrw
+cdev_decl(fl);
+
+#include "dz.h"
+cdev_decl(dz);
+
+#include "vp.h"
+cdev_decl(vp);
+
+#include "lp.h"
+cdev_decl(lp);
+
+#include "va.h"
+cdev_decl(va);
+
+#include "lpa.h"
+cdev_decl(lpa);
+
+#include "dn.h"
+cdev_decl(dn);
+
+#include "ik.h"
+cdev_decl(ik);
+
+#include "ps.h"
+cdev_decl(ps);
+
+#include "ad.h"
+cdev_decl(ad);
+
+#include "dhu.h"
+cdev_decl(dhu);
+
+#include "dmz.h"
+cdev_decl(dmz);
+
+#include "qv.h"
+cdev_decl(qv);
+
+#include "qd.h"
+cdev_decl(qd);
+
+#if defined(INGRES)
+#define NII 1
+#else
+#define NII 0
+#endif
+cdev_decl(ii);
+
+struct cdevsw cdevsw[] =
+{
+ cdev_cn_init(1,cn), /* 0: virtual console */
+ cdev_tty_init(NDZ,dz), /* 1: DZ11 */
+ cdev_ctty_init(1,ctty), /* 2: controlling terminal */
+ cdev_mm_init(1,mm), /* 3: /dev/{null,mem,kmem,...} */
+ cdev_disk_init(NHP,hp), /* 4: Massbuss disk */
+ cdev_notdef(), /* 5 */
+ cdev_plotter_init(NVP,vp), /* 6: Versatec plotter */
+ cdev_swap_init(1,sw), /* 7 */
+ cdev_cnstore_init(NFL,fl), /* 8: 11/780 console floppy */
+ cdev_disk_init(NUDA,uda), /* 9: MSCP disk interface */
+ cdev_plotter_init(NVA,va), /* 10: Benson-Varian plotter */
+ cdev_disk_init(NRK,rk), /* 11: RK06/07 */
+ cdev_tty_init(NDH,dh), /* 12: DH-11/DM-11 */
+ cdev_disk_init(NUP,up), /* 13: SC-21/SC-31 */
+ cdev_tape_init(NTE,tm), /* 14: TM11/TE10 */
+ cdev_lp_init(NLP,lp), /* 15: LP-11 line printer */
+ cdev_tape_init(NTS,ts), /* 16: TS11 */
+ cdev_tape_init(NTJ,ut), /* 17: TU45 */
+ cdev_lp_init(NCT,ct), /* 18: phototypesetter interface */
+ cdev_tape_init(NMU,mt), /* 19: TU78 */
+ cdev_tty_init(NPTY,pts), /* 20: pseudo-tty slave */
+ cdev_ptc_init(NPTY,ptc), /* 21: pseudo-tty master */
+ cdev_tty_init(NDMF,dmf), /* 22: DMF32 */
+ cdev_disk_init(NRB,idc), /* 23: IDC (RB730) */
+ cdev_lp_init(NDN,dn), /* 24: DN-11 autocall unit */
+ cdev_tty_init(1,gencn), /* 25: Generic console (mtpr...) */
+ cdev_audio_init(NLPA,lpa), /* 26 ??? */
+ cdev_graph_init(NPS,ps), /* 27: E/S graphics device */
+ cdev_lkm_init(NLKM,lkm), /* 28: loadable module driver */
+ cdev_ch_init(NAD,ad), /* 29: DT A/D converter */
+ cdev_disk_init(NRX,rx), /* 30: RX01/02 on unibus */
+ cdev_graph_init(NIK,ik), /* 31: Ikonas frame buffer */
+ cdev_disk_init(NRL,rl), /* 32: RL01/02 on unibus */
+ cdev_log_init(1,log), /* 33: /dev/klog */
+ cdev_tty_init(NDHU,dhu), /* 34: DHU-11 */
+ cdev_cnstore_init(NCRL,crl), /* 35: Console RL02 on 8600 */
+ cdev_notdef(), /* 36: was vs100 interface. ??? */
+ cdev_tty_init(NDMZ,dmz), /* 37: DMZ32 */
+ cdev_tape_init(NTMSCP,tmscp), /* 38: TMSCP tape */
+ cdev_audio_init(NNP,np), /* 39: NP Intelligent Board */
+ cdev_graph_init(NQV,qv), /* 40: QVSS graphic display */
+ cdev_graph_init(NQD,qd), /* 41: QDSS graphic display */
+ cdev_notdef(), /* 42 */
+ cdev_ingres_init(NII,ii), /* 43: Ingres device */
+ cdev_notdef(), /* 44 was Datakit */
+ cdev_notdef(), /* 45 was Datakit */
+ cdev_notdef(), /* 46 was Datakit */
+ cdev_notdef(), /* 47 */
+ cdev_notdef(), /* 48 */
+ cdev_notdef(), /* 49 */
+ cdev_notdef(), /* 50 */
+ cdev_cnstore_init(NCRX,crx), /* 51: Console RX50 at 8200 */
+ cdev_disk_init(NKDB,kdb), /* 52: KDB50/RA?? */
+ cdev_fd_init(1,fd), /* 53: file descriptor pseudo-device */
+ cdev_disk_init(NCCD,ccd), /* 54: concatenated disk driver */
+};
+int nchrdev = sizeof(cdevsw) / sizeof(cdevsw[0]);
+
+int mem_no = 3; /* major device number of memory special file */
+
+/*
+ * Swapdev is a fake device implemented
+ * in sw.c used only internally to get to swstrategy.
+ * It cannot be provided to the users, because the
+ * swstrategy routine munches the b_dev and b_blkno entries
+ * before calling the appropriate driver. This would horribly
+ * confuse, e.g. the hashing routines. Instead, /dev/drum is
+ * provided as a character (raw) device.
+ */
+dev_t swapdev = makedev(4, 0);
+
+int chrtoblktbl[] = {
+ NODEV, /* 0 */
+ NODEV, /* 1 */
+ NODEV, /* 2 */
+ NODEV, /* 3 */
+ 0, /* 4 */
+ 1, /* 5 */
+ NODEV, /* 6 */
+ NODEV, /* 7 */
+ NODEV, /* 8 */
+ 9, /* 9 */
+ NODEV, /* 10 */
+ 3, /* 11 */
+ NODEV, /* 12 */
+ 2, /* 13 */
+ 5, /* 14 */
+ NODEV, /* 15 */
+ 6, /* 16 */
+ 10, /* 17 */
+ NODEV, /* 18 */
+ 7, /* 19 */
+ NODEV, /* 20 */
+ NODEV, /* 21 */
+ NODEV, /* 22 */
+ 11, /* 23 */
+ NODEV, /* 24 */
+ NODEV, /* 25 */
+ NODEV, /* 26 */
+ NODEV, /* 27 */
+ NODEV, /* 28 */
+ NODEV, /* 29 */
+ 12, /* 30 */
+ NODEV, /* 31 */
+ 14, /* 32 */
+ NODEV, /* 33 */
+ NODEV, /* 34 */
+ NODEV, /* 35 */
+ NODEV, /* 36 */
+ NODEV, /* 37 */
+ 15, /* 38 */
+ NODEV, /* 39 */
+ NODEV, /* 40 */
+ NODEV, /* 41 */
+ NODEV, /* 42 */
+ NODEV, /* 43 */
+ NODEV, /* 44 */
+ NODEV, /* 45 */
+ NODEV, /* 46 */
+ NODEV, /* 47 */
+ NODEV, /* 48 */
+ NODEV, /* 49 */
+ NODEV, /* 50 */
+ NODEV, /* 51 */
+ 16, /* 52 */
+ NODEV, /* 53 */
+ 17, /* 54 */
+};
+
+chrtoblk(dev)
+ dev_t dev;
+{
+ if(major(dev)>=nchrdev) return(NODEV);
+ return chrtoblktbl[major(dev)]==NODEV?NODEV:
+ makedev(chrtoblktbl[major(dev)],minor(dev));
+}
+
+/*
+ * Returns true if dev is /dev/mem or /dev/kmem.
+ */
+iskmemdev(dev)
+ dev_t dev;
+{
+
+ return (major(dev) == 3 && minor(dev) < 2);
+}
+
+/*
+ * Returns true if dev is /dev/zero.
+ * ?? Shall I use 12 as /dev/zero?
+ */
+iszerodev(dev)
+ dev_t dev;
+{
+
+ return (major(dev) == 3 && minor(dev) == 12);
+}
diff --git a/sys/arch/vax/vax/db_disasm.c b/sys/arch/vax/vax/db_disasm.c
new file mode 100644
index 00000000000..0b93e6d9567
--- /dev/null
+++ b/sys/arch/vax/vax/db_disasm.c
@@ -0,0 +1,347 @@
+#include <sys/param.h>
+#include <sys/proc.h>
+#include <sys/reboot.h>
+
+#include <ddb/db_variables.h>
+
+#include <machine/db_machdep.h>
+
+
+
+struct vax_insn {
+ char *insn;
+ int nargs;
+} instr[] = {
+ "halt", 0,
+ "nop", 0,
+ "rei", 0,
+ "bpt", 0,
+ "ret", 0,
+ "rsb", 0,
+ "ldpctx", 0,
+ "svpctx", 0,
+ "cvtps", 4,
+ "cvtsp", 4,
+ "index", 6,
+ "crc", 4,
+ "prober", 3,
+ "probew", 3,
+ "insque", 2,
+ "remque", 2,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+ "", -1,
+};
+
+
+/*
+ * Disassemble instruction at 'loc'. 'altfmt' specifies an
+ * (optional) alternate format. Return address of start of
+ * next instruction.
+ */
+db_addr_t
+db_disasm(loc, altfmt)
+ db_addr_t loc;
+ boolean_t altfmt;
+{
+ char *i_pl;
+ int inr, i;
+
+ i_pl = loc;
+ inr = *i_pl;
+
+ if (instr[*i_pl].nargs < 0) {
+ printf("Ok{nd instruktion: %2x",*i_pl&0xff);
+ i_pl++;
+ } else {
+ printf("\t%s\t",instr[inr].insn);
+ i_pl++;
+ for (i=0;i<instr[inr].nargs;i++) {
+ i_pl = argprint(i_pl);
+ if (i<instr[inr].nargs-1)
+ printf(",");
+ }
+ }
+
+
+
+ return i_pl;
+}
+
+argprint(plats)
+ char *plats;
+{
+ switch (*plats&0xf0) {
+ case 0x00:
+ case 0x10:
+ case 0x20:
+ case 0x30:
+ printf("$%x",*plats++);
+ break;
+
+ case 0xe0:
+ if (*plats++&15 == 15) {
+ printf("%8x",*(unsigned *)plats + plats);
+ plats += 4;
+ } else {
+ printf("Oinpl. s{tt.");
+ }
+ break;
+ default:
+ printf("Oinpl. s{tt.");
+ }
+ return plats;
+}
diff --git a/sys/arch/vax/vax/db_machdep.c b/sys/arch/vax/vax/db_machdep.c
new file mode 100644
index 00000000000..e924f940fff
--- /dev/null
+++ b/sys/arch/vax/vax/db_machdep.c
@@ -0,0 +1,216 @@
+/* $NetBSD: db_machdep.c,v 1.2 1995/07/05 09:54:09 ragge Exp $ */
+
+/*
+ * Mach Operating System
+ * Copyright (c) 1991,1990 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ *
+ * db_interface.c,v 2.4 1991/02/05 17:11:13 mrt (CMU)
+ */
+
+/*
+ * Interface to new debugger.
+ * Taken from i386 port and modified for vax.
+ */
+#include <sys/param.h>
+#include <sys/proc.h>
+#include <sys/reboot.h>
+#include <sys/systm.h> /* just for boothowto --eichin */
+
+#include <ddb/db_variables.h>
+
+#include <vm/vm.h>
+
+#include <machine/db_machdep.h>
+#include <machine/trap.h>
+#include <machine/../vax/gencons.h>
+
+#include <setjmp.h>
+
+extern jmp_buf *db_recover;
+
+int db_active = 0;
+
+/*
+ * kdb_trap - field a TRACE or BPT trap
+ */
+int
+kdb_trap(frame)
+ struct trapframe *frame;
+{
+ int s;
+
+#if 0
+ if ((boothowto&RB_KDB) == 0)
+ return(0);
+#endif
+
+ switch (frame->trap) {
+ case T_BPTFLT: /* breakpoint */
+ case T_TRCTRAP: /* single_step */
+ break;
+ default:
+ kdbprinttrap(frame->trap, frame->code);
+ if (db_recover != 0) {
+ db_error("Faulted in DDB; continuing...\n");
+ /*NOTREACHED*/
+ }
+ }
+ bcopy(frame, &ddb_regs, sizeof(struct trapframe));
+
+ /* XXX Should switch to interrupt stack here. */
+
+
+ s = splddb();
+ mtpr(0, PR_RXCS);
+ mtpr(0, PR_TXCS);
+ db_active++;
+ db_trap(frame->trap, frame->code);
+ db_active--;
+ mtpr(GC_RIE, PR_RXCS);
+ mtpr(GC_TIE, PR_TXCS);
+ splx(s);
+
+ bcopy(&ddb_regs, frame, sizeof(struct trapframe));
+
+ return (1);
+}
+
+extern char *traptypes[];
+extern int no_traps;
+
+/*
+ * Print trap reason.
+ */
+kdbprinttrap(type, code)
+ int type, code;
+{
+ db_printf("kernel: ");
+ if (type >= no_traps || type < 0)
+ db_printf("type %d", type);
+ else
+ db_printf("%s", traptypes[type]);
+ db_printf(" trap, code=%x\n", code);
+}
+
+/*
+ * Read bytes from kernel address space for debugger.
+ */
+void
+db_read_bytes(addr, size, data)
+ vm_offset_t addr;
+ register int size;
+ register char *data;
+{
+ register char *src;
+
+ src = (char *)addr;
+ while (--size >= 0)
+ *data++ = *src++;
+}
+
+/*
+ * Write bytes to kernel address space for debugger.
+ */
+void
+db_write_bytes(addr, size, data)
+ vm_offset_t addr;
+ register int size;
+ register char *data;
+{
+ register char *dst;
+
+ dst = addr;
+ for (;size;size--)
+ *dst++ = *data++;
+}
+
+int
+Debugger()
+{
+ int s = splx(0xe); /* Is this good? We must lower anyway... */
+ mtpr(0xf, PR_SIRR); /* beg for debugger */
+ splx(s);
+}
+
+/*
+ * Machine register set.
+ * XXX - lost stackpointer.
+ */
+struct db_variable db_regs[] = {
+ "r0", &ddb_regs.r0, FCN_NULL,
+ "r1", &ddb_regs.r1, FCN_NULL,
+ "r2", &ddb_regs.r2, FCN_NULL,
+ "r3", &ddb_regs.r3, FCN_NULL,
+ "r4", &ddb_regs.r4, FCN_NULL,
+ "r5", &ddb_regs.r5, FCN_NULL,
+ "r6", &ddb_regs.r6, FCN_NULL,
+ "r7", &ddb_regs.r7, FCN_NULL,
+ "r8", &ddb_regs.r8, FCN_NULL,
+ "r9", &ddb_regs.r9, FCN_NULL,
+ "r10", &ddb_regs.r10, FCN_NULL,
+ "r11", &ddb_regs.r11, FCN_NULL,
+ "ap", &ddb_regs.ap, FCN_NULL,
+ "fp", &ddb_regs.fp, FCN_NULL,
+ "pc", &ddb_regs.pc, FCN_NULL,
+ "psl", &ddb_regs.psl, FCN_NULL,
+};
+struct db_variable *db_eregs = db_regs + sizeof(db_regs)/sizeof(db_regs[0]);
+
+void
+db_stack_trace_cmd(addr, have_addr, count, modif)
+ db_expr_t addr;
+ boolean_t have_addr;
+ db_expr_t count;
+ char *modif;
+{
+ printf("db_stack_trace_cmd - addr %x, have_addr %x, count %x, modif %x\n",addr, have_addr, count, modif);
+}
+
+static int ddbescape = 0;
+
+int
+kdbrint(tkn)
+ int tkn;
+{
+
+ if (ddbescape && ((tkn & 0x7f) == 'D')) {
+ mtpr(0xf, PR_SIRR);
+ return 1;
+ }
+
+ if ((ddbescape == 0) && ((tkn & 0x7f) == 27)) {
+ ddbescape = 1;
+ return 1;
+ }
+
+ if (ddbescape) {
+ ddbescape = 0;
+ return 2;
+ }
+
+ ddbescape = 0;
+ return 0;
+}
+
+
diff --git a/sys/arch/vax/vax/disksubr.c b/sys/arch/vax/vax/disksubr.c
new file mode 100644
index 00000000000..f59565a52dc
--- /dev/null
+++ b/sys/arch/vax/vax/disksubr.c
@@ -0,0 +1,293 @@
+/* $NetBSD: disksubr.c,v 1.6 1995/05/08 19:10:53 ragge Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988 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.
+ *
+ * @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91
+ */
+
+#include "param.h"
+#include "systm.h"
+#include "buf.h"
+#include "dkbad.h"
+#include "disklabel.h"
+#include "syslog.h"
+#include "machine/macros.h"
+
+/* XXX encoding of disk minor numbers, should be elsewhere... */
+#define dkunit(dev) (minor(dev) >> 3)
+#define dkpart(dev) (minor(dev) & 7)
+#define dkminor(unit, part) (((unit) << 3) | (part))
+
+#define b_cylin b_resid
+
+#define RAW_PART 3
+
+/*
+ * Determine the size of the transfer, and make sure it is
+ * within the boundaries of the partition. Adjust transfer
+ * if needed, and signal errors or early completion.
+ */
+int
+bounds_check_with_label(struct buf *bp, struct disklabel *lp, int wlabel)
+{
+ struct partition *p = lp->d_partitions + dkpart(bp->b_dev);
+ int labelsect = lp->d_partitions[0].p_offset;
+ int maxsz = p->p_size,
+ sz = (bp->b_bcount + DEV_BSIZE - 1) >> DEV_BSHIFT;
+
+ /* overwriting disk label ? */
+ /* XXX should also protect bootstrap in first 8K */
+ if (bp->b_blkno + p->p_offset <= LABELSECTOR + labelsect &&
+#if LABELSECTOR != 0
+ bp->b_blkno + p->p_offset + sz > LABELSECTOR + labelsect &&
+#endif
+ (bp->b_flags & B_READ) == 0 && wlabel == 0) {
+ bp->b_error = EROFS;
+ goto bad;
+ }
+
+#if defined(DOSBBSECTOR) && defined(notyet)
+ /* overwriting master boot record? */
+ if (bp->b_blkno + p->p_offset <= DOSBBSECTOR &&
+ (bp->b_flags & B_READ) == 0 && wlabel == 0) {
+ bp->b_error = EROFS;
+ goto bad;
+ }
+#endif
+
+ /* beyond partition? */
+ if (bp->b_blkno < 0 || bp->b_blkno + sz > maxsz) {
+ /* if exactly at end of disk, return an EOF */
+ if (bp->b_blkno == maxsz) {
+ bp->b_resid = bp->b_bcount;
+ return(0);
+ }
+ /* or truncate if part of it fits */
+ sz = maxsz - bp->b_blkno;
+ if (sz <= 0) {
+ bp->b_error = EINVAL;
+ goto bad;
+ }
+ bp->b_bcount = sz << DEV_BSHIFT;
+ }
+
+ /* calculate cylinder for disksort to order transfers with */
+ bp->b_cylin = (bp->b_blkno + p->p_offset) / lp->d_secpercyl;
+ return(1);
+
+bad:
+ bp->b_flags |= B_ERROR;
+ return(-1);
+}
+
+/* NYFIL */
+
+/* encoding of disk minor numbers, should be elsewhere... */
+#define dkunit(dev) (minor(dev) >> 3)
+#define dkpart(dev) (minor(dev) & 7)
+#define dkminor(unit, part) (((unit) << 3) | (part))
+
+/*
+ * Check new disk label for sensibility
+ * before setting it.
+ */
+setdisklabel(olp, nlp, openmask, osdep)
+ register struct disklabel *olp, *nlp;
+ u_long openmask;
+ struct cpu_disklabel *osdep;
+{
+ return cpu_setdisklabel(olp, nlp, openmask, osdep);
+}
+
+
+/*
+ * Write disk label back to device after modification.
+ */
+writedisklabel(dev, strat, lp, osdep)
+ dev_t dev;
+ void (*strat)();
+ register struct disklabel *lp;
+ struct cpu_disklabel *osdep;
+{
+ return cpu_writedisklabel(dev, strat, lp, osdep);
+}
+/*
+ * from: @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91
+ */
+
+/*
+ * Attempt to read a disk label from a device
+ * using the indicated stategy routine.
+ * The label must be partly set up before this:
+ * secpercyl and anything required in the strategy routine
+ * (e.g., sector size) must be filled in before calling us.
+ * Returns null on success and an error string on failure.
+ */
+char *
+readdisklabel(dev, strat, lp, osdep)
+ dev_t dev;
+ void (*strat)();
+ register struct disklabel *lp;
+ struct cpu_disklabel *osdep;
+{
+ register struct buf *bp;
+ struct disklabel *dlp;
+ char *msg = NULL;
+
+ if (lp->d_secperunit == 0)
+ lp->d_secperunit = 0x1fffffff;
+ lp->d_npartitions = 1;
+ if (lp->d_partitions[0].p_size == 0)
+ lp->d_partitions[0].p_size = 0x1fffffff;
+ lp->d_partitions[0].p_offset = 0;
+
+ bp = geteblk((int)lp->d_secsize);
+ bp->b_dev = dev;
+ bp->b_blkno = LABELSECTOR;
+ bp->b_bcount = lp->d_secsize;
+ bp->b_flags = B_BUSY | B_READ;
+ bp->b_cylin = LABELSECTOR / lp->d_secpercyl;
+ (*strat)(bp);
+ if (biowait(bp)) {
+ msg = "I/O error";
+ } else for (dlp = (struct disklabel *)bp->b_un.b_addr;
+ dlp <= (struct disklabel *)(bp->b_un.b_addr+DEV_BSIZE-sizeof(*dlp));
+ dlp = (struct disklabel *)((char *)dlp + sizeof(long))) {
+ if (dlp->d_magic != DISKMAGIC || dlp->d_magic2 != DISKMAGIC) {
+ if (msg == NULL)
+ msg = "no disk label";
+ } else if (dlp->d_npartitions > MAXPARTITIONS ||
+ dkcksum(dlp) != 0)
+ msg = "disk label corrupted";
+ else {
+ *lp = *dlp;
+ msg = NULL;
+ break;
+ }
+ }
+ bp->b_flags = B_INVAL | B_AGE;
+ brelse(bp);
+ return (msg);
+}
+
+/*
+ * Check new disk label for sensibility
+ * before setting it.
+ */
+cpu_setdisklabel(olp, nlp, openmask, osdep)
+ register struct disklabel *olp, *nlp;
+ u_long openmask;
+ struct cpu_disklabel *osdep;
+{
+ register i;
+ register struct partition *opp, *npp;
+
+ if (nlp->d_magic != DISKMAGIC || nlp->d_magic2 != DISKMAGIC ||
+ dkcksum(nlp) != 0)
+ return (EINVAL);
+ while ((i = ffs((long)openmask)) != 0) {
+ i--;
+ openmask &= ~(1 << i);
+ if (nlp->d_npartitions <= i)
+ return (EBUSY);
+ opp = &olp->d_partitions[i];
+ npp = &nlp->d_partitions[i];
+ if (npp->p_offset != opp->p_offset || npp->p_size < opp->p_size)
+ return (EBUSY);
+ /*
+ * Copy internally-set partition information
+ * if new label doesn't include it. XXX
+ */
+ if (npp->p_fstype == FS_UNUSED && opp->p_fstype != FS_UNUSED) {
+ npp->p_fstype = opp->p_fstype;
+ npp->p_fsize = opp->p_fsize;
+ npp->p_frag = opp->p_frag;
+ npp->p_cpg = opp->p_cpg;
+ }
+ }
+ nlp->d_checksum = 0;
+ nlp->d_checksum = dkcksum(nlp);
+ *olp = *nlp;
+ return (0);
+}
+
+/* encoding of disk minor numbers, should be elsewhere... */
+#define dkunit(dev) (minor(dev) >> 3)
+#define dkminor(unit, part) (((unit) << 3) | (part))
+
+/*
+ * Write disk label back to device after modification.
+ */
+cpu_writedisklabel(dev, strat, lp, osdep)
+ dev_t dev;
+ int (*strat)();
+ register struct disklabel *lp;
+ struct cpu_disklabel *osdep;
+{
+ struct buf *bp;
+ struct disklabel *dlp;
+ int labelpart;
+ int error = 0;
+
+ labelpart = dkpart(dev);
+ if (lp->d_partitions[labelpart].p_offset != 0) {
+ if (lp->d_partitions[0].p_offset != 0)
+ return (EXDEV); /* not quite right */
+ labelpart = 0;
+ }
+ bp = geteblk((int)lp->d_secsize);
+ bp->b_dev = makedev(major(dev), dkminor(dkunit(dev), labelpart));
+ bp->b_blkno = LABELSECTOR;
+ bp->b_bcount = lp->d_secsize;
+ bp->b_flags = B_READ;
+ (*strat)(bp);
+ if (error = biowait(bp))
+ goto done;
+ for (dlp = (struct disklabel *)bp->b_un.b_addr;
+ dlp <= (struct disklabel *)
+ (bp->b_un.b_addr + lp->d_secsize - sizeof(*dlp));
+ dlp = (struct disklabel *)((char *)dlp + sizeof(long))) {
+ if (dlp->d_magic == DISKMAGIC && dlp->d_magic2 == DISKMAGIC &&
+ dkcksum(dlp) == 0) {
+ *dlp = *lp;
+ bp->b_flags = B_WRITE;
+ (*strat)(bp);
+ error = biowait(bp);
+ goto done;
+ }
+ }
+ error = ESRCH;
+done:
+ brelse(bp);
+ return (error);
+}
diff --git a/sys/arch/vax/vax/emulate.s b/sys/arch/vax/vax/emulate.s
new file mode 100644
index 00000000000..7a6fc026577
--- /dev/null
+++ b/sys/arch/vax/vax/emulate.s
@@ -0,0 +1,1297 @@
+/* $NetBSD: emulate.s,v 1.1 1995/02/24 01:35:08 ragge Exp $ */
+/*
+ * Copyright (c) 1986, 1987 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Mt. Xinu.
+ *
+ * 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.
+ *
+ * @(#)emulate.s 7.5 (Berkeley) 6/28/90
+ */
+
+#if VAX630 || VAX650
+/*
+ * String instruction emulation - MicroVAX only. These routines are called
+ * from locore.s when an "emulate" fault occurs on the MicroVAX. They are
+ * called with the stack set up as follows:
+ *
+ * (sp): Return address of trap handler
+ * 4(sp): Instruction Opcode (also holds PSL result from emulator)
+ * 8(sp): Instruction PC
+ * 12(sp): Operand 1
+ * 16(sp): Operand 2
+ * 20(sp): Operand 3
+ * 24(sp): Operand 4
+ * 28(sp): Operand 5
+ * 32(sp): Operand 6
+ * 36(sp): old Register 11
+ * 40(sp): old Register 10
+ * 44(sp): Return PC
+ * 48(sp): Return PSL
+ * 52(sp): TOS before instruction
+ *
+ * R11 and r10 are available for use. If any routine needs to use r9-r1
+ * they need to save them first (unless those registers are SUPPOSED to be
+ * messed with by the "instruction"). These routines leave their results
+ * in registers 0-5 explicitly, as needed, and use the macros defined below
+ * to link up with calling routine.
+ */
+
+#define return rsb
+#define savepsl movpsl 4(sp)
+#define setpsl(reg) movl reg,4(sp)
+#define overflowpsl movl $2,4(sp)
+#define arg1 12(sp)
+#define arg2 16(sp)
+#define arg3 20(sp)
+#define arg4 24(sp)
+#define arg5 28(sp)
+#define arg6 32(sp)
+#define argub(num,reg) movzbl 8+4*num(sp),reg
+#define arguw(num,reg) movzwl 8+4*num(sp),reg
+#define argul(num,reg) movl 8+4*num(sp),reg
+#define argb(num,reg) cvtbl 8+4*num(sp),reg
+#define argw(num,reg) cvtwl 8+4*num(sp),reg
+#define argl(num,reg) movl 8+4*num(sp),reg
+#define toarg(reg,num) movl reg,8+4*num(sp)
+
+
+ .text
+ .align 1
+ .globl _EMcrc
+_EMcrc:
+ argl(1,r11) # (1) table address == r11
+ argl(2,r0) # (2) initial crc == r0
+ argl(4,r3) # (4) source address == r3
+ arguw(3,r2) # (3) source length == r2
+ jeql Lcrc_out
+Lcrc_loop:
+ xorb2 (r3)+,r0
+ extzv $0,$4,r0,r10
+ extzv $4,$28,r0,r1
+ xorl3 r1,(r11)[r10],r0
+ extzv $0,$4,r0,r10
+ extzv $4,$28,r0,r1
+ xorl3 r1,(r11)[r10],r0
+ sobgtr r2,Lcrc_loop
+ tstl r0
+Lcrc_out:
+ savepsl
+ clrl r1
+ return
+
+
+ .align 1
+ .globl _EMmovtc
+_EMmovtc:
+ arguw(1,r0) # (1) source length == r0
+ argl(2,r1) # (2) source address == r1
+ argub(3,r11) # (3) fill character == r11
+ argl(4,r3) # (4) table address == r3
+ argl(6,r5) # (6) destination address == r5
+ arguw(5,r4) # (5) destination length == r4
+ jeql Lmovtc_out
+Lmovtc_loop:
+ tstl r0
+ jeql Lmovtc_2loop
+ movzbl (r1)+,r2
+ movb (r3)[r2],(r5)+
+ decl r0
+ sobgtr r4,Lmovtc_loop
+ jbr Lmovtc_out
+Lmovtc_2loop:
+ movb r11,(r5)+
+ sobgtr r4,Lmovtc_2loop
+Lmovtc_out:
+ cmpl r4,r0
+ savepsl
+ clrl r2
+ return
+
+
+ .align 1
+ .globl _EMmovtuc
+_EMmovtuc:
+ arguw(1,r0) # (1) source length == r0
+ argl(2,r1) # (2) source address == r1
+ argub(3,r11) # (3) escape character == r11
+ argl(4,r3) # (4) table address == r3
+ argl(6,r5) # (6) destination address == r5
+ arguw(5,r4) # (5) destination length == r4
+ jeql Lmovtuc_out
+Lmovtuc_loop:
+ tstl r0
+ jeql Lmovtuc_out
+ movzbl (r1),r2
+ movzbl (r3)[r2],r2
+ cmpl r2,r11
+ jeql Lmovtuc_out
+ movzbl (r1)+,r2
+ movb (r3)[r2],(r5)+
+ decl r0
+ sobgtr r4,Lmovtuc_loop
+Lmovtuc_out:
+ cmpl r4,r0
+ savepsl
+ clrl r2
+ return
+
+
+ .align 1
+ .globl _EMmatchc
+_EMmatchc:
+ argl(2,r10) # (2) substring address == r10
+ arguw(3,r2) # (3) source length == r2
+ argl(4,r3) # (4) source address == r3
+ arguw(1,r11) # (1) substring length == r11
+ jeql Lmatchc_out # temp source address == r1
+ addl2 r10,r11 # temp substring address == r0
+ tstl r2
+ jeql Lmatchc_out
+Lmatchc_loop:
+ cmpb (r10),(r3)
+ jneq Lmatchc_fail
+ movl r3,r1
+ movl r10,r0
+Lmatchc_2loop:
+ cmpl r0,r11
+ jeql Lmatchc_succ
+ cmpb (r0)+,(r1)+
+ jeql Lmatchc_2loop
+Lmatchc_fail:
+ incl r3
+ sobgtr r2,Lmatchc_loop
+ movl r10,r1
+ subl3 r10,r11,r0
+ jbr Lmatchc_out
+Lmatchc_succ:
+ movl r1,r3
+ movl r11,r1
+ clrl r0
+Lmatchc_out:
+ savepsl
+ return
+
+
+ .align 1
+ .globl _EMspanc
+_EMspanc:
+ argl(2,r1) # (2) string address == r1
+ argub(4,r2) # (4) character-mask == r2
+ argl(3,r3) # (3) table address == r3
+ arguw(1,r0) # (1) string length == r0
+ jeql Lspanc_out
+Lspanc_loop:
+ movzbl (r1),r11
+ mcomb (r3)[r11],r11
+ bicb3 r11,r2,r11
+ jeql Lspanc_out
+ incl r1
+ sobgtr r0,Lspanc_loop
+Lspanc_out:
+ savepsl
+ clrl r2
+ return
+
+
+ .align 1
+ .globl _EMscanc
+_EMscanc:
+ argl(2,r1) # (2) string address == r1
+ argub(4,r2) # (4) character-mask == r2
+ argl(3,r3) # (3) table address == r3
+ arguw(1,r0) # (1) string length == r0
+ jeql Lscanc_out
+Lscanc_loop:
+ movzbl (r1),r11
+ mcomb (r3)[r11],r11
+ bicb3 r11,r2,r11
+ jneq Lscanc_out
+ incl r1
+ sobgtr r0,Lscanc_loop
+Lscanc_out:
+ savepsl
+ clrl r2
+ return
+
+
+ .align 1
+ .globl _EMskpc
+_EMskpc:
+ argub(1,r11) # (1) character == r11
+ argl(3,r1) # (3) string address == r1
+ arguw(2,r0) # (2) string length == r0
+ jeql Lskpc_out # forget zero length strings
+Lskpc_loop:
+ cmpb (r1),r11
+ jneq Lskpc_out
+ incl r1
+ sobgtr r0,Lskpc_loop
+Lskpc_out:
+ tstl r0 # be sure of condition codes
+ savepsl
+ return
+
+
+ .align 1
+ .globl _EMlocc
+_EMlocc:
+ argub(1,r11) # (1) character == r11
+ argl(3,r1) # (3) string address == r1
+ arguw(2,r0) # (2) string length == r0
+ jeql Lskpc_out # forget zero length strings
+Llocc_loop:
+ cmpb (r1),r11
+ jeql Llocc_out
+ incl r1
+ sobgtr r0,Llocc_loop
+Llocc_out:
+ tstl r0 # be sure of condition codes
+ savepsl
+ return
+
+
+ .align 1
+ .globl _EMcmpc3
+_EMcmpc3:
+ argl(2,r1) # (2) string1 address == r1
+ argl(3,r3) # (3) string2 address == r3
+ arguw(1,r0) # (1) strings length == r0
+ jeql Lcmpc3_out
+Lcmpc3_loop:
+ cmpb (r1),(r3)
+ jneq Lcmpc3_out
+ incl r1
+ incl r3
+ sobgtr r0,Lcmpc3_loop
+Lcmpc3_out:
+ savepsl
+ movl r0,r2
+ return
+
+
+ .align 1
+ .globl _EMcmpc5
+_EMcmpc5:
+ argl(2,r1) # (2) string1 address == r1
+ argub(3,r11) # (1) fill character == r11
+ arguw(4,r2) # (1) string2 length == r2
+ argl(5,r3) # (3) string2 address == r3
+ arguw(1,r0) # (1) string1 length == r0
+ jeql Lcmpc5_str2
+Lcmpc5_loop:
+ tstl r2
+ jeql Lcmpc5_str1loop
+ cmpb (r1),(r3)
+ jneq Lcmpc5_out
+ incl r1
+ incl r3
+ decl r2
+ sobgtr r0,Lcmpc5_loop
+Lcmpc5_str2:
+ tstl r2
+ jeql Lcmpc5_out
+Lcmpc5_str2loop:
+ cmpb r11,(r3)
+ jneq Lcmpc5_out
+ incl r3
+ sobgtr r2,Lcmpc5_str2loop
+ jbr Lcmpc5_out
+Lcmpc5_str1loop:
+ cmpb (r1),r11
+ jneq Lcmpc5_out
+ incl r1
+ sobgtr r0,Lcmpc5_str1loop
+Lcmpc5_out:
+ savepsl
+ return
+
+
+/*
+ * Packed Decimal string operations
+ */
+
+#define POSITIVE $12
+#define NEGATIVE $13
+#define NEGATIVEalt $11
+
+
+ .align 1
+ .globl _EMaddp4
+_EMaddp4:
+ toarg(r9,6) # save register r9 in arg6 spot
+ arguw(1,r11) # (1) source length == r11
+ argl(2,r10) # (2) source address == r10
+ arguw(3,r9) # (3) destination length == r9
+ argl(4,r3) # (4) destination address == r3
+ ashl $-1,r11,r11
+ addl2 r11,r10 # source address of LSNibble
+ incl r11 # source length is in bytes
+ ashl $-1,r9,r9
+ addl2 r9,r3 # r3 = destination address of LSNibble
+ incl r9 # destination length is in bytes
+ toarg(r3,5)
+ extzv $0,$4,(r3),r2 # set standard +/- indicators in destination
+ cmpl r2,NEGATIVE
+ jeql L112
+ cmpl r2,NEGATIVEalt
+ jeql L111
+ insv POSITIVE,$0,$4,(r3)
+ jbr L112
+L111:
+ insv NEGATIVE,$0,$4,(r3)
+L112:
+ extzv $0,$4,(r10),r2 # r2 = standard +/- of source
+ cmpl r2,NEGATIVE
+ jeql L114
+ cmpl r2,NEGATIVEalt
+ jeql L113
+ movl POSITIVE,r2
+ jbr L114
+L113:
+ movl NEGATIVE,r2
+L114:
+ cmpl r11,r9 # if source is longer than destination
+ jleq L115
+ movl r9,r11 # set source length == destination length
+L115:
+ extzv $4,$4,(r3),r9 # r9 = LSDigit of destination
+ extzv $4,$4,(r10),r1 # r1 = LSDigit of source
+ extzv $0,$4,(r3),r0
+ cmpl r0,r2 # if signs of operands are not equal
+ jeql Laddp4_same # do a subtraction
+ clrl r2 # r2 is non-zero if result is non-zero
+ subl2 r1,r9 # r9 = "addition" of operands high nibble
+ jbr L119 # jump into addition loop
+Laddp4_diff_loop:
+ decl r3
+ extzv $0,$4,(r3),r0
+ addl2 r0,r1 # r1 = carry + next (low) nibble of source
+ decl r10
+ extzv $0,$4,(r10),r0
+ subl2 r0,r1 # r1 -= next (low) nibble of destination
+ jgeq L121 # if negative result
+ mnegl $1,r9 # r9 == carry = -1
+ addl2 $10,r1 # r1 == result += 10
+ jbr L122 # else
+L121:
+ clrl r9 # r9 == carry = 0
+L122:
+ insv r1,$0,$4,(r3) # store result low nibble
+ bisl2 r1,r2
+ extzv $4,$4,(r3),r0
+ addl2 r0,r9 # r9 = carry + next (high) nibble of source
+ extzv $4,$4,(r10),r0
+ subl2 r0,r9 # r9 -= next (high) nibble of destination
+L119:
+ jgeq L117 # if negative result
+ mnegl $1,r1 # r1 == carry = -1
+ addl2 $10,r9 # r9 == result += 10
+ jbr L118 # else
+L117:
+ clrl r1 # r1 == carry = 0
+L118:
+ insv r9,$4,$4,(r3) # store result high nibble
+ bisl2 r9,r2 # r2 is non-zero if result is non-zero
+ decl r11 # while (--source length)
+ jneq Laddp4_diff_loop
+ argl(4,r10) # r10 = address of destination MSNibble
+ jbr Laddp4_diff_carry
+Laddp4_diff_carlop:
+ decl r3
+ extzv $0,$4,(r3),r0
+ addl2 r0,r1 # r1 == carry += next (low) nibble
+ jgeq L127 # if less than zero
+ movl r1,r9 # r9 == carry (must be -1)
+ movl $9,r1 # r1 == result = 9
+ jbr L128
+L127: # else
+ clrl r9 # r9 == carry = 0
+L128:
+ insv r1,$0,$4,(r3) # store result
+ bisl2 r1,r2
+ extzv $4,$4,(r3),r0
+ addl2 r0,r9 # r9 == carry += next (high) nibble
+ jgeq L129 # if less than zero
+ movl r9,r1 # r1 == carry (must be -1)
+ movl $9,r9 # r9 == result = 9
+ jbr L130
+L129:
+ clrl r1
+L130:
+ insv r9,$4,$4,(r3) # store result
+ bisl2 r9,r2
+Laddp4_diff_carry:
+ cmpl r3,r10
+ jneq Laddp4_diff_carlop
+ tstl r1 # if carry out of MSN then fix up result
+ jeql Laddp4_add_done
+ argl(5,r3) # r3 == address of LSN of destination
+ extzv $0,$4,(r3),r0
+ cmpl r0,NEGATIVE # switch sign of result
+ jneq L132
+ insv POSITIVE,$0,$4,(r3)
+ jbr L133
+L132:
+ insv NEGATIVE,$0,$4,(r3)
+L133:
+ extzv $4,$4,(r3),r0 # normalize result (carry out of MSN into LSN)
+ subl3 r0,$10,r9 # r9 = 10 - destination LSNibble
+ jbr L134
+L137:
+ movl $9,r1
+Laddp4_diff_norm:
+ insv r9,$4,$4,(r3)
+ cmpl r3,r10 # while (not at MSNibble)
+ jeql Laddp4_add_done
+ decl r3
+ extzv $0,$4,(r3),r0 # low nibble = (9 + carry) - low nibble
+ subl2 r0,r1
+ cmpl r1,$9
+ jleq L135
+ clrl r1
+ movl $10,r9
+ jbr L136
+L135:
+ movl $9,r9
+L136:
+ insv r1,$0,$4,(r3)
+ extzv $4,$4,(r3),r0 # high nibble = (9 + carry) - high nibble
+ subl2 r0,r9
+L134:
+ cmpl r9,$9
+ jleq L137
+ clrl r9
+ movl $10,r1
+ jbr Laddp4_diff_norm
+
+Laddp4_same: # operands are of the same sign
+ clrl r2
+ addl2 r1,r9
+ jbr L139
+Laddp4_same_loop:
+ decl r3
+ extzv $0,$4,(r3),r0
+ addl2 r0,r1 # r1 == carry += next (low) nibble of dest
+ decl r10
+ extzv $0,$4,(r10),r0
+ addl2 r0,r1 # r1 += next (low) nibble of source
+ cmpl r1,$9 # if result > 9
+ jleq L141
+ movl $1,r9 # r9 == carry = 1
+ subl2 $10,r1 # r1 == result -= 10
+ jbr L142
+L141: # else
+ clrl r9 # r9 == carry = 0
+L142:
+ insv r1,$0,$4,(r3) # store result
+ bisl2 r1,r2
+ extzv $4,$4,(r10),r0
+ addl2 r0,r9 # ditto for high nibble
+ extzv $4,$4,(r3),r0
+ addl2 r0,r9
+L139:
+ cmpl r9,$9
+ jleq L143
+ movl $1,r1
+ subl2 $10,r9
+ jbr L144
+L143:
+ clrl r1
+L144:
+ insv r9,$4,$4,(r3)
+ bisl2 r9,r2
+ sobgtr r11,Laddp4_same_loop # while (--source length)
+ argl(4,r10) # r10 = destination address of MSNibble
+ jbr Laddp4_same_carry
+Laddp4_same_cloop:
+ decl r3
+ extzv $0,$4,(r3),r0 # propagate carry up to MSNibble of destination
+ addl2 r0,r1
+ cmpl r1,$10
+ jneq L147
+ movl $1,r9
+ clrl r1
+ jbr L148
+L147:
+ clrl r9
+L148:
+ insv r1,$0,$4,(r3)
+ bisl2 r1,r2
+ extzv $4,$4,(r3),r0
+ addl2 r0,r9
+ cmpl r9,$10
+ jneq L149
+ movl $1,r1
+ clrl r9
+ jbr L150
+L149:
+ clrl r1
+L150:
+ insv r9,$4,$4,(r3)
+ bisl2 r9,r2
+Laddp4_same_carry:
+ cmpl r3,r10
+ jneq Laddp4_same_cloop
+
+Laddp4_add_done:
+ argl(5,r3) # r3 = destination address of LSNibble
+ tstl r2 # if zero result
+ jneq L151
+ savepsl # remember that for condition codes
+ insv POSITIVE,$0,$4,(r3) # make sure sign of result is positive
+ jbr Laddp4_out
+L151: # else
+ extzv $0,$4,(r3),r0
+ cmpl r0,NEGATIVE # if result is negative
+ jneq Laddp4_out
+ mnegl r2,r2 # remember THAT in Cond Codes
+ savepsl
+Laddp4_out:
+ argl(4,r3)
+ argl(2,r1)
+ clrl r0
+ clrl r2
+ argl(6,r9) # restore r9 from stack
+ return
+
+
+ .align 1
+ .globl _EMmovp
+_EMmovp:
+ arguw(1,r11) # (1) string length == r11
+ argl(2,r10) # (1) source address == r10
+ argl(3,r3) # (1) destination address == r3
+ # we will need arg2 and arg3 later
+ clrl r2 # r2 == non-zero if source is non-zero
+ ashl $-1,r11,r11 # length is number of bytes, not nibbles
+ jeql Lmovp_zlen
+Lmovp_copy:
+ bisb2 (r10),r2 # keep track of non-zero source
+ movb (r10)+,(r3)+ # move two nibbles
+ sobgtr r11,Lmovp_copy # loop for length of source
+Lmovp_zlen:
+ extzv $4,$4,(r10),r0 # look at least significant nibble
+ bisl2 r0,r2
+ extzv $0,$4,(r10),r0 # check sign nibble
+ cmpl r0,NEGATIVEalt
+ jeql Lmovp_neg
+ cmpl r0,NEGATIVE
+ jneq Lmovp_pos
+Lmovp_neg: # source was negative
+ mnegl r2,r2
+Lmovp_pos:
+ tstl r2 # set condition codes
+ savepsl
+ jeql Lmovp_zero
+ movb (r10),(r3) # move last byte if non-zero result
+ jbr Lmovp_out
+Lmovp_zero:
+ movb POSITIVE,(r3) # otherwise, make result zero and positive
+Lmovp_out:
+ clrl r0
+ argl(2,r1)
+ clrl r2
+ argl(3,r3)
+ return
+
+
+/*
+ * Definitions for Editpc instruction
+ *
+ * Here are the commands and their corresponding hex values:
+ *
+ * EPend 0x00
+ * EPend_float 0x01
+ * EPclear_signif 0x02
+ * EPset_signif 0x03
+ * EPstore_sign 0x04
+ * EPload_fill 0x40
+ * EPload_sign 0x41
+ * EPload_plus 0x42
+ * EPload_minus 0x43
+ * EPinsert 0x44
+ * EPblank_zero 0x45
+ * EPreplace_sign 0x46
+ * EPadjust_input 0x47
+ * EPfill 0x80
+ * EPmove 0x90
+ * EPfloat 0xa0
+ *
+ *
+ * r4 is carved up as follows:
+ *
+ * -------------------------------------------
+ * | N Z V C |
+ * -------------------------------------------
+ *
+ * fill character is stuffed into arg5 space
+ * sign character is stuffed into arg6 space
+ */
+
+#define SIGNIFBIT $0
+#define setsignif bisl2 $1,r4
+#define clsignif bicl2 $1,r4
+#define OVERFLOWBIT $1
+#define setoverflow bisl2 $2,r4
+#define cloverflow bicl2 $2,r4
+#define ZEROBIT $2
+#define setzero bisl2 $4,r4
+#define clzero bicl2 $4,r4
+#define NEGATIVEBIT $3
+#define setnegative bisl2 $8,r4
+#define clnegative bicl2 $8,r4
+#define putfill movb arg5,(r5)+
+#define setfill(reg) movb reg,arg5
+#define putsign movb arg6,(r5)+
+#define setsign(reg) movb reg,arg6
+
+
+ .align 1
+ .globl _EMeditpc
+_EMeditpc:
+ arguw(1,r11) # (1) source length == r11
+ argl(2,r10) # (2) source address == r10
+ argl(3,r3) # (3) pattern address == r3
+ argl(4,r5) # (4) destination address == r5
+/* # we will need arg1 and arg2 later */
+/* # arg5 and arg6 are used for fill and sign - r0 is free */
+ setfill($32) # fill character is ' '
+ setsign($32) # sign character is ' '
+ clrl r4 # clear flags
+ ashl $-1,r11,r11 # source length / 2
+ addl3 r11,r10,r2
+ extzv $4,$4,(r2),r1 # r1 == least significant nibble of source
+L169:
+ cmpl r2,r10
+ jeql L170
+ tstb -(r2) # loop over source packed decimal number
+ jeql L169
+ incl r1 # r1 is non-zero if source is non-zero
+L170:
+ addl3 r11,r10,r2
+ tstl r1
+ jeql L172 # source is zero - set flags
+ extzv $0,$4,(r2),r11
+ cmpl r11,NEGATIVEalt
+ jeql L9998 # source is negative - set sign and flags
+ cmpl r11,NEGATIVE
+ jneq L175
+L9998:
+ setnegative
+ setsign($45) # sign character is '-'
+ jbr L175
+L172:
+ setzero
+L175:
+ arguw(1,r2) # (1) source length == r2
+Ledit_case:
+ movzbl (r3)+,r11 # get next edit command (pattern)
+ cmpl r11,$128
+ jlss L180
+ extzv $0,$4,r11,r1 # command has a "count" arg - into r1
+ ashl $-4,r11,r11 # and shift over
+L180:
+ jbc $6,r11,L181 # "shift" those commands > 64 to 16 and up
+ subl2 $48,r11
+L181:
+ caseb r11,$0,$0x18 # "do" the command
+ # r11 is available for use, r1 has "count" in it
+Lcaseb_label:
+ .word Le_end - Lcaseb_label # 00
+ .word Le_end_float - Lcaseb_label # 01
+ .word Le_clear_signif - Lcaseb_label # 02
+ .word Le_set_signif - Lcaseb_label # 03
+ .word Le_store_sign - Lcaseb_label # 04
+ .word Le_end - Lcaseb_label # 05
+ .word Le_end - Lcaseb_label # 06
+ .word Le_end - Lcaseb_label # 07
+ .word Le_fill - Lcaseb_label # 80
+ .word Le_move - Lcaseb_label # 90
+ .word Le_float - Lcaseb_label # a0
+ .word Le_end - Lcaseb_label # b0
+ .word Le_end - Lcaseb_label # c0
+ .word Le_end - Lcaseb_label # d0
+ .word Le_end - Lcaseb_label # e0
+ .word Le_end - Lcaseb_label # f0
+ .word Le_load_fill - Lcaseb_label # 40
+ .word Le_load_sign - Lcaseb_label # 41
+ .word Le_load_plus - Lcaseb_label # 42
+ .word Le_load_minus - Lcaseb_label # 43
+ .word Le_insert - Lcaseb_label # 44
+ .word Le_blank_zero - Lcaseb_label # 45
+ .word Le_replace_sign - Lcaseb_label # 46
+ .word Le_adjust_input - Lcaseb_label # 47
+Le_end:
+ arguw(1,r0)
+ argl(2,r1)
+ clrl r2
+ decl r3
+ setpsl(r4)
+ clrl r4
+ return
+
+Le_end_float:
+ jbs SIGNIFBIT,r4,Ledit_case # if significance not set
+ putsign # drop in the sign
+ # fall into...
+Le_set_signif:
+ setsignif
+ jbr Ledit_case
+
+Le_clear_signif:
+ clsignif
+ jbr Ledit_case
+
+Le_store_sign:
+ putsign
+ jbr Ledit_case
+
+Le_load_fill:
+ setfill((r3)+)
+ jbr Ledit_case
+
+Le_load_plus:
+ jbs NEGATIVEBIT,r4,Lpattern_inc # if non-negative
+ # fall into...
+Le_load_sign:
+ setsign((r3)+)
+ jbr Ledit_case
+
+Le_load_minus:
+ jbs NEGATIVEBIT,r4,Le_load_sign # if negative load the sign
+ incl r3 # else increment pattern
+ jbr Ledit_case
+
+Le_insert:
+ jbc SIGNIFBIT,r4,L196 # if significance set, put next byte
+ movb (r3)+,(r5)+
+ jbr Ledit_case
+L196: # else put in fill character
+ putfill
+ # and throw away character in pattern
+Le_replace_sign: # we dont do anything with
+Lpattern_inc: # replace sign cause we dont
+ incl r3 # get negative zero
+ jbr Ledit_case
+
+Le_blank_zero:
+ jbc ZEROBIT,r4,Lpattern_inc # if zero
+ movzbl (r3)+,r11 # next byte is a count
+ jeql Ledit_case
+ subl2 r11,r5 # to back up over output and replace
+L200:
+ putfill # with fill character
+ sobgtr r11,L200
+ jbr Ledit_case
+
+Le_adjust_input:
+ movzbl (r3)+,r0 # get count of nibbles from pattern
+ subl3 r2,r0,r11
+ jgeq Ledit_case # if length of source is > this number
+L204: # discard digits in source
+ jlbc r2,L206 # use low bit of length to choose nibble
+ bitb $0xf0,(r10) # high nibble
+ jeql L208
+ setsignif # set significance and overflow if
+ setoverflow # wasted digit is non-zero
+ jbr L208
+L206:
+ bitb $0xf,(r10) # low nibble
+ jeql L209
+ setsignif
+ setoverflow
+L209:
+ incl r10 # increment to next byte
+L208:
+ decl r2 # decrement source length
+ incl r11 # continue till were out of excess
+ jlss L204
+ jbr Ledit_case
+
+Le_fill:
+ tstl r1 # put (count in r1) fill characters
+ jeql Ledit_case
+Le_fill_loop:
+ putfill
+ sobgtr r1,Le_fill_loop
+ jbr Ledit_case
+
+Le_move:
+ tstl r1 # move (count in r1) characters
+ jeql Ledit_case # from source to destination
+L214:
+ jlbc r2,L215 # read a nibble
+ extzv $4,$4,(r10),r11
+ jbr L216
+L215:
+ extzv $0,$4,(r10),r11
+ incl r10
+L216:
+ decl r2 # source length CAN go negative here...
+ tstl r11
+ jeql L218 # if non-zero
+ setsignif # set significance
+L218:
+ jbc SIGNIFBIT,r4,L219 # if significance set
+ addb3 $48,r11,(r5)+ # put 0 + digit into destination
+ jbr L220
+L219: # else put fill character
+ putfill
+L220:
+ sobgtr r1,L214
+ jbr Ledit_case
+
+Le_float: # move with floating sign character
+ tstl r1
+ jeql Ledit_case
+L221:
+ jlbc r2,L222
+ extzv $4,$4,(r10),r11
+ jbr L223
+L222:
+ extzv $0,$4,(r10),r11
+ incl r10
+L223:
+ decl r2 # source length CAN go negative here...
+ tstl r11
+ jeql L225
+ jbs SIGNIFBIT,r4,L226
+ putsign
+L226:
+ setsignif
+L225:
+ jbc SIGNIFBIT,r4,L227
+ addb3 $48,r11,(r5)+
+ jbr L228
+L227:
+ putfill
+L228:
+ sobgtr r1,L221
+ jbr Ledit_case
+
+
+ .align 1
+ .globl _EMashp
+_EMashp:
+ argb(1,r11) # (1) scale (number to shift) == r11
+ arguw(2,r10) # (2) source length == r10
+ argl(3,r1) # (3) source address == r1
+ argub(4,r2) # (4) rounding factor == r2
+ arguw(5,r3) # (5) destination length == r3
+ toarg(r6,3)/* # arg3 holds register 6 from caller */
+ argl(6,r6) # (6) destination address == r6
+/*
+ # we need arg6 for later
+ # arg1 is used for temporary storage
+ # arg2 holds "even or odd" destination length
+ # arg4 is used as general storage
+ # arg5 is used as general storage
+*/
+ ashl $-1,r3,r0 # destination length is number of bytes
+ addl2 r0,r6 # destination address == least sig nibble
+ toarg(r6,1) # save in arg1 spot for later
+ ashl $-1,r10,r0
+ addl2 r0,r1 # source address == least sig nibble
+ extzv $0,$4,(r1),r0 # determine sign of source
+ cmpl r0,NEGATIVEalt
+ jeql Lashp_neg
+ cmpl r0,NEGATIVE
+ jeql Lashp_neg
+ movb POSITIVE,(r6)
+ jbr L245
+Lashp_neg:
+ movb NEGATIVE,(r6)
+L245:
+ clrl arg2 # arg2 is 1 if dstlen is even, 0 if odd
+ blbs r3,L246
+ incl arg2
+ bisl2 $1,r3 # r3<0> counts digits going into destination
+L246: # and is flip-flop for which nibble to
+ tstl r11 # write in destination (1 = high, 0 = low)
+ jgeq Lashp_left # (it must start out odd)
+ addl2 r11,r10 # scale is negative (right shift)
+ jgeq Lashp_right
+ clrl r10 # test for shifting whole number out
+ jbr Lashp_setround
+Lashp_right:
+ divl3 $2,r11,r0
+ addl2 r0,r1 # source address == MSNibble to be shifted off
+ jlbc r11,L249
+ extzv $4,$4,(r1),r0
+ addl2 r0,r2 # round = last nibble to be shifted off + round
+ jbr Lashp_setround
+L249:
+ extzv $0,$4,(r1),r0
+ addl2 r0,r2 # round = last nibble to be shifted off + round
+Lashp_setround: # r11<0> now is flip-flop for which nibble to
+ incl r11 # read from source (1 == high, 0 == low)
+ cmpl r2,$9 # set rounding factor to one if nibble shifted
+ jleq Lashp_noround # off + round argument was 10 or greater
+ movl $1,r2
+ jbr Lashp_shift
+Lashp_zloop:
+ jlbs r3,L257 # dont need to clear high nibble twice
+ clrb -(r6) # clear low (and high) nib of next byte in dest
+L257:
+ sobgtr r3,L258 # move to next nibble in destination, but
+ incl r3 # dont go beyond the end.
+L258:
+ decl r11
+Lashp_left: # while scale is positive
+ jneq Lashp_zloop
+ incl r11 # r11<0> is flip-plop ... (incl sets it to one)
+Lashp_noround:
+ clrl r2 # no more rounding
+Lashp_shift:
+ clrl arg4 # arg4 will be used for result condition codes
+ tstl r10
+ jeql Lashp_round
+Lashp_shloop:
+ jlbc r11,L260
+ extzv $4,$4,(r1),r0
+ jbr L261
+L260:
+ decl r1
+ extzv $0,$4,(r1),r0
+L261:
+ incl r11 # flip the source nibble flip/flop
+ addl2 r0,r2 # round += next nibble
+ cmpl r2,$10 # if round == 10
+ jneq L262
+ clrl arg5 # then result = 0 and round = 1
+ movl $1,r2
+ jbr L263
+L262: # else
+ movl r2,arg5 # store result and round = 0
+ clrl r2
+L263:
+ bisl2 arg5,arg4 # remember if result was nonzero in arg4
+ decl r3 # move to next nibble early to check
+ cmpl r3,arg2 # if weve moved passed destination limits
+ jgeq Lashp_noovfl # test the result for possible overflow
+ movl arg2,r3 # ignore zero nibbles
+ tstl arg5 # if the nibble was non-zero, overflow
+ jeql L265
+ jbr Lashp_overfl
+Lashp_noovfl: # else
+ jlbs r3,L264
+ insv arg5,$4,$4,(r6) # put the result into destination (high or low)
+ jbr L265
+L264:
+ movb arg5,-(r6)
+L265:
+ sobgtr r10,Lashp_shloop # loop for length of source
+
+Lashp_round:
+ tstl r2 # take care of round out of high nibble
+ jeql Lashp_zeroround
+ decl r3
+ cmpl r3,arg2 # if weve moved passed destination limits
+ jlss Lashp_overfl # then overflow
+ jlbs r3,L266
+ insv arg5,$4,$4,(r6) # put the round into destination (high or low)
+ jbr Lashp_zeroround
+L266:
+ movb arg5,-(r6)
+
+Lashp_zeroround:
+ argl(1,r10) # r10 = address of destination LSNibble
+ argl(6,r3) # r3 = address of destination MSNibble
+ movl arg4,r11 # r11 = non-zero if destination == non-zero
+ savepsl
+ jbr L267
+Lashp_zerofill:
+ clrb -(r6) # fill up MSNs of destination with zeros
+L267:
+ cmpl r3,r6
+ jneq Lashp_zerofill
+ extzv $0,$4,(r10),r0 # test for negative result
+ cmpl r0,NEGATIVE
+ jneq Lashp_out
+ mnegl r11,r11
+ savepsl
+ jneq Lashp_out # turn -0 into 0
+ insv POSITIVE,$0,$4,(r10)
+Lashp_out:
+ clrl r0
+ argl(3,r6) # restore r6 from stack
+ return
+Lashp_overfl: # do overflow
+ clrl r2
+ overflowpsl
+ jbr Lashp_out
+
+
+ .align 1
+ .globl _EMcvtlp
+_EMcvtlp:
+ arguw(2,r10) # (2) destination length == r10
+ argl(3,r3) # (3) destination address == r3
+ ashl $-1,r10,r10
+ addl2 r10,r3 # destination address points to Least Sig byte
+ incl r10 # length is # of bytes, not nibbles
+ argl(1,r11) # (1) source == r11
+ savepsl
+ jgeq Lcvtlp_pos
+ movb NEGATIVE,(r3) # source is negative
+ divl3 $10,r11,r0
+ mull3 $10,r0,r1
+ subl3 r11,r1,r2 # r2 = source mod 10
+ mnegl r0,r11 # source = -(source / 10)
+ jbr Lcvtlp_cvt
+Lcvtlp_pos:
+ movb POSITIVE,(r3) # source is non-negative
+ divl3 $10,r11,r0
+ mull3 $10,r0,r1
+ subl3 r1,r11,r2 # r2 = source mod 10
+ movl r0,r11 # source = source / 10
+Lcvtlp_cvt:
+ insv r2,$4,$4,(r3) # store least significant digit
+ tstl r11
+ jeql Lcvtlp_zloop
+Lcvtlp_loop: # while source is non-zero
+ decl r10 # and for length of destination ...
+ jeql Lcvtlp_over
+ divl3 $10,r11,r1 # r1 = source / 10
+ mull3 $10,r1,r0
+ subl2 r0,r11 # source = source mod 10
+ movb r11,-(r3) # store low "nibble" in next significant byte
+ divl3 $10,r1,r11 # source = r1 / 10
+ mull3 $10,r11,r0
+ subl2 r0,r1 # r1 = source mod 10
+ insv r1,$4,$4,(r3) # store high nibble
+ tstl r11
+ jneq Lcvtlp_loop # quit if source becomes zero
+Lcvtlp_zloop: # fill any remaining bytes with zeros
+ decl r10
+ jeql Lcvtlp_out
+ clrb -(r3)
+ jbr Lcvtlp_zloop
+Lcvtlp_over:
+ overflowpsl
+Lcvtlp_out:
+ clrl r1 # r0 is already zero
+ clrl r2
+ return
+
+
+ .align 1
+ .globl _EMcvtpl
+_EMcvtpl:
+ arguw(1,r11) # (1) source length == r11
+ argl(2,r10) # (2) source address == r10
+ clrl r3 # r3 == destination
+ movl r10,r1 # r1 set up now for return
+ ashl $-1,r11,r11 # source length is number of bytes
+ jeql Lcvtpl_zero
+Lcvtpl_loop: # for source length
+ mull2 $10,r3 # destination *= 10
+ extzv $4,$4,(r10),r0
+ addl2 r0,r3 # destination += high nibble
+ mull2 $10,r3 # destination *= 10
+ extzv $0,$4,(r10),r0
+ addl2 r0,r3 # destination += low nibble
+ incl r10
+ sobgtr r11,Lcvtpl_loop
+Lcvtpl_zero: # least significant byte
+ mull2 $10,r3
+ extzv $4,$4,(r10),r0
+ addl2 r0,r3 # dest = 10 * dest + high nibble
+ savepsl
+ extzv $0,$4,(r10),r2 # test sign nibble
+ cmpl r2,NEGATIVE
+ jeql Lcvtpl_neg
+ cmpl r2,NEGATIVEalt
+ jneq Lcvtpl_out
+Lcvtpl_neg: # source was negative - negate destination
+ mnegl r3,r3
+ savepsl
+Lcvtpl_out:
+ toarg(r3,3)
+ clrl r0
+ clrl r2
+ clrl r3
+ return
+
+
+ .align 1
+ .globl _EMcvtps
+_EMcvtps:
+ return
+
+
+ .align 1
+ .globl _EMcvtsp
+_EMcvtsp:
+ return
+
+
+ .align 1
+ .globl _EMaddp6
+_EMaddp6:
+ return
+
+
+ .align 1
+ .globl _EMsubp4
+_EMsubp4:
+ return
+
+
+ .align 1
+ .globl _EMsubp6
+_EMsubp6:
+ return
+
+
+ .align 1
+ .globl _EMcvtpt
+_EMcvtpt:
+ return
+
+
+ .align 1
+ .globl _EMmulp
+_EMmulp:
+ return
+
+
+ .align 1
+ .globl _EMcvttp
+_EMcvttp:
+ return
+
+
+ .align 1
+ .globl _EMdivp
+_EMdivp:
+ return
+
+
+ .align 1
+ .globl _EMcmpp3
+_EMcmpp3:
+ return
+
+
+ .align 1
+ .globl _EMcmpp4
+_EMcmpp4:
+ return
+
+
+#endif UVAXII
+
+
+#ifdef notdef
+/*
+ * Emulation OpCode jump table:
+ * ONLY GOES FROM 0xf8 (-8) TO 0x3B (59)
+ */
+#define EMUTABLE 0x43
+#define NOEMULATE .long noemulate
+#define EMULATE(a) .long _EM/**/a
+ .globl _emJUMPtable
+_emJUMPtable:
+/* f8 */ EMULATE(ashp); EMULATE(cvtlp); NOEMULATE; NOEMULATE
+/* fc */ NOEMULATE; NOEMULATE; NOEMULATE; NOEMULATE
+/* 00 */ NOEMULATE; NOEMULATE; NOEMULATE; NOEMULATE
+/* 04 */ NOEMULATE; NOEMULATE; NOEMULATE; NOEMULATE
+/* 08 */ EMULATE(cvtps); EMULATE(cvtsp); NOEMULATE; EMULATE(crc)
+/* 0c */ NOEMULATE; NOEMULATE; NOEMULATE; NOEMULATE
+/* 10 */ NOEMULATE; NOEMULATE; NOEMULATE; NOEMULATE
+/* 14 */ NOEMULATE; NOEMULATE; NOEMULATE; NOEMULATE
+/* 18 */ NOEMULATE; NOEMULATE; NOEMULATE; NOEMULATE
+/* 1c */ NOEMULATE; NOEMULATE; NOEMULATE; NOEMULATE
+/* 20 */ EMULATE(addp4); EMULATE(addp6); EMULATE(subp4); EMULATE(subp6)
+/* 24 */ EMULATE(cvtpt); EMULATE(mulp); EMULATE(cvttp); EMULATE(divp)
+/* 28 */ NOEMULATE; EMULATE(cmpc3); EMULATE(scanc); EMULATE(spanc)
+/* 2c */ NOEMULATE; EMULATE(cmpc5); EMULATE(movtc); EMULATE(movtuc)
+/* 30 */ NOEMULATE; NOEMULATE; NOEMULATE; NOEMULATE
+/* 34 */ EMULATE(movp); EMULATE(cmpp3); EMULATE(cvtpl); EMULATE(cmpp4)
+/* 38 */ EMULATE(editpc); EMULATE(matchc); EMULATE(locc); EMULATE(skpc)
+
+/*
+ * The following is called with the stack set up as follows:
+ *
+ * (sp): Opcode
+ * 4(sp): Instruction PC
+ * 8(sp): Operand 1
+ * 12(sp): Operand 2
+ * 16(sp): Operand 3
+ * 20(sp): Operand 4
+ * 24(sp): Operand 5
+ * 28(sp): Operand 6
+ * 32(sp): Operand 7 (unused)
+ * 36(sp): Operand 8 (unused)
+ * 40(sp): Return PC
+ * 44(sp): Return PSL
+ * 48(sp): TOS before instruction
+ *
+ * Each individual routine is called with the stack set up as follows:
+ *
+ * (sp): Return address of trap handler
+ * 4(sp): Opcode (will get return PSL)
+ * 8(sp): Instruction PC
+ * 12(sp): Operand 1
+ * 16(sp): Operand 2
+ * 20(sp): Operand 3
+ * 24(sp): Operand 4
+ * 28(sp): Operand 5
+ * 32(sp): Operand 6
+ * 36(sp): saved register 11
+ * 40(sp): saved register 10
+ * 44(sp): Return PC
+ * 48(sp): Return PSL
+ * 52(sp): TOS before instruction
+ */
+
+SCBVEC(emulate):
+ movl r11,32(sp) # save register r11 in unused operand
+ movl r10,36(sp) # save register r10 in unused operand
+ cvtbl (sp),r10 # get opcode
+ addl2 $8,r10 # shift negative opcodes
+ subl3 r10,$EMUTABLE,r11 # forget it if opcode is out of range
+ bcs noemulate
+ movl _emJUMPtable[r10],r10 # call appropriate emulation routine
+ jsb (r10) # routines put return values into regs 0-5
+ movl 32(sp),r11 # restore register r11
+ movl 36(sp),r10 # restore register r10
+ insv (sp),$0,$4,44(sp) # and condition codes in Opcode spot
+ addl2 $40,sp # adjust stack for return
+ rei
+noemulate:
+ addl2 $48,sp # adjust stack for
+ .word 0xffff # "reserved instruction fault"
+SCBVEC(emulateFPD):
+ .word 0xffff # "reserved instruction fault"
+#endif
diff --git a/sys/arch/vax/vax/gencons.c b/sys/arch/vax/vax/gencons.c
new file mode 100644
index 00000000000..ddf31f6ef87
--- /dev/null
+++ b/sys/arch/vax/vax/gencons.c
@@ -0,0 +1,292 @@
+/* $NetBSD: gencons.c,v 1.6 1995/08/21 03:24:46 ragge Exp $ */
+
+/*
+ * Copyright (c) 1994 Gordon W. Ross
+ * Copyright (c) 1994 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}.
+ * 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.
+ *
+ * kd.c,v 1.2 1994/05/05 04:46:51 gwr Exp $
+ */
+
+ /* All bugs are subject to removal without further notice */
+
+#include "sys/param.h"
+#include "sys/proc.h"
+#include "sys/systm.h"
+#include "sys/ioctl.h"
+#include "sys/tty.h"
+#include "sys/file.h"
+#include "sys/conf.h"
+#include "sys/device.h"
+#include "sys/reboot.h"
+
+#include "dev/cons.h"
+
+#include "machine/mtpr.h"
+#include "machine/../vax/gencons.h"
+
+struct tty *gencn_tty[1];
+
+int consinied = 0;
+
+int gencnparam();
+void gencnstart();
+
+int
+gencnopen(dev, flag, mode, p)
+ dev_t dev;
+ int flag, mode;
+ struct proc *p;
+{
+ int unit;
+ struct tty *tp;
+
+ unit = minor(dev);
+ if (unit) return ENXIO;
+
+ tp = gencn_tty[0];
+
+ tp->t_oproc = gencnstart;
+ tp->t_param = gencnparam;
+ tp->t_dev = dev;
+ if ((tp->t_state & TS_ISOPEN) == 0) {
+ tp->t_state |= TS_WOPEN;
+ ttychars(tp);
+ tp->t_iflag = TTYDEF_IFLAG;
+ tp->t_oflag = TTYDEF_OFLAG;
+ tp->t_cflag = TTYDEF_CFLAG;
+ tp->t_lflag = TTYDEF_LFLAG;
+ tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
+ gencnparam(tp, &tp->t_termios);
+ ttsetwater(tp);
+ } else if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0)
+ return EBUSY;
+ tp->t_state |= TS_CARR_ON;
+ mtpr(GC_RIE, PR_RXCS); /* Turn on interrupts */
+ mtpr(GC_TIE, PR_TXCS);
+
+ return ((*linesw[tp->t_line].l_open)(dev, tp));
+}
+
+int
+gencnclose(dev, flag, mode, p)
+ dev_t dev;
+ int flag, mode;
+ struct proc *p;
+{
+ int unit = minor(dev);
+ struct tty *tp = gencn_tty[0];
+
+ (*linesw[tp->t_line].l_close)(tp, flag);
+ ttyclose(tp);
+ return (0);
+}
+
+struct tty *
+gencntty(dev)
+ dev_t dev;
+{
+ return gencn_tty[0]; /* XXX */
+}
+
+int
+gencnread(dev, uio, flag)
+ dev_t dev;
+ struct uio *uio;
+ int flag;
+{
+ int unit = minor(dev);
+ struct tty *tp = gencn_tty[0];
+
+ return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
+}
+
+int
+gencnwrite(dev, uio, flag)
+ dev_t dev;
+ struct uio *uio;
+ int flag;
+{
+ int unit = minor(dev);
+ struct tty *tp = gencn_tty[0];
+ return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
+}
+
+int
+gencnioctl(dev, cmd, data, flag, p)
+ dev_t dev;
+ int cmd;
+ caddr_t data;
+ int flag;
+ struct proc *p;
+{
+ int error;
+ int unit = minor(dev);
+ struct tty *tp = gencn_tty[0];
+
+ error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
+ if (error >= 0)
+ return error;
+ error = ttioctl(tp, cmd, data, flag, p);
+ if (error >= 0) return error;
+
+ return ENOTTY;
+}
+
+void
+gencnstart(tp)
+ struct tty *tp;
+{
+ struct clist *cl;
+ int s, ch;
+
+ s = spltty();
+ if (tp->t_state & (TS_BUSY|TS_TTSTOP|TS_TIMEOUT))
+ goto out;
+ cl = &tp->t_outq;
+
+ if(cl->c_cc){
+ tp->t_state |= TS_BUSY;
+ ch = getc(cl);
+ mtpr(ch, PR_TXDB);
+ } else {
+ if (tp->t_state & TS_ASLEEP) {
+ tp->t_state &= ~TS_ASLEEP;
+ wakeup((caddr_t)cl);
+ }
+ selwakeup(&tp->t_wsel);
+ }
+
+out: splx(s);
+}
+
+gencnrint()
+{
+ struct tty *tp;
+ int i, j;
+
+ tp = gencn_tty[0];
+ i = mfpr(PR_RXDB);
+
+#ifdef DDB
+ j = kdbrint(i);
+
+ if (j == 1) /* Escape received, just return */
+ return;
+
+ if (j == 2) /* Second char wasn't 'D' */
+ (*linesw[tp->t_line].l_rint)(27, tp);
+#endif
+
+ (*linesw[tp->t_line].l_rint)(i,tp);
+ return;
+}
+
+int
+gencnstop(tp, flag)
+ struct tty *tp;
+ int flag;
+{
+}
+
+gencntint()
+{
+ struct tty *tp;
+
+ tp = gencn_tty[0];
+ tp->t_state &= ~TS_BUSY;
+
+ gencnstart(tp);
+}
+
+int
+gencnparam(tp, t)
+ struct tty *tp;
+ struct termios *t;
+{
+ /* XXX - These are ignored... */
+ tp->t_ispeed = t->c_ispeed;
+ tp->t_ospeed = t->c_ospeed;
+ tp->t_cflag = t->c_cflag;
+ return 0;
+}
+
+int
+gencnprobe(cndev)
+ struct consdev *cndev;
+{
+ int i;
+
+ for (i = 0; i < nchrdev; i++)
+ if (cdevsw[i].d_open == gencnopen) {
+ cndev->cn_dev = makedev(i,0);
+ cndev->cn_pri = CN_NORMAL;
+ break;
+ }
+ return 0;
+}
+
+int
+gencninit(cndev)
+ struct consdev *cndev;
+{
+}
+
+gencnslask()
+{
+ gencn_tty[0] = ttymalloc();
+}
+
+int
+gencnputc(dev,ch)
+ dev_t dev;
+ int ch;
+{
+ while ((mfpr(PR_TXCS) & GC_RDY) == 0) /* Wait until xmit ready */
+ ;
+ mtpr(ch, PR_TXDB); /* xmit character */
+ if(ch == 10)
+ gencnputc(dev, 13); /* CR/LF */
+
+}
+
+int
+gencngetc(dev)
+ dev_t dev;
+{
+ while ((mfpr(PR_RXCS) & GC_DON) == 0) /* Receive chr */
+ ;
+ return mfpr(PR_RXDB) & 0x7f;
+}
+
+conout(str)
+ char *str;
+{
+ while (*str)
+ gencnputc(0, *str++);
+}
diff --git a/sys/arch/vax/vax/gencons.h b/sys/arch/vax/vax/gencons.h
new file mode 100644
index 00000000000..cd985437709
--- /dev/null
+++ b/sys/arch/vax/vax/gencons.h
@@ -0,0 +1,55 @@
+/* $NetBSD: gencons.h,v 1.3 1995/06/05 16:26:38 ragge Exp $ */
+
+/*
+ * Copyright (c) 1994 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}.
+ * 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 */
+
+
+/*
+ * Some definitions for generic console interface (PR 32-35)
+ */
+
+/* PR_TXCS */
+#define GC_RDY 0x80 /* Console ready to xmit chr */
+#define GC_TIE 0x40 /* xmit interrupt enable */
+
+/* PR_RXCS */
+#define GC_DON 0x80 /* character received */
+#define GC_RIE 0x40 /* recv interrupt enable */
+
+/* PR_RXDB */
+#define GC_ERR 0x8000 /* received character error */
+#define GC_CON 0xf00 /* mfpr($PR_RXDB)&GC_CON==0 then console chr */
+
+/* PR_TXDB */
+#define GC_BOOT 0xf02 /* boot machine */
+#define GC_CCF 0xf04 /* clear cold start flag */
diff --git a/sys/arch/vax/vax/intvec.s b/sys/arch/vax/vax/intvec.s
new file mode 100644
index 00000000000..997d93ec959
--- /dev/null
+++ b/sys/arch/vax/vax/intvec.s
@@ -0,0 +1,398 @@
+/* $NetBSD: intvec.s,v 1.11 1995/06/16 15:36:40 ragge Exp $ */
+
+/*
+ * Copyright (c) 1994 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}.
+ * 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 "vax/include/mtpr.h"
+#include "vax/include/pte.h"
+#include "vax/include/trap.h"
+#include "uba.h"
+
+#define TRAPCALL(namn, typ) \
+ .align 2; namn ## :;.globl namn ;pushl $0; pushl $typ; jbr trap;
+
+#define TRAPARGC(namn, typ) \
+ .align 2; namn ## :;.globl namn ; pushl $typ; jbr trap;
+
+#define FASTINTR(namn, rutin) \
+ .align 2; namn ## :;.globl namn ;pushr $0x3f; \
+ calls $0,_ ## rutin ;popr $0x3f;rei
+#define STRAY(scbnr,vecnr) \
+ .align 2;stray ## vecnr ## :;pushr $0x3f;pushl $ ## 0x ## vecnr; \
+ pushl $scbnr; calls $2,_stray ; popr $0x3f; rei;
+#define KSTACK 0
+#define ISTACK 1
+#define INTVEC(label,stack) \
+ .long label+stack;
+ .text
+
+ .globl _kernbase,_rpb
+_kernbase:
+_rpb:
+/*
+ * First page in memory we have rpb; so that we know where :-)
+ * Second page contain scb, and thereafter uba vectors.
+ * Virtual adress is 0x80000000.
+ */
+ .space 512 /* rpb takes one page */
+
+ INTVEC(stray00, ISTACK) # Unused., 0
+ INTVEC(mcheck, ISTACK) # Machine Check., 4
+ INTVEC(invkstk, ISTACK) # Kernel Stack Invalid., 8
+ INTVEC(stray0C, ISTACK) # Power Failed., C
+ INTVEC(privinflt, KSTACK) # Privileged/Reserved Instruction.
+ INTVEC(stray14, ISTACK) # Customer Reserved Instruction, 14
+ INTVEC(resopflt, KSTACK) # Reserved Operand/Boot Vector(?), 18
+ INTVEC(resadflt, KSTACK) # # Reserved Address Mode., 1C
+ INTVEC(access_v, KSTACK) # Access Control Violation, 20
+ INTVEC(transl_v, KSTACK) # Translation Invalid, 24
+ INTVEC(tracep, KSTACK) # Trace Pending, 28
+ INTVEC(breakp, KSTACK) # Breakpoint Instruction, 2C
+ INTVEC(stray30, ISTACK) # Compatibility Exception, 30
+ INTVEC(arithflt, KSTACK) # Arithmetic Fault, 34
+ INTVEC(stray38, ISTACK) # Unused, 38
+ INTVEC(stray3C, ISTACK) # Unused, 3C
+ INTVEC(syscall, KSTACK) # main syscall trap, chmk, 40
+ INTVEC(resopflt, KSTACK) # chme, 44
+ INTVEC(resopflt, KSTACK) # chms, 48
+ INTVEC(resopflt, KSTACK) # chmu, 4C
+ INTVEC(stray50, ISTACK) # System Backplane Exception, 50
+ INTVEC(stray54, ISTACK) # Corrected Memory Read, 54
+ INTVEC(stray58, ISTACK) # System Backplane Alert, 58
+ INTVEC(stray5C, ISTACK) # System Backplane Fault, 5C
+ INTVEC(stray60, ISTACK) # Memory Write Timeout, 60
+ INTVEC(stray64, ISTACK) # Unused, 64
+ INTVEC(stray68, ISTACK) # Unused, 68
+ INTVEC(stray6C, ISTACK) # Unused, 6C
+ INTVEC(stray70, ISTACK) # Unused, 70
+ INTVEC(stray74, ISTACK) # Unused, 74
+ INTVEC(stray78, ISTACK) # Unused, 78
+ INTVEC(stray7C, ISTACK) # Unused, 7C
+ INTVEC(stray80, ISTACK) # Unused, 80
+ INTVEC(stray84, ISTACK) # Unused, 84
+ INTVEC(astintr, KSTACK) # Asynchronous Sustem Trap, AST
+ INTVEC(stray8C, ISTACK) # Unused, 8C
+ INTVEC(stray90, ISTACK) # Unused, 90
+ INTVEC(stray94, ISTACK) # Unused, 94
+ INTVEC(stray98, ISTACK) # Unused, 98
+ INTVEC(stray9C, ISTACK) # Unused, 9C
+ INTVEC(softclock,ISTACK) # Software clock interrupt
+ INTVEC(strayA4, ISTACK) # Unused, A4
+ INTVEC(strayA8, ISTACK) # Unused, A8
+ INTVEC(strayAC, ISTACK) # Unused, AC
+ INTVEC(netint, ISTACK) # Network interrupt
+ INTVEC(strayB4, ISTACK) # Unused, B4
+ INTVEC(strayB8, ISTACK) # Unused, B8
+ INTVEC(ddbtrap, ISTACK) # Kernel debugger trap, BC
+ INTVEC(hardclock,ISTACK) # Interval Timer
+ INTVEC(strayC4, ISTACK) # Unused, C4
+ INTVEC(emulate, KSTACK) # Subset instruction emulation
+ INTVEC(strayCC, ISTACK) # Unused, CC
+ INTVEC(strayD0, ISTACK) # Unused, D0
+ INTVEC(strayD4, ISTACK) # Unused, D4
+ INTVEC(strayD8, ISTACK) # Unused, D8
+ INTVEC(strayDC, ISTACK) # Unused, DC
+ INTVEC(strayE0, ISTACK) # Unused, E0
+ INTVEC(strayE4, ISTACK) # Unused, E4
+ INTVEC(strayE8, ISTACK) # Unused, E8
+ INTVEC(strayEC, ISTACK) # Unused, EC
+ INTVEC(strayF0, ISTACK) # Console Storage Recieve Interrupt
+ INTVEC(strayF4, ISTACK) # Console Storage Transmit Interrupt
+ INTVEC(consrint, ISTACK) # Console Terminal Recieve Interrupt
+ INTVEC(constint, ISTACK) # Console Terminal Transmit Interrupt
+
+
+ .globl _V_DEVICE_VEC
+_V_DEVICE_VEC: .space 0x100
+
+#if NUBA
+#include "vax/uba/ubavec.s"
+#endif
+
+#if NUBA>4 /* Safety belt */
+#error "Number of bus adapters must be increased in ubavec.s"
+#endif
+
+ STRAY(0, 00)
+
+ .align 2
+#
+# mcheck is the badaddress trap, also called when referencing
+# a invalid address (busserror)
+# _memtest (memtest in C) holds the address to continue execution
+# at when returning from a intentional test.
+#
+mcheck: .globl mcheck
+ tstl _cold # Ar we still in coldstart?
+ bneq L4 # Yes.
+
+ pushr $0x3f
+ pushab 24(sp)
+ calls $1, _machinecheck
+ popr $0x3f
+ addl2 (sp)+,sp
+
+ rei
+
+L4: addl2 (sp)+,sp # remove info pushed on stack
+ mtpr $0xF,$PR_MCESR # clear the bus error bit
+ movl _memtest,(sp) # REI to new adress
+ rei
+
+ TRAPCALL(invkstk, T_KSPNOTVAL)
+ STRAY(0, 0C)
+
+ TRAPCALL(privinflt, T_PRIVINFLT)
+ STRAY(0, 14)
+ TRAPCALL(resopflt, T_RESOPFLT)
+ TRAPCALL(resadflt, T_RESADFLT)
+
+ .align 2
+transl_v: .globl transl_v # Translation violation, 20
+ pushl $T_TRANSFLT
+L3: bbc $1,4(sp),L1
+ bisl2 $T_PTEFETCH, (sp)
+L1: bbc $2,4(sp),L2
+ bisl2 $T_WRITE, (sp)
+L2: movl (sp), 4(sp)
+ addl2 $4, sp
+ jbr trap
+
+
+ .align 2
+access_v:.globl access_v # Access cntrl viol fault, 24
+ blbs (sp), ptelen
+ pushl $T_ACCFLT
+ jbr L3
+
+ptelen: movl $T_PTELEN, (sp) # PTE must expand (or send segv)
+ jbr trap;
+
+ TRAPCALL(tracep, T_TRCTRAP)
+ TRAPCALL(breakp, T_BPTFLT)
+ STRAY(0, 30)
+
+ TRAPARGC(arithflt, T_ARITHFLT)
+
+ STRAY(0, 38)
+ STRAY(0, 3C)
+
+
+
+
+
+ .align 2 # Main system call
+ .globl syscall
+syscall:
+ pushl $T_SYSCALL
+ pushr $0xfff
+ pushl ap
+ pushl fp
+ pushl sp # pointer to syscall frame; defined in trap.h
+ calls $1,_syscall
+ movl (sp)+,fp
+ movl (sp)+,ap
+ popr $0xfff
+ addl2 $8,sp
+ mtpr $0x1f,$PR_IPL # Be sure we can REI
+ rei
+
+ STRAY(0, 44)
+ STRAY(0, 48)
+ STRAY(0, 4C)
+ STRAY(0, 50)
+ STRAY(0, 54)
+ STRAY(0, 58)
+ STRAY(0, 5C)
+ STRAY(0, 60)
+ STRAY(0, 64)
+ STRAY(0, 68)
+ STRAY(0, 6C)
+ STRAY(0, 70)
+ STRAY(0, 74)
+ STRAY(0, 78)
+ STRAY(0, 7C)
+ STRAY(0, 80)
+ STRAY(0, 84)
+
+ TRAPCALL(astintr, T_ASTFLT)
+
+ STRAY(0, 8C)
+ STRAY(0, 90)
+ STRAY(0, 94)
+ STRAY(0, 98)
+ STRAY(0, 9C)
+
+ FASTINTR(softclock, softclock)
+
+ STRAY(0, A4)
+ STRAY(0, A8)
+ STRAY(0, AC)
+
+ FASTINTR(netint, netintr) #network packet interrupt
+
+ STRAY(0, B4)
+ STRAY(0, B8)
+ TRAPCALL(ddbtrap,T_KDBTRAP)
+
+ .align 2
+ .globl hardclock
+hardclock: mtpr $0xc1,$PR_ICCS # Reset interrupt flag
+ pushr $0x3f
+ pushl sp
+ addl2 $24,(sp)
+ calls $1,_hardclock
+ popr $0x3f
+ rei
+
+ STRAY(0, C4)
+ STRAY(0, CC)
+ STRAY(0, D0)
+ STRAY(0, D4)
+ STRAY(0, D8)
+ STRAY(0, DC)
+ STRAY(0, E0)
+ STRAY(0, E4)
+ STRAY(0, E8)
+ STRAY(0, EC)
+ STRAY(0, F0)
+ STRAY(0, F4)
+
+ FASTINTR(consrint, gencnrint)
+ FASTINTR(constint, gencntint)
+
+trap: pushr $0xfff
+ pushl ap
+ pushl fp
+ pushl sp
+ calls $1,_arithflt
+ movl (sp)+,fp
+ movl (sp)+,ap
+ popr $0xfff
+ addl2 $8,sp
+ mtpr $0x1f,$PR_IPL # Be sure we can REI
+ rei
+
+#if VAX630 || VAX650
+/*
+ * Table of emulated Microvax instructions supported by emulate.s.
+ * Use noemulate to convert unimplemented ones to reserved instruction faults.
+ */
+ .globl _emtable
+_emtable:
+/* f8 */ .long _EMashp; .long _EMcvtlp; .long noemulate; .long noemulate
+/* fc */ .long noemulate; .long noemulate; .long noemulate; .long noemulate
+/* 00 */ .long noemulate; .long noemulate; .long noemulate; .long noemulate
+/* 04 */ .long noemulate; .long noemulate; .long noemulate; .long noemulate
+/* 08 */ .long _EMcvtps; .long _EMcvtsp; .long noemulate; .long _EMcrc
+/* 0c */ .long noemulate; .long noemulate; .long noemulate; .long noemulate
+/* 10 */ .long noemulate; .long noemulate; .long noemulate; .long noemulate
+/* 14 */ .long noemulate; .long noemulate; .long noemulate; .long noemulate
+/* 18 */ .long noemulate; .long noemulate; .long noemulate; .long noemulate
+/* 1c */ .long noemulate; .long noemulate; .long noemulate; .long noemulate
+/* 20 */ .long _EMaddp4; .long _EMaddp6; .long _EMsubp4; .long _EMsubp6
+/* 24 */ .long _EMcvtpt; .long _EMmulp; .long _EMcvttp; .long _EMdivp
+/* 28 */ .long noemulate; .long _EMcmpc3; .long _EMscanc; .long _EMspanc
+/* 2c */ .long noemulate; .long _EMcmpc5; .long _EMmovtc; .long _EMmovtuc
+/* 30 */ .long noemulate; .long noemulate; .long noemulate; .long noemulate
+/* 34 */ .long _EMmovp; .long _EMcmpp3; .long _EMcvtpl; .long _EMcmpp4
+/* 38 */ .long _EMeditpc; .long _EMmatchc; .long _EMlocc; .long _EMskpc
+#endif
+/*
+ * The following is called with the stack set up as follows:
+ *
+ * (sp): Opcode
+ * 4(sp): Instruction PC
+ * 8(sp): Operand 1
+ * 12(sp): Operand 2
+ * 16(sp): Operand 3
+ * 20(sp): Operand 4
+ * 24(sp): Operand 5
+ * 28(sp): Operand 6
+ * 32(sp): Operand 7 (unused)
+ * 36(sp): Operand 8 (unused)
+ * 40(sp): Return PC
+ * 44(sp): Return PSL
+ * 48(sp): TOS before instruction
+ *
+ * Each individual routine is called with the stack set up as follows:
+ *
+ * (sp): Return address of trap handler
+ * 4(sp): Opcode (will get return PSL)
+ * 8(sp): Instruction PC
+ * 12(sp): Operand 1
+ * 16(sp): Operand 2
+ * 20(sp): Operand 3
+ * 24(sp): Operand 4
+ * 28(sp): Operand 5
+ * 32(sp): Operand 6
+ * 36(sp): saved register 11
+ * 40(sp): saved register 10
+ * 44(sp): Return PC
+ * 48(sp): Return PSL
+ * 52(sp): TOS before instruction
+ * See the VAX Architecture Reference Manual, Section B-5 for more
+ * information.
+ */
+
+ .align 2
+ .globl emulate
+emulate:
+#if VAX630 || VAX650
+ movl r11,32(sp) # save register r11 in unused operand
+ movl r10,36(sp) # save register r10 in unused operand
+ cvtbl (sp),r10 # get opcode
+ addl2 $8,r10 # shift negative opcodes
+ subl3 r10,$0x43,r11 # forget it if opcode is out of range
+ bcs noemulate
+ movl _emtable[r10],r10 # call appropriate emulation routine
+ jsb (r10) # routines put return values into regs 0-5
+ movl 32(sp),r11 # restore register r11
+ movl 36(sp),r10 # restore register r10
+ insv (sp),$0,$4,44(sp) # and condition codes in Opcode spot
+ addl2 $40,sp # adjust stack for return
+ rei
+noemulate:
+ addl2 $48,sp # adjust stack for
+#endif
+ .word 0xffff # "reserved instruction fault"
+
+ .globl _intrnames, _eintrnames, _intrcnt, _eintrcnt
+_intrnames:
+ .long 0
+_eintrnames:
+_intrcnt:
+ .long 0
+_eintrcnt:
+
diff --git a/sys/arch/vax/vax/ka750.c b/sys/arch/vax/vax/ka750.c
new file mode 100644
index 00000000000..4dc30a4dafc
--- /dev/null
+++ b/sys/arch/vax/vax/ka750.c
@@ -0,0 +1,236 @@
+/* $NetBSD: ka750.c,v 1.5.2.1 1995/10/15 14:18:49 ragge Exp $ */
+
+/*-
+ * Copyright (c) 1982, 1986, 1988 The Regents of the University of California.
+ * Copyright (c) 1994 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 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.
+ *
+ * @(#)ka750.c 7.4 (Berkeley) 5/9/91
+ * @(#)autoconf.c 7.20 (Berkeley) 5/9/91
+ */
+
+/* All bugs are subject to removal without further notice */
+
+#if VAX750
+
+#include "sys/param.h"
+#include "sys/types.h"
+#include "sys/device.h"
+#include "machine/ka750.h"
+#include "machine/nexus.h"
+#include "machine/pte.h"
+#include "machine/mtpr.h"
+#include "vax/uba/ubavar.h"
+#include "vax/uba/ubareg.h"
+
+#include "mba.h"
+#include "uba.h"
+
+#include "vm/vm.h"
+#include "vm/vm_kern.h"
+#include "vax/include/pmap.h"
+
+struct nexus *nexus;
+
+int
+ka750_conf()
+{
+ extern char cpu_model[];
+
+ strcpy(cpu_model,"VAX 11/750");
+ config_rootfound("backplane",(void *)75);
+}
+
+int
+conf_750(){
+ extern int cpu_type, nmba, numuba;
+
+ printf(": 11/750, hardware rev %d, ucode rev %d\n",
+ V750HARDW(cpu_type), V750UCODE(cpu_type));
+}
+
+ka750_clock(){
+ u_int i;
+/*
+ * It's time to start clocks in system...
+ */
+ i=~10000; /* Complement of 10000 milliseconds */
+ mtpr(i,PR_NICR); /* Load in count register */
+ mtpr(0x51,PR_ICCS); /* Start clock and enable interrupt */
+ if(mfpr(PR_TODR)){
+ /* todr running */
+ return 0;
+ } else {
+ /* Start TODR register. */
+ mtpr(1,PR_TODR);
+ return 1;
+ }
+
+}
+
+#if NMBA < 1
+/*
+ * Dummy routine; should never be called.
+ * Should also be somewhere else, but it doesn't matter right now :)
+ */
+mbainterrupt(){return;}
+#endif
+
+
+/*
+ * 750-specific code.
+ */
+
+
+#include "sys/param.h"
+
+/* #include "mem.h" */
+
+extern volatile caddr_t mcraddr[];
+
+struct mcr750 {
+ int mc_err; /* error bits */
+ int mc_inh; /* inhibit crd */
+ int mc_inf; /* info bits */
+};
+
+#define M750_ICRD 0x10000000 /* inhibit crd interrupts, in [1] */
+#define M750_UNCORR 0xc0000000 /* uncorrectable error, in [0] */
+#define M750_CORERR 0x20000000 /* correctable error, in [0] */
+
+#define M750_INH(mcr) ((mcr)->mc_inh = 0)
+#define M750_ENA(mcr) ((mcr)->mc_err = (M750_UNCORR|M750_CORERR), \
+ (mcr)->mc_inh = M750_ICRD)
+#define M750_ERR(mcr) ((mcr)->mc_err & (M750_UNCORR|M750_CORERR))
+
+#define M750_SYN(err) ((err) & 0x7f)
+#define M750_ADDR(err) (((err) >> 9) & 0x7fff)
+
+/* enable crd interrupts */
+ka750_memenable(sa,self)
+ struct sbi_attach_args *sa;
+ struct device *self;
+{
+ extern int nmcr;
+ int k,l,m,cardinfo;
+ struct mcr750 *mcr=(struct mcr750 *)sa->nexaddr;
+
+ mcraddr[self->dv_unit]=(caddr_t)sa->nexaddr;
+
+ /* We will use this info for error reporting - later! */
+ cardinfo=mcr->mc_inf;
+ switch((cardinfo>>24)&3){
+ case 0: printf(": L0011 ");
+ break;
+ case 1: printf(": L0016 ");
+ m=cardinfo&0xaaaa;
+ for(k=l=0;k<16;k++){if(m&1)l++;m>>=1;}
+ printf("with %d M8750",l);
+ break;
+ case 3: printf(": L0022 ");
+ m=cardinfo&0x5555;
+ for(k=l=0;k<16;k++){if(m&1)l++;m>>=1;}
+ printf("with %d M7199",l);
+ m=cardinfo&0xaaaa;
+ if(m){
+ for(k=l=0;k<16;k++){if(m&1)l++;m>>=1;}
+ printf(" and %d M8750",l);
+ }
+ break;
+ }
+ printf("\n");
+
+
+ M750_ENA((struct mcr750 *)mcraddr[0]);
+}
+
+/* log crd errors */
+ka750_memerr()
+{
+ register struct mcr750 *mcr = (struct mcr750 *)mcraddr[0];
+ register int err;
+
+ if (M750_ERR(mcr)) {
+ err = mcr->mc_err; /* careful with i/o space refs */
+ printf("mcr0: %s", err & M750_UNCORR ?
+ "hard error" : "soft ecc");
+ printf(" addr %x syn %x\n", M750_ADDR(err), M750_SYN(err));
+ M750_INH(mcr);
+ }
+}
+
+char *mc750[]={"0","1","2","3","4","5","6","7","8","9","10","11","12","13",
+ "14","15"};
+
+struct mc750frame {
+ int mc5_bcnt; /* byte count == 0x28 */
+ int mc5_summary; /* summary parameter (as above) */
+ int mc5_va; /* virtual address register */
+ int mc5_errpc; /* error pc */
+ int mc5_mdr;
+ int mc5_svmode; /* saved mode register */
+ int mc5_rdtimo; /* read lock timeout */
+ int mc5_tbgpar; /* tb group parity error register */
+ int mc5_cacherr; /* cache error register */
+ int mc5_buserr; /* bus error register */
+ int mc5_mcesr; /* machine check status register */
+ int mc5_pc; /* trapped pc */
+ int mc5_psl; /* trapped psl */
+};
+
+#define MC750_TBERR 2 /* type code of cp tbuf par */
+#define MC750_TBPAR 4 /* tbuf par bit in mcesr */
+
+ka750_mchk(cmcf)
+ caddr_t cmcf;
+{
+ register struct mc750frame *mcf = (struct mc750frame *)cmcf;
+ register int type = mcf->mc5_summary;
+ int mcsr = mfpr(PR_MCSR);
+
+ printf("machine check %x: %s%s\n", type, mc750[type&0xf],
+ (type&0xf0) ? " abort" : " fault");
+ printf(
+"\tva %x errpc %x mdr %x smr %x rdtimo %x tbgpar %x cacherr %x\n",
+ mcf->mc5_va, mcf->mc5_errpc, mcf->mc5_mdr, mcf->mc5_svmode,
+ mcf->mc5_rdtimo, mcf->mc5_tbgpar, mcf->mc5_cacherr);
+ printf("\tbuserr %x mcesr %x pc %x psl %x mcsr %x\n",
+ mcf->mc5_buserr, mcf->mc5_mcesr, mcf->mc5_pc, mcf->mc5_psl,
+ mcsr);
+ mtpr(0, PR_TBIA);
+ mtpr(0xf, PR_MCESR);
+ if (type == MC750_TBERR && (mcf->mc5_mcesr&0xe) == MC750_TBPAR) {
+ printf("tbuf par: flushing and returning\n");
+ return (0);
+ }
+ return (-1);
+}
+#endif
diff --git a/sys/arch/vax/vax/locore.c b/sys/arch/vax/vax/locore.c
new file mode 100644
index 00000000000..ffb7b9b42f9
--- /dev/null
+++ b/sys/arch/vax/vax/locore.c
@@ -0,0 +1,149 @@
+/* $NetBSD: locore.c,v 1.8 1995/06/16 15:36:42 ragge Exp $ */
+
+/*
+ * Copyright (c) 1994 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}.
+ * 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 "sys/param.h"
+#include "sys/types.h"
+#include "sys/reboot.h"
+
+#include "vm/vm.h"
+
+#include "machine/cpu.h"
+#include "machine/sid.h"
+#include "machine/uvaxII.h"
+#include "machine/loconf.h"
+#include "machine/param.h"
+#include "machine/vmparam.h"
+#include "machine/pcb.h"
+
+#define ROUND_PAGE(x) (((uint)(x)+PAGE_SIZE-1)& ~(PAGE_SIZE-1))
+
+u_int proc0paddr;
+volatile int cpunumber, *Sysmap, boothowto, cpu_type;
+volatile char *esym;
+extern volatile int bootdev;
+
+/*
+ * Start is called from boot; the first routine that is called
+ * in kernel. Kernel stack is setup somewhere in a safe place;
+ * but we need to move it to a better known place. Memory
+ * management is disabled, and no interrupt system is active.
+ * We shall be at kernel stack when called; not interrupt stack.
+ */
+
+start(how, dev)
+{
+ extern u_int *end;
+ extern void *scratch;
+ register curtop;
+
+ mtpr(0x1f,PR_IPL); /* No interrupts before istack is ok, please */
+#ifdef COMPAT_RENO
+ asm("
+ movl r9,_esym
+ movl r10,_bootdev
+ movl r11,_boothowto
+ jsb ett
+ett: cmpl (sp)+,$0x80000000
+ bleq tvo # New boot
+ pushl $0x001f0000
+ pushl $to_kmem
+ rei
+tvo: movl (sp)+,_boothowto
+ movl (sp)+,_bootdev
+to_kmem:
+ ");
+#else
+ bootdev=dev;
+ boothowto=how;
+#endif
+
+/*
+ * FIRST we must set up kernel stack, directly after end.
+ * This is the only thing we have to setup here, rest in pmap.
+ */
+
+ PAGE_SIZE = NBPG*2; /* Set logical page size */
+#ifdef DDB
+ if ((boothowto & RB_KDB) != 0)
+ proc0paddr = ROUND_PAGE(esym) | 0x80000000;
+ else
+#endif
+ proc0paddr = ROUND_PAGE(&end);
+
+ mtpr(proc0paddr, PR_PCBB); /* must be set before ksp for some cpus */
+ mtpr(proc0paddr+UPAGES*NBPG,PR_KSP); /* new kernel stack */
+
+ /*
+ * Set logical page size and put Sysmap on its place.
+ */
+ Sysmap=(u_int *)ROUND_PAGE(mfpr(PR_KSP));
+
+ /* Be sure some important internal registers have safe values */
+ ((struct pcb *)proc0paddr)->P0LR = 0;
+ ((struct pcb *)proc0paddr)->P0BR = 0;
+ ((struct pcb *)proc0paddr)->P1LR = 0;
+ ((struct pcb *)proc0paddr)->P1BR = (void *)0x80000000;
+ ((struct pcb *)proc0paddr)->iftrap = NULL;
+ mtpr(0,PR_P0LR);
+ mtpr(0,PR_P0BR);
+ mtpr(0,PR_P1LR);
+ mtpr(0x80000000,PR_P1BR);
+
+ mtpr(512,PR_SCBB); /* SCB at physical addr 512 */
+ mtpr(0,PR_ESP); /* Must be zero, used in page fault routine */
+ mtpr(AST_NO,PR_ASTLVL);
+
+ cninit();
+
+ /* Count up memory etc... early machine dependent routines */
+ if((cpunumber=MACHID(mfpr(PR_SID)))>VAX_MAX) cpunumber=0;
+ cpu_type=mfpr(PR_SID);
+#if VAX630 || VAX410
+ if (cpunumber == VAX_78032)
+ cpu_type=(((*UVAXIISID) >> 24) & 0xff)|(cpu_type & 0xff000000);
+#endif
+ pmap_bootstrap();
+
+ ((struct pcb *)proc0paddr)->framep = scratch;
+
+ /*
+ * change mode down to userspace is done by faking an stack
+ * frame that is setup in cpu_set_kpc(). Not done by returning
+ * from main anymore.
+ */
+ main();
+
+ /* NOTREACHED */
+}
diff --git a/sys/arch/vax/vax/machdep.c b/sys/arch/vax/vax/machdep.c
new file mode 100644
index 00000000000..b50c1a9bd8f
--- /dev/null
+++ b/sys/arch/vax/vax/machdep.c
@@ -0,0 +1,715 @@
+/* $NetBSD: machdep.c,v 1.19.2.1 1995/10/15 14:06:18 ragge Exp $ */
+
+/*
+ * Copyright (c) 1994 Ludd, University of Lule}, Sweden.
+ * Copyright (c) 1993 Adam Glass
+ * Copyright (c) 1988 University of Utah.
+ * Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Changed for the VAX port (and for readability) /IC
+ *
+ * This code is derived from software contributed to Berkeley by 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: machdep.c 1.63 91/04/24
+ *
+ * @(#)machdep.c 7.16 (Berkeley) 6/3/91
+ */
+
+#include "sys/param.h"
+#include "sys/systm.h"
+#include "sys/map.h"
+#include "sys/proc.h"
+#include "sys/user.h"
+#include "sys/time.h"
+#include "sys/signal.h"
+#include "sys/kernel.h"
+#include "sys/reboot.h"
+#include "sys/msgbuf.h"
+#include "sys/buf.h"
+#include "sys/mbuf.h"
+#include "sys/reboot.h"
+#include "sys/conf.h"
+#include "sys/callout.h"
+#include "sys/device.h"
+#include "sys/exec.h"
+#include "sys/mount.h"
+#ifdef SYSVMSG
+#include "sys/msg.h"
+#endif
+#ifdef SYSVSEM
+#include "sys/sem.h"
+#endif
+#ifdef SYSVSHM
+#include "sys/shm.h"
+#endif
+#include "machine/sid.h"
+#include "machine/pte.h"
+#include "machine/mtpr.h"
+#include "machine/cpu.h"
+#include "machine/macros.h"
+#include "machine/nexus.h"
+#include "machine/trap.h"
+#include "machine/reg.h"
+#include "machine/../vax/gencons.h"
+#include "vm/vm_kern.h"
+#include "net/netisr.h"
+
+#include <sys/syscallargs.h>
+
+#include "ppp.h" /* For NERISR_PPP */
+
+/*
+ * We do these external declarations here, maybe they should be done
+ * somewhere else...
+ */
+int nmcr, nmba, numuba, cold = 1;
+caddr_t mcraddr[MAXNMCR];
+int astpending;
+int want_resched;
+char machine[] = "vax";
+char cpu_model[100];
+int msgbufmapped = 0;
+struct msgbuf *msgbufp;
+int physmem;
+struct cfdriver nexuscd;
+int todrstopped = 0, glurg;
+int dumpsize = 0;
+
+caddr_t allocsys __P((caddr_t));
+
+#define valloclim(name, type, num, lim) \
+ (name) = (type *)v; v = (caddr_t)((lim) = ((name)+(num)))
+
+#ifdef BUFPAGES
+int bufpages = BUFPAGES;
+#else
+int bufpages = 0;
+#endif
+int nswbuf = 0;
+#ifdef NBUF
+int nbuf = NBUF;
+#else
+int nbuf = 0;
+#endif
+
+cpu_startup()
+{
+ caddr_t v, tempaddr;
+ extern char version[];
+ int base, residual, i, sz;
+ vm_offset_t minaddr, maxaddr;
+ vm_size_t size;
+ extern int cpu_type, boothowto, startpmapdebug;
+ extern unsigned int avail_end;
+
+ /*
+ * Initialize error message buffer.
+ */
+ msgbufmapped = 1;
+
+#ifdef VAX750
+ if (cpunumber == VAX_750)
+ if (!mfpr(PR_TODR))
+ mtpr(todrstopped = 1, PR_TODR);
+#endif
+ /*
+ * Good {morning,afternoon,evening,night}.
+ */
+ printf("%s\n", version);
+ printf("realmem = %d\n", avail_end);
+ physmem = btoc(avail_end);
+ panicstr = NULL;
+ mtpr(AST_NO, PR_ASTLVL);
+ spl0();
+
+ dumpsize = physmem + 1;
+
+ /*
+ * Find out how much space we need, allocate it, and then give
+ * everything true virtual addresses.
+ */
+ sz = (int) allocsys((caddr_t) 0);
+ if ((v = (caddr_t) kmem_alloc(kernel_map, round_page(sz))) == 0)
+ panic("startup: no room for tables");
+ if (allocsys(v) - v != sz)
+ panic("startup: table size inconsistency");
+
+ /*
+ * Now allocate buffers proper. They are different than the above in
+ * that they usually occupy more virtual memory than physical.
+ */
+ size = MAXBSIZE * nbuf;
+ buffer_map = kmem_suballoc(kernel_map, (vm_offset_t *) & buffers,
+ &maxaddr, size, TRUE);
+ minaddr = (vm_offset_t) buffers;
+ if (vm_map_find(buffer_map, vm_object_allocate(size), (vm_offset_t) 0,
+ &minaddr, size, FALSE) != KERN_SUCCESS)
+ panic("startup: cannot allocate buffers");
+ if ((bufpages / nbuf) >= btoc(MAXBSIZE)) {
+ /* don't want to alloc more physical mem than needed */
+ bufpages = btoc(MAXBSIZE) * nbuf;
+ }
+ base = bufpages / nbuf;
+ residual = bufpages % nbuf;
+ for (i = 0; i < nbuf; i++) {
+ vm_size_t curbufsize;
+ vm_offset_t curbuf;
+
+ /*
+ * First <residual> buffers get (base+1) physical pages
+ * allocated for them. The rest get (base) physical pages.
+ *
+ * The rest of each buffer occupies virtual space, but has no
+ * physical memory allocated for it.
+ */
+ curbuf = (vm_offset_t) buffers + i * MAXBSIZE;
+ curbufsize = CLBYTES * (i < residual ? base + 1 : base);
+ vm_map_pageable(buffer_map, curbuf, curbuf + curbufsize, FALSE);
+ vm_map_simplify(buffer_map, curbuf);
+ }
+
+ /*
+ * Allocate a submap for exec arguments. This map effectively limits
+ * the number of processes exec'ing at any time.
+ */
+ exec_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr,
+ 16 * NCARGS, TRUE);
+
+ /*
+ * Finally, allocate mbuf pool. Since mclrefcnt is an off-size we
+ * use the more space efficient malloc in place of kmem_alloc.
+ */
+
+ mclrefcnt = (char *) malloc(NMBCLUSTERS + CLBYTES / MCLBYTES,
+ M_MBUF, M_NOWAIT);
+ bzero(mclrefcnt, NMBCLUSTERS + CLBYTES / MCLBYTES);
+ mb_map = kmem_suballoc(kernel_map, (vm_offset_t *) & mbutl, &maxaddr,
+ VM_MBUF_SIZE, FALSE);
+ /*
+ * Initialize callouts
+ */
+
+ callfree = callout;
+ for (i = 1; i < ncallout; i++)
+ callout[i - 1].c_next = &callout[i];
+ callout[i - 1].c_next = NULL;
+
+ printf("avail mem = %d\n", ptoa(cnt.v_free_count));
+ printf("Using %d buffers containing %d bytes of memory.\n",
+ nbuf, bufpages * CLBYTES);
+
+ /*
+ * Set up buffers, so they can be used to read disk labels.
+ */
+
+ bufinit();
+
+ /*
+ * Configure the system.
+ */
+ configure();
+}
+
+/*
+ * Allocate space for system data structures. We are given a starting
+ * virtual address and we return a final virtual address; along the way we
+ * set each data structure pointer.
+ *
+ * We call allocsys() with 0 to find out how much space we want, allocate that
+ * much and fill it with zeroes, and then call allocsys() again with the
+ * correct base virtual address.
+ */
+caddr_t
+allocsys(v)
+ register caddr_t v;
+{
+
+#define valloc(name, type, num) \
+ v = (caddr_t)(((name) = (type *)v) + (num))
+
+#ifdef REAL_CLISTS
+ valloc(cfree, struct cblock, nclist);
+#endif
+ valloc(callout, struct callout, ncallout);
+ valloc(swapmap, struct map, nswapmap = maxproc * 2);
+#ifdef SYSVSHM
+ valloc(shmsegs, struct shmid_ds, shminfo.shmmni);
+#endif
+#ifdef SYSVSEM
+ valloc(sema, struct semid_ds, seminfo.semmni);
+ valloc(sem, struct sem, seminfo.semmns);
+ /* This is pretty disgusting! */
+ valloc(semu, int, (seminfo.semmnu * seminfo.semusz) / sizeof(int));
+#endif
+#ifdef SYSVMSG
+ valloc(msgpool, char, msginfo.msgmax);
+ valloc(msgmaps, struct msgmap, msginfo.msgseg);
+ valloc(msghdrs, struct msg, msginfo.msgtql);
+ valloc(msqids, struct msqid_ds, msginfo.msgmni);
+#endif
+
+ /*
+ * Determine how many buffers to allocate (enough to hold 5% of total
+ * physical memory, but at least 16). Allocate 1/2 as many swap
+ * buffer headers as file i/o buffers.
+ */
+ if (bufpages == 0)
+ if (physmem < btoc(2 * 1024 * 1024))
+ bufpages = (physmem / 10) / CLSIZE;
+ else
+ bufpages = (physmem / 20) / CLSIZE;
+ if (nbuf == 0) {
+ nbuf = bufpages;
+ if (nbuf < 16)
+ nbuf = 16;
+ }
+ if (nswbuf == 0) {
+ nswbuf = (nbuf / 2) & ~1; /* force even */
+ if (nswbuf > 256)
+ nswbuf = 256; /* sanity */
+ }
+ valloc(swbuf, struct buf, nswbuf);
+ valloc(buf, struct buf, nbuf);
+ return v;
+}
+
+long dumplo = 0;
+
+dumpconf()
+{
+ int nblks;
+ extern int dumpdev;
+
+ /*
+ * XXX include the final RAM page which is not included in physmem.
+ */
+ dumpsize = physmem + 1;
+ if (dumpdev != NODEV && bdevsw[major(dumpdev)].d_psize) {
+ nblks = (*bdevsw[major(dumpdev)].d_psize) (dumpdev);
+ if (dumpsize > btoc(dbtob(nblks - dumplo)))
+ dumpsize = btoc(dbtob(nblks - dumplo));
+ else if (dumplo == 0)
+ dumplo = nblks - btodb(ctob(dumpsize));
+ }
+ /*
+ * Don't dump on the first CLBYTES (why CLBYTES?) in case the dump
+ * device includes a disk label.
+ */
+ if (dumplo < btodb(CLBYTES))
+ dumplo = btodb(CLBYTES);
+}
+
+cpu_initclocks()
+{
+ (cpu_calls[cpunumber].cpu_clock) ();
+}
+
+cpu_sysctl()
+{
+ printf("cpu_sysctl:\n");
+ return (EOPNOTSUPP);
+}
+
+void
+setstatclockrate(hzrate)
+ int hzrate;
+{
+ panic("setstatclockrate");
+}
+
+consinit()
+{
+#ifdef DDB
+ db_machine_init();
+ ddb_init();
+#endif
+}
+
+int
+sys_sigreturn(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct sys_sigreturn_args /* {
+ syscallarg(struct sigcontext *) sigcntxp;
+ } */ *uap = v;
+ struct trapframe *scf;
+ struct sigcontext *cntx;
+
+ scf = p->p_addr->u_pcb.framep;
+ cntx = SCARG(uap, sigcntxp);
+
+ /* Compatibility mode? */
+ if ((cntx->sc_ps & (PSL_IPL | PSL_IS)) ||
+ ((cntx->sc_ps & (PSL_U | PSL_PREVU)) != (PSL_U | PSL_PREVU)) ||
+ (cntx->sc_ps & PSL_CM)) {
+ return (EINVAL);
+ }
+ if (cntx->sc_onstack & 01)
+ p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK;
+ else
+ p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
+ p->p_sigmask = cntx->sc_mask & ~sigcantmask;
+
+ scf->fp = cntx->sc_fp;
+ scf->ap = cntx->sc_ap;
+ scf->pc = cntx->sc_pc;
+ scf->psl = cntx->sc_ps;
+ mtpr(cntx->sc_sp, PR_USP);
+ return (EJUSTRETURN);
+}
+
+struct trampframe {
+ u_int sig; /* Signal number */
+ u_int code; /* Info code */
+ u_int scp; /* Pointer to struct sigcontext */
+ u_int r0, r1, r2, r3, r4, r5; /* Registers saved when
+ * interrupt */
+ u_int pc; /* Address of signal handler */
+ u_int arg; /* Pointer to first (and only) sigreturn
+ * argument */
+};
+
+void
+sendsig(catcher, sig, mask, code)
+ sig_t catcher;
+ int sig, mask;
+ u_long code;
+{
+ struct proc *p = curproc;
+ struct sigacts *psp = p->p_sigacts;
+ struct trapframe *syscf;
+ struct sigcontext *sigctx;
+ struct trampframe *trampf;
+ u_int *cursp;
+ int oonstack;
+ extern char sigcode[], esigcode[];
+ /*
+ * Allocate and validate space for the signal handler context. Note
+ * that if the stack is in P0 space, the call to grow() is a nop, and
+ * the useracc() check will fail if the process has not already
+ * allocated the space with a `brk'. We shall allocate space on the
+ * stack for both struct sigcontext and struct calls...
+ */
+ /* First check what stack to work on */
+ if ((psp->ps_flags & SAS_ALTSTACK) && !oonstack &&
+ (psp->ps_sigonstack & sigmask(sig))) {
+ cursp = (u_int *) (psp->ps_sigstk.ss_base +
+ psp->ps_sigstk.ss_size);
+ psp->ps_sigstk.ss_flags |= SS_ONSTACK;
+ } else
+ cursp = (u_int *) mfpr(PR_USP);
+ if ((u_int) cursp <= USRSTACK - ctob(p->p_vmspace->vm_ssize))
+ (void) grow(p, (u_int) cursp);
+
+ /* Set up positions for structs on stack */
+ sigctx = (struct sigcontext *) ((u_int) cursp -
+ sizeof(struct sigcontext));
+ trampf = (struct trampframe *) ((u_int) sigctx -
+ sizeof(struct trampframe));
+ cursp = (u_int *) sigctx - 2; /* Place for pointer to arg list in
+ * sigreturn */
+
+ syscf = p->p_addr->u_pcb.framep;
+ if (useracc((caddr_t) cursp, sizeof(struct sigcontext) +
+ sizeof(struct trampframe), B_WRITE) == 0) {
+ /*
+ * Process has trashed its stack; give it an illegal
+ * instruction to halt it in its tracks.
+ */
+ SIGACTION(p, SIGILL) = SIG_DFL;
+ sig = sigmask(SIGILL);
+ p->p_sigignore &= ~sig;
+ p->p_sigcatch &= ~sig;
+ p->p_sigmask &= ~sig;
+ psignal(p, SIGILL);
+ return;
+ }
+ /* Set up pointers for sigreturn args */
+ trampf->arg = (int) sigctx;
+ trampf->pc = (u_int) catcher;
+ trampf->scp = (int) sigctx;
+ trampf->code = code;
+ trampf->sig = sig;
+
+
+ sigctx->sc_pc = syscf->pc;
+ sigctx->sc_ps = syscf->psl;
+ sigctx->sc_ap = syscf->ap;
+ sigctx->sc_fp = syscf->fp;
+ sigctx->sc_sp = mfpr(PR_USP);
+ sigctx->sc_onstack = oonstack;
+ sigctx->sc_mask = mask;
+
+ syscf->pc = (u_int) (((char *) PS_STRINGS) - (esigcode - sigcode));
+ syscf->psl = PSL_U | PSL_PREVU;
+ syscf->ap = (u_int) cursp;
+ mtpr(cursp, PR_USP);
+}
+
+int waittime = -1;
+
+boot(howto)
+ int howto;
+{
+ if ((howto & RB_NOSYNC) == 0 && waittime < 0) {
+ waittime = 0;
+ vfs_shutdown();
+ /*
+ * If we've been adjusting the clock, the todr will be out of
+ * synch; adjust it now.
+ */
+ resettodr();
+ }
+ splhigh(); /* extreme priority */
+ if (howto & RB_HALT) {
+ printf("halting (in tight loop); hit\n\t^P\n\tHALT\n\n");
+ for (;;);
+ } else {
+ if (howto & RB_DUMP)
+ dumpsys();
+ asm("movl %0,r5":: "g" (howto)); /* How to boot */
+ mtpr(GC_BOOT, PR_TXDB); /* boot command */
+ asm("halt");
+ }
+}
+
+netintr()
+{
+#ifdef INET
+ if (netisr & (1 << NETISR_ARP)) {
+ netisr &= ~(1 << NETISR_ARP);
+ arpintr();
+ }
+ if (netisr & (1 << NETISR_IP)) {
+ netisr &= ~(1 << NETISR_IP);
+ ipintr();
+ }
+#endif
+#ifdef NS
+ if (netisr & (1 << NETISR_NS)) {
+ netisr &= ~(1 << NETISR_NS);
+ nsintr();
+ }
+#endif
+#ifdef ISO
+ if (netisr & (1 << NETISR_ISO)) {
+ netisr &= ~(1 << NETISR_ISO);
+ clnlintr();
+ }
+#endif
+#ifdef CCITT
+ if (netisr & (1 << NETISR_CCITT)) {
+ netisr &= ~(1 << NETISR_CCITT);
+ ccittintr();
+ }
+#endif
+#if NPPP > 0
+ if (netisr & (1 << NETISR_PPP)) {
+ pppintr();
+ }
+#endif
+}
+
+machinecheck(frame)
+ u_int frame;
+{
+ if ((*cpu_calls[cpunumber].cpu_mchk) (frame) == 0)
+ return;
+ (*cpu_calls[cpunumber].cpu_memerr) ();
+ panic("machine check");
+}
+
+dumpsys()
+{
+ extern int dumpdev;
+
+ msgbufmapped = 0;
+ if (dumpdev == NODEV)
+ return;
+ /*
+ * For dumps during autoconfiguration, if dump device has already
+ * configured...
+ */
+ if (dumpsize == 0)
+ dumpconf();
+ if (dumplo < 0)
+ return;
+ printf("\ndumping to dev %x, offset %d\n", dumpdev, dumplo);
+ printf("dump ");
+ switch ((*bdevsw[major(dumpdev)].d_dump) (dumpdev)) {
+
+ case ENXIO:
+ printf("device bad\n");
+ break;
+
+ case EFAULT:
+ printf("device not ready\n");
+ break;
+
+ case EINVAL:
+ printf("area improper\n");
+ break;
+
+ case EIO:
+ printf("i/o error\n");
+ break;
+
+ default:
+ printf("succeeded\n");
+ break;
+ }
+}
+
+fuswintr()
+{
+ panic("fuswintr: need to be implemented");
+}
+
+suibyte(base, byte)
+ int byte;
+ void *base;
+{
+ panic("suibyte: need to be implemented");
+}
+
+suswintr()
+{
+ panic("suswintr: need to be implemented");
+}
+
+int
+process_read_regs(p, regs)
+ struct proc *p;
+ struct reg *regs;
+{
+ struct trapframe *tf = p->p_addr->u_pcb.framep;
+
+ regs->r0 = tf->r0;
+ regs->r1 = tf->r1;
+ regs->r2 = tf->r2;
+ regs->r3 = tf->r3;
+ regs->r4 = tf->r4;
+ regs->r5 = tf->r5;
+ regs->r6 = tf->r6;
+ regs->r7 = tf->r7;
+ regs->r8 = tf->r8;
+ regs->r9 = tf->r9;
+ regs->r10 = tf->r10;
+ regs->r11 = tf->r11;
+ regs->ap = tf->ap;
+ regs->fp = tf->fp;
+ regs->sp = mfpr(PR_USP);
+ regs->pc = tf->pc;
+ regs->psl = tf->psl;
+ return 0;
+}
+
+int
+process_write_regs(p, regs)
+ struct proc *p;
+ struct reg *regs;
+{
+ struct trapframe *tf = p->p_addr->u_pcb.framep;
+
+ tf->r0 = regs->r0;
+ tf->r1 = regs->r1;
+ tf->r2 = regs->r2;
+ tf->r3 = regs->r3;
+ tf->r4 = regs->r4;
+ tf->r5 = regs->r5;
+ tf->r6 = regs->r6;
+ tf->r7 = regs->r7;
+ tf->r8 = regs->r8;
+ tf->r9 = regs->r9;
+ tf->r10 = regs->r10;
+ tf->r11 = regs->r11;
+ tf->ap = regs->ap;
+ tf->fp = regs->fp;
+ mtpr(regs->sp, PR_USP);
+ tf->pc = regs->pc;
+ tf->psl = regs->psl;
+ return 0;
+}
+
+int
+process_set_pc(p, addr)
+ struct proc *p;
+ caddr_t addr;
+{
+ void *ptr;
+ struct trapframe *tf;
+
+ if ((p->p_flag & P_INMEM) == 0)
+ return (EIO);
+
+ ptr = (char *) p->p_addr->u_pcb.framep;
+ tf = ptr;
+
+ tf->pc = (u_int) addr;
+
+ return (0);
+}
+
+int
+process_sstep(p, sstep)
+ struct proc *p;
+{
+ void *ptr;
+ struct trapframe *tf;
+
+ if ((p->p_flag & P_INMEM) == 0)
+ return (EIO);
+
+ ptr = p->p_addr->u_pcb.framep;
+ tf = ptr;
+
+ if (sstep)
+ tf->psl |= PSL_T;
+ else
+ tf->psl &= ~PSL_T;
+
+ return (0);
+}
+
+#undef setsoftnet
+setsoftnet()
+{
+ panic("setsoftnet");
+}
+
+ns_cksum()
+{
+ panic("ns_cksum");
+}
diff --git a/sys/arch/vax/vax/mem.c b/sys/arch/vax/vax/mem.c
new file mode 100644
index 00000000000..645007fb8fe
--- /dev/null
+++ b/sys/arch/vax/vax/mem.c
@@ -0,0 +1,191 @@
+/* $NetBSD: mem.c,v 1.7 1995/04/10 16:49:25 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1988 University of Utah.
+ * Copyright (c) 1982, 1986, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * 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.
+ *
+ * @(#)mem.c 8.3 (Berkeley) 1/12/94
+ */
+
+/*
+ * Memory special file
+ */
+
+#include <sys/param.h>
+#include <sys/conf.h>
+#include <sys/buf.h>
+#include <sys/systm.h>
+#include <sys/uio.h>
+#include <sys/malloc.h>
+
+#include <machine/pte.h>
+#include <machine/mtpr.h>
+
+#include <vm/vm.h>
+
+extern unsigned int vmmap, avail_end;
+caddr_t zeropage;
+
+/*ARGSUSED*/
+int
+mmopen(dev, flag, mode)
+ dev_t dev;
+ int flag, mode;
+{
+
+ return (0);
+}
+
+/*ARGSUSED*/
+int
+mmclose(dev, flag, mode)
+ dev_t dev;
+ int flag, mode;
+{
+
+ return (0);
+}
+
+/*ARGSUSED*/
+int
+mmrw(dev, uio, flags)
+ dev_t dev;
+ struct uio *uio;
+ int flags;
+{
+ register vm_offset_t o, v;
+ register int c;
+ register struct iovec *iov;
+ int error = 0;
+ static int physlock;
+
+ if (minor(dev) == 0) {
+ /* lock against other uses of shared vmmap */
+ while (physlock > 0) {
+ physlock++;
+ error = tsleep((caddr_t)&physlock, PZERO | PCATCH,
+ "mmrw", 0);
+ if (error)
+ return (error);
+ }
+ physlock = 1;
+ }
+ while (uio->uio_resid > 0 && error == 0) {
+ iov = uio->uio_iov;
+ if (iov->iov_len == 0) {
+ uio->uio_iov++;
+ uio->uio_iovcnt--;
+ if (uio->uio_iovcnt < 0)
+ panic("mmrw");
+ continue;
+ }
+ switch (minor(dev)) {
+
+/* minor device 0 is physical memory */
+ case 0:
+ v = uio->uio_offset;
+ if (v < 0 || v >= avail_end) {
+ error = EFAULT;
+ goto unlock;
+ }
+ pmap_enter(pmap_kernel(), (vm_offset_t)vmmap,
+ trunc_page(v), uio->uio_rw == UIO_READ ?
+ VM_PROT_READ : VM_PROT_WRITE, TRUE);
+ o = uio->uio_offset & PGOFSET;
+ c = min(uio->uio_resid, (int)(NBPG - o));
+ error = uiomove((caddr_t)vmmap + o, c, uio);
+ pmap_remove(pmap_kernel(), (vm_offset_t)vmmap,
+ (vm_offset_t)vmmap + NBPG);
+ continue;
+
+/* minor device 1 is kernel memory */
+ case 1:
+ v = uio->uio_offset;
+ c = min(iov->iov_len, MAXPHYS);
+ if (!kernacc((caddr_t)v, c,
+ uio->uio_rw == UIO_READ ? B_READ : B_WRITE))
+ return (EFAULT);
+ error = uiomove((caddr_t)v, c, uio);
+ continue;
+
+/* minor device 2 is EOF/RATHOLE */
+ case 2:
+ if (uio->uio_rw == UIO_WRITE)
+ uio->uio_resid = 0;
+ return (0);
+
+/* minor device 12 (/dev/zero) is source of nulls on read, rathole on write */
+ case 12:
+ if (uio->uio_rw == UIO_WRITE) {
+ c = iov->iov_len;
+ break;
+ }
+ if (zeropage == NULL) {
+ zeropage = (caddr_t)
+ malloc(CLBYTES, M_TEMP, M_WAITOK);
+ bzero(zeropage, CLBYTES);
+ }
+ c = min(iov->iov_len, CLBYTES);
+ error = uiomove(zeropage, c, uio);
+ continue;
+
+ default:
+ return (ENXIO);
+ }
+ if (error)
+ break;
+ iov->iov_base += c;
+ iov->iov_len -= c;
+ uio->uio_offset += c;
+ uio->uio_resid -= c;
+ }
+ if (minor(dev) == 0) {
+unlock:
+ if (physlock > 1)
+ wakeup((caddr_t)&physlock);
+ physlock = 0;
+ }
+ return (error);
+}
+
+int
+mmmmap(dev, off, prot)
+ dev_t dev;
+ int off, prot;
+{
+
+ return (EOPNOTSUPP);
+}
diff --git a/sys/arch/vax/vax/mscp.c b/sys/arch/vax/vax/mscp.c
new file mode 100644
index 00000000000..a4af2b4bc08
--- /dev/null
+++ b/sys/arch/vax/vax/mscp.c
@@ -0,0 +1,962 @@
+/* $NetBSD: mscp.c,v 1.4.2.1 1995/10/15 14:18:52 ragge Exp $ */
+
+/*
+ * Copyright (c) 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * 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.
+ *
+ * @(#)mscp.c 7.5 (Berkeley) 12/16/90
+ */
+
+/*
+ * MSCP generic driver routines
+ */
+
+#include "sys/param.h"
+#include "sys/buf.h"
+#include "sys/errno.h"
+#include "sys/dkstat.h"
+#include "sys/ioctl.h"
+#include "sys/disklabel.h"
+#include "sys/syslog.h"
+
+#include "../uba/ubavar.h"
+
+#include "mscp.h"
+#include "mscpvar.h"
+
+#define PCMD PSWP /* priority for command packet waits */
+
+/*
+ * During transfers, mapping info is saved in the buffer's b_resid.
+ */
+#define b_info b_resid
+
+/*
+ * Get a command packet. Second argument is true iff we are
+ * to wait if necessary. Return NULL if none are available and
+ * we cannot wait.
+ */
+struct mscp *
+mscp_getcp(mi, canwait)
+ register struct mscp_info *mi;
+ int canwait;
+{
+#define mri (&mi->mi_cmd)
+ register struct mscp *mp;
+ register int i;
+ int s = splbio();
+
+again:
+ /*
+ * Ensure that we have some command credits, and
+ * that the next command packet is free.
+ */
+ if (mi->mi_credits <= MSCP_MINCREDITS) {
+ if (!canwait) {
+ splx(s);
+ return (NULL);
+ }
+ mi->mi_wantcredits = 1;
+ sleep((caddr_t) &mi->mi_wantcredits, PCMD);
+ goto again;
+ }
+ i = mri->mri_next;
+ if (mri->mri_desc[i] & MSCP_OWN) {
+ if (!canwait) {
+ splx(s);
+ return (NULL);
+ }
+ mi->mi_wantcmd = 1;
+ sleep((caddr_t) &mi->mi_wantcmd, PCMD);
+ goto again;
+ }
+ mi->mi_credits--;
+ mri->mri_desc[i] &= ~MSCP_INT;
+ mri->mri_next = (mri->mri_next + 1) % mri->mri_size;
+ splx(s);
+ mp = &mri->mri_ring[i];
+
+ /*
+ * Initialise some often-zero fields.
+ * ARE THE LAST TWO NECESSARY IN GENERAL? IT SURE WOULD BE
+ * NICE IF DEC SOLD DOCUMENTATION FOR THEIR OWN CONTROLLERS.
+ */
+ mp->mscp_msglen = MSCP_MSGLEN;
+ mp->mscp_flags = 0;
+ mp->mscp_modifier = 0;
+ mp->mscp_seq.seq_bytecount = 0;
+ mp->mscp_seq.seq_buffer = 0;
+ mp->mscp_seq.seq_mapbase = 0;
+/*???*/ mp->mscp_sccc.sccc_errlgfl = 0;
+/*???*/ mp->mscp_sccc.sccc_copyspd = 0;
+ return (mp);
+#undef mri
+}
+
+#ifdef AVOID_EMULEX_BUG
+int mscp_aeb_xor = 0x8000bb80;
+#endif
+
+/*
+ * Do a device go. The driver calls this once it has allocated
+ * resources for the transfer. Save the resource information in
+ * bp->b_ubinfo, and finish the MSCP packet.
+ *
+ * N.B.: If we were blocked for some time, the drive could have gone
+ * off line and might still be that way. We should probably handle
+ * such a case by changing this command into an on line request and
+ * not dequeuing the transfer after all.
+ */
+mscp_go(mi, mp, info)
+ register struct mscp_info *mi;
+ register struct mscp *mp;
+ int info;
+{
+ register struct buf *bp, *dp;
+
+ /*
+ * Now is also the time to move the transfer off the
+ * controller and drive queues, and shuffle the drive
+ * queue on the controller queue. The idea is to try
+ * to keep as many drives busy as possible---to deal
+ * the controller's credits out to the drives in a `fair
+ * share' arrangement. (To do this fully would be more
+ * trouble than it is worth, though.)
+ */
+ dp = mi->mi_tab->b_actf;
+ bp = dp->b_actf;
+ dp->b_actf = bp->b_actf; /* transfer off drive queue */
+ mi->mi_tab->b_actf = dp->b_hash.le_next;/* drive off ctlr queue */
+ MSCP_APPEND(dp, mi->mi_tab, b_hash.le_next); /* then back again */
+/* Was: dp->b_actf = bp->av_forw; /* transfer off drive queue */
+/* Was: mi->mi_tab->b_actf = dp->b_forw;/* drive off ctlr queue */
+/* Was: MSCP_APPEND(dp, mi->mi_tab, b_forw); /* then back again */
+
+ /*
+ * Move the buffer to the I/O wait queue.
+ */
+ {
+ struct buf *tmp;
+
+ bp->b_actf=&mi->mi_wtab;
+ if(mi->mi_wtab.b_actf==&mi->mi_wtab){
+ mi->mi_wtab.b_actf=bp;
+ } else {
+ tmp=mi->mi_wtab.b_actf;
+ while(tmp->b_actf!=&mi->mi_wtab) tmp=tmp->b_actf;
+ tmp->b_actf=bp;
+ }}
+
+/* Was: bp->av_back = mi->mi_wtab.av_back;
+/* Was: bp->av_forw = &mi->mi_wtab;
+/* Was: mi->mi_wtab.av_back->av_forw = bp;
+/* Was: mi->mi_wtab.av_back = bp;
+
+ /*
+ * Save the mapping info, finish the command packet, and give
+ * it to the device. The device's dgo routine should then
+ * initiate polling.
+ */
+ bp->b_info = info;
+#ifdef AVOID_EMULEX_BUG
+ /*
+ * The Emulex SC41/MS will occasionally zero the lower half word
+ * of the command reference number. The upper half word remains
+ * intact. To keep running, we convert the buffer address into
+ * a small but nonzero integer that is unique over all pending
+ * transfers, and store that value in the upper half word. To
+ * catch occurrances of the bug (so that we can gripe to Emulex),
+ * we also put a nonzero value in the lower word.
+ */
+ {
+ register u_int i = mi->mi_nextbp;
+
+ do { /* find a free value */
+ if (mi->mi_bp[i] == 0)
+ goto found;
+ i = (i + 1) % AEB_MAX_BP;
+ } while (i != mi->mi_nextbp);
+ panic("mscp_go: AEB_MAX_BP too small");
+found:
+ mi->mi_bp[i++] = bp;
+ mi->mi_nextbp = i % AEB_MAX_BP;
+ mp->mscp_cmdref = (i << 16) ^ mscp_aeb_xor;
+ }
+#else
+ mp->mscp_cmdref = (long) bp;
+#endif
+ *mp->mscp_addr |= MSCP_OWN | MSCP_INT;
+}
+
+/*
+ * Handle a response ring transition.
+ */
+mscp_dorsp(mi)
+ register struct mscp_info *mi;
+{
+ register struct uba_device *ui;
+ register struct buf *bp;
+ register struct mscp *mp;
+ register int nextrsp;
+ struct mscp_driver *md = mi->mi_md;
+ char *ctlrname, *drivename;
+ int st, error, info;
+
+ ctlrname = md->md_mname;
+ drivename = md->md_dname;
+ nextrsp = mi->mi_rsp.mri_next;
+loop:
+ if (mi->mi_rsp.mri_desc[nextrsp] & MSCP_OWN) {
+ /*
+ * No more responses. Remember the next expected
+ * response index. Check to see if we have some
+ * credits back, and wake up sleepers if so.
+ */
+ mi->mi_rsp.mri_next = nextrsp;
+ if (mi->mi_wantcredits && mi->mi_credits > MSCP_MINCREDITS) {
+ mi->mi_wantcredits = 0;
+ wakeup((caddr_t) &mi->mi_wantcredits);
+ }
+ return;
+ }
+
+ /*
+ * Found a response. Update credit information. If there is
+ * nothing else to do, jump to `done' to get the next response.
+ */
+ mp = &mi->mi_rsp.mri_ring[nextrsp];
+ mi->mi_credits += MSCP_CREDITS(mp->mscp_msgtc);
+ switch (MSCP_MSGTYPE(mp->mscp_msgtc)) {
+
+ case MSCPT_SEQ:
+ break;
+
+ case MSCPT_DATAGRAM:
+ (*md->md_dgram)(mi, mp);
+ goto done;
+
+ case MSCPT_CREDITS:
+ goto done;
+
+ case MSCPT_MAINTENANCE:
+ default:
+ printf("%s%d: unit %d: unknown message type 0x%x ignored\n",
+ ctlrname, mi->mi_ctlr, mp->mscp_unit,
+ MSCP_MSGTYPE(mp->mscp_msgtc));
+ goto done;
+ }
+
+ /*
+ * Controllers are allowed to interrupt as any drive, so we
+ * must check the command before checking for a drive.
+ */
+ if (mp->mscp_opcode == (M_OP_SETCTLRC | M_OP_END)) {
+ (*md->md_ctlrdone)(mi, mp);
+ goto done;
+ }
+
+ /*
+ * Find the drive info. If there is none, and this is an
+ * available attention response, try configuring a new drive.
+ */
+ if (mp->mscp_unit > md->md_ndpc) {
+ printf("%s%d: unit %d out of range\n",
+ ctlrname, mi->mi_ctlr, mp->mscp_unit);
+ goto done;
+ }
+ if ((ui = mi->mi_ip[mp->mscp_unit]) == NULL) {
+ if ((*md->md_unconf)(mi, mp) != MSCP_DONE) {
+ printf("%s%d: unit %d not configured, ",
+ ctlrname, mi->mi_ctlr, mp->mscp_unit);
+ if (mp->mscp_opcode == M_OP_AVAILATTN)
+ printf("available attn");
+ else
+ printf("stray response op 0x%x status 0x%x",
+ mp->mscp_opcode, mp->mscp_status);
+ printf(" ignored\n");
+ }
+ goto done;
+ }
+
+ /*
+ * Handle individual responses.
+ */
+ st = mp->mscp_status & M_ST_MASK;
+ error = 0;
+ switch (mp->mscp_opcode) {
+
+ case M_OP_END:
+ /*
+ * The controller presents a bogus END packet when
+ * a read/write command is given with an illegal
+ * block number. This is contrary to the MSCP
+ * specification (ENDs are to be given only for
+ * invalid commands), but that is the way of it.
+ */
+ if (st == M_ST_INVALCMD && mp->mscp_cmdref != 0) {
+ printf("%s%d: bad lbn (%d)?\n", drivename,
+ ui->ui_unit, mp->mscp_seq.seq_lbn);
+ error = EIO;
+ goto rwend;
+ }
+ goto unknown;
+
+ case M_OP_ONLINE | M_OP_END:
+ /*
+ * Finished an ON LINE request. Call the driver to
+ * find out whether it succeeded. If so, mark it on
+ * line.
+ */
+ if (ui->ui_flags & UNIT_ONLINE) {
+ printf("%s%d: duplicate ONLINE ignored\n",
+ drivename, ui->ui_unit);
+ break;
+ }
+ if ((*md->md_online)(ui, mp) == MSCP_DONE)
+ ui->ui_flags |= UNIT_ONLINE;
+ break;
+
+ case M_OP_GETUNITST | M_OP_END:
+ /*
+ * Got unit status. Call the driver to find out
+ * whether it succeeded, and if so, mark it.
+ */
+ if ((*md->md_gotstatus)(ui, mp) == MSCP_DONE)
+ ui->ui_flags |= UNIT_HAVESTATUS;
+ break;
+
+ case M_OP_AVAILATTN:
+ /*
+ * The drive went offline and we did not notice.
+ * Mark it off line now, to force an on line request
+ * next, so we can make sure it is still the same
+ * drive.
+ *
+ * IF THE UDA DRIVER HAS A COMMAND AWAITING UNIBUS
+ * RESOURCES, THAT COMMAND MAY GO OUT BEFORE THE ON
+ * LINE. IS IT WORTH FIXING??
+ */
+ ui->ui_flags &= ~(UNIT_ONLINE | UNIT_HAVESTATUS);
+#ifdef notyet
+ (*md->md_offline)(ui, mp);
+#endif
+ break;
+
+ case M_OP_READ | M_OP_END:
+ case M_OP_WRITE | M_OP_END:
+ /*
+ * A transfer finished. Get the buffer, and release its
+ * map registers via ubadone(). If the command finished
+ * with an off line or available status, the drive went
+ * off line (the idiot controller does not tell us until
+ * it comes back *on* line, or until we try to use it).
+ */
+ if (mp->mscp_cmdref == 0) {
+ /*
+ * No buffer means there is a bug somewhere!
+ */
+ printf("%s%d: io done, but no buffer?\n",
+ drivename, ui->ui_unit);
+ mscp_hexdump(mp);
+ break;
+ }
+
+rwend:
+#ifdef AVOID_EMULEX_BUG
+ {
+ register u_short *p = (u_short *) &mp->mscp_cmdref;
+
+ /*
+ * Note any errors on the part of the controller.
+ * The lower word should be zero after exclusive
+ * or'ing with mscp_aeb_xor, and the upper should
+ * then be in the range [1..AEB_MAX_BP].
+ */
+ mp->mscp_cmdref ^= mscp_aeb_xor;
+ p[1]--;
+ if (p[1] >= AEB_MAX_BP)
+ panic("unrecoverable Emulex screwup");
+ if (p[0] == 0)
+ mi->mi_ok++;
+ else {
+ /*
+ * Calculate the expected response,
+ * assuming p[1] is correct. The
+ * actual response is then the expected
+ * response xor p[0].
+ */
+ int sb = ((p[1] + 1) << 16) ^ mscp_aeb_xor;
+
+ log(LOG_WARNING, "\
+Emulex SC41/MS screwup: %s%d, got %d correct, then changed 0x%x to 0x%x\n",
+ ctlrname, mi->mi_ctlr,
+ mi->mi_ok, sb, sb ^ p[0]);
+ mi->mi_ok = 0;
+ }
+ /* convert index back to buffer, and mark free */
+ bp = mi->mi_bp[p[1]];
+ mi->mi_bp[p[1]] = 0;
+ }
+#else
+ bp = (struct buf *) mp->mscp_cmdref;
+#ifdef MSCP_PARANOIA
+ {
+ register struct buf *q = mi->mi_wtab.av_forw;
+
+ /*
+ * Ensure that this response corresponds to
+ * some outstanding request. If not, ignore
+ * it entirely. This will likely cause a
+ * Unibus reset soon, after which the controller
+ * just might behave.
+ */
+ while (q != bp && q != &mi->mi_wtab)
+ q = q->av_forw;
+ if (q != bp) {
+ printf("%s%d: bad response packet ignored\n",
+ ctlrname, mi->mi_ctlr);
+ mscp_hexdump(mp);
+ goto out;
+ }
+ }
+#endif MSCP_PARANOIA
+#endif AVOID_EMULEX_BUG
+
+ /*
+ * Mark any error-due-to-bad-LBN (via `goto rwend').
+ * WHAT STATUS WILL THESE HAVE? IT SURE WOULD BE NICE
+ * IF DEC SOLD DOCUMENTATION FOR THEIR OWN CONTROLLERS.
+ */
+ if (error) {
+ bp->b_flags |= B_ERROR;
+ bp->b_error = error;
+ }
+ if (st == M_ST_OFFLINE || st == M_ST_AVAILABLE) {
+ ui->ui_flags &= ~(UNIT_ONLINE | UNIT_HAVESTATUS);
+#ifdef notyet
+ (*md->md_offline)(ui, mp);
+#endif
+ }
+
+ /*
+ * Unlink the transfer from the wait queue mi_wtab.
+ * If there are no more transfers on the drive queue
+ * for this drive, and it is a profiled disk, turn
+ * off its busy bit.
+ */
+
+
+ { /* Insane */
+ struct buf *tmp;
+
+ tmp=bp->b_actf;
+ if(!tmp){
+ printf("Found 0 - bad!\n");
+ asm("halt");
+ }
+ while(tmp->b_actf!=bp){
+ if(!tmp){
+ printf("Got lost in chains...\n");
+ asm("halt");
+ }
+ tmp=tmp->b_actf;
+ }
+ tmp->b_actf=bp->b_actf;
+ }
+ if (ui->ui_dk >= 0 && md->md_utab[ui->ui_unit].b_hash.le_next == NULL)
+ dk_busy &= ~(1 << ui->ui_dk);
+
+/* Was: bp->av_back->av_forw = bp->av_forw;
+ bp->av_forw->av_back = bp->av_back;
+ if (ui->ui_dk >= 0 && md->md_utab[ui->ui_unit].b_forw == NULL)
+ dk_busy &= ~(1 << ui->ui_dk);
+*/
+ /*
+ * If the transfer has something to do with bad
+ * block forwarding, let the driver handle the
+ * rest.
+ */
+ if ((bp->b_flags & B_BAD) != 0 && md->md_bb != NULL) {
+ (*md->md_bb)(ui, mp, bp);
+ goto out;
+ }
+
+ /*
+ * If the transfer failed, give the driver a crack
+ * at fixing things up.
+ */
+ if (st != M_ST_SUCCESS) {
+ switch ((*md->md_ioerr)(ui, mp, bp)) {
+
+ case MSCP_DONE: /* fixed */
+ break;
+
+ case MSCP_RESTARTED: /* still working on it */
+ goto out;
+
+ case MSCP_FAILED: /* no luck */
+ diskerr(bp, drivename, "hard error",
+ LOG_PRINTF, -1, md->md_lab ?
+ &md->md_lab[ui->ui_unit] : md->md_lab);
+ mscp_printevent(mp);
+ bp->b_flags |= B_ERROR;
+ bp->b_error = EIO;
+ break;
+ }
+ }
+
+ /*
+ * Set the residual count and mark the transfer as
+ * done. If the I/O wait queue is now empty, release
+ * the shared BDP, if any.
+ */
+ info = bp->b_info; /* we are about to clobber it */
+ bp->b_resid = bp->b_bcount - mp->mscp_seq.seq_bytecount;
+ (*md->md_iodone)(mi, bp, info);
+out:
+ break;
+
+ case M_OP_REPLACE | M_OP_END:
+ /*
+ * A replace operation finished. Just let the driver
+ * handle it (if it does replaces).
+ */
+ if (md->md_replace == NULL)
+ printf("%s%d: bogus REPLACE end\n",
+ drivename, ui->ui_unit);
+ else
+ (*md->md_replace)(ui, mp);
+ break;
+
+ default:
+ /*
+ * If it is not one of the above, we cannot handle it.
+ * (And we should not have received it, for that matter.)
+ */
+unknown:
+ printf("%s%d: unknown opcode 0x%x status 0x%x ignored\n",
+ mi->mi_md->md_dname, ui->ui_unit,
+ mp->mscp_opcode, mp->mscp_status);
+ mscp_hexdump(mp);
+ break;
+ }
+
+ /*
+ * If the drive needs to be put back in the controller queue,
+ * do that now. (`bp' below ought to be `dp', but they are all
+ * struct buf *.) Note that b_active was cleared in the driver;
+ * we presume that there is something to be done, hence reassert it.
+ */
+ if (ui->ui_flags & UNIT_REQUEUE) {
+ bp = &md->md_utab[ui->ui_unit];
+ if (bp->b_active) panic("mscp_dorsp requeue");
+ MSCP_APPEND(bp, mi->mi_tab, b_hash.le_next);
+/* Was: MSCP_APPEND(bp, mi->mi_tab, b_forw); */
+ bp->b_active = 1;
+ ui->ui_flags &= ~UNIT_REQUEUE;
+ }
+
+done:
+ /*
+ * Give back the response packet, and take a look at the next.
+ */
+ mp->mscp_msglen = MSCP_MSGLEN;
+ mi->mi_rsp.mri_desc[nextrsp] |= MSCP_OWN;
+ nextrsp = (nextrsp + 1) % mi->mi_rsp.mri_size;
+ goto loop;
+}
+
+/*
+ * Dump the entire contents of an MSCP packet in hex. Mainly useful
+ * for debugging....
+ */
+mscp_hexdump(mp)
+ register struct mscp *mp;
+{
+ register long *p = (long *) mp;
+ register int i = mp->mscp_msglen;
+
+ if (i > 256) /* sanity */
+ i = 256;
+ i /= sizeof (*p); /* ASSUMES MULTIPLE OF sizeof(long) */
+ while (--i >= 0)
+ printf("0x%x ", *p++);
+ printf("\n");
+}
+
+/*
+ * Requeue outstanding transfers, e.g., after bus reset.
+ * Also requeue any drives that have on line or unit status
+ * info pending.
+ */
+mscp_requeue(mi)
+ struct mscp_info *mi;
+{
+ register struct uba_device *ui;
+ register struct mscp_driver *md = mi->mi_md;
+ register struct buf *bp, *dp;
+ register int unit;
+ struct buf *nextbp;
+
+ /*
+ * Clear the controller chain. Mark everything un-busy; we
+ * will soon fix any that are in fact busy.
+ */
+ mi->mi_tab->b_actf = NULL;
+ mi->mi_tab->b_active = 0;
+ for (unit = 0, dp = md->md_utab; unit < md->md_nunits; unit++, dp++) {
+ ui = md->md_dinfo[unit];
+ if (ui == NULL || !ui->ui_alive || ui->ui_ctlr != mi->mi_ctlr)
+ continue; /* not ours */
+ dp->b_hash.le_next = NULL;
+ dp->b_active = 0;
+ }
+
+ /*
+ * Scan the wait queue, linking buffers onto drive queues.
+ * Note that these must be put at the front of the drive queue,
+ * lest we reorder I/O operations.
+ */
+ for (bp = *mi->mi_wtab.b_actb; bp != &mi->mi_wtab; bp = nextbp) {
+ nextbp = *bp->b_actb;
+ dp = &md->md_utab[minor(bp->b_dev) >> md->md_unitshift];
+ bp->b_actf = dp->b_actf;
+ if (dp->b_actf == NULL)
+ dp->b_actb = (void *)bp;
+ dp->b_actf = bp;
+ }
+ mi->mi_wtab.b_actf = *mi->mi_wtab.b_actb = &mi->mi_wtab;
+
+ /*
+ * Scan for drives waiting for on line or status responses,
+ * and for drives with pending transfers. Put these on the
+ * controller queue, and mark the controller busy.
+ */
+ for (unit = 0, dp = md->md_utab; unit < md->md_nunits; unit++, dp++) {
+ ui = md->md_dinfo[unit];
+ if (ui == NULL || !ui->ui_alive || ui->ui_ctlr != mi->mi_ctlr)
+ continue;
+ ui->ui_flags &= ~(UNIT_HAVESTATUS | UNIT_ONLINE);
+ if ((ui->ui_flags & UNIT_REQUEUE) == 0 && dp->b_actf == NULL)
+ continue;
+ ui->ui_flags &= ~UNIT_REQUEUE;
+ MSCP_APPEND(dp, mi->mi_tab, b_hash.le_next);
+
+ dp->b_active = 1;
+ mi->mi_tab->b_active = 1;
+ }
+
+#ifdef AVOID_EMULEX_BUG
+ /*
+ * ... and clear the index-to-buffer table.
+ */
+ for (unit = 0; unit < AEB_MAX_BP; unit++)
+ mi->mi_bp[unit] = 0;
+#endif
+}
+
+
+/*
+ * MSCP error reporting
+ */
+
+/*
+ * Messages for the various subcodes.
+ */
+static char unknown_msg[] = "unknown subcode";
+
+/*
+ * Subcodes for Success (0)
+ */
+static char *succ_msgs[] = {
+ "normal", /* 0 */
+ "spin down ignored", /* 1 = Spin-Down Ignored */
+ "still connected", /* 2 = Still Connected */
+ unknown_msg,
+ "dup. unit #", /* 4 = Duplicate Unit Number */
+ unknown_msg,
+ unknown_msg,
+ unknown_msg,
+ "already online", /* 8 = Already Online */
+ unknown_msg,
+ unknown_msg,
+ unknown_msg,
+ unknown_msg,
+ unknown_msg,
+ unknown_msg,
+ unknown_msg,
+ "still online", /* 16 = Still Online */
+};
+
+/*
+ * Subcodes for Invalid Command (1)
+ */
+static char *icmd_msgs[] = {
+ "invalid msg length", /* 0 = Invalid Message Length */
+};
+
+/*
+ * Subcodes for Command Aborted (2)
+ */
+/* none known */
+
+/*
+ * Subcodes for Unit Offline (3)
+ */
+static char *offl_msgs[] = {
+ "unknown drive", /* 0 = Unknown, or online to other ctlr */
+ "not mounted", /* 1 = Unmounted, or RUN/STOP at STOP */
+ "inoperative", /* 2 = Unit Inoperative */
+ unknown_msg,
+ "duplicate", /* 4 = Duplicate Unit Number */
+ unknown_msg,
+ unknown_msg,
+ unknown_msg,
+ "in diagnosis", /* 8 = Disabled by FS or diagnostic */
+};
+
+/*
+ * Subcodes for Unit Available (4)
+ */
+/* none known */
+
+/*
+ * Subcodes for Media Format Error (5)
+ */
+static char *media_fmt_msgs[] = {
+ "fct unread - edc", /* 0 = FCT unreadable */
+ "invalid sector header",/* 1 = Invalid Sector Header */
+ "not 512 sectors", /* 2 = Not 512 Byte Sectors */
+ "not formatted", /* 3 = Not Formatted */
+ "fct ecc", /* 4 = FCT ECC */
+};
+
+/*
+ * Subcodes for Write Protected (6)
+ * N.B.: Code 6 subcodes are 7 bits higher than other subcodes
+ * (i.e., bits 12-15).
+ */
+static char *wrprot_msgs[] = {
+ unknown_msg,
+ "software", /* 1 = Software Write Protect */
+ "hardware", /* 2 = Hardware Write Protect */
+};
+
+/*
+ * Subcodes for Compare Error (7)
+ */
+/* none known */
+
+/*
+ * Subcodes for Data Error (8)
+ */
+static char *data_msgs[] = {
+ "forced error", /* 0 = Forced Error (software) */
+ unknown_msg,
+ "header compare", /* 2 = Header Compare Error */
+ "sync timeout", /* 3 = Sync Timeout Error */
+ unknown_msg,
+ unknown_msg,
+ unknown_msg,
+ "uncorrectable ecc", /* 7 = Uncorrectable ECC */
+ "1 symbol ecc", /* 8 = 1 bit ECC */
+ "2 symbol ecc", /* 9 = 2 bit ECC */
+ "3 symbol ecc", /* 10 = 3 bit ECC */
+ "4 symbol ecc", /* 11 = 4 bit ECC */
+ "5 symbol ecc", /* 12 = 5 bit ECC */
+ "6 symbol ecc", /* 13 = 6 bit ECC */
+ "7 symbol ecc", /* 14 = 7 bit ECC */
+ "8 symbol ecc", /* 15 = 8 bit ECC */
+};
+
+/*
+ * Subcodes for Host Buffer Access Error (9)
+ */
+static char *host_buffer_msgs[] = {
+ unknown_msg,
+ "odd xfer addr", /* 1 = Odd Transfer Address */
+ "odd xfer count", /* 2 = Odd Transfer Count */
+ "non-exist. memory", /* 3 = Non-Existent Memory */
+ "memory parity", /* 4 = Memory Parity Error */
+};
+
+/*
+ * Subcodes for Controller Error (10)
+ */
+static char *cntlr_msgs[] = {
+ unknown_msg,
+ "serdes overrun", /* 1 = Serialiser/Deserialiser Overrun */
+ "edc", /* 2 = Error Detection Code? */
+ "inconsistant internal data struct",/* 3 = Internal Error */
+};
+
+/*
+ * Subcodes for Drive Error (11)
+ */
+static char *drive_msgs[] = {
+ unknown_msg,
+ "sdi command timeout", /* 1 = SDI Command Timeout */
+ "ctlr detected protocol",/* 2 = Controller Detected Protocol Error */
+ "positioner", /* 3 = Positioner Error */
+ "lost rd/wr ready", /* 4 = Lost R/W Ready Error */
+ "drive clock dropout", /* 5 = Lost Drive Clock */
+ "lost recvr ready", /* 6 = Lost Receiver Ready */
+ "drive detected error", /* 7 = Drive Error */
+ "ctlr detected pulse or parity",/* 8 = Pulse or Parity Error */
+};
+
+/*
+ * The following table correlates message codes with the
+ * decoding strings.
+ */
+struct code_decode {
+ char *cdc_msg;
+ int cdc_nsubcodes;
+ char **cdc_submsgs;
+} code_decode[] = {
+#define SC(m) sizeof (m) / sizeof (m[0]), m
+ "success", SC(succ_msgs),
+ "invalid command", SC(icmd_msgs),
+ "command aborted", 0, 0,
+ "unit offline", SC(offl_msgs),
+ "unit available", 0, 0,
+ "media format error", SC(media_fmt_msgs),
+ "write protected", SC(wrprot_msgs),
+ "compare error", 0, 0,
+ "data error", SC(data_msgs),
+ "host buffer access error", SC(host_buffer_msgs),
+ "controller error", SC(cntlr_msgs),
+ "drive error", SC(drive_msgs),
+#undef SC
+};
+
+/*
+ * Print the decoded error event from an MSCP error datagram.
+ */
+mscp_printevent(mp)
+ struct mscp *mp;
+{
+ register int event = mp->mscp_event;
+ register struct code_decode *cdc;
+ int c, sc;
+ char *cm, *scm;
+
+ /*
+ * The code is the lower six bits of the event number (aka
+ * status). If that is 6 (write protect), the subcode is in
+ * bits 12-15; otherwise, it is in bits 5-11.
+ * I WONDER WHAT THE OTHER BITS ARE FOR. IT SURE WOULD BE
+ * NICE IF DEC SOLD DOCUMENTATION FOR THEIR OWN CONTROLLERS.
+ */
+ c = event & M_ST_MASK;
+ sc = (c != 6 ? event >> 5 : event >> 12) & 0x7ff;
+ if (c >= sizeof code_decode / sizeof code_decode[0])
+ cm = "- unknown code", scm = "??";
+ else {
+ cdc = &code_decode[c];
+ cm = cdc->cdc_msg;
+ if (sc >= cdc->cdc_nsubcodes)
+ scm = unknown_msg;
+ else
+ scm = cdc->cdc_submsgs[sc];
+ }
+ printf(" %s (%s) (code %d, subcode %d)\n", cm, scm, c, sc);
+}
+
+/*
+ * Print the code and logical block number for an error packet.
+ * THIS IS PROBABLY PECULIAR TO DISK DRIVES. IT SURE WOULD BE
+ * NICE IF DEC SOLD DOCUMENTATION FOR THEIR OWN CONTROLLERS.
+ */
+mscp_decodeerror(name, ctlr, mp)
+ char *name;
+ int ctlr;
+ register struct mscp *mp;
+{
+ /*
+ * For bad blocks, mp->mscp_erd.erd_hdr identifies a code and
+ * the logical block number. Code 0 is a regular block; code 6
+ * is a replacement block. The remaining codes are currently
+ * undefined. The code is in the upper four bits of the header
+ * (bits 0-27 are the lbn).
+ */
+ int issoft = mp->mscp_flags & (M_LF_SUCC | M_LF_CONT);
+ static char *codemsg[16] = {
+ "lbn", "code 1", "code 2", "code 3",
+ "code 4", "code 5", "rbn", "code 7",
+ "code 8", "code 9", "code 10", "code 11",
+ "code 12", "code 13", "code 14", "code 15"
+ };
+#define BADCODE(h) (codemsg[(unsigned)(h) >> 28])
+#define BADLBN(h) ((h) & 0xfffffff)
+
+ printf("%s%d: %s error datagram%s:", name, ctlr,
+ issoft ? "soft" : "hard",
+ mp->mscp_flags & M_LF_CONT ? " (continuing)" : "");
+ switch (mp->mscp_format & 0377) {
+
+ case M_FM_CTLRERR: /* controller error */
+ break;
+
+ case M_FM_BUSADDR: /* host memory access error */
+ printf(" memory addr 0x%x:", mp->mscp_erd.erd_busaddr);
+ break;
+
+ case M_FM_DISKTRN:
+ printf(" unit %d: level %d retry %d, %s %d:",
+ mp->mscp_unit,
+ mp->mscp_erd.erd_level, mp->mscp_erd.erd_retry,
+ BADCODE(mp->mscp_erd.erd_hdr),
+ BADLBN(mp->mscp_erd.erd_hdr));
+ break;
+
+ case M_FM_SDI:
+ printf(" unit %d: %s %d:", mp->mscp_unit,
+ BADCODE(mp->mscp_erd.erd_hdr),
+ BADLBN(mp->mscp_erd.erd_hdr));
+ break;
+
+ case M_FM_SMLDSK:
+ printf(" unit %d: small disk error, cyl %d:",
+ mp->mscp_unit, mp->mscp_erd.erd_sdecyl);
+ break;
+
+ default:
+ printf(" unit %d: unknown error, format 0x%x:",
+ mp->mscp_unit, mp->mscp_format);
+ }
+ mscp_printevent(mp);
+#undef BADCODE
+#undef BADLBN
+}
diff --git a/sys/arch/vax/vax/mscp.h b/sys/arch/vax/vax/mscp.h
new file mode 100644
index 00000000000..76817ce5984
--- /dev/null
+++ b/sys/arch/vax/vax/mscp.h
@@ -0,0 +1,472 @@
+/* $NetBSD: mscp.h,v 1.2 1994/10/26 08:03:18 cgd Exp $ */
+
+/*
+ * Copyright (c) 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * 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.
+ *
+ * @(#)mscp.h 7.5 (Berkeley) 6/28/90
+ */
+
+/*
+ * Definitions for the Mass Storage Control Protocol
+ * I WISH I KNEW WHAT MORE OF THESE WERE. IT SURE WOULD BE NICE
+ * IF DEC SOLD DOCUMENTATION FOR THEIR OWN CONTROLLERS.
+ */
+
+/*
+ * Control message opcodes
+ */
+#define M_OP_ABORT 0x01 /* Abort command */
+#define M_OP_GETCMDST 0x02 /* Get command status command */
+#define M_OP_GETUNITST 0x03 /* Get unit status command */
+#define M_OP_SETCTLRC 0x04 /* Set controller characteristics command */
+#define M_OP_SEREX 0x07 /* Serious exception end message */
+#define M_OP_AVAILABLE 0x08 /* Available command */
+#define M_OP_ONLINE 0x09 /* Online command */
+#define M_OP_SETUNITC 0x0a /* Set unit characteristics command */
+#define M_OP_DTACCPATH 0x0b /* Determine access paths command */
+#define M_OP_ACCESS 0x10 /* Access command */
+#define M_OP_COMPCD 0x11 /* Compare controller data command */
+#define M_OP_ERASE 0x12 /* Erase command */
+#define M_OP_FLUSH 0x13 /* Flush command */
+#define M_OP_REPLACE 0x14 /* Replace command */
+#define M_OP_COMPHD 0x20 /* Compare host data command */
+#define M_OP_READ 0x21 /* Read command */
+#define M_OP_WRITE 0x22 /* Write command */
+#define M_OP_AVAILATTN 0x40 /* Available attention message */
+#define M_OP_DUPUNIT 0x41 /* Duplicate unit number attention message */
+#define M_OP_ACCPATH 0x42 /* Access path attention message */
+#define M_OP_END 0x80 /* End message flag */
+
+
+/*
+ * Generic command modifiers
+ */
+#define M_MD_EXPRS 0x8000 /* Express request */
+#define M_MD_COMP 0x4000 /* Compare */
+#define M_MD_CLSEX 0x2000 /* Clear serious exception */
+#define M_MD_ERROR 0x1000 /* Force error */
+#define M_MD_SCCHH 0x0800 /* Suppress caching (high speed) */
+#define M_MD_SCCHL 0x0400 /* Suppress caching (low speed) */
+#define M_MD_SECOR 0x0200 /* Suppress error correction */
+#define M_MD_SEREC 0x0100 /* Suppress error recovery */
+#define M_MD_SSHDW 0x0080 /* Suppress shadowing */
+#define M_MD_WBKNV 0x0040 /* Write back (non-volatile) */
+#define M_MD_WBKVL 0x0020 /* Write back (volatile) */
+#define M_MD_WRSEQ 0x0010 /* Write shadow set one unit at a time */
+
+/*
+ * AVAILABLE command modifiers
+ */
+#define M_AVM_ALLCD 0x0002 /* All class drivers */
+#define M_AVM_SPINDOWN 0x0001 /* Spin down */
+
+/*
+ * FLUSH command modifiers
+ */
+#define M_FLM_FLUSHENU 0x0001 /* Flush entire unit */
+#define M_FLM_VOLATILE 0x0002 /* Volatile only */
+
+/*
+ * GET UNIT STATUS command modifiers
+ */
+#define M_GUM_NEXTUNIT 0x0001 /* Next unit */
+
+/*
+ * ONLINE command modifiers
+ */
+#define M_OLM_RIP 0x0001 /* Allow self destruction */
+#define M_OLM_IGNMF 0x0002 /* Ignore media format error */
+
+/*
+ * ONLINE and SET UNIT CHARACTERISTICS command modifiers
+ */
+#define M_OSM_ALTERHI 0x0020 /* Alter host identifier */
+#define M_OSM_SHADOWSP 0x0010 /* Shadow unit specified */
+#define M_OSM_CLEARWBL 0x0008 /* Clear write-back data lost */
+#define M_OSM_SETWRPROT 0x0004 /* Set write protect */
+
+/*
+ * REPLACE command modifiers
+ */
+#define M_RPM_PRIMARY 0x0001 /* Primary replacement block */
+
+/*
+ * End message flags
+ */
+#define M_EF_BBLKR 0x80 /* Bad block reported */
+#define M_EF_BBLKU 0x40 /* Bad block unreported */
+#define M_EF_ERLOG 0x20 /* Error log generated */
+#define M_EF_SEREX 0x10 /* Serious exception */
+
+/*
+ * Controller flags
+ */
+#define M_CF_ATTN 0x80 /* Enable attention messages */
+#define M_CF_MISC 0x40 /* Enable miscellaneous error log messages */
+#define M_CF_OTHER 0x20 /* Enable other host's error log messages */
+#define M_CF_THIS 0x10 /* Enable this host's error log messages */
+#define M_CF_MLTHS 0x04 /* Multi-host */
+#define M_CF_SHADW 0x02 /* Shadowing */
+#define M_CF_576 0x01 /* 576 byte sectors */
+
+/*
+ * Unit flags
+ */
+#define M_UF_REPLC 0x8000 /* Controller initiated bad block replacement */
+#define M_UF_INACT 0x4000 /* Inactive shadow set unit */
+#define M_UF_WRTPH 0x2000 /* Write protect (hardware) */
+#define M_UF_WRTPS 0x1000 /* Write protect (software or volume) */
+#define M_UF_SCCHH 0x8000 /* Suppress caching (high speed) */
+#define M_UF_SCCHL 0x4000 /* Suppress caching (low speed) */
+#define M_UF_RMVBL 0x0080 /* Removable media */
+#define M_UF_WBKNV 0x0040 /* Write back (non-volatile) */
+#define M_UF_576 0x0004 /* 576 byte sectors */
+#define M_UF_CMPWR 0x0002 /* Compare writes */
+#define M_UF_CMPRD 0x0001 /* Compare reads */
+
+/*
+ * Error Log message format codes
+ */
+#define M_FM_CTLRERR 0x00 /* Controller error */
+#define M_FM_BUSADDR 0x01 /* Host memory access error */
+#define M_FM_DISKTRN 0x02 /* Disk transfer error */
+#define M_FM_SDI 0x03 /* SDI error */
+#define M_FM_SMLDSK 0x04 /* Small disk error */
+
+/*
+ * Error Log message flags
+ */
+#define M_LF_SUCC 0x80 /* Operation successful */
+#define M_LF_CONT 0x40 /* Operation continuing */
+#define M_LF_SQNRS 0x01 /* Sequence number reset */
+
+/*
+ * Status codes
+ */
+#define M_ST_MASK 0x1f /* Status code mask */
+#define M_ST_SUCCESS 0x00 /* Success */
+#define M_ST_INVALCMD 0x01 /* Invalid command */
+#define M_ST_ABORTED 0x02 /* Command aborted */
+#define M_ST_OFFLINE 0x03 /* Unit offline */
+#define M_ST_AVAILABLE 0x04 /* Unit available */
+#define M_ST_MFMTERR 0x05 /* Media format error */
+#define M_ST_WRPROT 0x06 /* Write protected */
+#define M_ST_COMPERR 0x07 /* Compare error */
+#define M_ST_DATAERR 0x08 /* Data error */
+#define M_ST_HOSTBUFERR 0x09 /* Host buffer access error */
+#define M_ST_CTLRERR 0x0a /* Controller error */
+#define M_ST_DRIVEERR 0x0b /* Drive error */
+#define M_ST_DIAG 0x1f /* Message from an internal diagnostic */
+
+/*
+ * Subcodes of M_ST_OFFLINE
+ */
+#define M_OFFLINE_UNKNOWN (0 << 5) /* unknown or on other ctlr */
+#define M_OFFLINE_UNMOUNTED (1 << 5) /* unmounted or RUN/STOP at STOP */
+#define M_OFFLINE_INOPERATIVE (2 << 5) /* inoperative? */
+#define M_OFFLINE_DUPLICATE (4 << 5) /* duplicate unit number */
+#define M_OFFLINE_INDIAGNOSTIC (8 << 5) /* disabled by FS or diagnostic */
+
+/*
+ * An MSCP packet begins with a header giving the length of
+ * the entire packet (including the header itself)(?), two bytes
+ * of device specific data, and the a whole bunch of variants
+ * depending on message type.
+ *
+ * N.B.: In most cases we distinguish between a `command' and
+ * an `end' variant as well. The command variant is that which
+ * is given to the controller; the `end' variant is its response.
+ */
+
+/*
+ * Generic sequential message variant (command and response).
+ */
+struct mscpv_seq {
+ long seq_bytecount; /* byte count */
+#define seq_rbn seq_bytecount /* aka RBN (replace) */
+#define seq_outref seq_bytecount /* aka outref (abort/get cmd status) */
+ long seq_buffer; /* buffer descriptor */
+ long seq_mapbase; /* page map (first PTE) phys address */
+ long seq_xxx1; /* ? */ /* unused */
+ long seq_lbn; /* logical block number */
+ long seq_xxx2; /* ? */ /* unused */
+ long *seq_addr; /* pointer to cmd descriptor */
+ long seq_software[4]; /* reserved to software; unused */
+};
+
+/*
+ * Set Controller Characteristics command variant
+ */
+struct mscpv_sccc {
+ u_short sccc_version; /* MSCP version number */
+ u_short sccc_ctlrflags; /* controller flags */
+ u_short sccc_hosttimo; /* host timeout */
+ u_short sccc_usefrac; /* use fraction */
+ long sccc_time; /* time and date */
+ long sccc_xxx1; /* ? */
+ long sccc_errlgfl; /* ? */
+ short sccc_xxx2; /* ? */
+ short sccc_copyspd; /* ? */
+};
+
+/*
+ * Set Controller Characteristics end variant
+ */
+struct mscpv_scce {
+ u_short scce_version; /* MSCP version number */
+ u_short scce_ctlrflags; /* controller flags */
+ u_short scce_ctlrtimo; /* controller timeout */
+ u_short scce_ctlrcmdl; /* ??? */
+ quad_t scce_ctlrid; /* controller ID */
+ long scce_xxx[3]; /* ? */
+ long scce_volser; /* volume serial number */
+};
+
+/*
+ * On Line command variant
+ */
+struct mscpv_onlc {
+ long onlc_xxx1[4]; /* ? */
+ long onlc_errlgfl; /* error log flag? */
+ short onlc_xxx2; /* ? */
+ short onlc_copyspd; /* copy speed? */
+};
+
+/*
+ * On Line end variant
+ */
+struct mscpv_onle {
+ long onle_xxx1[3]; /* ? */
+/*???*/ short onle_xxx2; /* ? */
+ u_char onle_drivetype; /* drive type index (same in guse) */
+ char onle_xxx3; /* ? */
+ long onle_mediaid; /* media type id (same in guse) */
+ long onle_xxx4; /* ? */
+ long onle_unitsize; /* unit size in sectors */
+ long onle_volser; /* volume serial number */
+};
+
+/*
+ * Get Unit Status end variant (and Avail Attn?)
+ */
+struct mscpv_guse {
+ u_short guse_multunit; /* multi-unit code */
+ u_short guse_unitflags; /* unit flags */
+ long guse_hostid; /* host id */
+ long guse_unitid0; /*???*/
+ short guse_unitid1; /*???*/
+ u_char guse_drivetype; /* drive type index */
+ u_char guse_unitid2; /*???*/
+ long guse_mediaid; /* media type id (encoded) */
+ short guse_shadowunit; /* shadow unit */
+ short guse_shadowstat; /* shadow status */
+ u_short guse_nspt; /* sectors per track */
+ u_short guse_group; /* track group size */
+ u_short guse_ngpc; /* groups per cylinder */
+ u_short guse_xxx; /* reserved */
+ u_short guse_rctsize; /* RCT size (sectors) */
+ u_char guse_nrpt; /* RBNs per track */
+ u_char guse_nrct; /* number of RCTs */
+};
+
+/*
+ * Macros to break up and build media IDs. An ID encodes the port
+ * type in the top 10 bits, and the drive type in the remaining 22.
+ * The 10 bits, and 15 of the 22, are in groups of 5, with the value
+ * 0 representing space and values 1..26 representing A..Z. The low
+ * 7 bits represent a number in 0..127. Hence an RA81 on a UDA50
+ * is <D><U><R><A>< >81, or 0x25641051. This encoding scheme is known
+ * in part in uda.c.
+ *
+ * The casts below are just to make pcc generate better code.
+ */
+#define MSCP_MEDIA_PORT(id) (((long)(id) >> 22) & 0x3ff) /* port */
+#define MSCP_MEDIA_DRIVE(id) ((long)(id) & 0x003fffff) /* drive */
+#define MSCP_MID_ECH(n, id) (((long)(id) >> ((n) * 5 + 7)) & 0x1f)
+#define MSCP_MID_CHAR(n, id) \
+ (MSCP_MID_ECH(n, id) ? MSCP_MID_ECH(n, id) + '@' : ' ')
+#define MSCP_MID_NUM(id) ((id) & 0x7f)
+/* for, e.g., RA81 */
+#define MSCP_MKDRIVE2(a, b, n) \
+ (((a) - '@') << 17 | ((b) - '@') << 12 | (n))
+/* for, e.g., RRD50 */
+#define MSCP_MKDRIVE3(a, b, c, n) \
+ (((a) - '@') << 17 | ((b) - '@') << 12 | ((c) - '@') << 7 | (n))
+
+/*
+ * Error datagram variant.
+ */
+struct mscpv_erd {
+ quad_t erd_ctlrid; /* controller ID */
+ u_char erd_ctlrsoftware; /* controller software version */
+ u_char erd_ctlrhardware; /* controller hardware version */
+ u_short erd_multiunit; /* multi-unit code (?) */
+ union {
+ u_long un_busaddr; /* bus address, if mem access err */
+ quad_t un_unitid; /* unit id, otherwise */
+ } erd_un1;
+#define erd_busaddr erd_un1.un_busaddr
+#define erd_unitid erd_un1.un_unitid
+ u_char erd_unitsoftware; /* unit software version */
+ u_char erd_unithardware; /* unit hardware version */
+ union {
+ u_char un_b[2]; /* level, retry (if disk xfer err) */
+ u_short un_s; /* cylinder (if small disk error) */
+ } erd_un2;
+#define erd_level erd_un2.un_b[0]
+#define erd_retry erd_un2.un_b[1]
+#define erd_sdecyl erd_un2.un_s
+ long erd_volser; /* volume serial number */
+ u_long erd_hdr; /* `header' (block number) */
+ u_char erd_sdistat[12]; /* SDI status information (?) */
+};
+
+/*
+ * I am making brash assumptions about the first four bytes of all
+ * MSCP packets. These appear to be true for both UDA50s and TMSCP
+ * devices (TU81, TA81, TK50). DEC claim that these four bytes are
+ * not part of MSCP itself, yet at least the length is necessary
+ * for, e.g., error checking.
+ */
+struct mscp {
+ u_short mscp_msglen; /* length in bytes */
+ u_char mscp_msgtc; /* type (high 4 bits) and credits */
+ u_char mscp_vcid; /* virtual circuit ID */
+ long mscp_cmdref; /* command reference number */
+ u_short mscp_unit; /* unit number */
+ u_short mscp_seqnum; /* sequence number */
+ u_char mscp_opcode; /* opcode */
+#define mscp_format mscp_opcode /* aka format (datagrams) */
+ u_char mscp_flags; /* flags */
+ u_short mscp_modifier; /* modifier (commands) */
+#define mscp_status mscp_modifier /* aka status (ends) */
+#define mscp_event mscp_modifier /* aka event (datagrams) */
+ union {
+ struct mscpv_seq un_seq; /* generic sequential msg */
+ struct mscpv_sccc un_sccc; /* SCC command */
+ struct mscpv_scce un_scce; /* SCC end */
+ struct mscpv_onlc un_onlc; /* on line command */
+ struct mscpv_onle un_onle; /* on line end */
+ struct mscpv_guse un_guse; /* get unit status */
+ struct mscpv_erd un_erd; /* error datagram */
+ } mscp_un;
+/*???*/ long mscp_xxx; /* pad to 64 bytes */
+};
+
+/*
+ * Define message length according to the DEC specifications by dropping
+ * the four byte header.
+ */
+#define MSCP_MSGLEN (sizeof (struct mscp) - 4)
+
+/*
+ * Shorthand
+ */
+
+/*
+ * Generic packet
+ */
+#define mscp_seq mscp_un.un_seq
+
+/*
+ * Set Controller Characteristics packet
+ */
+#define mscp_sccc mscp_un.un_sccc
+
+/*
+ * Set Controller Characteristics end packet
+ */
+#define mscp_scce mscp_un.un_scce
+
+/*
+ * Online / Set Unit Characteristics command packet
+ */
+#define mscp_onlc mscp_un.un_onlc
+
+/*
+ * Online end packet
+ */
+#define mscp_onle mscp_un.un_onle
+
+/*
+ * Get Unit Status end packet
+ */
+#define mscp_guse mscp_un.un_guse
+
+/*
+ * MSCP Error Log packet
+ */
+#define mscp_erd mscp_un.un_erd
+
+/*
+ * MSCP seq_addr field actually belongs to overall packet.
+ */
+#define mscp_addr mscp_seq.seq_addr
+
+/*
+ * Macros to break up mscp_msgtc, and types.
+ */
+#define MSCP_MSGTYPE(m) ((m) & 0xf0)
+#define MSCP_CREDITS(m) ((m) & 0x0f)
+
+#define MSCPT_SEQ 0x00 /* sequential message */
+#define MSCPT_DATAGRAM 0x10 /* error datagram */
+#define MSCPT_CREDITS 0x20 /* credit notification */
+#define MSCPT_MAINTENANCE 0xf0 /* who knows */
+
+
+/*
+ * Here begin more perhaps brash assumptions about MSCP devices...
+ */
+
+/*
+ * MSCP controllers have `command rings' and `response rings'. A
+ * command ring is a pool of MSCP packets that the host uses to give
+ * commands to the controller; a response ring is a pool of MSCP
+ * packets that the controller uses to give back responses. Entries
+ * in the command and response rings are `owned' by either the host
+ * or the controller; only the owner is allowed to alter any of the
+ * fields in the MSCP packet. Thus, free command packets are owned
+ * by the host, and free response packets by the controller. When
+ * the host gives a packet to the controller, it tells the controller
+ * by touching a device register; when the controller gives a response
+ * to the host, it generates an interrupt if enabled, and sets
+ * a device register as well.
+ *
+ * The pool is `described' by a set of pointers to the packets, along
+ * with the two flags below.
+ */
+#define MSCP_OWN 0x80000000 /* controller owns this packet */
+#define MSCP_INT 0x40000000 /* controller should interrupt */
diff --git a/sys/arch/vax/vax/mscpvar.h b/sys/arch/vax/vax/mscpvar.h
new file mode 100644
index 00000000000..8b9a63a6ce3
--- /dev/null
+++ b/sys/arch/vax/vax/mscpvar.h
@@ -0,0 +1,219 @@
+/* $NetBSD: mscpvar.h,v 1.5.2.1 1995/10/15 14:18:53 ragge Exp $ */
+
+/*
+ * Copyright (c) 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * 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.
+ *
+ * @(#)mscpvar.h 7.3 (Berkeley) 6/28/90
+ */
+
+/*
+ * MSCP generic driver configuration
+ */
+
+/*
+ * Enabling MSCP_PARANOIA makes the response code perform various checks
+ * on the hardware. (Right now it verifies only the buffer pointer in
+ * mscp_cmdref.)
+ *
+ * Enabling AVOID_EMULEX_BUG selects an alternative method of identifying
+ * transfers in progress, which gets around a rather peculiar bug in the
+ * SC41/MS. Enabling MSCP_PARANOIA instead should work, but will cause
+ * `extra' Unibus resets.
+ *
+ * Either of these flags can simply be included as an `options' line in
+ * your configuration file.
+ */
+
+/* #define MSCP_PARANOIA */
+/* #define AVOID_EMULEX_BUG */
+
+/*
+ * Per driver information.
+ *
+ * md_ndpc sets the maximum unit number allowed in response packets.
+ * md_nunits is the number of drives attached to all controllers.
+ * md_unitshift is the divisor for converting a minor device number
+ * to a unit index for the device queues in md_utab.
+ *
+ * The routines are called from the generic response dispatcher.
+ * THE FOLLOWING IS OUT OF DATE
+ * The first three (dgram, ctlrdone, and unconf) get passed a pointer
+ * to the uba_ctlr and to the packet; the rest get a pointer to the
+ * uba_device and to the packet (`um, mp' and `ui, mp' respectively).
+ * The routines unconf, online, gotstatus, and ioerr are functions
+ * and should return one of the values given below. In addition,
+ * the ioerr and bb routines get a third argument, `bp': a pointer
+ * to the buffer describing the transfer in error.
+ * END OUT OF DATE
+ */
+struct mscp_driver {
+ int md_ndpc; /* number of drives per ctlr */
+ int md_nunits; /* total number drives (all ctlrs) */
+ int md_unitshift; /* device number to unit: >> count */
+ struct buf *md_utab; /* pointer to device queues */
+ struct disklabel *md_lab; /* pointer to devicee disklabels */
+ struct uba_device **md_dinfo; /* pointer to device info */
+ int (*md_dgram)(); /* error datagram */
+ int (*md_ctlrdone)(); /* controller operation complete */
+ int (*md_unconf)(); /* response from unconfigured drive */
+ int (*md_iodone)(); /* normal I/O is done */
+ int (*md_online)(); /* drive on line */
+ int (*md_gotstatus)(); /* got unit status */
+ int (*md_replace)(); /* replace done */
+ int (*md_ioerr)(); /* read or write failed */
+ int (*md_bb)(); /* B_BAD io done */
+ char *md_mname; /* name of controllers */
+ char *md_dname; /* name of drives */
+};
+
+/*
+ * Return values from functions.
+ * MSCP_RESTARTED is peculiar to I/O errors.
+ */
+#define MSCP_DONE 0 /* all ok */
+#define MSCP_FAILED 1 /* no go */
+#define MSCP_RESTARTED 2 /* transfer restarted */
+
+/*
+ * Ring information, per ring (one each for commands and responses).
+ */
+struct mscp_ri {
+ int mri_size; /* ring size */
+ int mri_next; /* next (expected|free) */
+ long *mri_desc; /* base address of descriptors */
+ struct mscp *mri_ring; /* base address of packets */
+};
+
+/*
+ * Per device information.
+ *
+ * mi_ip is a pointer to the inverting pointers (things that get `ui's
+ * given unit numbers) FOR THIS CONTROLLER (NOT the whole set!).
+ *
+ * mi_wtab holds a queue of those transfers that were started but have
+ * not yet finished. Other Unibus drivers do not need this as they hand
+ * out requests one at a time. MSCP devices, however, take a slew of
+ * requests and pick their own order to execute them. This means that
+ * we have to have a place to move transfers that were given to the
+ * controller, so we can tell those apart from those that have not yet
+ * been handed out; mi_wtab is that place.
+ */
+struct mscp_info {
+ struct mscp_driver *mi_md; /* pointer to driver info */
+ int mi_ctlr; /* controller index */
+ struct buf *mi_tab; /* pointer to ctlr's drive queue */
+ struct uba_device **mi_ip; /* pointer to inverting pointers */
+ struct mscp_ri mi_cmd; /* MSCP command ring info */
+ struct mscp_ri mi_rsp; /* MSCP response ring info */
+ short mi_credits; /* transfer credits */
+ char mi_wantcmd; /* waiting for command packet */
+ char mi_wantcredits; /* waiting for transfer credits */
+ struct buf mi_wtab; /* transfer wait queue */
+#ifdef AVOID_EMULEX_BUG
+#define AEB_MAX_BP 32 /* max pend xfers (power of 2) XXX */
+ volatile struct buf *mi_bp[AEB_MAX_BP]; /* xfer no. to buffer */
+ u_int mi_nextbp; /* generates unique xfer no's */
+ int mi_ok; /* for error rate statistics */
+#endif AVOID_EMULEX_BUG
+};
+
+/*
+ * We have run out of credits when mi_credits is <= MSCP_MINCREDITS.
+ * It is still possible to issue one command in this case, but it must
+ * not be a data transfer. E.g., `get command status' or `abort command'
+ * is legal, while `read' is not.
+ */
+#define MSCP_MINCREDITS 1
+
+/*
+ * Flags for mscp_getcp().
+ */
+#define MSCP_WAIT 1
+#define MSCP_DONTWAIT 0
+
+struct mscp *mscp_getcp(); /* get a command packet */
+
+/*
+ * Unit flags
+ */
+#define UNIT_ONLINE 0x01 /* drive is on line */
+#define UNIT_HAVESTATUS 0x02 /* got unit status */
+#define UNIT_REQUEUE 0x04 /* requeue after response */
+
+/*
+ * Handle a command ring transition: wake up sleepers for command packets.
+ * This is too simple to bother with a function call.
+ */
+#define MSCP_DOCMD(mi) { \
+ if ((mi)->mi_wantcmd) { \
+ (mi)->mi_wantcmd = 0; \
+ wakeup((caddr_t) &(mi)->mi_wantcmd); \
+ } \
+}
+
+/*
+ * The following macro appends a buffer to a drive queue or a drive to
+ * a controller queue, given the name of the forward link. Use as
+ * `APPEND(dp, &um->um_tab, b_forw)' or `APPEND(bp, dp, av_forw)',
+ * where `bp' is a transfer request, `dp' is a drive queue, and `um_tab'
+ * is a controller queue. (That is, the forward link for controller
+ * queues is `b_forw'; for drive queues, it is `av_forw'.)
+ *
+ * Changed to new buf structure 940605/Ragge
+ */
+#define MSCP_APPEND(bp, queue, link) { \
+ struct buf *tmp; \
+ \
+ (bp)->link = NULL; \
+ if ((queue)->b_actf == NULL) \
+ (queue)->b_actf = (bp); \
+ else { \
+ tmp=(queue)->b_actf; \
+ while(tmp->link) tmp=tmp->link; \
+ tmp->link = (bp); \
+ } \
+}
+
+/* Old APPEND macro */
+/*
+#define APPEND(bp, queue, link) { \
+ (bp)->link = NULL; \
+ if ((queue)->b_actf == NULL) \
+ (queue)->b_actf = (bp); \
+ else \
+ (queue)->b_actl->link = (bp); \
+ (queue)->b_actl = (bp); \
+}
+*/
diff --git a/sys/arch/vax/vax/pmap.c b/sys/arch/vax/vax/pmap.c
new file mode 100644
index 00000000000..b113a553f67
--- /dev/null
+++ b/sys/arch/vax/vax/pmap.c
@@ -0,0 +1,916 @@
+/* $NetBSD: pmap.c,v 1.17 1995/08/22 04:34:17 ragge Exp $ */
+#define DEBUG
+/*
+ * Copyright (c) 1994 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}.
+ * 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 "sys/types.h"
+#include "sys/param.h"
+#include "sys/queue.h"
+#include "sys/malloc.h"
+#include "sys/proc.h"
+#include "sys/user.h"
+#include "sys/msgbuf.h"
+#include "vm/vm.h"
+#include "vm/vm_page.h"
+#include "vm/vm_kern.h"
+#include "vax/include/pte.h"
+#include "vax/include/pcb.h"
+#include "vax/include/mtpr.h"
+#include "vax/include/loconf.h"
+#include "vax/include/macros.h"
+#include "vax/include/sid.h"
+
+#include "uba.h"
+
+pt_entry_t *pmap_virt2pte(pmap_t, u_int);
+
+#define PTE_TO_PV(pte) (PHYS_TO_PV((pte&PG_FRAME)<<PG_SHIFT))
+
+
+struct pmap kernel_pmap_store;
+unsigned int gurkskit[50],istack;
+
+static pv_entry_t alloc_pv_entry();
+static void free_pv_entry();
+
+static int prot_array[]={ PG_NONE, PG_RO, PG_RW, PG_RW,
+ PG_RO, PG_RO, PG_RW, PG_RW };
+
+static int kernel_prot[]={ PG_NONE, PG_KR, PG_KW, PG_KW,
+ PG_RO,PG_KR,PG_KW,PG_URKW};
+
+static pv_entry_t pv_head =NULL;
+static unsigned int pv_count=0;
+vm_offset_t ptemapstart,ptemapend;
+
+extern uint etext;
+extern u_int *pte_cmap;
+extern int maxproc;
+extern struct vmspace vmspace0;
+extern int edata, end;
+uint* UMEMmap;
+void* Numem;
+void *scratch;
+uint sigsida;
+#ifdef DEBUG
+int startpmapdebug=0;
+extern int startsysc, faultdebug;
+#endif
+unsigned int *valueptr=gurkskit, vmmap;
+pt_entry_t *Sysmap;
+vm_map_t pte_map;
+
+vm_offset_t avail_start, avail_end;
+vm_offset_t virtual_avail, virtual_end; /* Available virtual memory */
+
+/*
+ * pmap_bootstrap().
+ * Called as part of vm bootstrap, allocates internal pmap structures.
+ * Assumes that nothing is mapped, and that kernel stack is located
+ * immediately after end.
+ */
+
+void
+pmap_bootstrap()
+{
+ uint i;
+ extern u_int sigcode, esigcode, proc0paddr;
+ extern char *esym;
+ struct pmap *p0pmap=&vmspace0.vm_pmap;
+ vm_offset_t pend=0;
+#define ROUND_PAGE(x) (((uint)(x) + PAGE_SIZE-1)& ~(PAGE_SIZE - 1))
+
+ /* These are in phys memory */
+ istack = ROUND_PAGE((uint)Sysmap + SYSPTSIZE * 4);
+ (u_int)scratch = istack + ISTACK_SIZE;
+ mtpr(scratch, PR_ISP); /* set interrupt stack pointer */
+ msgbufp = (void *)(scratch + NBPG * 4);
+ (u_int)pv_table = (int)ROUND_PAGE(sizeof(struct msgbuf)) +
+ (u_int)msgbufp;
+
+/* Count up phys memory */
+ while (!badaddr(pend, 4))
+ pend += NBPG * 128;
+
+#if VAX630
+ if (cpu_type == VAX_630)
+ pend -= 8 * NBPG; /* Avoid console scratchpad */
+#endif
+#if VAX650
+ if (cpu_type == VAX_650)
+ pend -= 64 * NBPG;
+#endif
+/* These are virt only */
+ vmmap = ROUND_PAGE(pv_table + (pend / PAGE_SIZE));
+ (u_int)Numem = vmmap + NBPG * 2;
+
+ (pt_entry_t *)UMEMmap=kvtopte(Numem);
+ (pt_entry_t *)pte_cmap=kvtopte(vmmap);
+
+ avail_start=ROUND_PAGE(vmmap)&0x7fffffff;
+ avail_end=pend-ROUND_PAGE(sizeof(struct msgbuf));
+ virtual_avail=ROUND_PAGE((uint)Numem+NUBA*NBPG*NBPG);
+ virtual_end=SYSPTSIZE*NBPG+KERNBASE;
+#ifdef DEBUG
+ printf("Sysmap %x, istack %x, scratch %x\n",Sysmap,istack,scratch);
+ printf("etext %x, edata %x, end %x, esym %x\n",
+ &etext,&edata, &end, esym);
+ printf("SYSPTSIZE %x, USRPTSIZE %x\n",SYSPTSIZE,USRPTSIZE);
+ printf("pv_table %x, vmmap %x, Numem %x, pte_cmap %x\n",
+ pv_table,vmmap,Numem,pte_cmap);
+ printf("avail_start %x, avail_end %x\n",avail_start,avail_end);
+ printf("virtual_avail %x,virtual_end %x\n",virtual_avail,virtual_end);
+ printf("clearomr: %x \n",(uint)vmmap-(uint)Sysmap);
+ printf("faultdebug %x, startsysc %x\n",&faultdebug, &startsysc);
+ printf("startpmapdebug %x\n",&startpmapdebug);
+#endif
+
+ blkclr(Sysmap,(uint)vmmap-(uint)Sysmap);
+ pmap_map(0x80000000,0,2*NBPG,VM_PROT_READ|VM_PROT_WRITE);
+#ifdef DDB
+ pmap_map(0x80000400,2*NBPG,(vm_offset_t)(&etext),
+ VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
+#else
+ pmap_map(0x80000400,2*NBPG,(vm_offset_t)(&etext),VM_PROT_EXECUTE);
+#endif
+ pmap_map((vm_offset_t)(&etext),(vm_offset_t)&etext,
+ (vm_offset_t)Sysmap,VM_PROT_READ|VM_PROT_WRITE);
+ pmap_map((vm_offset_t)Sysmap,(vm_offset_t)Sysmap,istack,
+ VM_PROT_READ|VM_PROT_WRITE);
+ pmap_map(istack,istack,istack+NBPG,VM_PROT_NONE);/* Red zone */
+ pmap_map(istack+NBPG,istack+NBPG,(vm_offset_t)scratch,
+ VM_PROT_READ|VM_PROT_WRITE);
+ pmap_map((vm_offset_t)scratch,(vm_offset_t)scratch,
+ (vm_offset_t)msgbufp, VM_PROT_READ|VM_PROT_WRITE);
+ pmap_map((vm_offset_t)msgbufp, (vm_offset_t)msgbufp,
+ (vm_offset_t)pv_table, VM_PROT_ALL);
+ pmap_map((vm_offset_t)pv_table,(vm_offset_t)pv_table,vmmap,
+ VM_PROT_READ|VM_PROT_WRITE);
+
+ /* Init kernel pmap */
+ pmap_kernel()->ref_count = 1;
+ simple_lock_init(&pmap_kernel()->pm_lock);
+ p0pmap->pm_pcb=(struct pcb *)proc0paddr;
+
+ /* used for signal trampoline code */
+ sigsida=(u_int)(scratch+NBPG)&0x7fffffff;
+ bcopy(&sigcode, (void *)sigsida, (u_int)&esigcode-(u_int)&sigcode);
+
+ p0pmap->pm_pcb->P1BR = (void *)0x80000000;
+ p0pmap->pm_pcb->P0BR = 0;
+ p0pmap->pm_pcb->P1LR = 0x200000;
+ p0pmap->pm_pcb->P0LR = AST_PCB;
+ mtpr(0x80000000, PR_P1BR);
+ mtpr(0, PR_P0BR);
+ mtpr(0x200000, PR_P1LR);
+ mtpr(AST_PCB, PR_P0LR);
+/*
+ * Now everything should be complete, start virtual memory.
+ */
+ mtpr((uint)Sysmap&0x7fffffff,PR_SBR); /* Where is SPT? */
+ mtpr(SYSPTSIZE,PR_SLR);
+ mtpr(1,PR_MAPEN);
+ bzero(valueptr, 200);
+}
+
+/****************************************************************************** *
+ * pmap_init()
+ *
+ ******************************************************************************
+ *
+ * Called as part of vm init.
+ *
+ */
+
+void
+pmap_init(s, e)
+ vm_offset_t s,e;
+{
+
+ /* reserve place on SPT for UPT */
+ pte_map = kmem_suballoc(kernel_map, &ptemapstart, &ptemapend,
+ USRPTSIZE * 4, TRUE);
+}
+
+/******************************************************************************
+ *
+ * pmap_create()
+ *
+ ******************************************************************************
+ *
+ * pmap_t pmap_create(phys_size)
+ *
+ * Create a pmap for a new task.
+ *
+ * Allocate a pmap form kernel memory with malloc.
+ * Clear the pmap.
+ * Allocate a ptab for the pmap.
+ *
+ */
+pmap_t
+pmap_create(phys_size)
+ vm_size_t phys_size;
+{
+ pmap_t pmap;
+
+#ifdef DEBUG
+if(startpmapdebug)printf("pmap_create: phys_size %x\n",phys_size);
+#endif
+ if(phys_size) return NULL;
+
+/* Malloc place for pmap struct */
+
+ pmap = (pmap_t) malloc(sizeof(struct pmap), M_VMPMAP, M_WAITOK);
+ pmap_pinit(pmap);
+
+ return (pmap);
+}
+
+
+/*
+ * Release any resources held by the given physical map.
+ * Called when a pmap initialized by pmap_pinit is being released.
+ * Should only be called if the map contains no valid mappings.
+ */
+void
+pmap_release(pmap)
+ struct pmap *pmap;
+{
+#ifdef DEBUG
+if(startpmapdebug)printf("pmap_release: pmap %x\n",pmap);
+#endif
+
+ if (pmap->pm_pcb->P0BR)
+ kmem_free_wakeup(pte_map, (vm_offset_t)pmap->pm_pcb->P0BR,
+ (pmap->pm_pcb->P0LR & ~AST_MASK) * 4);
+
+ if (pmap->pm_pcb->P1BR)
+ kmem_free_wakeup(pte_map, (vm_offset_t)pmap->pm_stack,
+ (0x200000 - pmap->pm_pcb->P1LR) * 4);
+
+ bzero(pmap, sizeof(struct pmap));
+}
+
+
+/*
+ * pmap_destroy(pmap): Remove a reference from the pmap.
+ * If the pmap is NULL then just return else decrese pm_count.
+ * If this was the last reference we call's pmap_relaese to release this pmap.
+ * OBS! remember to set pm_lock
+ */
+
+void
+pmap_destroy(pmap)
+ pmap_t pmap;
+{
+ int count;
+
+#ifdef DEBUG
+if(startpmapdebug)printf("pmap_destroy: pmap %x\n",pmap);
+#endif
+ if (pmap == NULL)
+ return;
+
+ simple_lock(&pmap->pm_lock);
+ count = --pmap->ref_count;
+ simple_unlock(&pmap->pm_lock);
+
+ if (!count) {
+ pmap_release(pmap);
+ free((caddr_t)pmap, M_VMPMAP);
+ }
+}
+
+void
+pmap_enter(pmap, v, p, prot, wired)
+ register pmap_t pmap;
+ vm_offset_t v;
+ vm_offset_t p;
+ vm_prot_t prot;
+ boolean_t wired;
+{
+ u_int j, i, pte, s, *patch;
+ pv_entry_t pv, tmp;
+
+ if (v > 0x7fffffff) pte = kernel_prot[prot] | PG_PFNUM(p) | PG_V;
+ else pte = prot_array[prot] | PG_PFNUM(p) | PG_V;
+ s = splimp();
+ pv = PHYS_TO_PV(p);
+
+#ifdef DEBUG
+if(startpmapdebug)
+printf("pmap_enter: pmap: %x,virt %x, phys %x,pv %x prot %x\n",
+ pmap,v,p,pv,prot);
+#endif
+ if (!pmap) return;
+ if (wired) pte |= PG_W;
+
+
+ if (v < 0x40000000) {
+ patch = (int *)pmap->pm_pcb->P0BR;
+ i = (v >> PG_SHIFT);
+ if (i >= (pmap->pm_pcb->P0LR&~AST_MASK))
+ pmap_expandp0(pmap, i);
+ patch = (int *)pmap->pm_pcb->P0BR;
+ } else if (v < (u_int)0x80000000) {
+ patch = (int *)pmap->pm_pcb->P1BR;
+ i = (v - 0x40000000) >> PG_SHIFT;
+ if (i < pmap->pm_pcb->P1LR)
+ panic("pmap_enter: must expand P1");
+ } else {
+ patch = (int *)Sysmap;
+ i = (v - (u_int)0x80000000) >> PG_SHIFT;
+ }
+
+ if ((patch[i] & PG_FRAME) == (pte & PG_FRAME)) { /* no map change */
+ if ((patch[i] & PG_W) != (pte & PG_W)) { /* wiring change */
+ pmap_change_wiring(pmap, v, wired);
+ } else if ((patch[i] & PG_PROT) != (pte & PG_PROT)) {
+ patch[i] &= ~PG_PROT;
+ patch[i++] |= prot_array[prot];
+ patch[i] &= ~PG_PROT;
+ patch[i] |= prot_array[prot];
+ mtpr(v, PR_TBIS);
+ mtpr(v + NBPG, PR_TBIS);
+ } else if ((patch[i] & PG_V) == 0) {
+ if (patch[i] & PG_SREF) {
+ patch[i] &= ~PG_SREF;
+ patch[i] |= PG_V | PG_REF;
+ } else patch[i] |= PG_V;
+ if (patch[++i] & PG_SREF) {
+ patch[i] &= ~PG_SREF;
+ patch[i] |= PG_V | PG_REF;
+ } else patch[i] |= PG_V;
+ mtpr(v, PR_TBIS);
+ mtpr(v + NBPG, PR_TBIS);
+ } /* else nothing to do */
+ splx(s);
+ return;
+ }
+
+ if (!pv->pv_pmap) {
+ pv->pv_pmap = pmap;
+ pv->pv_next = NULL;
+ pv->pv_va = v;
+ } else {
+ tmp = alloc_pv_entry();
+ tmp->pv_pmap = pmap;
+ tmp->pv_next = pv->pv_next;
+ tmp->pv_va = v;
+ pv->pv_next = tmp;
+ }
+ patch[i++] = pte++;
+ patch[i] = pte;
+ mtpr(v, PR_TBIS);
+ mtpr(v + NBPG, PR_TBIS);
+ splx(s);
+}
+
+void *
+pmap_bootstrap_alloc(size)
+ int size;
+{
+ void *mem;
+
+ size = round_page(size);
+ mem = (void *)virtual_avail;
+ virtual_avail = pmap_map(virtual_avail, avail_start,
+ avail_start + size, VM_PROT_READ|VM_PROT_WRITE);
+ avail_start += size;
+ blkclr(mem, size);
+ return (mem);
+}
+
+vm_offset_t
+pmap_map(virtuell, pstart, pend, prot)
+ vm_offset_t virtuell, pstart, pend;
+ int prot;
+{
+ vm_offset_t count;
+ int *pentry;
+
+#ifdef DEBUG
+if(startpmapdebug)printf("pmap_map: virt %x, pstart %x, pend %x\n",virtuell, pstart, pend);
+#endif
+
+ pstart=(uint)pstart &0x7fffffff;
+ pend=(uint)pend &0x7fffffff;
+ virtuell=(uint)virtuell &0x7fffffff;
+ (uint)pentry= (((uint)(virtuell)>>PGSHIFT)*4)+(uint)Sysmap;
+ for(count=pstart;count<pend;count+=NBPG){
+ *pentry++ = (count>>PGSHIFT)|kernel_prot[prot]|PG_V;
+ }
+ mtpr(0,PR_TBIA);
+ return(virtuell+(count-pstart)+0x80000000);
+}
+
+vm_offset_t
+pmap_extract(pmap, va)
+ pmap_t pmap;
+ vm_offset_t va;
+{
+
+ int *pte, nypte;
+#ifdef DEBUG
+if(startpmapdebug)printf("pmap_extract: pmap %x, va %x\n",pmap, va);
+#endif
+
+ pte=(int *)pmap_virt2pte(pmap,va);
+ if(pte) return(((*pte&PG_FRAME)<<PG_SHIFT)+((u_int)va&PGOFSET));
+ else return 0;
+}
+
+/*
+ * pmap_protect( pmap, vstart, vend, protect)
+ */
+void
+pmap_protect(pmap, start, end, prot)
+ pmap_t pmap;
+ vm_offset_t start;
+ vm_offset_t end;
+ vm_prot_t prot;
+{
+ int pte, *patch, s;
+
+#ifdef DEBUG
+if(startpmapdebug) printf("pmap_protect: pmap %x, start %x, end %x, prot %x\n",
+ pmap, start, end,prot);
+#endif
+ if(pmap==NULL) return;
+ s=splimp();
+ if(start>0x7fffffff) pte=kernel_prot[prot];
+ else pte=prot_array[prot];
+
+ if(end<0x40000000){
+ while((end>>PG_SHIFT)>(pmap->pm_pcb->P0LR&~AST_MASK))
+ pmap_expandp0(pmap,(end>>PG_SHIFT));
+ } else if(end<(u_int)0x80000000){
+ u_int i;
+ i=(start&0x3fffffff)>>PG_SHIFT;
+ if(i<pmap->pm_pcb->P1LR)
+ start=((pmap->pm_pcb->P1LR)<<PG_SHIFT)+0x40000000;
+ i=(end&0x3fffffff)>>PG_SHIFT;
+ if(i<pmap->pm_pcb->P1LR) return;
+ }
+ while (start < end) {
+ patch = (int *)pmap_virt2pte(pmap,start);
+ if(patch){
+ *patch&=(~PG_PROT);
+ *patch|=pte;
+ mtpr(start,PR_TBIS);
+ }
+ start += NBPG;
+ }
+ mtpr(0,PR_TBIA);
+ splx(s);
+}
+
+/*
+ * pmap_remove(pmap, start, slut) removes all valid mappings between
+ * the two virtual adresses start and slut from pmap pmap.
+ * NOTE: all adresses between start and slut may not be mapped.
+ */
+
+void
+pmap_remove(pmap, start, slut)
+ pmap_t pmap;
+ vm_offset_t start, slut;
+{
+ u_int *ptestart, *pteslut,i,s,*temp;
+ pv_entry_t pv;
+ vm_offset_t countup;
+
+#ifdef DEBUG
+if(startpmapdebug) printf("pmap_remove: pmap=0x %x, start=0x %x, slut=0x %x\n",
+ pmap, start, slut);
+#endif
+
+ if(!pmap) return;
+ if(!pmap->pm_pcb&&start<0x80000000) return; /* No page registers */
+/* First, get pte first address */
+ if(start<0x40000000){ /* P0 */
+ if(!(temp=pmap->pm_pcb->P0BR)) return; /* No page table */
+ ptestart=&temp[start>>PG_SHIFT];
+ pteslut=&temp[slut>>PG_SHIFT];
+ if(pteslut>&temp[(pmap->pm_pcb->P0LR&~AST_MASK)])
+ pteslut=&temp[(pmap->pm_pcb->P0LR&~AST_MASK)];
+ } else if(start>0x7fffffff){ /* System region */
+ ptestart=(u_int *)&Sysmap[(start&0x3fffffff)>>PG_SHIFT];
+ pteslut=(u_int *)&Sysmap[(slut&0x3fffffff)>>PG_SHIFT];
+ } else { /* P1 (stack) region */
+ if(!(temp=pmap->pm_pcb->P1BR)) return; /* No page table */
+ pteslut=&temp[(slut&0x3fffffff)>>PG_SHIFT];
+ ptestart=&temp[(start&0x3fffffff)>>PG_SHIFT];
+ if(ptestart<&temp[pmap->pm_pcb->P1LR])
+ ptestart=&temp[pmap->pm_pcb->P1LR];
+ }
+
+#ifdef DEBUG
+if(startpmapdebug)
+printf("pmap_remove: ptestart %x, pteslut %x, pv %x\n",ptestart, pteslut,pv);
+#endif
+
+ s=splimp();
+ for(countup=start;ptestart<pteslut;ptestart+=2, countup+=PAGE_SIZE){
+
+ if(!(*ptestart&PG_FRAME))
+ continue; /* not valid phys addr,no mapping */
+
+ pv=PTE_TO_PV(*ptestart);
+ if(!remove_pmap_from_mapping(pv,pmap)){
+ panic("pmap_remove: pmap not in pv_table");
+ }
+ *ptestart=0;
+ *(ptestart+1)=0;
+ }
+ mtpr(0,PR_TBIA);
+ splx(s);
+}
+
+
+remove_pmap_from_mapping(pv, pmap)
+ pv_entry_t pv;
+ pmap_t pmap;
+{
+ pv_entry_t temp_pv,temp2;
+
+ if(!pv->pv_pmap&&pv->pv_next)
+ panic("remove_pmap_from_mapping: j{ttefel");
+
+ if(pv->pv_pmap==pmap){
+ if(pv->pv_next){
+ temp_pv=pv->pv_next;
+ pv->pv_pmap=temp_pv->pv_pmap;
+ pv->pv_va=temp_pv->pv_va;
+ pv->pv_next=temp_pv->pv_next;
+ free_pv_entry(temp_pv);
+ } else {
+ bzero(pv,sizeof(struct pv_entry));
+ }
+ } else {
+ temp_pv=pv;
+ while(temp_pv->pv_next){
+ if(temp_pv->pv_next->pv_pmap==pmap){
+ temp2=temp_pv->pv_next;
+ temp_pv->pv_next=temp2->pv_next;
+ free_pv_entry(temp2);
+ return 1;
+ }
+ temp_pv=temp_pv->pv_next;
+ }
+ return 0;
+ }
+ return 1;
+}
+
+void
+pmap_copy_page(src, dst)
+ vm_offset_t src;
+ vm_offset_t dst;
+{
+ int s;
+ extern uint vmmap;
+
+#ifdef DEBUG
+if(startpmapdebug)printf("pmap_copy_page: src %x, dst %x\n",src, dst);
+#endif
+ s=splimp();
+ pte_cmap[0]=(src>>PGSHIFT)|PG_V|PG_RO;
+ pte_cmap[1]=(dst>>PGSHIFT)|PG_V|PG_KW;
+ mtpr(vmmap,PR_TBIS);
+ mtpr(vmmap+NBPG,PR_TBIS);
+ bcopy((void *)vmmap, (void *)vmmap+NBPG, NBPG);
+ pte_cmap[0]=((src+NBPG)>>PGSHIFT)|PG_V|PG_RO;
+ pte_cmap[1]=((dst+NBPG)>>PGSHIFT)|PG_V|PG_RW;
+ mtpr(vmmap,PR_TBIS);
+ mtpr(vmmap+NBPG,PR_TBIS);
+ bcopy((void *)vmmap, (void *)vmmap+NBPG, NBPG);
+ splx(s);
+}
+
+pv_entry_t
+alloc_pv_entry()
+{
+ pv_entry_t temporary;
+
+ if(!pv_head) {
+ temporary=(pv_entry_t)malloc(sizeof(struct pv_entry),
+ M_VMPVENT, M_NOWAIT);
+#ifdef DEBUG
+if(startpmapdebug) printf("alloc_pv_entry: %x\n",temporary);
+#endif
+ } else {
+ temporary=pv_head;
+ pv_head=temporary->pv_next;
+ pv_count--;
+ }
+ bzero(temporary, sizeof(struct pv_entry));
+ return temporary;
+}
+
+void
+free_pv_entry(entry)
+ pv_entry_t entry;
+{
+ if(pv_count>=100) { /* Should be a define? */
+ free(entry, M_VMPVENT);
+ } else {
+ entry->pv_next=pv_head;
+ pv_head=entry;
+ pv_count++;
+ }
+}
+
+boolean_t
+pmap_is_referenced(pa)
+ vm_offset_t pa;
+{
+ struct pv_entry *pv;
+ u_int *pte,spte=0;
+
+ pv=PHYS_TO_PV(pa);
+
+ if(!pv->pv_pmap) return 0;
+
+ do {
+ pte=(u_int *)pmap_virt2pte(pv->pv_pmap,pv->pv_va);
+ spte|=*pte++;
+ spte|=*pte;
+ } while(pv=pv->pv_next);
+ return((spte&PG_REF)?1:0);
+}
+
+boolean_t
+pmap_is_modified(pa)
+ vm_offset_t pa;
+{
+ struct pv_entry *pv;
+ u_int *pte, spte=0;
+
+ pv=PHYS_TO_PV(pa);
+ if(!pv->pv_pmap) return 0;
+ do {
+ pte=(u_int *)pmap_virt2pte(pv->pv_pmap,pv->pv_va);
+ spte|=*pte++;
+ spte|=*pte;
+ } while(pv=pv->pv_next);
+ return((spte&PG_M)?1:0);
+}
+
+/*
+ * Reference bits are simulated and connected to logical pages,
+ * not physical. This makes reference simulation much easier.
+ */
+
+void
+pmap_clear_reference(pa)
+ vm_offset_t pa;
+{
+ struct pv_entry *pv;
+ int *pte,s,i;
+/*
+ * Simulate page reference bit
+ */
+ pv=PHYS_TO_PV(pa);
+#ifdef DEBUG
+if(startpmapdebug) printf("pmap_clear_reference: pa %x, pv %x\n",pa,pv);
+#endif
+
+ pv->pv_flags&=~PV_REF;
+ if(!pv->pv_pmap) return;
+
+ do {
+ pte=(int *)pmap_virt2pte(pv->pv_pmap,pv->pv_va);
+ *pte&= ~(PG_REF|PG_V);
+ *pte++|=PG_SREF;
+ *pte&= ~(PG_REF|PG_V);
+ *pte|=PG_SREF;
+ } while(pv=pv->pv_next);
+ mtpr(0,PR_TBIA);
+}
+
+void
+pmap_clear_modify(pa)
+ vm_offset_t pa;
+{
+ struct pv_entry *pv;
+ u_int *pte,spte=0,s;
+
+ pv=PHYS_TO_PV(pa);
+ if(!pv->pv_pmap) return;
+ do {
+ pte=(u_int *)pmap_virt2pte(pv->pv_pmap,pv->pv_va);
+ *pte++&= ~PG_M;
+ *pte&= ~PG_M;
+ } while(pv=pv->pv_next);
+}
+
+void
+pmap_change_wiring(pmap, va, wired)
+ register pmap_t pmap;
+ vm_offset_t va;
+ boolean_t wired;
+{
+ int *pte;
+#ifdef DEBUG
+if(startpmapdebug) printf("pmap_change_wiring: pmap %x, va %x, wired %x\n",
+ pmap, va, wired);
+#endif
+
+ pte=(int *)pmap_virt2pte(pmap,va);
+ if(!pte) return; /* no pte allocated */
+ if(wired) *pte|=PG_W;
+ else *pte&=~PG_W;
+}
+
+/*
+ * pmap_page_protect:
+ *
+ * Lower the permission for all mappings to a given page.
+ */
+void
+pmap_page_protect(pa, prot)
+ vm_offset_t pa;
+ vm_prot_t prot;
+{
+ pv_entry_t pv,opv;
+ u_int s,*pte,*pte1,nyprot,kprot;
+
+#ifdef DEBUG
+if(startpmapdebug) printf("pmap_page_protect: pa %x, prot %x\n",pa, prot);
+#endif
+ pv = PHYS_TO_PV(pa);
+ if(!pv->pv_pmap) return;
+ nyprot=prot_array[prot];
+ kprot=kernel_prot[prot];
+
+ switch (prot) {
+
+ case VM_PROT_ALL:
+ break;
+ case VM_PROT_READ:
+ case VM_PROT_READ|VM_PROT_EXECUTE:
+ do {
+ pte=pte1=(int *)pmap_virt2pte(pv->pv_pmap, pv->pv_va);
+ s=splimp();
+ *pte1++&=~PG_PROT;
+ *pte1&=~PG_PROT;
+ if(pv->pv_va>0x7fffffff){
+ *pte|=kprot;
+ *pte1|=kprot;
+ } else{
+ *pte|=nyprot;
+ *pte1|=nyprot;
+ }
+ splx(s);
+ } while(pv=pv->pv_next);
+ mtpr(0,PR_TBIA);
+ break;
+
+ default:
+
+ pte=(int *)pmap_virt2pte(pv->pv_pmap, pv->pv_va);
+ s = splimp();
+ *pte++=0;
+ *pte=0;
+ opv=pv;
+ pv=pv->pv_next;
+ bzero(opv,sizeof(struct pv_entry));
+ while(pv){
+ pte=(int *)pmap_virt2pte(pv->pv_pmap, pv->pv_va);
+ *pte++=0;
+ *pte=0;
+ opv=pv;
+ pv=pv->pv_next;
+ free_pv_entry(opv);
+ }
+
+ mtpr(0,PR_TBIA);
+ splx(s);
+ break;
+ }
+}
+
+/*
+ * pmap_zero_page zeros the specified (machine independent)
+ * page by mapping the page into virtual memory and using
+ * bzero to clear its contents, one machine dependent page
+ * at a time.
+ */
+void
+pmap_zero_page(phys)
+ vm_offset_t phys;
+{
+ int s;
+
+#ifdef DEBUG
+if(startpmapdebug)printf("pmap_zero_page(phys %x, vmmap %x, pte_cmap %x\n",
+ phys,vmmap,pte_cmap);
+#endif
+ s=splimp();
+ pte_cmap[0]=(phys>>PG_SHIFT)|PG_V|PG_KW;
+ pte_cmap[1]=pte_cmap[0]+1;
+ mtpr(vmmap,PR_TBIS);
+ mtpr(vmmap+NBPG,PR_TBIS);
+ bzero((void *)vmmap,NBPG*2);
+ pte_cmap[0]=pte_cmap[1]=0;
+ mtpr(vmmap,PR_TBIS);
+ mtpr(vmmap+NBPG,PR_TBIS);
+ splx(s);
+}
+
+pt_entry_t *
+pmap_virt2pte(pmap,vaddr)
+ pmap_t pmap;
+ u_int vaddr;
+{
+ u_int *pte,scr;
+
+ if(vaddr<0x40000000){
+ pte=pmap->pm_pcb->P0BR;
+ if((vaddr>>PG_SHIFT)>(pmap->pm_pcb->P0LR&~AST_MASK)) return 0;
+ } else if(vaddr<(u_int)0x80000000){
+ pte=pmap->pm_pcb->P1BR;
+ if(((vaddr&0x3fffffff)>>PG_SHIFT)<pmap->pm_pcb->P1LR) return 0;
+ } else {
+ pte=(u_int *)Sysmap;
+ }
+
+ vaddr&=(u_int)0x3fffffff;
+
+ return((pt_entry_t *)&pte[vaddr>>PG_SHIFT]);
+}
+
+pmap_expandp0(pmap,ny_storlek)
+ struct pmap *pmap;
+{
+ u_int tmp,s,size,osize,oaddr,astlvl,*i,j;
+
+ astlvl=pmap->pm_pcb->P0LR&AST_MASK;
+ osize=(pmap->pm_pcb->P0LR&~AST_MASK)*4;
+ size=ny_storlek*4;
+ tmp=kmem_alloc_wait(pte_map, size);
+ s=splhigh();
+ if(osize) blkcpy(pmap->pm_pcb->P0BR, (void*)tmp,osize);
+ oaddr=(u_int)pmap->pm_pcb->P0BR;
+ mtpr(tmp,PR_P0BR);
+ mtpr(((size>>2)|astlvl),PR_P0LR);
+ mtpr(0,PR_TBIA);
+ pmap->pm_pcb->P0BR=(void*)tmp;
+ pmap->pm_pcb->P0LR=((size>>2)|astlvl);
+ splx(s);
+ if(osize)
+ kmem_free_wakeup(pte_map, (vm_offset_t)oaddr, osize);
+}
+
+pmap_expandp1(pmap)
+ struct pmap *pmap;
+{
+ u_int tmp,s,size,osize,oaddr,*i,j;
+
+ osize=0x800000-(pmap->pm_pcb->P1LR*4);
+ size=osize+PAGE_SIZE;
+ tmp=kmem_alloc_wait(pte_map, size);
+ s=splhigh();
+
+ if(osize) blkcpy((void*)pmap->pm_stack, (void*)tmp+PAGE_SIZE,osize);
+ oaddr=pmap->pm_stack;
+ pmap->pm_pcb->P1BR=(void*)(tmp+size-0x800000);
+ pmap->pm_pcb->P1LR=(0x800000-size)>>2;
+ pmap->pm_stack=tmp;
+ mtpr(pmap->pm_pcb->P1BR,PR_P1BR);
+ mtpr(pmap->pm_pcb->P1LR,PR_P1LR);
+ mtpr(0,PR_TBIA);
+ splx(s);
+ if (osize)
+ kmem_free_wakeup(pte_map, (vm_offset_t)oaddr, osize);
+}
diff --git a/sys/arch/vax/vax/random.s b/sys/arch/vax/vax/random.s
new file mode 100644
index 00000000000..b6dc4db0bff
--- /dev/null
+++ b/sys/arch/vax/vax/random.s
@@ -0,0 +1,83 @@
+/* $NetBSD: random.s,v 1.2 1994/10/26 08:03:24 cgd Exp $ */
+
+/*
+ * Copyright (c) 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: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Here is a very good random number generator. This implementation is
+ * based on ``Two Fast Implementations of the "Minimal Standard" Random
+ * Number Generator'', David G. Carta, Communications of the ACM, Jan 1990,
+ * Vol 33 No 1. Do NOT modify this code unless you have a very thorough
+ * understanding of the algorithm. It's trickier than you think. If
+ * you do change it, make sure that its 10,000'th invocation returns
+ * 1043618065.
+ *
+ * This implementation Copyright (c) 1994 Ludd, University of Lule}, Sweden
+ * All rights reserved.
+ *
+ * All bugs subject to removal without further notice.
+ *
+ * Here is easier-to-decipher pseudocode:
+ *
+ * p = (16807*seed)<30:0> # e.g., the low 31 bits of the product
+ * q = (16807*seed)<62:31> # e.g., the high 31 bits starting at bit 32
+ * if (p + q < 2^31)
+ * seed = p + q
+ * else
+ * seed = ((p + q) & (2^31 - 1)) + 1
+ * return (seed);
+ *
+ * The result is in (0,2^31), e.g., it's always positive.
+ */
+
+ .data
+randseed:
+ .long 1
+ .text
+ .globl _random
+_random:
+ .word 0x0
+ movl $16807,r0
+
+ movl randseed,r1 # r2=16807*loword(randseed)
+ bicl3 $0xffff0000,r1,r2
+ mull2 r0,r2
+ ashl $-16,r1,r1 # r1=16807*hiword(randseed)
+ bicl2 $0xffff0000,r1
+ mull2 r0,r1
+ bicl3 $0xffff0000,r2,r0
+ ashl $-16,r2,r2 # r1+=(r2>>16)
+ bicl2 $0xffff0000,r2
+ addl2 r2,r1
+ ashl $16,r1,r2 # r0|=r1<<16
+ bisl2 r2,r0
+ ashl $-16,r1,r1 # r1=r1>>16
+
+ ashl $1,r1,r1
+ movl r0,r2
+ rotl $1,r0,r0
+ bicl2 $0xfffffffe,r0
+ bisl2 r0,r1
+ movl r2,r0
+ bicl2 $0x80000000,r0
+ addl2 r1,r0
+ bgeq L1
+ subl2 $0x7fffffff,r0
+L1: movl r0,randseed
+ ret
diff --git a/sys/arch/vax/vax/rootfil.c b/sys/arch/vax/vax/rootfil.c
new file mode 100644
index 00000000000..38ab448b58f
--- /dev/null
+++ b/sys/arch/vax/vax/rootfil.c
@@ -0,0 +1,229 @@
+/* $NetBSD: rootfil.c,v 1.6 1995/04/12 15:35:04 ragge Exp $ */
+
+/*
+ * Copyright (c) 1988 University of Utah.
+ * Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
+ * Copyright (c) 1994 Ludd, University of Lule}, Sweden.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * 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: machdep.c 1.63 91/04/24
+ *
+ * @(#)machdep.c 7.16 (Berkeley) 6/3/91
+ */
+ /* All bugs are subject to removal without further notice */
+
+#include "param.h"
+#include "vax/include/sid.h"
+#include "buf.h"
+#include "mbuf.h"
+#include "vax/include/pte.h"
+#include "uda.h"
+#include "uba.h"
+#include "reboot.h"
+#include "conf.h"
+#include "vax/include/macros.h"
+#include "vax/include/nexus.h"
+#include "vax/uba/ubavar.h"
+
+#define DOSWAP /* Change swdevt, argdev, and dumpdev too */
+u_long bootdev; /* should be dev_t, but not until 32 bits */
+extern dev_t rootdev, dumpdev;
+
+static char devname[][2] = {
+ 'h','p', /* 0 = hp */
+ 0,0, /* 1 = ht */
+ 'u','p', /* 2 = up */
+ 'r','k', /* 3 = hk */
+ 0,0, /* 4 = sw */
+ 0,0, /* 5 = tm */
+ 0,0, /* 6 = ts */
+ 0,0, /* 7 = mt */
+ 0,0, /* 8 = tu */
+ 'r','a', /* 9 = ra */
+ 0,0, /* 10 = ut */
+ 'r','b', /* 11 = rb */
+ 0,0, /* 12 = uu */
+ 0,0, /* 13 = rx */
+ 'r','l', /* 14 = rl */
+ 0,0, /* 15 = tmscp */
+ 'k','r', /* 16 = ra on kdb50 */
+};
+
+#define PARTITIONMASK 0x7
+#define PARTITIONSHIFT 3
+
+/*
+ * Attempt to find the device from which we were booted.
+ * If we can do so, and not instructed not to do so,
+ * change rootdev to correspond to the load device.
+ */
+setroot()
+{
+ int majdev, mindev, unit, part, controller, adaptor;
+ dev_t temp, orootdev;
+#if NUDA > 0
+ extern struct uba_device ubdinit[];
+#endif
+ struct swdevt *swp;
+ extern int boothowto;
+
+ if (boothowto & RB_DFLTROOT ||
+ (bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC)
+ return;
+ majdev = B_TYPE(bootdev);
+ if (majdev >= sizeof(devname) / sizeof(devname[0]))
+ return;
+ adaptor = B_ADAPTOR(bootdev);
+ controller = B_CONTROLLER(bootdev);
+ part = B_PARTITION(bootdev);
+ unit = B_UNIT(bootdev);
+ if (majdev == 0) { /* MBA device */
+#if NMBA > 0
+ register struct mba_device *mbap;
+ int mask;
+
+/*
+ * The MBA number used at boot time is not necessarily the same as the
+ * MBA number used by the kernel. In order to change the rootdev we need to
+ * convert the boot MBA number to the kernel MBA number. The address space
+ * for an MBA used by the boot code is 0x20010000 + 0x2000 * MBA_number
+ * on the 78? and 86?0, 0xf28000 + 0x2000 * MBA_number on the 750.
+ * Therefore we can search the mba_hd table for the MBA that has the physical
+ * address corresponding to the boot MBA number.
+ */
+#define PHYSADRSHFT 13
+#define PHYSMBAMASK780 0x7
+#define PHYSMBAMASK750 0x3
+
+ switch (MACHID(cpu_type)) {
+
+ case VAX_780:
+/* case VAX_8600: */
+ default:
+ mask = PHYSMBAMASK780;
+ break;
+
+ case VAX_750:
+ mask = PHYSMBAMASK750;
+ break;
+ }
+ for (mbap = mbdinit; mbap->driver; mbap++)
+ if (mbap->alive && mbap->drive == unit &&
+ (((long)mbap->hd->mh_physmba >> PHYSADRSHFT)
+ & mask) == adaptor)
+ break;
+ if (mbap->driver == 0)
+ return;
+ mindev = mbap->unit;
+#else
+ return;
+#endif
+#if NUBA > 0
+ } else {
+ register struct uba_device *ubap;
+
+ for (ubap = ubdinit; ubap->ui_driver; ubap++){
+ printf("ubap %x\n",ubap);
+ if (ubap->ui_alive && ubap->ui_slave == unit &&
+ ubap->ui_ctlr == controller &&
+ ubap->ui_ubanum == adaptor &&
+ ubap->ui_driver->ud_dname[0] == devname[majdev][0] &&
+ ubap->ui_driver->ud_dname[1] == devname[majdev][1])
+ break;
+ }
+ if (ubap->ui_driver == 0)
+ return;
+ mindev = ubap->ui_unit;
+ printf("mindev %x, majdev %x\n",mindev,majdev);
+#endif
+ }
+ mindev = (mindev << PARTITIONSHIFT) + part;
+ orootdev = rootdev;
+ rootdev = makedev(majdev, mindev);
+ /*
+ * If the original rootdev is the same as the one
+ * just calculated, don't need to adjust the swap configuration.
+ */
+ if (rootdev == orootdev)
+ return;
+
+ printf("Changing root device to %c%c%d%c\n",
+ devname[majdev][0], devname[majdev][1],
+ mindev >> PARTITIONSHIFT, part + 'a');
+
+#ifdef DOSWAP
+ mindev &= ~PARTITIONMASK;
+ for (swp = swdevt; swp->sw_dev; swp++) {
+ if (majdev == major(swp->sw_dev) &&
+ mindev == (minor(swp->sw_dev) & ~PARTITIONMASK)) {
+ temp = swdevt[0].sw_dev;
+ swdevt[0].sw_dev = swp->sw_dev;
+ swp->sw_dev = temp;
+ break;
+ }
+ }
+ if (swp->sw_dev == 0)
+ return;
+
+ /*
+ * If argdev and dumpdev were the same as the old primary swap
+ * device, move them to the new primary swap device.
+ */
+ if (temp == dumpdev)
+ dumpdev = swdevt[0].sw_dev;
+ panic("autoconf.c: argdev\n");
+/* if (temp == argdev)
+ argdev = swdevt[0].sw_dev; */
+#endif
+}
+
+/*
+ * Configure swap space and related parameters.
+ */
+swapconf()
+{
+ register struct swdevt *swp;
+ register int nblks;
+
+ for (swp = swdevt; swp->sw_dev; swp++)
+ if (swp->sw_dev != NODEV &&bdevsw[major(swp->sw_dev)].d_psize){
+ nblks =
+ (*bdevsw[major(swp->sw_dev)].d_psize)(swp->sw_dev);
+ if (nblks != -1 &&
+ (swp->sw_nblks == 0 || swp->sw_nblks > nblks))
+ swp->sw_nblks = nblks;
+ }
+ dumpconf();
+}
diff --git a/sys/arch/vax/vax/sbi.c b/sys/arch/vax/vax/sbi.c
new file mode 100644
index 00000000000..5306145e1a0
--- /dev/null
+++ b/sys/arch/vax/vax/sbi.c
@@ -0,0 +1,178 @@
+/* $NetBSD: sbi.c,v 1.2 1995/02/23 17:54:03 ragge Exp $ */
+/*
+ * Copyright (c) 1994 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}.
+ * 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 "sys/types.h"
+#include "sys/param.h"
+#include "sys/device.h"
+#include "vm/vm.h"
+#include "vm/vm_kern.h"
+#include "vm/vm_page.h"
+#include "machine/nexus.h"
+#include "machine/pmap.h"
+#include "machine/sid.h"
+
+static int sbi_attached=0;
+
+struct bp_conf {
+ char *type;
+ int num;
+ int partyp;
+};
+
+int
+sbi_print(aux, name)
+ void *aux;
+ char *name;
+{
+ struct sbi_attach_args *sa=(struct sbi_attach_args *)aux;
+ int unsupp=0;
+ extern int nmba;
+
+ if(name){
+ switch(sa->type){
+ case NEX_MBA:
+ printf("mba%d at %s",nmba++, name);
+ unsupp++;
+ break;
+ default:
+ printf("unknown device 0x%x at %s",sa->type,name);
+ unsupp++;
+ }
+ }
+ printf(" tr%d",sa->nexnum);
+ return(unsupp?UNSUPP:UNCONF);
+}
+
+int
+sbi_match(parent, cf, aux)
+ struct device *parent;
+ struct cfdata *cf;
+ void *aux;
+{
+ struct bp_conf *bp=aux;
+
+ if(strcmp(bp->type,"sbi"))
+ return 1;
+ return 0;
+}
+
+void
+sbi_attach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ void *nisse;
+ struct nexus *nexus;
+ u_int nextype, nexnum, maxnex;
+ struct sbi_attach_args sa;
+
+ /* SBI space should be alloc'ed in SYSPT instead */
+ kmem_suballoc(kernel_map, (void*)&nexus, (void*)&nisse,
+ (NNEXSBI*sizeof(struct nexus)), FALSE);
+ switch(cpunumber){
+#ifdef VAX730
+ case VAX_730:
+ pmap_map((int)nexus, 0xf20000, 0xf40000, VM_PROT_READ|VM_PROT_WRITE);
+ maxnex = NNEX730;
+ printf(": BL[730\n");
+ break;
+#endif
+#ifdef VAX750
+ case VAX_750:
+ pmap_map((int)nexus, 0xf20000, 0xf40000, VM_PROT_READ|VM_PROT_WRITE);
+ maxnex = NNEX750;
+ printf(": CMI750\n");
+ break;
+#endif
+#ifdef VAX630
+ case VAX_78032:
+ switch (cpu_type) {
+ case VAX_630:
+ pmap_map((int)nexus, 0x20088000, 0x200a8000,
+ VM_PROT_READ|VM_PROT_WRITE);
+ maxnex = NNEX630;
+ printf(": Q22\n");
+ break;
+ default:
+ panic("Microvax not supported");
+ };
+ break;
+#endif
+
+ case VAX_780:
+ case VAX_8600:
+ maxnex = NNEXSBI;
+ printf(": SBI780\n");
+ }
+
+/*
+ * Now a problem: on different machines with SBI units identifies
+ * in different ways (if they identifies themselves at all).
+ * We have to fake identifying depending on different CPUs.
+ */
+ for(nexnum=0;nexnum<maxnex;nexnum++){
+ if(badaddr((caddr_t)&nexus[nexnum],4))continue;
+
+ switch(cpunumber){
+#ifdef VAX750
+ case VAX_750:
+ { extern int nexty750[];
+ sa.type=nexty750[nexnum];
+ break;
+ }
+#endif
+#ifdef VAX730
+ case VAX_730:
+ { extern int nexty730[];
+ sa.type=nexty730[nexnum];
+ break;
+ }
+#endif
+#ifdef VAX630
+ case VAX_78032:
+ sa.type = NEX_UBA0;
+ break;
+#endif
+ default:
+ sa.type=nexus[nexnum].nexcsr.nex_type;
+ }
+ sa.nexnum=nexnum;
+ sa.nexaddr=nexus+nexnum;
+ config_found(self, (void*)&sa, sbi_print);
+ }
+}
+
+struct cfdriver sbicd =
+ { NULL, "sbi", sbi_match, sbi_attach, DV_DULL, sizeof(struct device) };
+
diff --git a/sys/arch/vax/vax/subr.s b/sys/arch/vax/vax/subr.s
new file mode 100644
index 00000000000..a0d9d5d6b73
--- /dev/null
+++ b/sys/arch/vax/vax/subr.s
@@ -0,0 +1,279 @@
+/* $NetBSD: subr.s,v 1.11 1995/06/16 15:36:50 ragge Exp $ */
+
+/*
+ * Copyright (c) 1994 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}.
+ * 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 "vax/include/mtpr.h"
+#include "vax/include/param.h"
+#include "vax/include/loconf.h"
+#include "vax/include/vmparam.h"
+#include "vax/include/pte.h"
+#include "vax/include/nexus.h"
+#include "sys/syscall.h"
+#include "sys/errno.h"
+
+
+ .text
+
+ .globl _sigcode,_esigcode
+_sigcode: pushr $0x3f
+ subl2 $0xc,sp
+ movl 0x24(sp),r0
+ calls $3,(r0)
+ popr $0x3f
+ chmk $SYS_sigreturn
+ halt
+ .align 2
+_esigcode:
+
+ .globl _subyte
+_subyte: .word 0x0
+ movl 4(ap),r0
+# probew $3,$1,(r0)
+# beql suerr
+ movb 8(ap),(r0)
+ clrl r0
+ ret
+
+suerr: movl $-1,r0
+ ret
+
+ .globl _fubyte
+_fubyte: .word 0x0
+ movl 4(ap),r0
+# prober $3,$1,(r0)
+# beql suerr
+ movzbl (r0),r0
+ ret
+
+
+
+
+
+
+
+ .globl _physcopypage
+_physcopypage: .word 0x7
+ movl 4(ap),r0
+ ashl $-PGSHIFT,r0,r0
+ bisl2 $(PG_V|PG_RO),r0
+
+ movl 8(ap),r1
+ ashl $-PGSHIFT,r1,r1
+ bisl2 $(PG_V|PG_KW),r1
+
+ movl r0,*(_pte_cmap)
+ movl r1,*$4+(_pte_cmap)
+
+ movl _vmmap,r2
+ addl3 $0x200,r2,r1
+ mtpr r1,$PR_TBIS
+ mtpr r2,$PR_TBIS
+
+ movl r1,r0
+1: movl (r2)+,(r1)+
+ cmpl r0,r2
+ bneq 1b
+ ret
+
+
+ .globl _badaddr
+_badaddr: .word 0x0
+ # Called with addr,b/w/l
+ mfpr $0x12,r0
+ mtpr $0x1f,$0x12
+ movl 4(ap),r2 # First argument, the address
+ movl 8(ap),r1 # Sec arg, b,w,l
+ pushl r0 # Save old IPL
+ clrl r3
+ movl $4f,_memtest # Set the return adress
+
+ caseb r1,$1,$4 # What is the size
+1: .word 1f-1b
+ .word 2f-1b
+ .word 3f-1b # This is unused
+ .word 3f-1b
+
+1: movb (r2),r1 # Test a byte
+ brb 5f
+
+2: movw (r2),r1 # Test a word
+ brb 5f
+
+3: movl (r2),r1 # Test a long
+ brb 5f
+
+4: incl r3 # Got machine chk => addr bad
+5: mtpr (sp)+,$0x12
+ movl r3,r0
+ ret
+
+#
+# copyin(from, to, len) copies from userspace to kernelspace.
+#
+
+ .globl _locopyin
+_locopyin:.word 0x1c
+ movl 16(ap),r0 # Get fault pointer flag
+ movl $ci,(r0)
+
+ movl 4(ap),r0 # from
+ movl 8(ap),r1 # to
+ movl 12(ap),r2 # len
+
+ movl r0,r4
+ movl r2,r3
+
+ tstl r2
+ beql 3f
+2: movb (r0)+,(r1)+ # XXX Should be done in a faster way.
+ decl r2
+ bneq 2b
+3: movl 16(ap),r0
+ clrl (r0)
+ clrl r0
+ci: ret
+
+#
+# locopyout(from, to, len, addr) in the same manner as copyin()
+# addr is iftrap addr for faulting.
+#
+
+ .globl _locopyout
+_locopyout:.word 0x1c
+ movl 16(ap),r0 # Get fault pointer flag
+ movl $co,(r0) # and save ret addr
+
+ movl 4(ap),r0 # from
+ movl 8(ap),r1 # to
+ movl 12(ap),r2 # len
+
+ movl r1,r4
+ movl r2,r3
+
+ tstl r2
+ beql 3f
+2: movb (r0)+,(r1)+ # XXX Should be done in a faster way.
+ decl r2
+ bneq 2b
+3: movl 16(ap),r0
+ clrl (r0)
+ clrl r0
+co: ret
+
+#
+# copystr(from, to, maxlen, *copied, addr)
+# Only used in kernel mode, doesnt check accessability.
+#
+
+ .globl _copystr
+_copystr: .word 0x7c
+ movl 4(ap),r4 # from
+ movl 8(ap),r5 # to
+ movl 12(ap),r2 # len
+ movl 16(ap),r3 # copied
+
+#if VAX630
+ movl r4, r1 # (3) string address == r1
+ movl r2, r0 # (2) string length == r0
+ jeql Llocc_out # forget zero length strings
+Llocc_loop:
+ tstb (r1)
+ jeql Llocc_out
+ incl r1
+ sobgtr r0,Llocc_loop
+Llocc_out:
+ tstl r0 # be sure of condition codes
+#else
+ locc $0, r2, (r4) # check for null byte
+#endif
+ beql 1f
+
+ subl3 r0, r2, r6 # Len to copy.
+ incl r6
+ tstl r3
+ beql 7f
+ movl r6,(r3)
+7: movc3 r6,(r4),(r5)
+ movl $0,r0
+cs: ret
+
+1: movc3 r2,(r4),(r5)
+ movl $ENAMETOOLONG, r0
+ ret
+
+
+_loswtch: .globl _loswtch,_rei
+ mtpr _curpcb,$PR_PCBB
+ svpctx
+ mtpr _nypcb,$PR_PCBB
+ ldpctx
+_rei: rei
+
+ .data
+
+mbanum: .long 0
+
+
+/*** DATA ********************************************************************/
+
+
+
+_pte_cmap: .long 0 ; .globl _pte_cmap /* Address of PTE
+ corresponding to cmap */
+
+_memtest: .long 0 ; .globl _memtest # Memory test in progress.
+
+#ifdef DDB
+/*
+ * DDB is the only routine that uses setjmp/longjmp.
+ */
+ .globl _setjmp, _longjmp
+_setjmp:.word 0
+ movl 4(ap), r0
+ movl 8(fp), (r0)
+ movl 12(fp), 4(r0)
+ movl 16(fp), 8(r0)
+ addl3 fp,$28,12(r0)
+ clrl r0
+ ret
+
+_longjmp:.word 0
+ movl 4(ap), r1
+ movl 8(ap), r0
+ movl (r1), ap
+ movl 4(r1), fp
+ movl 12(r1), sp
+ jmp *8(r1)
+#endif
diff --git a/sys/arch/vax/vax/swapgeneric.c b/sys/arch/vax/vax/swapgeneric.c
new file mode 100644
index 00000000000..00b5c1f1633
--- /dev/null
+++ b/sys/arch/vax/vax/swapgeneric.c
@@ -0,0 +1,212 @@
+/* $NetBSD: swapgeneric.c,v 1.5 1995/03/30 21:25:41 ragge Exp $ */
+
+/*-
+ * Copyright (c) 1982, 1986 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.
+ *
+ * @(#)swapgeneric.c 7.11 (Berkeley) 5/9/91
+ */
+
+#include "mba.h"
+#include "uda.h"
+
+
+#include "sys/param.h"
+#include "sys/conf.h"
+#include "sys/buf.h"
+#include "sys/systm.h"
+#include "sys/reboot.h"
+
+#include "machine/pte.h"
+#include "machine/mtpr.h"
+#if NMBA > 0
+#include "../mba/mbareg.h"
+#include "../mba/mbavar.h"
+#endif
+#include "../uba/ubareg.h"
+#include "../uba/ubavar.h"
+
+/*
+ * Generic configuration; all in one
+ */
+dev_t rootdev = NODEV;
+dev_t argdev = NODEV;
+dev_t dumpdev = NODEV;
+int nswap;
+struct swdevt swdevt[] = {
+ { -1, 1, 0 },
+ { -1, 1, 0 },
+ { -1, 1, 0 },
+ { 0, 0, 0 },
+};
+long dumplo;
+int dmmin, dmmax, dmtext;
+
+extern int ffs_mountroot();
+int (*mountroot)() = ffs_mountroot;
+
+extern struct mba_driver hpdriver;
+extern struct uba_driver scdriver;
+extern struct uba_driver hkdriver;
+extern struct uba_driver idcdriver;
+extern struct uba_driver hldriver;
+extern struct uba_driver udadriver;
+extern struct uba_driver kdbdriver;
+
+struct genericconf {
+ caddr_t gc_driver;
+ char *gc_name;
+ dev_t gc_root;
+} genericconf[] = {
+/* { (caddr_t)&hpdriver, "hp", makedev(0, 0), },
+ { (caddr_t)&scdriver, "up", makedev(2, 0), }, */
+#if NUDA > 0
+ { (caddr_t)&udadriver, "ra", makedev(9, 0), },
+#endif
+/* { (caddr_t)&idcdriver, "rb", makedev(11, 0), },
+ { (caddr_t)&hldriver, "rl", makedev(14, 0), },
+ { (caddr_t)&hkdriver, "hk", makedev(3, 0), },
+ { (caddr_t)&hkdriver, "rk", makedev(3, 0), },
+ { (caddr_t)&kdbdriver, "kra", makedev(16, 0), }, */
+ { 0 },
+};
+
+setconf()
+{
+#if NMBA > 0
+ register struct mba_device *mi;
+#endif
+#if NUDA > 0
+ register struct uba_device *ui;
+#endif
+ register struct genericconf *gc;
+ register char *cp, *gp;
+ int unit, swaponroot = 0;
+
+ if (rootdev != NODEV)
+ goto doswap;
+ unit = 0;
+ if (boothowto & RB_ASKNAME) {
+ char name[128];
+retry:
+ printf("root device? ");
+ gets(name);
+ for (gc = genericconf; gc->gc_driver; gc++)
+ for (cp = name, gp = gc->gc_name; *cp == *gp; cp++)
+ if (*++gp == 0)
+ goto gotit;
+ printf(
+ "use hp%%d, up%%d, ra%%d, rb%%d, rl%%d, hk%%d or kra%%d\n");
+ goto retry;
+gotit:
+ if (*++cp < '0' || *cp > '9') {
+ printf("bad/missing unit number\n");
+ goto retry;
+ }
+ while (*cp >= '0' && *cp <= '9')
+ unit = 10 * unit + *cp++ - '0';
+ if (*cp == '*')
+ swaponroot++;
+ goto found;
+ }
+ for (gc = genericconf; gc->gc_driver; gc++) {
+#if NMBA > 0
+ for (mi = mbdinit; mi->mi_driver; mi++) {
+ if (mi->mi_alive == 0)
+ continue;
+ if (mi->mi_unit == unit && mi->mi_driver ==
+ (struct mba_driver *)gc->gc_driver) {
+ printf("root on %s%d\n",
+ mi->mi_driver->md_dname, unit);
+ goto found;
+ }
+ }
+#endif
+#if NUDA > 0
+ for (ui = ubdinit; ui->ui_driver; ui++) {
+ if (ui->ui_alive == 0)
+ continue;
+ if (ui->ui_unit == unit && ui->ui_driver ==
+ (struct uba_driver *)gc->gc_driver) {
+ printf("root on %s%d\n",
+ ui->ui_driver->ud_dname, unit);
+ goto found;
+ }
+ }
+#endif
+ }
+
+ printf("no suitable root\n");
+ asm("halt");
+
+found:
+ gc->gc_root = makedev(major(gc->gc_root), unit*8);
+ rootdev = gc->gc_root;
+doswap:
+ swdevt[0].sw_dev = argdev = dumpdev =
+ makedev(major(rootdev), minor(rootdev)+1);
+ /* swap size and dumplo set during autoconfigure */
+ if (swaponroot)
+ rootdev = dumpdev;
+
+}
+
+gets(cp)
+ char *cp;
+{
+ register char *lp;
+ register c;
+
+ lp = cp;
+ for (;;) {
+ cnputc(c = (cngetc()&0x7f));
+ switch (c) {
+ case '\n':
+ case '\r':
+ *lp++ = '\0';
+ return;
+ case '\b':
+ case '#':
+ case '\177':
+ lp--;
+ if (lp < cp)
+ lp = cp;
+ continue;
+ case '@':
+ case 'u'&037:
+ lp = cp;
+ cnputc('\n');
+ continue;
+ default:
+ *lp++ = c;
+ }
+ }
+}
diff --git a/sys/arch/vax/vax/tmscpinf.h b/sys/arch/vax/vax/tmscpinf.h
new file mode 100644
index 00000000000..5d6989995d6
--- /dev/null
+++ b/sys/arch/vax/vax/tmscpinf.h
@@ -0,0 +1,321 @@
+/* $NetBSD: tmscpinf.h,v 1.1 1995/02/23 17:54:06 ragge Exp $ */
+
+/* @(#)tmscp.h 7.2 (Berkeley) 5/27/88 */
+/*
+ * @(#)tmscp.h 1.3 10/21/85
+ * Definitions for the Tape Mass Storage Control Protocol
+ */
+
+/****************************************************************
+ * *
+ * Licensed from Digital Equipment Corporation *
+ * Copyright (c) *
+ * Digital Equipment Corporation *
+ * Maynard, Massachusetts *
+ * 1985, 1986 *
+ * All rights reserved. *
+ * *
+ * The Information in this software is subject to change *
+ * without notice and should not be construed as a commitment *
+ * by Digital Equipment Corporation. Digital makes no *
+ * representations about the suitability of this software for *
+ * any purpose. It is supplied "As Is" without expressed or *
+ * implied warranty. *
+ * *
+ * If the Regents of the University of California or its *
+ * licensees modify the software in a manner creating *
+ * diriviative copyright rights, appropriate copyright *
+ * legends may be placed on the drivative work in addition *
+ * to that set forth above. *
+ * *
+ ****************************************************************
+ *
+ * Modification history: /sys/vax/tmscp.h
+ *
+ * 18-Oct-85 - afd
+ * Added: defines for tape format (density) flag values.
+ *
+ * 18-Jul-85 - afd
+ * Added: #define M_UF_WBKNV 0000100
+ * for write back (which enables cache).
+ ************************************************************************/
+
+/*
+ * Control message opcodes
+ */
+#define M_OP_ABORT 0001 /* Abort command */
+#define M_OP_GTCMD 0002 /* Get command status command */
+#define M_OP_GTUNT 0003 /* Get unit status command */
+#define M_OP_STCON 0004 /* Set controller characteristics command */
+#define M_OP_AVAIL 0010 /* Available command */
+#define M_OP_ONLIN 0011 /* Online command */
+#define M_OP_STUNT 0012 /* Set unit characteristics command */
+#define M_OP_DTACP 0013 /* Determine access paths command */
+#define M_OP_ACCES 0020 /* Access command */
+#define M_OP_CMPCD 0021 /* Compare controller data command */
+#define M_OP_ERASE 0022 /* Erase command */
+#define M_OP_FLUSH 0023 /* Flush command */
+#define M_OP_ERGAP 0026 /* Erase gap command */
+#define M_OP_COMP 0040 /* Compare host data command */
+#define M_OP_READ 0041 /* Read command */
+#define M_OP_WRITE 0042 /* Write command */
+#define M_OP_WRITM 0044 /* Write tape mark command */
+#define M_OP_REPOS 0045 /* Reposition command */
+#define M_OP_AVATN 0100 /* Available attention message */
+#define M_OP_DUPUN 0101 /* Duplicate unit number attention message */
+#define M_OP_ACPTH 0102 /* Access path attention message */
+#define M_OP_END 0200 /* End message flag */
+
+
+/*
+ * Generic command modifiers
+ */
+#define M_MD_COMP 0040000 /* Compare */
+#define M_MD_CLSEX 0020000 /* Clear serious exception */
+#define M_MD_SECOR 0001000 /* Suppress error correction */
+#define M_MD_SEREC 0000400 /* Suppress error recovery */
+#define M_MD_STWRP 0000004 /* Set write protect */
+#define M_MD_ALLCD 0000002 /* All class drivers */
+#define M_MD_NXUNT 0000001 /* Next unit */
+
+/*
+ * TMSCP command modifiers
+ */
+#define M_MD_DLEOT 0000200 /* Delete LEOT */
+#define M_MD_IMMED 0000100 /* Immediate completion */
+#define M_MD_EXCAC 0000040 /* Exclusive access */
+#define M_MD_UNLOD 0000020 /* Unload */
+#define M_MD_REVRS 0000010 /* reverse */
+#define M_MD_OBJCT 0000004 /* object count */
+#define M_MD_REWND 0000002 /* rewind */
+
+/*
+ * End message flags
+ */
+#define M_EF_ERLOG 0040 /* Error log generated */
+#define M_EF_SEREX 0020 /* Serious exception */
+#define M_EF_EOT 0010 /* End of tape encountered */
+#define M_EF_PLS 0004 /* Position lost */
+
+
+/*
+ * Controller flags
+ */
+#define M_CF_ATTN 0200 /* Enable attention messages */
+#define M_CF_MISC 0100 /* Enable miscellaneous error log messages */
+#define M_CF_OTHER 0040 /* Enable other host's error log messages */
+#define M_CF_THIS 0020 /* Enable this host's error log messages */
+
+
+/*
+ * Unit flags
+ */
+#define M_UF_WRTPH 0020000 /* Write protect (hardware) */
+#define M_UF_WRTPS 0010000 /* Write protect (software or volume) */
+#define M_UF_WBKNV 0000100 /* Write back (enables cache) */
+#define M_UF_VSMSU 0000040 /* Variable speed mode suppression */
+#define M_UF_VARSP 0000020 /* Variable speed unit */
+#define M_UF_CMPWR 0000002 /* Compare writes */
+#define M_UF_CMPRD 0000001 /* Compare reads */
+
+
+/*
+ * Status codes
+ */
+#define M_ST_MASK 037 /* Status code mask */
+#define M_ST_SUCC 000 /* Success */
+#define M_ST_ICMD 001 /* Invalid command */
+#define M_ST_ABRTD 002 /* Command aborted */
+#define M_ST_OFFLN 003 /* Unit offline */
+#define M_ST_AVLBL 004 /* Unit available */
+#define M_ST_WRTPR 006 /* Write protected */
+#define M_ST_COMP 007 /* Compare error */
+#define M_ST_DATA 010 /* Data error */
+#define M_ST_HSTBF 011 /* Host buffer access error */
+#define M_ST_CNTLR 012 /* Controller error */
+#define M_ST_DRIVE 013 /* Drive error */
+#define M_ST_FMTER 014 /* Formatter error */
+#define M_ST_BOT 015 /* BOT encountered */
+#define M_ST_TAPEM 016 /* Tape mark encountered */
+#define M_ST_RDTRN 020 /* Record data truncated */
+#define M_ST_PLOST 021 /* Position lost */
+#define M_ST_SEX 022 /* Serious exception */
+#define M_ST_LED 023 /* LEOT detected */
+#define M_ST_DIAG 037 /* Message from an internal diagnostic */
+
+/*
+ * An MSCP packet
+ */
+
+struct mscp {
+ struct mscp_header mscp_header;/* device specific header */
+ long mscp_cmdref; /* command reference number */
+ short mscp_unit; /* unit number */
+ short mscp_xxx1; /* unused */
+ u_char mscp_opcode; /* opcode */
+ u_char mscp_flags; /* end message flags */
+ short mscp_modifier; /* modifiers */
+ union {
+ struct {
+ long Mscp_bytecnt; /* byte count */
+ long Mscp_buffer; /* buffer descriptor */
+ long Mscp_mapbase; /* physical addr of map registers */
+ long Mscp_xxx2; /* unused */
+ long Mscp_lbn; /* logical block number */
+ long Mscp_xxx4; /* unused */
+ long *Mscp_dscptr; /* pointer to descriptor (software) */
+ long Mscp_sftwds[17];/* software words, padding */
+ } mscp_generic;
+ struct {
+ short Mscp_version; /* MSCP version */
+ short Mscp_cntflgs; /* controller flags */
+ short Mscp_hsttmo; /* host timeout */
+ short Mscp_usefrac; /* use fraction */
+ quad_t Mscp_time; /* time and date */
+ long Mscp_cntdep; /* controller dependent parameters */
+ } mscp_setcntchar;
+ struct {
+ short Mscp_multunt; /* multi-unit code */
+ short Mscp_unitflgs; /* unit flags */
+ long Mscp_hostid; /* host identifier */
+ quad_t Mscp_unitid; /* unit identifier */
+ long Mscp_mediaid; /* media type identifier */
+ short Mscp_format; /* format (tape density) */
+ short Mscp_speed; /* tape speed = (ips * bpi) /1000 */
+ short Mscp_fmtmenu; /* format menu */
+ short Mscp_group; /* group size */
+ short Mscp_cylinder; /* cylinder size */
+ short Mscp_xxx3; /* reserved */
+ short Mscp_rctsize; /* RCT table size */
+ char Mscp_rbns; /* RBNs / track */
+ char Mscp_rctcpys; /* RCT copies */
+ } mscp_getunitsts;
+ } mscp_un;
+ short mscp_fil1;
+ short mscp_fil2;
+ short mscp_fil3;
+};
+
+#define mscp_msglen (sizeof (struct mscp) - sizeof(struct mscp_header))
+
+/*
+ * generic packet
+ */
+
+#define mscp_bytecnt mscp_un.mscp_generic.Mscp_bytecnt
+#define mscp_buffer mscp_un.mscp_generic.Mscp_buffer
+#define mscp_mapbase mscp_un.mscp_generic.Mscp_mapbase
+#define mscp_lbn mscp_un.mscp_generic.Mscp_lbn
+#define mscp_dscptr mscp_un.mscp_generic.Mscp_dscptr
+#define mscp_sftwds mscp_un.mscp_generic.Mscp_sftwds
+#define mscp_status mscp_modifier
+
+/*
+ * Abort / Get Command Status packet
+ */
+
+#define mscp_outref mscp_bytecnt
+
+/*
+ * Set Controller Characteristics packet
+ */
+
+#define mscp_version mscp_un.mscp_setcntchar.Mscp_version
+#define mscp_cntflgs mscp_un.mscp_setcntchar.Mscp_cntflgs
+#define mscp_hsttmo mscp_un.mscp_setcntchar.Mscp_hsttmo
+#define mscp_usefrac mscp_un.mscp_setcntchar.Mscp_usefrac
+#define mscp_time mscp_un.mscp_setcntchar.Mscp_time
+#define mscp_cntdep mscp_un.mscp_setcntchar.Mscp_cntdep
+
+/*
+ * Reposition command packet fields
+ */
+
+#define mscp_reccnt mscp_bytecnt /* record/object count */
+#define mscp_tmkcnt mscp_buffer /* tape mark count */
+
+/*
+ * Get Unit Status end packet
+ */
+
+#define mscp_multunt mscp_un.mscp_getunitsts.Mscp_multunt
+#define mscp_unitflgs mscp_un.mscp_getunitsts.Mscp_unitflgs
+#define mscp_hostid mscp_un.mscp_getunitsts.Mscp_hostid
+#define mscp_unitid mscp_un.mscp_getunitsts.Mscp_unitid
+#define mscp_mediaid mscp_un.mscp_getunitsts.Mscp_mediaid
+#define mscp_format mscp_un.mscp_getunitsts.Mscp_format /* density:0=high */
+#define mscp_speed mscp_un.mscp_getunitsts.Mscp_speed /* (ips*bpi)/1000 */
+#define mscp_fmtmenu mscp_un.mscp_getunitsts.Mscp_fmtmenu
+
+/*
+ * Online / Set Unit Characteristics end packet
+ */
+
+#define mscp_maxwrt mscp_dscptr /* max write byte count */
+#define mscp_noiserec mscp_cylinder /* noise record */
+
+/*
+ * Set Controller Characteristics end packet
+ */
+
+#define mscp_cnttmo mscp_hsttmo /* controller timeout */
+#define mscp_cntcmdl mscp_usefrac /* controller soft & hardware version */
+#define mscp_cntid mscp_unitid /* controller id */
+
+
+/*
+ * Error Log message format codes
+ */
+#define M_FM_CNTERR 0 /* Controller error */
+#define M_FM_BUSADDR 1 /* Host memory access error */
+#define M_FM_TAPETRN 5 /* Tape transfer error */
+#define M_FM_STIERR 6 /* STI communication or command failure */
+#define M_FM_STIDEL 7 /* STI drive error log */
+#define M_FM_STIFEL 010 /* STI formatter error log */
+
+/*
+ * Error Log message flags
+ */
+#define M_LF_SUCC 0200 /* Operation successful */
+#define M_LF_CONT 0100 /* Operation continuing */
+#define M_LF_SQNRS 0001 /* Sequence number reset */
+
+/*
+ * Tape Format Flag Values
+ */
+#define M_TF_800 001 /* NRZI 800 bpi */
+#define M_TF_PE 002 /* Phase Encoded 1600 bpi */
+#define M_TF_GCR 004 /* Group Code Recording 6250 bpi */
+#define M_TF_BLK 010 /* Cartridge Block Mode */
+
+/*
+ * MSCP Error Log packet
+ *
+ * NOTE: MSCP packet must be padded to this size.
+ */
+
+struct mslg {
+ struct mscp_header mslg_header;/* device specific header */
+ long mslg_cmdref; /* command reference number */
+ short mslg_unit; /* unit number */
+ short mslg_seqnum; /* sequence number */
+ u_char mslg_format; /* format */
+ u_char mslg_flags; /* error log message flags */
+ short mslg_event; /* event code */
+ quad_t mslg_cntid; /* controller id */
+ u_char mslg_cntsvr; /* controller software version */
+ u_char mslg_cnthvr; /* controller hardware version */
+ short mslg_multunt; /* multi-unit code */
+ quad_t mslg_unitid; /* unit id */
+ u_char mslg_unitsvr; /* unit software version */
+ u_char mslg_unithvr; /* unit hardware version */
+ short mslg_group; /* group; retry + level */
+ long mslg_position; /* position (object count) */
+ u_char mslg_fmtsvr; /* formatter software version */
+ u_char mslg_fmthvr; /* formatter hardware version */
+ short mslg_xxx2; /* unused */
+ char mslg_stiunsucc[62]; /* STI status information */
+};
+
+#define mslg_sdecyl mslg_group
+
diff --git a/sys/arch/vax/vax/trap.c b/sys/arch/vax/vax/trap.c
new file mode 100644
index 00000000000..3db706dee09
--- /dev/null
+++ b/sys/arch/vax/vax/trap.c
@@ -0,0 +1,468 @@
+/* $NetBSD: trap.c,v 1.13 1995/07/05 08:39:48 ragge Exp $ */
+
+/*
+ * Copyright (c) 1994 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}.
+ * 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 "sys/types.h"
+#include "sys/param.h"
+#include "sys/proc.h"
+#include "sys/user.h"
+#include "sys/syscall.h"
+#include "sys/systm.h"
+#include "sys/signalvar.h"
+#include "sys/exec.h"
+#include "vm/vm.h"
+#include "vm/vm_kern.h"
+#include "vm/vm_page.h"
+#include "vax/include/mtpr.h"
+#include "vax/include/pte.h"
+#include "vax/include/pcb.h"
+#include "vax/include/trap.h"
+#include "vax/include/pmap.h"
+#include "kern/syscalls.c"
+
+
+extern int want_resched,whichqs;
+volatile int startsysc=0,ovalidstart=0,faultdebug=0,haltfault=0;
+
+
+userret(p, pc, psl)
+ struct proc *p;
+ u_int pc, psl;
+{
+ int s,sig;
+
+ while ((sig = CURSIG(p)) !=0)
+ postsig(sig);
+ p->p_priority = p->p_usrpri;
+ if (want_resched) {
+ /*
+ * Since we are curproc, clock will normally just change
+ * our priority without moving us from one queue to another
+ * (since the running process is not on a queue.)
+ * If that happened after we setrq ourselves but before we
+ * swtch()'ed, we might not be on the queue indicated by
+ * our priority.
+ */
+ s=splstatclock();
+ setrunqueue(curproc);
+ cpu_switch();
+ splx(s);
+ while ((sig = CURSIG(curproc)) != 0)
+ postsig(sig);
+ }
+
+ curpriority = curproc->p_priority;
+}
+
+char *traptypes[]={
+ "reserved addressing",
+ "privileged instruction",
+ "reserved operand",
+ "breakpoint instruction",
+ "Nothing",
+ "system call ",
+ "arithmetic trap",
+ "asynchronous system trap",
+ "page table length fault",
+ "translation violation fault",
+ "trace trap",
+ "compatibility mode fault",
+ "access violation fault",
+ "",
+ "",
+ "KSP invalid",
+ "",
+ "kernel debugger trap"
+};
+int no_traps = 18;
+
+arithflt(frame)
+ struct trapframe *frame;
+{
+ u_int sig, type=frame->trap,trapsig=1,s;
+ u_int rv, addr,*i,j;
+ struct proc *p=curproc;
+ struct pmap *pm;
+ vm_map_t map;
+ vm_prot_t ftype;
+ extern vm_map_t pte_map;
+
+ if((frame->psl & PSL_U) == PSL_U) {
+ type|=T_USER;
+ p->p_addr->u_pcb.framep = frame;
+ }
+
+ type&=~(T_WRITE|T_PTEFETCH);
+
+
+
+if(frame->trap==7) goto fram;
+if(faultdebug)printf("Trap: type %x, code %x, pc %x, psl %x\n",
+ frame->trap, frame->code, frame->pc, frame->psl);
+fram:
+ switch(type){
+
+ default:
+faulter:
+#ifdef DDB
+ if (kdb_trap(frame))
+ return;
+#endif
+ panic("trap: adr %x",frame->code);
+ case T_KSPNOTVAL:
+ goto faulter;
+
+ case T_TRANSFLT|T_USER:
+ case T_TRANSFLT: /* Translation invalid - may be simul page ref */
+ if(frame->trap&T_PTEFETCH){
+ u_int *ptep, *pte, *pte1;
+
+ if(frame->code<0x40000000)
+ ptep=(u_int *)p->p_addr->u_pcb.P0BR;
+ else
+ ptep=(u_int *)p->p_addr->u_pcb.P1BR;
+ pte1=(u_int *)trunc_page(&ptep[(frame->code
+ &0x3fffffff)>>PG_SHIFT]);
+ pte=(u_int*)&Sysmap[((u_int)pte1&0x3fffffff)>>PG_SHIFT];
+ if(*pte&PG_SREF){ /* Yes, simulated */
+ s=splhigh();
+
+ *pte|=PG_REF|PG_V;*pte&=~PG_SREF;pte++;
+ *pte|=PG_REF|PG_V;*pte&=~PG_SREF;
+ mtpr(0,PR_TBIA);
+ splx(s);
+ goto uret;
+ }
+ } else {
+ u_int *ptep, *pte;
+
+ frame->code=trunc_page(frame->code);
+ if(frame->code<0x40000000){
+ ptep=(u_int *)p->p_addr->u_pcb.P0BR;
+ pte=&ptep[(frame->code>>PG_SHIFT)];
+ } else if(frame->code>0x7fffffff){
+ pte=(u_int *)&Sysmap[((u_int)frame->code&
+ 0x3fffffff)>>PG_SHIFT];
+ } else {
+ ptep=(u_int *)p->p_addr->u_pcb.P1BR;
+ pte=&ptep[(frame->code&0x3fffffff)>>PG_SHIFT];
+ }
+ if(*pte&PG_SREF){
+ s=splhigh();
+ *pte|=PG_REF|PG_V;*pte&=~PG_SREF;pte++;
+ *pte|=PG_REF|PG_V;*pte&=~PG_SREF;
+ /* mtpr(frame->code,PR_TBIS); */
+ /* mtpr(frame->code+NBPG,PR_TBIS); */
+ mtpr(0,PR_TBIA);
+ splx(s);
+ goto uret;
+ }
+ }
+ /* Fall into... */
+ case T_ACCFLT:
+ case T_ACCFLT|T_USER:
+if(faultdebug)printf("trap accflt type %x, code %x, pc %x, psl %x\n",
+ frame->trap, frame->code, frame->pc, frame->psl);
+
+ if(!p) panic("trap: access fault without process");
+ pm=&p->p_vmspace->vm_pmap;
+ if(frame->trap&T_PTEFETCH){
+ u_int faultaddr,testaddr=(u_int)frame->code&0x3fffffff;
+ int P0=0,P1=0,SYS=0;
+
+ if(frame->code==testaddr) P0++;
+ else if(frame->code>0x7fffffff) SYS++;
+ else P1++;
+
+ if(P0){
+ faultaddr=(u_int)pm->pm_pcb->P0BR+
+ ((testaddr>>PG_SHIFT)<<2);
+ } else if(P1){
+ faultaddr=(u_int)pm->pm_pcb->P1BR+
+ ((testaddr>>PG_SHIFT)<<2);
+ } else panic("pageflt: PTE fault in SPT\n");
+
+ faultaddr&=~PAGE_MASK;
+ rv = vm_fault(pte_map, faultaddr,
+ VM_PROT_WRITE|VM_PROT_READ, FALSE);
+ if (rv != KERN_SUCCESS) {
+
+ sig=SIGSEGV;
+ goto bad;
+ } else trapsig=0;
+/* return; /* We don't know if it was a trap only for PTE*/
+/* break; */
+ }
+ addr=(frame->code& ~PAGE_MASK);
+ if((frame->pc>(unsigned)0x80000000)&&
+ (frame->code>(unsigned)0x80000000)){
+ map=kernel_map;
+ } else {
+ map= &p->p_vmspace->vm_map;
+ }
+ if(frame->trap&T_WRITE) ftype=VM_PROT_WRITE|VM_PROT_READ;
+ else ftype = VM_PROT_READ;
+
+ rv = vm_fault(map, addr, ftype, FALSE);
+ if (rv != KERN_SUCCESS) {
+ if(frame->pc>(u_int)0x80000000){
+ if(p->p_addr->u_pcb.iftrap){
+ frame->pc=(int)p->p_addr->u_pcb.iftrap;
+ return;
+ }
+ printf("Segv in kernel mode: rv %d\n",rv);
+ goto faulter;
+ }
+ sig=SIGSEGV;
+ } else trapsig=0;
+ break;
+
+ case T_PTELEN:
+ case T_PTELEN|T_USER: /* Page table length exceeded */
+ pm=&p->p_vmspace->vm_pmap;
+if(faultdebug)printf("trap ptelen type %x, code %x, pc %x, psl %x\n",
+ frame->trap, frame->code, frame->pc, frame->psl);
+ if(frame->code<0x40000000){ /* P0 */
+ int i;
+
+ if (p->p_vmspace == 0){
+ printf("no vmspace in fault\n");
+ goto faulter;
+ }
+ i = p->p_vmspace->vm_tsize + p->p_vmspace->vm_dsize;
+ if (i > (frame->code >> PAGE_SHIFT)){
+ pmap_expandp0(pm, i << 1);
+ trapsig = 0;
+ } else {
+ sig = SIGSEGV;
+ }
+ } else if (frame->code > 0x7fffffff){ /* System, segv */
+ sig = SIGSEGV;
+ } else { /* P1 */
+ int i;
+
+ i = (u_int)(p->p_vmspace->vm_maxsaddr);
+ if (frame->code < i){
+ sig = SIGSEGV;
+ } else {
+ pmap_expandp1(pm);
+ trapsig = 0;
+ }
+ }
+ break;
+
+ case T_BPTFLT|T_USER:
+ case T_TRCTRAP|T_USER:
+ sig = SIGTRAP;
+ frame->psl &= ~PSL_T;
+ break;
+
+ case T_PRIVINFLT|T_USER:
+ case T_RESADFLT|T_USER:
+ case T_RESOPFLT|T_USER:
+ sig=SIGILL;
+ break;
+
+ case T_ARITHFLT|T_USER:
+ sig=SIGFPE;
+ break;
+
+ case T_ASTFLT|T_USER:
+ mtpr(AST_NO,PR_ASTLVL);
+ trapsig=0;
+ break;
+ }
+bad:
+ if(trapsig) trapsignal(curproc, sig, frame->code);
+uret:
+ userret(curproc, frame->pc, frame->psl);
+};
+
+showstate(p)
+ struct proc *p;
+{
+if(p){
+ printf("\npid %d, command %s\n",p->p_pid, p->p_comm);
+ printf("text size %x, data size %x, stack size %x\n",
+ p->p_vmspace->vm_tsize, p->p_vmspace->vm_dsize,p->p_vmspace->
+ vm_ssize);
+ printf("virt text %x, virt data %x, max stack %x\n",
+ p->p_vmspace->vm_taddr,p->p_vmspace->vm_daddr,
+ p->p_vmspace->vm_maxsaddr);
+ printf("kernel uarea %x, end uarea %x\n",p->p_addr,
+ (u_int)p->p_addr + USPACE);
+} else {
+ printf("No process\n");
+}
+ printf("kernel stack: %x, interrupt stack %x\n",
+ mfpr(PR_KSP),mfpr(PR_ISP));
+ printf("P0BR %x, P0LR %x, P1BR %x, P1LR %x\n",
+ mfpr(PR_P0BR),mfpr(PR_P0LR),mfpr(PR_P1BR),mfpr(PR_P1LR));
+}
+
+void
+setregs(p, pack, stack, retval)
+ struct proc *p;
+ struct exec_package *pack;
+ u_long stack;
+ register_t retval[2];
+{
+ struct trapframe *exptr;
+
+ exptr = p->p_addr->u_pcb.framep;
+ exptr->pc = pack->ep_entry + 2;
+ mtpr(stack, PR_USP);
+ retval[0] = retval[1] = 0;
+}
+
+syscall(frame)
+ struct trapframe *frame;
+{
+ struct sysent *callp;
+ int nsys;
+ int err,rval[2],args[8],sig;
+ struct trapframe *exptr;
+ struct proc *p=curproc;
+
+if(startsysc)printf("trap syscall %s pc %x, psl %x, ap %x, pid %d, frame %x\n",
+ syscallnames[frame->code], frame->pc, frame->psl,frame->ap,
+ curproc->p_pid,frame);
+
+ p->p_addr->u_pcb.framep = frame;
+ callp = p->p_emul->e_sysent;
+ nsys = p->p_emul->e_nsysent;
+
+ if(frame->code == SYS___syscall){
+ int g = *(int *)(frame->ap);
+
+ frame->code=*(int *)(frame->ap+4);
+ frame->ap+=8;
+ *(int *)(frame->ap)=g-2;
+ }
+
+ if(frame->code<0||frame->code>=nsys)
+ callp += p->p_emul->e_nosys;
+ else
+ callp += frame->code;
+
+ rval[0]=0;
+ rval[1]=frame->r1;
+ if(callp->sy_narg)
+ copyin((char*)frame->ap+4, args, callp->sy_argsize);
+
+ err=(*callp->sy_call)(curproc,args,rval);
+ exptr=curproc->p_addr->u_pcb.framep;
+
+if(startsysc)
+ printf("retur %s pc %x, psl %x, ap %x, pid %d, v{rde %d r0 %d, r1 %d, frame %x\n",
+ syscallnames[exptr->code], exptr->pc, exptr->psl,exptr->ap,
+ curproc->p_pid,err,rval[0],rval[1],exptr);
+
+ switch(err){
+ case 0:
+ exptr->r1=rval[1];
+ exptr->r0=rval[0];
+ exptr->psl &= ~PSL_C;
+ break;
+ case EJUSTRETURN:
+ return;
+ case ERESTART:
+ exptr->pc=exptr->pc-2;
+ break;
+ default:
+ exptr->r0=err;
+ exptr->psl |= PSL_C;
+ break;
+ }
+ userret(curproc, exptr->pc, exptr->psl);
+}
+
+stray(scb, vec){
+ printf("stray interrupt scb %d, vec 0x%x\n", scb, vec);
+}
+
+struct inta {
+ char pushr[2]; /* pushr $3f */
+ char pushl[2]; /* pushl $? */
+ char nop; /* nop, for foolish gcc */
+ char calls[3]; /* $1,? */
+ u_int hoppaddr; /* jump for calls */
+ char popr[2]; /* popr $0x3f */
+ char rei; /* rei */
+} intasm = {0xbb, 0x3f, 0xdd, 0, 1, 0xfb, 1, 0xef, 0, 0xba, 0x3f, 2};
+
+u_int
+settrap(plats, nyrut,arg)
+ u_int plats; /* Pointer to place to copy interrupt routine */
+ u_int nyrut; /* Pointer to new routine to jump to */
+ u_int arg; /* arg number to pass to routine. */
+{
+ struct inta *introut;
+
+ introut=(void *)((plats&0xfffffffc)+4);
+ bcopy(&intasm, introut, sizeof(struct inta));
+ introut->pushl[1]=arg;
+ introut->hoppaddr=nyrut-(u_int)&introut->popr[0];
+ return (u_int)introut;
+}
+
+printstack(loaddr, highaddr)
+ u_int *loaddr, *highaddr;
+{
+ u_int *tmp;
+
+ (u_int)tmp = 0xfffffffc & (u_int)loaddr; /* Easy align */
+
+ for (;tmp < highaddr;tmp += 4)
+ printf("%8x: %8x %8x %8x %8x\n",
+ tmp, *tmp, *(tmp + 1), *(tmp + 2), *(tmp + 3));
+}
+
+showregs(frame)
+ struct trapframe *frame;
+{
+ printf("P0BR %8x P1BR %8x P0LR %8x P1LR %8x\n",
+ mfpr(PR_P0BR), mfpr(PR_P1BR), mfpr(PR_P0LR), mfpr(PR_P1LR));
+ printf("KSP %8x ISP %8x USP %8x\n",
+ mfpr(PR_KSP), mfpr(PR_ISP), mfpr(PR_USP));
+ printf("R0 %8x R1 %8x R2 %8x R3 %8x\n",
+ frame->r0, frame->r1, frame->r2, frame->r3);
+ printf("R4 %8x R5 %8x R6 %8x R7 %8x\n",
+ frame->r4, frame->r5, frame->r6, frame->r7);
+ printf("R8 %8x R9 %8x R10 %8x R11 %8x\n",
+ frame->r8, frame->r9, frame->r10, frame->r11);
+ printf("FP %8x AP %8x PC %8x PSL %8x\n",
+ frame->fp, frame->ap, frame->pc, frame->psl);
+}
diff --git a/sys/arch/vax/vax/udiv.s b/sys/arch/vax/vax/udiv.s
new file mode 100644
index 00000000000..99fb0fcab21
--- /dev/null
+++ b/sys/arch/vax/vax/udiv.s
@@ -0,0 +1,71 @@
+/* $NetBSD: udiv.s,v 1.2 1994/10/26 08:03:34 cgd Exp $ */
+
+/*-
+ * Copyright (c) 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Donn Seeley at UUNET Technologies, Inc.
+ *
+ * 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.
+ *
+ * @(#)udiv.s 5.6 (Berkeley) 4/15/91
+ */
+
+/*
+ * Unsigned division, PCC flavor.
+ * udiv() takes an ordinary dividend/divisor pair;
+ * audiv() takes a pointer to a dividend and an ordinary divisor.
+ */
+
+
+#define DIVIDEND 4(ap)
+#define DIVISOR 8(ap)
+
+ .globl udiv
+ .align 2
+udiv: .word 0x0
+ movl DIVISOR,r2
+ jlss Leasy # big divisor: settle by comparison
+ movl DIVIDEND,r0
+ jlss Lhard # big dividend: extended division
+ divl2 r2,r0 # small divisor and dividend: signed division
+ ret
+Lhard:
+ clrl r1
+ ediv r2,r0,r0,r1
+ ret
+Leasy:
+ cmpl DIVIDEND,r2
+ jgequ Lone # if dividend is as big or bigger, return 1
+ clrl r0 # else return 0
+ ret
+Lone:
+ movl $1,r0
+ ret
diff --git a/sys/arch/vax/vax/urem.s b/sys/arch/vax/vax/urem.s
new file mode 100644
index 00000000000..c0f0857df02
--- /dev/null
+++ b/sys/arch/vax/vax/urem.s
@@ -0,0 +1,69 @@
+/* $NetBSD: urem.s,v 1.2 1994/10/26 08:03:37 cgd Exp $ */
+
+/*-
+ * Copyright (c) 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Donn Seeley at UUNET Technologies, Inc.
+ *
+ * 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.
+ *
+ * @(#)urem.s 5.6 (Berkeley) 4/15/91
+ */
+
+/*
+ * Unsigned modulus, PCC flavor.
+ * urem() takes an ordinary dividend/divisor pair;
+ */
+
+#define DIVIDEND 4(ap)
+#define DIVISOR 8(ap)
+ .globl urem
+ .align 2
+urem: .word 0x0
+
+ movl 8(ap),r2
+ jlss Leasy # big divisor: settle by comparison
+ movl 4(ap),r0
+ jlss Lhard # big dividend: need extended division
+ divl3 r2,r0,r1 # small divisor and dividend: signed modulus
+ mull2 r2,r1
+ subl2 r1,r0
+ ret
+Lhard:
+ clrl r1
+ ediv r2,r0,r1,r0
+ ret
+Leasy:
+ subl3 r2,DIVIDEND,r0
+ jcc Ldifference # if divisor goes in once, return difference
+ movl DIVIDEND,r0 # if divisor is bigger, return dividend
+Ldifference:
+ ret
diff --git a/sys/arch/vax/vax/uvaxII.c b/sys/arch/vax/vax/uvaxII.c
new file mode 100644
index 00000000000..3b617d2dc36
--- /dev/null
+++ b/sys/arch/vax/vax/uvaxII.c
@@ -0,0 +1,262 @@
+/* $NetBSD: uvaxII.c,v 1.2 1995/04/18 22:08:25 ragge Exp $ */
+
+/*-
+ * Copyright (c) 1988 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.
+ *
+ * @(#)ka630.c 7.8 (Berkeley) 5/9/91
+ */
+
+/* All bugs are subject to removal without further notice */
+
+#if VAX630 || VAX410
+
+#include "sys/param.h"
+#include "sys/types.h"
+#include "sys/device.h"
+#include "machine/uvaxII.h"
+#include "machine/nexus.h"
+#include "machine/pte.h"
+#include "machine/mtpr.h"
+#include "machine/sid.h"
+#include "vax/uba/ubavar.h"
+#include "vax/uba/ubareg.h"
+
+#include "mba.h"
+#include "uba.h"
+
+#include "vm/vm.h"
+#include "vm/vm_kern.h"
+#include "vax/include/pmap.h"
+
+struct nexus *nexus;
+struct uvaxIIcpu *uvaxIIcpu_ptr;
+#if VAX630
+struct ka630clock *ka630clk_ptr;
+u_long ka630_clkread();
+void ka630_clkwrite();
+#endif
+extern int cpu_type, nmba, numuba;
+
+int
+uvaxII_conf()
+{
+ extern char cpu_model[];
+
+ switch (cpu_type) {
+ case VAX_630:
+ strcpy(cpu_model,"MicroVAXII");
+ break;
+ case VAX_410:
+ strcpy(cpu_model,"MicroVAX 2000");
+ break;
+ };
+ config_rootfound("backplane",(void*)75);
+}
+
+int
+conf_uvaxII(){
+
+ printf(": UvaxII CPU (78032/78132)\n");
+}
+
+uvaxII_clock(){
+
+ mtpr(0x40,PR_ICCS); /* Start clock and enable interrupt */
+ return 1;
+}
+
+/* log crd errors */
+uvaxII_memerr()
+{
+ printf("memory err!\n");
+}
+
+#define NMC78032 10
+char *mc78032[] = {
+ 0, "immcr (fsd)", "immcr (ssd)", "fpu err 0",
+ "fpu err 7", "mmu st(tb)", "mmu st(m=0)", "pte in p0",
+ "pte in p1", "un intr id",
+};
+
+struct mc78032frame {
+ int mc63_bcnt; /* byte count == 0xc */
+ int mc63_summary; /* summary parameter */
+ int mc63_mrvaddr; /* most recent vad */
+ int mc63_istate; /* internal state */
+ int mc63_pc; /* trapped pc */
+ int mc63_psl; /* trapped psl */
+};
+
+uvaxII_mchk(cmcf)
+ caddr_t cmcf;
+{
+ register struct mc78032frame *mcf = (struct mc78032frame *)cmcf;
+ register u_int type = mcf->mc63_summary;
+
+ printf("machine check %x", type);
+ if (type < NMC78032 && mc78032[type])
+ printf(": %s", mc78032[type]);
+ printf("\n\tvap %x istate %x pc %x psl %x\n",
+ mcf->mc63_mrvaddr, mcf->mc63_istate,
+ mcf->mc63_pc, mcf->mc63_psl);
+ if (uvaxIIcpu_ptr && uvaxIIcpu_ptr->uvaxII_mser & UVAXIIMSER_MERR) {
+ printf("\tmser=0x%x ", uvaxIIcpu_ptr->uvaxII_mser);
+ if (uvaxIIcpu_ptr->uvaxII_mser & UVAXIIMSER_CPUE)
+ printf("page=%d", uvaxIIcpu_ptr->uvaxII_cear);
+ if (uvaxIIcpu_ptr->uvaxII_mser & UVAXIIMSER_DQPE)
+ printf("page=%d", uvaxIIcpu_ptr->uvaxII_dear);
+ printf("\n");
+ }
+ return (-1);
+}
+
+/*
+ * Handle the watch chip used by the ka630 and ka410 mother boards.
+ */
+u_long
+uvaxII_gettodr(stopped_flag)
+ int *stopped_flag;
+{
+ register u_long year_secs;
+
+ switch (cpu_type) {
+#if VAX630
+ case VAX_630:
+ year_secs = ka630_clkread(stopped_flag);
+ break;
+#endif
+ default:
+ year_secs = 0;
+ *stopped_flag = 1;
+ };
+ return (year_secs * 100);
+}
+
+void
+uvaxII_settodr(year_ticks)
+ u_long year_ticks;
+{
+ register u_long year_secs;
+
+ year_secs = year_ticks / 100;
+ switch (cpu_type) {
+#if VAX630
+ case VAX_630:
+ ka630_clkwrite(year_secs);
+ break;
+#endif
+ };
+}
+
+#if VAX630
+static short dayyr[12] = { 0,31,59,90,120,151,181,212,243,273,304,334 };
+/* init system time from tod clock */
+/* ARGSUSED */
+u_long
+ka630_clkread(stopped_flag)
+ int *stopped_flag;
+{
+ register struct ka630clock *claddr = ka630clk_ptr;
+ register int days, yr;
+ register u_long year_secs;
+
+ *stopped_flag = 0;
+ claddr->csr1 = KA630CLK_SET;
+ while ((claddr->csr0 & KA630CLK_UIP) != 0)
+ ;
+ /* If the clock is valid, use it. */
+ if ((claddr->csr3 & KA630CLK_VRT) != 0 &&
+ (claddr->csr1 & KA630CLK_ENABLE) == KA630CLK_ENABLE) {
+ /* simple sanity checks */
+ if (claddr->mon < 1 || claddr->mon > 12 ||
+ claddr->day < 1 || claddr->day > 31) {
+ printf("WARNING: preposterous clock chip time.\n");
+ year_secs = 0;
+ } else {
+ days = dayyr[claddr->mon - 1] + claddr->day - 1;
+ year_secs = days * DAYSEC + claddr->hr * HRSEC +
+ claddr->min * MINSEC + claddr->sec;
+ }
+ claddr->yr = 70; /* any non-leap year */
+#ifndef lint
+ { volatile int t = claddr->csr2; } /* ??? */
+#endif
+ claddr->csr0 = KA630CLK_RATE;
+ claddr->csr1 = KA630CLK_ENABLE;
+
+ return (year_secs);
+ }
+ printf("WARNING: TOY clock invalid.\n");
+ return (0);
+}
+
+/* Set the time of day clock, called via. stime system call.. */
+void
+ka630_clkwrite(year_secs)
+ u_long year_secs;
+{
+ register struct ka630clock *claddr = ka630clk_ptr;
+ register int t, t2;
+ int s;
+
+ s = splhigh();
+ claddr->csr1 = KA630CLK_SET;
+ while ((claddr->csr0 & KA630CLK_UIP) != 0)
+ ;
+ claddr->yr = 70; /* any non-leap year is ok */
+
+ /* t = month + day; separate */
+ t = year_secs % YEARSEC;
+ for (t2 = 1; t2 < 12; t2++)
+ if (t < dayyr[t2])
+ break;
+
+ /* t2 is month */
+ claddr->mon = t2;
+ claddr->day = t - dayyr[t2 - 1] + 1;
+
+ /* the rest is easy */
+ t = year_secs % DAYSEC;
+ claddr->hr = t / HRSEC;
+ t %= HRSEC;
+ claddr->min = t / MINSEC;
+ claddr->sec = t % MINSEC;
+#ifndef lint
+ { int t = claddr->csr2; } /* ??? */
+ { int t = claddr->csr3; } /* ??? */
+#endif
+ claddr->csr0 = KA630CLK_RATE;
+ claddr->csr1 = KA630CLK_ENABLE;
+ splx(s);
+}
+#endif
+#endif
diff --git a/sys/arch/vax/vax/vm_machdep.c b/sys/arch/vax/vax/vm_machdep.c
new file mode 100644
index 00000000000..a33f58daa38
--- /dev/null
+++ b/sys/arch/vax/vax/vm_machdep.c
@@ -0,0 +1,521 @@
+/* $NetBSD: vm_machdep.c,v 1.16.2.1 1995/10/15 14:01:06 ragge Exp $ */
+
+#undef SWDEBUG
+/*
+ * Copyright (c) 1994 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}.
+ * 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 "sys/types.h"
+#include "sys/param.h"
+#include "sys/proc.h"
+#include "sys/user.h"
+#include "sys/exec.h"
+#include "sys/vnode.h"
+#include "sys/core.h"
+#include "sys/mount.h"
+#include "vm/vm.h"
+#include "vm/vm_kern.h"
+#include "vm/vm_page.h"
+#include "machine/vmparam.h"
+#include "machine/mtpr.h"
+#include "machine/pmap.h"
+#include "machine/pte.h"
+#include "machine/macros.h"
+#include "machine/trap.h"
+#include "machine/pcb.h"
+
+#include <sys/syscallargs.h>
+
+volatile int whichqs;
+
+/*
+ * pagemove - moves pages at virtual address from to virtual address to,
+ * block moved of size size. Using fast insn bcopy for pte move.
+ */
+void
+pagemove(from, to, size)
+ caddr_t from, to;
+ int size;
+{
+ u_int *fpte, *tpte,stor;
+
+ fpte = kvtopte(from);
+ tpte = kvtopte(to);
+
+ stor = (size/NBPG) * sizeof(struct pte);
+ bcopy(fpte,tpte,stor);
+ bzero(fpte,stor);
+ mtpr(0,PR_TBIA);
+}
+
+#define VIRT2PHYS(x) \
+ (((*(int *)((((((int)x)&0x7fffffff)>>9)*4)+ \
+ (unsigned int)Sysmap))&0x1fffff)<<9)
+
+/*
+ * cpu_fork() copies parent process trapframe directly into child PCB
+ * so that when we swtch() to the child process it will go directly
+ * back to user mode without any need to jump back through kernel.
+ * We also take away mapping for the second page after pcb, so that
+ * we get something like a "red zone".
+ * No need for either double-map kernel stack or relocate it when
+ * forking.
+ */
+int
+cpu_fork(p1, p2)
+ struct proc *p1, *p2;
+{
+ struct pcb *nyproc;
+ struct trapframe *tf;
+ struct pmap *pmap, *opmap;
+ u_int *p2pte;
+ extern vm_map_t pte_map;
+
+ nyproc = &p2->p_addr->u_pcb;
+ tf = p1->p_addr->u_pcb.framep;
+ opmap = &p1->p_vmspace->vm_pmap;
+ pmap = &p2->p_vmspace->vm_pmap;
+ pmap->pm_pcb = nyproc;
+
+#ifdef notyet
+ /* Mark page invalid */
+ p2pte = kvtopte((u_int *)p2->p_addr + 2 * NBPG);
+ *p2pte = 0;
+#endif
+
+#ifdef notyet
+ /* Set up internal defs in PCB, and alloc PTEs. */
+ nyproc->P0BR = kmem_alloc_wait(pte_map,
+ (opmap->pm_pcb->P0LR & ~AST_MASK) * 4);
+ nyproc->P1BR = kmem_alloc_wait(pte_map,
+ (0x800000 - (pmap->pm_pcb->P1LR * 4))) - 0x800000;
+ nyproc->P0LR = opmap->pm_pcb->P0LR;
+ nyproc->P1LR = opmap->pm_pcb->P1LR;
+#else
+ nyproc->P0BR = (void *)0;
+ nyproc->P1BR = (void *)0x80000000;
+ nyproc->P0LR = AST_PCB;
+ nyproc->P1LR = 0x200000;
+#endif
+ nyproc->USP = mfpr(PR_USP);
+ nyproc->iftrap = NULL;
+ nyproc->KSP = (u_int)p2->p_addr + USPACE;
+
+ /* General registers as taken from userspace */
+ /* trapframe should be synced with pcb */
+ bcopy(&tf->r2,&nyproc->R[2],10*sizeof(int));
+ nyproc->AP = tf->ap;
+ nyproc->FP = tf->fp;
+ nyproc->PC = tf->pc;
+ nyproc->PSL = tf->psl & ~PSL_C;
+ nyproc->R[0] = p1->p_pid; /* parent pid. (shouldn't be needed) */
+ nyproc->R[1] = 1;
+
+ return 0; /* Child is ready. Parent, return! */
+
+}
+
+/*
+ * cpu_set_kpc() sets up pcb for the new kernel process so that it will
+ * start at the procedure pointed to by pc next time swtch() is called.
+ * When that procedure returns, it will pop off everything from the
+ * faked calls frame on the kernel stack, do an REI and go down to
+ * user mode.
+ */
+void
+cpu_set_kpc(p, pc)
+ struct proc *p;
+ u_int pc;
+{
+ struct pcb *nyproc;
+ struct {
+ u_int chand;
+ u_int mask;
+ u_int ap;
+ u_int fp;
+ u_int pc;
+ u_int nargs;
+ u_int pp;
+ u_int rpc;
+ u_int rpsl;
+ } *kc;
+ extern int rei;
+
+ kc = (void *)p->p_addr + USPACE - sizeof(*kc);
+ kc->chand = 0;
+ kc->mask = 0x20000000;
+ kc->pc = (u_int)&rei;
+ kc->nargs = 1;
+ kc->pp = (u_int)p;
+ kc->rpsl = 0x3c00000;
+
+ nyproc = &p->p_addr->u_pcb;
+ nyproc->framep = (void *)p->p_addr + USPACE - sizeof(struct trapframe);
+ nyproc->AP = (u_int)&kc->nargs;
+ nyproc->FP = nyproc->KSP = (u_int)kc;
+ nyproc->PC = pc + 2;
+}
+
+void
+setrunqueue(p)
+ struct proc *p;
+{
+ struct prochd *q;
+ int knummer;
+
+ if(p->p_back)
+ panic("sket sig i setrunqueue\n");
+ knummer=(p->p_priority>>2);
+ bitset(knummer,whichqs);
+ q=&qs[knummer];
+
+ _insque(p,q);
+
+ return;
+}
+
+void
+remrq(p)
+ struct proc *p;
+{
+ struct proc *qp;
+ int bitnr;
+
+ bitnr=(p->p_priority>>2);
+ if(bitisclear(bitnr,whichqs))
+ panic("remrq: Process not in queue\n");
+
+ _remque(p);
+
+ qp=(struct proc *)&qs[bitnr];
+ if(qp->p_forw==qp)
+ bitclear(bitnr,whichqs);
+}
+
+volatile caddr_t curpcb,nypcb;
+
+cpu_switch(){
+ int i,j,s;
+ struct proc *p;
+ volatile struct proc *q;
+ extern unsigned int want_resched,scratch;
+
+hej:
+ /* F|rst: Hitta en k|. */
+ s=splhigh();
+ if((i=ffs(whichqs)-1)<0) goto idle;
+
+found:
+ asm(".data;savpsl: .long 0;.text;movpsl savpsl");
+ q=(struct proc *)&qs[i];
+ if(q->p_forw==q)
+ panic("swtch: no process queued");
+
+ bitclear(i,whichqs);
+ p=q->p_forw;
+ _remque(p);
+
+ if(q->p_forw!=q) bitset(i,whichqs);
+ if(curproc) (u_int)curpcb=VIRT2PHYS(&curproc->p_addr->u_pcb);
+ else (u_int)curpcb=scratch;
+ (u_int)nypcb=VIRT2PHYS(&p->p_addr->u_pcb);
+
+ if(!p) panic("switch: null proc pointer\n");
+ want_resched=0;
+ curproc=p;
+ if(curpcb==nypcb) return;
+
+ asm("pushl savpsl");
+ asm("jsb _loswtch");
+
+ return; /* New process! */
+
+idle:
+ spl0();
+ while(!whichqs);
+ goto hej;
+}
+
+/* Should check that values is in bounds XXX */
+copyinstr(from, to, maxlen, lencopied)
+void *from, *to;
+u_int *lencopied,maxlen;
+{
+ u_int i;
+ void *addr=&curproc->p_addr->u_pcb.iftrap;
+ char *gfrom=from, *gto=to;
+
+ asm("movl $Lstr,(%0)":: "r"(addr));
+ for(i=0;i<maxlen;i++){
+ *(gto+i)=*(gfrom+i);
+ if(!(*(gto+i))) goto ok;
+ }
+
+ return(ENAMETOOLONG);
+ok:
+ if(lencopied) *lencopied=i+1;
+ return(0);
+}
+
+asm("Lstr: ret");
+
+/* Should check that values is in bounds XXX */
+copyoutstr(from, to, maxlen, lencopied)
+void *from, *to;
+u_int *lencopied,maxlen;
+{
+ u_int i;
+ char *gfrom=from, *gto=to;
+ void *addr=&curproc->p_addr->u_pcb.iftrap;
+
+ asm("movl $Lstr,(%0)":: "r"(addr));
+ for(i=0;i<maxlen;i++){
+ *(gto+i)=*(gfrom+i);
+ if(!(*(gto+i))) goto ok;
+ }
+
+ return(ENAMETOOLONG);
+ok:
+ if(lencopied) *lencopied=i+1;
+ return 0;
+}
+
+cpu_exec_aout_makecmds(p, epp)
+ struct proc *p;
+ struct exec_package *epp;
+{
+ int error;
+ struct exec *ep;
+/*
+ * Compatibility with reno programs.
+ */
+ ep=epp->ep_hdr;
+ switch (ep->a_midmag) {
+ case 0x10b: /* ZMAGIC in 4.3BSD Reno programs */
+ error = reno_zmagic(p, epp);
+ break;
+ case 0x108:
+printf("Warning: reno_nmagic\n");
+ error = exec_aout_prep_nmagic(p, epp);
+ break;
+ case 0x107:
+printf("Warning: reno_omagic\n");
+ error = exec_aout_prep_omagic(p, epp);
+ break;
+ default:
+ error = ENOEXEC;
+ }
+ return(error);
+}
+
+int
+sys_sysarch(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+
+ return (ENOSYS);
+};
+
+#ifdef COMPAT_ULTRIX
+extern struct emul emul_ultrix;
+#endif
+/*
+ * 4.3BSD Reno programs have an 1K header first in the executable
+ * file, containing a.out header. Otherwise programs are identical.
+ *
+ * from: exec_aout.c,v 1.9 1994/01/28 23:46:59 jtc Exp $
+ */
+
+int
+reno_zmagic(p, epp)
+ struct proc *p;
+ struct exec_package *epp;
+{
+ struct exec *execp = epp->ep_hdr;
+
+ epp->ep_taddr = 0;
+ epp->ep_tsize = execp->a_text;
+ epp->ep_daddr = epp->ep_taddr + execp->a_text;
+ epp->ep_dsize = execp->a_data + execp->a_bss;
+ epp->ep_entry = execp->a_entry;
+
+#ifdef COMPAT_ULTRIX
+ epp->ep_emul = &emul_ultrix;
+#endif
+
+ /*
+ * check if vnode is in open for writing, because we want to
+ * demand-page out of it. if it is, don't do it, for various
+ * reasons
+ */
+ if ((execp->a_text != 0 || execp->a_data != 0) &&
+ epp->ep_vp->v_writecount != 0) {
+ return ETXTBSY;
+ }
+ epp->ep_vp->v_flag |= VTEXT;
+
+ /* set up command for text segment */
+ NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_pagedvn, execp->a_text,
+ epp->ep_taddr, epp->ep_vp, 0x400, VM_PROT_READ|VM_PROT_EXECUTE);
+
+ /* set up command for data segment */
+ NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_pagedvn, execp->a_data,
+ epp->ep_daddr, epp->ep_vp, execp->a_text+0x400,
+ VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
+
+ /* set up command for bss segment */
+ NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, execp->a_bss,
+ epp->ep_daddr + execp->a_data, NULLVP, 0,
+ VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
+
+ return exec_aout_setup_stack(p, epp);
+}
+
+void
+cpu_exit(p)
+ struct proc *p;
+{
+ extern unsigned int scratch;
+
+ if(!p) panic("cpu_exit from null process");
+ vmspace_free(p->p_vmspace);
+
+ (void) splimp();
+ mtpr(scratch+NBPG,PR_KSP);/* Must change kernel stack before freeing */
+ kmem_free(kernel_map, (vm_offset_t)p->p_addr, ctob(UPAGES));
+ cpu_switch();
+ /* NOTREACHED */
+}
+
+suword(ptr,val)
+ void *ptr;
+ int val;
+{
+ void *addr=&curproc->p_addr->u_pcb.iftrap;
+
+ asm("movl $Lstr,(%0)":: "r"(addr));
+ *(int *)ptr=val;
+ return 0;
+}
+
+/*
+ * Dump the machine specific header information at the start of a core dump.
+ * First put all regs in PCB for debugging purposes. This is not an good
+ * way to do this, but good for my purposes so far.
+ */
+int
+cpu_coredump(p, vp, cred, chdr)
+ struct proc *p;
+ struct vnode *vp;
+ struct ucred *cred;
+ struct core *chdr;
+{
+ struct trapframe *tf;
+ struct md_coredump state;
+ struct coreseg cseg;
+ int error;
+
+ tf = p->p_addr->u_pcb.framep;
+ CORE_SETMAGIC(*chdr, COREMAGIC, MID_VAX, 0);
+ chdr->c_hdrsize = sizeof(struct core);
+ chdr->c_seghdrsize = sizeof(struct coreseg);
+ chdr->c_cpusize = sizeof(struct md_coredump);
+
+ bcopy(tf, &state, sizeof(struct md_coredump));
+ state.md_tf.code = mfpr(PR_USP); /* XXX */
+
+ CORE_SETMAGIC(cseg, CORESEGMAGIC, MID_VAX, CORE_CPU);
+ cseg.c_addr = 0;
+ cseg.c_size = chdr->c_cpusize;
+
+ error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&cseg, chdr->c_seghdrsize,
+ (off_t)chdr->c_hdrsize, UIO_SYSSPACE,
+ IO_NODELOCKED|IO_UNIT, cred, (int *)NULL, p);
+ if (error)
+ return error;
+
+ error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&state, sizeof(state),
+ (off_t)(chdr->c_hdrsize + chdr->c_seghdrsize), UIO_SYSSPACE,
+ IO_NODELOCKED|IO_UNIT, cred, (int *)NULL, p);
+
+ if (!error)
+ chdr->c_nseg++;
+
+ return error;
+}
+
+copyout(from, to, len)
+ void *from, *to;
+{
+ void *addr=&curproc->p_addr->u_pcb.iftrap;
+
+ return locopyout(from, to, len, addr);
+}
+
+copyin(from, to, len)
+ void *from, *to;
+{
+ void *addr=&curproc->p_addr->u_pcb.iftrap;
+
+ return locopyin(from, to, len, addr);
+}
+
+/*
+ * cpu_swapin() is called just before a process shall be swapped in.
+ * Kernel stack and pcb must be mapped when we swtch() to this new
+ * process, to guarantee that we frob all pages here to ensure that
+ * they actually are in-core. Kernel stack red zone is also updated
+ * here.
+ */
+void
+cpu_swapin(p)
+ struct proc *p;
+{
+ u_int uarea, i, *j, rv;
+
+ uarea = (u_int)p->p_addr;
+
+ for(i = uarea;i < uarea + USPACE;i += PAGE_SIZE) {
+ j = (u_int *)kvtopte(i);
+ if ((*j & PG_V) == 0) {
+ rv = vm_fault(kernel_map, i,
+ VM_PROT_WRITE|VM_PROT_READ, FALSE);
+ if (rv != KERN_SUCCESS)
+ panic("cpu_swapin: rv %d",rv);
+ }
+ }
+#ifdef notyet
+ j = (u_int *)kvtopte(uarea + 2 * NBPG);
+ *j = 0; /* Set kernel stack red zone */
+#endif
+}