summaryrefslogtreecommitdiff
path: root/sys/arch/vax/stand/bootxx.c
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>1995-10-18 08:53:40 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>1995-10-18 08:53:40 +0000
commitd6583bb2a13f329cf0332ef2570eb8bb8fc0e39c (patch)
treeece253b876159b39c620e62b6c9b1174642e070e /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.c399
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;
+}