diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-10-18 08:53:40 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-10-18 08:53:40 +0000 |
commit | d6583bb2a13f329cf0332ef2570eb8bb8fc0e39c (patch) | |
tree | ece253b876159b39c620e62b6c9b1174642e070e /sys/arch/vax/stand/bootxx.c |
initial import of NetBSD tree
Diffstat (limited to 'sys/arch/vax/stand/bootxx.c')
-rw-r--r-- | sys/arch/vax/stand/bootxx.c | 399 |
1 files changed, 399 insertions, 0 deletions
diff --git a/sys/arch/vax/stand/bootxx.c b/sys/arch/vax/stand/bootxx.c new file mode 100644 index 00000000000..b2f01417c95 --- /dev/null +++ b/sys/arch/vax/stand/bootxx.c @@ -0,0 +1,399 @@ +/* $NetBSD: bootxx.c,v 1.3 1995/09/16 13:01:06 ragge Exp $ */ +/*- + * Copyright (c) 1982, 1986 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)boot.c 7.15 (Berkeley) 5/4/91 + */ + +#include "sys/param.h" +#include "sys/reboot.h" +#include "sys/disklabel.h" + +#include "lib/libsa/stand.h" +#include "lib/libsa/ufs.h" + +#include "../mba/mbareg.h" +#include "../mba/hpreg.h" + +#include "../include/pte.h" +#include "../include/sid.h" +#include "../include/mtpr.h" +#include "../include/reg.h" + +#define NRSP 0 /* Kludge */ +#define NCMD 0 /* Kludge */ +#include "../uba/ubareg.h" +#include "../uba/udareg.h" +#include "../vax/mscp.h" + +#include "data.h" +#include "vaxstand.h" + +#include <a.out.h> + +int romstrategy(), romopen(); +int command(int, int); + +/* + * Boot program... argume passed in r10 and r11 determine whether boot + * stops to ask for system name and which device boot comes from. + */ + +volatile u_int devtype, bootdev; +unsigned opendev, boothowto, bootset; +int cpu_type, cpunumber; +unsigned *bootregs; +int is_750 = 0, is_mvax = 0, is_tmscp = 0; +struct rpb *rpb; + +main() +{ + int io; + char *hej = "/boot"; + + cpu_type = mfpr(PR_SID); + cpunumber = (mfpr(PR_SID) >> 24) & 0xFF; + + switch (cpunumber) { + + case VAX_78032: + case VAX_650: + { + int cpu_sie; /* sid-extension */ + + is_mvax = 1; + cpu_sie = *((int *) 0x20040004) >> 24; + cpu_type |= cpu_sie; + rpb = bootregs[11]; + bootdev = rpb->devtyp; + + break; + } + case VAX_750: + is_750 = 1; + bootdev = bootregs[10]; + + break; + } + + bootset = getbootdev(); + + printf("\nhowto 0x%x, bdev 0x%x, booting...\n", boothowto, bootdev); + io = open(hej, 0); + + if (io >= 0 && io < SOPEN_MAX) { + copyunix(io); + } else { + printf("Boot failed. errno %d (%s)\n", errno, strerror(errno)); + } +} + +/* ARGSUSED */ +copyunix(aio) +{ + struct exec x; + register int io = aio, i; + char *addr; + + i = read(io, (char *) &x, sizeof(x)); + if (i != sizeof(x) || N_BADMAG(x)) { + printf("Bad format: errno %s\n", strerror(errno)); + return; + } + printf("%d", x.a_text); + if (N_GETMAGIC(x) == ZMAGIC && lseek(io, N_TXTADDR(x), SEEK_SET) == -1) + goto shread; + if (read(io, (char *) 0x10000, x.a_text) != x.a_text) + goto shread; + addr = (char *) x.a_text; + if (N_GETMAGIC(x) == ZMAGIC || N_GETMAGIC(x) == NMAGIC) + while ((int) addr & CLOFSET) + *addr++ = 0; + printf("+%d", x.a_data); + if (read(io, addr + 0x10000, x.a_data) != x.a_data) + goto shread; + addr += x.a_data; + bcopy((void *) 0x10000, 0, (int) addr); + printf("+%d", x.a_bss); + for (i = 0; i < x.a_bss; i++) + *addr++ = 0; + for (i = 0; i < 128 * 512; i++) /* slop */ + *addr++ = 0; + printf(" start 0x%x\n", x.a_entry); + hoppabort(x.a_entry, boothowto, bootset); + (*((int (*) ()) x.a_entry)) (); + return; +shread: + printf("Short read\n"); + return; +} + +getbootdev() +{ + int i, major, adaptor, controller, unit, partition; + + + switch (cpunumber) { + case VAX_78032: + case VAX_650: + adaptor = 0; + controller = ((rpb->csrphy & 017777) == 0xDC)?1:0; + unit = rpb->unit; /* DUC, DUD? */ + + break; + + case VAX_750: + controller = 0; /* XXX Actually massbuss can be on 3 ctlr's */ + unit = bootregs[3]; + break; + } + + partition = 0; + + switch (bootdev) { + case 0: /* massbuss boot */ + major = 0; /* hp / ... */ + adaptor = (bootregs[1] & 0x6000) >> 17; + break; + + case 17: /* UDA50 boot */ + major = 9; /* ra / mscp */ + if (is_750) + adaptor = (bootregs[1] & 0x40000 ? 0 : 1); + break; + + case 18: /* TK50 boot */ + major = 15; /* tms / tmscp */ + is_tmscp = 1; /* use tape spec in mscp routines */ + break; + + default: + printf("Unsupported boot device %d, trying anyway.\n", bootdev); + boothowto |= (RB_SINGLE | RB_ASKNAME); + } + return MAKEBOOTDEV(major, adaptor, controller, unit, partition); +} + +struct devsw devsw[] = { + SADEV("rom", romstrategy,nullsys,nullsys, noioctl), +}; + +int ndevs = (sizeof(devsw) / sizeof(devsw[0])); + +struct fs_ops file_system[] = { + {ufs_open, ufs_close, ufs_read, ufs_write, ufs_seek, ufs_stat} +}; + +int nfsys = (sizeof(file_system) / sizeof(struct fs_ops)); + +struct disklabel lp; +int part_off = 0; /* offset into partition holding /boot */ +char io_buf[MAXBSIZE]; +volatile struct uda { + struct uda1ca uda_ca; /* communications area */ + struct mscp uda_rsp; /* response packets */ + struct mscp uda_cmd; /* command packets */ +} uda; +volatile struct udadevice *csr; + +devopen(f, fname, file) + struct open_file *f; + const char *fname; + char **file; +{ + char *msg; + int i, err, off; + char line[64]; + + f->f_dev = &devsw[0]; + *file = fname; + + /* + * On uVAX we need to init [T]MSCP ctlr to be able to use it. + */ + if (is_mvax) { + switch (bootdev) { + case 17: /* MSCP */ + case 18: /* TMSCP */ + csr = (struct udadevice *)rpb->csrphy; + + csr->udaip = 0; /* Start init */ + while((csr->udasa & UDA_STEP1) == 0); + csr->udasa = 0x8000; + while((csr->udasa & UDA_STEP2) == 0); + csr->udasa = (short)(((u_int)&uda)&0xffff) + 8; + while((csr->udasa & UDA_STEP3) == 0); + csr->udasa = 0x10; + while((csr->udasa & UDA_STEP4) == 0); + csr->udasa = 0x0001; + + uda.uda_ca.ca_rspdsc = + (int) &uda.uda_rsp.mscp_cmdref; + uda.uda_ca.ca_cmddsc = + (int) &uda.uda_cmd.mscp_cmdref; + if (is_tmscp) + uda.uda_cmd.mscp_vcid = 1; + command(M_OP_SETCTLRC, 0); + uda.uda_cmd.mscp_unit = rpb->unit; + command(M_OP_ONLINE, 0); + } + } + + /* + * the disklabel _shall_ be at address LABELOFFSET + RELOC in + * phys memory now, no need at all to reread it again. + * Actually disklabel is only needed when using hp disks, + * but it doesn't hurt to always get it. + */ + if (!is_tmscp) { + msg = getdisklabel(LABELOFFSET + RELOC, &lp); + if (msg) { + printf("getdisklabel: %s\n", msg); + } + } + return 0; +} + +command(cmd, arg) +{ + volatile int hej; + + uda.uda_cmd.mscp_opcode = cmd; + uda.uda_cmd.mscp_modifier = arg; + + uda.uda_cmd.mscp_msglen = MSCP_MSGLEN; + uda.uda_rsp.mscp_msglen = MSCP_MSGLEN; + uda.uda_ca.ca_rspdsc |= MSCP_OWN|MSCP_INT; + uda.uda_ca.ca_cmddsc |= MSCP_OWN|MSCP_INT; + hej = csr->udaip; + while (uda.uda_ca.ca_rspdsc < 0); + +} + +int curblock = 0; + +romstrategy(sc, func, dblk, size, buf, rsize) + void *sc; + int func; + daddr_t dblk; + char *buf; + int size, *rsize; +{ + int i; + int block = dblk; + int nsize = size; + + switch (cpunumber) { + + case VAX_650: + case VAX_78032: + switch (bootdev) { + + case 17: /* MSCP */ + uda.uda_cmd.mscp_seq.seq_lbn = dblk; + uda.uda_cmd.mscp_seq.seq_bytecount = size; + uda.uda_cmd.mscp_seq.seq_buffer = buf; + uda.uda_cmd.mscp_unit = rpb->unit; + command(M_OP_READ, 0); + break; + + case 18: /* TMSCP */ + if (dblk < curblock) { + uda.uda_cmd.mscp_seq.seq_bytecount = + curblock - dblk; + command(M_OP_POS, 12); + } else { + uda.uda_cmd.mscp_seq.seq_bytecount = + dblk - curblock; + command(M_OP_POS, 4); + } + curblock = size/512 + dblk; + for (i = 0 ; i < size/512 ; i++) { + uda.uda_cmd.mscp_seq.seq_lbn = 1; + uda.uda_cmd.mscp_seq.seq_bytecount = 512; + uda.uda_cmd.mscp_seq.seq_buffer = buf + i * 512; + uda.uda_cmd.mscp_unit = rpb->unit; + command(M_OP_READ, 0); + } + break; + + } + break; + + case VAX_750: + if (bootdev) { + while (size > 0) { + if ((read750(block, bootregs) & 0x01) == 0) + return 1; + + bcopy(0, buf, 512); + size -= 512; + buf += 512; + block++; + } + } else + hpread(block, size, buf); + break; + } + + *rsize = nsize; + return 0; +} + +hpread(block, size, buf) + char *buf; +{ + volatile struct mba_regs *mr = (void *) bootregs[1]; + volatile struct hp_drv *hd = (void*)&mr->mba_md[bootregs[3]]; + struct disklabel *dp = &lp; + u_int pfnum, nsize, mapnr, bn, cn, sn, tn; + + pfnum = (u_int) buf >> PGSHIFT; + + for (mapnr = 0, nsize = size; (nsize + NBPG) > 0; nsize -= NBPG) + mr->mba_map[mapnr++] = PG_V | pfnum++; + mr->mba_var = ((u_int) buf & PGOFSET); + mr->mba_bc = (~size) + 1; + bn = block; + cn = bn / dp->d_secpercyl; + sn = bn % dp->d_secpercyl; + tn = sn / dp->d_nsectors; + sn = sn % dp->d_nsectors; + hd->hp_dc = cn; + hd->hp_da = (tn << 8) | sn; + hd->hp_cs1 = HPCS_READ; + while (mr->mba_sr & MBASR_DTBUSY); + if (mr->mba_sr & MBACR_ABORT){ + return 1; + } + return 0; +} |