diff --git a/sys/arch/mvme68k/stand/libsa/bugdev.c b/sys/arch/mvme68k/stand/libsa/bugdev.c new file mode 100644 index 000000000000..424789edd40a --- /dev/null +++ b/sys/arch/mvme68k/stand/libsa/bugdev.c @@ -0,0 +1,238 @@ +/* $NetBSD: bugdev.c,v 1.1 1996/05/17 20:59:53 chuck 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 +#include +#include + +#include "stand.h" +#include "libsa.h" + +void cputobsdlabel __P((struct disklabel *lp, struct cpu_disklabel *clp)); + +int errno; + +struct bugsc_softc { + int fd; /* Prom file descriptor */ + int poff; /* Partition offset */ + int psize; /* Partition size */ + short ctrl; + short dev; +} bugsc_softc[1]; + +int +devopen(f, fname, file) + struct open_file *f; + const char *fname; + char **file; +{ + register struct bugsc_softc *pp = &bugsc_softc[0]; + int error, i, dn = 0, pn = 0; + char *dev, *cp; + static char iobuf[MAXBSIZE]; + struct disklabel sdlabel; + + dev = bugargs.arg_start; + + /* + * Extract partition # from boot device string. + */ + for (cp = dev; *cp; cp++) /* void */; + while (*cp != '/' && cp > dev) { + if (*cp == ':') + pn = *(cp+1) - 'a'; + --cp; + } + + pp->fd = bugscopen(f); + + if (pp->fd < 0) { + printf("Can't open device `%s'\n", dev); + return (ENXIO); + } + error = bugscstrategy(pp, F_READ, LABELSECTOR, DEV_BSIZE, iobuf, &i); + if (error) + return (error); + if (i != DEV_BSIZE) + return (EINVAL); + + cputobsdlabel(&sdlabel, (struct cpu_disklabel *)iobuf); + pp->poff = sdlabel.d_partitions[pn].p_offset; + pp->psize = sdlabel.d_partitions[pn].p_size; + + f->f_dev = devsw; + f->f_devdata = (void *)pp; + *file = (char *)fname; + return (0); +} + +/* silly block scale factor */ +#define BUG_BLOCK_SIZE 256 +#define BUG_SCALE (512/BUG_BLOCK_SIZE) +int +bugscstrategy(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 bugsc_softc *pp = (struct bugsc_softc *)devdata; + daddr_t blk = dblk + pp->poff; + + twiddle(); + + dio.ctrl_lun = pp->ctrl; + dio.dev_lun = pp->dev; + 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("bugscstrategy: 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 +bugscopen(f) + struct open_file *f; +{ +#ifdef DEBUG + printf("bugscopen:\n"); +#endif + + f->f_devdata = (void *)bugsc_softc; + bugsc_softc[0].ctrl = (short)bugargs.ctrl_lun; + bugsc_softc[0].dev = (short)bugargs.dev_lun; +#ifdef DEBUG + printf("using mvmebug ctrl %d dev %d\n", + bugsc_softc[0].ctrl, bugsc_softc[0].dev); +#endif + return (0); +} + +int +bugscclose(f) + struct open_file *f; +{ + return (EIO); +} + +int +bugscioctl(f, cmd, data) + struct open_file *f; + u_long cmd; + void *data; +{ + return (EIO); +} + +void +cputobsdlabel(lp, clp) + struct disklabel *lp; + struct cpu_disklabel *clp; +{ + int i; + + lp->d_magic = clp->magic1; + lp->d_type = clp->type; + lp->d_subtype = clp->subtype; + bcopy(clp->vid_vd, lp->d_typename, 16); + bcopy(clp->packname, lp->d_packname, 16); + lp->d_secsize = clp->cfg_psm; + lp->d_nsectors = clp->cfg_spt; + lp->d_ncylinders = clp->cfg_trk; /* trk is really num of cyl! */ + lp->d_ntracks = clp->cfg_hds; + + lp->d_secpercyl = clp->secpercyl; + lp->d_secperunit = clp->secperunit; + lp->d_secpercyl = clp->secpercyl; + lp->d_secperunit = clp->secperunit; + lp->d_sparespertrack = clp->sparespertrack; + lp->d_sparespercyl = clp->sparespercyl; + lp->d_acylinders = clp->acylinders; + lp->d_rpm = clp->rpm; + lp->d_interleave = clp->cfg_ilv; + lp->d_trackskew = clp->cfg_sof; + lp->d_cylskew = clp->cylskew; + lp->d_headswitch = clp->headswitch; + + /* this silly table is for winchester drives */ + switch (clp->cfg_ssr) { + case 0: + lp->d_trkseek = 0; + break; + case 1: + lp->d_trkseek = 6; + break; + case 2: + lp->d_trkseek = 10; + break; + case 3: + lp->d_trkseek = 15; + break; + case 4: + lp->d_trkseek = 20; + break; + default: + lp->d_trkseek = 0; + break; + } + lp->d_flags = clp->flags; + for (i = 0; i < NDDATA; i++) + lp->d_drivedata[i] = clp->drivedata[i]; + for (i = 0; i < NSPARE; i++) + lp->d_spare[i] = clp->spare[i]; + lp->d_magic2 = clp->magic2; + lp->d_checksum = clp->checksum; + lp->d_npartitions = clp->partitions; + lp->d_bbsize = clp->bbsize; + lp->d_sbsize = clp->sbsize; + bcopy(clp->vid_4, &(lp->d_partitions[0]),sizeof (struct partition) * 4); + bcopy(clp->cfg_4, &(lp->d_partitions[4]), sizeof (struct partition) + * ((MAXPARTITIONS < 16) ? (MAXPARTITIONS - 4) : 12)); +} diff --git a/sys/arch/mvme68k/stand/libsa/exec_mvme.c b/sys/arch/mvme68k/stand/libsa/exec_mvme.c new file mode 100644 index 000000000000..3cf91e47f012 --- /dev/null +++ b/sys/arch/mvme68k/stand/libsa/exec_mvme.c @@ -0,0 +1,190 @@ +/* $NetBSD: exec_mvme.c,v 1.1 1996/05/17 21:00:02 chuck Exp $ */ + +/*- + * Copyright (c) 1982, 1986, 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)boot.c 8.1 (Berkeley) 6/10/93 + */ + +#include +#include +#include +#include + +#include "stand.h" +#include "libsa.h" + +/*ARGSUSED*/ +void +exec_mvme(file, flag) + char *file; + int flag; +{ + char *loadaddr; + register int io; + struct exec x; + int cc, magic; + void (*entry)(); + register char *cp; + register int *ip; + +#ifdef DEBUG + printf("exec_mvme: file=%s flag=0x%x\n", file, flag); +#endif + + io = open(file, 0); + if (io < 0) + return; + + /* + * Read in the exec header, and validate it. + */ + if (read(io, (char *)&x, sizeof(x)) != sizeof(x)) + goto shread; + if (N_BADMAG(x)) { + errno = EFTYPE; + goto closeout; + } + + /* + * note: on the mvme ports, the kernel is linked in such a way that + * its entry point is the first item in .text, and thus a_entry can + * be used to determine both the load address and the entry point. + * (also note that we make use of the fact that the kernel will live + * in a VA == PA range of memory ... otherwise we would take + * loadaddr as a parameter and let the kernel relocate itself!) + * + * note that ZMAGIC files included the a.out header in the text area + * so we must mask that off (has no effect on the other formats + */ + loadaddr = (void *)(x.a_entry & ~sizeof(x)); + + cp = loadaddr; + magic = N_GETMAGIC(x); + if (magic == ZMAGIC) + cp += sizeof(x); + entry = (void (*)())cp; + + /* + * Leave a copy of the exec header before the text. + * The sun3 kernel uses this to verify that the + * symbols were loaded by this boot program. + */ + bcopy(&x, cp - sizeof(x), sizeof(x)); + + /* + * Read in the text segment. + */ + printf("%d", x.a_text); + cc = x.a_text; + if (magic == ZMAGIC) + cc = cc - sizeof(x); /* a.out header part of text in zmagic */ + if (read(io, cp, cc) != cc) + goto shread; + cp += cc; + + /* + * NMAGIC may have a gap between text and data. + */ + if (magic == NMAGIC) { + register int mask = N_PAGSIZ(x) - 1; + while ((int)cp & mask) + *cp++ = 0; + } + + /* + * Read in the data segment. + */ + printf("+%d", x.a_data); + if (read(io, cp, x.a_data) != x.a_data) + goto shread; + cp += x.a_data; + + /* + * Zero out the BSS section. + * (Kernel doesn't care, but do it anyway.) + */ + printf("+%d", x.a_bss); + cc = x.a_bss; + while ((int)cp & 3) { + *cp++ = 0; + --cc; + } + ip = (int*)cp; + cp += cc; + while ((char*)ip < cp) + *ip++ = 0; + + /* + * Read in the symbol table and strings. + * (Always set the symtab size word.) + */ + *ip++ = x.a_syms; + cp = (char*) ip; + + if (x.a_syms > 0 && (flag & RB_NOSYM) == 0) { + + /* Symbol table and string table length word. */ + cc = x.a_syms; + printf("+[%d", cc); + cc += sizeof(int); /* strtab length too */ + if (read(io, cp, cc) != cc) + goto shread; + cp += x.a_syms; + ip = (int*)cp; /* points to strtab length */ + cp += sizeof(int); + + /* String table. Length word includes itself. */ + cc = *ip; + printf("+%d]", cc); + cc -= sizeof(int); + if (cc <= 0) + goto shread; + if (read(io, cp, cc) != cc) + goto shread; + cp += cc; + } + printf("=0x%x\n", cp - loadaddr); + close(io); + + printf("Start @ 0x%x ...\n", (int)entry); + (*entry)(flag, 0, cp, 0, 0); + printf("exec: kernel returned!\n"); + return; + +shread: + printf("exec: short read\n"); + errno = EIO; +closeout: + close(io); + return; +} diff --git a/sys/arch/mvme68k/stand/libsa/libsa.h b/sys/arch/mvme68k/stand/libsa/libsa.h new file mode 100644 index 000000000000..798b80059f0b --- /dev/null +++ b/sys/arch/mvme68k/stand/libsa/libsa.h @@ -0,0 +1,24 @@ +/* $NetBSD: libsa.h,v 1.1 1996/05/17 21:00:14 chuck Exp $ */ + +/* + * libsa prototypes + */ + +#include "libbug.h" + +/* bugdev.c */ +int bugscopen __P((struct open_file *, ...)); +int bugscclose __P((struct open_file *)); +int bugscioctl __P((struct open_file *, u_long, void *)); +int bugscstrategy __P((void *, int, daddr_t, size_t, void *, size_t *)); + +/* exec_mvme.c */ +void exec_mvme __P((char *, int)); + +/* parse_args.c */ +void parse_args __P((char **, int *)); + +#ifndef RB_NOSYM +#define RB_NOSYM 0x400 +#endif + diff --git a/sys/arch/mvme68k/stand/libsa/parse_args.c b/sys/arch/mvme68k/stand/libsa/parse_args.c new file mode 100644 index 000000000000..ff7529230d43 --- /dev/null +++ b/sys/arch/mvme68k/stand/libsa/parse_args.c @@ -0,0 +1,94 @@ +/* $NetBSD: parse_args.c,v 1.1 1996/05/17 21:00:22 chuck 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 +#include +#include +#include + +#include "stand.h" +#include "libsa.h" + +#define KERNEL_NAME "netbsd" + +struct flags { + char c; + short bit; +} bf[] = { + { 'a', RB_ASKNAME }, + { 'b', RB_HALT }, + { 'y', RB_NOSYM }, + { 'd', RB_KDB }, + { 'm', RB_MINIROOT }, + { 'r', RB_DFLTROOT }, + { 's', RB_SINGLE }, +}; + +void +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; + if (c != '-') { + name = ptr; + while ((c = *++ptr) && c != ' ') + ; + if (c) + *ptr++ = 0; + continue; + } + while ((c = *++ptr) && c != ' ') { + for (i = 0; i < sizeof(bf)/sizeof(bf[0]); i++) + if (bf[i].c == c) { + howto |= bf[i].bit; + } + } + } + } + *flagp = howto; + *filep = name; +}