diff options
Diffstat (limited to 'sys/arch/mvmeppc/stand/libsa')
-rw-r--r-- | sys/arch/mvmeppc/stand/libsa/Makefile | 48 | ||||
-rw-r--r-- | sys/arch/mvmeppc/stand/libsa/Makefile.inc | 15 | ||||
-rw-r--r-- | sys/arch/mvmeppc/stand/libsa/SRT0.S | 90 | ||||
-rw-r--r-- | sys/arch/mvmeppc/stand/libsa/SRT1.c | 124 | ||||
-rw-r--r-- | sys/arch/mvmeppc/stand/libsa/bugdev.c | 609 | ||||
-rw-r--r-- | sys/arch/mvmeppc/stand/libsa/cache.c | 23 | ||||
-rw-r--r-- | sys/arch/mvmeppc/stand/libsa/clock.c | 63 | ||||
-rw-r--r-- | sys/arch/mvmeppc/stand/libsa/conf.c | 33 | ||||
-rw-r--r-- | sys/arch/mvmeppc/stand/libsa/exec_mvme.c | 260 | ||||
-rw-r--r-- | sys/arch/mvmeppc/stand/libsa/libsa.h | 31 | ||||
-rw-r--r-- | sys/arch/mvmeppc/stand/libsa/parse_args.c | 121 | ||||
-rw-r--r-- | sys/arch/mvmeppc/stand/libsa/rawfs.c | 178 | ||||
-rw-r--r-- | sys/arch/mvmeppc/stand/libsa/rawfs.h | 15 | ||||
-rw-r--r-- | sys/arch/mvmeppc/stand/libsa/tftpfs.c | 291 | ||||
-rw-r--r-- | sys/arch/mvmeppc/stand/libsa/tftpfs.h | 43 |
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 |