summaryrefslogtreecommitdiff
path: root/sys/arch/mvmeppc/stand
diff options
context:
space:
mode:
authorSteve Murphree <smurph@cvs.openbsd.org>2001-06-26 21:58:11 +0000
committerSteve Murphree <smurph@cvs.openbsd.org>2001-06-26 21:58:11 +0000
commit416f561c78b0eca90fdb484e72a96080b0825dca (patch)
treed310db0254b85229b90b9d90e79cabfbbcb6101a /sys/arch/mvmeppc/stand
parent77682e0d8d22531ed2952aaab30aae7c69483b3d (diff)
Initial import of mvmeppc.
Diffstat (limited to 'sys/arch/mvmeppc/stand')
-rw-r--r--sys/arch/mvmeppc/stand/Makefile10
-rw-r--r--sys/arch/mvmeppc/stand/Makefile.inc10
-rw-r--r--sys/arch/mvmeppc/stand/bootsd/Makefile36
-rw-r--r--sys/arch/mvmeppc/stand/bootsd/README7
-rw-r--r--sys/arch/mvmeppc/stand/bootsd/boot.c94
-rw-r--r--sys/arch/mvmeppc/stand/bootsd/version.c8
-rw-r--r--sys/arch/mvmeppc/stand/bootst/Makefile38
-rw-r--r--sys/arch/mvmeppc/stand/bootst/boot.c76
-rw-r--r--sys/arch/mvmeppc/stand/bootst/version.c8
-rw-r--r--sys/arch/mvmeppc/stand/bootxx/Makefile33
-rw-r--r--sys/arch/mvmeppc/stand/bootxx/bootxx.c142
-rw-r--r--sys/arch/mvmeppc/stand/bootxx/version.c8
-rw-r--r--sys/arch/mvmeppc/stand/bugcrt/Makefile38
-rw-r--r--sys/arch/mvmeppc/stand/bugcrt/Makefile.inc24
-rw-r--r--sys/arch/mvmeppc/stand/bugcrt/bugcrt.c126
-rw-r--r--sys/arch/mvmeppc/stand/bugcrt/crt.c125
-rw-r--r--sys/arch/mvmeppc/stand/bugcrt/sdcrt.c87
-rw-r--r--sys/arch/mvmeppc/stand/installboot/Makefile19
-rw-r--r--sys/arch/mvmeppc/stand/installboot/installboot.865
-rw-r--r--sys/arch/mvmeppc/stand/installboot/installboot.c474
-rw-r--r--sys/arch/mvmeppc/stand/libbug/Makefile19
-rw-r--r--sys/arch/mvmeppc/stand/libbug/Makefile.inc14
-rw-r--r--sys/arch/mvmeppc/stand/libbug/delay.c15
-rw-r--r--sys/arch/mvmeppc/stand/libbug/diskrd.c19
-rw-r--r--sys/arch/mvmeppc/stand/libbug/diskwr.c19
-rw-r--r--sys/arch/mvmeppc/stand/libbug/getbrdid.c17
-rw-r--r--sys/arch/mvmeppc/stand/libbug/inchr.c22
-rw-r--r--sys/arch/mvmeppc/stand/libbug/instat.c17
-rw-r--r--sys/arch/mvmeppc/stand/libbug/libbug.h29
-rw-r--r--sys/arch/mvmeppc/stand/libbug/netctrl.c129
-rw-r--r--sys/arch/mvmeppc/stand/libbug/netfopen.c16
-rw-r--r--sys/arch/mvmeppc/stand/libbug/netfread.c16
-rw-r--r--sys/arch/mvmeppc/stand/libbug/netrd.c16
-rw-r--r--sys/arch/mvmeppc/stand/libbug/netwr.c16
-rw-r--r--sys/arch/mvmeppc/stand/libbug/outch.c15
-rw-r--r--sys/arch/mvmeppc/stand/libbug/outln.c15
-rw-r--r--sys/arch/mvmeppc/stand/libbug/outstr.c15
-rw-r--r--sys/arch/mvmeppc/stand/libbug/putchar.c25
-rw-r--r--sys/arch/mvmeppc/stand/libbug/return.c26
-rw-r--r--sys/arch/mvmeppc/stand/libbug/rtc_rd.c14
-rw-r--r--sys/arch/mvmeppc/stand/libsa/Makefile48
-rw-r--r--sys/arch/mvmeppc/stand/libsa/Makefile.inc15
-rw-r--r--sys/arch/mvmeppc/stand/libsa/SRT0.S90
-rw-r--r--sys/arch/mvmeppc/stand/libsa/SRT1.c124
-rw-r--r--sys/arch/mvmeppc/stand/libsa/bugdev.c609
-rw-r--r--sys/arch/mvmeppc/stand/libsa/cache.c23
-rw-r--r--sys/arch/mvmeppc/stand/libsa/clock.c63
-rw-r--r--sys/arch/mvmeppc/stand/libsa/conf.c33
-rw-r--r--sys/arch/mvmeppc/stand/libsa/exec_mvme.c260
-rw-r--r--sys/arch/mvmeppc/stand/libsa/libsa.h31
-rw-r--r--sys/arch/mvmeppc/stand/libsa/parse_args.c121
-rw-r--r--sys/arch/mvmeppc/stand/libsa/rawfs.c178
-rw-r--r--sys/arch/mvmeppc/stand/libsa/rawfs.h15
-rw-r--r--sys/arch/mvmeppc/stand/libsa/tftpfs.c291
-rw-r--r--sys/arch/mvmeppc/stand/libsa/tftpfs.h43
-rw-r--r--sys/arch/mvmeppc/stand/libz/Makefile8
-rw-r--r--sys/arch/mvmeppc/stand/libz/Makefile.inc14
-rw-r--r--sys/arch/mvmeppc/stand/tftpboot/Makefile45
-rw-r--r--sys/arch/mvmeppc/stand/tftpboot/boot.c120
-rw-r--r--sys/arch/mvmeppc/stand/tftpboot/version.c8
60 files changed, 4041 insertions, 0 deletions
diff --git a/sys/arch/mvmeppc/stand/Makefile b/sys/arch/mvmeppc/stand/Makefile
new file mode 100644
index 00000000000..e88a919c8ab
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/Makefile
@@ -0,0 +1,10 @@
+# $OpenBSD: Makefile,v 1.1 2001/06/26 21:57:58 smurph Exp $
+#.if ${MACHINE} == "mvmeppc"
+
+SUBDIR= bugcrt libbug libsa libz bootsd bootxx bootst tftpboot
+#sboot XXX future
+#.endif
+
+SUBDIR+=installboot
+
+.include <bsd.subdir.mk>
diff --git a/sys/arch/mvmeppc/stand/Makefile.inc b/sys/arch/mvmeppc/stand/Makefile.inc
new file mode 100644
index 00000000000..5404d746abb
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/Makefile.inc
@@ -0,0 +1,10 @@
+# $OpenBSD: Makefile.inc,v 1.1 2001/06/26 21:57:58 smurph Exp $
+
+MDEC_DIR?=/usr/mdec
+
+# Load addresses for first and second stage bootstraps
+STAGE1_RELOC=4000
+STAGE2_RELOC=6000
+STAGE3_RELOC=6000
+
+
diff --git a/sys/arch/mvmeppc/stand/bootsd/Makefile b/sys/arch/mvmeppc/stand/bootsd/Makefile
new file mode 100644
index 00000000000..158ce346fe2
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/bootsd/Makefile
@@ -0,0 +1,36 @@
+# from: @(#)Makefile 8.1 (Berkeley) 6/10/93
+# $OpenBSD: Makefile,v 1.1 2001/06/26 21:57:59 smurph Exp $
+
+
+S= ${.CURDIR}/../../../..
+DEFS=
+INCPATH=-I${.CURDIR} -I${.CURDIR}/../libsa -I${.CURDIR}/../libbug \
+ -I${.CURDIR}/../../include -I${S} -I${S}/lib/libsa
+CFLAGS=-O0 ${INCPATH} ${DEFS} ${COPTS}
+LDFLAGS=-N -Ttext ${STAGE2_RELOC}
+CLEANFILES+=bootsd
+
+.include "${S}/arch/mvmeppc/stand/bugcrt/Makefile.inc"
+.include "${S}/arch/mvmeppc/stand/libbug/Makefile.inc"
+.include "${S}/arch/mvmeppc/stand/libsa/Makefile.inc"
+.include "${S}/arch/mvmeppc/stand/libz/Makefile.inc"
+
+SRCS= boot.c version.c
+
+LIBS= ${LIBSA} ${LIBBUG} ${LIBZ} ${LIBGCC}
+
+OBJS= ${SRCS:N*.h:R:S/$/.o/g}
+
+BOOTS= bootsd
+ALL= ${BOOTS}
+
+all: ${ALL}
+
+bootsd: ${OBJS} ${STAGE2} ${LIBS}
+ ${LD} ${LDFLAGS} -o $@ \
+ ${STAGE2} ${OBJS} ${LIBS}
+
+install:
+ install -c -m 555 -g bin -o bin ${BOOTS} ${DESTDIR}${MDEC_DIR}
+
+.include <bsd.prog.mk>
diff --git a/sys/arch/mvmeppc/stand/bootsd/README b/sys/arch/mvmeppc/stand/bootsd/README
new file mode 100644
index 00000000000..47a7aab2813
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/bootsd/README
@@ -0,0 +1,7 @@
+In short:
+ cd /usr/mdec
+ cp bootsd /
+ ./installboot -v /bootsd ./bootxx /dev/rsd0a
+
+ (you will need to be single user to run installboot since it writes
+ to a raw disk device)
diff --git a/sys/arch/mvmeppc/stand/bootsd/boot.c b/sys/arch/mvmeppc/stand/bootsd/boot.c
new file mode 100644
index 00000000000..6feb4224273
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/bootsd/boot.c
@@ -0,0 +1,94 @@
+/* $OpenBSD: boot.c,v 1.1 2001/06/26 21:57:59 smurph Exp $ */
+/* $NetBSD: boot.c,v 1.2 1995/09/23 03:42:52 gwr Exp $ */
+
+/*-
+ * Copyright (c) 1982, 1986, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)boot.c 8.1 (Berkeley) 6/10/93
+ */
+
+#include <sys/param.h>
+#include <sys/reboot.h>
+
+#include <machine/prom.h>
+
+#include "stand.h"
+#include "libsa.h"
+
+#define RB_NOSYM 0x400
+#define RB_MULTI 0x4000
+#define RB_EXTRA 0x8000
+#define RB_ASKKERN 0x0010 /* ask kernel name */
+
+int debug;
+int errno;
+extern char *version;
+char line[80];
+
+int
+main()
+{
+ char *cp, *file;
+ int io, flag, ret;
+ int ask = 0;
+
+ bootdev_type = BUGDEV_DISK;
+
+ printf("\n>> OpenBSD/mvme88k bootsd [%s]\n", version);
+
+ ret = parse_args(&file, &flag);
+ if (flag & RB_ASKKERN) {
+ ask = 1;
+ }
+ for (;;) {
+ if (ask) {
+ printf("boot: ");
+ gets(line);
+ if (line[0]) {
+ bugargs.arg_start = line;
+ cp = line;
+ while (cp < (line + sizeof(line) -1) && *cp)
+ cp++;
+ bugargs.arg_end = cp;
+ ret = parse_args(&file, &flag);
+ }
+ }
+ if (ret) {
+ printf("boot: -q returning to MVME-Bug\n");
+ break;
+ }
+ exec_mvme(file, flag);
+ printf("boot: %s: %s\n", file, strerror(errno));
+ ask = 1;
+ }
+ return (0);
+}
diff --git a/sys/arch/mvmeppc/stand/bootsd/version.c b/sys/arch/mvmeppc/stand/bootsd/version.c
new file mode 100644
index 00000000000..7162d459350
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/bootsd/version.c
@@ -0,0 +1,8 @@
+/* $OpenBSD: version.c,v 1.1 2001/06/26 21:57:59 smurph Exp $ */
+
+/*
+ * make a random change to this file when you want the bootblock
+ * revision to increase. like change this q to an x, or something.
+ */
+
+char *version = "$Revision: 1.1 $";
diff --git a/sys/arch/mvmeppc/stand/bootst/Makefile b/sys/arch/mvmeppc/stand/bootst/Makefile
new file mode 100644
index 00000000000..15b6465861c
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/bootst/Makefile
@@ -0,0 +1,38 @@
+# from: @(#)Makefile 8.1 (Berkeley) 6/10/93
+# $OpenBSD: Makefile,v 1.1 2001/06/26 21:58:00 smurph Exp $
+
+SIZE?= size
+
+S= ${.CURDIR}/../../../..
+DEFS= -DSTANDALONE -DCOMPAT_NOLABEL
+INCPATH=-I${.CURDIR} -I${.CURDIR}/../libsa -I${.CURDIR}/../libbug \
+ -I${.CURDIR}/../../include -I${S} -I${S}/lib/libsa
+CFLAGS=-O0 ${INCPATH} ${DEFS} ${COPTS}
+LDFLAGS=-s -N -Ttext ${STAGE2_RELOC}
+CLEANFILES+=stboot bootst bootst.bug
+
+#.include "${S}/arch/mvme88k/stand/wrtvid/Makefile.inc"
+.include "${S}/arch/mvmeppc/stand/bugcrt/Makefile.inc"
+.include "${S}/arch/mvmeppc/stand/libbug/Makefile.inc"
+.include "${S}/arch/mvmeppc/stand/libsa/Makefile.inc"
+.include "${S}/arch/mvmeppc/stand/libz/Makefile.inc"
+
+SRCS= boot.c version.c
+
+LIBS= ${LIBSA} ${LIBBUG} ${LIBZ}
+
+OBJS= ${SRCS:N*.h:R:S/$/.o/g}
+
+BOOTS= bootst
+ALL= ${BOOTS}
+
+all: ${ALL}
+
+bootst: ${OBJS} ${SINGLE} ${LIBS}
+ ${LD} ${LDFLAGS} ${SINGLE} ${OBJS} ${LIBS} -o $@
+ @${SIZE} $@
+
+install:
+ install -c -m 555 -g bin -o bin ${BOOTS} ${DESTDIR}${MDEC_DIR}
+
+.include <bsd.prog.mk>
diff --git a/sys/arch/mvmeppc/stand/bootst/boot.c b/sys/arch/mvmeppc/stand/bootst/boot.c
new file mode 100644
index 00000000000..1db477b2abf
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/bootst/boot.c
@@ -0,0 +1,76 @@
+/* $OpenBSD: boot.c,v 1.1 2001/06/26 21:58:00 smurph Exp $ */
+/*-
+ * Changes Copyright (c) 1998 steve Murphree, Jr.
+ * Copyright (c) 1982, 1986, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)boot.c 8.1 (Berkeley) 6/10/93
+ */
+
+#include <sys/param.h>
+#include <sys/reboot.h>
+#include <machine/prom.h>
+
+#include "stand.h"
+#include "libsa.h"
+
+#define LOADADDR 0x10000
+
+extern char *version;
+extern int errno;
+
+int main()
+{
+ static char dnm[32] = "2";
+ char line[80];
+ char *cp, *filename;
+ int bflag = 0;
+
+ bootdev_type = BUGDEV_TAPE;
+
+ printf(">> OpenBSD/mvme88k tapeboot [%s]\n", version);
+
+ *bugargs.arg_end = 0; /* ensure */
+ parse_args(&filename, &bflag);
+ filename = dnm; /* override */
+
+ if (bflag & RB_ASKNAME) {
+ printf("tapeboot: segment? [%s] ", dnm);
+ gets(line);
+ if (line[0])
+ filename = line;
+ }
+
+ exec_mvme(filename, bflag);
+
+ printf("tapeboot: %s: %s\n", filename, strerror(errno));
+ return(0);
+}
diff --git a/sys/arch/mvmeppc/stand/bootst/version.c b/sys/arch/mvmeppc/stand/bootst/version.c
new file mode 100644
index 00000000000..0ebfccf685d
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/bootst/version.c
@@ -0,0 +1,8 @@
+/* $OpenBSD: version.c,v 1.1 2001/06/26 21:58:00 smurph Exp $ */
+
+/*
+ * make a random change to this file when you want the bootblock
+ * revision to increase. like change this x to an q, or something.
+ */
+
+char *version = "$Revision: 1.1 $";
diff --git a/sys/arch/mvmeppc/stand/bootxx/Makefile b/sys/arch/mvmeppc/stand/bootxx/Makefile
new file mode 100644
index 00000000000..1f5fdf5af01
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/bootxx/Makefile
@@ -0,0 +1,33 @@
+# from: @(#)Makefile 8.1 (Berkeley) 6/10/93
+# $OpenBSD: Makefile,v 1.1 2001/06/26 21:58:01 smurph Exp $
+
+S= ${.CURDIR}/../../../..
+DEFS=-DSTAGE2_RELOC=${STAGE2_RELOC}
+INCPATH=-I${.CURDIR} -I${.CURDIR}/../libsa -I${.CURDIR}/../libbug \
+ -I${.CURDIR}/../../include -I${S} -I${S}/lib/libsa
+CFLAGS=-O0 ${INCPATH} ${DEFS} ${COPTS}
+CLEANFILES+=bootxx
+
+.include "${S}/arch/mvmeppc/stand/bugcrt/Makefile.inc"
+.include "${S}/arch/mvmeppc/stand/libbug/Makefile.inc"
+.include "${S}/arch/mvmeppc/stand/libsa/Makefile.inc"
+.include "${S}/arch/mvmeppc/stand/libz/Makefile.inc"
+
+SRCS= bootxx.c version.c
+
+LIBS= ${LIBSA} ${LIBBUG} ${LIBZ} ${LIBGCC}
+
+OBJS= ${SRCS:N*.h:R:S/$/.o/g}
+
+BOOTS= bootxx
+ALL= ${BOOTS}
+
+all: ${ALL}
+
+bootxx: ${OBJS} ${STAGE1} ${LIBS}
+ ${LD} -X -N -Ttext ${STAGE1_RELOC} ${STAGE1} ${OBJS} ${LIBS} -o $@
+
+install:
+ install -c -m 555 -g bin -o bin ${BOOTS} ${DESTDIR}${MDEC_DIR}
+
+.include <bsd.prog.mk>
diff --git a/sys/arch/mvmeppc/stand/bootxx/bootxx.c b/sys/arch/mvmeppc/stand/bootxx/bootxx.c
new file mode 100644
index 00000000000..451ae40de97
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/bootxx/bootxx.c
@@ -0,0 +1,142 @@
+/* $OpenBSD: bootxx.c,v 1.1 2001/06/26 21:58:01 smurph Exp $ */
+
+/*
+ * Copyright (c) 1994 Paul Kranenburg
+ * 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 Paul Kranenburg.
+ * 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.
+ */
+
+/*
+ * This is a generic "first-stage" boot program.
+ *
+ * Note that this program has absolutely no filesystem knowledge!
+ *
+ * Instead, this uses a table of disk block numbers that are
+ * filled in by the installboot program such that this program
+ * can load the "second-stage" boot program.
+ */
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/exec.h>
+#include <machine/prom.h>
+
+#include "stand.h"
+#include "libsa.h"
+
+/*
+ * Boot device is derived from ROM provided information.
+ */
+
+/* This determines the largest boot program we can load. */
+#define MAXBLOCKNUM 64
+
+/*
+ * These three names are known by installboot.
+ * The block_table contains starting block numbers,
+ * in terms of 512-byte blocks. Each non-zero value
+ * will result in a read of block_size bytes.
+ */
+int block_size = 512; /* default */
+int block_count = MAXBLOCKNUM; /* length of table */
+daddr_t block_table[MAXBLOCKNUM] = { 0 };
+
+extern char *version;
+
+
+main()
+{
+ struct open_file f;
+ char *addr;
+ int n, error;
+
+ bootdev_type = BUGDEV_DISK;
+
+ printf("Boot: bug device: ctrl=%d, dev=%d\n",
+ bugargs.ctrl_lun, bugargs.dev_lun);
+ printf("\nbootxx: first level bootstrap program [%s]\n\n", version);
+
+ f.f_flags = F_RAW;
+ if (devopen(&f, 0, &addr)) {
+ printf("bootxx: open failed\n");
+ _rtt();
+ }
+
+ addr = (char*)STAGE2_RELOC;
+ error = copyboot(&f, addr);
+ f.f_dev->dv_close(&f);
+ if (!error) {
+ bugexec((void (*)())addr);
+ }
+ /* copyboot had a problem... */
+ _rtt();
+}
+
+int
+copyboot(fp, addr)
+ struct open_file *fp;
+ char *addr;
+{
+ int n, i, blknum;
+ struct exec *x;
+
+ addr -= sizeof(struct exec); /* assume OMAGIC, verify below */
+ x = (struct exec *)addr;
+
+ if (!block_count) {
+ printf("bootxx: no data!?!\n");
+ return -1;
+ }
+
+ for (i = 0; i < block_count; i++) {
+
+ if ((blknum = block_table[i]) == 0)
+ break;
+
+#ifdef DEBUG
+ printf("bootxx: read block # %d = %d\n", i, blknum);
+#endif
+ if ((fp->f_dev->dv_strategy)(fp->f_devdata, F_READ,
+ blknum, block_size, addr, &n))
+ {
+ printf("bootxx: read failed\n");
+ return -1;
+ }
+ if (n != block_size) {
+ printf("bootxx: short read\n");
+ return -1;
+ }
+ addr += block_size;
+ }
+
+ if (N_GETMAGIC(*x) != OMAGIC) {
+ printf("bootxx: secondary bootstrap isn't in OMAGIC format\n");
+ return(-1);
+ }
+
+ return 0;
+}
diff --git a/sys/arch/mvmeppc/stand/bootxx/version.c b/sys/arch/mvmeppc/stand/bootxx/version.c
new file mode 100644
index 00000000000..1dca3531fee
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/bootxx/version.c
@@ -0,0 +1,8 @@
+/* $OpenBSD: version.c,v 1.1 2001/06/26 21:58:01 smurph Exp $ */
+
+/*
+ * make a random change to this file when you want the bootblock
+ * revision to increase. like change this y to an x, or something.
+ */
+
+char *version = "$Revision: 1.1 $";
diff --git a/sys/arch/mvmeppc/stand/bugcrt/Makefile b/sys/arch/mvmeppc/stand/bugcrt/Makefile
new file mode 100644
index 00000000000..4ebcfc372ae
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/bugcrt/Makefile
@@ -0,0 +1,38 @@
+# $OpenBSD: Makefile,v 1.1 2001/06/26 21:58:02 smurph Exp $
+#
+# DO NOT OPTMIZE bugcrt (i.e. no "-O2")
+#
+S=${.CURDIR}/../../../..
+
+CFLAGS=-I${.CURDIR}/../../include -I${.CURDIR}/../libbug -I${S}/lib/libsa \
+ -fomit-frame-pointer -save-temps
+STAGE1_CFLAGS=-DSTACK_ASM_OP="\".long ${STAGE1_RELOC}\"" -DSTAGE1
+STAGE2_CFLAGS=-DSTACK_ASM_OP="\".long ${STAGE2_RELOC}\""
+SINGLE_CFLAGS=-DSTACK_ASM_OP="\".long ${STAGE2_RELOC}\"" -DSTAGE1
+SRCS=crt.c
+OBJS=stage1crt.o stage2crt.o singlecrt.o
+
+CLEANFILES+=a.out ${OBJS} *.i *.s
+
+all: ${OBJS}
+
+stage1crt.o: crt.c
+ ${CC} ${CFLAGS} ${STAGE1_CFLAGS} -c ${.CURDIR}/crt.c -o ${.TARGET}
+ ${LD} -x -r ${.TARGET}
+ mv a.out ${.TARGET}
+
+stage2crt.o: crt.c
+ ${CC} ${CFLAGS} ${STAGE2_CFLAGS} -c ${.CURDIR}/crt.c -o ${.TARGET}
+ ${LD} -x -r ${.TARGET}
+ mv a.out ${.TARGET}
+
+singlecrt.o: crt.c
+ ${CC} ${CFLAGS} ${SINGLE_CFLAGS} -c ${.CURDIR}/crt.c -o ${.TARGET}
+ ${LD} -x -r ${.TARGET}
+ mv a.out ${.TARGET}
+
+install:
+
+lint tags:
+
+.include <bsd.prog.mk>
diff --git a/sys/arch/mvmeppc/stand/bugcrt/Makefile.inc b/sys/arch/mvmeppc/stand/bugcrt/Makefile.inc
new file mode 100644
index 00000000000..38be2b62f90
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/bugcrt/Makefile.inc
@@ -0,0 +1,24 @@
+# $OpenBSD: Makefile.inc,v 1.1 2001/06/26 21:58:02 smurph Exp $
+
+BUG_CRT_DIR=${S}/arch/mvmeppc/stand/bugcrt
+
+BUGCRT_DIR!= cd ${BUG_CRT_DIR}; \
+ printf "xxx:\n\techo \$${.OBJDIR}\n" | ${MAKE} -r -s -f - xxx
+
+STAGE1=${BUGCRT_DIR}/stage1crt.o
+STAGE2=${BUGCRT_DIR}/stage2crt.o
+SINGLE=${BUGCRT_DIR}/singlecrt.o
+
+$(STAGE1): .NOTMAIN __always_make_bugcrt
+ @echo making sure the stage1crt.o is up to date...
+ @(cd ${BUG_CRT_DIR}; ${MAKE} stage1crt.o)
+
+$(STAGE2): .NOTMAIN __always_make_bugcrt
+ @echo making sure the stage2crt.o is up to date...
+ @(cd ${BUG_CRT_DIR}; ${MAKE} stage2crt.o)
+
+$(SINGLE): .NOTMAIN __always_make_bugcrt
+ @echo making sure the singlecrt.o is up to date...
+ @(cd ${BUG_CRT_DIR}; ${MAKE} singlecrt.o)
+
+__always_make_bugcrt: .NOTMAIN
diff --git a/sys/arch/mvmeppc/stand/bugcrt/bugcrt.c b/sys/arch/mvmeppc/stand/bugcrt/bugcrt.c
new file mode 100644
index 00000000000..edb48124f98
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/bugcrt/bugcrt.c
@@ -0,0 +1,126 @@
+/* $OpenBSD: bugcrt.c,v 1.1 2001/06/26 21:58:02 smurph Exp $ */
+
+/*
+ * This is the startup file for single stage bootstraps or the first
+ * stage of a two stage bootstrap. It includes code to enable the
+ * SFU1.
+ */
+
+#include <sys/types.h>
+#include <machine/prom.h>
+
+struct mvmeprom_args bugargs = { 1}; /* not BSS */
+
+ asm (".text");
+ /* pseudo reset vector */
+ asm (STACK_ASM_OP); /* initial sp value */
+ asm (".long _start"); /* initial ip value */
+start()
+{
+ register int dev_lun asm (MVMEPROM_REG_DEVLUN);
+ register int ctrl_lun asm (MVMEPROM_REG_CTRLLUN);
+ register int flags asm (MVMEPROM_REG_FLAGS);
+ register int ctrl_addr asm (MVMEPROM_REG_CTRLADDR);
+ register int entry asm (MVMEPROM_REG_ENTRY);
+ register int conf_blk asm (MVMEPROM_REG_CONFBLK);
+ register char *arg_start asm (MVMEPROM_REG_ARGSTART);
+ register char *arg_end asm (MVMEPROM_REG_ARGEND);
+ register char *nbarg_start asm (MVMEPROM_REG_NBARGSTART);
+ register char *nbarg_end asm (MVMEPROM_REG_NBARGEND);
+ extern int edata, end;
+ struct mvmeprom_brdid *id, *mvmeprom_brdid();
+
+#ifdef STAGE1
+ /* Do not use r10 to enable the SFU1. This wipes out
+ the netboot args. Not cool at all... r25 seems free. */
+ asm("| enable SFU1");
+ asm(" ldcr r25,cr1");
+ asm(" xor r25,r25,0x8");
+ asm(" stcr r25,cr1");
+#endif
+
+ bugargs.dev_lun = dev_lun;
+ bugargs.ctrl_lun = ctrl_lun;
+ bugargs.flags = flags;
+ bugargs.ctrl_addr = ctrl_addr;
+ bugargs.entry = entry;
+ bugargs.conf_blk = conf_blk;
+ bugargs.arg_start = arg_start;
+ bugargs.arg_end = arg_end;
+ bugargs.nbarg_start = nbarg_start;
+ bugargs.nbarg_end = nbarg_end;
+ *bugargs.arg_end = 0;
+
+ id = mvmeprom_brdid();
+ bugargs.cputyp = id->model;
+
+ /*
+ * Initialize PSR and CMMU to a known, stable state.
+ * This has to be done early for MVME197.
+ * Per EB162 mc88110 engineering bulletin.
+ */
+ /*
+ if (bugargs.cputyp == 0x197) {
+ asm("| init MVME197");
+ asm("| 1. PSR");
+ asm("or.u r2,r0,0xA200");
+ asm("or r2,r2,0x03E2");
+ asm("stcr r2,cr1");
+ asm("| 2. ICTL");
+ asm("or r2,r0,r0");
+ asm("or r2,r2,0x8000");
+ asm("or r2,r2,0x0040");
+ asm("stcr r2,cr26");
+ asm("| 3. DCTL");
+ asm("or r2,r0,r0");
+ asm("or r2,r2,0x2000");
+ asm("or r2,r2,0x0040");
+ asm("stcr r2,cr41");
+ asm("| 4. init cache");
+ asm("or r2,r0,0x01");
+ asm("stcr r2,cr25");
+ asm("stcr r2,cr40");
+ }
+ */
+ memset(&edata, 0, ((int)&end - (int)&edata));
+
+ asm ("| main()");
+ main();
+ mvmeprom_return();
+ /* NOTREACHED */
+}
+
+__main()
+{
+}
+
+void
+bugexec(addr)
+
+void (*addr)();
+
+{
+ register int dev_lun asm (MVMEPROM_REG_DEVLUN);
+ register int ctrl_lun asm (MVMEPROM_REG_CTRLLUN);
+ register int flags asm (MVMEPROM_REG_FLAGS);
+ register int ctrl_addr asm (MVMEPROM_REG_CTRLADDR);
+ register int entry asm (MVMEPROM_REG_ENTRY);
+ register int conf_blk asm (MVMEPROM_REG_CONFBLK);
+ register char *arg_start asm (MVMEPROM_REG_ARGSTART);
+ register char *arg_end asm (MVMEPROM_REG_ARGEND);
+
+ dev_lun = bugargs.dev_lun;
+ ctrl_lun = bugargs.ctrl_lun;
+ flags = bugargs.flags;
+ ctrl_addr = bugargs.ctrl_addr;
+ entry = bugargs.entry;
+ conf_blk = bugargs.conf_blk;
+ arg_start = bugargs.arg_start;
+ arg_end = bugargs.arg_end;
+
+ (*addr)();
+ printf("bugexec: 0x%x returned!\n", addr);
+
+ _rtt();
+}
+
diff --git a/sys/arch/mvmeppc/stand/bugcrt/crt.c b/sys/arch/mvmeppc/stand/bugcrt/crt.c
new file mode 100644
index 00000000000..992a907a481
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/bugcrt/crt.c
@@ -0,0 +1,125 @@
+/* $OpenBSD: crt.c,v 1.1 2001/06/26 21:58:02 smurph Exp $ */
+
+#include <sys/types.h>
+#include <machine/prom.h>
+
+struct mvmeprom_args bugargs = { 1}; /* not BSS */
+
+/* pseudo reset vector */
+#if 0
+asm (".text");
+asm (STACK_ASM_OP); /* initial sp value */
+asm (".long _start"); /* initial ip value */
+#endif
+_start()
+{
+ register int dev_lun asm (MVMEPROM_REG_DEVLUN);
+ register int ctrl_lun asm (MVMEPROM_REG_CTRLLUN);
+ register int flags asm (MVMEPROM_REG_SCSUPP);
+ register int ctrl_addr asm (MVMEPROM_REG_CTRLADDR);
+ register int entry asm (MVMEPROM_REG_ENTRY);
+ register int conf_blk asm (MVMEPROM_REG_IPA);
+ register char *arg_start asm (MVMEPROM_REG_ARGSTART);
+ register char *arg_end asm (MVMEPROM_REG_ARGEND);
+ register char *nbarg_start asm (MVMEPROM_REG_NBARGSTART);
+ register char *nbarg_end asm (MVMEPROM_REG_NBARGEND);
+ extern int edata, end;
+ struct mvmeprom_brdid *id, *mvmeprom_brdid();
+
+#ifdef notyet
+ /*
+ * This code enables the SFU1 and is used for single stage
+ * bootstraps or the first stage of a two stage bootstrap.
+ * Do not use r10 to enable the SFU1. This wipes out
+ * the netboot args. Not cool at all... r25 seems free.
+ */
+ asm("| enable SFU1");
+ asm(" ldcr r25,cr1");
+ asm(" clr r25,r25,1<3>"); /* bit 3 is SFU1D */
+ asm(" stcr r25,cr1");
+#endif
+ bugargs.dev_lun = dev_lun;
+ bugargs.ctrl_lun = ctrl_lun;
+ bugargs.flags = flags;
+ bugargs.ctrl_addr = ctrl_addr;
+ bugargs.entry = entry;
+ bugargs.conf_blk = conf_blk;
+ bugargs.arg_start = arg_start;
+ bugargs.arg_end = arg_end;
+ bugargs.nbarg_start = nbarg_start;
+ bugargs.nbarg_end = nbarg_end;
+ *bugargs.arg_end = 0;
+ *bugargs.nbarg_end = 0;
+
+ id = mvmeprom_brdid();
+ bugargs.cputyp = id->model;
+
+#ifdef notyet /* STAGE1 */
+ /*
+ * Initialize PSR and CMMU to a known, stable state.
+ * This has to be done early for MVME197.
+ * Per EB162 mc88110 engineering bulletin.
+ */
+ if (bugargs.cputyp == 0x197) {
+ asm("| init MVME197");
+ asm("| 1. PSR");
+ asm("or.u r2,r0,0xA200");
+ asm("or r2,r2,0x03E2");
+ asm("stcr r2,cr1");
+ asm("| 2. ICTL");
+ asm("or r2,r0,r0");
+ asm("or r2,r2,0x8000");
+ asm("or r2,r2,0x0040");
+ asm("stcr r2,cr26");
+ asm("| 3. DCTL");
+ asm("or r2,r0,r0");
+ asm("or r2,r2,0x2000");
+ asm("or r2,r2,0x0040");
+ asm("stcr r2,cr41");
+ asm("| 4. init cache");
+ asm("or r2,r0,0x01");
+ asm("stcr r2,cr25");
+ asm("stcr r2,cr40");
+ }
+#endif
+
+ memset(&edata, 0, ((int)&end - (int)&edata));
+
+ asm ("# main()");
+ main();
+ mvmeprom_return();
+ /* NOTREACHED */
+}
+
+__main()
+{
+}
+
+void
+bugexec(addr)
+ void (*addr)();
+{
+ register int dev_lun asm (MVMEPROM_REG_DEVLUN);
+ register int ctrl_lun asm (MVMEPROM_REG_CTRLLUN);
+ register int flags asm (MVMEPROM_REG_SCSUPP);
+ register int ctrl_addr asm (MVMEPROM_REG_CTRLADDR);
+ register int entry asm (MVMEPROM_REG_ENTRY);
+ register int conf_blk asm (MVMEPROM_REG_IPA);
+ register char *arg_start asm (MVMEPROM_REG_ARGSTART);
+ register char *arg_end asm (MVMEPROM_REG_ARGEND);
+
+ dev_lun = bugargs.dev_lun;
+ ctrl_lun = bugargs.ctrl_lun;
+ flags = bugargs.flags;
+ ctrl_addr = bugargs.ctrl_addr;
+ entry = bugargs.entry;
+ conf_blk = bugargs.conf_blk;
+ arg_start = bugargs.arg_start;
+ arg_end = bugargs.arg_end;
+
+ (*addr)();
+ printf("bugexec: 0x%x returned!\n", addr);
+
+ _rtt();
+}
+
diff --git a/sys/arch/mvmeppc/stand/bugcrt/sdcrt.c b/sys/arch/mvmeppc/stand/bugcrt/sdcrt.c
new file mode 100644
index 00000000000..0476a421a59
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/bugcrt/sdcrt.c
@@ -0,0 +1,87 @@
+/* $OpenBSD: sdcrt.c,v 1.1 2001/06/26 21:58:02 smurph Exp $ */
+
+/*
+ * This is the startup file for the second stage bootstrap. (bootsd)
+ * It does *not* includes code to enable the SFU1.
+ */
+
+#include <sys/types.h>
+#include <machine/prom.h>
+
+struct mvmeprom_args bugargs = { 1 }; /* not BSS */
+
+ asm (".text");
+ /* pseudo reset vector */
+ asm (STACK_ASM_OP); /* initial sp value */
+ asm (".long _start"); /* initial ip value */
+start()
+{
+ register int dev_lun asm (MVMEPROM_REG_DEVLUN);
+ register int ctrl_lun asm (MVMEPROM_REG_CTRLLUN);
+ register int flags asm (MVMEPROM_REG_FLAGS);
+ register int ctrl_addr asm (MVMEPROM_REG_CTRLADDR);
+ register int entry asm (MVMEPROM_REG_ENTRY);
+ register int conf_blk asm (MVMEPROM_REG_CONFBLK);
+ register char *arg_start asm (MVMEPROM_REG_ARGSTART);
+ register char *arg_end asm (MVMEPROM_REG_ARGEND);
+ register char *nbarg_start asm (MVMEPROM_REG_NBARGSTART);
+ register char *nbarg_end asm (MVMEPROM_REG_NBARGEND);
+ extern int edata, end;
+ struct mvmeprom_brdid *id, *mvmeprom_brdid();
+
+ bugargs.dev_lun = dev_lun;
+ bugargs.ctrl_lun = ctrl_lun;
+ bugargs.flags = flags;
+ bugargs.ctrl_addr = ctrl_addr;
+ bugargs.entry = entry;
+ bugargs.conf_blk = conf_blk;
+ bugargs.arg_start = arg_start;
+ bugargs.arg_end = arg_end;
+ bugargs.nbarg_start = nbarg_start;
+ bugargs.nbarg_end = nbarg_end;
+ *bugargs.arg_end = 0;
+
+ memset(&edata, 0, ((int)&end - (int)&edata));
+
+ id = mvmeprom_brdid();
+ bugargs.cputyp = id->model;
+
+ main();
+ mvmeprom_return();
+ /* NOTREACHED */
+}
+
+__main()
+{
+}
+
+void
+bugexec(addr)
+
+void (*addr)();
+
+{
+ register int dev_lun asm (MVMEPROM_REG_DEVLUN);
+ register int ctrl_lun asm (MVMEPROM_REG_CTRLLUN);
+ register int flags asm (MVMEPROM_REG_FLAGS);
+ register int ctrl_addr asm (MVMEPROM_REG_CTRLADDR);
+ register int entry asm (MVMEPROM_REG_ENTRY);
+ register int conf_blk asm (MVMEPROM_REG_CONFBLK);
+ register char *arg_start asm (MVMEPROM_REG_ARGSTART);
+ register char *arg_end asm (MVMEPROM_REG_ARGEND);
+
+ dev_lun = bugargs.dev_lun;
+ ctrl_lun = bugargs.ctrl_lun;
+ flags = bugargs.flags;
+ ctrl_addr = bugargs.ctrl_addr;
+ entry = bugargs.entry;
+ conf_blk = bugargs.conf_blk;
+ arg_start = bugargs.arg_start;
+ arg_end = bugargs.arg_end;
+
+ (*addr)();
+ printf("bugexec: 0x%x returned!\n", addr);
+
+ _rtt();
+}
+
diff --git a/sys/arch/mvmeppc/stand/installboot/Makefile b/sys/arch/mvmeppc/stand/installboot/Makefile
new file mode 100644
index 00000000000..d13f574cd03
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/installboot/Makefile
@@ -0,0 +1,19 @@
+# $OpenBSD: Makefile,v 1.1 2001/06/26 21:58:03 smurph Exp $
+
+.if ${MACHINE} == "mvmeppc"
+PROG= installboot
+MAN= installboot.8
+MANSUBDIR=/mvme88k
+
+BINDIR=/usr/mdec
+DPADD=${LIBUTIL}
+LDADD=-lutil
+CFLAGS+=-O0
+# Need this to work in the miniroot
+LDSTATIC=-static
+.else
+NOPROG=
+.endif
+
+.include <bsd.prog.mk>
+
diff --git a/sys/arch/mvmeppc/stand/installboot/installboot.8 b/sys/arch/mvmeppc/stand/installboot/installboot.8
new file mode 100644
index 00000000000..38018126dda
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/installboot/installboot.8
@@ -0,0 +1,65 @@
+.\" $OpenBSD: installboot.8,v 1.1 2001/06/26 21:58:03 smurph Exp $
+.\"
+.Dd 31 May 1995
+.Dt INSTALLBOOT 8 mvme88k
+.Os
+.Sh NAME
+.Nm installboot
+.Nd install a bootstrap on a UFS disk
+.Sh SYNOPSIS
+.Nm installboot
+.Op Fl n
+.Op Fl v
+.Ar bootsd
+.Ar bootxx
+.Ar rawdev
+.Sh DESCRIPTION
+.Nm installboot
+is used to install a "first-stage" boot program into the boot area
+of a UFS disk partition, and initialize the table of block numbers the
+.Ar bootxx
+program uses to load the second-stage boot program.
+.Pp
+The options are as follows:
+.Bl -tag -width flag
+.It Fl n
+Do not actually write anything on the disk.
+.It Fl v
+Be verbose, printing out the block numbers that
+.Ar bootxx
+will use to load
+.Ar bootsd .
+.El
+.Pp
+The arguments are:
+.Bl -tag -width bootsd
+.It Ar bootsd
+the name of the second-stage boot program in the file system
+where the first-stage boot program is to be installed.
+.It Ar bootxx
+the name of the prototype file for the first stage boot program.
+.It Ar rawdev
+the name of the raw device in which the first-stage boot program
+is to be installed. This should correspond to the block device
+on which the file system containing
+.Ar ufsboot
+is mounted.
+.El
+.Sh EXAMPLE
+.Bd -literal -offset
+cd /usr/mdec
+cp bootsd /
+installboot -v /bootsd ./bootxx /dev/rsd0a
+.Ed
+.Sh BUGS
+.Nm installboot
+requires simultaneous access to the mounted file system and
+the raw device, but that is not allowed with the kernel
+.Nm securelevel
+variable set to a value greater than zero (the default), so
+.Nm installboot
+only works in single-user mode (or insecure mode - see
+.Xr init 8 ).
+.Sh SEE ALSO
+.Xr disklabel 8 ,
+.Xr init 8
diff --git a/sys/arch/mvmeppc/stand/installboot/installboot.c b/sys/arch/mvmeppc/stand/installboot/installboot.c
new file mode 100644
index 00000000000..ad853175a69
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/installboot/installboot.c
@@ -0,0 +1,474 @@
+/* $NetBSD: installboot.c,v 1.5 1995/11/17 23:23:50 gwr Exp $ */
+
+/*
+ * Copyright (c) 1994 Paul Kranenburg
+ * 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 Paul Kranenburg.
+ * 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/mount.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <ufs/ufs/dinode.h>
+#include <ufs/ufs/dir.h>
+#include <ufs/ffs/fs.h>
+#include <err.h>
+#include <a.out.h>
+#include <fcntl.h>
+#include <nlist.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <util.h>
+#include <machine/disklabel.h>
+
+int verbose, nowrite, hflag;
+char *boot, *proto, *dev;
+char cdev[80];
+
+struct nlist nl[] = {
+#define X_BLOCK_SIZE 0
+ {"_block_size"},
+#define X_BLOCK_COUNT 1
+ {"_block_count"},
+#define X_BLOCK_TABLE 2
+ {"_block_table"},
+ {NULL}
+};
+
+int *block_size_p; /* block size var. in prototype image */
+int *block_count_p; /* block count var. in prototype image */
+daddr_t *block_table; /* block number array in prototype image */
+int maxblocknum; /* size of this array */
+
+
+char *loadprotoblocks __P((char *, long *));
+int loadblocknums __P((char *, int));
+static void devread __P((int, void *, daddr_t, size_t, char *));
+static void usage __P((void));
+int main __P((int, char *[]));
+static void vid_to_disklabel __P((char *, char*));
+
+
+static void
+usage()
+{
+ fprintf(stderr,
+ "usage: installboot [-n] [-v] [-h] <boot> <proto> <device>\n");
+ exit(1);
+}
+
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ int c;
+ int devfd;
+ char *protostore;
+ long protosize;
+
+ while ((c = getopt(argc, argv, "vnh")) != -1) {
+ switch (c) {
+ case 'h':
+ /* Don't strip a.out header */
+ hflag = 1;
+ break;
+ case 'n':
+ /* Do not actually write the bootblock to disk */
+ nowrite = 1;
+ break;
+ case 'v':
+ /* Chat */
+ verbose = 1;
+ break;
+ default:
+ usage();
+ }
+ }
+
+ if (argc - optind < 3) {
+ usage();
+ }
+
+ boot = argv[optind];
+ proto = argv[optind + 1];
+ dev = argv[optind + 2];
+ strcpy(cdev, dev);
+ cdev[strlen(cdev)-1] = 'c';
+
+ if (verbose) {
+ printf("boot: %s\n", boot);
+ printf("proto: %s\n", proto);
+ printf("device: %s\n", dev);
+ printf("cdevice: %s\n", cdev);
+ }
+
+ /* Insert VID into disklabel */
+ vid_to_disklabel(cdev, proto);
+
+ /* Load proto blocks into core */
+ if ((protostore = loadprotoblocks(proto, &protosize)) == NULL)
+ exit(1);
+
+ /* XXX - Paranoia: Make sure size is aligned! */
+ if (protosize & (DEV_BSIZE - 1))
+ err(1, "proto bootblock bad size=%d", protosize);
+
+ /* Open and check raw disk device */
+ if ((devfd = open(dev, O_RDONLY, 0)) < 0)
+ err(1, "open: %s", dev);
+
+ /* Extract and load block numbers */
+ if (loadblocknums(boot, devfd) != 0)
+ exit(1);
+
+ (void)close(devfd);
+
+ if (nowrite)
+ return 0;
+
+ /* Write patched proto bootblocks into the superblock */
+ if (protosize > SBSIZE - DEV_BSIZE)
+ errx(1, "proto bootblocks too big");
+
+ if ((devfd = open(cdev, O_RDWR, 0)) < 0)
+ err(1, "open: %s", dev);
+
+ if (lseek(devfd, DEV_BSIZE, SEEK_SET) != DEV_BSIZE)
+ err(1, "lseek bootstrap");
+
+ /* Sync filesystems (to clean in-memory superblock?) */
+ sync();
+
+ if (write(devfd, protostore, protosize) != protosize)
+ err(1, "write bootstrap");
+ (void)close(devfd);
+ return 0;
+}
+
+char *
+loadprotoblocks(fname, size)
+ char *fname;
+ long *size;
+{
+ int fd;
+ size_t tdsize; /* text+data size */
+ size_t bbsize; /* boot block size (block aligned) */
+ char *bp;
+ struct nlist *nlp;
+ struct exec eh;
+ long off;
+
+ fd = -1;
+ bp = NULL;
+
+ /* Locate block number array in proto file */
+ if (nlist(fname, nl) != 0) {
+ warnx("nlist: %s: symbols not found", fname);
+ return NULL;
+ }
+ /* Validate symbol types (global data). */
+ for (nlp = nl; nlp->n_un.n_name; nlp++) {
+ if (nlp->n_type != (N_DATA | N_EXT)) {
+ warnx("nlist: %s: wrong type", nlp->n_un.n_name);
+ return NULL;
+ }
+ }
+
+ if ((fd = open(fname, O_RDONLY)) < 0) {
+ warn("open: %s", fname);
+ return NULL;
+ }
+ if (read(fd, &eh, sizeof(eh)) != sizeof(eh)) {
+ warn("read: %s", fname);
+ goto bad;
+ }
+ if (N_GETMAGIC(eh) != OMAGIC) {
+ warn("bad magic: 0x%x", eh.a_midmag);
+ goto bad;
+ }
+ /*
+ * We have to include the exec header in the beginning of
+ * the buffer, and leave extra space at the end in case
+ * the actual write to disk wants to skip the header.
+ */
+ tdsize = eh.a_text + eh.a_data;
+ bbsize = tdsize + sizeof(eh);
+ bbsize = roundup(bbsize, DEV_BSIZE);
+
+ /*
+ * Allocate extra space here because the caller may copy
+ * the boot block starting at the end of the exec header.
+ * This prevents reading beyond the end of the buffer.
+ */
+ if ((bp = calloc(bbsize + sizeof(eh), 1)) == NULL) {
+ warnx("malloc: %s: no memory", fname);
+ goto bad;
+ }
+ /* Copy the exec header and read the rest of the file. */
+ memcpy(bp, &eh, sizeof(eh));
+ if (read(fd, bp+sizeof(eh), tdsize) != tdsize) {
+ warn("read: %s", fname);
+ goto bad;
+ }
+
+ *size = bbsize; /* aligned to DEV_BSIZE */
+
+ /* Calculate the symbols' locations within the proto file */
+ off = N_DATOFF(eh) - N_DATADDR(eh) - (eh.a_entry - N_TXTADDR(eh));
+ block_size_p = (int *) (bp + nl[X_BLOCK_SIZE ].n_value + off);
+ block_count_p = (int *) (bp + nl[X_BLOCK_COUNT].n_value + off);
+ block_table = (daddr_t *) (bp + nl[X_BLOCK_TABLE].n_value + off);
+ maxblocknum = *block_count_p;
+
+ if (verbose) {
+ printf("%s: entry point %#x\n", fname, eh.a_entry);
+ printf("proto bootblock size %ld\n", *size);
+ printf("room for %d filesystem blocks at %#x\n",
+ maxblocknum, nl[X_BLOCK_TABLE].n_value);
+ }
+
+ close(fd);
+ if (!hflag)
+ bp += sizeof(struct exec);
+ return bp;
+
+ bad:
+ if (bp)
+ free(bp);
+ if (fd >= 0)
+ close(fd);
+ return NULL;
+}
+
+static void
+devread(fd, buf, blk, size, msg)
+ int fd;
+ void *buf;
+ daddr_t blk;
+ size_t size;
+ char *msg;
+{
+ if (lseek(fd, dbtob(blk), SEEK_SET) != dbtob(blk))
+ err(1, "%s: devread: lseek", msg);
+
+ if (read(fd, buf, size) != size)
+ err(1, "%s: devread: read", msg);
+}
+
+static char sblock[SBSIZE];
+
+int
+loadblocknums(boot, devfd)
+char *boot;
+int devfd;
+{
+ int i, fd;
+ struct stat statbuf;
+ struct statfs statfsbuf;
+ struct fs *fs;
+ char *buf;
+ daddr_t blk, *ap;
+ struct dinode *ip;
+ int ndb;
+
+ /*
+ * Open 2nd-level boot program and record the block numbers
+ * it occupies on the filesystem represented by `devfd'.
+ */
+
+ /* Make sure the (probably new) boot file is on disk. */
+ sync(); sleep(1);
+
+ if ((fd = open(boot, O_RDONLY)) < 0)
+ err(1, "open: %s", boot);
+
+ if (fstatfs(fd, &statfsbuf) != 0)
+ err(1, "statfs: %s", boot);
+
+ if (strncmp(statfsbuf.f_fstypename, "ffs", MFSNAMELEN) &&
+ strncmp(statfsbuf.f_fstypename, "ufs", MFSNAMELEN) ) {
+ errx(1, "%s: must be on an FFS filesystem", boot);
+ }
+
+ if (fsync(fd) != 0)
+ err(1, "fsync: %s", boot);
+
+ if (fstat(fd, &statbuf) != 0)
+ err(1, "fstat: %s", boot);
+
+ close(fd);
+
+ /* Read superblock */
+ devread(devfd, sblock, SBLOCK, SBSIZE, "superblock");
+ fs = (struct fs *)sblock;
+
+ /* Sanity-check super-block. */
+
+ if (fs->fs_magic != FS_MAGIC)
+ errx(1, "Bad magic number in superblock");
+
+ if (fs->fs_inopb <= 0)
+ err(1, "Bad inopb=%d in superblock", fs->fs_inopb);
+
+ /* Read inode */
+ if ((buf = malloc(fs->fs_bsize)) == NULL)
+ errx(1, "No memory for filesystem block");
+
+ blk = fsbtodb(fs, ino_to_fsba(fs, statbuf.st_ino));
+ devread(devfd, buf, blk, fs->fs_bsize, "inode");
+ ip = (struct dinode *)(buf) + ino_to_fsbo(fs, statbuf.st_ino);
+
+ /*
+ * Have the inode. Figure out how many blocks we need.
+ */
+ ndb = howmany(ip->di_size, fs->fs_bsize);
+ if (ndb > maxblocknum)
+ errx(1, "Too many blocks");
+ *block_count_p = ndb;
+ *block_size_p = fs->fs_bsize;
+ if (verbose)
+ printf("Will load %d blocks of size %d each.\n",
+ ndb, fs->fs_bsize);
+
+ /*
+ * Get the block numbers; we don't handle fragments
+ */
+ ap = ip->di_db;
+ for (i = 0; i < NDADDR && *ap && ndb; i++, ap++, ndb--) {
+ blk = fsbtodb(fs, *ap);
+ if (verbose)
+ printf("%d: %d\n", i, blk);
+ block_table[i] = blk;
+ }
+ if (ndb == 0)
+ return 0;
+
+ /*
+ * Just one level of indirections; there isn't much room
+ * for more in the 1st-level bootblocks anyway.
+ */
+ blk = fsbtodb(fs, ip->di_ib[0]);
+ devread(devfd, buf, blk, fs->fs_bsize, "indirect block");
+ ap = (daddr_t *)buf;
+ for (; i < NINDIR(fs) && *ap && ndb; i++, ap++, ndb--) {
+ blk = fsbtodb(fs, *ap);
+ if (verbose)
+ printf("%d: %d\n", i, blk);
+ block_table[i] = blk;
+ }
+
+ return 0;
+}
+
+static void
+vid_to_disklabel(dkname, bootproto)
+char *dkname;
+char *bootproto;
+{
+ char *specname;
+ int exe_file, f;
+ struct cpu_disklabel *pcpul;
+ struct stat stat;
+ unsigned int exe_addr;
+ unsigned short exe_addr_u;
+ unsigned short exe_addr_l;
+
+ pcpul = (struct cpu_disklabel *)malloc(sizeof(struct cpu_disklabel));
+ bzero(pcpul, sizeof(struct cpu_disklabel));
+
+ if (verbose)
+ printf("modifying vid.\n");
+
+ exe_file = open(bootproto, O_RDONLY, 0444);
+ if (exe_file == -1) {
+ perror(bootproto);
+ exit(2);
+ }
+
+ f = opendev(dkname, O_RDWR, OPENDEV_PART, &specname);
+
+ if (lseek(f, 0, SEEK_SET) < 0 ||
+ read(f, pcpul, sizeof(struct cpu_disklabel))
+ < sizeof(struct cpu_disklabel))
+ err(4, "%s", specname);
+
+
+ pcpul->version = 1;
+ strcpy(pcpul->vid_id, "M88K");
+
+ fstat(exe_file, &stat);
+
+ /* size in 256 byte blocks round up after a.out header removed */
+
+ pcpul->vid_oss = 2;
+ pcpul->vid_osl = (((stat.st_size -0x20) +511) / 512) *2;
+
+ lseek(exe_file, 0x14, SEEK_SET);
+ read(exe_file, &exe_addr, 4);
+
+ /* check this, it may not work in both endian. */
+ /* No, it doesn't. Use a big endian machine for now. SPM */
+
+ {
+ union {
+ struct s {
+ unsigned short s1;
+ unsigned short s2;
+ } s;
+ unsigned long l;
+ } a;
+ a.l = exe_addr;
+ pcpul->vid_osa_u = a.s.s1;
+ pcpul->vid_osa_l = a.s.s2;
+
+ }
+ pcpul->vid_cas = 1;
+ pcpul->vid_cal = 1;
+
+ /* do not want to write past end of structure, not null terminated */
+
+ strncpy(pcpul->vid_mot, "MOTOROLA", 8);
+
+ pcpul->cfg_rec = 0x100;
+ pcpul->cfg_psm = 0x200;
+
+ if (!nowrite) {
+ if (lseek(f, 0, SEEK_SET) < 0 ||
+ write(f, pcpul, sizeof(struct cpu_disklabel))
+ < sizeof(struct cpu_disklabel))
+ err(4, "%s", specname);
+ }
+ free(pcpul);
+
+ close(exe_file);
+ close(f);
+
+}
diff --git a/sys/arch/mvmeppc/stand/libbug/Makefile b/sys/arch/mvmeppc/stand/libbug/Makefile
new file mode 100644
index 00000000000..a360e63b233
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/libbug/Makefile
@@ -0,0 +1,19 @@
+# $OpenBSD: Makefile,v 1.1 2001/06/26 21:58:03 smurph Exp $
+
+LIB=bug
+
+NOPIC=
+NOPROFILE=
+
+S=${.CURDIR}/../../../..
+DIR_SA=$S/lib/libsa
+
+CFLAGS+=-O2 -I${.CURDIR}/../../include -I${DIR_SA}
+
+SRCS= delay.c diskrd.c diskwr.c getbrdid.c inchr.c instat.c outln.c outch.c\
+ outstr.c putchar.c return.c rtc_rd.c netrd.c netwr.c netfopen.c \
+ netfread.c netctrl.c
+
+install:
+
+.include <bsd.lib.mk>
diff --git a/sys/arch/mvmeppc/stand/libbug/Makefile.inc b/sys/arch/mvmeppc/stand/libbug/Makefile.inc
new file mode 100644
index 00000000000..1d780fe931e
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/libbug/Makefile.inc
@@ -0,0 +1,14 @@
+# $OpenBSD: Makefile.inc,v 1.1 2001/06/26 21:58:04 smurph Exp $
+
+LIB_BUG_DIR=${S}/arch/mvmeppc/stand/libbug
+
+LIBBUG_DIR!= cd ${LIB_BUG_DIR}; \
+ printf "xxx:\n\techo \$${.OBJDIR}\n" | ${MAKE} -r -s -f - xxx
+
+LIBBUG=${LIBBUG_DIR}/libbug.a
+
+$(LIBBUG): .NOTMAIN __always_make_libbug
+ @echo making sure the libbug is up to date...
+ @(cd ${LIB_BUG_DIR}; ${MAKE})
+
+__always_make_libbug: .NOTMAIN
diff --git a/sys/arch/mvmeppc/stand/libbug/delay.c b/sys/arch/mvmeppc/stand/libbug/delay.c
new file mode 100644
index 00000000000..7e101de2cc0
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/libbug/delay.c
@@ -0,0 +1,15 @@
+/*
+ * bug routines -- assumes that the necessary sections of memory
+ * are preserved.
+ */
+#include <sys/types.h>
+#include <machine/prom.h>
+
+/* BUG - timing routine */
+void
+mvmeprom_delay(msec)
+ int msec; /* This is r3 */
+{
+ asm volatile ("mr 3, %0" :: "r"(msec));
+ MVMEPROM_CALL(MVMEPROM_DELAY);
+}
diff --git a/sys/arch/mvmeppc/stand/libbug/diskrd.c b/sys/arch/mvmeppc/stand/libbug/diskrd.c
new file mode 100644
index 00000000000..3ff1de00e71
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/libbug/diskrd.c
@@ -0,0 +1,19 @@
+/*
+ * bug routines -- assumes that the necessary sections of memory
+ * are preserved.
+ */
+#include <sys/types.h>
+#include <machine/prom.h>
+
+/* returns 0: success, nonzero: error */
+int
+mvmeprom_diskrd(arg)
+ struct mvmeprom_dskio *arg;
+{
+ int ret;
+
+ asm volatile ("mr 3, %0" :: "r"(arg));
+ MVMEPROM_CALL(MVMEPROM_NETRD);
+ asm volatile ("mr %0, 3" : "=r" (ret));
+ return ((ret & 0x8));
+}
diff --git a/sys/arch/mvmeppc/stand/libbug/diskwr.c b/sys/arch/mvmeppc/stand/libbug/diskwr.c
new file mode 100644
index 00000000000..8b1290a222d
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/libbug/diskwr.c
@@ -0,0 +1,19 @@
+/*
+ * bug routines -- assumes that the necessary sections of memory
+ * are preserved.
+ */
+#include <sys/types.h>
+#include <machine/prom.h>
+
+/* returns 0: success, nonzero: error */
+int
+mvmeprom_diskwr(arg)
+ struct mvmeprom_dskio *arg;
+{
+ int ret;
+
+ asm volatile ("mr 3, %0" :: "r"(arg));
+ MVMEPROM_CALL(MVMEPROM_DSKWR);
+ asm volatile ("mr %0, 3" : "=r" (ret));
+ return ((ret & 0x8));
+}
diff --git a/sys/arch/mvmeppc/stand/libbug/getbrdid.c b/sys/arch/mvmeppc/stand/libbug/getbrdid.c
new file mode 100644
index 00000000000..541bb2603aa
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/libbug/getbrdid.c
@@ -0,0 +1,17 @@
+/*
+ * bug routines -- assumes that the necessary sections of memory
+ * are preserved.
+ */
+#include <sys/types.h>
+#include <machine/prom.h>
+
+/* BUG - query board routines */
+struct mvmeprom_brdid *
+mvmeprom_brdid()
+{
+ struct mvmeprom_brdid *id;
+
+ MVMEPROM_CALL(MVMEPROM_BRD_ID);
+ asm volatile ("mr %0, 3": "=r" (id):);
+ return (id);
+}
diff --git a/sys/arch/mvmeppc/stand/libbug/inchr.c b/sys/arch/mvmeppc/stand/libbug/inchr.c
new file mode 100644
index 00000000000..c1fce2e7414
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/libbug/inchr.c
@@ -0,0 +1,22 @@
+/* $OpenBSD: inchr.c,v 1.1 2001/06/26 21:58:04 smurph Exp $ */
+
+/*
+ * bug routines -- assumes that the necessary sections of memory
+ * are preserved.
+ */
+#include <sys/types.h>
+#include <machine/prom.h>
+
+#include "stand.h"
+#include "libbug.h"
+
+/* returns 0 if no characters ready to read */
+int
+getchar()
+{
+ int ret;
+
+ MVMEPROM_CALL(MVMEPROM_INCHR);
+ asm volatile ("mr %0, 3" : "=r" (ret));
+ return ret;
+}
diff --git a/sys/arch/mvmeppc/stand/libbug/instat.c b/sys/arch/mvmeppc/stand/libbug/instat.c
new file mode 100644
index 00000000000..096abdedd99
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/libbug/instat.c
@@ -0,0 +1,17 @@
+/*
+ * bug routines -- assumes that the necessary sections of memory
+ * are preserved.
+ */
+#include <sys/types.h>
+#include <machine/prom.h>
+
+/* returns 0 if no characters ready to read */
+int
+mvmeprom_instat()
+{
+ int ret;
+
+ MVMEPROM_CALL(MVMEPROM_INSTAT);
+ asm volatile ("mr %0, 3" : "=r" (ret));
+ return (!(ret & 0x4));
+}
diff --git a/sys/arch/mvmeppc/stand/libbug/libbug.h b/sys/arch/mvmeppc/stand/libbug/libbug.h
new file mode 100644
index 00000000000..c282cfaac9e
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/libbug/libbug.h
@@ -0,0 +1,29 @@
+/* $OpenBSD: libbug.h,v 1.1 2001/06/26 21:58:04 smurph Exp $ */
+
+/*
+ * prototypes and such. note that get/put char are in stand.h
+ */
+
+void mvmeprom_delay __P((int));
+int mvmeprom_diskrd __P((struct mvmeprom_dskio *));
+int mvmeprom_diskwr __P((struct mvmeprom_dskio *));
+struct mvmeprom_brdid *mvmeprom_getbrdid __P((void));
+int peekchar __P((void));
+void mvmeprom_outln __P((char *, char *));
+void mvmeprom_outstr __P((char *, char *));
+void mvmeprom_rtc_rd __P((struct mvmeprom_time *));
+int mvmeprom_netctrl __P((struct mvmeprom_netctrl *));
+int mvmeprom_netctrl_init __P((u_char, u_char));
+int mvmeprom_netctrl_hwa __P((u_char, u_char, void *, u_long *));
+int mvmeprom_netctrl_tx __P((u_char, u_char, void *, u_long *));
+int mvmeprom_netctrl_rx __P((u_char, u_char, void *, u_long *));
+int mvmeprom_netctrl_flush_rx __P((u_char, u_char));
+int mvmeprom_netctrl_reset __P((u_char, u_char));
+
+/*
+ * bugcrt stuff
+ */
+
+extern struct mvmeprom_args bugargs;
+
+void bugexec __P((void (*)()));
diff --git a/sys/arch/mvmeppc/stand/libbug/netctrl.c b/sys/arch/mvmeppc/stand/libbug/netctrl.c
new file mode 100644
index 00000000000..cf671f124a5
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/libbug/netctrl.c
@@ -0,0 +1,129 @@
+/*
+ * bug routines -- assumes that the necessary sections of memory
+ * are preserved.
+ */
+#include <sys/types.h>
+#include <machine/prom.h>
+
+/* returns 0: success, nonzero: error */
+int
+mvmeprom_netctrl(arg)
+ struct mvmeprom_netctrl *arg;
+{
+ asm volatile ("mr 3, %0":: "r" (arg));
+ MVMEPROM_CALL(MVMEPROM_NETCTRL);
+ return (arg->status);
+}
+
+int
+mvmeprom_netctrl_init(clun, dlun)
+u_char clun;
+u_char dlun;
+{
+ struct mvmeprom_netctrl niocall;
+ niocall.clun = clun;
+ niocall.dlun = dlun;
+ niocall.status = 0;
+ niocall.cmd = 0; /* init */
+ niocall.addr = 0;
+ niocall.len = 0;
+ niocall.flags = 0;
+ mvmeprom_netctrl(&niocall);
+ return(niocall.status);
+}
+
+int
+mvmeprom_netctrl_hwa(clun, dlun, addr, len)
+u_char clun;
+u_char dlun;
+void *addr;
+u_long *len;
+{
+ struct mvmeprom_netctrl niocall;
+ niocall.clun = clun;
+ niocall.dlun = dlun;
+ niocall.status = 0;
+ niocall.cmd = 1; /* get hw address */
+ niocall.addr = addr;
+ niocall.len = *len;
+ niocall.flags = 0;
+ mvmeprom_netctrl(&niocall);
+ *len = niocall.len;
+ return(niocall.status);
+}
+
+int
+mvmeprom_netctrl_tx(clun, dlun, addr, len)
+u_char clun;
+u_char dlun;
+void *addr;
+u_long *len;
+{
+ struct mvmeprom_netctrl niocall;
+ niocall.clun = clun;
+ niocall.dlun = dlun;
+ niocall.status = 0;
+ niocall.cmd = 2; /* transmit */
+ niocall.addr = addr;
+ niocall.len = *len;
+ niocall.flags = 0;
+ mvmeprom_netctrl(&niocall);
+ *len = niocall.len;
+ return(niocall.status);
+}
+
+int
+mvmeprom_netctrl_rx(clun, dlun, addr, len)
+u_char clun;
+u_char dlun;
+void *addr;
+u_long *len;
+{
+ struct mvmeprom_netctrl niocall;
+ niocall.clun = clun;
+ niocall.dlun = dlun;
+ niocall.status = 0;
+ niocall.cmd = 3; /* receive */
+ niocall.addr = addr;
+ niocall.len = *len;
+ niocall.flags = 0;
+ mvmeprom_netctrl(&niocall);
+ *len = niocall.len;
+ return(niocall.status);
+}
+
+int
+mvmeprom_netctrl_flush_rx(clun, dlun)
+u_char clun;
+u_char dlun;
+{
+ struct mvmeprom_netctrl niocall;
+ niocall.clun = clun;
+ niocall.dlun = dlun;
+ niocall.status = 0;
+ niocall.cmd = 4; /* reset */
+ niocall.addr = 0;
+ niocall.len = 0;
+ niocall.flags = 0;
+ mvmeprom_netctrl(&niocall);
+ return(niocall.status);
+}
+
+int
+mvmeprom_netctrl_reset(clun, dlun)
+u_char clun;
+u_char dlun;
+{
+ struct mvmeprom_netctrl niocall;
+ niocall.clun = clun;
+ niocall.dlun = dlun;
+ niocall.status = 0;
+ niocall.cmd = 5; /* reset */
+ niocall.addr = 0;
+ niocall.len = 0;
+ niocall.flags = 0;
+ mvmeprom_netctrl(&niocall);
+ return(niocall.status);
+}
+
+
diff --git a/sys/arch/mvmeppc/stand/libbug/netfopen.c b/sys/arch/mvmeppc/stand/libbug/netfopen.c
new file mode 100644
index 00000000000..2ff21f39646
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/libbug/netfopen.c
@@ -0,0 +1,16 @@
+/*
+ * bug routines -- assumes that the necessary sections of memory
+ * are preserved.
+ */
+#include <sys/types.h>
+#include <machine/prom.h>
+
+/* returns 0: success, nonzero: error */
+int
+mvmeprom_netfopen(arg)
+ struct mvmeprom_netfopen *arg;
+{
+ asm volatile ("mr 3, %0": : "r" (arg));
+ MVMEPROM_CALL(MVMEPROM_NETFOPEN);
+ return (arg->status);
+}
diff --git a/sys/arch/mvmeppc/stand/libbug/netfread.c b/sys/arch/mvmeppc/stand/libbug/netfread.c
new file mode 100644
index 00000000000..32b9108b2c9
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/libbug/netfread.c
@@ -0,0 +1,16 @@
+/*
+ * bug routines -- assumes that the necessary sections of memory
+ * are preserved.
+ */
+#include <sys/types.h>
+#include <machine/prom.h>
+
+/* returns 0: success, nonzero: error */
+int
+mvmeprom_netfread(arg)
+ struct mvmeprom_netfread *arg;
+{
+ asm volatile ("mr 3, %0": : "r" (arg));
+ MVMEPROM_CALL(MVMEPROM_NETFREAD);
+ return (arg->status);
+}
diff --git a/sys/arch/mvmeppc/stand/libbug/netrd.c b/sys/arch/mvmeppc/stand/libbug/netrd.c
new file mode 100644
index 00000000000..b4fa0376dec
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/libbug/netrd.c
@@ -0,0 +1,16 @@
+/*
+ * bug routines -- assumes that the necessary sections of memory
+ * are preserved.
+ */
+#include <sys/types.h>
+#include <machine/prom.h>
+
+/* returns 0: success, nonzero: error */
+int
+mvmeprom_netrd(arg)
+ struct mvmeprom_netio *arg;
+{
+ asm volatile ("mr 3, %0": : "r" (arg));
+ MVMEPROM_CALL(MVMEPROM_NETRD);
+ return (arg->status);
+}
diff --git a/sys/arch/mvmeppc/stand/libbug/netwr.c b/sys/arch/mvmeppc/stand/libbug/netwr.c
new file mode 100644
index 00000000000..e96d888db18
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/libbug/netwr.c
@@ -0,0 +1,16 @@
+/*
+ * bug routines -- assumes that the necessary sections of memory
+ * are preserved.
+ */
+#include <sys/types.h>
+#include <machine/prom.h>
+
+/* returns 0: success, nonzero: error */
+int
+mvmeprom_netwr(arg)
+ struct mvmeprom_netio *arg;
+{
+ asm volatile ("mr 3, %0": : "r" (arg));
+ MVMEPROM_CALL(MVMEPROM_NETWR);
+ return (arg->status);
+}
diff --git a/sys/arch/mvmeppc/stand/libbug/outch.c b/sys/arch/mvmeppc/stand/libbug/outch.c
new file mode 100644
index 00000000000..5d98a4e0065
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/libbug/outch.c
@@ -0,0 +1,15 @@
+/*
+ * bug routines -- assumes that the necessary sections of memory
+ * are preserved.
+ */
+#include <sys/types.h>
+#include <machine/prom.h>
+
+void
+mvmeprom_outchr(a)
+ char a;
+{
+ asm volatile ("mr 3, %0" : :"r" (a));
+ MVMEPROM_CALL(MVMEPROM_OUTCHR);
+}
+
diff --git a/sys/arch/mvmeppc/stand/libbug/outln.c b/sys/arch/mvmeppc/stand/libbug/outln.c
new file mode 100644
index 00000000000..dc4015a7762
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/libbug/outln.c
@@ -0,0 +1,15 @@
+/*
+ * bug routines -- assumes that the necessary sections of memory
+ * are preserved.
+ */
+#include <sys/types.h>
+#include <machine/prom.h>
+
+void
+mvmeprom_outln(start, end)
+ char *start, *end;
+{
+ asm volatile ("mr 3, %0": : "r" (start));
+ asm volatile ("mr 4, %0": : "r" (end));
+ MVMEPROM_CALL(MVMEPROM_OUTLN);
+}
diff --git a/sys/arch/mvmeppc/stand/libbug/outstr.c b/sys/arch/mvmeppc/stand/libbug/outstr.c
new file mode 100644
index 00000000000..5f317081ab0
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/libbug/outstr.c
@@ -0,0 +1,15 @@
+/*
+ * bug routines -- assumes that the necessary sections of memory
+ * are preserved.
+ */
+#include <sys/types.h>
+#include <machine/prom.h>
+
+void
+mvmeprom_outstr(start, end)
+ char *start, *end;
+{
+ asm volatile ("mr 3, %0": : "r" (start));
+ asm volatile ("mr 4, %0": : "r" (end));
+ MVMEPROM_CALL(MVMEPROM_OUTSTR);
+}
diff --git a/sys/arch/mvmeppc/stand/libbug/putchar.c b/sys/arch/mvmeppc/stand/libbug/putchar.c
new file mode 100644
index 00000000000..9a15bfb6b3f
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/libbug/putchar.c
@@ -0,0 +1,25 @@
+/* $OpenBSD: putchar.c,v 1.1 2001/06/26 21:58:05 smurph Exp $ */
+
+/*
+ * putchar: easier to do this with outstr than to add more macros to
+ * handle byte passing on the stack
+ */
+
+#include <sys/types.h>
+#include <machine/prom.h>
+
+#include "stand.h"
+#include "libbug.h"
+
+void
+putchar(c)
+ int c;
+{
+ char ca;
+ ca = (char)c & 0xFF;
+ if (ca == '\n')
+ putchar('\r');
+
+ asm volatile ("mr 3, %0" :: "r" (ca));
+ MVMEPROM_CALL(MVMEPROM_OUTCHR);
+}
diff --git a/sys/arch/mvmeppc/stand/libbug/return.c b/sys/arch/mvmeppc/stand/libbug/return.c
new file mode 100644
index 00000000000..53fb5a3b1cc
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/libbug/return.c
@@ -0,0 +1,26 @@
+/*
+ * bug routines -- assumes that the necessary sections of memory
+ * are preserved.
+ */
+#include <sys/types.h>
+#include <machine/prom.h>
+#include "stand.h"
+#include "libbug.h"
+
+/* BUG - return to bug routine */
+void
+mvmeprom_return()
+{
+ MVMEPROM_CALL(MVMEPROM_RETURN);
+ /*NOTREACHED*/
+}
+
+/* BUG - return to bug routine */
+__dead void
+_rtt()
+{
+ MVMEPROM_CALL(MVMEPROM_RETURN);
+ printf("_rtt: exit failed. spinning...");
+ while (1) ;
+ /*NOTREACHED*/
+}
diff --git a/sys/arch/mvmeppc/stand/libbug/rtc_rd.c b/sys/arch/mvmeppc/stand/libbug/rtc_rd.c
new file mode 100644
index 00000000000..c1ee9f5a0da
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/libbug/rtc_rd.c
@@ -0,0 +1,14 @@
+/*
+ * bug routines -- assumes that the necessary sections of memory
+ * are preserved.
+ */
+#include <sys/types.h>
+#include <machine/prom.h>
+
+void
+mvmeprom_rtc_rd(ptime)
+ struct mvmeprom_time *ptime;
+{
+ asm volatile ("mr 3, %0": : "r" (ptime));
+ MVMEPROM_CALL(MVMEPROM_RTC_RD);
+}
diff --git a/sys/arch/mvmeppc/stand/libsa/Makefile b/sys/arch/mvmeppc/stand/libsa/Makefile
new file mode 100644
index 00000000000..3c8b70fa1ea
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/libsa/Makefile
@@ -0,0 +1,48 @@
+# $OpenBSD: Makefile,v 1.1 2001/06/26 21:58:06 smurph Exp $
+
+LIB=sa
+
+CLEANFILES+=SRT0.o SRT1.o
+
+NOPIC=nopic
+NOPROFILE=noprofile
+
+# Logically src/sys
+S=${.CURDIR}/../../../..
+DIR_SA=$S/lib/libsa
+DIR_KERN=$S/lib/libkern
+
+SRC_net= arp.c ether.c in_cksum.c net.c netif.c rpc.c nfs.c \
+ rarp.c bootparam.c
+
+SRC_sa= alloc.c memcpy.c exit.c getfile.c gets.c globals.c \
+ printf.c strerror.c memset.c memcmp.c strncpy.c strcmp.c strlen.c \
+ close.c closeall.c dev.c disklabel.c dkcksum.c \
+ lseek.c open.c nullfs.c read.c fstat.c \
+ ufs.c cread.c
+
+SRC_kern= ashrdi3.c bzero.c strcpy.c
+
+SRC_mvme= exec_mvme.c
+
+SRC_here= bugdev.c cache.c clock.c conf.c parse_args.c rawfs.c tftpfs.c
+
+SRCS= ${SRC_net} ${SRC_sa} ${SRC_mvme} ${SRC_here} ${SRC_kern}
+
+# DBG= -DDEBUG -DNETIF_DEBUG -DNFS_DEBUG -DRPC_DEBUG \
+# -DNET_DEBUG -DRARP_DEBUG -DETHER_DEBUG
+
+#DEFS= -DCOMPAT_UFS
+DEFS= -D__INTERNAL_LIBSA_CREAD
+#-DNETIF_DEBUG
+INCL= -I${.CURDIR} -I${.CURDIR}/../libbug -I${S}/lib/libsa -I${S}
+COPTS= #-fno-defer-pop
+CFLAGS+= ${XCFLAGS} ${COPTS} ${DEFS} ${DBG} ${INCL} -O2
+
+.PATH: ${DIR_SA} ${DIR_KERN}
+
+all: libsa.a
+
+install:
+
+.include <bsd.lib.mk>
diff --git a/sys/arch/mvmeppc/stand/libsa/Makefile.inc b/sys/arch/mvmeppc/stand/libsa/Makefile.inc
new file mode 100644
index 00000000000..568e3b9e4d0
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/libsa/Makefile.inc
@@ -0,0 +1,15 @@
+# $OpenBSD: Makefile.inc,v 1.1 2001/06/26 21:58:06 smurph Exp $
+
+LIB_SA_DIR=${S}/arch/mvmeppc/stand/libsa
+
+LIBSA_DIR!= cd ${LIB_SA_DIR}; \
+ printf "xxx:\n\techo \$${.OBJDIR}\n" | ${MAKE} -r -s -f - xxx
+
+LIBSA=${LIBSA_DIR}/libsa.a
+SRTOBJ?= ${LIBSA_DIR}/SRT0.o
+
+$(LIBSA): .NOTMAIN __always_make_libsa
+ @echo making sure the libsa is up to date...
+ @(cd ${LIB_SA_DIR}; ${MAKE} "XCFLAGS=${CFLAGS}")
+
+__always_make_libsa: .NOTMAIN
diff --git a/sys/arch/mvmeppc/stand/libsa/SRT0.S b/sys/arch/mvmeppc/stand/libsa/SRT0.S
new file mode 100644
index 00000000000..82cf7c28ffd
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/libsa/SRT0.S
@@ -0,0 +1,90 @@
+; $OpenBSD: SRT0.S,v 1.1 2001/06/26 21:58:07 smurph Exp $
+
+; Copyright (c) 1996 Nivas Madhur
+; Copyright (c) 1995 Theo de Raadt
+;
+; 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 under OpenBSD by
+; Theo de Raadt for Willowglen Singapore.
+; 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.
+;
+; Copyright (c) 1995 Gordon W. Ross
+; 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.
+; 4. All advertising materials mentioning features or use of this software
+; must display the following acknowledgement:
+; This product includes software developed by Gordon Ross
+;
+; 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.
+
+; SRT0.S - Stand-alone Run-Time startup code, part 0
+ .file "SRT0.S"
+ .text
+ .globl _stack
+_stack:
+ .globl _start
+_start:
+ .word __estack
+ .word _start
+
+ align 8
+ or.u r10, r0, hi16(_devlun)
+ st r2, r0, lo16(_devlun)
+ or.u r10, r0, hi16(_ctrlun)
+ st r3, r0, lo16(_ctrlun)
+ or.u r10, r0, hi16(_oparg)
+ st r8, r0, lo16(_oparg)
+ or.u r10, r0, hi16(_opargend)
+ st r9, r0, lo16(_opargend)
+; enable SFU1 - 88k disables SFU1 on a reset
+ ldcr r10, cr1
+ xor r10, r10, 0x8
+ stcr r10, cr1
+
+; Call the run-time startup C code, which will:
+; call main & call exit - exit passes control back to
+; to the Bug.
+ bsr __start
+
+; The end.
diff --git a/sys/arch/mvmeppc/stand/libsa/SRT1.c b/sys/arch/mvmeppc/stand/libsa/SRT1.c
new file mode 100644
index 00000000000..c7188ad3213
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/libsa/SRT1.c
@@ -0,0 +1,124 @@
+/* $OpenBSD: SRT1.c,v 1.1 2001/06/26 21:58:07 smurph Exp $ */
+
+/*
+ * Copyright (c) 1996 Nivas Madhur
+ * Copyright (c) 1995 Theo de Raadt
+ *
+ * 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 under OpenBSD by
+ * Theo de Raadt for Willowglen Singapore.
+ * 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.
+ *
+ * Copyright (c) 1995 Gordon W. Ross
+ * 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.
+ * 4. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Gordon Ross
+ *
+ * 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.
+ */
+
+/* SRT1.c - Stand-alone Run-time startup code, part 1 */
+
+#include <stdarg.h>
+#include <sys/types.h>
+
+#include "config.h"
+
+extern char *edata, *end;
+
+int devlun = 0;
+int ctrlun = 0;
+int oparg = 0;
+int opargend = 0;
+
+getvbr()
+{
+ asm volatile ("ldcr r2, cr7");
+}
+
+void
+exit()
+{
+ /*
+ * Return to the Bug
+ */
+
+ asm volatile ("or r9, r0, 0x63; tb0 0, r0, 496");
+ /* NOTREACHED */
+ for(;;); /* keep compiler happy */
+}
+
+struct brdid brdid;
+int cputyp;
+
+/*
+ * This is called by SRT0.S
+ * to do final prep for main
+ */
+_start()
+{
+ struct brdid *p;
+
+ /* Clear BSS */
+
+ bzero(edata, end - edata);
+
+ asm volatile("or r9, r0, 0x70\n
+ tb0 0, r0, 496\n
+ st r2, %0" : "=m" (p));
+
+ bcopy(p, &brdid, sizeof brdid);
+ cputyp = brdid.model;
+
+ main(0);
+ exit();
+}
+
+/*
+ * Boot programs in C++ ? Not likely!
+ */
+__main()
+{}
diff --git a/sys/arch/mvmeppc/stand/libsa/bugdev.c b/sys/arch/mvmeppc/stand/libsa/bugdev.c
new file mode 100644
index 00000000000..b3a8c8bce27
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/libsa/bugdev.c
@@ -0,0 +1,609 @@
+/* $OpenBSD: bugdev.c,v 1.1 2001/06/26 21:58:07 smurph Exp $ */
+
+/*
+ * Copyright (c) 1993 Paul Kranenburg
+ * 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 Paul Kranenburg.
+ * 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/disklabel.h>
+#include <machine/prom.h>
+
+#include <stand.h>
+#include <ufs.h>
+#include "rawfs.h"
+#include "tftpfs.h"
+
+#include "libsa.h"
+
+int errno;
+int bootdev_type = BUGDEV_DISK;
+
+#if 1
+#define md_swap_long(x) ( (((x) >> 24) & 0xff) | (((x) >> 8 ) & 0xff00) | \
+ (((x) << 8) & 0xff0000) | (((x) << 24) & 0xff000000))
+#else
+#define md_swap_long(x) (x)
+#endif
+
+struct bugdev_softc {
+ int fd; /* Prom file descriptor */
+ u_int pnum; /* Partition number */
+ u_int poff; /* Partition offset */
+ u_int psize; /* Partition size */
+ short clun;
+ short dlun;
+} bugdev_softc[1];
+
+extern struct fs_ops ufs_file_system;
+extern struct fs_ops tftp_file_system;
+extern struct fs_ops raw_file_system;
+
+struct fs_ops file_system[1];
+
+struct mvmeprom_dskio tape_ioreq;
+
+#ifdef BUG_DEBUG
+unsigned io = 0, mem = 0;
+#define PCI_BASE 0x80000000
+#define CFC *(unsigned *)(PCI_BASE + 0xcfc)
+#define CF8 *(unsigned *)(PCI_BASE + 0xcf8)
+#define BUS_SHIFT 16
+#define DEVICE_SHIFT 11
+#define FNC_SHIFT 8
+
+unsigned
+bugpci_make_tag(bus, dev, fnc)
+ int bus, dev, fnc;
+{
+ return (bus << BUS_SHIFT) | (dev << DEVICE_SHIFT) | (fnc << FNC_SHIFT);
+}
+
+static unsigned
+bugpci_gen_config_reg(tag, offset)
+ unsigned tag;
+ int offset;
+{
+ unsigned reg;
+
+ /* config mechanism #2, type 0
+ /* standard cf8/cfc config */
+ reg = 0x80000000 | tag | offset;
+
+ return reg;
+}
+
+/*#define DEBUG_CONFIG */
+unsigned
+bugpci_conf_read(bus, dev, func, offset)
+ int bus, dev, func, offset;
+{
+
+ unsigned data;
+ unsigned reg, tag, xx;
+
+ if(offset & 3 || offset < 0 || offset >= 0x100) {
+ printf ("bugpci_conf_read: bad reg %x\n", offset);
+ return(~0);
+ }
+
+ tag = bugpci_make_tag(bus, dev, func);
+ reg = bugpci_gen_config_reg(tag, offset);
+ reg = md_swap_long(reg);
+ /* if invalid tag, return -1 */
+ if (reg == 0xffffffff) {
+ return 0xffffffff;
+ }
+
+ CF8 = reg;
+ xx = CF8;
+ data = CFC;
+ data = md_swap_long(data);
+
+ CF8 = 0;
+
+ return(data);
+}
+
+void
+bugpci_conf_write(bus, dev, func, offset, data)
+ int bus, dev, func, offset;
+ unsigned data;
+{
+ unsigned reg, tag, xx;
+
+ tag = bugpci_make_tag(bus, dev, func);
+ reg = bugpci_gen_config_reg(tag, offset);
+ reg = md_swap_long(reg);
+
+ /* if invalid tag, return ??? */
+ if (reg == 0xffffffff) {
+ return;
+ }
+
+ CF8 = reg;
+ xx = CF8;
+ data = md_swap_long(data);
+ CFC = data;
+ CF8 = 0;
+ xx = CF8;
+}
+#endif
+
+static u_long
+get_long(p)
+ const void *p;
+{
+ const unsigned char *cp = p;
+
+ return cp[0] | (cp[1] << 8) | (cp[2] << 16) | (cp[3] << 24);
+}
+
+/*
+ * Find a valid disklabel.
+ */
+static int
+search_label(devp, off, buf, lp, off0)
+ void *devp;
+ u_long off;
+ char *buf;
+ struct disklabel *lp;
+ u_long off0;
+{
+ size_t read;
+ struct dos_partition *p;
+ int i;
+ u_long poff;
+ static int recursion;
+
+ if (dsk_strategy(devp, F_READ, off, DEV_BSIZE, buf, &read)
+ || read != DEV_BSIZE)
+ return ERDLAB;
+
+ if (buf[510] != 0x55 || buf[511] != 0xaa)
+ return ERDLAB;
+
+ if (recursion++ <= 1)
+ off0 += off;
+ for (p = (struct dos_partition *)(buf + DOSPARTOFF), i = 4;
+ --i >= 0; p++) {
+ if (p->dp_typ == DOSPTYP_OPENBSD ||
+ p->dp_typ == DOSPTYP_NETBSD) {
+ poff = get_long(&p->dp_start) + off0;
+ if (dsk_strategy(devp, F_READ, poff + LABELSECTOR,
+ DEV_BSIZE, buf, &read) == 0
+ && read == DEV_BSIZE) {
+ if (!getdisklabel(buf, lp)) {
+ recursion--;
+ return 0;
+ }
+ }
+ if (dsk_strategy(devp, F_READ, off, DEV_BSIZE, buf, &read)
+ || read != DEV_BSIZE) {
+ recursion--;
+ return ERDLAB;
+ }
+ } else if (p->dp_typ == DOSPTYP_EXTEND) {
+ poff = get_long(&p->dp_start);
+ if (!search_label(devp, poff, buf, lp, off0)) {
+ recursion--;
+ return 0;
+ }
+ if (dsk_strategy(devp, F_READ, off, DEV_BSIZE, buf, &read)
+ || read != DEV_BSIZE) {
+ recursion--;
+ return ERDLAB;
+ }
+ }
+ }
+ recursion--;
+ return ERDLAB;
+}
+
+int dsk_read_disklabel(devp)
+ void *devp;
+{
+ static char iobuf[MAXBSIZE];
+ struct disklabel label;
+ int error = 0;
+ int i;
+
+ register struct bugdev_softc *pp = (struct bugdev_softc *)devp;
+
+#ifdef DEBUG
+ printf("dsk_open:\n");
+#endif
+ /* First try to find a disklabel without MBR partitions */
+ if (dsk_strategy(pp, F_READ, LABELSECTOR, DEV_BSIZE, iobuf, &i) != 0
+ || i != DEV_BSIZE
+ || getdisklabel(iobuf, &label)) {
+ /* Else try MBR partitions */
+ error = search_label(pp, 0, iobuf, &label, 0);
+ if (error && error != ERDLAB)
+ return (error);
+ }
+ if (error == ERDLAB) {
+ if (pp->pnum)
+ /* User specified a partition, but there is none */
+ return (error);
+ /* No, label, just use complete disk */
+ pp->poff = 0;
+ } else {
+ pp->poff = label.d_partitions[pp->pnum].p_offset;
+ pp->psize = label.d_partitions[pp->pnum].p_size;
+ }
+ return(0);
+}
+
+
+int
+devopen(f, fname, file)
+ struct open_file *f;
+ const char *fname;
+ char **file;
+{
+ register struct bugdev_softc *pp = &bugdev_softc[0];
+ int error;
+ char *dev, *cp;
+
+ pp->clun = (short)bugargs.ctrl_lun;
+ pp->dlun = (short)bugargs.dev_lun;
+ pp->poff = 0;
+ pp->psize = 0;
+ pp->fd = 0;
+ pp->pnum = 0;
+
+ f->f_devdata = (void *)pp;
+
+ switch (bootdev_type) {
+ case BUGDEV_DISK:
+ dev = bugargs.arg_start;
+ /*
+ * Extract partition # from boot device string.
+ */
+ for (cp = dev; *cp; cp++) /* void */;
+ while (*cp != '/' && cp > dev) {
+ if (*cp == ':')
+ pp->pnum = *(cp+1) - 'a';
+ --cp;
+ }
+
+ error = dsk_read_disklabel(pp);
+ if (error)
+ return(error);
+
+ bcopy(&ufs_file_system, file_system, sizeof file_system[0]);
+ break;
+
+ case BUGDEV_NET:
+ bcopy(&tftp_file_system, file_system, sizeof file_system[0]);
+ break;
+
+ case BUGDEV_TAPE:
+ bcopy(&raw_file_system, file_system, sizeof file_system[0]);
+ break;
+ }
+
+ f->f_dev = &devsw[bootdev_type];
+ nfsys = 1;
+ *file = (char *)fname;
+ return (0);
+}
+
+/* silly block scale factor */
+#define BUG_BLOCK_SIZE 256
+#define BUG_SCALE (512/BUG_BLOCK_SIZE)
+int
+dsk_strategy(devdata, func, dblk, size, buf, rsize)
+ void *devdata;
+ int func;
+ daddr_t dblk;
+ size_t size;
+ void *buf;
+ size_t *rsize;
+{
+ struct mvmeprom_dskio dio;
+ register struct bugdev_softc *pp = (struct bugdev_softc *)devdata;
+ daddr_t blk = dblk + pp->poff;
+
+ twiddle();
+
+ dio.ctrl_lun = pp->clun;
+ dio.dev_lun = pp->dlun;
+ dio.status = 0;
+ dio.pbuffer = buf;
+ dio.blk_num = blk * BUG_SCALE;
+ dio.blk_cnt = size / BUG_BLOCK_SIZE; /* assumed size in bytes */
+ dio.flag = 0;
+ dio.addr_mod = 0;
+#ifdef DEBUG
+ printf("dsk_strategy: size=%d blk=%d buf=%x\n", size, blk, buf);
+ printf("ctrl %d dev %d\n", dio.ctrl_lun, dio.dev_lun);
+#endif
+ mvmeprom_diskrd(&dio);
+
+ *rsize = dio.blk_cnt * BUG_BLOCK_SIZE;
+#ifdef DEBUG
+printf("rsize %d status %x\n", *rsize, dio.status);
+#endif
+
+ if (dio.status)
+ return (EIO);
+ return (0);
+}
+
+int
+dsk_open(f)
+ struct open_file *f;
+{
+#ifdef DEBUG
+ register struct bugdev_softc *pp = (struct bugdev_softc *)f->f_devdata;
+ printf("dsk_open:\n");
+ printf("using mvmebug ctrl %d dev %d\n",
+ pp->clun, pp->dlun);
+#endif
+ return (0);
+}
+
+int
+dsk_close(f)
+ struct open_file *f;
+{
+ return (EIO);
+}
+
+int
+dsk_ioctl(f, cmd, data)
+ struct open_file *f;
+ u_long cmd;
+ void *data;
+{
+ return (EIO);
+}
+
+#define NFR_TIMEOUT 5
+/* netboot stuff */
+int
+net_strategy(devdata, func, nblk, size, buf, rsize)
+ void *devdata;
+ int func;
+ daddr_t nblk;
+ size_t size;
+ void *buf;
+ size_t *rsize;
+{
+ int attempts = 0;
+ struct mvmeprom_netfread nfr;
+ register struct bugdev_softc *pp = (struct bugdev_softc *)devdata;
+
+retry:
+
+ attempts+=1;
+
+ nfr.clun = pp->clun;
+ nfr.dlun = pp->dlun;
+ nfr.status = 0;
+ nfr.addr = buf;
+ nfr.bytes = 0;
+ nfr.blk = nblk;
+ nfr.timeout = NFR_TIMEOUT;
+#ifdef DEBUG
+ printf("net_strategy: size=%d blk=%d buf=%x\n", size, nblk, buf);
+ printf("ctrl %d dev %d\n", nfr.clun, nfr.dlun);
+#endif
+ mvmeprom_netfread(&nfr);
+
+#ifdef BUG_DEBUG
+ io = bugpci_conf_read(0, 14, 0, 0x10) & ~0xf;
+ mem = bugpci_conf_read(0, 14, 0, 0x14) & ~0xf;
+
+ printf(" IO @ %x\n", io);
+ printf("MEM @ %x\n", mem);
+
+#define PRINT_REG(regname, x) printf("%s = 0x%x\n", regname, md_swap_long(*(unsigned *)(io + x)))
+
+ PRINT_REG("CSR0", 0x00);
+ PRINT_REG("CSR1", 0x08);
+ PRINT_REG("CSR2", 0x10);
+ PRINT_REG("CSR3", 0x18);
+ PRINT_REG("CSR4", 0x20);
+ PRINT_REG("CSR5", 0x28);
+ PRINT_REG("CSR6", 0x30);
+ PRINT_REG("CSR7", 0x38);
+ PRINT_REG("CSR8", 0x40);
+ PRINT_REG("CSR9", 0x48);
+ PRINT_REG("CSR10", 0x50);
+ PRINT_REG("CSR11", 0x58);
+ PRINT_REG("CSR12", 0x60);
+ PRINT_REG("CSR13", 0x68);
+ PRINT_REG("CSR14", 0x70);
+ PRINT_REG("CSR15", 0x78);
+#endif
+ if (rsize) {
+ *rsize = nfr.bytes;
+ }
+#ifdef DEBUG
+ printf("rsize %d status %x\n", *rsize, nfr.status);
+#endif
+
+ if (nfr.status)
+ if (attempts < 10)
+ goto retry;
+ else
+ return (EIO);
+ return (0);
+}
+
+int
+net_open(struct open_file *f, ...)
+{
+ va_list ap;
+ struct mvmeprom_netfopen nfo;
+ register struct bugdev_softc *pp = (struct bugdev_softc *)f->f_devdata;
+ char *filename;
+ short nfoerr = 0;
+ va_start(ap, f);
+ filename = va_arg(ap, char *);
+ va_end(ap);
+
+#ifdef DEBUG
+ printf("net_open: using mvmebug ctrl %d dev %d, filename: %s\n", pp->clun, pp->dlun, filename);
+#endif
+ nfo.clun = pp->clun;
+ nfo.dlun = pp->dlun;
+ nfo.status = 0;
+ strcpy(nfo.filename, filename);
+ /* .NETFOPN syscall */
+ mvmeprom_netfopen(&nfo);
+
+#ifdef DEBUG
+ if (nfo.status) {
+ nfoerr = nfo.status;
+ printf("net_open: ci err = 0x%x, cd err = 0x%x\n", ((nfoerr >> 8) & 0x0F), (nfoerr & 0x0F));
+ }
+#endif
+ return (nfo.status);
+}
+
+int
+net_close(f)
+ struct open_file *f;
+{
+ return (EIO);
+}
+
+int
+net_ioctl(f, cmd, data)
+ struct open_file *f;
+ u_long cmd;
+ void *data;
+{
+ return (EIO);
+}
+
+int
+tape_open(struct open_file *f, ...)
+{
+ va_list ap;
+ int error = 0;
+ int part;
+ struct mvmeprom_dskio *ti;
+ char *fname; /* partition number, i.e. "1" */
+
+ va_start(ap, f);
+ fname = va_arg(ap, char *);
+ va_end(ap);
+
+ /*
+ * Set the tape segment number to the one indicated
+ * by the single digit fname passed in above.
+ */
+ if ((fname[0] < '0') && (fname[0] > '9')) {
+ return ENOENT;
+ }
+ part = fname[0] - '0';
+ fname = NULL;
+
+ /*
+ * Setup our part of the saioreq.
+ * (determines what gets opened)
+ */
+ ti = &tape_ioreq;
+ bzero((caddr_t)ti, sizeof(*ti));
+
+ ti->ctrl_lun = bugargs.ctrl_lun;
+ ti->dev_lun = bugargs.dev_lun;
+ ti->status = 0;
+ ti->pbuffer = NULL;
+ ti->blk_num = part;
+ ti->blk_cnt = 0;
+ ti->flag = 0;
+ ti->addr_mod = 0;
+
+ f->f_devdata = ti;
+
+ return (0);
+}
+
+int
+tape_close(f)
+ struct open_file *f;
+{
+ struct mvmeprom_dskio *ti;
+
+
+ ti = f->f_devdata;
+ f->f_devdata = NULL;
+ return 0;
+}
+
+#define MVMEPROM_SCALE (512/MVMEPROM_BLOCK_SIZE)
+
+int
+tape_strategy(devdata, flag, dblk, size, buf, rsize)
+ void *devdata;
+ int flag;
+ daddr_t dblk;
+ size_t size;
+ void *buf;
+ size_t *rsize;
+{
+ struct mvmeprom_dskio *ti;
+ int ret;
+
+ ti = devdata;
+
+ if (flag != F_READ)
+ return(EROFS);
+
+ ti->status = 0;
+ ti->pbuffer = buf;
+ /* don't change block #, set in open */
+ ti->blk_cnt = size / (512 / MVMEPROM_SCALE);
+
+ ret = mvmeprom_diskrd(ti);
+
+ if (ret != 0)
+ return (EIO);
+
+ *rsize = (ti->blk_cnt / MVMEPROM_SCALE) * 512;
+ ti->flag |= IGNORE_FILENUM; /* ignore next time */
+
+ return (0);
+}
+
+int
+tape_ioctl(f, cmd, data)
+ struct open_file *f;
+ u_long cmd;
+ void *data;
+{
+ return EIO;
+}
+
+
diff --git a/sys/arch/mvmeppc/stand/libsa/cache.c b/sys/arch/mvmeppc/stand/libsa/cache.c
new file mode 100644
index 00000000000..7c6f8b4de97
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/libsa/cache.c
@@ -0,0 +1,23 @@
+/* $OpenBSD: cache.c,v 1.1 2001/06/26 21:58:07 smurph Exp $ */
+#define CACHELINESIZE 32 /* For now XXX */
+
+void
+syncicache(from, len)
+ void *from;
+ int len;
+{
+ int l = len;
+ void *p = from;
+
+ do {
+ asm volatile ("dcbf %1,%0" :: "r"(p), "r"(0));
+ p += CACHELINESIZE;
+ } while ((l -= CACHELINESIZE) > 0);
+ asm volatile ("sync");
+ do {
+ asm volatile ("icbi %1,%0" :: "r"(from), "r"(0));
+ from += CACHELINESIZE;
+ } while ((len -= CACHELINESIZE) > 0);
+ asm volatile ("isync");
+}
+
diff --git a/sys/arch/mvmeppc/stand/libsa/clock.c b/sys/arch/mvmeppc/stand/libsa/clock.c
new file mode 100644
index 00000000000..c9ebce75fa9
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/libsa/clock.c
@@ -0,0 +1,63 @@
+
+#include <sys/types.h>
+#include <machine/prom.h>
+
+#include "stand.h"
+#include "libsa.h"
+
+/*
+ * BCD to decimal and decimal to BCD.
+ */
+#define FROMBCD(x) (((x) >> 4) * 10 + ((x) & 0xf))
+#define TOBCD(x) (((x) / 10 * 16) + ((x) % 10))
+
+#define SECDAY (24 * 60 * 60)
+#define SECYR (SECDAY * 365)
+#define LEAPYEAR(y) (((y) & 3) == 0)
+#define YEAR0 68
+
+
+/*
+ * This code is defunct after 2068.
+ * Will Unix still be here then??
+ */
+const short dayyr[12] =
+{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
+
+static u_long
+chiptotime(sec, min, hour, day, mon, year)
+ register int sec, min, hour, day, mon, year;
+{
+ register int days, yr;
+
+ sec = FROMBCD(sec);
+ min = FROMBCD(min);
+ hour = FROMBCD(hour);
+ day = FROMBCD(day);
+ mon = FROMBCD(mon);
+ year = FROMBCD(year) + YEAR0;
+ if (year < 70)
+ year = 70;
+
+ /* simple sanity checks */
+ if (year < 70 || mon < 1 || mon > 12 || day < 1 || day > 31)
+ return (0);
+ days = 0;
+ for (yr = 70; yr < year; yr++)
+ days += LEAPYEAR(yr) ? 366 : 365;
+ days += dayyr[mon - 1] + day - 1;
+ if (LEAPYEAR(yr) && mon > 2)
+ days++;
+ /* now have days since Jan 1, 1970; the rest is easy... */
+ return (days * SECDAY + hour * 3600 + min * 60 + sec);
+}
+
+time_t
+getsecs()
+{
+ struct mvmeprom_time m;
+
+ mvmeprom_rtc_rd(&m);
+ return (chiptotime(m.sec_BCD, m.min_BCD, m.hour_BCD, m.day_BCD,
+ m.month_BCD, m.year_BCD));
+}
diff --git a/sys/arch/mvmeppc/stand/libsa/conf.c b/sys/arch/mvmeppc/stand/libsa/conf.c
new file mode 100644
index 00000000000..e238235cd86
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/libsa/conf.c
@@ -0,0 +1,33 @@
+/* $OpenBSD: conf.c,v 1.1 2001/06/26 21:58:07 smurph Exp $ */
+
+#include <sys/types.h>
+#include <machine/prom.h>
+
+#include <stand.h>
+#include <ufs.h>
+#include "tftpfs.h"
+#include "rawfs.h"
+#include "libsa.h"
+
+struct fs_ops ufs_file_system[] = {
+ { ufs_open, ufs_close, ufs_read, ufs_write, ufs_seek, ufs_stat },
+};
+
+struct fs_ops tftp_file_system[] = {
+ { tftpfs_open, tftpfs_close, tftpfs_read, tftpfs_write, tftpfs_seek, tftpfs_stat },
+};
+
+struct fs_ops raw_file_system[] = {
+ { rawfs_open, rawfs_close, rawfs_read, rawfs_write, rawfs_seek, rawfs_stat },
+};
+
+int nfsys = 1; /* devopen will choose the correct one. */
+
+struct devsw devsw[] = {
+ { "dsk", dsk_strategy, dsk_open, dsk_close, dsk_ioctl },
+ { "net", net_strategy, net_open, net_close, net_ioctl },
+ { "tape", tape_strategy, tape_open, tape_close, tape_ioctl },
+};
+
+int ndevs = (sizeof(devsw)/sizeof(devsw[0]));
+
diff --git a/sys/arch/mvmeppc/stand/libsa/exec_mvme.c b/sys/arch/mvmeppc/stand/libsa/exec_mvme.c
new file mode 100644
index 00000000000..05b4269874d
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/libsa/exec_mvme.c
@@ -0,0 +1,260 @@
+
+/*-
+ * Copyright (c) 1982, 1986, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)boot.c 8.1 (Berkeley) 6/10/93
+ */
+
+#include <sys/param.h>
+#include <sys/reboot.h>
+#include <machine/prom.h>
+#include <a.out.h>
+#include <sys/exec_elf.h>
+
+#include "stand.h"
+#include "libsa.h"
+
+#define RB_NOSYM 0x400
+#define RB_MULTI 0x4000
+#define RB_EXTRA 0x8000
+#define RB_ASKKERN 0x0010 /* ask kernel name */
+
+vaddr_t ssym, esym;
+
+int
+load_elf(fd, elf, entryp, esymp)
+ int fd;
+ Elf32_Ehdr *elf;
+ u_int32_t *entryp;
+ void **esymp;
+
+{
+ Elf32_Shdr *shpp;
+ Elf32_Off off;
+ Elf32_Ehdr *elfp;
+ void *addr;
+ size_t size;
+ int n, havesyms, i, first = 1;
+ size_t sz;
+
+ void *maxp = 0; /* correct type? */
+
+ /*
+ * Don't display load address for ELF; it's encoded in
+ * each section.
+ */
+
+ for (i = 0; i < elf->e_phnum; i++) {
+ Elf32_Phdr phdr;
+ (void)lseek(fd, elf->e_phoff + sizeof(phdr) * i, SEEK_SET);
+ if (read(fd, (void *)&phdr, sizeof(phdr)) != sizeof(phdr)) {
+ printf("read phdr: %s\n", strerror(errno));
+ return (1);
+ }
+ if (phdr.p_type != PT_LOAD ||
+ (phdr.p_flags & (PF_W|PF_X)) == 0)
+ continue;
+
+ /* Read in segment. */
+ printf("%s%lu@0x%lx", first ? "" : "+", phdr.p_filesz,
+ (u_long)phdr.p_vaddr);
+ (void)lseek(fd, phdr.p_offset, SEEK_SET);
+ maxp = maxp > (void *)(phdr.p_vaddr+ phdr.p_memsz) ?
+ maxp : (void *)(phdr.p_vaddr+ phdr.p_memsz);
+ if (read(fd, (void *)phdr.p_vaddr, phdr.p_filesz) !=
+ phdr.p_filesz) {
+ printf("read segment: %s\n", strerror(errno));
+ return (1);
+ }
+ syncicache((void *)phdr.p_vaddr, phdr.p_filesz);
+
+ /* Zero BSS. */
+ if (phdr.p_filesz < phdr.p_memsz) {
+ printf("+%lu@0x%lx", phdr.p_memsz - phdr.p_filesz,
+ (u_long)(phdr.p_vaddr + phdr.p_filesz));
+ bzero((void *)(phdr.p_vaddr + phdr.p_filesz),
+ phdr.p_memsz - phdr.p_filesz);
+ }
+ first = 0;
+ }
+
+#if 1
+ /*
+ * Copy the ELF and section headers.
+ */
+ maxp = (void *)roundup((long)maxp, sizeof(long));
+ (void *)ssym = elfp = maxp; /* mark the start of the symbol table */
+
+ maxp += sizeof(Elf_Ehdr);
+
+ if (lseek(fd, elf->e_shoff, SEEK_SET) == -1) {
+ printf("lseek section headers: %s\n", strerror(errno));
+ return 1;
+ }
+ sz = elf->e_shnum * sizeof(Elf_Shdr);
+
+ shpp = maxp;
+ maxp += roundup(sz, sizeof(long));
+
+ if (read(fd, shpp, sz) != sz) {
+ printf("read section headers: %s\n", strerror(errno));
+ return 1;
+ }
+ /*
+ * Now load the symbol sections themselves. Make sure the
+ * sections are aligned. Don't bother with string tables if
+ * there are no symbol sections.
+ */
+ off = roundup((sizeof(Elf_Ehdr) + sz), sizeof(long));
+
+ for (havesyms = i = 0; i < elf->e_shnum; i++)
+ if (shpp[i].sh_type == SHT_SYMTAB)
+ havesyms = 1;
+ if (!havesyms)
+ goto no_syms;
+
+ for (first = 1, i = 0; i < elf->e_shnum; i++) {
+ if (shpp[i].sh_type == SHT_SYMTAB ||
+ shpp[i].sh_type == SHT_STRTAB) {
+ printf("%s%ld", first ? " [" : "+",
+ (u_long)shpp[i].sh_size);
+ if (lseek(fd, shpp[i].sh_offset, SEEK_SET) == -1) {
+ printf("lseek symbols: %s\n", strerror(errno));
+ return 1;
+ }
+ if (read(fd, maxp, shpp[i].sh_size) != shpp[i].sh_size) {
+ printf("read symbols: %s\n", strerror(errno));
+ return 1;
+ }
+ maxp += roundup(shpp[i].sh_size, sizeof(long));
+ shpp[i].sh_offset = off;
+ off += roundup(shpp[i].sh_size, sizeof(long));
+ first = 0;
+ }
+ }
+ if (first == 0)
+ printf("]");
+
+ /*
+ * Frob the copied ELF header to give information relative
+ * to elfp.
+ */
+ elf->e_phoff = 0;
+ elf->e_shoff = sizeof(Elf_Ehdr);
+ elf->e_phentsize = 0;
+ elf->e_phnum = 0;
+ bcopy(elf, elfp, sizeof(*elf));
+
+#endif
+no_syms:
+ *esymp = (void *)esym = maxp; /* mark end of symbol table */
+ *entryp = elf->e_entry;
+ printf(" \n");
+ return (0);
+}
+
+/*ARGSUSED*/
+void
+exec_mvme(file, flag)
+char *file;
+int flag;
+{
+ char *loadaddr;
+ register int io;
+ Elf32_Ehdr hdr;
+ struct exec x;
+ int cc, magic;
+ void (*entry)();
+ void *esym;
+ register char *cp;
+ register int *ip;
+ int n;
+ int bootdev;
+ int rval = 1;
+ char dummy[]="\0";
+
+ if (flag & RB_EXTRA) {
+ printf("exec_mvme: file=%s flag=0x%x cputyp=%x\n", file, flag, bugargs.cputyp);
+ }
+
+ io = open(file, 0);
+ if (io < 0)
+ return;
+
+ printf("Booting %s\n", file);
+ /*
+ * Read in the exec header, and validate it.
+ */
+ if (read(io, &hdr, sizeof(hdr)) != sizeof(hdr)) {
+ printf("read header: %s\n", strerror(errno));
+ goto shread;
+ }
+
+ if (IS_ELF(hdr)) {
+ rval = load_elf(io, &hdr, &entry, &esym);
+ } else {
+ printf("unknown executable format\n");
+ errno = EFTYPE;
+ goto closeout;
+ }
+ if (rval)
+ goto closeout;
+
+ close(io);
+
+ printf("Start @ 0x%x ...\n", (int)entry);
+ printf("Controler Address @ %x ...\n", bugargs.ctrl_addr);
+ if (flag & RB_HALT) mvmeprom_return();
+
+ bootdev = (bugargs.ctrl_lun << 8) | (bugargs.dev_lun & 0xFF);
+
+/* arguments to start
+ * r1 - stack provided by firmware/bootloader
+ * r3 - unused
+ * r4 - unused
+ * r5 - firmware pointer (NULL for PPC1bug)
+ * r6 - arg list
+ * r7 - arg list length
+ * r8 - end of symbol table
+ */
+/* r3 r4 r5 r6 r7 r8 */
+ (*entry)(bugargs.ctrl_addr, bootdev, NULL, &dummy, 0, esym);
+ printf("exec: kernel returned!\n");
+ return;
+
+shread:
+ printf("exec: short read\n");
+ errno = EIO;
+closeout:
+ close(io);
+ return;
+}
diff --git a/sys/arch/mvmeppc/stand/libsa/libsa.h b/sys/arch/mvmeppc/stand/libsa/libsa.h
new file mode 100644
index 00000000000..d53d2f994f8
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/libsa/libsa.h
@@ -0,0 +1,31 @@
+/*
+ * libsa prototypes
+ */
+
+#include "libbug.h"
+
+/* bugdev.c */
+int dsk_open __P((struct open_file *, ...));
+int dsk_close __P((struct open_file *));
+int dsk_ioctl __P((struct open_file *, u_long, void *));
+int dsk_strategy __P((void *, int, daddr_t, size_t, void *, size_t *));
+int net_open __P((struct open_file *, ...));
+int net_close __P((struct open_file *));
+int net_ioctl __P((struct open_file *, u_long, void *));
+int net_strategy __P((void *, int, daddr_t, size_t, void *, size_t *));
+int tape_open __P((struct open_file *, ...));
+int tape_close __P((struct open_file *));
+int tape_ioctl __P((struct open_file *, u_long, void *));
+int tape_strategy __P((void *, int, daddr_t, size_t, void *, size_t *));
+
+/* exec_mvme.c */
+void exec_mvme __P((char *, int));
+
+/* parse_args.c */
+int parse_args __P((char **, int *));
+
+#define BUGDEV_DISK 0
+#define BUGDEV_NET 1
+#define BUGDEV_TAPE 2
+
+extern int bootdev_type;
diff --git a/sys/arch/mvmeppc/stand/libsa/parse_args.c b/sys/arch/mvmeppc/stand/libsa/parse_args.c
new file mode 100644
index 00000000000..86cb34bbf39
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/libsa/parse_args.c
@@ -0,0 +1,121 @@
+/* $OpenBSD: parse_args.c,v 1.1 2001/06/26 21:58:07 smurph Exp $ */
+
+/*-
+ * Copyright (c) 1995 Theo de Raadt
+ *
+ * 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 under OpenBSD by
+ * Theo de Raadt for Willowglen Singapore.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <sys/param.h>
+#include <sys/reboot.h>
+#include <machine/prom.h>
+#include <a.out.h>
+
+#include "stand.h"
+#include "libsa.h"
+
+#define KERNEL_NAME "bsd"
+#define RB_NOSYM 0x400
+
+#define RB_AUTOBOOT 0 /* flags for system auto-booting itself */
+
+#if 0
+#define RB_ASKNAME 0x0001 /* ask for file name to reboot from */
+#define RB_SINGLE 0x0002 /* reboot to single user only */
+#define RB_NOSYNC 0x0004 /* dont sync before reboot */
+#define RB_HALT 0x0008 /* don't reboot, just halt */
+#define RB_INITNAME 0x0010 /* name given for /etc/init (unused) */
+#define RB_DFLTROOT 0x0020 /* use compiled-in rootdev */
+#define RB_KDB 0x0040 /* give control to kernel debugger */
+#define RB_RDONLY 0x0080 /* mount root fs read-only */
+#define RB_DUMP 0x0100 /* dump kernel memory before reboot */
+#define RB_MINIROOT 0x0200 /* mini-root present in memory at boot time */
+#define RB_CONFIG 0x0400 /* change configured devices */
+#define RB_TIMEBAD 0x0800 /* don't call resettodr() in boot() */
+#define RB_POWERDOWN 0x1000 /* attempt to power down machine */
+#define RB_SERCONS 0x2000 /* use serial console if available */
+#endif
+
+struct flags {
+ char c;
+ short bit;
+} bf[] = {
+ { 'a', RB_ASKNAME }, /* ask root */
+ { 'b', RB_HALT },
+ { 'c', RB_CONFIG },
+ { 'd', RB_KDB },
+ { 'e', 0x4000 }, /* spin slave cpus */
+ { 'f', 0x0010 }, /* ask kernel name */
+ { 'm', RB_MINIROOT },
+ { 'r', RB_DFLTROOT },
+ { 's', RB_SINGLE },
+ { 'x', 0x8000 }, /* extra boot debug */
+ { 'y', RB_NOSYM },
+};
+
+int
+parse_args(filep, flagp)
+
+char **filep;
+int *flagp;
+
+{
+ char *name = KERNEL_NAME, *ptr;
+ int i, howto = 0;
+ char c;
+
+ if (bugargs.arg_start != bugargs.arg_end) {
+ ptr = bugargs.arg_start;
+ while (c = *ptr) {
+ while (c == ' ')
+ c = *++ptr;
+ if (c == '\0')
+ return (0);
+ if (c != '-') {
+ name = ptr;
+ while ((c = *++ptr) && c != ' ')
+ ;
+ if (c)
+ *ptr++ = 0;
+ continue;
+ }
+ while ((c = *++ptr) && c != ' ') {
+ if (c == 'q')
+ return (1);
+ for (i = 0; i < sizeof(bf)/sizeof(bf[0]); i++)
+ if (bf[i].c == c) {
+ howto |= bf[i].bit;
+ }
+ }
+ }
+ }
+ *flagp = howto;
+ *filep = name;
+ return (0);
+}
diff --git a/sys/arch/mvmeppc/stand/libsa/rawfs.c b/sys/arch/mvmeppc/stand/libsa/rawfs.c
new file mode 100644
index 00000000000..3784175b92d
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/libsa/rawfs.c
@@ -0,0 +1,178 @@
+/* $OpenBSD: rawfs.c,v 1.1 2001/06/26 21:58:08 smurph Exp $ */
+
+/*
+ * Copyright (c) 1995 Gordon W. Ross
+ * 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.
+ * 4. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Gordon W. Ross
+ *
+ * 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.
+ */
+
+/*
+ * Raw file system - for stream devices like tapes.
+ * No random access, only sequential read allowed.
+ * This exists only to allow upper level code to be
+ * shielded from the fact that the device must be
+ * read only with whole block position and size.
+ */
+
+#include <sys/param.h>
+#include <stand.h>
+#include <rawfs.h>
+
+#define RAWFS_BSIZE 512
+
+/*
+ * In-core open file.
+ */
+struct cfile {
+ daddr_t fs_nextblk; /* block number to read next */
+ int fs_len; /* amount left in f_buf */
+ char * fs_ptr; /* read pointer into f_buf */
+ char fs_buf[RAWFS_BSIZE];
+};
+
+static int
+rawfs_get_block __P((struct open_file *));
+
+int rawfs_open(path, f)
+ char *path;
+ struct open_file *f;
+{
+ struct cfile *fs;
+
+ /*
+ * The actual PROM driver has already been opened.
+ * Just allocate the I/O buffer, etc.
+ */
+ fs = alloc(sizeof(struct cfile));
+ fs->fs_nextblk = 0;
+ fs->fs_len = 0;
+ fs->fs_ptr = fs->fs_buf;
+
+ f->f_fsdata = fs;
+ return (0);
+}
+
+int rawfs_close(f)
+ struct open_file *f;
+{
+ struct cfile *fs;
+
+ fs = (struct cfile *) f->f_fsdata;
+ f->f_fsdata = (void *)0;
+
+ if (fs != (struct cfile *)0)
+ free(fs, sizeof(*fs));
+
+ return (0);
+}
+
+int rawfs_read(f, start, size, resid)
+ struct open_file *f;
+ void *start;
+ u_int size;
+ u_int *resid;
+{
+ struct cfile *fs = (struct cfile *)f->f_fsdata;
+ char *addr = start;
+ int error = 0;
+ size_t csize;
+
+ while (size != 0) {
+
+ if (fs->fs_len == 0)
+ if ((error = rawfs_get_block(f)) != 0)
+ break;
+
+ if (fs->fs_len <= 0)
+ break; /* EOF */
+
+ csize = size;
+ if (csize > fs->fs_len)
+ csize = fs->fs_len;
+
+ bcopy(fs->fs_ptr, addr, csize);
+ fs->fs_ptr += csize;
+ fs->fs_len -= csize;
+ addr += csize;
+ size -= csize;
+ }
+ if (resid)
+ *resid = size;
+ return (error);
+}
+
+int rawfs_write(f, start, size, resid)
+ struct open_file *f;
+ void *start;
+ size_t size;
+ size_t *resid; /* out */
+{
+ return (EROFS);
+}
+
+off_t rawfs_seek(f, offset, where)
+ struct open_file *f;
+ off_t offset;
+ int where;
+{
+ return (EFTYPE);
+}
+
+int rawfs_stat(f, sb)
+ struct open_file *f;
+ struct stat *sb;
+{
+ return (EFTYPE);
+}
+
+
+/*
+ * Read a block from the underlying stream device
+ * (In our case, a tape drive.)
+ */
+static int
+rawfs_get_block(f)
+ struct open_file *f;
+{
+ struct cfile *fs;
+ int error, len;
+
+ fs = (struct cfile *)f->f_fsdata;
+ fs->fs_ptr = fs->fs_buf;
+
+ twiddle();
+ error = f->f_dev->dv_strategy(f->f_devdata, F_READ,
+ fs->fs_nextblk, RAWFS_BSIZE, fs->fs_buf, &len);
+
+ if (!error) {
+ fs->fs_len = len;
+ fs->fs_nextblk += (RAWFS_BSIZE / DEV_BSIZE);
+ }
+
+ return (error);
+}
+
diff --git a/sys/arch/mvmeppc/stand/libsa/rawfs.h b/sys/arch/mvmeppc/stand/libsa/rawfs.h
new file mode 100644
index 00000000000..cf29be5800b
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/libsa/rawfs.h
@@ -0,0 +1,15 @@
+/* $OpenBSD: rawfs.h,v 1.1 2001/06/26 21:58:08 smurph Exp $ */
+
+/*
+ * Raw file system - for stream devices like tapes.
+ * No random access, only sequential read allowed.
+ */
+
+int rawfs_open __P((char *path, struct open_file *f));
+int rawfs_close __P((struct open_file *f));
+int rawfs_read __P((struct open_file *f, void *buf,
+ u_int size, u_int *resid));
+int rawfs_write __P((struct open_file *f, void *buf,
+ u_int size, u_int *resid));
+off_t rawfs_seek __P((struct open_file *f, off_t offset, int where));
+int rawfs_stat __P((struct open_file *f, struct stat *sb));
diff --git a/sys/arch/mvmeppc/stand/libsa/tftpfs.c b/sys/arch/mvmeppc/stand/libsa/tftpfs.c
new file mode 100644
index 00000000000..0b2e90759b1
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/libsa/tftpfs.c
@@ -0,0 +1,291 @@
+/* $OpenBSD: tftpfs.c,v 1.1 2001/06/26 21:58:08 smurph Exp $ */
+
+/*-
+ * Copyright (c) 2001 Steve Murphree, Jr.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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.
+ */
+
+/*
+ * TFTP file system.
+ */
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <ufs/ffs/fs.h>
+#include <lib/libkern/libkern.h>
+
+#include "stand.h"
+
+/*
+ * In-core open file.
+ */
+struct tftp_file {
+ char filename[128];
+ off_t f_seekp; /* seek pointer */
+ char *f_buf; /* buffer for data block */
+ off_t f_off; /* index into buffer for data block */
+ daddr_t f_buf_blkno; /* block number of data block */
+ size_t f_buf_size;
+};
+
+#define TFTP_BLOCK_SHIFT 9
+#define TFTP_BLOCK_SIZE (1<<TFTP_BLOCK_SHIFT) /* 512 by tftp convention */
+#define TFTP_BLOCK_NO(x) ((x >> TFTP_BLOCK_SHIFT) + 1)
+#define TFTP_BLOCK_OFF(x) (x % TFTP_BLOCK_SIZE)
+
+static int read_inode __P((ino_t, struct open_file *));
+static int block_map __P((struct open_file *, daddr_t, daddr_t *));
+static int tftp_read_file __P((struct open_file *, char **, size_t *));
+#ifdef COMPAT_UFS
+static void ffs_oldfscompat __P((struct fs *));
+#endif
+
+/*
+ * Read a portion of a file into an internal buffer. Return
+ * the location in the buffer and the amount in the buffer.
+ */
+
+char tftp_buf[TFTP_BLOCK_SIZE]; /* static */
+struct tftp_file tftp_ctrl;
+
+static int
+tftp_read_file(f, buf_p, size_p)
+ struct open_file *f;
+ char **buf_p; /* out */
+ size_t *size_p; /* out */
+{
+ register struct tftp_file *fp = (struct tftp_file *)f->f_fsdata;
+ long off;
+ register daddr_t file_block;
+ size_t block_size;
+ int i, rc;
+
+ off = TFTP_BLOCK_OFF(fp->f_seekp);
+ file_block = TFTP_BLOCK_NO(fp->f_seekp);
+ block_size = TFTP_BLOCK_SIZE;
+
+ if (file_block == fp->f_buf_blkno + 1) {
+ /*
+ * Normal, incremental block transfer.
+ */
+ rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
+ file_block, block_size, fp->f_buf, &fp->f_buf_size);
+ if (rc)
+ return (rc);
+ if (!(file_block % 4)) /* twiddle every 4 blocks */
+ twiddle();
+ fp->f_buf_blkno = file_block;
+ } else if (file_block > fp->f_buf_blkno + 1) {
+ /*
+ * Read ahead to the requested block; If we need
+ * those we skipped, see below.
+ */
+ for (i = (fp->f_buf_blkno + 1); i <= file_block; i++) {
+ rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
+ i, block_size, fp->f_buf, &fp->f_buf_size);
+ if (rc)
+ return (rc);
+ }
+ fp->f_buf_blkno = file_block;
+ } else if (file_block < fp->f_buf_blkno) {
+ /*
+ * Uh oh... We can't rewind. Reopen the file
+ * and start again.
+ */
+ char filename[64];
+ strcpy(filename, fp->filename);
+ tftpfs_close(f);
+ tftpfs_open(filename, f);
+ for (i = 1; i <= file_block; i++) {
+ rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
+ i, block_size, fp->f_buf, &fp->f_buf_size);
+ if (rc)
+ return (rc);
+ }
+ fp->f_buf_blkno = file_block;
+ }
+
+ /*
+ * Return address of byte in buffer corresponding to
+ * offset, and size of remainder of buffer after that
+ * byte.
+ */
+ *buf_p = fp->f_buf + off;
+ *size_p = fp->f_buf_size - off;
+
+ /*
+ * But truncate buffer at end of file.
+ */
+ if (fp->f_buf_size > block_size){
+ twiddle();
+ return(EIO);
+ }
+
+
+ return (0);
+}
+
+/*
+ * Open a file.
+ */
+int
+tftpfs_open(path, f)
+ char *path;
+ struct open_file *f;
+{
+ struct tftp_file *fp;
+ int rc = 0;
+
+ /* locate file system specific data structure and zero it.*/
+ fp = &tftp_ctrl;
+ bzero(fp, sizeof(struct tftp_file));
+ f->f_fsdata = (void *)fp;
+ fp->f_seekp = 0;
+ fp->f_buf = tftp_buf;
+ bzero(fp->f_buf, TFTP_BLOCK_SIZE);
+ fp->f_buf_size = 0;
+
+ strcpy(fp->filename, path);
+
+ if (f->f_dev->dv_open == NULL) {
+ panic("No device open()!");
+ }
+ twiddle();
+ rc = (f->f_dev->dv_open)(f, path);
+ return (rc);
+}
+
+int
+tftpfs_close(f)
+ struct open_file *f;
+{
+ register struct tftp_file *fp = (struct tftp_file *)f->f_fsdata;
+
+ fp->f_buf = (void *)0;
+ f->f_fsdata = (void *)0;
+ (f->f_dev->dv_close)(f);
+ return (0);
+}
+
+/*
+ * Copy a portion of a file into kernel memory.
+ * Cross block boundaries when necessary.
+ */
+int
+tftpfs_read(f, start, size, resid)
+ struct open_file *f;
+ void *start;
+ size_t size;
+ size_t *resid; /* out */
+{
+ register struct tftp_file *fp = (struct tftp_file *)f->f_fsdata;
+ register size_t csize;
+ char *buf;
+ size_t buf_size;
+ int rc = 0;
+ register char *addr = start;
+
+ while (size != 0) {
+ rc = tftp_read_file(f, &buf, &buf_size);
+ if (rc)
+ break;
+
+ csize = size;
+ if (csize > buf_size)
+ csize = buf_size;
+
+ bcopy(buf, addr, csize);
+
+ fp->f_seekp += csize;
+ addr += csize;
+ size -= csize;
+ }
+ if (resid)
+ *resid = size;
+ return (rc);
+}
+
+/*
+ * Not implemented.
+ */
+int
+tftpfs_write(f, start, size, resid)
+ struct open_file *f;
+ void *start;
+ size_t size;
+ size_t *resid; /* out */
+{
+
+ return (EROFS);
+}
+
+/*
+ * We only see forward. We can't rewind.
+ */
+off_t
+tftpfs_seek(f, offset, where)
+ struct open_file *f;
+ off_t offset;
+ int where;
+{
+ register struct tftp_file *fp = (struct tftp_file *)f->f_fsdata;
+
+ switch (where) {
+ case SEEK_SET:
+ fp->f_seekp = offset;
+ break;
+ case SEEK_CUR:
+ fp->f_seekp += offset;
+ break;
+ case SEEK_END:
+ errno = EIO;
+ return (-1);
+ break;
+ default:
+ return (-1);
+ }
+ return (fp->f_seekp);
+}
+
+int
+tftpfs_stat(f, sb)
+ struct open_file *f;
+ struct stat *sb;
+{
+ return EIO;
+}
+
+#ifndef NO_READDIR
+int
+tftpfs_readdir (struct open_file *f, char *name)
+{
+ return EIO;
+}
+#endif
+
diff --git a/sys/arch/mvmeppc/stand/libsa/tftpfs.h b/sys/arch/mvmeppc/stand/libsa/tftpfs.h
new file mode 100644
index 00000000000..f8ea6c53c0a
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/libsa/tftpfs.h
@@ -0,0 +1,43 @@
+/* $OpenBSD: tftpfs.h,v 1.1 2001/06/26 21:58:08 smurph Exp $ */
+
+/*-
+ * Copyright (c) 2001 Steve Murphree, Jr.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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.
+ */
+
+int tftpfs_open __P((char *path, struct open_file *f));
+int tftpfs_close __P((struct open_file *f));
+int tftpfs_read __P((struct open_file *f, void *buf,
+ size_t size, size_t *resid));
+int tftpfs_write __P((struct open_file *f, void *buf,
+ size_t size, size_t *resid));
+off_t tftpfs_seek __P((struct open_file *f, off_t offset, int where));
+int tftpfs_stat __P((struct open_file *f, struct stat *sb));
+#ifndef NO_READDIR
+int tftpfs_readdir __P((struct open_file *f, char *name));
+#endif
diff --git a/sys/arch/mvmeppc/stand/libz/Makefile b/sys/arch/mvmeppc/stand/libz/Makefile
new file mode 100644
index 00000000000..5dc7476587e
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/libz/Makefile
@@ -0,0 +1,8 @@
+# $OpenBSD: Makefile,v 1.1 2001/06/26 21:58:08 smurph Exp $
+
+S=${.CURDIR}/../../../..
+ZDST=${.OBJDIR}
+
+.PATH: ${S}/lib/libz
+
+.include "${S}/lib/libz/Makefile"
diff --git a/sys/arch/mvmeppc/stand/libz/Makefile.inc b/sys/arch/mvmeppc/stand/libz/Makefile.inc
new file mode 100644
index 00000000000..c1d26bc509e
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/libz/Makefile.inc
@@ -0,0 +1,14 @@
+# $OpenBSD: Makefile.inc,v 1.1 2001/06/26 21:58:09 smurph Exp $
+
+LIB_Z_DIR=${S}/arch/mvmeppc/stand/libz
+
+LIBZ_DIR!= cd ${LIB_Z_DIR}; \
+ printf "xxx:\n\techo \$${.OBJDIR}\n" | ${MAKE} -r -s -f - xxx
+
+LIBZ=${LIBZ_DIR}/libz.a
+
+$(LIBZ): .NOTMAIN __always_make_libz
+ @echo making sure the libz is up to date...
+ @(cd ${LIB_Z_DIR}; ${MAKE} "XCFLAGS=${CFLAGS}")
+
+__always_make_libz: .NOTMAIN
diff --git a/sys/arch/mvmeppc/stand/tftpboot/Makefile b/sys/arch/mvmeppc/stand/tftpboot/Makefile
new file mode 100644
index 00000000000..7c248c806bf
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/tftpboot/Makefile
@@ -0,0 +1,45 @@
+# $OpenBSD: Makefile,v 1.1 2001/06/26 21:58:09 smurph Exp $
+
+SIZE?= size
+STRIP?= strip
+
+S= ${.CURDIR}/../../../..
+DEFS= -DSUN_BOOTPARAMS
+#-DNETIF_DEBUG
+INCPATH=-I${.CURDIR} -I${.CURDIR}/../libsa -I${.CURDIR}/../libbug \
+ -I${S} -I${S}/lib/libsa
+CFLAGS=-O2 ${DEFS} ${INCPATH} ${COPTS}
+CLEANFILES+=tftpboot tftpboot.bin
+
+.include "${S}/arch/mvmeppc/stand/bugcrt/Makefile.inc"
+.include "${S}/arch/mvmeppc/stand/libbug/Makefile.inc"
+.include "${S}/arch/mvmeppc/stand/libsa/Makefile.inc"
+.include "${S}/arch/mvmeppc/stand/libz/Makefile.inc"
+
+SRCS= boot.c version.c
+#SRCS+= if_ie.c
+#SRCS+= if_le.c
+OBJS= ${SRCS:S/.c/.o/g}
+LIBS= ${LIBSA} ${LIBBUG} ${LIBZ} ${LIBGCC}
+LDFLAGS+= -s -X -N -Ttext ${STAGE1_RELOC} -e _start
+#LDFLAGS+= -nostdlib -s -N -Ttext ${RELOC}
+
+all: tftpboot.bin
+
+tftpboot: ${OBJS} ${SINGLE} ${LIBS}
+ ${LD} ${LDFLAGS} \
+ ${SINGLE} ${OBJS} ${LIBS} -o $@
+# @${SIZE} $@
+
+tftpboot.bin: tftpboot
+ ${STRIP} tftpboot
+ dd ibs=96 skip=1 if=tftpboot of=$@
+# dd ibs=38 skip=1 if=tftpboot of=$@
+ chown ${LIBOWN}.${LIBGRP} tftpboot.bin
+ chmod ${LIBMODE} tftpboot.bin
+
+install:
+ ${INSTALL} ${INSTALL_COPY} -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \
+ tftpboot.bin ${DESTDIR}${MDEC_DIR}/tftpboot
+
+.include <bsd.prog.mk>
diff --git a/sys/arch/mvmeppc/stand/tftpboot/boot.c b/sys/arch/mvmeppc/stand/tftpboot/boot.c
new file mode 100644
index 00000000000..004be9af878
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/tftpboot/boot.c
@@ -0,0 +1,120 @@
+/* $OpenBSD: boot.c,v 1.1 2001/06/26 21:58:10 smurph Exp $ */
+/*-
+ * Copyright (c) 1995 Theo de Raadt
+ * Copyright (c) 2001 Steve Murphree, Jr.
+ * 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 Theo de Raadt
+ * 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.
+ *
+ * Copyright (c) 1982, 1986, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)boot.c 8.1 (Berkeley) 6/10/93
+ */
+
+#include <sys/param.h>
+#include <sys/reboot.h>
+#include <machine/prom.h>
+
+#include "stand.h"
+#include "libsa.h"
+
+
+/*
+ * Boot device is derived from ROM provided information.
+ */
+#define LOADADDR 0x10000
+
+extern char *version;
+char line[80];
+
+main()
+{
+ char *cp, *file;
+ int ask = 0, howto, ret;
+
+ /* cycle in the correct args */
+ bugargs.arg_start = bugargs.nbarg_start;
+ bugargs.arg_end = bugargs.nbarg_end;
+ *bugargs.arg_end = 0; /* ensure */
+
+ bootdev_type = BUGDEV_NET;
+
+ printf("\n>> OpenBSD/mvmeppc netboot [%s]\n", version);
+
+ ret = parse_args(&file, &howto);
+
+ for (;;) {
+ if (ask) {
+ printf("boot: ");
+ gets(line);
+ if (line[0]) {
+ bugargs.arg_start = line;
+ cp = line;
+ while (cp < (line + sizeof(line) - 1) && *cp)
+ cp++;
+ bugargs.arg_end = cp;
+ ret =parse_args(&file, &howto);
+ }
+ }
+ if (ret) {
+ printf("boot: -q returning to MVME-Bug\n");
+ break;
+ }
+ exec_mvme(file, howto);
+ printf("boot: %s: %s\n", file, strerror(errno));
+ ask = 1;
+ }
+}
diff --git a/sys/arch/mvmeppc/stand/tftpboot/version.c b/sys/arch/mvmeppc/stand/tftpboot/version.c
new file mode 100644
index 00000000000..6d76885e63d
--- /dev/null
+++ b/sys/arch/mvmeppc/stand/tftpboot/version.c
@@ -0,0 +1,8 @@
+/* $OpenBSD: version.c,v 1.1 2001/06/26 21:58:10 smurph Exp $ */
+
+/*
+ * make a random change to this file when you want the bootblock
+ * revision to increase. like change this q to an x, or something.
+ */
+
+char *version = "$Revision: 1.1 $";