summaryrefslogtreecommitdiffstats
path: root/sys/boot/alpha/libalpha
diff options
context:
space:
mode:
authormsmith <msmith@FreeBSD.org>1998-08-21 03:17:42 +0000
committermsmith <msmith@FreeBSD.org>1998-08-21 03:17:42 +0000
commit8adeb775c43d4c2ae76cce40837a3953af6abc83 (patch)
treeec778e5f3903abe2dbb59959c0fd8398c99c145b /sys/boot/alpha/libalpha
parent335c4be5b17816baac6b70d4d0b3132925de858d (diff)
downloadFreeBSD-src-8adeb775c43d4c2ae76cce40837a3953af6abc83.zip
FreeBSD-src-8adeb775c43d4c2ae76cce40837a3953af6abc83.tar.gz
This is the new unified bootstrap, sometimes known previously as the
'three-stage' bootstrap. There are a number of caveats with the code in its current state: - The i386 bootstrap only supports booting from a floppy. - The kernel and kld do not yet know how to deal with the extended information and module summary passed in. - PnP-based autodetection and demand loading of modules is not implemented. - i386 ELF kernel loading is not ready yet. - The i386 bootstrap is loaded via an ugly blockmap. On the alpha, both net- and disk-booting (SRM console machines only) is supported. No blockmaps are used by this code. Obtained from: Parts from the NetBSD/i386 standalone bootstrap.
Diffstat (limited to 'sys/boot/alpha/libalpha')
-rw-r--r--sys/boot/alpha/libalpha/Makefile23
-rw-r--r--sys/boot/alpha/libalpha/OSFpal.c71
-rw-r--r--sys/boot/alpha/libalpha/alpha_module.c64
-rw-r--r--sys/boot/alpha/libalpha/bbinfo.h57
-rw-r--r--sys/boot/alpha/libalpha/common.h11
-rw-r--r--sys/boot/alpha/libalpha/delay.c40
-rw-r--r--sys/boot/alpha/libalpha/devicename.c232
-rw-r--r--sys/boot/alpha/libalpha/elf_freebsd.c316
-rw-r--r--sys/boot/alpha/libalpha/getsecs.c37
-rw-r--r--sys/boot/alpha/libalpha/libalpha.h107
-rw-r--r--sys/boot/alpha/libalpha/pal.S351
-rw-r--r--sys/boot/alpha/libalpha/prom.c165
-rw-r--r--sys/boot/alpha/libalpha/prom_disp.S118
-rw-r--r--sys/boot/alpha/libalpha/prom_swpal.S139
-rw-r--r--sys/boot/alpha/libalpha/reboot.c48
-rw-r--r--sys/boot/alpha/libalpha/srmdisk.c334
-rw-r--r--sys/boot/alpha/libalpha/srmnet.c257
-rw-r--r--sys/boot/alpha/libalpha/start.S85
-rw-r--r--sys/boot/alpha/libalpha/time.c43
19 files changed, 2498 insertions, 0 deletions
diff --git a/sys/boot/alpha/libalpha/Makefile b/sys/boot/alpha/libalpha/Makefile
new file mode 100644
index 0000000..191649f
--- /dev/null
+++ b/sys/boot/alpha/libalpha/Makefile
@@ -0,0 +1,23 @@
+# $Id$
+
+LIB= alpha
+NOPIC= true
+NOPROFILE= true
+INTERNALLIB= true
+
+# XXX hack to pick up stand.h
+CFLAGS= -I/home/dfr/FreeBSD/alpha/src/lib/libstand
+CFLAGS+= -DDEBUG
+
+# Pick up the bootstrap header for some interface items
+CFLAGS+= -I${.CURDIR}/../../common -mno-fp-regs
+
+CFLAGS+= -DDISK_DEBUG
+#CPPFLAGS+= -DNO_DISKLABEL
+#CPPFLAGS+= -DSAVE_MEMORY
+
+SRCS= OSFpal.c elf_freebsd.c prom.c prom_disp.S prom_swpal.S start.S \
+ pal.S reboot.c delay.c time.c alpha_module.c devicename.c \
+ srmdisk.c srmnet.c getsecs.c
+
+.include <bsd.lib.mk>
diff --git a/sys/boot/alpha/libalpha/OSFpal.c b/sys/boot/alpha/libalpha/OSFpal.c
new file mode 100644
index 0000000..b77ee12
--- /dev/null
+++ b/sys/boot/alpha/libalpha/OSFpal.c
@@ -0,0 +1,71 @@
+/*
+ * $Id$
+ * From $NetBSD: OSFpal.c,v 1.5 1998/06/24 01:33:19 ross Exp $
+ */
+
+/*
+ * Copyright (c) 1994, 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Keith Bostic
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <sys/types.h>
+#include <stand.h>
+
+#include <machine/prom.h>
+#include <machine/rpb.h>
+#include <machine/alpha_cpu.h>
+
+vm_offset_t ptbr_save;
+
+#include "common.h"
+
+void
+OSFpal()
+{
+ struct rpb *r;
+ struct pcs *p;
+
+ r = (struct rpb *)HWRPB_ADDR;
+ /*
+ * Note, cpu_number() is a VMS op, can't necessarily call it.
+ * Real fun: PAL_VMS_mfpr_whami == PAL_OSF1_rti...
+ * We might not be rpb_primary_cpu_id, but it is supposed to go
+ * first so the answer should apply to everyone.
+ */
+ p = LOCATE_PCS(r, r->rpb_primary_cpu_id);
+
+ printf("VMS PAL rev: 0x%lx\n", p->pcs_palrevisions[PALvar_OpenVMS]);
+ printf("OSF PAL rev: 0x%lx\n", p->pcs_palrevisions[PALvar_OSF1]);
+
+ if(p->pcs_pal_type==PAL_TYPE_OSF1) {
+ printf("OSF PAL code already running.\n");
+ ptbr_save = ((struct alpha_pcb *)p)->apcb_ptbr;
+ printf("PTBR is: 0x%lx\n", ptbr_save);
+ return;
+ }
+ switch_palcode();
+ printf("Switch to OSF PAL code succeeded.\n");
+}
+
diff --git a/sys/boot/alpha/libalpha/alpha_module.c b/sys/boot/alpha/libalpha/alpha_module.c
new file mode 100644
index 0000000..a08fc85
--- /dev/null
+++ b/sys/boot/alpha/libalpha/alpha_module.c
@@ -0,0 +1,64 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $Id$
+ */
+
+/*
+ * alpha-specific module functionality.
+ *
+ */
+
+#include <stand.h>
+#include <string.h>
+
+#include "bootstrap.h"
+#include "libalpha.h"
+
+/*
+ * Look for a method and having found it, boot the kernel module.
+ */
+int
+alpha_boot(void)
+{
+ int i;
+
+ for (i = 0; module_formats[i] != NULL; i++) {
+ if (((loaded_modules->m_flags & MF_FORMATMASK) == module_formats[i]->l_format) &&
+ (module_formats[i]->l_exec != NULL)) {
+ return((module_formats[i]->l_exec)(loaded_modules));
+ }
+ }
+}
+
+/*
+ * Use voodoo to load modules required by current hardware.
+ */
+int
+alpha_autoload(void)
+{
+ /* XXX use PnP to locate stuff here */
+ return(0);
+}
diff --git a/sys/boot/alpha/libalpha/bbinfo.h b/sys/boot/alpha/libalpha/bbinfo.h
new file mode 100644
index 0000000..5529035
--- /dev/null
+++ b/sys/boot/alpha/libalpha/bbinfo.h
@@ -0,0 +1,57 @@
+/*
+ * $Id$
+ * From $NetBSD: bbinfo.h,v 1.2 1997/04/06 08:40:57 cgd Exp $
+ */
+
+/*
+ * Copyright (c) 1995, 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+struct bbinfoloc {
+ u_int64_t magic1;
+ u_int64_t start;
+ u_int64_t end;
+ u_int64_t pad1[4];
+ u_int64_t magic2;
+};
+
+struct bbinfo {
+ int32_t cksum;
+ int32_t nblocks;
+ int32_t bsize;
+ u_int32_t pad1[8];
+ int32_t blocks[1];
+};
+
+struct netbbinfo {
+ u_int64_t magic1;
+ u_int8_t set;
+ u_int8_t ether_addr[6];
+ u_int8_t force;
+ u_int64_t pad1[4];
+ u_int64_t cksum;
+ u_int64_t magic2;
+};
diff --git a/sys/boot/alpha/libalpha/common.h b/sys/boot/alpha/libalpha/common.h
new file mode 100644
index 0000000..8acd3f93
--- /dev/null
+++ b/sys/boot/alpha/libalpha/common.h
@@ -0,0 +1,11 @@
+/*
+ * $Id$
+ * From: $NetBSD: common.h,v 1.2 1998/01/05 07:02:48 perry Exp $
+ */
+
+int prom_open __P((char*, int));
+void OSFpal __P((void));
+void halt __P((void));
+u_int64_t prom_dispatch __P((int, ...));
+int cpu_number __P((void));
+void switch_palcode __P((void));
diff --git a/sys/boot/alpha/libalpha/delay.c b/sys/boot/alpha/libalpha/delay.c
new file mode 100644
index 0000000..a7621b7
--- /dev/null
+++ b/sys/boot/alpha/libalpha/delay.c
@@ -0,0 +1,40 @@
+/*-
+ * Copyright (c) 1998 Doug Rabson
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $Id$
+ */
+
+#include <stand.h>
+#include <machine/rpb.h>
+
+void
+delay(int usecs)
+{
+ struct rpb *hwrpb = (struct rpb *)HWRPB_ADDR;
+ unsigned long start = alpha_rpcc();
+ unsigned long end = start + (hwrpb->rpb_cc_freq * usecs) / 1000000;
+ while (alpha_rpcc() < end)
+ ;
+}
diff --git a/sys/boot/alpha/libalpha/devicename.c b/sys/boot/alpha/libalpha/devicename.c
new file mode 100644
index 0000000..310bb94
--- /dev/null
+++ b/sys/boot/alpha/libalpha/devicename.c
@@ -0,0 +1,232 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $Id$
+ */
+
+#include <stand.h>
+#include <string.h>
+#include <sys/disklabel.h>
+#include "bootstrap.h"
+#include "libalpha.h"
+
+static int alpha_parsedev(struct alpha_devdesc **dev, char *devspec, char **path);
+
+/*
+ * Point (dev) at an allocated device specifier for the device matching the
+ * path in (devspec). If it contains an explicit device specification,
+ * use that. If not, use the default device.
+ */
+int
+alpha_getdev(void **vdev, char *devspec, char **path)
+{
+ struct alpha_devdesc **dev = (struct alpha_devdesc **)vdev;
+ int rv;
+
+ /*
+ * If it looks like this is just a path and no
+ * device, go with the current device.
+ */
+ if ((devspec == NULL) ||
+ (devspec[0] == '/') ||
+ (strchr(devspec, ':') == NULL)) {
+
+ if (((rv = alpha_parsedev(dev, getenv("currdev"), NULL)) == 0) &&
+ (path != NULL))
+ *path = devspec;
+ return(rv);
+ }
+
+ /*
+ * Try to parse the device name off the beginning of the devspec
+ */
+ return(alpha_parsedev(dev, devspec, path));
+}
+
+/*
+ * Point (dev) at an allocated device specifier matching the string version
+ * at the beginning of (devspec). Return a pointer to the remaining
+ * text in (path).
+ *
+ * In all cases, the beginning of (devspec) is compared to the names
+ * of known devices in the device switch, and then any following text
+ * is parsed according to the rules applied to the device type.
+ *
+ * For disk-type devices, the syntax is:
+ *
+ * disk<unit>[s<slice>][<partition>]:
+ *
+ */
+static int
+alpha_parsedev(struct alpha_devdesc **dev, char *devspec, char **path)
+{
+ struct alpha_devdesc *idev;
+ struct devsw *dv;
+ int i, unit, slice, partition, err;
+ char *cp, *np;
+
+ /* minimum length check */
+ if (strlen(devspec) < 2)
+ return(EINVAL);
+
+ /* look for a device that matches */
+ for (i = 0, dv = NULL; devsw[i] != NULL; i++) {
+ if (!strncmp(devspec, devsw[i]->dv_name, strlen(devsw[i]->dv_name))) {
+ dv = devsw[i];
+ break;
+ }
+ }
+
+ if (dv == NULL)
+ return(ENOENT);
+ idev = malloc(sizeof(struct alpha_devdesc));
+ err = 0;
+ np = (devspec + strlen(dv->dv_name));
+
+ switch(dv->dv_type) {
+ case DEVT_NONE: /* XXX what to do here? Do we care? */
+ break;
+
+ case DEVT_DISK:
+ unit = -1;
+ slice = -1;
+ partition = -1;
+ if (*np && (*np != ':')) {
+ unit = strtol(np, &cp, 10); /* next comes the unit number */
+ if (cp == np) {
+ err = EUNIT;
+ goto fail;
+ }
+ if (*cp == 's') { /* got a slice number */
+ np = cp + 1;
+ slice = strtol(np, &cp, 10);
+ if (cp == np) {
+ err = ESLICE;
+ goto fail;
+ }
+ }
+ if (*cp && (*cp != ':')) {
+ partition = *cp - 'a'; /* get a partition number */
+ if ((partition < 0) || (partition >= MAXPARTITIONS)) {
+ err = EPART;
+ goto fail;
+ }
+ cp++;
+ }
+ }
+ if (*cp && (*cp != ':')) {
+ err = EINVAL;
+ goto fail;
+ }
+
+ idev->d_kind.srmdisk.unit = unit;
+ idev->d_kind.srmdisk.slice = slice;
+ idev->d_kind.srmdisk.partition = partition;
+ if (path != NULL)
+ *path = (*cp == 0) ? cp : cp + 1;
+ break;
+
+ case DEVT_NET:
+ unit = 0;
+
+ if (*np && (*np != ':')) {
+ unit = strtol(np, &cp, 0); /* get unit number if present */
+ if (cp == np) {
+ err = EUNIT;
+ goto fail;
+ }
+ }
+ if (*cp && (*cp != ':')) {
+ err = EINVAL;
+ goto fail;
+ }
+
+ idev->d_kind.netif.unit = unit;
+ if (path != NULL)
+ *path = (*cp == 0) ? cp : cp + 1;
+ break;
+
+ default:
+ err = EINVAL;
+ goto fail;
+ }
+ idev->d_dev = dv;
+ idev->d_type = dv->dv_type;
+ if (dev != NULL)
+ *dev = idev;
+ return(0);
+
+ fail:
+ free(idev);
+ return(err);
+}
+
+
+char *
+alpha_fmtdev(void *vdev)
+{
+ struct alpha_devdesc *dev = (struct alpha_devdesc *)vdev;
+ static char buf[128]; /* XXX device length constant? */
+ char *cp;
+
+ switch(dev->d_type) {
+ case DEVT_NONE:
+ strcpy(buf, "(no device)");
+ break;
+
+ case DEVT_DISK:
+ cp = buf;
+ cp += sprintf(cp, "%s%d", dev->d_dev->dv_name, dev->d_kind.srmdisk.unit);
+ if (dev->d_kind.srmdisk.slice > 0)
+ cp += sprintf(cp, "s%d", dev->d_kind.srmdisk.slice);
+ if (dev->d_kind.srmdisk.partition >= 0)
+ cp += sprintf(cp, "%c", dev->d_kind.srmdisk.partition + 'a');
+ strcat(cp, ":");
+ break;
+
+ case DEVT_NET:
+ sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_kind.netif.unit);
+ break;
+ }
+ return(buf);
+}
+
+
+/*
+ * Set currdev to suit the value being supplied in (value)
+ */
+int
+alpha_setcurrdev(struct env_var *ev, int flags, void *value)
+{
+ struct alpha_devdesc *ncurr;
+ int rv;
+
+ if ((rv = alpha_parsedev(&ncurr, value, NULL)) != 0)
+ return(rv);
+ free(ncurr);
+ env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL);
+ return(0);
+}
+
diff --git a/sys/boot/alpha/libalpha/elf_freebsd.c b/sys/boot/alpha/libalpha/elf_freebsd.c
new file mode 100644
index 0000000..4f618d8
--- /dev/null
+++ b/sys/boot/alpha/libalpha/elf_freebsd.c
@@ -0,0 +1,316 @@
+/* $Id$ */
+/* $NetBSD: loadfile.c,v 1.10 1998/06/25 06:45:46 ross Exp $ */
+
+/*-
+ * Copyright (c) 1997 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center.
+ *
+ * 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 NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ */
+
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell.
+ *
+ * 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 <stand.h>
+#include <string.h>
+
+#include <sys/param.h>
+#include <machine/elf.h>
+#include <machine/prom.h>
+#include <machine/rpb.h>
+#include <machine/bootinfo.h>
+
+#include "bootstrap.h"
+
+#define _KERNEL
+
+struct elf_kernel_module
+{
+ struct loaded_module m;
+ vm_offset_t m_entry; /* module entrypoint */
+ struct bootinfo_v1 m_bi; /* legacy bootinfo */
+};
+
+static int elf_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result);
+static int elf_exec(struct loaded_module *amp);
+static int elf_load(int fd, Elf_Ehdr *elf, vm_offset_t dest);
+
+struct module_format alpha_elf = { MF_ELF, elf_loadmodule, elf_exec };
+
+vm_offset_t ffp_save, ptbr_save;
+vm_offset_t ssym, esym;
+
+static int
+elf_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result)
+{
+ struct elf_kernel_module *mp;
+ Elf_Ehdr hdr;
+ ssize_t nr;
+ int fd, rval;
+
+ /* Open the file. */
+ rval = 1;
+ if ((fd = open(filename, 0)) < 0) {
+ (void)printf("open %s: %s\n", filename, strerror(errno));
+ goto err;
+ }
+
+ /* Read the exec header. */
+ if ((nr = read(fd, &hdr, sizeof(hdr))) != sizeof(hdr)) {
+ (void)printf("read header: %s\n", strerror(errno));
+ goto err;
+ }
+
+ if (!(hdr.e_ident[0] == ELFMAG0
+ && hdr.e_ident[1] == ELFMAG1
+ && hdr.e_ident[2] == ELFMAG2
+ && hdr.e_ident[3] == ELFMAG3)) {
+ (void)printf("%s: unknown executable format\n", filename);
+ goto err;
+ }
+
+ /*
+ * Ok, we think this is for us.
+ */
+ mp = malloc(sizeof(struct elf_kernel_module));
+ mp->m.m_name = strdup(filename); /* XXX should we prune the name? */
+ mp->m.m_type = "elf kernel"; /* XXX only if that's what we really are */
+ mp->m.m_args = NULL; /* XXX should we put the bootstrap args here and parse later? */
+ mp->m.m_flags = MF_ELF; /* we're an elf kernel */
+ mp->m_entry = hdr.e_entry;
+ if (dest == 0)
+ dest = (vm_offset_t) hdr.e_entry;
+ if (mod_findmodule(NULL, mp->m.m_type) != NULL) {
+ printf("elf_loadmodule: kernel already loaded\n");
+ rval = EPERM;
+ goto err;
+ }
+ rval = elf_load(fd, &hdr, (vm_offset_t) dest);
+
+ *result = (struct loaded_module *)mp;
+
+ err:
+ if (fd >= 0)
+ (void)close(fd);
+ return (rval);
+}
+
+static int
+elf_load(int fd, Elf_Ehdr *elf, vm_offset_t dest)
+{
+ Elf_Shdr *shp;
+ Elf_Off off;
+ int i;
+ int first = 1;
+ int havesyms;
+
+ for (i = 0; i < elf->e_phnum; i++) {
+ Elf_Phdr phdr;
+ if (lseek(fd, elf->e_phoff + sizeof(phdr) * i, SEEK_SET)
+ == -1) {
+ (void)printf("lseek phdr: %s\n", strerror(errno));
+ return (1);
+ }
+ if (read(fd, (void *)&phdr, sizeof(phdr)) != sizeof(phdr)) {
+ (void)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. */
+ (void)printf("%s%lu", first ? "" : "+", phdr.p_filesz);
+ if (lseek(fd, phdr.p_offset, SEEK_SET) == -1) {
+ (void)printf("lseek text: %s\n", strerror(errno));
+ return (1);
+ }
+ if (read(fd, (void *)phdr.p_vaddr, phdr.p_filesz) !=
+ phdr.p_filesz) {
+ (void)printf("read text: %s\n", strerror(errno));
+ return (1);
+ }
+ if (first || ffp_save < phdr.p_vaddr + phdr.p_memsz)
+ ffp_save = phdr.p_vaddr + phdr.p_memsz;
+
+ /* Zero out bss. */
+ if (phdr.p_filesz < phdr.p_memsz) {
+ (void)printf("+%lu", phdr.p_memsz - phdr.p_filesz);
+ bzero((void *)(phdr.p_vaddr + phdr.p_filesz),
+ phdr.p_memsz - phdr.p_filesz);
+ }
+ first = 0;
+ }
+ /*
+ * Copy the ELF and section headers.
+ */
+ ffp_save = roundup(ffp_save, sizeof(long));
+ ssym = ffp_save;
+ bcopy(elf, (void *)ffp_save, sizeof(Elf_Ehdr));
+ ffp_save += sizeof(Elf_Ehdr);
+ if (lseek(fd, elf->e_shoff, SEEK_SET) == -1) {
+ printf("lseek section headers: %s\n", strerror(errno));
+ return (1);
+ }
+ if (read(fd, (void *)ffp_save, elf->e_shnum * sizeof(Elf_Shdr)) !=
+ elf->e_shnum * sizeof(Elf_Shdr)) {
+ printf("read section headers: %s\n", strerror(errno));
+ return (1);
+ }
+ shp = (Elf_Shdr *)ffp_save;
+ ffp_save += roundup((elf->e_shnum * sizeof(Elf_Shdr)), sizeof(long));
+
+ /*
+ * 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) + (elf->e_shnum * sizeof(Elf_Shdr))),
+ sizeof(long));
+ for (havesyms = i = 0; i < elf->e_shnum; i++)
+ if (shp[i].sh_type == SHT_SYMTAB)
+ havesyms = 1;
+ for (first = 1, i = 0; i < elf->e_shnum; i++) {
+ if (shp[i].sh_type == SHT_SYMTAB ||
+ shp[i].sh_type == SHT_STRTAB) {
+ printf("%s%ld", first ? " [" : "+", shp[i].sh_size);
+ if (havesyms) {
+ if (lseek(fd, shp[i].sh_offset, SEEK_SET)
+ == -1) {
+ printf("\nlseek symbols: %s\n",
+ strerror(errno));
+ return (1);
+ }
+ if (read(fd, (void *)ffp_save, shp[i].sh_size)
+ != shp[i].sh_size) {
+ printf("\nread symbols: %s\n",
+ strerror(errno));
+ return (1);
+ }
+ }
+ ffp_save += roundup(shp[i].sh_size, sizeof(long));
+ shp[i].sh_offset = off;
+ off += roundup(shp[i].sh_size, sizeof(long));
+ first = 0;
+ }
+ }
+ esym = ffp_save;
+
+ if (first == 0)
+ printf("]");
+
+ ffp_save = ALPHA_K0SEG_TO_PHYS((ffp_save + PAGE_MASK) & ~PAGE_MASK)
+ >> PAGE_SHIFT;
+ ffp_save += 2; /* XXX OSF/1 does this, no idea why. */
+
+ (void)printf("\n");
+
+ /*
+ * Frob the copied ELF header to give information relative
+ * to ssym.
+ */
+ elf = (Elf_Ehdr *)ssym;
+ elf->e_phoff = 0;
+ elf->e_shoff = sizeof(Elf_Ehdr);
+ elf->e_phentsize = 0;
+ elf->e_phnum = 0;
+
+ return (0);
+}
+
+static int
+elf_exec(struct loaded_module *amp)
+{
+ struct elf_kernel_module *mp = (struct elf_kernel_module *)amp;
+ static struct bootinfo_v1 bootinfo_v1;
+
+ /*
+ * Fill in the bootinfo for the kernel.
+ */
+ bzero(&bootinfo_v1, sizeof(bootinfo_v1));
+ bootinfo_v1.ssym = ssym;
+ bootinfo_v1.esym = esym;
+ strncpy(bootinfo_v1.booted_kernel, mp->m.m_name,
+ sizeof(bootinfo_v1.booted_kernel));
+ prom_getenv(PROM_E_BOOTED_OSFLAGS, bootinfo_v1.boot_flags,
+ sizeof(bootinfo_v1.boot_flags));
+ bootinfo_v1.hwrpb = (void *)HWRPB_ADDR;
+ bootinfo_v1.hwrpbsize = ((struct rpb *)HWRPB_ADDR)->rpb_size;
+ bootinfo_v1.cngetc = NULL;
+ bootinfo_v1.cnputc = NULL;
+ bootinfo_v1.cnpollc = NULL;
+
+ printf("Entering %s at 0x%lx...\n", mp->m.m_name, mp->m_entry);
+ closeall();
+ alpha_pal_imb();
+ (*(void (*)())mp->m_entry)(ffp_save, ptbr_save,
+ BOOTINFO_MAGIC, &bootinfo_v1, 1, 0);
+}
+
+
+
diff --git a/sys/boot/alpha/libalpha/getsecs.c b/sys/boot/alpha/libalpha/getsecs.c
new file mode 100644
index 0000000..f234a37
--- /dev/null
+++ b/sys/boot/alpha/libalpha/getsecs.c
@@ -0,0 +1,37 @@
+/*
+ * $Id$
+ * From: $NetBSD: getsecs.c,v 1.5 1998/01/05 07:02:49 perry Exp $
+ */
+
+#include <sys/param.h>
+#include <machine/prom.h>
+#include <machine/rpb.h>
+
+int
+getsecs()
+{
+ static long tnsec;
+ static long lastpcc, wrapsecs;
+ long curpcc;
+
+ if (tnsec == 0) {
+ tnsec = 1;
+ lastpcc = alpha_rpcc() & 0xffffffff;
+ wrapsecs = (0xffffffff /
+ ((struct rpb *)HWRPB_ADDR)->rpb_cc_freq) + 1;
+
+#if 0
+ printf("getsecs: cc freq = %d, time to wrap = %d\n",
+ ((struct rpb *)HWRPB_ADDR)->rpb_cc_freq, wrapsecs);
+#endif
+ }
+
+ curpcc = alpha_rpcc() & 0xffffffff;
+ if (curpcc < lastpcc)
+ curpcc += 0x100000000;
+
+ tnsec += ((curpcc - lastpcc) * 1000000000) / ((struct rpb *)HWRPB_ADDR)->rpb_cc_freq;
+ lastpcc = curpcc;
+
+ return (tnsec / 1000000000);
+}
diff --git a/sys/boot/alpha/libalpha/libalpha.h b/sys/boot/alpha/libalpha/libalpha.h
new file mode 100644
index 0000000..24b29d2
--- /dev/null
+++ b/sys/boot/alpha/libalpha/libalpha.h
@@ -0,0 +1,107 @@
+/* $Id$ */
+
+/*
+ * Copyright (c) 1996
+ * Matthias Drochner. 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 for the NetBSD Project
+ * by Matthias Drochner.
+ * 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.
+ *
+ */
+
+
+/*
+ * alpha fully-qualified device descriptor
+ */
+struct alpha_devdesc
+{
+ struct devsw *d_dev;
+ int d_type;
+#define DEVT_NONE 0
+#define DEVT_DISK 1
+#define DEVT_NET 2
+ union
+ {
+ struct
+ {
+ int unit;
+ int slice;
+ int partition;
+ } srmdisk;
+ struct
+ {
+ int unit; /* XXX net layer lives over these? */
+ } netif;
+ } d_kind;
+};
+
+extern int alpha_getdev(void **vdev, char *devspec, char **path);
+extern char *alpha_fmtdev(void *vdev);
+extern int alpha_setcurrdev(struct env_var *ev, int flags, void *value);
+
+#define MAXDEV 31 /* maximum number of distinct devices */
+
+typedef unsigned long physaddr_t;
+
+/* exported devices XXX rename? */
+extern struct devsw srmdisk;
+extern struct netif_driver srmnet;
+
+/* this is in startup code */
+extern void delay(int);
+extern void reboot(void);
+
+/*
+ * alpha module loader
+ */
+#define MF_FORMATMASK 0xf
+#define MF_AOUT 0 /* not supported */
+#define MF_ELF 1
+
+struct alpha_module
+{
+ char *m_name; /* module name */
+ char *m_type; /* module type, eg 'kernel', 'pnptable', etc. */
+ char *m_args; /* arguments for the module */
+ int m_flags; /* 0xffff reserved for arch-specific use */
+ struct alpha_module *m_next; /* next module */
+ physaddr_t m_addr; /* load address */
+ size_t m_size; /* module size */
+};
+
+struct alpha_format
+{
+ int l_format;
+ /* Load function must return EFTYPE if it can't handle the module supplied */
+ int (* l_load)(char *filename, physaddr_t dest, struct alpha_module **result);
+ int (* l_exec)(struct alpha_module *amp);
+};
+extern struct alpha_format *formats[]; /* supplied by consumer */
+extern struct alpha_format alpha_elf;
+
+extern int alpha_boot(void);
+extern int alpha_autoload(void);
+extern struct alpha_module *alpha_findmodule(char *name, char *type);
diff --git a/sys/boot/alpha/libalpha/pal.S b/sys/boot/alpha/libalpha/pal.S
new file mode 100644
index 0000000..c33f317
--- /dev/null
+++ b/sys/boot/alpha/libalpha/pal.S
@@ -0,0 +1,351 @@
+/*
+ * $Id$
+ * From: $NetBSD: pal.s,v 1.12 1998/02/27 03:44:53 thorpej Exp $
+ */
+
+/*
+ * Copyright (c) 1994, 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+/*
+ * The various OSF PALcode routines.
+ *
+ * The following code is originally derived from pages: (I) 6-5 - (I) 6-7
+ * and (III) 2-1 - (III) 2-25 of "Alpha Architecture Reference Manual" by
+ * Richard L. Sites.
+ *
+ * Updates taken from pages: (II-B) 2-1 - (II-B) 2-33 of "Alpha AXP
+ * Architecture Reference Manual, Second Edition" by Richard L. Sites
+ * and Richard T. Witek.
+ */
+
+#include <machine/asm.h>
+
+inc2: .stabs __FILE__,132,0,0,inc2; .loc 1 __LINE__
+/*
+ * alpha_rpcc: read process cycle counter (XXX INSTRUCTION, NOT PALcode OP)
+ */
+ .text
+LEAF(alpha_rpcc,1)
+ rpcc v0
+ RET
+ END(alpha_rpcc)
+
+/*
+ * alpha_mb: memory barrier (XXX INSTRUCTION, NOT PALcode OP)
+ */
+ .text
+LEAF(alpha_mb,0)
+ mb
+ RET
+ END(alpha_mb)
+
+/*
+ * alpha_wmb: write memory barrier (XXX INSTRUCTION, NOT PALcode OP)
+ */
+ .text
+LEAF(alpha_wmb,0)
+ /* wmb XXX */
+ mb /* XXX */
+ RET
+ END(alpha_wmb)
+
+/*
+ * alpha_amask: read architecture features (XXX INSTRUCTION, NOT PALcode OP)
+ *
+ * Arguments:
+ * a0 bitmask of features to test
+ *
+ * Returns:
+ * v0 bitmask - bit is _cleared_ if feature is supported
+ */
+ .text
+LEAF(alpha_amask,1)
+ amask a0, v0
+ RET
+ END(alpha_amask)
+
+/*
+ * alpha_implver: read implementation version (XXX INSTRUCTION, NOT PALcode OP)
+ *
+ * Returns:
+ * v0 implementation version - see <machine/alpha_cpu.h>
+ */
+ .text
+LEAF(alpha_implver,0)
+#if 0
+ implver 0x1, v0
+#else
+ .long 0x47e03d80 /* XXX gas(1) does the Wrong Thing */
+#endif
+ RET
+ END(alpha_implver)
+
+/*
+ * alpha_pal_imb: I-Stream memory barrier. [UNPRIVILEGED]
+ * (Makes instruction stream coherent with data stream.)
+ */
+ .text
+LEAF(alpha_pal_imb,0)
+ call_pal PAL_imb
+ RET
+ END(alpha_pal_imb)
+
+/*
+ * alpha_pal_cflush: Cache flush [PRIVILEGED]
+ *
+ * Flush the entire physical page specified by the PFN specified in
+ * a0 from any data caches associated with the current processor.
+ *
+ * Arguments:
+ * a0 page frame number of page to flush
+ */
+ .text
+LEAF(alpha_pal_cflush,1)
+ call_pal PAL_cflush
+ RET
+ END(alpha_pal_cflush)
+
+/*
+ * alpha_pal_draina: Drain aborts. [PRIVILEGED]
+ */
+ .text
+LEAF(alpha_pal_draina,0)
+ call_pal PAL_draina
+ RET
+ END(alpha_pal_draina)
+
+/*
+ * alpha_pal_halt: Halt the processor. [PRIVILEGED]
+ */
+ .text
+LEAF(alpha_pal_halt,0)
+ call_pal PAL_halt
+ br zero,alpha_pal_halt /* Just in case */
+ RET
+ END(alpha_pal_halt)
+
+/*
+ * alpha_pal_rdmces: Read MCES processor register. [PRIVILEGED]
+ *
+ * Return:
+ * v0 current MCES value
+ */
+ .text
+LEAF(alpha_pal_rdmces,1)
+ call_pal PAL_OSF1_rdmces
+ RET
+ END(alpha_pal_rdmces)
+
+/*
+ * alpha_pal_rdps: Read processor status. [PRIVILEGED]
+ *
+ * Return:
+ * v0 current PS value
+ */
+ .text
+LEAF(alpha_pal_rdps,0)
+ call_pal PAL_OSF1_rdps
+ RET
+ END(alpha_pal_rdps)
+
+/*
+ * alpha_pal_rdusp: Read user stack pointer. [PRIVILEGED]
+ *
+ * Return:
+ * v0 current user stack pointer
+ */
+ .text
+LEAF(alpha_pal_rdusp,0)
+ call_pal PAL_OSF1_rdusp
+ RET
+ END(alpha_pal_rdusp)
+
+/*
+ * alpha_pal_rdval: Read system value. [PRIVILEGED]
+ *
+ * Returns the sysvalue in v0, allowing access to a 64-bit
+ * per-processor value for use by the operating system.
+ *
+ * Return:
+ * v0 sysvalue
+ */
+ .text
+LEAF(alpha_pal_rdval,0)
+ call_pal PAL_OSF1_rdval
+ RET
+ END(alpha_pal_rdval)
+
+/*
+ * alpha_pal_swpipl: Swap Interrupt priority level. [PRIVILEGED]
+ * _alpha_pal_swpipl: Same, from profiling code. [PRIVILEGED]
+ *
+ * Arguments:
+ * a0 new IPL
+ *
+ * Return:
+ * v0 old IPL
+ */
+ .text
+LEAF(alpha_pal_swpipl,1)
+ call_pal PAL_OSF1_swpipl
+ RET
+ END(alpha_pal_swpipl)
+
+LEAF_NOPROFILE(_alpha_pal_swpipl,1)
+ call_pal PAL_OSF1_swpipl
+ RET
+ END(_alpha_pal_swpipl)
+
+/*
+ * alpha_pal_tbi: Translation buffer invalidate. [PRIVILEGED]
+ *
+ * Arguments:
+ * a0 operation selector
+ * a1 address to operate on (if necessary)
+ */
+ .text
+LEAF(alpha_pal_tbi,2)
+ call_pal PAL_OSF1_tbi
+ RET
+ END(alpha_pal_tbi)
+
+/*
+ * alpha_pal_whami: Who am I? [PRIVILEGED]
+ *
+ * Return:
+ * v0 processor number
+ */
+ .text
+LEAF(alpha_pal_whami,0)
+ call_pal PAL_OSF1_whami
+ RET
+ END(alpha_pal_whami)
+
+/*
+ * alpha_pal_wrent: Write system entry address. [PRIVILEGED]
+ *
+ * Arguments:
+ * a0 new vector
+ * a1 vector selector
+ */
+ .text
+LEAF(alpha_pal_wrent,2)
+ call_pal PAL_OSF1_wrent
+ RET
+ END(alpha_pal_wrent)
+
+/*
+ * alpha_pal_wrfen: Write floating-point enable. [PRIVILEGED]
+ *
+ * Arguments:
+ * a0 new enable value (val & 0x1 -> enable).
+ */
+ .text
+LEAF(alpha_pal_wrfen,1)
+ call_pal PAL_OSF1_wrfen
+ RET
+ END(alpha_pal_wrfen)
+
+/*
+ * alpha_pal_wripir: Write interprocessor interrupt request. [PRIVILEGED]
+ *
+ * Generate an interprocessor interrupt on the processor specified by
+ * processor number in a0.
+ *
+ * Arguments:
+ * a0 processor to interrupt
+ */
+ .text
+LEAF(alpha_pal_wripir,1)
+ call_pal PAL_ipir
+ RET
+ END(alpha_pal_wripir)
+
+/*
+ * alpha_pal_wrusp: Write user stack pointer. [PRIVILEGED]
+ *
+ * Arguments:
+ * a0 new user stack pointer
+ */
+ .text
+LEAF(alpha_pal_wrusp,1)
+ call_pal PAL_OSF1_wrusp
+ RET
+ END(alpha_pal_wrusp)
+
+/*
+ * alpha_pal_wrvptptr: Write virtual page table pointer. [PRIVILEGED]
+ *
+ * Arguments:
+ * a0 new virtual page table pointer
+ */
+ .text
+LEAF(alpha_pal_wrvptptr,1)
+ call_pal PAL_OSF1_wrvptptr
+ RET
+ END(alpha_pal_wrvptptr)
+
+/*
+ * alpha_pal_wrmces: Write MCES processor register. [PRIVILEGED]
+ *
+ * Arguments:
+ * a0 value to write to MCES
+ */
+ .text
+LEAF(alpha_pal_wrmces,1)
+ call_pal PAL_OSF1_wrmces
+ RET
+ END(alpha_pal_wrmces)
+
+/*
+ * alpha_pal_wrval: Write system value. [PRIVILEGED]
+ *
+ * Write the value passed in a0 to this processor's sysvalue.
+ *
+ * Arguments:
+ * a0 value to write to sysvalue
+ */
+LEAF(alpha_pal_wrval,1)
+ call_pal PAL_OSF1_wrval
+ RET
+ END(alpha_pal_wrval)
+
+/*
+ * alpha_pal_swpctx: Swap context. [PRIVILEGED]
+ *
+ * Switch to a new process context.
+ *
+ * Arguments:
+ * a0 physical address of hardware PCB describing context
+ *
+ * Returns:
+ * v0 physical address of hardware PCB describing previous context
+ */
+LEAF(alpha_pal_swpctx,1)
+ call_pal PAL_OSF1_swpctx
+ RET
+ END(alpha_pal_swpctx)
diff --git a/sys/boot/alpha/libalpha/prom.c b/sys/boot/alpha/libalpha/prom.c
new file mode 100644
index 0000000..535ce31
--- /dev/null
+++ b/sys/boot/alpha/libalpha/prom.c
@@ -0,0 +1,165 @@
+/* $Id$ */
+/* $NetBSD: prom.c,v 1.3 1997/09/06 14:03:58 drochner Exp $ */
+
+/*
+ * Mach Operating System
+ * Copyright (c) 1992 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+
+#include <sys/types.h>
+
+#include <machine/prom.h>
+#include <machine/rpb.h>
+
+#include "common.h"
+#include "bootstrap.h"
+
+int console;
+
+static void prom_probe(struct console *cp);
+static int prom_init(int);
+void prom_putchar(int);
+int prom_getchar(void);
+static int prom_poll(void);
+
+struct console promconsole = {
+ "prom",
+ "SRM firmware console",
+ 0,
+ prom_probe,
+ prom_init,
+ prom_putchar,
+ prom_getchar,
+ prom_poll,
+};
+
+void
+init_prom_calls()
+{
+ extern struct prom_vec prom_dispatch_v;
+ struct rpb *r;
+ struct crb *c;
+ char buf[4];
+
+ r = (struct rpb *)HWRPB_ADDR;
+ c = (struct crb *)((u_int8_t *)r + r->rpb_crb_off);
+
+ prom_dispatch_v.routine_arg = c->crb_v_dispatch;
+ prom_dispatch_v.routine = c->crb_v_dispatch->entry_va;
+
+ /* Look for console tty. */
+ prom_getenv(PROM_E_TTY_DEV, buf, 4);
+ console = buf[0] - '0';
+}
+
+static void
+prom_probe(struct console *cp)
+{
+ init_prom_calls();
+ cp->c_flags |= C_PRESENTIN|C_PRESENTOUT;
+}
+
+static int
+prom_init(int arg)
+{
+ return 0;
+}
+
+void
+prom_putchar(int c)
+{
+ prom_return_t ret;
+ char cbuf;
+
+ cbuf = c;
+ do {
+ ret.bits = prom_dispatch(PROM_R_PUTS, console, &cbuf, 1);
+ } while ((ret.u.retval & 1) == 0);
+}
+
+static int saved_char = -1;
+
+int
+prom_getchar()
+{
+ prom_return_t ret;
+
+ if (saved_char != -1) {
+ int c = saved_char;
+ saved_char = -1;
+ return c;
+ }
+
+ for (;;) {
+ ret.bits = prom_dispatch(PROM_R_GETC, console);
+ if (ret.u.status == 0 || ret.u.status == 1)
+ return (ret.u.retval);
+ }
+}
+
+int
+prom_poll()
+{
+ prom_return_t ret;
+
+ if (saved_char != -1)
+ return 1;
+
+ ret.bits = prom_dispatch(PROM_R_GETC, console);
+ if (ret.u.status == 0 || ret.u.status == 1) {
+ saved_char = ret.u.retval;
+ return 1;
+ }
+
+ return 0;
+}
+
+int
+prom_getenv(id, buf, len)
+ int id, len;
+ char *buf;
+{
+ prom_return_t ret;
+
+ ret.bits = prom_dispatch(PROM_R_GETENV, id, buf, len-1);
+ if (ret.u.status & 0x4)
+ ret.u.retval = 0;
+ buf[ret.u.retval] = '\0';
+
+ return (ret.u.retval);
+}
+
+int
+prom_open(dev, len)
+ char *dev;
+ int len;
+{
+ prom_return_t ret;
+
+ ret.bits = prom_dispatch(PROM_R_OPEN, dev, len);
+ if (ret.u.status & 0x4)
+ return (-1);
+ else
+ return (ret.u.retval);
+}
diff --git a/sys/boot/alpha/libalpha/prom_disp.S b/sys/boot/alpha/libalpha/prom_disp.S
new file mode 100644
index 0000000..6d5e087
--- /dev/null
+++ b/sys/boot/alpha/libalpha/prom_disp.S
@@ -0,0 +1,118 @@
+/*
+ * $Id$
+ * From: $NetBSD: prom_disp.S,v 1.2 1997/04/06 08:41:00 cgd Exp $
+ */
+
+/*
+ * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#ifndef _LOCORE
+#define ASSEMBLER
+#include <machine/asm.h>
+#include <machine/prom.h>
+#include <machine/rpb.h>
+#endif
+
+ .globl prom_dispatch_v
+ .comm prom_dispatch_v,16
+
+ .text
+ .align 4
+
+/*
+ * Dispatcher routine. Implements prom's calling machinery, saves our
+ * callee-saved registers as required by C.
+ */
+#define D_RA (7*8)
+#define D_S0 (8*8)
+#define D_S1 (9*8)
+#define D_S2 (10*8)
+#define D_S3 (11*8)
+#define D_S4 (12*8)
+#define D_S5 (13*8)
+#define D_S6 (14*8)
+#define DISPATCH_FRAME_SIZE (15*8)
+#define DISPATCH_REGS IM_RA|IM_S0|IM_S1|IM_S2|IM_S3|IM_S4|IM_S5|IM_S6
+
+NESTED(prom_dispatch, 5, DISPATCH_FRAME_SIZE, ra, DISPATCH_REGS, 0)
+ LDGP(pv)
+
+ lda sp, -DISPATCH_FRAME_SIZE(sp)
+ stq ra, D_RA(sp)
+ stq s0, D_S0(sp)
+ stq s1, D_S1(sp)
+ stq s2, D_S2(sp)
+ stq s3, D_S3(sp)
+ stq s4, D_S4(sp)
+ stq s5, D_S5(sp)
+ stq s6, D_S6(sp)
+
+ /* Lord have mercy because.. I would not. */
+/* #define STUPID_PROM_IS_32_BITS */
+#ifdef STUPID_PROM_IS_32_BITS
+ ldah s0, 0x2000(zero) /* hack for hack */
+ lda s0, (0x2000-8)(s0)
+
+ stq sp, 0(s0)
+ or s0, zero, sp
+#endif /* STUPID_PROM_IS_32_BITS */
+
+ lda pv, prom_dispatch_v
+ ldq v0, 0(pv) /* routine */
+ ldq pv, 8(pv) /* routine_arg */
+
+ jsr ra, (v0)
+
+#ifdef STUPID_PROM_IS_32_BITS
+ ldah s0, 0x2000(zero) /* hack for hack */
+ lda s0, (0x2000-8)(s0)
+
+ ldq sp, 0(s0)
+#endif /* STUPID_PROM_IS_32_BITS */
+
+ ldq ra, D_RA(sp)
+ ldq s0, D_S0(sp)
+ ldq s1, D_S1(sp)
+ ldq s2, D_S2(sp)
+ ldq s3, D_S3(sp)
+ ldq s4, D_S4(sp)
+ ldq s5, D_S5(sp)
+ ldq s6, D_S6(sp)
+ lda sp, DISPATCH_FRAME_SIZE(sp)
+ RET
+END(prom_dispatch)
+
+#undef D_RA
+#undef D_S0
+#undef D_S1
+#undef D_S2
+#undef D_S3
+#undef D_S4
+#undef D_S5
+#undef D_S6
+#undef DISPATCH_FRAME_SIZE
+#undef DISPATCH_REGS
diff --git a/sys/boot/alpha/libalpha/prom_swpal.S b/sys/boot/alpha/libalpha/prom_swpal.S
new file mode 100644
index 0000000..b4d3cac
--- /dev/null
+++ b/sys/boot/alpha/libalpha/prom_swpal.S
@@ -0,0 +1,139 @@
+/*
+ * $Id$
+ * From: $NetBSD: prom_swpal.S,v 1.2 1997/04/06 08:41:01 cgd Exp $
+ */
+
+/*
+ * Copyright (c) 1994, 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Keith Bostic
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#define ASSEMBLER
+#include <machine/asm.h>
+#include <machine/prom.h>
+#include <machine/rpb.h>
+
+/* Offsets from base of HWRPB. */
+#define RPB_SELFREF 0x00
+#define RPB_SLOTSIZE 0x98
+#define RPB_PERCPU_OFF 0xA0
+
+/* Offsets in a boot PCB. */
+#define PCB_KSP 0x00
+#define PCB_PTBR 0x10
+#define PCB_ASN 0x1c
+#define PCB_FEN 0x28
+
+/* Pal values. */
+#define PAL_RESERVED 0 /* Reserved to Digital. */
+#define PAL_VMS 1 /* VMS */
+#define PAL_OSF 2 /* OSF */
+
+/*
+ * PAL code switch routine.
+ */
+#define D_RA (7*8)
+#define D_S0 (8*8)
+#define D_S1 (9*8)
+#define D_S2 (10*8)
+#define D_S3 (11*8)
+#define D_S4 (12*8)
+#define D_S5 (13*8)
+#define PALSW_FRAME_SIZE (14*8)
+#define PALSW_REGS IM_RA|IM_S0|IM_S1|IM_S2|IM_S3|IM_S4|IM_S5
+
+ .comm ptbr_save,8
+
+ .text
+ .align 4
+
+NESTED(switch_palcode, 0, PALSW_FRAME_SIZE, ra, PALSW_REGS, 0)
+ LDGP(pv)
+/* ldgp gp, 0(pv)*/
+
+ lda sp, -PALSW_FRAME_SIZE(sp)
+ stq ra, D_RA(sp)
+ stq s0, D_S0(sp)
+ stq s1, D_S1(sp)
+ stq s2, D_S2(sp)
+ stq s3, D_S3(sp)
+ stq s4, D_S4(sp)
+ stq s5, D_S5(sp)
+
+ stq pv, 0(sp)
+ stq gp, 8(sp)
+
+ ldiq s0, HWRPB_ADDR /* s0 HWRPB_ADDR */
+ ldq s1, RPB_SLOTSIZE(s0)
+ call_pal PAL_VMS_mfpr_whami
+ mulq s1, v0, s1 /* s1 per_cpu offset from base */
+ ldq s2, RPB_PERCPU_OFF(s0)
+ addq s0, s2, s2
+ addq s2, s1, s2 /* s2 PCB (virtual) */
+
+ call_pal PAL_VMS_mfpr_ptbr
+ stq v0, PCB_PTBR(s2)
+ stq v0, ptbr_save /* save PTBR for the kernel */
+ stl zero, PCB_ASN(s2)
+ stq zero, PCB_FEN(s2)
+ stq sp, PCB_KSP(s2)
+
+ ldq t0, RPB_SELFREF(s0) /* HWRBP base (physical) */
+ ldq t1, RPB_PERCPU_OFF(s0)
+ addq t0, t1, t0
+ addq t0, s1, t0 /* PCB base (phys) */
+ stq t0, 16(sp)
+
+ call_pal PAL_VMS_mfpr_vptb
+ mov v0, a3
+ ldiq a0, PAL_OSF
+ lda a1, contin
+ ldq a2, 16(sp)
+
+ call_pal PAL_swppal /* a0, a1, a2, a3 */
+
+contin: ldq pv, 0(sp)
+ ldq gp, 8(sp)
+
+ ldq ra, D_RA(sp)
+ ldq s0, D_S0(sp)
+ ldq s1, D_S1(sp)
+ ldq s2, D_S2(sp)
+ ldq s3, D_S3(sp)
+ ldq s4, D_S4(sp)
+ ldq s5, D_S5(sp)
+ lda sp, PALSW_FRAME_SIZE(sp)
+ RET
+END(switch_palcode)
+
+#undef D_RA
+#undef D_S0
+#undef D_S1
+#undef D_S2
+#undef D_S3
+#undef D_S4
+#undef D_S5
+#undef PALSW_FRAME_SIZE
+#undef PALSW_REGS
diff --git a/sys/boot/alpha/libalpha/reboot.c b/sys/boot/alpha/libalpha/reboot.c
new file mode 100644
index 0000000..35750ec
--- /dev/null
+++ b/sys/boot/alpha/libalpha/reboot.c
@@ -0,0 +1,48 @@
+/*-
+ * Copyright (c) 1998 Doug Rabson
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $Id$
+ */
+
+#include <stand.h>
+#include <machine/rpb.h>
+
+void
+reboot(void)
+{
+ struct rpb *hwrpb = (struct rpb *)HWRPB_ADDR;
+ struct pcs *pcs = LOCATE_PCS(hwrpb, hwrpb->rpb_primary_cpu_id);
+ pcs->pcs_flags |= PCS_HALT_WARM_BOOT;
+ alpha_pal_halt();
+}
+
+void
+exit(int code)
+{
+ struct rpb *hwrpb = (struct rpb *)HWRPB_ADDR;
+ struct pcs *pcs = LOCATE_PCS(hwrpb, hwrpb->rpb_primary_cpu_id);
+ pcs->pcs_flags |= PCS_HALT_STAY_HALTED;
+ alpha_pal_halt();
+}
diff --git a/sys/boot/alpha/libalpha/srmdisk.c b/sys/boot/alpha/libalpha/srmdisk.c
new file mode 100644
index 0000000..f7427bd
--- /dev/null
+++ b/sys/boot/alpha/libalpha/srmdisk.c
@@ -0,0 +1,334 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * Copyright (c) 1998 Doug Rabson <dfr@freebsd.org>
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $Id$
+ */
+
+/*
+ * SRM disk device handling.
+ *
+ * Ideas and algorithms from:
+ *
+ * - NetBSD libi386/biosdisk.c
+ * - FreeBSD biosboot/disk.c
+ *
+ * XXX Todo: add bad144 support.
+ */
+
+#include <stand.h>
+
+#include <sys/disklabel.h>
+#include <sys/diskslice.h>
+
+#include <machine/stdarg.h>
+#include <machine/prom.h>
+
+#include "libalpha.h"
+
+#define SRMDISK_SECSIZE 512
+
+#define BUFSIZE (1 * SRMDISK_SECSIZE)
+#define MAXBDDEV MAXDEV
+
+#ifdef DISK_DEBUG
+# define D(x) x
+#else
+# define D(x)
+#endif
+
+static int bd_init(void);
+static int bd_strategy(void *devdata, int flag, daddr_t dblk, size_t size, void *buf, size_t *rsize);
+static int bd_open(struct open_file *f, void *vdev);
+static int bd_close(struct open_file *f);
+
+struct open_disk {
+ int od_fd;
+ int od_unit; /* our unit number */
+ int od_boff; /* block offset from beginning of SRM disk */
+ int od_flags;
+#define BD_MODEMASK 0x3
+#define BD_MODEINT13 0x0
+#define BD_MODEEDD1 0x1
+#define BD_MODEEDD3 0x2
+#define BD_FLOPPY (1<<2)
+ u_char od_buf[BUFSIZE]; /* transfer buffer (do we want/need this?) */
+};
+
+struct devsw srmdisk = {
+ "disk",
+ DEVT_DISK,
+ bd_init,
+ bd_strategy,
+ bd_open,
+ bd_close,
+ noioctl
+};
+
+/*
+ * List of SRM devices, translation from disk unit number to
+ * SRM unit number.
+ */
+static struct
+{
+ char bd_name[64];
+ int bd_unit; /* SRM unit number */
+ int bd_namelen;
+ int bd_flags;
+} bdinfo [MAXBDDEV];
+static int nbdinfo = 0;
+
+/*
+ * Quiz SRM for disk devices, save a little info about them.
+ */
+static int
+bd_init(void)
+{
+ prom_return_t ret;
+ char devname[64];
+
+ bdinfo[0].bd_unit = 0; /* XXX */
+ bdinfo[0].bd_flags = 0; /* XXX */
+ ret.bits = prom_getenv(PROM_E_BOOTED_DEV,
+ bdinfo[0].bd_name, sizeof(bdinfo[0].bd_name));
+ bdinfo[0].bd_namelen = ret.u.retval;
+ nbdinfo++;
+
+ return (0);
+}
+
+/*
+ * Attempt to open the disk described by (dev) for use by (f).
+ *
+ * Note that the philosophy here is "give them exactly what
+ * they ask for". This is necessary because being too "smart"
+ * about what the user might want leads to complications.
+ * (eg. given no slice or partition value, with a disk that is
+ * sliced - are they after the first BSD slice, or the DOS
+ * slice before it?)
+ */
+static int
+bd_open(struct open_file *f, void *vdev)
+{
+ struct alpha_devdesc *dev = vdev;
+ struct dos_partition *dptr;
+ struct open_disk *od;
+ struct disklabel *lp;
+ int sector, slice, i;
+ int error;
+ int unit;
+ prom_return_t ret;
+
+ unit = dev->d_kind.srmdisk.unit;
+ if (unit >= nbdinfo) {
+ D(printf("attempt to open nonexistent disk\n"));
+ return(ENXIO);
+ }
+
+ /* Call the prom to open the disk. */
+ ret.bits = prom_open(bdinfo[unit].bd_name, bdinfo[unit].bd_namelen);
+ if (ret.u.status == 2)
+ return (ENXIO);
+ if (ret.u.status == 3)
+ return (EIO);
+
+ od = (struct open_disk *) malloc(sizeof(struct open_disk));
+ if (!od) {
+ D(printf("srmdiskopen: no memory\n"));
+ return (ENOMEM);
+ }
+
+ /* Look up SRM unit number, intialise open_disk structure */
+ od->od_fd = ret.u.retval;
+ od->od_unit = dev->d_kind.srmdisk.unit;
+ od->od_flags = bdinfo[od->od_unit].bd_flags;
+ od->od_boff = 0;
+ error = 0;
+
+#if 0
+ /* Get geometry for this open (removable device may have changed) */
+ if (set_geometry(&od->od_ll)) {
+ D(printf("bd_open: can't get geometry\n"));
+ error = ENXIO;
+ goto out;
+ }
+#endif
+
+ /*
+ * Following calculations attempt to determine the correct value
+ * for d->od_boff by looking for the slice and partition specified,
+ * or searching for reasonable defaults.
+ */
+
+#if 0
+ /*
+ * Find the slice in the DOS slice table.
+ */
+ if (readsects(&od->od_ll, 0, 1, od->od_buf, 0)) {
+ D(printf("bd_open: error reading MBR\n"));
+ error = EIO;
+ goto out;
+ }
+
+ /*
+ * Check the slice table magic.
+ */
+ if ((od->od_buf[0x1fe] != 0xff) || (od->od_buf[0x1ff] != 0xaa)) {
+ /* If a slice number was explicitly supplied, this is an error */
+ if (dev->d_kind.srmdisk.slice > 0) {
+ D(printf("bd_open: no slice table/MBR (no magic)\n"));
+ error = ENOENT;
+ goto out;
+ }
+ sector = 0;
+ goto unsliced; /* may be a floppy */
+ }
+ dptr = (struct dos_partition *) & od->od_buf[DOSPARTOFF];
+
+ /*
+ * XXX No support here for 'extended' slices
+ */
+ if (dev->d_kind.srmdisk.slice <= 0) {
+ /*
+ * Search for the first FreeBSD slice; this also works on "unsliced"
+ * disks, as they contain a "historically bogus" MBR.
+ */
+ for (i = 0; i < NDOSPART; i++, dptr++)
+ if (dptr->dp_typ == DOSPTYP_386BSD) {
+ sector = dptr->dp_start;
+ break;
+ }
+ /* Did we find something? */
+ if (sector == -1) {
+ error = ENOENT;
+ goto out;
+ }
+ } else {
+ /*
+ * Accept the supplied slice number unequivocally (we may be looking
+ * for a DOS partition) if we can handle it.
+ */
+ if ((dev->d_kind.srmdisk.slice > NDOSPART) || (dev->d_kind.srmdisk.slice < 1)) {
+ error = ENOENT;
+ goto out;
+ }
+ dptr += (dev->d_kind.srmdisk.slice - 1);
+ sector = dptr->dp_start;
+ }
+ unsliced:
+
+#else
+ sector = 0;
+#endif
+ /*
+ * Now we have the slice, look for the partition in the disklabel if we have
+ * a partition to start with.
+ */
+ if (dev->d_kind.srmdisk.partition < 0) {
+ od->od_boff = sector; /* no partition, must be after the slice */
+ } else {
+ if (bd_strategy(od, F_READ, sector + LABELSECTOR, 512, od->od_buf, 0)) {
+ D(printf("bd_open: error reading disklabel\n"));
+ error = EIO;
+ goto out;
+ }
+ lp = (struct disklabel *) (od->od_buf + LABELOFFSET);
+ if (lp->d_magic != DISKMAGIC) {
+ D(printf("bd_open: no disklabel\n"));
+ error = ENOENT;
+ goto out;
+
+ } else if (dev->d_kind.srmdisk.partition >= lp->d_npartitions) {
+
+ /*
+ * The partition supplied is out of bounds; this is fatal.
+ */
+ D(printf("partition '%c' exceeds partitions in table (a-'%c')\n",
+ 'a' + dev->d_kind.srmdisk.partition, 'a' + lp->d_npartitions));
+ error = EPART;
+ goto out;
+
+ } else {
+
+ /*
+ * Complain if the partition type is wrong and it shouldn't be, but
+ * regardless accept this partition.
+ */
+ D(if ((lp->d_partitions[dev->d_kind.srmdisk.partition].p_fstype == FS_UNUSED) &&
+ !(od->od_flags & BD_FLOPPY)) /* Floppies often have bogus fstype */
+ printf("bd_open: warning, partition marked as unused\n"););
+
+ od->od_boff = lp->d_partitions[dev->d_kind.srmdisk.partition].p_offset;
+ }
+ }
+ /*
+ * Save our context
+ */
+ f->f_devdata = od;
+
+ out:
+ if (error)
+ free(od);
+ return(error);
+}
+
+static int
+bd_close(struct open_file *f)
+{
+ struct open_disk *od = f->f_devdata;
+
+ (void)prom_close(od->od_fd);
+
+ free(od);
+ f->f_devdata = NULL;
+ return(0);
+}
+
+static int
+bd_strategy(void *devdata, int flag, daddr_t dblk, size_t size, void *buf, size_t *rsize)
+{
+ prom_return_t ret;
+ struct open_disk *od = (struct open_disk *)devdata;
+
+ if (size % SRMDISK_SECSIZE)
+ panic("bd_strategy: I/O not block multiple");
+
+ if (flag != F_READ)
+ return(EROFS);
+
+ if (rsize)
+ *rsize = 0;
+
+ ret.bits = prom_read(od->od_fd, size, buf, dblk + od->od_boff);
+ if (ret.u.status) {
+ D(printf("read error\n"));
+ return (EIO);
+ }
+
+ if (rsize)
+ *rsize = size;
+ return (0);
+}
+
diff --git a/sys/boot/alpha/libalpha/srmnet.c b/sys/boot/alpha/libalpha/srmnet.c
new file mode 100644
index 0000000..d15fa5f
--- /dev/null
+++ b/sys/boot/alpha/libalpha/srmnet.c
@@ -0,0 +1,257 @@
+/*
+ * $Id$
+ * From: $NetBSD: if_prom.c,v 1.10 1997/09/06 14:08:33 drochner Exp $
+ */
+
+/*
+ * Copyright (c) 1997 Christopher G. Demetriou. All rights reserved.
+ * Copyright (c) 1993 Adam Glass
+ * 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 Adam Glass.
+ * 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 Adam Glass ``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.
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+
+#include <stand.h>
+#include <net.h>
+#include <netif.h>
+#include <machine/prom.h>
+#include "bbinfo.h"
+
+int prom_probe();
+int prom_match();
+void prom_init();
+int prom_get();
+int prom_put();
+void prom_end();
+
+extern struct netif_stats prom_stats[];
+
+struct netif_dif prom_ifs[] = {
+/* dif_unit dif_nsel dif_stats dif_private */
+ { 0, 1, &prom_stats[0], 0, },
+};
+
+struct netif_stats prom_stats[NENTS(prom_ifs)];
+
+struct netbbinfo netbbinfo = {
+ 0xfeedbabedeadbeef, /* magic number */
+ 0, /* set */
+ {0, 0, 0, 0, 0, 0}, /* ether address */
+ 0, /* force */
+ { 0, }, /* pad2 */
+ 0, /* cksum */
+ 0xfeedbeefdeadbabe, /* magic number */
+};
+
+struct netif_driver srmnet = {
+ "prom", /* netif_bname */
+ prom_match, /* netif_match */
+ prom_probe, /* netif_probe */
+ prom_init, /* netif_init */
+ prom_get, /* netif_get */
+ prom_put, /* netif_put */
+ prom_end, /* netif_end */
+ prom_ifs, /* netif_ifs */
+ NENTS(prom_ifs) /* netif_nifs */
+};
+
+int netfd = 0, broken_firmware;
+
+int
+prom_match(nif, machdep_hint)
+ struct netif *nif;
+ void *machdep_hint;
+{
+
+ return (1);
+}
+
+int
+prom_probe(nif, machdep_hint)
+ struct netif *nif;
+ void *machdep_hint;
+{
+
+ return 0;
+}
+
+int
+prom_put(desc, pkt, len)
+ struct iodesc *desc;
+ void *pkt;
+ int len;
+{
+
+ prom_write(netfd, len, pkt, 0);
+
+ return len;
+}
+
+
+int
+prom_get(desc, pkt, len, timeout)
+ struct iodesc *desc;
+ void *pkt;
+ int len;
+ time_t timeout;
+{
+ prom_return_t ret;
+ time_t t;
+ int cc;
+ char hate[2000];
+
+ t = getsecs();
+ cc = 0;
+ while (((getsecs() - t) < timeout) && !cc) {
+ if (broken_firmware)
+ ret.bits = prom_read(netfd, 0, hate, 0);
+ else
+ ret.bits = prom_read(netfd, sizeof hate, hate, 0);
+ if (ret.u.status == 0)
+ cc = ret.u.retval;
+ }
+ if (broken_firmware)
+ cc = min(cc, len);
+ else
+ cc = len;
+ bcopy(hate, pkt, cc);
+
+ return cc;
+}
+
+extern char *strchr();
+
+void
+prom_init(desc, machdep_hint)
+ struct iodesc *desc;
+ void *machdep_hint;
+{
+ prom_return_t ret;
+ char devname[64];
+ int devlen, i;
+ int netbbinfovalid;
+ char *enet_addr;
+ u_int64_t *qp, csum;
+
+ broken_firmware = 0;
+
+ csum = 0;
+ for (i = 0, qp = (u_int64_t *)&netbbinfo;
+ i < (sizeof netbbinfo / sizeof (u_int64_t)); i++, qp++)
+ csum += *qp;
+ netbbinfovalid = (csum == 0);
+ if (netbbinfovalid)
+ netbbinfovalid = netbbinfo.set;
+
+ printf("netbbinfo ");
+ if (!netbbinfovalid)
+ printf("invalid\n");
+ else
+ printf("valid: force = %d, ea = %s\n", netbbinfo.force,
+ ether_sprintf(netbbinfo.ether_addr));
+
+ ret.bits = prom_getenv(PROM_E_BOOTED_DEV, devname, sizeof(devname));
+ devlen = ret.u.retval;
+
+ /* Ethernet address is the 9th component of the booted_dev string. */
+ enet_addr = devname;
+ for (i = 0; i < 8; i++) {
+ enet_addr = strchr(enet_addr, ' ');
+ if (enet_addr == NULL) {
+ printf("boot: boot device name does not contain ethernet address.\n");
+ goto punt;
+ }
+ enet_addr++;
+ }
+ if (enet_addr != NULL) {
+ int hv, lv;
+
+#define dval(c) (((c) >= '0' && (c) <= '9') ? ((c) - '0') : \
+ (((c) >= 'A' && (c) <= 'F') ? (10 + (c) - 'A') : \
+ (((c) >= 'a' && (c) <= 'f') ? (10 + (c) - 'a') : -1)))
+
+ for (i = 0; i < 6; i++) {
+ hv = dval(*enet_addr); enet_addr++;
+ lv = dval(*enet_addr); enet_addr++;
+ enet_addr++;
+
+ if (hv == -1 || lv == -1) {
+ printf("boot: boot device name contains bogus ethernet address.\n");
+ goto punt;
+ }
+
+ desc->myea[i] = (hv << 4) | lv;
+ }
+#undef dval
+ }
+
+ if (netbbinfovalid && netbbinfo.force) {
+ printf("boot: using hard-coded ethernet address (forced).\n");
+ bcopy(netbbinfo.ether_addr, desc->myea, sizeof desc->myea);
+ }
+
+ gotit:
+ printf("boot: ethernet address: %s\n", ether_sprintf(desc->myea));
+
+ ret.bits = prom_open(devname, devlen + 1);
+ if (ret.u.status) {
+ printf("prom_init: open failed: %d\n", ret.u.status);
+ goto reallypunt;
+ }
+ netfd = ret.u.retval;
+ return;
+
+ punt:
+ broken_firmware = 1;
+ if (netbbinfovalid) {
+ printf("boot: using hard-coded ethernet address.\n");
+ bcopy(netbbinfo.ether_addr, desc->myea, sizeof desc->myea);
+ goto gotit;
+ }
+
+ reallypunt:
+ printf("\n");
+ printf("Boot device name was: \"%s\"\n", devname);
+ printf("\n");
+ printf("Your firmware may be too old to network-boot NetBSD/Alpha,\n");
+ printf("or you might have to hard-code an ethernet address into\n");
+ printf("your network boot block with setnetbootinfo(8).\n");
+ halt();
+}
+
+void
+prom_end(nif)
+ struct netif *nif;
+{
+ prom_close(netfd);
+}
diff --git a/sys/boot/alpha/libalpha/start.S b/sys/boot/alpha/libalpha/start.S
new file mode 100644
index 0000000..53063ab
--- /dev/null
+++ b/sys/boot/alpha/libalpha/start.S
@@ -0,0 +1,85 @@
+/*
+ * $Id$
+ * From: $NetBSD: start.S,v 1.4 1998/03/28 00:54:15 cgd Exp $
+ */
+
+/*
+ * Mach Operating System
+ * Copyright (c) 1992 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+
+#include <machine/asm.h>
+
+/*
+ * start --
+ * Entry point for boot/standalone programs.
+ *
+ * Arguments:
+ * a0 long (first free physical page)
+ *
+ * This is where the prom comes to. Leaves all exception and interrupts
+ * to prom, runs off prom's stack too. No return values.
+ */
+ .text
+ .set noreorder /* don't reorder instructions */
+
+#define ENTRY_FRAME 32
+
+NESTED(start, 1, ENTRY_FRAME, ra, 0, 0)
+ br pv,Lstartgp
+Lstartgp:
+ LDGP(pv)
+
+#ifndef PRIMARY_BOOTBLOCK
+ lda sp,start /* start stack below text */
+ lda sp,-ENTRY_FRAME(sp)
+#endif
+
+ lda a0,_edata
+ lda a1,_end
+ subq a1,a0,a1
+ CALL(bzero)
+
+ CALL(main) /* transfer to C */
+
+XLEAF(_rtt, 0)
+XLEAF(halt, 0)
+ call_pal PAL_halt /* halt if we ever return */
+END(start)
+
+/*
+ * Dummy routine for GCC2.
+ */
+LEAF(__main,0)
+ RET
+END(__main)
+
+/*
+ * cpu_number
+ * Return the cpu number, using the whami instruction.
+ */
+LEAF(cpu_number, 0)
+ call_pal PAL_VMS_mfpr_whami
+ RET
+END(cpu_number)
diff --git a/sys/boot/alpha/libalpha/time.c b/sys/boot/alpha/libalpha/time.c
new file mode 100644
index 0000000..7b87d2f
--- /dev/null
+++ b/sys/boot/alpha/libalpha/time.c
@@ -0,0 +1,43 @@
+/*-
+ * Copyright (c) 1998 Doug Rabson
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $Id$
+ */
+
+#include <stand.h>
+
+/*
+ * Can't do this properly without putting PCI chipset drivers into the
+ * bootstrap :-(
+ */
+
+time_t
+time(time_t *tloc)
+{
+ int secs = getsecs();
+ if (tloc)
+ *tloc = secs;
+ return secs;
+}
OpenPOWER on IntegriCloud