diff options
Diffstat (limited to 'sys/boot/alpha')
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. |