diff options
Diffstat (limited to 'sys/boot/ia64')
-rw-r--r-- | sys/boot/ia64/common/copy.c | 59 | ||||
-rw-r--r-- | sys/boot/ia64/common/devicename.c | 239 | ||||
-rw-r--r-- | sys/boot/ia64/common/exec.c | 143 | ||||
-rw-r--r-- | sys/boot/ia64/efi/Makefile | 102 | ||||
-rw-r--r-- | sys/boot/ia64/efi/conf.c | 88 | ||||
-rw-r--r-- | sys/boot/ia64/efi/ldscript.ia64 | 74 | ||||
-rw-r--r-- | sys/boot/ia64/efi/main.c | 134 | ||||
-rw-r--r-- | sys/boot/ia64/efi/start.S | 343 | ||||
-rw-r--r-- | sys/boot/ia64/efi/version | 7 |
9 files changed, 1189 insertions, 0 deletions
diff --git a/sys/boot/ia64/common/copy.c b/sys/boot/ia64/common/copy.c new file mode 100644 index 0000000..ffecba6 --- /dev/null +++ b/sys/boot/ia64/common/copy.c @@ -0,0 +1,59 @@ +/*- + * 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 <efi.h> +#include <efilib.h> +#include <machine/ia64_cpu.h> + +int +efi_copyin(void *src, vm_offset_t dest, size_t len) +{ + bcopy(src, (void*) dest, len); + return(len); +} + +int +efi_copyout(vm_offset_t src, void *dest, size_t len) +{ + bcopy((void*) src, dest, len); + return(len); +} + +int +efi_readin(int fd, vm_offset_t dest, size_t len) +{ + return(read(fd, (void*) dest, len)); +} + + diff --git a/sys/boot/ia64/common/devicename.c b/sys/boot/ia64/common/devicename.c new file mode 100644 index 0000000..c041019 --- /dev/null +++ b/sys/boot/ia64/common/devicename.c @@ -0,0 +1,239 @@ +/*- + * 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 <efi.h> +#include <efilib.h> +#include "efiboot.h" + +static int efi_parsedev(struct efi_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 +efi_getdev(void **vdev, const char *devspec, const char **path) +{ + struct efi_devdesc **dev = (struct efi_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 = efi_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(efi_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 +efi_parsedev(struct efi_devdesc **dev, const char *devspec, const char **path) +{ + struct efi_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 efi_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.efidisk.unit = unit; + idev->d_kind.efidisk.slice = slice; + idev->d_kind.efidisk.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 * +efi_fmtdev(void *vdev) +{ + struct efi_devdesc *dev = (struct efi_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.efidisk.unit); + if (dev->d_kind.efidisk.slice > 0) + cp += sprintf(cp, "s%d", dev->d_kind.efidisk.slice); + if (dev->d_kind.efidisk.partition >= 0) + cp += sprintf(cp, "%c", dev->d_kind.efidisk.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 +efi_setcurrdev(struct env_var *ev, int flags, void *value) +{ + struct efi_devdesc *ncurr; + int rv; + + if ((rv = efi_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/ia64/common/exec.c b/sys/boot/ia64/common/exec.c new file mode 100644 index 0000000..994a787 --- /dev/null +++ b/sys/boot/ia64/common/exec.c @@ -0,0 +1,143 @@ +/* $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 elf_exec(struct preloaded_file *amp); +int bi_load(struct bootinfo_v1 *, vm_offset_t *, + struct preloaded_file *); + +struct file_format alpha_elf = { elf_loadfile, elf_exec }; + +vm_offset_t ffp_save, ptbr_save; + +static int +elf_exec(struct preloaded_file *fp) +{ +#if 0 + static struct bootinfo_v1 bootinfo_v1; + struct file_metadata *md; + Elf_Ehdr *hdr; + int err; + + 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 the bootinfo for the kernel. + */ + strncpy(bootinfo_v1.booted_kernel, fp->f_name, + sizeof(bootinfo_v1.booted_kernel)); + prom_getenv(PROM_E_BOOTED_OSFLAGS, bootinfo_v1.boot_flags, + sizeof(bootinfo_v1.boot_flags)); + bootinfo_v1.hwrpb = (void *)HWRPB_ADDR; + bootinfo_v1.hwrpbsize = ((struct rpb *)HWRPB_ADDR)->rpb_size; + bootinfo_v1.cngetc = NULL; + bootinfo_v1.cnputc = NULL; + bootinfo_v1.cnpollc = NULL; + + printf("Entering %s at 0x%lx...\n", fp->f_name, hdr->e_entry); + exit(0); + closeall(); + alpha_pal_imb(); + (*(void (*)())hdr->e_entry)(ffp_save, ptbr_save, + BOOTINFO_MAGIC, &bootinfo_v1, 1, 0); +#endif +} + + + diff --git a/sys/boot/ia64/efi/Makefile b/sys/boot/ia64/efi/Makefile new file mode 100644 index 0000000..4fb3f0e --- /dev/null +++ b/sys/boot/ia64/efi/Makefile @@ -0,0 +1,102 @@ +# $FreeBSD$ + +BASE= loader +PROG= ${BASE}.efi +NOMAN= +NEWVERSWHAT= "EFI boot" ${MACHINE_ARCH} + +.PATH: ${.CURDIR}/../common + +SRCS+= main.c conf.c + +# Enable BootForth +#BOOT_FORTH= yes +CFLAGS+= -I${.CURDIR}/../../ficl -I${.CURDIR}/../../ficl/alpha +.if BOOT_FORTH +CFLAGS+= -DBOOT_FORTH +.if exists(${.OBJDIR}/../../ficl/libficl.a) +LIBFICL= ${.OBJDIR}/../../ficl/libficl.a +.else +LIBFICL= ${.CURDIR}/../../ficl/libficl.a +.endif +.else +LIBFICL= +.endif + +# Always add MI sources +.PATH: ${.CURDIR}/../../common +.include <${.CURDIR}/../../common/Makefile.inc> +CFLAGS+= -I- +CFLAGS+= -I${.CURDIR}/../include +CFLAGS+= -I${.CURDIR}/../include/${MACHINE_ARCH} +CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR} +CFLAGS+= -I${.CURDIR}/../../.. -I. +CFLAGS+= -I${.CURDIR}/../libefi +CFLAGS+= -DLOADER +CFLAGS+= -Wall + +LDSCRIPT= ${.CURDIR}/../libefi/arch/${MACHINE_ARCH}/ldscript.${MACHINE_ARCH} +LDFLAGS= -nostdlib -T ${LDSCRIPT} -shared -Bsymbolic + +CLEANFILES+= setdef0.c setdef0.o setdef1.c setdef1.o setdefs.h start.o \ + vers.c vers.o ${BASE}.efi ${BASE}.sym ${BASE}.list +CLEANFILES+= loader.help +CLEANFILES+= machine + +CRT= start.o + +all: ${PROG} + +vers.o: ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version + sh ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version ${NEWVERSWHAT} + ${CC} -c vers.c + +${BASE}.efi: ${BASE}.sym + ${OBJCOPY} -j .text \ + -j .hash \ + -j .data \ + -j .sdata \ + -j .dynamic \ + -j .rela \ + -j .reloc \ + -j .dynsym \ + --target=efi-app-${MACHINE_ARCH} \ + ${BASE}.sym ${BASE}.efi + +${BASE}.sym: ${OBJS} ${LIBSTAND} ${LIBARC} ${CRT} vers.o setdef0.o setdef1.o + ${LD} ${LDFLAGS} -o ${BASE}.sym -M \ + ${CRT} setdef0.o ${OBJS} setdef1.o vers.o \ + ${LIBFICL} ${LIBSTAND} ${LIBEFI} ${LIBSTAND} \ + > ${.OBJDIR}/${BASE}.list + +${BASE}.help: help.common help.efi + cat ${.ALLSRC} | awk -f ${.CURDIR}/../../common/merge_help.awk > ${.TARGET} + +beforeinstall: +.if exists(${.OBJDIR}/loader.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 + +# Other fragments still to be brought in from ../Makfile.booters? +start.o: ${.CURDIR}/../libefi/arch/${MACHINE_ARCH}/start.S + ${CC} -c ${CFLAGS} $< + +setdef0.o: setdefs.h + +setdef1.o: setdefs.h + +machine: + ln -sf ${.CURDIR}/../../../${MACHINE_ARCH}/include machine + +.include <bsd.prog.mk> + +.ORDER: setdefs.h setdef0.c setdef1.c +setdefs.h setdef0.c setdef1.c: ${OBJS} + @echo Generating linker sets + @perl ${.CURDIR}/../../../kern/gensetdefs.pl ${OBJS} + +beforedepend ${OBJS}: machine diff --git a/sys/boot/ia64/efi/conf.c b/sys/boot/ia64/efi/conf.c new file mode 100644 index 0000000..49bfcc3 --- /dev/null +++ b/sys/boot/ia64/efi/conf.c @@ -0,0 +1,88 @@ +/* + * $FreeBSD$ + * From $NetBSD: conf.c,v 1.2 1997/03/22 09:03:29 thorpej Exp $ + */ + +/* + * Copyright (c) 1997 + * 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. + */ + + +#include <stand.h> +#include <efi.h> +#include <efilib.h> + +#include "efiboot.h" + +/* + * 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[] = { +/* &efi_disk, */ + NULL +}; + +struct fs_ops *file_system[] = { + &ufs_fsops, + &zipfs_fsops, + NULL +}; + +/* Exported for ia64 only */ +/* + * Sort formats so that those that can detect based on arguments + * rather than reading the file go first. + */ +extern struct file_format ia64_elf; + +struct file_format *file_formats[] = { +/* &ia64_elf, */ + NULL +}; + +/* + * Consoles + * + * We don't prototype these in libalpha.h because they require + * data structures from bootstrap.h as well. + */ +extern struct console efi_console; + +struct console *consoles[] = { + &efi_console, + NULL +}; diff --git a/sys/boot/ia64/efi/ldscript.ia64 b/sys/boot/ia64/efi/ldscript.ia64 new file mode 100644 index 0000000..13d5971 --- /dev/null +++ b/sys/boot/ia64/efi/ldscript.ia64 @@ -0,0 +1,74 @@ +/* $FreeBSD$ */ +OUTPUT_FORMAT("elf64-ia64-little", "elf64-ia64-little", "elf64-ia64-little") +OUTPUT_ARCH(ia64) +ENTRY(_start_plabel) +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = 0; + ImageBase = .; + .text : + { + *(.text) + *(.stub) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + *(.gnu.linkonce.t*) + } + . = ALIGN(4096); + .hash : { *(.hash) } + . = ALIGN(4096); + .data : + { + *(.rodata) + *(.rodata1) + *(.set.*) + *(.ctors) + *(.data) + *(.data1) + *(.gnu.linkonce.d*) + *(.plabel) + *(.IA_64.unwind) + *(.IA_64.unwind_info) + *(.bss) + *(.dynbss) + *(COMMON) + } + . = ALIGN(4096); + __gp = ALIGN(8) + 0x200000; + .sdata : + { + *(.got.plt) + *(.got) + *(.sdata) + *(.sbss) + *(.scommon) + } + . = ALIGN(4096); + .dynamic : { *(.dynamic) } + . = ALIGN(4096); + .rela : + { + *(.rela.text) + *(.rela.gnu.linkonce.t*) + *(.rela.set.*) + *(.rela.sdata) + *(.rela.data) + *(.rela.gnu.linkonce.d*) + *(.rela.got) + *(.rela.stab) + *(.rela.ctors) + } + . = ALIGN(4096); + .reloc : { *(.reloc) } + . = ALIGN(4096); + .dynsym : { *(.dynsym) } + . = ALIGN(4096); + .dynstr : { *(.dynstr) } + .ignored : + { + *(.rela.plabel) + *(.rela.reloc) + } +} + diff --git a/sys/boot/ia64/efi/main.c b/sys/boot/ia64/efi/main.c new file mode 100644 index 0000000..1caa84a --- /dev/null +++ b/sys/boot/ia64/efi/main.c @@ -0,0 +1,134 @@ +/*- + * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> + * Copyright (c) 1998,2000 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 <setjmp.h> + +#include <efi.h> +#include <efilib.h> + +#include "bootstrap.h" +#include "efiboot.h" + +extern char bootprog_name[]; +extern char bootprog_rev[]; +extern char bootprog_date[]; +extern char bootprog_maker[]; + +struct efi_devdesc currdev; /* our current device */ +struct arch_switch archsw; /* MI/MD interface boundary */ + +EFI_STATUS +efi_main (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table) +{ + int i; + EFI_PHYSICAL_ADDRESS mem; + + efi_init(image_handle, system_table); + + /* + * Initialise the heap as early as possible. Once this is done, + * alloc() is usable. The stack is buried inside us, so this is + * safe. + */ + BS->AllocatePages(AllocateAnyPages, EfiLoaderData, + 512*1024/4096, &mem); + setheap((void *)mem, (void *)(mem + 512*1024)); + + /* + * 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(); + + /* + * 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); +#if 0 + printf("Memory: %ld k\n", memsize() / 1024); +#endif + + /* We're booting from an SRM disk, try to spiff this */ + /* XXX presumes that biosdisk is first in devsw */ + currdev.d_dev = devsw[0]; + currdev.d_type = currdev.d_dev->dv_type; + currdev.d_kind.efidisk.unit = 0; + /* XXX should be able to detect this, default to autoprobe */ + currdev.d_kind.efidisk.slice = -1; + /* default to 'a' */ + currdev.d_kind.efidisk.partition = 0; + +#if 0 + /* Create arc-specific variables */ + bootfile = GetEnvironmentVariable(ARCENV_BOOTFILE); + if (bootfile) + setenv("bootfile", bootfile, 1); + + env_setenv("currdev", EV_VOLATILE, + arc_fmtdev(&currdev), arc_setcurrdev, env_nounset); + env_setenv("loaddev", EV_VOLATILE, + arc_fmtdev(&currdev), env_noset, env_nounset); +#endif + + setenv("LINES", "24", 1); /* optional */ + + archsw.arch_autoload = efi_autoload; + archsw.arch_getdev = efi_getdev; + archsw.arch_copyin = efi_copyin; + archsw.arch_copyout = efi_copyout; + archsw.arch_readin = efi_readin; + + interact(); /* doesn't return */ + + return EFI_SUCCESS; /* keep compiler happy */ +} + +COMMAND_SET(quit, "quit", "exit the loader", command_quit); + +static int +command_quit(int argc, char *argv[]) +{ + exit(0); + return(CMD_OK); +} diff --git a/sys/boot/ia64/efi/start.S b/sys/boot/ia64/efi/start.S new file mode 100644 index 0000000..4bb41e2 --- /dev/null +++ b/sys/boot/ia64/efi/start.S @@ -0,0 +1,343 @@ +/*- + * Copyright (c) 2001 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$ + */ + + .text + +#include <sys/cdefs.h> +#include <machine/asm.h> + +#define EFI_SUCCESS 0 +#define EFI_LOAD_ERROR 1 +#define EFI_BUFFER_TOO_SMALL 5 + +#define DT_NULL 0 /* Terminating entry. */ +#define DT_NEEDED 1 /* String table offset of a needed shared + library. */ +#define DT_PLTRELSZ 2 /* Total size in bytes of PLT relocations. */ +#define DT_PLTGOT 3 /* Processor-dependent address. */ +#define DT_HASH 4 /* Address of symbol hash table. */ +#define DT_STRTAB 5 /* Address of string table. */ +#define DT_SYMTAB 6 /* Address of symbol table. */ +#define DT_RELA 7 /* Address of ElfNN_Rela relocations. */ +#define DT_RELASZ 8 /* Total size of ElfNN_Rela relocations. */ +#define DT_RELAENT 9 /* Size of each ElfNN_Rela relocation entry. */ +#define DT_STRSZ 10 /* Size of string table. */ +#define DT_SYMENT 11 /* Size of each symbol table entry. */ +#define DT_INIT 12 /* Address of initialization function. */ +#define DT_FINI 13 /* Address of finalization function. */ +#define DT_SONAME 14 /* String table offset of shared object + name. */ +#define DT_RPATH 15 /* String table offset of library path. */ +#define DT_SYMBOLIC 16 /* Indicates "symbolic" linking. */ +#define DT_REL 17 /* Address of ElfNN_Rel relocations. */ +#define DT_RELSZ 18 /* Total size of ElfNN_Rel relocations. */ +#define DT_RELENT 19 /* Size of each ElfNN_Rel relocation. */ +#define DT_PLTREL 20 /* Type of relocation used for PLT. */ +#define DT_DEBUG 21 /* Reserved (not used). */ +#define DT_TEXTREL 22 /* Indicates there may be relocations in + non-writable segments. */ +#define DT_JMPREL 23 /* Address of PLT relocations. */ + +#define DT_COUNT 24 /* Number of defined d_tag values. */ + +#define R_IA64_NONE 0 /* None */ +#define R_IA64_DIR64MSB 0x26 /* word64 MSB S + A */ +#define R_IA64_DIR64LSB 0x27 /* word64 LSB S + A */ +#define R_IA64_FPTR64MSB 0x46 /* word64 MSB @fptr(S + A) */ +#define R_IA64_FPTR64LSB 0x47 /* word64 LSB @fptr(S + A) */ +#define R_IA64_REL64MSB 0x6e /* word64 MSB BD + A */ +#define R_IA64_REL64LSB 0x6f /* word64 LSB BD + A */ + +ENTRY(_start, 2) + alloc loc0=ar.pfs,2,3,3,0 + mov loc1=rp + movl loc2=@gprel(ImageBase) + ;; + br.sptk.few 9f + add loc2=gp,loc2 + ;; + mov out0=loc2 + mov out1=in1 + ;; + br.call.sptk.few rp=_reloc // relocate image + + cmp.ne p6,p0=EFI_SUCCESS,r8 // did it work? +(p6) br.cond.dpnt.few 9f + + mov out0=in0 // image_handle + mov out1=in1 // system_table + br.call.sptk.few rp=efi_main +9: + mov ar.pfs=loc0 + mov rp=loc1 + ;; + br.ret.sptk.few rp +END(_start) + + // PLABEL for PE32+ + .global _start_plabel + .section .plabel, "a" + .align 16 +_start_plabel: + .quad _start + .quad __gp + .previous + + // A PE32+ relocation entry for the plabel + + .section .reloc, "a" + .long _start_plabel + .long 12 + .short (10 << 12) + 0 + .short (10 << 12) + 8 + .previous + + // in0: image base + // in1: system table +STATIC_ENTRY(_reloc, 2) + alloc loc0=ar.pfs,2,2,2,0 + mov loc1=rp + ;; + movl r15=@gprel(_DYNAMIC) // find _DYNAMIC etc. + movl r2=@gprel(fptr_storage) + movl r3=@gprel(fptr_storage_end) + ;; + add r15=r15,gp // relocate _DYNAMIC etc. + add r2=r2,gp + add r3=r3,gp + ;; +1: ld8 r16=[r15],8 // read r15->d_tag + ;; + ld8 r17=[r15],8 // and r15->d_val + ;; + cmp.eq p6,p0=DT_NULL,r16 // done? +(p6) br.cond.dpnt.few 2f + ;; + cmp.eq p6,p0=DT_RELA,r16 + ;; +(p6) add r18=r17,in0 // found rela section + ;; + cmp.eq p6,p0=DT_RELASZ,r16 + ;; +(p6) mov r19=r17 // found rela size + ;; + cmp.eq p6,p0=DT_SYMTAB,r16 + ;; +(p6) add r20=r17,in0 // found symbol table + ;; +(p6) setf.sig f8=r20 + ;; + cmp.eq p6,p0=DT_SYMENT,r16 + ;; +(p6) setf.sig f9=r17 // found symbol entry size + ;; + cmp.eq p6,p0=DT_RELAENT,r16 + ;; +(p6) mov r22=r17 // found rela entry size + ;; + br.sptk.few 1b + +2: + ld8 r15=[r18],8 // read r_offset + ;; + ld8 r16=[r18],8 // read r_info + add r15=r15,in0 // relocate r_offset + ;; + ld8 r17=[r18],8 // read r_addend + sub r19=r19,r22 // update relasz + + extr.u r23=r16,0,32 // ELF64_R_TYPE(r16) + ;; + cmp.eq p6,p0=R_IA64_NONE,r23 +(p6) br.cond.dpnt.few 3f + ;; + cmp.eq p6,p0=R_IA64_DIR64LSB,r23 + ;; +(p6) br.cond.dptk.few 4f + ;; + cmp.eq p6,p0=R_IA64_FPTR64LSB,r23 + ;; +(p6) br.cond.dptk.few 5f + ;; + cmp.eq p6,p0=R_IA64_REL64LSB,r23 + ;; +(p6) br.cond.dptk.few 4f + ;; + +3: cmp.ltu p6,p0=0,r19 // more? +(p6) br.cond.dptk.few 2b // loop + + mov r8=EFI_SUCCESS // success return value + ;; + br.cond.sptk.few 9f // done + +4: + ld8 r16=[r15] // read value + ;; + add r16=r16,in0 // relocate it + ;; + st8 [r15]=r16 // and store it back + br.cond.sptk.few 3b + +5: + extr.u r23=r16,32,32 // ELF64_R_SYM(r16) + ;; + setf.sig f10=r23 // so we can multiply + ;; + xma.lu f10=f10,f9,f8 // f10=symtab + r_sym*syment + ;; + getf.sig r16=f10 + mov r8=EFI_BUFFER_TOO_SMALL // failure return value + ;; + cmp.geu p6,p0=r2,r3 // space left? +(p6) br.cond.dpnt.few 9f // bail out + + st8 [r15]=r2 // install fptr + add r16=8,r16 // address of st_value + ;; + ld8 r16=[r16] // read symbol value + ;; + add r16=r16,in0 // relocate symbol value + ;; + st8 [r2]=r16,8 // write fptr address + ;; + st8 [r2]=gp,8 // write fptr gp + br.cond.sptk.few 3b + +9: + mov ar.pfs=loc0 + mov rp=loc1 + ;; + br.ret.sptk.few rp + +END(_reloc) + + // in0: system table + // in1: character +ENTRY(_putchar, 2) + alloc loc0=ar.pfs,2,3,2,0 + mov loc1=rp + mov loc2=gp + add sp=-32,sp + ;; + add r14=64,in0 // r14 = &in1->ConOut + ;; + ld8 r14=[r14] // r14 = in1->ConOut + ;; + add r15=8,r14 // r15 = &r14->OutputString + mov out0=r14 + mov out1=sp + mov r16=sp + ;; + ld8 r15=[r15] // r15 = r14->OutputString + st2 [r16]=in1,2 // write character + ;; + st2 [r16]=r0 // terminate + ld8 r17=[r15],8 // function address + ;; + ld8 gp=[r15] // function gp + mov b6=r17 // transfer to branch register + ;; + br.call.sptk.few rp=b6 // call function + ;; + mov gp=loc2 // restore gp + mov ar.pfs=loc0 + mov rp=loc1 + add sp=32,sp + ;; + br.ret.sptk.few rp + +END(_putchar) + + // in0: system table + // in1: string +ENTRY(_puts, 2) + alloc loc0=ar.pfs,3,2,2,0 + mov loc1=rp + ;; + mov out0=in0 + ;; +1: ld1 out1=[in1],1 + ;; + cmp.eq p6,p0=r0,out1 +(p6) br.cond.dpnt.few 9f + ;; + br.call.sptk.few rp=_putchar + ;; + br.cond.sptk.few 1b +9: + mov ar.pfs=loc0 + mov rp=loc1 + ;; + br.ret.sptk.few rp +END(_puts) + + // in0: system table + // in1: number +ENTRY(_puthex, 2) + alloc loc0=ar.pfs,2,3,2,0 + mov loc1=rp + mov loc2=ar.lc + ;; + mov out0=in0 + mov ar.lc=15 + ;; +1: extr.u out1=in1,60,4 + ;; + cmp.leu p6,p7=10,out1 + ;; +(p6) add out1='a'-10,out1 +(p7) add out1='0',out1 + dep.z in1=in1,4,60 + ;; + br.call.sptk.few rp=_putchar + ;; + br.cloop.sptk.few 1b + ;; + mov out1='\r' + ;; + br.call.sptk.few rp=_putchar + ;; + mov out1='\n' + ;; + br.call.sptk.few rp=_putchar + ;; +9: + mov ar.pfs=loc0 + mov rp=loc1 + mov ar.lc=loc2 + ;; + br.ret.sptk.few rp +END(_puthex) + + .data + .align 16 + +fptr_storage: + .space 1024*16 // XXX +fptr_storage_end: diff --git a/sys/boot/ia64/efi/version b/sys/boot/ia64/efi/version new file mode 100644 index 0000000..d49b5ef --- /dev/null +++ b/sys/boot/ia64/efi/version @@ -0,0 +1,7 @@ +$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. + +0.1: Initial EFI version, germinated from the NetBSD i386 + standalone, but enormously modified. |