summaryrefslogtreecommitdiff
path: root/sys/arch/mvmeppc/stand/libsa
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/mvmeppc/stand/libsa')
-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
15 files changed, 1944 insertions, 0 deletions
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