summaryrefslogtreecommitdiffstats
path: root/sys/boot/alpha
diff options
context:
space:
mode:
Diffstat (limited to 'sys/boot/alpha')
-rw-r--r--sys/boot/alpha/Makefile6
-rw-r--r--sys/boot/alpha/Makefile.inc9
-rw-r--r--sys/boot/alpha/boot1/Makefile44
-rw-r--r--sys/boot/alpha/boot1/boot1.c278
-rw-r--r--sys/boot/alpha/cdboot/Makefile11
-rw-r--r--sys/boot/alpha/cdboot/version10
-rw-r--r--sys/boot/alpha/common/Makefile.common95
-rw-r--r--sys/boot/alpha/common/conf.c102
-rw-r--r--sys/boot/alpha/common/help.alpha0
-rw-r--r--sys/boot/alpha/common/main.c244
-rw-r--r--sys/boot/alpha/libalpha/Makefile29
-rw-r--r--sys/boot/alpha/libalpha/OSFpal.c73
-rw-r--r--sys/boot/alpha/libalpha/alpha_copy.c57
-rw-r--r--sys/boot/alpha/libalpha/alpha_module.c48
-rw-r--r--sys/boot/alpha/libalpha/bbinfo.h57
-rw-r--r--sys/boot/alpha/libalpha/bootinfo.c233
-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.c236
-rw-r--r--sys/boot/alpha/libalpha/elf_freebsd.c160
-rw-r--r--sys/boot/alpha/libalpha/getsecs.c37
-rw-r--r--sys/boot/alpha/libalpha/libalpha.h82
-rw-r--r--sys/boot/alpha/libalpha/pal.S352
-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.c380
-rw-r--r--sys/boot/alpha/libalpha/srmnet.c259
-rw-r--r--sys/boot/alpha/libalpha/start.S93
-rw-r--r--sys/boot/alpha/libalpha/time.c43
-rw-r--r--sys/boot/alpha/loader/Makefile12
-rw-r--r--sys/boot/alpha/loader/version12
-rw-r--r--sys/boot/alpha/netboot/Makefile13
-rw-r--r--sys/boot/alpha/netboot/version12
35 files changed, 3508 insertions, 0 deletions
diff --git a/sys/boot/alpha/Makefile b/sys/boot/alpha/Makefile
new file mode 100644
index 0000000..e97c8e8
--- /dev/null
+++ b/sys/boot/alpha/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+SUBDIR= libalpha
+SUBDIR+= boot1 loader cdboot netboot
+
+.include <bsd.subdir.mk>
diff --git a/sys/boot/alpha/Makefile.inc b/sys/boot/alpha/Makefile.inc
new file mode 100644
index 0000000..cd9f18a
--- /dev/null
+++ b/sys/boot/alpha/Makefile.inc
@@ -0,0 +1,9 @@
+# $FreeBSD$
+# Options used when building app-specific libalpha components
+PRIMARY_LOAD_ADDRESS= 0x20000000 # "Region 1 start"
+SECONDARY_LOAD_ADDRESS= 0x2000c000 # "Region 1 start" + 48k
+HEAP_LIMIT= 0x20040000 # "Region 1 start" + 256k
+DPADD+= ${DESTDIR}/${LIBDIR}/libstand.a
+LIBSTANDDIR= ${.CURDIR}/../../../../lib/libstand
+LIBSTAND= -lstand
+LIBALPHA= ${.OBJDIR}/../libalpha/libalpha.a
diff --git a/sys/boot/alpha/boot1/Makefile b/sys/boot/alpha/boot1/Makefile
new file mode 100644
index 0000000..d937c17
--- /dev/null
+++ b/sys/boot/alpha/boot1/Makefile
@@ -0,0 +1,44 @@
+# $NetBSD: Makefile,v 1.15 1998/03/28 00:21:35 thorpej Exp $
+# $FreeBSD$
+
+.include <../Makefile.inc>
+
+PROG = boot1
+LINKS = ${BINDIR}/${PROG} ${BINDIR}/boot
+
+.PATH: ${.CURDIR}/../libalpha
+
+SRCS= start.S boot1.c
+CFLAGS+= -ffreestanding -mno-fp-regs
+CFLAGS+= -DSECONDARY_LOAD_ADDRESS=${SECONDARY_LOAD_ADDRESS} -DMINIMAL
+CFLAGS+= -DBOOT1
+CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}
+CFLAGS+= -I${LIBSTANDDIR}
+CFLAGS+= -I${.CURDIR}/..
+NOMAN=1
+STRIP=
+BINDIR?= /boot
+
+BOOT_RELOC = ${PRIMARY_LOAD_ADDRESS}
+
+CLEANFILES+= ${PROG}.sym ${PROG}.nosym ${PROG}.list
+
+all: ${PROG}
+
+${PROG}.nosym: ${PROG}.sym
+ cp ${PROG}.sym ${PROG}.nosym
+ strip ${PROG}.nosym
+
+${PROG}: ${PROG}.nosym
+ objcopy -O binary ${PROG}.nosym ${PROG}
+
+.include <bsd.prog.mk>
+
+start.o: ${.CURDIR}/../libalpha/start.S
+ ${CC} -c ${CFLAGS} $<
+
+${PROG}.sym: ${OBJS} ${LIBKERN}
+ ${LD} -M -Ttext ${BOOT_RELOC} -N -e start -o ${PROG}.sym ${OBJS} \
+ -L${DESTDIR}${LIBDIR} ${LIBSTAND} ${LIBALPHA} ${LIBSTAND} \
+ > ${.OBJDIR}/${PROG}.list
+ size ${PROG}.sym
diff --git a/sys/boot/alpha/boot1/boot1.c b/sys/boot/alpha/boot1/boot1.c
new file mode 100644
index 0000000..9454011
--- /dev/null
+++ b/sys/boot/alpha/boot1/boot1.c
@@ -0,0 +1,278 @@
+/*
+ * $FreeBSD$
+ * From $NetBSD: bootxx.c,v 1.4 1997/09/06 14:08:29 drochner Exp $
+ */
+
+/*
+ * Copyright (c) 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.
+ */
+
+#include <string.h>
+#include <sys/param.h>
+#include <sys/dirent.h>
+
+#include <machine/prom.h>
+#include <machine/rpb.h>
+
+#define DEBUGxx
+
+void puts(const char *s);
+void puthex(u_long v);
+static int dskread(void *, u_int64_t, size_t);
+
+#define printf(...) \
+while (0)
+
+#define memcpy(dst, src, len) \
+bcopy(src, dst, len)
+
+#include "ufsread.c"
+
+extern end[];
+int errno;
+
+char *heap = (char*) end;
+
+void
+bcopy(const void *src, void *dst, size_t len)
+{
+ const char *s;
+ char *d;
+
+ for (d = dst, s = src; len; len--)
+ *d++ = *s++;
+}
+
+void
+putchar(int c)
+{
+ if (c == '\n')
+ prom_putchar('\r');
+ prom_putchar(c);
+}
+
+int
+getchar()
+{
+ return prom_getchar();
+}
+
+int
+ischar()
+{
+ return prom_poll();
+}
+
+void
+puts(const char *s)
+{
+ while (*s)
+ putchar(*s++);
+}
+
+void
+panic(const char *message, ...)
+{
+ puts(message);
+ puts("\r\n");
+ halt();
+}
+
+int prom_fd = 0;
+
+int
+devopen()
+{
+ prom_return_t ret;
+ char devname[64];
+
+ if (prom_fd)
+ return;
+
+ ret.bits = prom_getenv(PROM_E_BOOTED_DEV, devname, sizeof devname);
+
+ ret.bits = prom_open(devname, ret.u.retval + 1);
+ if (ret.u.status)
+ panic("devopen: open failed\n");
+
+ prom_fd = ret.u.retval;
+
+ /* XXX read disklabel and setup partition offset */
+
+ return 0;
+}
+
+#ifdef DEBUG
+
+void
+puthex(u_long v)
+{
+ int digit;
+ char hex[] = "0123456789abcdef";
+
+ puts("0x");
+ if (!v) {
+ puts("0");
+ return;
+ }
+
+ for (digit = 0; v >= (0x10L << digit); digit += 4)
+ ;
+
+ for (; digit >= 0; digit -= 4)
+ putchar(hex[(v >> digit) & 0xf]);
+}
+
+#endif
+
+int
+dskread(void *buf, u_int64_t block, size_t size)
+{
+#ifdef DEBUG
+ puts("dskread(");
+ puthex((u_long)buf);
+ puts(",");
+ puthex(block);
+ puts(",");
+ puthex(size);
+ puts(")\n");
+#endif
+
+ prom_read(prom_fd, size * DEV_BSIZE, buf, block);
+ return (0);
+}
+
+static inline void
+devclose()
+{
+ if (prom_fd) {
+ prom_close(prom_fd);
+ prom_fd = 0;
+ }
+}
+
+static inline void
+getfilename(char *filename, const char *defname)
+{
+ int c;
+ char *p = filename;
+
+ puts("Boot: ");
+
+ while ((c = getchar()) != '\r') {
+ if (c == '\b' || c == 0177) {
+ if (p > filename) {
+ puts("\b \b");
+ p--;
+ }
+ } else {
+ putchar(c);
+ *p++ = c;
+ }
+ }
+ putchar('\n');
+ *p = '\0';
+ if (!*filename)
+ strcpy(filename, defname);
+ return;
+}
+
+static struct dmadat __dmadat;
+
+static inline void
+loadfile(char *name, char *addr)
+{
+ int n;
+ char *p;
+ ino_t ino;
+
+ puts("Loading ");
+ puts(name);
+ puts("\n");
+
+ dmadat = &__dmadat;
+
+ if (devopen() || (ino = lookup(name)) == 0) {
+ puts("Can't open file ");
+ puts(name);
+ puts("\n");
+ halt();
+ }
+
+ p = addr;
+ do {
+ n = fsread(ino, p, VBLKSIZE);
+ if (n < 0) {
+ puts("Can't read file ");
+ puts(name);
+ puts("\n");
+ halt();
+ }
+ p += n;
+ twiddle();
+ } while (n == VBLKSIZE);
+
+ devclose();
+}
+
+static inline u_long rpcc()
+{
+ u_long v;
+ __asm__ __volatile__ ("rpcc %0" : "=r"(v));
+ return v & 0xffffffff;
+}
+
+int
+main()
+{
+ char *loadaddr = (char*) SECONDARY_LOAD_ADDRESS;
+ char *name = "/boot/loader";
+ char *p;
+ char filename[512];
+ void (*entry)(void);
+ u_long start, freq;
+ int i;
+
+ init_prom_calls();
+
+ start = rpcc();
+ freq = ((struct rpb *)HWRPB_ADDR)->rpb_cc_freq;
+ while (((rpcc() - start) & 0xffffffff) < freq) {
+ twiddle();
+ if (ischar()) {
+ getfilename(filename, name);
+ name = filename;
+ break;
+ }
+ }
+
+ loadfile(name, loadaddr);
+
+ entry = (void (*)())loadaddr;
+ (*entry)();
+
+ return 0;
+}
diff --git a/sys/boot/alpha/cdboot/Makefile b/sys/boot/alpha/cdboot/Makefile
new file mode 100644
index 0000000..b4f07bb
--- /dev/null
+++ b/sys/boot/alpha/cdboot/Makefile
@@ -0,0 +1,11 @@
+# $FreeBSD$
+
+BASE= cdboot
+PROG= ${BASE}
+NOMAN=
+NEWVERSWHAT= "SRM CD9660 boot" alpha
+LOAD_ADDRESS= ${PRIMARY_LOAD_ADDRESS}
+
+CFLAGS+= -ffreestanding -DLOADER_CDROM_SUPPORT
+
+.include <${.CURDIR}/../common/Makefile.common>
diff --git a/sys/boot/alpha/cdboot/version b/sys/boot/alpha/cdboot/version
new file mode 100644
index 0000000..028be8b
--- /dev/null
+++ b/sys/boot/alpha/cdboot/version
@@ -0,0 +1,10 @@
+$FreeBSD$
+
+NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this
+file is important. Make sure the current version number is on line 6.
+
+1.2: New calling conventions for fopen.
+1.1: New semantics for finding the kernel, new boot.
+1.0: Released working DEC Alpha version.
+0.1: Initial i386 version, germinated from the NetBSD i386
+ standalone, but enormously modified.
diff --git a/sys/boot/alpha/common/Makefile.common b/sys/boot/alpha/common/Makefile.common
new file mode 100644
index 0000000..ac473a8
--- /dev/null
+++ b/sys/boot/alpha/common/Makefile.common
@@ -0,0 +1,95 @@
+# $FreeBSD$
+#
+# Common Alpha loader build rules
+
+.PATH: ${.CURDIR}/../common
+
+# Alpha-specific bootstrap sources
+SRCS+= main.c conf.c
+.if ${BASE} == netboot
+SRCS+= dev_net.c
+.endif
+
+.if !defined(NOFORTH)
+# Enable BootForth
+BOOT_FORTH= yes
+CFLAGS+= -DBOOT_FORTH
+CFLAGS+= -I${.CURDIR}/../../ficl -I${.CURDIR}/../../ficl/alpha
+.if exists(${.OBJDIR}/../../ficl/libficl.a)
+LIBFICL= ${.OBJDIR}/../../ficl/libficl.a
+.else
+LIBFICL= ${.CURDIR}/../../ficl/libficl.a
+.endif
+.endif
+
+# Always add MI sources
+.PATH: ${.CURDIR}/../../common
+.include <${.CURDIR}/../../common/Makefile.inc>
+CFLAGS+= -mno-fp-regs
+CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}
+CFLAGS+= -I${.CURDIR}/../../.. -I.
+CFLAGS+= -DPRIMARY_LOAD_ADDRESS=${PRIMARY_LOAD_ADDRESS} \
+ -DSECONDARY_LOAD_ADDRESS=${SECONDARY_LOAD_ADDRESS}
+
+CLEANFILES+= setdef0.c setdef0.o setdef1.c setdef1.o setdefs.h start.o \
+ vers.c vers.o ${BASE} ${BASE}.sym ${BASE}.list
+
+CFLAGS+= -Wall
+
+CFLAGS+= -I${LIBSTANDDIR}
+CFLAGS+= -I${.CURDIR}/..
+CRT= start.o
+STRIP=
+BINDIR?= /boot
+INSTALLFLAGS?= -b
+
+all: ${BASE} ${BASE}.help
+
+vers.o: ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version
+ sh ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version ${NEWVERSWHAT}
+ ${CC} -c vers.c
+
+${BASE}: ${OBJS} ${LIBSTAND} ${LIBFICL} ${LIBALPHA} ${CRT} vers.o
+ ${LD} -o ${BASE}.sym -M -e start -N -Ttext ${LOAD_ADDRESS} \
+ ${CRT} ${OBJS} vers.o \
+ -L${DESTDIR}${LIBDIR} ${LIBSTAND} ${LIBALPHA} ${LIBFICL} ${LIBSTAND} \
+ >${.OBJDIR}/${BASE}.list
+ objcopy -O binary ${BASE}.sym ${BASE}
+
+CLEANFILES+= ${BASE}.help
+${BASE}.help: help.common help.alpha
+ cat ${.ALLSRC} | awk -f ${.CURDIR}/../../common/merge_help.awk > ${.TARGET}
+
+beforeinstall:
+.ifdef INSTALL_HELP
+.if exists(${.OBJDIR}/${BASE}.help)
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \
+ ${.OBJDIR}/${BASE}.help ${DESTDIR}/boot
+.else
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \
+ ${.CURDIR}/${BASE}.help ${DESTDIR}/boot
+.endif
+.endif
+.if !exists(${DESTDIR}/boot/loader.rc)
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \
+ ${.CURDIR}/../../forth/loader.rc ${DESTDIR}/boot
+.endif
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \
+ ${.CURDIR}/../../forth/loader.4th ${DESTDIR}/boot
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \
+ ${.CURDIR}/../../forth/support.4th ${DESTDIR}/boot
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \
+ ${.CURDIR}/../../forth/loader.conf ${DESTDIR}/boot/defaults
+
+
+start.o: ${.CURDIR}/../libalpha/start.S
+ ${CC} -c ${CFLAGS} $<
+
+machine:
+ ln -sf ${.CURDIR}/../../../alpha/include machine
+
+CLEANFILES+= machine
+
+.include <bsd.prog.mk>
+
+beforedepend ${OBJS}: machine
diff --git a/sys/boot/alpha/common/conf.c b/sys/boot/alpha/common/conf.c
new file mode 100644
index 0000000..8db3ff7
--- /dev/null
+++ b/sys/boot/alpha/common/conf.c
@@ -0,0 +1,102 @@
+/*-
+ * Copyright (c) 1999 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.
+ *
+ * $FreeBSD$
+ */
+
+#include <stand.h>
+#include "libalpha/libalpha.h"
+#ifdef LOADER_NET_SUPPORT
+#include "dev_net.h"
+#endif
+
+/*
+ * We could use linker sets for some or all of these, but
+ * then we would have to control what ended up linked into
+ * the bootstrap. So it's easier to conditionalise things
+ * here.
+ *
+ * XXX rename these arrays to be consistent and less namespace-hostile
+ */
+
+/* Exported for libstand */
+struct devsw *devsw[] = {
+#if defined(LOADER_DISK_SUPPORT) || defined(LOADER_CDROM_SUPPORT)
+ &srmdisk,
+#endif
+#ifdef LOADER_NET_SUPPORT
+ &netdev,
+#endif
+ NULL
+};
+
+struct fs_ops *file_system[] = {
+#ifdef LOADER_DISK_SUPPORT
+ &ufs_fsops,
+#endif
+#ifdef LOADER_CDROM_SUPPORT
+ &cd9660_fsops,
+#endif
+#ifdef LOADER_EXT2FS_SUPPORT
+ &ext2fs_fsops,
+#endif
+#ifdef LOADER_NET_SUPPORT
+ &nfs_fsops,
+#endif
+ &gzipfs_fsops,
+ NULL
+};
+
+#ifdef LOADER_NET_SUPPORT
+struct netif_driver *netif_drivers[] = {
+ &srmnet,
+ NULL,
+};
+#endif
+
+/* Exported for alpha only */
+/*
+ * Sort formats so that those that can detect based on arguments
+ * rather than reading the file go first.
+ */
+extern struct file_format alpha_elf;
+
+struct file_format *file_formats[] = {
+ &alpha_elf,
+ NULL
+};
+
+/*
+ * Consoles
+ *
+ * We don't prototype these in libalpha.h because they require
+ * data structures from bootstrap.h as well.
+ */
+extern struct console promconsole;
+
+struct console *consoles[] = {
+ &promconsole,
+ NULL
+};
diff --git a/sys/boot/alpha/common/help.alpha b/sys/boot/alpha/common/help.alpha
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/sys/boot/alpha/common/help.alpha
diff --git a/sys/boot/alpha/common/main.c b/sys/boot/alpha/common/main.c
new file mode 100644
index 0000000..8b5fcff
--- /dev/null
+++ b/sys/boot/alpha/common/main.c
@@ -0,0 +1,244 @@
+/*-
+ * 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.
+ *
+ * $FreeBSD$
+ */
+
+
+#include <stand.h>
+#include <string.h>
+
+#include <sys/param.h>
+#include <machine/rpb.h>
+#include <machine/prom.h>
+#include "bootstrap.h"
+#include "libalpha/libalpha.h"
+
+extern char bootprog_name[], bootprog_rev[], bootprog_date[], bootprog_maker[];
+
+struct alpha_devdesc currdev; /* our current device */
+struct arch_switch archsw; /* MI/MD interface boundary */
+
+extern char end[];
+extern void OSFpal(void);
+extern void halt(void);
+
+unsigned long
+memsize()
+{
+ struct rpb *hwrpb = (struct rpb *)HWRPB_ADDR;
+ struct mddt *mddtp;
+ struct mddt_cluster *memc;
+ int i;
+ unsigned long total = 0;
+
+ mddtp = (struct mddt *)(((caddr_t)hwrpb) + hwrpb->rpb_memdat_off);
+ for (i = 0; i < mddtp->mddt_cluster_cnt; i++) {
+ memc = &mddtp->mddt_clusters[i];
+ total += memc->mddt_pg_cnt << PAGE_SHIFT;
+ }
+ return total;
+}
+
+/* #define XTRA_PAGES 32 */
+#define XTRA_PAGES 64
+
+void
+extend_heap(void)
+{
+ struct rpb *hwrpb = (struct rpb *)HWRPB_ADDR;
+ struct mddt *mddtp;
+ struct mddt_cluster *memc = 0;
+ int i;
+ unsigned long startpfn;
+ vm_offset_t startva;
+ vm_offset_t startpte;
+
+ /*
+ * Find the last usable memory cluster and add some of its pages
+ * to our address space. The 256k allowed by the firmware isn't quite
+ * adequate for our needs.
+ */
+ mddtp = (struct mddt *)(((caddr_t)hwrpb) + hwrpb->rpb_memdat_off);
+ for (i = mddtp->mddt_cluster_cnt - 1; i >= 0; i--) {
+ memc = &mddtp->mddt_clusters[i];
+ if (!(memc->mddt_usage & (MDDT_NONVOLATILE | MDDT_PALCODE)))
+ break;
+ }
+
+ /*
+ * We want to extend the heap from 256k up to XTRA_PAGES more pages.
+ * We take pages from the end of the last usable memory region,
+ * taking care to avoid the memory used by the kernel's message
+ * buffer. We allow 4 pages for the message buffer.
+ */
+ startpfn = memc->mddt_pfn + memc->mddt_pg_cnt - 4 - XTRA_PAGES;
+ startva = 0x20040000;
+ startpte = 0x40000000
+ + (((startva >> 23) & 0x3ff) << PAGE_SHIFT)
+ + (((startva >> 13) & 0x3ff) << 3);
+
+ for (i = 0; i < XTRA_PAGES; i++) {
+ u_int64_t pte;
+ pte = ((startpfn + i) << 32) | 0x1101;
+ *(u_int64_t *) (startpte + 8 * i) = pte;
+ }
+}
+
+int
+main(void)
+{
+ int i;
+ char bootfile[128];
+
+ /*
+ * Initialise the heap as early as possible. Once this is done,
+ * alloc() is usable. The stack is buried inside us, so this is
+ * safe.
+ */
+ setheap((void *)end, (void *)(0x20040000 + XTRA_PAGES * 8192));
+
+#ifdef LOADER
+ /*
+ * If this is the two stage disk loader, add the memory used by
+ * the first stage to the heap.
+ */
+ free_region((void *)PRIMARY_LOAD_ADDRESS,
+ (void *)SECONDARY_LOAD_ADDRESS);
+#endif
+
+ /*
+ * XXX Chicken-and-egg problem; we want to have console output
+ * early, but some console attributes may depend on reading from
+ * eg. the boot device, which we can't do yet. We can use
+ * printf() etc. once this is done.
+ */
+ cons_probe();
+
+ /* switch to OSF pal code. */
+ OSFpal();
+
+ /*
+ * Initialise the block cache
+ */
+ bcache_init(32, 512); /* 16k XXX tune this */
+
+ /*
+ * March through the device switch probing for things.
+ */
+ for (i = 0; devsw[i] != NULL; i++)
+ if (devsw[i]->dv_init != NULL)
+ (devsw[i]->dv_init)();
+
+ printf("\n");
+ printf("%s, Revision %s\n", bootprog_name, bootprog_rev);
+ printf("(%s, %s)\n", bootprog_maker, bootprog_date);
+ printf("Memory: %ld k\n", memsize() / 1024);
+
+ /* We're booting from an SRM disk, try to spiff this */
+ currdev.d_dev = devsw[0]; /* XXX presumes that biosdisk is first in devsw */
+ currdev.d_type = currdev.d_dev->dv_type;
+ currdev.d_kind.srmdisk.unit = 0;
+ currdev.d_kind.srmdisk.slice = -1; /* XXX should be able to detect this, default to autoprobe */
+ currdev.d_kind.srmdisk.partition = 0; /* default to 'a' */
+
+ /* Create alpha-specific variables */
+ prom_getenv(PROM_E_BOOTED_FILE, bootfile, sizeof(bootfile));
+ if (bootfile[0])
+ setenv("bootfile", bootfile, 1);
+ env_setenv("currdev", EV_VOLATILE, alpha_fmtdev(&currdev), alpha_setcurrdev, env_nounset);
+ env_setenv("loaddev", EV_VOLATILE, alpha_fmtdev(&currdev), env_noset, env_nounset);
+ setenv("LINES", "24", 1); /* optional */
+
+ archsw.arch_autoload = alpha_autoload;
+ archsw.arch_getdev = alpha_getdev;
+ archsw.arch_copyin = alpha_copyin;
+ archsw.arch_copyout = alpha_copyout;
+ archsw.arch_readin = alpha_readin;
+
+ /*
+ * SRM firmware takes *ages* to open the disk device. We hold it
+ * open until the closeall() when we exec the kernel. Note that
+ * we must close it eventually since otherwise the firmware leaves
+ * the ncr hardware in a broken state (at least it does on my EB164).
+ */
+ open("/boot", O_RDONLY);
+
+ interact(); /* doesn't return */
+
+ return 0;
+}
+
+COMMAND_SET(reboot, "reboot", "reboot the system", command_reboot);
+
+static int
+command_reboot(int argc, char *argv[])
+{
+
+ printf("Rebooting...\n");
+ delay(1000000);
+ reboot();
+ /* Note: we shouldn't get to this point! */
+ panic("Reboot failed!");
+ exit(0);
+}
+
+COMMAND_SET(halt, "halt", "halt the system", command_halt);
+
+static int
+command_halt(int argc, char *argv[])
+{
+ halt(); /* never returns */
+ return(CMD_OK);
+}
+
+#if 0
+
+COMMAND_SET(stack, "stack", "show stack usage", command_stack);
+
+static int
+command_stack(int argc, char *argv[])
+{
+ char *cp;
+
+ for (cp = &stackbase; cp < &stacktop; cp++)
+ if (*cp != 0)
+ break;
+
+ printf("%d bytes of stack used\n", &stacktop - cp);
+ return(CMD_OK);
+}
+
+#endif
+
+COMMAND_SET(heap, "heap", "show heap usage", command_heap);
+
+static int
+command_heap(int argc, char *argv[])
+{
+ printf("heap base at %p, top at %p, used %ld\n", end, sbrk(0), sbrk(0) - end);
+ return(CMD_OK);
+}
diff --git a/sys/boot/alpha/libalpha/Makefile b/sys/boot/alpha/libalpha/Makefile
new file mode 100644
index 0000000..7bb07cf
--- /dev/null
+++ b/sys/boot/alpha/libalpha/Makefile
@@ -0,0 +1,29 @@
+# $FreeBSD$
+
+LIB= alpha
+INTERNALLIB= true
+
+CFLAGS+= -ffreestanding
+#CFLAGS+= -DDISK_DEBUG
+#CPPFLAGS+= -DNO_DISKLABEL
+#CPPFLAGS+= -DSAVE_MEMORY
+
+# XXX hack to pick up stand.h
+LIBSTANDDIR= ${.CURDIR}/../../../../lib/libstand
+CFLAGS+= -DDEBUG
+CFLAGS+= -I${LIBSTANDDIR}
+
+# Pick up the bootstrap header for some interface items
+CFLAGS+= -I${.CURDIR}/../../common -mno-fp-regs \
+ -I${.CURDIR}/../../.. -I.
+
+SRCS= OSFpal.c elf_freebsd.c prom.c prom_disp.S prom_swpal.S \
+ pal.S reboot.c delay.c time.c alpha_module.c devicename.c \
+ srmdisk.c srmnet.c getsecs.c alpha_copy.c bootinfo.c
+
+machine:
+ ln -sf ${.CURDIR}/../../../alpha/include machine
+
+.include <bsd.lib.mk>
+
+beforedepend ${OBJS}: machine
diff --git a/sys/boot/alpha/libalpha/OSFpal.c b/sys/boot/alpha/libalpha/OSFpal.c
new file mode 100644
index 0000000..9a0ee35
--- /dev/null
+++ b/sys/boot/alpha/libalpha/OSFpal.c
@@ -0,0 +1,73 @@
+/*
+ * $FreeBSD$
+ * 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();
+ bcopy(&p->pcs_palrevisions[PALvar_OSF1], &p->pcs_pal_rev,
+ sizeof(p->pcs_pal_rev));
+ printf("Switch to OSF PAL code succeeded.\n");
+}
+
diff --git a/sys/boot/alpha/libalpha/alpha_copy.c b/sys/boot/alpha/libalpha/alpha_copy.c
new file mode 100644
index 0000000..12f56b1
--- /dev/null
+++ b/sys/boot/alpha/libalpha/alpha_copy.c
@@ -0,0 +1,57 @@
+/*-
+ * 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.
+ *
+ * $FreeBSD$
+ */
+/*
+ * MD primitives supporting placement of module data
+ *
+ * XXX should check load address/size against memory top.
+ */
+#include <stand.h>
+
+#include "libalpha.h"
+
+ssize_t
+alpha_copyin(const void *src, vm_offset_t dest, const size_t len)
+{
+ bcopy(src, (void *)dest, len);
+ return(len);
+}
+
+ssize_t
+alpha_copyout(const vm_offset_t src, void *dest, const size_t len)
+{
+ bcopy((void *)src, dest, len);
+ return(len);
+}
+
+ssize_t
+alpha_readin(const int fd, vm_offset_t dest, const size_t len)
+{
+ return(read(fd, (void *) dest, len));
+}
+
+
diff --git a/sys/boot/alpha/libalpha/alpha_module.c b/sys/boot/alpha/libalpha/alpha_module.c
new file mode 100644
index 0000000..4ac21d4
--- /dev/null
+++ b/sys/boot/alpha/libalpha/alpha_module.c
@@ -0,0 +1,48 @@
+/*-
+ * 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.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * alpha-specific module functionality.
+ *
+ */
+
+#include <stand.h>
+#include <string.h>
+
+#include "bootstrap.h"
+#include "libalpha.h"
+
+/*
+ * 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..94aa4bb
--- /dev/null
+++ b/sys/boot/alpha/libalpha/bbinfo.h
@@ -0,0 +1,57 @@
+/*
+ * $FreeBSD$
+ * 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/bootinfo.c b/sys/boot/alpha/libalpha/bootinfo.c
new file mode 100644
index 0000000..cb41bfb
--- /dev/null
+++ b/sys/boot/alpha/libalpha/bootinfo.c
@@ -0,0 +1,233 @@
+/*-
+ * 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.
+ *
+ * $FreeBSD$
+ */
+
+#include <stand.h>
+#include <string.h>
+#include <sys/param.h>
+#include <sys/linker.h>
+#include <machine/elf.h>
+#include <machine/prom.h>
+#include <machine/rpb.h>
+#include <machine/bootinfo.h>
+#include "bootstrap.h"
+
+extern char *alpha_fmtdev(void *vdev);
+
+/*
+ * Copy the environment into the load area starting at (addr).
+ * Each variable is formatted as <name>=<value>, with a single nul
+ * separating each variable, and a double nul terminating the environment.
+ */
+vm_offset_t
+bi_copyenv(vm_offset_t addr)
+{
+ struct env_var *ep;
+
+ /* traverse the environment */
+ for (ep = environ; ep != NULL; ep = ep->ev_next) {
+ alpha_copyin(ep->ev_name, addr, strlen(ep->ev_name));
+ addr += strlen(ep->ev_name);
+ alpha_copyin("=", addr, 1);
+ addr++;
+ if (ep->ev_value != NULL) {
+ alpha_copyin(ep->ev_value, addr, strlen(ep->ev_value));
+ addr += strlen(ep->ev_value);
+ }
+ alpha_copyin("", addr, 1);
+ addr++;
+ }
+ alpha_copyin("", addr, 1);
+ addr++;
+ return(addr);
+}
+
+/*
+ * Copy module-related data into the load area, where it can be
+ * used as a directory for loaded modules.
+ *
+ * Module data is presented in a self-describing format. Each datum
+ * is preceded by a 32-bit identifier and a 32-bit size field.
+ *
+ * Currently, the following data are saved:
+ *
+ * MOD_NAME (variable) module name (string)
+ * MOD_TYPE (variable) module type (string)
+ * MOD_ARGS (variable) module parameters (string)
+ * MOD_ADDR sizeof(vm_offset_t) module load address
+ * MOD_SIZE sizeof(size_t) module size
+ * MOD_METADATA (variable) type-specific metadata
+ */
+#define COPY32(v, a) { \
+ u_int32_t x = (v); \
+ alpha_copyin(&x, a, sizeof(x)); \
+ a += sizeof(x); \
+}
+
+#define MOD_STR(t, a, s) { \
+ COPY32(t, a); \
+ COPY32(strlen(s) + 1, a); \
+ alpha_copyin(s, a, strlen(s) + 1); \
+ a += roundup(strlen(s) + 1, sizeof(u_int64_t));\
+}
+
+#define MOD_NAME(a, s) MOD_STR(MODINFO_NAME, a, s)
+#define MOD_TYPE(a, s) MOD_STR(MODINFO_TYPE, a, s)
+#define MOD_ARGS(a, s) MOD_STR(MODINFO_ARGS, a, s)
+
+#define MOD_VAR(t, a, s) { \
+ COPY32(t, a); \
+ COPY32(sizeof(s), a); \
+ alpha_copyin(&s, a, sizeof(s)); \
+ a += roundup(sizeof(s), sizeof(u_int64_t)); \
+}
+
+#define MOD_ADDR(a, s) MOD_VAR(MODINFO_ADDR, a, s)
+#define MOD_SIZE(a, s) MOD_VAR(MODINFO_SIZE, a, s)
+
+#define MOD_METADATA(a, mm) { \
+ COPY32(MODINFO_METADATA | mm->md_type, a); \
+ COPY32(mm->md_size, a); \
+ alpha_copyin(mm->md_data, a, mm->md_size); \
+ a += roundup(mm->md_size, sizeof(u_int64_t));\
+}
+
+#define MOD_END(a) { \
+ COPY32(MODINFO_END, a); \
+ COPY32(0, a); \
+}
+
+vm_offset_t
+bi_copymodules(vm_offset_t addr)
+{
+ struct preloaded_file *fp;
+ struct file_metadata *md;
+
+ /* start with the first module on the list, should be the kernel */
+ for (fp = file_findfile(NULL, NULL); fp != NULL; fp = fp->f_next) {
+
+ MOD_NAME(addr, fp->f_name); /* this field must come first */
+ MOD_TYPE(addr, fp->f_type);
+ if (fp->f_args)
+ MOD_ARGS(addr, fp->f_args);
+ MOD_ADDR(addr, fp->f_addr);
+ MOD_SIZE(addr, fp->f_size);
+ for (md = fp->f_metadata; md != NULL; md = md->md_next)
+ if (!(md->md_type & MODINFOMD_NOCOPY))
+ MOD_METADATA(addr, md);
+ }
+ MOD_END(addr);
+ return(addr);
+}
+
+/*
+ * Load the information expected by an alpha kernel.
+ *
+ * - The kernel environment is copied into kernel space.
+ * - Module metadata are formatted and placed in kernel space.
+ */
+int
+bi_load(struct bootinfo_v1 *bi, vm_offset_t *ffp_save,
+ struct preloaded_file *fp)
+{
+ char *rootdevname;
+ struct alpha_devdesc *rootdev;
+ struct preloaded_file *xp;
+ vm_offset_t addr, bootinfo_addr;
+ u_int pad;
+ char *kernelname;
+ vm_offset_t ssym, esym;
+ struct file_metadata *md;
+
+ /*
+ * Allow the environment variable 'rootdev' to override the supplied device
+ * This should perhaps go to MI code and/or have $rootdev tested/set by
+ * MI code before launching the kernel.
+ */
+ rootdevname = getenv("rootdev");
+ alpha_getdev((void **)(&rootdev), rootdevname, NULL);
+ if (rootdev == NULL) { /* bad $rootdev/$currdev */
+ printf("can't determine root device\n");
+ return(EINVAL);
+ }
+
+ /* Try reading the /etc/fstab file to select the root device */
+ getrootmount(alpha_fmtdev((void *)rootdev));
+ free(rootdev);
+
+ ssym = esym = 0;
+ if ((md = file_findmetadata(fp, MODINFOMD_SSYM)) != NULL)
+ ssym = *((vm_offset_t *)&(md->md_data));
+ if ((md = file_findmetadata(fp, MODINFOMD_ESYM)) != NULL)
+ esym = *((vm_offset_t *)&(md->md_data));
+ if (ssym == 0 || esym == 0)
+ ssym = esym = 0; /* sanity */
+
+ bi->ssym = ssym;
+ bi->esym = esym;
+
+ /* find the last module in the chain */
+ addr = 0;
+ for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) {
+ if (addr < (xp->f_addr + xp->f_size))
+ addr = xp->f_addr + xp->f_size;
+ }
+ /* pad to a page boundary */
+ pad = (u_int)addr & PAGE_MASK;
+ if (pad != 0) {
+ pad = PAGE_SIZE - pad;
+ addr += pad;
+ }
+
+ /* copy our environment */
+ bi->envp = (char *)addr;
+ addr = bi_copyenv(addr);
+
+ /* pad to a page boundary */
+ pad = (u_int)addr & PAGE_MASK;
+ if (pad != 0) {
+ pad = PAGE_SIZE - pad;
+ addr += pad;
+ }
+ /* copy module list and metadata */
+ bi->modptr = addr;
+ addr = bi_copymodules(addr);
+
+ /* all done copying stuff in, save end of loaded object space */
+ bi->kernend = addr;
+
+ *ffp_save = ALPHA_K0SEG_TO_PHYS((addr + PAGE_MASK) & ~PAGE_MASK)
+ >> PAGE_SHIFT;
+ *ffp_save += 2; /* XXX OSF/1 does this, no idea why. */
+
+ kernelname = getenv("kernelname");
+ if (kernelname) {
+ strncpy(bi->booted_kernel, kernelname, sizeof(bi->booted_kernel) - 1);
+ }
+
+ return(0);
+}
diff --git a/sys/boot/alpha/libalpha/common.h b/sys/boot/alpha/libalpha/common.h
new file mode 100644
index 0000000..7ae5830
--- /dev/null
+++ b/sys/boot/alpha/libalpha/common.h
@@ -0,0 +1,11 @@
+/*
+ * $FreeBSD$
+ * From: $NetBSD: common.h,v 1.2 1998/01/05 07:02:48 perry Exp $
+ */
+
+int prom_open(char*, int);
+void OSFpal(void);
+void halt(void);
+u_int64_t prom_dispatch(int, ...);
+int cpu_number(void);
+void switch_palcode(void);
diff --git a/sys/boot/alpha/libalpha/delay.c b/sys/boot/alpha/libalpha/delay.c
new file mode 100644
index 0000000..faaf982
--- /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.
+ *
+ * $FreeBSD$
+ */
+
+#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..d8ee113
--- /dev/null
+++ b/sys/boot/alpha/libalpha/devicename.c
@@ -0,0 +1,236 @@
+/*-
+ * 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.
+ *
+ * $FreeBSD$
+ */
+
+#include <stand.h>
+#include <string.h>
+#include <sys/disklabel.h>
+#include "bootstrap.h"
+#include "libalpha.h"
+
+static int alpha_parsedev(struct alpha_devdesc **dev, const char *devspec, const 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, const char *devspec, const 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, const char *devspec, const char **path)
+{
+ struct alpha_devdesc *idev;
+ struct devsw *dv;
+ int i, unit, slice, partition, err;
+ char *cp;
+ const char *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) {
+ free(idev);
+ } else {
+ *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..a223652
--- /dev/null
+++ b/sys/boot/alpha/libalpha/elf_freebsd.c
@@ -0,0 +1,160 @@
+/* $FreeBSD$ */
+/* $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 <sys/linker.h>
+#include <machine/elf.h>
+#include <machine/prom.h>
+#include <machine/rpb.h>
+#include <machine/bootinfo.h>
+
+#include "bootstrap.h"
+
+#define _KERNEL
+
+static int elf64_exec(struct preloaded_file *afp);
+int bi_load(struct bootinfo_v1 *, vm_offset_t *,
+ struct preloaded_file *);
+
+struct file_format alpha_elf = { elf64_loadfile, elf64_exec };
+
+vm_offset_t ffp_save, ptbr_save;
+
+static int
+elf64_exec(struct preloaded_file *fp)
+{
+ static struct bootinfo_v1 bootinfo_v1;
+ struct file_metadata *md;
+ Elf_Ehdr *hdr;
+ int err;
+ int flen;
+
+ if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL)
+ return(EFTYPE); /* XXX actually EFUCKUP */
+ hdr = (Elf_Ehdr *)&(md->md_data);
+
+ /* XXX ffp_save does not appear to be used in the kernel.. */
+ bzero(&bootinfo_v1, sizeof(bootinfo_v1));
+ err = bi_load(&bootinfo_v1, &ffp_save, fp);
+ if (err)
+ return(err);
+
+ /*
+ * Fill in rest of bootinfo for the kernel.
+ */
+ flen = 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;
+
+ /*
+ * Append the boot command flags.
+ */
+ if (fp->f_args != NULL && *fp->f_args != '\0') {
+ const char *p = fp->f_args;
+
+ do {
+ if (*p == '-') {
+ while (*++p != ' ' && *p != '\0')
+ if (flen < sizeof(bootinfo_v1.boot_flags) - 1)
+ bootinfo_v1.boot_flags[flen++] = *p;
+ } else
+ while (*p != ' ' && *p != '\0')
+ p++;
+ while (*p == ' ')
+ p++;
+ } while (*p != '\0');
+ bootinfo_v1.boot_flags[flen] = '\0';
+ }
+
+ printf("Entering %s at 0x%lx...\n", fp->f_name, hdr->e_entry);
+ closeall();
+ dev_cleanup();
+ alpha_pal_imb();
+ (*(void (*)())hdr->e_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..13f1e53
--- /dev/null
+++ b/sys/boot/alpha/libalpha/getsecs.c
@@ -0,0 +1,37 @@
+/*
+ * $FreeBSD$
+ * 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..4790aaf
--- /dev/null
+++ b/sys/boot/alpha/libalpha/libalpha.h
@@ -0,0 +1,82 @@
+/* $FreeBSD$ */
+
+/*
+ * 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, const char *devspec, const 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);
+
+ssize_t alpha_copyin(const void *src, vm_offset_t dest, const size_t len);
+ssize_t alpha_copyout(const vm_offset_t src, void *dest, const size_t len);
+ssize_t alpha_readin(const int fd, vm_offset_t dest, const size_t len);
+
+extern int alpha_boot(void);
+extern int alpha_autoload(void);
diff --git a/sys/boot/alpha/libalpha/pal.S b/sys/boot/alpha/libalpha/pal.S
new file mode 100644
index 0000000..79f9306
--- /dev/null
+++ b/sys/boot/alpha/libalpha/pal.S
@@ -0,0 +1,352 @@
+/*
+ * $FreeBSD$
+ * 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__*/
+inc2: .stabs __FILE__,132,0,0,inc2
+/*
+ * 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..e32d43d
--- /dev/null
+++ b/sys/boot/alpha/libalpha/prom.c
@@ -0,0 +1,165 @@
+/* $FreeBSD$ */
+/* $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);
+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..184f1d3
--- /dev/null
+++ b/sys/boot/alpha/libalpha/prom_disp.S
@@ -0,0 +1,118 @@
+/*
+ * $FreeBSD$
+ * 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..be57632
--- /dev/null
+++ b/sys/boot/alpha/libalpha/prom_swpal.S
@@ -0,0 +1,139 @@
+/*
+ * $FreeBSD$
+ * 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..3361c6c
--- /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.
+ *
+ * $FreeBSD$
+ */
+
+#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..fc96872
--- /dev/null
+++ b/sys/boot/alpha/libalpha/srmdisk.c
@@ -0,0 +1,380 @@
+/*-
+ * 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.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * SRM disk device handling.
+ *
+ * Ideas and algorithms from:
+ *
+ * - NetBSD libi386/biosdisk.c
+ * - FreeBSD biosboot/disk.c
+ *
+ */
+
+#include <stand.h>
+
+#include <sys/disklabel.h>
+
+#include <machine/stdarg.h>
+#include <machine/prom.h>
+
+#include "bootstrap.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_realstrategy(void *devdata, int flag, daddr_t dblk, size_t size, void *buf, size_t *rsize);
+static int bd_open(struct open_file *f, ...);
+static int bd_close(struct open_file *f);
+static void bd_print(int verbose);
+
+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_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,
+ bd_print
+};
+
+/*
+ * 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;
+ int bd_fd;
+ int bd_opencount;
+} 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;
+ bdinfo[0].bd_fd = -1;
+ bdinfo[0].bd_opencount = 0;
+ nbdinfo++;
+
+ return (0);
+}
+
+/*
+ * Print information about disks
+ */
+static void
+bd_print(int verbose)
+{
+ int i;
+ char line[80];
+
+ for (i = 0; i < nbdinfo; i++) {
+ sprintf(line, " disk%d: SRM drive %s", i, bdinfo[i].bd_name);
+ pager_output(line);
+ /* XXX more detail? */
+ pager_output("\n");
+ }
+}
+
+/*
+ * 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, ...)
+{
+ va_list args;
+ struct alpha_devdesc *dev;
+ struct dos_partition *dptr;
+ struct open_disk *od;
+ struct disklabel *lp;
+ int sector, slice, i;
+ int error;
+ int unit, fd;
+ prom_return_t ret;
+
+ va_start(args, f);
+ dev = va_arg(args, struct alpha_devdesc*);
+ va_end(args);
+
+ 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. */
+ if (bdinfo[unit].bd_fd < 0) {
+ 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);
+ bdinfo[unit].bd_fd = fd = ret.u.retval;
+ } else {
+ fd = bdinfo[unit].bd_fd;
+ }
+ bdinfo[unit].bd_opencount++;
+
+ 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 = fd;
+ 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"));
+#if 0
+ error = ENOENT;
+ goto out;
+#endif
+ } 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;
+
+ bdinfo[od->od_unit].bd_opencount--;
+ if (bdinfo[od->od_unit].bd_opencount == 0) {
+ (void)prom_close(od->od_fd);
+ bdinfo[od->od_unit].bd_fd = -1;
+ }
+
+ free(od);
+ f->f_devdata = NULL;
+ return(0);
+}
+
+static int
+bd_strategy(void *devdata, int rw, daddr_t dblk, size_t size, void *buf, size_t *rsize)
+{
+ struct bcache_devdata bcd;
+ struct open_disk *od = (struct open_disk *)devdata;
+
+ bcd.dv_strategy = bd_realstrategy;
+ bcd.dv_devdata = devdata;
+ return(bcache_strategy(&bcd, od->od_unit, rw, dblk + od->od_boff, size, buf, rsize));
+}
+
+static int
+bd_realstrategy(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);
+ 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..969b378
--- /dev/null
+++ b/sys/boot/alpha/libalpha/srmnet.c
@@ -0,0 +1,259 @@
+/*
+ * $FreeBSD$
+ * 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;
+
+#if 0
+ printf("netbbinfo ");
+ if (!netbbinfovalid)
+ printf("invalid\n");
+ else
+ printf("valid: force = %d, ea = %s\n", netbbinfo.force,
+ ether_sprintf(netbbinfo.ether_addr));
+#endif
+
+ 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 FreeBSD/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..f7a46e1
--- /dev/null
+++ b/sys/boot/alpha/libalpha/start.S
@@ -0,0 +1,93 @@
+/*
+ * $FreeBSD$
+ * 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
+#define STACK_SIZE 12288
+
+NESTED(start, 1, ENTRY_FRAME, ra, 0, 0)
+ br pv,Lstartgp
+Lstartgp:
+ LDGP(pv)
+
+#ifndef BOOT1
+ CALL(extend_heap)
+#endif
+
+ lda a0,_edata
+ lda a1,_end
+ subq a1,a0,a1
+ CALL(bzero)
+
+#ifndef BOOT1
+ lda sp,stackbase + STACK_SIZE - ENTRY_FRAME
+#endif
+
+ 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)
+
+#ifndef BOOT1
+BSS(stackbase, STACK_SIZE)
+#endif
diff --git a/sys/boot/alpha/libalpha/time.c b/sys/boot/alpha/libalpha/time.c
new file mode 100644
index 0000000..18af172
--- /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.
+ *
+ * $FreeBSD$
+ */
+
+#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;
+}
diff --git a/sys/boot/alpha/loader/Makefile b/sys/boot/alpha/loader/Makefile
new file mode 100644
index 0000000..3b663de
--- /dev/null
+++ b/sys/boot/alpha/loader/Makefile
@@ -0,0 +1,12 @@
+# $FreeBSD$
+
+BASE= loader
+PROG= ${BASE}
+NEWVERSWHAT= "SRM disk boot" alpha
+INSTALL_HELP= yes
+LOAD_ADDRESS= ${SECONDARY_LOAD_ADDRESS}
+
+# Only disk support
+CFLAGS+= -ffreestanding -DLOADER_DISK_SUPPORT # -DLOADER_EXT2FS_SUPPORT
+
+.include <${.CURDIR}/../common/Makefile.common>
diff --git a/sys/boot/alpha/loader/version b/sys/boot/alpha/loader/version
new file mode 100644
index 0000000..d16c215
--- /dev/null
+++ b/sys/boot/alpha/loader/version
@@ -0,0 +1,12 @@
+$FreeBSD$
+
+NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this
+file is important. Make sure the current version number is on line 6.
+
+1.2: New calling conventions for fopen.
+1.1: New semantics for finding the kernel, new boot.
+1.0: Released working DEC Alpha version.
+0.3: Set/getenv&cia, copyin/out.
+0.2: FICL added to Alpha.
+0.1: Initial i386 version, germinated from the NetBSD i386
+ standalone, but enormously modified.
diff --git a/sys/boot/alpha/netboot/Makefile b/sys/boot/alpha/netboot/Makefile
new file mode 100644
index 0000000..5599aab
--- /dev/null
+++ b/sys/boot/alpha/netboot/Makefile
@@ -0,0 +1,13 @@
+# $FreeBSD$
+# $NetBSD: Makefile,v 1.12 1998/02/19 14:18:36 drochner Exp $
+
+BASE= netboot
+PROG= ${BASE}
+NOMAN=
+NEWVERSWHAT= "SRM net boot" alpha
+LOAD_ADDRESS= ${PRIMARY_LOAD_ADDRESS}
+
+CFLAGS+= -ffreestanding -DLOADER_NET_SUPPORT
+
+.include <${.CURDIR}/../common/Makefile.common>
+
diff --git a/sys/boot/alpha/netboot/version b/sys/boot/alpha/netboot/version
new file mode 100644
index 0000000..d16c215
--- /dev/null
+++ b/sys/boot/alpha/netboot/version
@@ -0,0 +1,12 @@
+$FreeBSD$
+
+NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this
+file is important. Make sure the current version number is on line 6.
+
+1.2: New calling conventions for fopen.
+1.1: New semantics for finding the kernel, new boot.
+1.0: Released working DEC Alpha version.
+0.3: Set/getenv&cia, copyin/out.
+0.2: FICL added to Alpha.
+0.1: Initial i386 version, germinated from the NetBSD i386
+ standalone, but enormously modified.
OpenPOWER on IntegriCloud