diff options
Diffstat (limited to 'sys/boot/ia64')
58 files changed, 7330 insertions, 0 deletions
diff --git a/sys/boot/ia64/Makefile b/sys/boot/ia64/Makefile new file mode 100644 index 0000000..b8d7f32 --- /dev/null +++ b/sys/boot/ia64/Makefile @@ -0,0 +1,5 @@ +# $FreeBSD$ + +SUBDIR= libski skiload + +.include <bsd.subdir.mk> diff --git a/sys/boot/ia64/Makefile.inc b/sys/boot/ia64/Makefile.inc new file mode 100644 index 0000000..3000e04 --- /dev/null +++ b/sys/boot/ia64/Makefile.inc @@ -0,0 +1,4 @@ +# $FreeBSD$ + +# Options used when building standalone components +CFLAGS+= -ffreestanding -fshort-wchar -Wformat diff --git a/sys/boot/ia64/common/bootinfo.c b/sys/boot/ia64/common/bootinfo.c new file mode 100644 index 0000000..076aed1 --- /dev/null +++ b/sys/boot/ia64/common/bootinfo.c @@ -0,0 +1,348 @@ +/*- + * 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/reboot.h> +#include <sys/linker.h> +#include <machine/elf.h> +#include <machine/bootinfo.h> + +#include <efi.h> +#include <efilib.h> + +#include "bootstrap.h" + +static EFI_GUID hcdp = HCDP_TABLE_GUID; + +/* + * Return a 'boothowto' value corresponding to the kernel arguments in + * (kargs) and any relevant environment variables. + */ +static struct +{ + const char *ev; + int mask; +} howto_names[] = { + {"boot_askname", RB_ASKNAME}, + {"boot_cdrom", RB_CDROM}, + {"boot_userconfig", RB_CONFIG}, + {"boot_ddb", RB_KDB}, + {"boot_gdb", RB_GDB}, + {"boot_single", RB_SINGLE}, + {"boot_verbose", RB_VERBOSE}, + {"boot_multicons", RB_MULTIPLE}, + {"boot_serial", RB_SERIAL}, + {NULL, 0} +}; + +extern char *efi_fmtdev(void *vdev); + +int +bi_getboothowto(char *kargs) +{ + char *cp; + int howto; + int active; + int i; + + /* Parse kargs */ + howto = 0; + if (kargs != NULL) { + cp = kargs; + active = 0; + while (*cp != 0) { + if (!active && (*cp == '-')) { + active = 1; + } else if (active) + switch (*cp) { + case 'a': + howto |= RB_ASKNAME; + break; + case 'c': + howto |= RB_CONFIG; + break; + case 'C': + howto |= RB_CDROM; + break; + case 'd': + howto |= RB_KDB; + break; + case 'D': + howto |= RB_MULTIPLE; + break; + case 'm': + howto |= RB_MUTE; + break; + case 'g': + howto |= RB_GDB; + break; + case 'h': + howto |= RB_SERIAL; + break; + case 'r': + howto |= RB_DFLTROOT; + break; + case 's': + howto |= RB_SINGLE; + break; + case 'v': + howto |= RB_VERBOSE; + break; + default: + active = 0; + break; + } + cp++; + } + } + /* get equivalents from the environment */ + for (i = 0; howto_names[i].ev != NULL; i++) + if (getenv(howto_names[i].ev) != NULL) + howto |= howto_names[i].mask; + if (!strcmp(getenv("console"), "comconsole")) + howto |= RB_SERIAL; + if (!strcmp(getenv("console"), "nullconsole")) + howto |= RB_MUTE; + return(howto); +} + +/* + * 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) { + efi_copyin(ep->ev_name, addr, strlen(ep->ev_name)); + addr += strlen(ep->ev_name); + efi_copyin("=", addr, 1); + addr++; + if (ep->ev_value != NULL) { + efi_copyin(ep->ev_value, addr, strlen(ep->ev_value)); + addr += strlen(ep->ev_value); + } + efi_copyin("", addr, 1); + addr++; + } + efi_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); \ + efi_copyin(&x, a, sizeof(x)); \ + a += sizeof(x); \ +} + +#define MOD_STR(t, a, s) { \ + COPY32(t, a); \ + COPY32(strlen(s) + 1, a); \ + efi_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); \ + efi_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); \ + efi_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 *bi, struct preloaded_file *fp, UINTN *mapkey, + UINTN pages) +{ + char *rootdevname; + struct efi_devdesc *rootdev; + struct preloaded_file *xp; + vm_offset_t addr, bootinfo_addr; + vm_offset_t ssym, esym; + struct file_metadata *md; + EFI_STATUS status; + UINTN bisz, key; + + /* + * Version 1 bootinfo. + */ + bi->bi_magic = BOOTINFO_MAGIC; + bi->bi_version = 1; + + /* + * Calculate boothowto. + */ + bi->bi_boothowto = bi_getboothowto(fp->f_args); + + /* + * Stash EFI System Table. + */ + bi->bi_systab = (u_int64_t) ST; + + /* + * 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"); + efi_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(efi_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->bi_symtab = ssym; + bi->bi_esymtab = esym; + + bi->bi_hcdp = (uint64_t)efi_get_table(&hcdp); /* DIG64 HCDP table addr. */ + fpswa_init(&bi->bi_fpswa); /* find FPSWA interface */ + + /* 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 */ + addr = (addr + PAGE_MASK) & ~PAGE_MASK; + + /* copy our environment */ + bi->bi_envp = addr; + addr = bi_copyenv(addr); + + /* pad to a page boundary */ + addr = (addr + PAGE_MASK) & ~PAGE_MASK; + + /* copy module list and metadata */ + bi->bi_modulep = addr; + addr = bi_copymodules(addr); + + /* all done copying stuff in, save end of loaded object space */ + bi->bi_kernend = addr; + + /* + * Read the memory map and stash it after bootinfo. Align the memory map + * on a 16-byte boundary (the bootinfo block is page aligned). + */ + bisz = (sizeof(struct bootinfo) + 0x0f) & ~0x0f; + bi->bi_memmap = ((u_int64_t)bi) + bisz; + bi->bi_memmap_size = EFI_PAGE_SIZE * pages - bisz; + status = BS->GetMemoryMap(&bi->bi_memmap_size, + (EFI_MEMORY_DESCRIPTOR *)bi->bi_memmap, &key, + &bi->bi_memdesc_size, &bi->bi_memdesc_version); + if (EFI_ERROR(status)) { + printf("bi_load: Can't read memory map\n"); + return EINVAL; + } + *mapkey = key; + + return(0); +} diff --git a/sys/boot/ia64/common/copy.c b/sys/boot/ia64/common/copy.c new file mode 100644 index 0000000..7bc4edf --- /dev/null +++ b/sys/boot/ia64/common/copy.c @@ -0,0 +1,68 @@ +/*- + * 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +/* + * MD primitives supporting placement of module data + */ +#include <stand.h> + +#include <efi.h> +#include <efilib.h> +#include <machine/ia64_cpu.h> +#include <machine/vmparam.h> + +int +efi_copyin(void *src, vm_offset_t dest, size_t len) +{ + EFI_PHYSICAL_ADDRESS p = IA64_RR_MASK(dest); +#if 0 + BS->AllocatePages(AllocateAddress, EfiRuntimeServicesData, + len >> 12, &p); +#endif + bcopy(src, (void*) p, len); + return (len); +} + +int +efi_copyout(vm_offset_t src, void *dest, size_t len) +{ + bcopy((void*) IA64_RR_MASK(src), dest, len); + return (len); +} + +int +efi_readin(int fd, vm_offset_t dest, size_t len) +{ + EFI_PHYSICAL_ADDRESS p = IA64_RR_MASK(dest); +#if 0 + BS->AllocatePages(AllocateAddress, EfiRuntimeServicesData, + len >> 12, &p); +#endif + return (read(fd, (void*) p, len)); +} diff --git a/sys/boot/ia64/common/devicename.c b/sys/boot/ia64/common/devicename.c new file mode 100644 index 0000000..dda2fb0 --- /dev/null +++ b/sys/boot/ia64/common/devicename.c @@ -0,0 +1,240 @@ +/*- + * 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..27d2b6e --- /dev/null +++ b/sys/boot/ia64/common/exec.c @@ -0,0 +1,223 @@ +/* $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/bootinfo.h> +#include <machine/ia64_cpu.h> +#include <machine/pte.h> +#include <machine/vmparam.h> + +#include <efi.h> +#include <efilib.h> + +#include "bootstrap.h" + +#define _KERNEL + +static int elf64_exec(struct preloaded_file *amp); + +struct file_format ia64_elf = { elf64_loadfile, elf64_exec }; + +static __inline u_int64_t +disable_ic() +{ + u_int64_t psr; + __asm __volatile("mov %0=psr;;" : "=r" (psr)); + __asm __volatile("rsm psr.ic|psr.i;; srlz.i;;"); + return psr; +} + +static __inline void +restore_ic(u_int64_t psr) +{ + __asm __volatile("mov psr.l=%0;; srlz.i" :: "r" (psr)); +} + +/* + * Entered with psr.ic and psr.i both zero. + */ +void +enter_kernel(u_int64_t start, struct bootinfo *bi) +{ + u_int64_t psr; + + __asm __volatile("srlz.i;;"); + __asm __volatile("mov cr.ipsr=%0" + :: "r"(IA64_PSR_IC + | IA64_PSR_DT + | IA64_PSR_RT + | IA64_PSR_IT + | IA64_PSR_BN)); + __asm __volatile("mov cr.iip=%0" :: "r"(start)); + __asm __volatile("mov cr.ifs=r0;;"); + __asm __volatile("mov ar.rsc=0;; flushrs;;"); + __asm __volatile("mov r8=%0" :: "r" (bi)); + __asm __volatile("rfi;;"); +} + +static int +elf64_exec(struct preloaded_file *fp) +{ + struct file_metadata *md; + Elf_Ehdr *hdr; + struct ia64_pte pte; + struct bootinfo *bi; + u_int64_t psr; + UINTN mapkey, pages, size; + UINTN descsz; + UINT32 descver; + EFI_STATUS status; + + if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) + return(EFTYPE); /* XXX actually EFUCKUP */ + hdr = (Elf_Ehdr *)&(md->md_data); + + /* + * Allocate enough pages to hold the bootinfo block and the memory + * map EFI will return to us. The memory map has an unknown size, + * so we have to determine that first. Note that the AllocatePages + * call can itself modify the memory map, so we have to take that + * into account as well. The changes to the memory map are caused + * by splitting a range of free memory into two (AFAICT), so that + * one is marked as being loader data. + */ + size = 0; + descsz = sizeof(EFI_MEMORY_DESCRIPTOR); + BS->GetMemoryMap(&size, NULL, &mapkey, &descsz, &descver); + size += descsz + ((sizeof(struct bootinfo) + 0x0f) & ~0x0f); + pages = EFI_SIZE_TO_PAGES(size); + status = BS->AllocatePages(AllocateAnyPages, EfiLoaderData, pages, + (void*)&bi); + if (EFI_ERROR(status)) { + printf("unable to create bootinfo block (status=0x%lx)\n", + (long)status); + return (ENOMEM); + } + + bzero(bi, sizeof(struct bootinfo)); + bi_load(bi, fp, &mapkey, pages); + + printf("Entering %s at 0x%lx...\n", fp->f_name, hdr->e_entry); + + status = BS->ExitBootServices(IH, mapkey); + if (EFI_ERROR(status)) { + printf("ExitBootServices returned 0x%lx\n", status); + return (EINVAL); + } + + psr = disable_ic(); + + /* + * Region 6 is direct mapped UC and region 7 is direct mapped + * WC. The details of this is controlled by the Alt {I,D}TLB + * handlers. Here we just make sure that they have the largest + * possible page size to minimise TLB usage. + */ + ia64_set_rr(IA64_RR_BASE(6), (6 << 8) | (28 << 2)); + ia64_set_rr(IA64_RR_BASE(7), (7 << 8) | (28 << 2)); + + bzero(&pte, sizeof(pte)); + pte.pte_p = 1; + pte.pte_ma = PTE_MA_WB; + pte.pte_a = 1; + pte.pte_d = 1; + pte.pte_pl = PTE_PL_KERN; + pte.pte_ar = PTE_AR_RWX; + pte.pte_ppn = 0; + + __asm __volatile("mov cr.ifa=%0" :: "r"(IA64_RR_BASE(7))); + __asm __volatile("mov cr.itir=%0" :: "r"(28 << 2)); + __asm __volatile("ptr.i %0,%1" :: "r"(IA64_RR_BASE(7)), "r"(28<<2)); + __asm __volatile("ptr.d %0,%1" :: "r"(IA64_RR_BASE(7)), "r"(28<<2)); + __asm __volatile("srlz.i;;"); + __asm __volatile("itr.i itr[%0]=%1;;" + :: "r"(0), "r"(*(u_int64_t*)&pte)); + __asm __volatile("srlz.i;;"); + __asm __volatile("itr.d dtr[%0]=%1;;" + :: "r"(0), "r"(*(u_int64_t*)&pte)); + __asm __volatile("srlz.i;;"); + + enter_kernel(hdr->e_entry, bi); + + restore_ic(psr); +} diff --git a/sys/boot/ia64/efi/Makefile b/sys/boot/ia64/efi/Makefile new file mode 100644 index 0000000..e2f9a84 --- /dev/null +++ b/sys/boot/ia64/efi/Makefile @@ -0,0 +1,123 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../common + +BASE= loader +PROG= ${BASE}.efi +NOMAN= +NEWVERSWHAT= "EFI boot" ${MACHINE_ARCH} +BINDIR?= /boot +STRIP= # We must not strip loader.efi at install time. + +SRCS+= main.c conf.c dev_net.c + +CFLAGS+= -ffreestanding + +.if !defined(NOFORTH) +# Enable BootForth +BOOT_FORTH= yes +CFLAGS+= -DBOOT_FORTH +CFLAGS+= -I${.CURDIR}/../../ficl -I${.CURDIR}/../../ficl/${MACHINE_ARCH} +.if exists(${.OBJDIR}/../../ficl/libficl.a) +LIBFICL= ${.OBJDIR}/../../ficl/libficl.a +.else +LIBFICL= ${.CURDIR}/../../ficl/libficl.a +.endif +.endif + +# where to get libstand from +.if exists(${.OBJDIR}/../../../../lib/libstand/libstand.a) +LIBSTAND= ${.OBJDIR}/../../../../lib/libstand/libstand.a +.else +LIBSTAND= ${.CURDIR}/../../../../lib/libstand/libstand.a +.endif + +.if exists(${.OBJDIR}/../libefi/libefi.a) +LIBEFI= ${.OBJDIR}/../libefi/libefi.a +.else +LIBEFI= ${.CURDIR}/../libefi/libefi.a +.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+= -I${.CURDIR}/../../../../lib/libstand +CFLAGS+= -DLOADER + +LDSCRIPT= ${.CURDIR}/../libefi/arch/${MACHINE_ARCH}/ldscript.${MACHINE_ARCH} +LDFLAGS= -nostdlib -T ${LDSCRIPT} -shared -Bsymbolic +OBJCOPY?= objcopy + +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: ${BASE} + +vers.o: ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version + sh ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version ${NEWVERSWHAT} + ${CC} -c vers.c + +${BASE}: ${BASE}.efi ${BASE}.help + +${BASE}.efi: ${BASE}.sym + ${OBJCOPY} -j .text \ + -j .hash \ + -j .data \ + -j .sdata \ + -j .dynamic \ + -j .rela \ + -j .reloc \ + -j .dynsym \ + -j .dynstr \ + --target=efi-app-${MACHINE_ARCH} \ + ${BASE}.sym ${BASE}.efi + +${BASE}.help: help.common + 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 +.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 + + +# Other fragments still to be brought in from ../Makfile.booters? +start.o: ${.CURDIR}/../libefi/arch/${MACHINE_ARCH}/start.S + ${CC} -c ${CFLAGS} ${.IMPSRC} + +machine: + ln -sf ${.CURDIR}/../../../${MACHINE_ARCH}/include machine + +.include <bsd.prog.mk> + +${BASE}.sym: ${OBJS} ${LIBFICL} ${LIBEFI} ${LIBSTAND} ${CRT} vers.o + ${LD} ${LDFLAGS} -o ${BASE}.sym -M ${CRT} ${OBJS} vers.o \ + ${LIBFICL} ${LIBEFI} ${LIBSTAND} > ${.OBJDIR}/${BASE}.list + +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..145b16b --- /dev/null +++ b/sys/boot/ia64/efi/conf.c @@ -0,0 +1,95 @@ +/* + * 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. + * + * $NetBSD: conf.c,v 1.2 1997/03/22 09:03:29 thorpej Exp $ + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#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[] = { + &efifs_dev, + &netdev, + NULL +}; + +struct fs_ops *file_system[] = { + &efi_fsops, +/* &ufs_fsops, */ + &nfs_fsops, + &gzipfs_fsops, + NULL +}; + +struct netif_driver *netif_drivers[] = { + &efi_net, + 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 efiboot.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..002c263 --- /dev/null +++ b/sys/boot/ia64/efi/ldscript.ia64 @@ -0,0 +1,73 @@ +/* $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 = .; + . = SIZEOF_HEADERS; + . = ALIGN(4096); + .text : { + *(.text .stub .text.* .gnu.linkonce.t.*) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + *(.plt) + } =0x00300000010070000002000001000400 + . = ALIGN(4096); + .data : { + *(.rodata .rodata.* .gnu.linkonce.r.*) + *(.rodata1) + *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) + *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) + *(.opd) + *(.IA_64.unwind_info* .gnu.linkonce.ia64unwi.*) + *(.IA_64.unwind* .gnu.linkonce.ia64unw.*) + __start_set_Xcommand_set = .; + *(set_Xcommand_set) + __stop_set_Xcommand_set = .; + *(.data .data.* .gnu.linkonce.d.*) + *(.data1) + *(.plabel) + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + } + . = ALIGN(4096); + __gp = .; + .sdata : { + *(.got.plt .got) + *(.IA_64.pltoff) + *(.sdata .sdata.* .gnu.linkonce.s.*) + *(dynsbss) + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + } + . = ALIGN(4096); + .dynamic : { *(.dynamic) } + . = ALIGN(4096); + .rela : { + *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) + *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) + *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) + *(.rela.got) + *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) + *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) + *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) + *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) + *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) + *(.rela.plt) + *(.rela.IA_64.pltoff) + *(.relaset_*) + *(.rela.dyn .rela.dyn.*) + } + . = ALIGN(4096); + .reloc : { *(.reloc) } + . = ALIGN(4096); + .hash : { *(.hash) } + . = ALIGN(4096); + .dynsym : { *(.dynsym) } + . = ALIGN(4096); + .dynstr : { *(.dynstr) } +} diff --git a/sys/boot/ia64/efi/main.c b/sys/boot/ia64/efi/main.c new file mode 100644 index 0000000..752c243 --- /dev/null +++ b/sys/boot/ia64/efi/main.c @@ -0,0 +1,562 @@ +/*- + * 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <stand.h> +#include <string.h> +#include <setjmp.h> +#include <machine/sal.h> +#include <machine/pal.h> +#include <machine/pte.h> +#include <machine/dig64.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 */ + +extern u_int64_t ia64_pal_entry; + +EFI_GUID acpi = ACPI_TABLE_GUID; +EFI_GUID acpi20 = ACPI_20_TABLE_GUID; +EFI_GUID devid = DEVICE_PATH_PROTOCOL; +EFI_GUID hcdp = HCDP_TABLE_GUID; +EFI_GUID imgid = LOADED_IMAGE_PROTOCOL; +EFI_GUID mps = MPS_TABLE_GUID; +EFI_GUID netid = EFI_SIMPLE_NETWORK_PROTOCOL; +EFI_GUID sal = SAL_SYSTEM_TABLE_GUID; +EFI_GUID smbios = SMBIOS_TABLE_GUID; + +static void +find_pal_proc(void) +{ + int i; + struct sal_system_table *saltab = 0; + static int sizes[6] = { + 48, 32, 16, 32, 16, 16 + }; + u_int8_t *p; + + saltab = efi_get_table(&sal); + if (saltab == NULL) { + printf("Can't find SAL System Table\n"); + return; + } + + if (memcmp(saltab->sal_signature, "SST_", 4)) { + printf("Bad signature for SAL System Table\n"); + return; + } + + p = (u_int8_t *) (saltab + 1); + for (i = 0; i < saltab->sal_entry_count; i++) { + if (*p == 0) { + struct sal_entrypoint_descriptor *dp; + dp = (struct sal_entrypoint_descriptor *) p; + ia64_pal_entry = dp->sale_pal_proc; + return; + } + p += sizes[*p]; + } + + printf("Can't find PAL proc\n"); + return; +} + +EFI_STATUS +main(int argc, CHAR16 *argv[]) +{ + EFI_LOADED_IMAGE *img; + int i; + + /* + * 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 */ + + find_pal_proc(); + + /* + * 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)(); + + efinet_init_driver(); + + /* Get our loaded image protocol interface structure. */ + BS->HandleProtocol(IH, &imgid, (VOID**)&img); + + printf("Image base: 0x%016lx\n", (u_long)img->ImageBase); + + printf("\n"); + printf("%s, Revision %s\n", bootprog_name, bootprog_rev); + printf("(%s, %s)\n", bootprog_maker, bootprog_date); + + i = efifs_get_unit(img->DeviceHandle); + if (i >= 0) { + currdev.d_dev = devsw[0]; /* XXX disk */ + currdev.d_kind.efidisk.unit = i; + /* XXX should be able to detect this, default to autoprobe */ + currdev.d_kind.efidisk.slice = -1; + currdev.d_kind.efidisk.partition = 0; + } else { + currdev.d_dev = devsw[1]; /* XXX net */ + currdev.d_kind.netif.unit = 0; /* XXX */ + } + currdev.d_type = currdev.d_dev->dv_type; + + /* + * Disable the watchdog timer. By default the boot manager sets + * the timer to 5 minutes before invoking a boot option. If we + * want to return to the boot manager, we have to disable the + * watchdog timer and since we're an interactive program, we don't + * want to wait until the user types "quit". The timer may have + * fired by then. We don't care if this fails. It does not prevent + * normal functioning in any way... + */ + BS->SetWatchdogTimer(0, 0, 0, NULL); + + env_setenv("currdev", EV_VOLATILE, efi_fmtdev(&currdev), + efi_setcurrdev, env_nounset); + env_setenv("loaddev", EV_VOLATILE, efi_fmtdev(&currdev), env_noset, + env_nounset); + + 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); +} + +COMMAND_SET(memmap, "memmap", "print memory map", command_memmap); + +static int +command_memmap(int argc, char *argv[]) +{ + UINTN sz; + EFI_MEMORY_DESCRIPTOR *map, *p; + UINTN key, dsz; + UINT32 dver; + EFI_STATUS status; + int i, ndesc; + static char *types[] = { + "Reserved", + "LoaderCode", + "LoaderData", + "BootServicesCode", + "BootServicesData", + "RuntimeServicesCode", + "RuntimeServicesData", + "ConventionalMemory", + "UnusableMemory", + "ACPIReclaimMemory", + "ACPIMemoryNVS", + "MemoryMappedIO", + "MemoryMappedIOPortSpace", + "PalCode" + }; + + sz = 0; + status = BS->GetMemoryMap(&sz, 0, &key, &dsz, &dver); + if (status != EFI_BUFFER_TOO_SMALL) { + printf("Can't determine memory map size\n"); + return CMD_ERROR; + } + map = malloc(sz); + status = BS->GetMemoryMap(&sz, map, &key, &dsz, &dver); + if (EFI_ERROR(status)) { + printf("Can't read memory map\n"); + return CMD_ERROR; + } + + ndesc = sz / dsz; + printf("%23s %12s %12s %8s %4s\n", + "Type", "Physical", "Virtual", "#Pages", "Attr"); + + for (i = 0, p = map; i < ndesc; + i++, p = NextMemoryDescriptor(p, dsz)) { + printf("%23s %012lx %012lx %08lx ", + types[p->Type], + p->PhysicalStart, + p->VirtualStart, + p->NumberOfPages); + if (p->Attribute & EFI_MEMORY_UC) + printf("UC "); + if (p->Attribute & EFI_MEMORY_WC) + printf("WC "); + if (p->Attribute & EFI_MEMORY_WT) + printf("WT "); + if (p->Attribute & EFI_MEMORY_WB) + printf("WB "); + if (p->Attribute & EFI_MEMORY_UCE) + printf("UCE "); + if (p->Attribute & EFI_MEMORY_WP) + printf("WP "); + if (p->Attribute & EFI_MEMORY_RP) + printf("RP "); + if (p->Attribute & EFI_MEMORY_XP) + printf("XP "); + if (p->Attribute & EFI_MEMORY_RUNTIME) + printf("RUNTIME"); + printf("\n"); + } + + return CMD_OK; +} + +COMMAND_SET(configuration, "configuration", + "print configuration tables", command_configuration); + +static const char * +guid_to_string(EFI_GUID *guid) +{ + static char buf[40]; + + sprintf(buf, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", + guid->Data1, guid->Data2, guid->Data3, guid->Data4[0], + guid->Data4[1], guid->Data4[2], guid->Data4[3], guid->Data4[4], + guid->Data4[5], guid->Data4[6], guid->Data4[7]); + return (buf); +} + +static int +command_configuration(int argc, char *argv[]) +{ + int i; + + printf("NumberOfTableEntries=%ld\n", ST->NumberOfTableEntries); + for (i = 0; i < ST->NumberOfTableEntries; i++) { + EFI_GUID *guid; + + printf(" "); + guid = &ST->ConfigurationTable[i].VendorGuid; + if (!memcmp(guid, &mps, sizeof(EFI_GUID))) + printf("MPS Table"); + else if (!memcmp(guid, &acpi, sizeof(EFI_GUID))) + printf("ACPI Table"); + else if (!memcmp(guid, &acpi20, sizeof(EFI_GUID))) + printf("ACPI 2.0 Table"); + else if (!memcmp(guid, &smbios, sizeof(EFI_GUID))) + printf("SMBIOS Table"); + else if (!memcmp(guid, &sal, sizeof(EFI_GUID))) + printf("SAL System Table"); + else if (!memcmp(guid, &hcdp, sizeof(EFI_GUID))) + printf("DIG64 HCDP Table"); + else + printf("Unknown Table (%s)", guid_to_string(guid)); + printf(" at %p\n", ST->ConfigurationTable[i].VendorTable); + } + + return CMD_OK; +} + +COMMAND_SET(sal, "sal", "print SAL System Table", command_sal); + +static int +command_sal(int argc, char *argv[]) +{ + int i; + struct sal_system_table *saltab = 0; + static int sizes[6] = { + 48, 32, 16, 32, 16, 16 + }; + u_int8_t *p; + + saltab = efi_get_table(&sal); + if (saltab == NULL) { + printf("Can't find SAL System Table\n"); + return CMD_ERROR; + } + + if (memcmp(saltab->sal_signature, "SST_", 4)) { + printf("Bad signature for SAL System Table\n"); + return CMD_ERROR; + } + + printf("SAL Revision %x.%02x\n", + saltab->sal_rev[1], + saltab->sal_rev[0]); + printf("SAL A Version %x.%02x\n", + saltab->sal_a_version[1], + saltab->sal_a_version[0]); + printf("SAL B Version %x.%02x\n", + saltab->sal_b_version[1], + saltab->sal_b_version[0]); + + p = (u_int8_t *) (saltab + 1); + for (i = 0; i < saltab->sal_entry_count; i++) { + printf(" Desc %d", *p); + if (*p == 0) { + struct sal_entrypoint_descriptor *dp; + dp = (struct sal_entrypoint_descriptor *) p; + printf("\n"); + printf(" PAL Proc at 0x%lx\n", + dp->sale_pal_proc); + printf(" SAL Proc at 0x%lx\n", + dp->sale_sal_proc); + printf(" SAL GP at 0x%lx\n", + dp->sale_sal_gp); + } else if (*p == 1) { + struct sal_memory_descriptor *dp; + dp = (struct sal_memory_descriptor *) p; + printf(" Type %d.%d, ", + dp->sale_memory_type[0], + dp->sale_memory_type[1]); + printf("Address 0x%lx, ", + dp->sale_physical_address); + printf("Length 0x%x\n", + dp->sale_length); + } else if (*p == 5) { + struct sal_ap_wakeup_descriptor *dp; + dp = (struct sal_ap_wakeup_descriptor *) p; + printf("\n"); + printf(" Mechanism %d\n", dp->sale_mechanism); + printf(" Vector 0x%lx\n", dp->sale_vector); + } else + printf("\n"); + + p += sizes[*p]; + } + + return CMD_OK; +} + +int +print_trs(int type) +{ + struct ia64_pal_result res; + int i, maxtr; + struct { + struct ia64_pte pte; + struct ia64_itir itir; + struct ia64_ifa ifa; + struct ia64_rr rr; + } buf; + static const char* psnames[] = { + "1B", "2B", "4B", "8B", + "16B", "32B", "64B", "128B", + "256B", "512B", "1K", "2K", + "4K", "8K", "16K", "32K", + "64K", "128K", "256K", "512K", + "1M", "2M", "4M", "8M", + "16M", "32M", "64M", "128M", + "256M", "512M", "1G", "2G" + }; + static const char* manames[] = { + "WB", "bad", "bad", "bad", + "UC", "UCE", "WC", "NaT", + + }; + + res = ia64_call_pal_static(PAL_VM_SUMMARY, 0, 0, 0); + if (res.pal_status != 0) { + printf("Can't get VM summary\n"); + return CMD_ERROR; + } + + if (type == 0) + maxtr = (res.pal_result[0] >> 40) & 0xff; + else + maxtr = (res.pal_result[0] >> 32) & 0xff; + + printf("%d translation registers\n", maxtr); + + pager_open(); + pager_output("TR# RID Virtual Page Physical Page PgSz ED AR PL D A MA P KEY\n"); + for (i = 0; i <= maxtr; i++) { + char lbuf[128]; + + bzero(&buf, sizeof(buf)); + res = ia64_call_pal_stacked(PAL_VM_TR_READ, i, type, + (u_int64_t) &buf); + if (res.pal_status != 0) + break; + + /* Only display valid translations */ + if ((buf.ifa.ifa_ig & 1) == 0) + continue; + + if (!(res.pal_result[0] & 1)) + buf.pte.pte_ar = 0; + if (!(res.pal_result[0] & 2)) + buf.pte.pte_pl = 0; + if (!(res.pal_result[0] & 4)) + buf.pte.pte_d = 0; + if (!(res.pal_result[0] & 8)) + buf.pte.pte_ma = 0; + sprintf(lbuf, + "%03d %06x %013lx %013lx %4s %d %d %d %d %d %-3s %d %06x\n", + i, + buf.rr.rr_rid, + buf.ifa.ifa_vpn, + buf.pte.pte_ppn, + psnames[buf.itir.itir_ps], + buf.pte.pte_ed, + buf.pte.pte_ar, + buf.pte.pte_pl, + buf.pte.pte_d, + buf.pte.pte_a, + manames[buf.pte.pte_ma], + buf.pte.pte_p, + buf.itir.itir_key); + pager_output(lbuf); + } + pager_close(); + + if (res.pal_status != 0) { + printf("Error while getting TR contents\n"); + return CMD_ERROR; + } + return CMD_OK; +} + +COMMAND_SET(itr, "itr", "print instruction TRs", command_itr); + +static int +command_itr(int argc, char *argv[]) +{ + return print_trs(0); +} + +COMMAND_SET(dtr, "dtr", "print data TRs", command_dtr); + +static int +command_dtr(int argc, char *argv[]) +{ + return print_trs(1); +} + +COMMAND_SET(hcdp, "hcdp", "Dump HCDP info", command_hcdp); + +static char * +hcdp_string(char *s, u_int len) +{ + static char buffer[256]; + + memcpy(buffer, s, len); + buffer[len] = 0; + return (buffer); +} + +static int +command_hcdp(int argc, char *argv[]) +{ + struct dig64_hcdp_table *tbl; + struct dig64_hcdp_entry *ent; + struct dig64_gas *gas; + int i; + + tbl = efi_get_table(&hcdp); + if (tbl == NULL) { + printf("No HCDP table present\n"); + return (CMD_OK); + } + if (memcmp(tbl->signature, HCDP_SIGNATURE, sizeof(tbl->signature))) { + printf("HCDP table has invalid signature\n"); + return (CMD_OK); + } + if (tbl->length < sizeof(*tbl) - sizeof(*tbl->entry)) { + printf("HCDP table too short\n"); + return (CMD_OK); + } + printf("HCDP table at 0x%016lx\n", (u_long)tbl); + printf("Signature = %s\n", hcdp_string(tbl->signature, 4)); + printf("Length = %u\n", tbl->length); + printf("Revision = %u\n", tbl->revision); + printf("Checksum = %u\n", tbl->checksum); + printf("OEM Id = %s\n", hcdp_string(tbl->oem_id, 6)); + printf("Table Id = %s\n", hcdp_string(tbl->oem_tbl_id, 8)); + printf("OEM rev = %u\n", tbl->oem_rev); + printf("Creator Id = %s\n", hcdp_string(tbl->creator_id, 4)); + printf("Creator rev= %u\n", tbl->creator_rev); + printf("Entries = %u\n", tbl->entries); + for (i = 0; i < tbl->entries; i++) { + ent = tbl->entry + i; + printf("Entry #%d:\n", i + 1); + printf(" Type = %u\n", ent->type); + printf(" Databits = %u\n", ent->databits); + printf(" Parity = %u\n", ent->parity); + printf(" Stopbits = %u\n", ent->stopbits); + printf(" PCI seg = %u\n", ent->pci_segment); + printf(" PCI bus = %u\n", ent->pci_bus); + printf(" PCI dev = %u\n", ent->pci_device); + printf(" PCI func = %u\n", ent->pci_function); + printf(" Interrupt = %u\n", ent->interrupt); + printf(" PCI flag = %u\n", ent->pci_flag); + printf(" Baudrate = %lu\n", + ((u_long)ent->baud_high << 32) + (u_long)ent->baud_low); + gas = &ent->address; + printf(" Addr space= %u\n", gas->addr_space); + printf(" Bit width = %u\n", gas->bit_width); + printf(" Bit offset= %u\n", gas->bit_offset); + printf(" Address = 0x%016lx\n", + ((u_long)gas->addr_high << 32) + (u_long)gas->addr_low); + printf(" PCI type = %u\n", ent->pci_devid); + printf(" PCI vndr = %u\n", ent->pci_vendor); + printf(" IRQ = %u\n", ent->irq); + printf(" PClock = %u\n", ent->pclock); + printf(" PCI iface = %u\n", ent->pci_interface); + } + printf("<EOT>\n"); + 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..643f1c9 --- /dev/null +++ b/sys/boot/ia64/efi/start.S @@ -0,0 +1,305 @@ +/*- + * 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 <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 */ +#define R_IA64_IPLTLSB 0x81 /* function descriptor LSB speciaal */ + +ENTRY(_start, 2) + alloc loc0=ar.pfs,2,3,3,0 + mov loc1=rp + movl loc2=@gprel(ImageBase) + ;; + 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 +// +// XXX Assumes PLT relocations are of type Elf_Rela +// +// r2 = address of fptr_storage +// r3 = address of fptr_storage_end +// r4 = address of first free fptr +// +// r15 = r_offset +// r16 = r_info -OR- d_tag +// r17 = r_addend -OR- d_val (=d_ptr) +// r18 = address of .rela dynamic section +// r19 = size of .rela section +// r20 = size of .rela element (Elf_Rela) +// r21 = address of first PLT relocation +// r22 = size of PLT relocations +// r23 = relocation type +// r24 = address of symbol +// r28 = R_IA64_IPLTLSB +// f8 = address of symbol table +// f9 = size of symtab element + +STATIC_ENTRY(_reloc, 2) + alloc loc0=ar.pfs,2,2,0,0 + ;; + mov loc1=rp + movl r29=@gprel(_DYNAMIC) // find _DYNAMIC etc. + ;; + add r15=r29,gp + movl r29=@gprel(fptr_storage) + ;; + add r2=r29,gp + movl r29=@gprel(fptr_storage_end) + ;; + add r3=r29,gp + mov r4=r2 + mov r19=0 + mov r22=0 + mov r20=24 + mov r28=R_IA64_IPLTLSB + ;; +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 // rela section? + ;; +(p6) add r18=r17,in0 + cmp.eq p6,p0=DT_RELASZ,r16 // rela section size? + ;; +(p6) mov r19=r17 + cmp.eq p6,p0=DT_RELAENT,r16 // rela entry size? + ;; +(p6) mov r20=r17 + cmp.eq p6,p0=DT_JMPREL,r16 // PLT relocs? + ;; +(p6) add r21=r17,in0 + cmp.eq p6,p0=DT_PLTRELSZ,r16 // PLT relocs size? + ;; +(p6) mov r22=r17 + cmp.eq p6,p0=DT_SYMTAB,r16 // symbol table? + ;; +(p6) add r29=r17,in0 + ;; +(p6) setf.sig f8=r29 + cmp.eq p6,p0=DT_SYMENT,r16 // symbol entry size? + ;; +(p6) setf.sig f9=r17 + br.dptk 1b + +2: + cmp.lt p6,p0=0,r19 +(p6) br.cond.dptk 3f + ;; + mov r19=r22 + mov r18=r21 + mov r21=0 + mov r22=0 + ;; + cmp.lt p6,p0=0,r19 +(p6) br.cond.dptk 3f + ;; + mov r8=EFI_SUCCESS + br.dptk 9f +3: + ld8 r29=[r18],8 // read r_offset + ;; + ld8 r16=[r18],8 // read r_info + add r15=r29,in0 // relocate r_offset + ;; + ld8 r17=[r18],8 // read r_addend + sub r19=r19,r20 // 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 2b + ;; + cmp.eq p6,p0=R_IA64_REL64LSB,r23 +(p6) br.cond.dptk.few 4f + ;; + extr.u r29=r16,32,32 // ELF64_R_SYM(r16) + ;; + setf.sig f10=r29 // so we can multiply + ;; + xma.lu f10=f10,f9,f8 // f10=symtab + r_sym*syment + ;; + getf.sig r29=f10 + ;; + add r29=8,r29 // address of st_value + ;; + ld8 r29=[r29] // read symbol value + ;; + add r24=r29,in0 // relocate symbol value + ;; + cmp.eq p6,p0=R_IA64_DIR64LSB,r23 +(p6) br.cond.dptk.few 5f + ;; + cmp.eq p6,p0=R_IA64_FPTR64LSB,r23 +(p6) br.cond.dptk.few 6f + ;; + cmp.ne p6,p0=r28,r23 // IPLTLSB +(p6) br.cond.dptk.few 2b + + // IPLTLSB + add r29=r24,r17 // S + A + ;; + st8 [r15]=r29,8 // fdesc:FP + ;; + st8 [r15]=gp // fdesc:GP + br.cond.sptk.few 2b + + // REL64LSB +4: + add r29=in0,r17 // BD + A + ;; + st8 [r15]=r29 // word64 + br.cond.sptk.few 2b + + // DIR64LSB +5: + add r29=r24,r17 // S + A + ;; + st8 [r15]=r29 // word64 + br.cond.sptk.few 2b + +6: + mov r29=r2 // FPTR64LSB + ;; +7: + cmp.geu p6,p0=r29,r4 // end of fptrs? +(p6) br.cond.dpnt.few 8f // can't find existing fptr + ld8 r17=[r29] // read function from fptr + ;; + cmp.eq p6,p0=r24,r17 // same function? + ;; +(p6) st8 [r15]=r29 // reuse fptr +(p6) br.cond.sptk.few 2b // done + add r29=16,r29 // next fptr + br.sptk.few 7b +8: + mov r8=EFI_BUFFER_TOO_SMALL // failure return value + cmp.geu p6,p0=r4,r3 // space left? +(p6) br.cond.dpnt.few 9f // bail out + st8 [r15]=r4 // install fptr + ;; + st8 [r4]=r24,8 // write fptr address + ;; + st8 [r4]=gp,8 // write fptr gp + br.cond.sptk.few 2b + +9: + mov ar.pfs=loc0 + mov rp=loc1 + ;; + br.ret.sptk.few rp +END(_reloc) + + .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..71f9400 --- /dev/null +++ b/sys/boot/ia64/efi/version @@ -0,0 +1,16 @@ +$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.1: Pass the HCDP table address to the kernel via bootinfo if one + is present in the EFI system table. +1.0: Don't map the I/O port range. We expect the kernel to do it. It + was done in the loader as a debugging aid and not intended as a + service/feature. +0.3: Pass the physical address of the bootinfo block in register r8 + to the kernel. Continue to put it at the fixed address for now. +0.2: Much improved version. Significant is the support for passing + the FPSWA interface pointer to the kernel. +0.1: Initial EFI version, germinated from the NetBSD i386 + standalone, but enormously modified. diff --git a/sys/boot/ia64/libski/Makefile b/sys/boot/ia64/libski/Makefile new file mode 100644 index 0000000..0288938 --- /dev/null +++ b/sys/boot/ia64/libski/Makefile @@ -0,0 +1,36 @@ +# $FreeBSD$ + +LIB= ski +INTERNALLIB= true + +SRCS= skiconsole.c time.c copy.c devicename.c module.c exit.c +SRCS+= delay.c skifs.c elf_freebsd.c bootinfo.c ssc.c +SRCS+= acpi_stub.c efi_stub.c pal_stub.S sal_stub.c + +CFLAGS+= -ffreestanding -fpic -g +CFLAGS+= -I${.CURDIR}/../include +CFLAGS+= -I${.CURDIR}/../include/${MACHINE_ARCH} +CFLAGS+= -I${.CURDIR}/../../../../lib/libstand/ +CFLAGS+= -I${.CURDIR}/../../efi/include +CFLAGS+= -I${.CURDIR}/../../efi/include/${MACHINE_ARCH} + +# Pick up the bootstrap header for some interface items +CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}/../../.. -I. + +.if ${MACHINE_ARCH} == "powerpc" +CFLAGS+= -msoft-float +.endif + +.ifdef(BOOT_DISK_DEBUG) +# Make the disk code more talkative +CFLAGS+= -DDISK_DEBUG +.endif + +machine: + ln -sf ${.CURDIR}/../../../${MACHINE_ARCH}/include machine + +CLEANFILES+= machine + +.include <bsd.lib.mk> + +beforedepend ${OBJS}: machine diff --git a/sys/boot/ia64/libski/acpi_stub.c b/sys/boot/ia64/libski/acpi_stub.c new file mode 100644 index 0000000..3e044e6 --- /dev/null +++ b/sys/boot/ia64/libski/acpi_stub.c @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2003 Marcel Moolenaar + * 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 ``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 <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <contrib/dev/acpica/acpi.h> + +#define APIC_IO_SAPIC 6 +#define APIC_LOCAL_SAPIC 7 + +#pragma pack(1) + +typedef struct /* LOCAL SAPIC */ +{ + APIC_HEADER Header; + UINT8 ProcessorId; /* ACPI processor id */ + UINT8 LocalSapicId; /* Processor local SAPIC id */ + UINT8 LocalSapicEid; /* Processor local SAPIC eid */ + UINT8 Reserved[3]; + UINT32 ProcessorEnabled: 1; + UINT32 FlagsReserved: 31; +} LOCAL_SAPIC; + +typedef struct /* IO SAPIC */ +{ + APIC_HEADER Header; + UINT8 IoSapicId; /* I/O SAPIC ID */ + UINT8 Reserved; /* reserved - must be zero */ + UINT32 Vector; /* interrupt base */ + UINT64 IoSapicAddress; /* SAPIC's physical address */ +} IO_SAPIC; + +/* + */ + +struct { + MULTIPLE_APIC_TABLE Header; + MADT_LOCAL_SAPIC cpu0; + MADT_LOCAL_SAPIC cpu1; + MADT_LOCAL_SAPIC cpu2; + MADT_LOCAL_SAPIC cpu3; + MADT_IO_SAPIC sapic; +} apic = { + /* Header. */ + { + APIC_SIG, /* Signature. */ + sizeof(apic), /* Length of table. */ + 0, /* ACPI minor revision. */ + 0, /* XXX checksum. */ + "FBSD", /* OEM Id. */ + "SKI", /* OEM table Id. */ + 0, /* OEM revision. */ + "FBSD", /* ASL compiler Id. */ + 0, /* ASL revision. */ + 0xfee00000, + }, + /* cpu0. */ + { + APIC_LOCAL_SAPIC, /* Type. */ + sizeof(apic.cpu0), /* Length. */ + 0, /* ACPI processor id */ + 0, /* Processor local SAPIC id */ + 0, /* Processor local SAPIC eid */ + { 0, 0, 0 }, + 1, /* FL: Enabled. */ + }, + /* cpu1. */ + { + APIC_LOCAL_SAPIC, /* Type. */ + sizeof(apic.cpu1), /* Length. */ + 1, /* ACPI processor id */ + 0, /* Processor local SAPIC id */ + 1, /* Processor local SAPIC eid */ + { 0, 0, 0 }, + 1, /* FL: Enabled. */ + }, + /* cpu2. */ + { + APIC_LOCAL_SAPIC, /* Type. */ + sizeof(apic.cpu2), /* Length. */ + 2, /* ACPI processor id */ + 1, /* Processor local SAPIC id */ + 0, /* Processor local SAPIC eid */ + { 0, 0, 0 }, + 0, /* FL: Enabled. */ + }, + /* cpu3. */ + { + APIC_LOCAL_SAPIC, /* Type. */ + sizeof(apic.cpu3), /* Length. */ + 3, /* ACPI processor id */ + 1, /* Processor local SAPIC id */ + 1, /* Processor local SAPIC eid */ + { 0, 0, 0 }, + 0, /* FL: Enabled. */ + }, + /* sapic. */ + { + APIC_IO_SAPIC, /* Type. */ + sizeof(apic.sapic), /* Length. */ + 4, /* IO SAPIC id. */ + 0, + 16, /* Interrupt base. */ + 0xfec00000 /* IO SAPIC address. */ + } +}; + +struct { + ACPI_TABLE_HEADER Header; + UINT64 apic_tbl; +} xsdt = { + { + XSDT_SIG, /* Signature. */ + sizeof(xsdt), /* Length of table. */ + 0, /* ACPI minor revision. */ + 0, /* XXX checksum. */ + "FBSD", /* OEM Id. */ + "SKI", /* OEM table Id. */ + 0, /* OEM revision. */ + "FBSD", /* ASL compiler Id. */ + 0 /* ASL revision. */ + }, + NULL /* XXX APIC table address. */ +}; + +RSDP_DESCRIPTOR acpi_root = { + RSDP_SIG, + 0, /* XXX checksum. */ + "FBSD", + 2, /* ACPI Rev 2.0. */ + NULL, + sizeof(xsdt), /* XSDT length. */ + NULL, /* XXX PA of XSDT. */ + 0, /* XXX Extended checksum. */ +}; + +static void +cksum(void *addr, int sz, UINT8 *sum) +{ + UINT8 *p, s; + + p = addr; + s = 0; + while (sz--) + s += *p++; + *sum = -s; +} + +void +acpi_stub_init(void) +{ + acpi_root.XsdtPhysicalAddress = (UINT64)&xsdt; + cksum(&acpi_root, 20, &acpi_root.Checksum); + cksum(&acpi_root, sizeof(acpi_root), &acpi_root.ExtendedChecksum); + + xsdt.apic_tbl = (UINT32)&apic; + cksum(&xsdt, sizeof(xsdt), &xsdt.Header.Checksum); +} diff --git a/sys/boot/ia64/libski/bootinfo.c b/sys/boot/ia64/libski/bootinfo.c new file mode 100644 index 0000000..dbc4673 --- /dev/null +++ b/sys/boot/ia64/libski/bootinfo.c @@ -0,0 +1,316 @@ +/*- + * 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <stand.h> +#include <string.h> +#include <sys/param.h> +#include <sys/reboot.h> +#include <sys/linker.h> +#include <machine/elf.h> +#include <machine/bootinfo.h> + +#include "bootstrap.h" + +/* + * Return a 'boothowto' value corresponding to the kernel arguments in + * (kargs) and any relevant environment variables. + */ +static struct +{ + const char *ev; + int mask; +} howto_names[] = { + {"boot_askname", RB_ASKNAME}, + {"boot_cdrom", RB_CDROM}, + {"boot_userconfig", RB_CONFIG}, + {"boot_ddb", RB_KDB}, + {"boot_gdb", RB_GDB}, + {"boot_single", RB_SINGLE}, + {"boot_verbose", RB_VERBOSE}, + {"boot_multicons", RB_MULTIPLE}, + {"boot_serial", RB_SERIAL}, + {NULL, 0} +}; + +extern char *ski_fmtdev(void *vdev); +extern int ski_init_stubs(struct bootinfo *); + +int +bi_getboothowto(char *kargs) +{ + char *cp; + int howto; + int active; + int i; + + /* Parse kargs */ + howto = 0; + if (kargs != NULL) { + cp = kargs; + active = 0; + while (*cp != 0) { + if (!active && (*cp == '-')) { + active = 1; + } else if (active) + switch (*cp) { + case 'a': + howto |= RB_ASKNAME; + break; + case 'c': + howto |= RB_CONFIG; + break; + case 'C': + howto |= RB_CDROM; + break; + case 'd': + howto |= RB_KDB; + break; + case 'm': + howto |= RB_MUTE; + break; + case 'g': + howto |= RB_GDB; + break; + case 'h': + howto |= RB_SERIAL; + break; + case 'r': + howto |= RB_DFLTROOT; + break; + case 's': + howto |= RB_SINGLE; + break; + case 'v': + howto |= RB_VERBOSE; + break; + default: + active = 0; + break; + } + cp++; + } + } + /* get equivalents from the environment */ + for (i = 0; howto_names[i].ev != NULL; i++) + if (getenv(howto_names[i].ev) != NULL) + howto |= howto_names[i].mask; + if (!strcmp(getenv("console"), "comconsole")) + howto |= RB_SERIAL; + if (!strcmp(getenv("console"), "nullconsole")) + howto |= RB_MUTE; + return(howto); +} + +/* + * 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) { + ski_copyin(ep->ev_name, addr, strlen(ep->ev_name)); + addr += strlen(ep->ev_name); + ski_copyin("=", addr, 1); + addr++; + if (ep->ev_value != NULL) { + ski_copyin(ep->ev_value, addr, strlen(ep->ev_value)); + addr += strlen(ep->ev_value); + } + ski_copyin("", addr, 1); + addr++; + } + ski_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); \ + ski_copyin(&x, a, sizeof(x)); \ + a += sizeof(x); \ +} + +#define MOD_STR(t, a, s) { \ + COPY32(t, a); \ + COPY32(strlen(s) + 1, a); \ + ski_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); \ + ski_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); \ + ski_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 *bi, struct preloaded_file *fp, char *args) +{ + char *rootdevname; + struct ski_devdesc *rootdev; + struct preloaded_file *xp; + vm_offset_t addr, bootinfo_addr; + char *kernelname; + vm_offset_t ssym, esym; + struct file_metadata *md; + + /* + * Version 1 bootinfo. + */ + bi->bi_magic = BOOTINFO_MAGIC; + bi->bi_version = 1; + + /* + * Calculate boothowto. + */ + bi->bi_boothowto = bi_getboothowto(fp->f_args); + + /* + * 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"); + ski_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(ski_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->bi_symtab = ssym; + bi->bi_esymtab = 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 */ + addr = (addr + PAGE_MASK) & ~PAGE_MASK; + + /* copy our environment */ + bi->bi_envp = addr; + addr = bi_copyenv(addr); + + /* pad to a page boundary */ + addr = (addr + PAGE_MASK) & ~PAGE_MASK; + + /* copy module list and metadata */ + bi->bi_modulep = addr; + addr = bi_copymodules(addr); + + /* all done copying stuff in, save end of loaded object space */ + bi->bi_kernend = addr; + + return (ski_init_stubs(bi)); +} diff --git a/sys/boot/ia64/libski/copy.c b/sys/boot/ia64/libski/copy.c new file mode 100644 index 0000000..d86537a --- /dev/null +++ b/sys/boot/ia64/libski/copy.c @@ -0,0 +1,58 @@ +/*- + * 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +/* + * MD primitives supporting placement of module data + * + * XXX should check load address/size against memory top. + */ +#include <stand.h> + +#include <machine/ia64_cpu.h> +#include <machine/vmparam.h> + +int +ski_copyin(void *src, vm_offset_t dest, size_t len) +{ + bcopy(src, (void*) IA64_RR_MASK(dest), len); + return (len); +} + +int +ski_copyout(vm_offset_t src, void *dest, size_t len) +{ + bcopy((void*) IA64_RR_MASK(src), dest, len); + return (len); +} + +int +ski_readin(int fd, vm_offset_t dest, size_t len) +{ + return (read(fd, (void*) IA64_RR_MASK(dest), len)); +} diff --git a/sys/boot/ia64/libski/delay.c b/sys/boot/ia64/libski/delay.c new file mode 100644 index 0000000..2389603 --- /dev/null +++ b/sys/boot/ia64/libski/delay.c @@ -0,0 +1,34 @@ +/*- + * 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +void +delay(int usecs) +{ + return; +} diff --git a/sys/boot/ia64/libski/devicename.c b/sys/boot/ia64/libski/devicename.c new file mode 100644 index 0000000..b01bf18 --- /dev/null +++ b/sys/boot/ia64/libski/devicename.c @@ -0,0 +1,238 @@ +/*- + * 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <stand.h> +#include <string.h> +#include <sys/disklabel.h> +#include "bootstrap.h" +#include "libski.h" + +static int ski_parsedev(struct ski_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 +ski_getdev(void **vdev, const char *devspec, const char **path) +{ + struct ski_devdesc **dev = (struct ski_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 = ski_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(ski_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 +ski_parsedev(struct ski_devdesc **dev, const char *devspec, const char **path) +{ + struct ski_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 ski_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.skidisk.unit = unit; + idev->d_kind.skidisk.slice = slice; + idev->d_kind.skidisk.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 * +ski_fmtdev(void *vdev) +{ + struct ski_devdesc *dev = (struct ski_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.skidisk.unit); + if (dev->d_kind.skidisk.slice > 0) + cp += sprintf(cp, "s%d", dev->d_kind.skidisk.slice); + if (dev->d_kind.skidisk.partition >= 0) + cp += sprintf(cp, "%c", dev->d_kind.skidisk.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 +ski_setcurrdev(struct env_var *ev, int flags, void *value) +{ + struct ski_devdesc *ncurr; + int rv; + + if ((rv = ski_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/libski/efi_stub.c b/sys/boot/ia64/libski/efi_stub.c new file mode 100644 index 0000000..f2a1dff --- /dev/null +++ b/sys/boot/ia64/libski/efi_stub.c @@ -0,0 +1,268 @@ +/* + * Copyright (c) 2003 Marcel Moolenaar + * 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 ``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 <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <machine/bootinfo.h> +#include <efi.h> +#include <stand.h> +#include "libski.h" + +extern void acpi_root; +extern void sal_systab; + +extern void acpi_stub_init(void); +extern void sal_stub_init(void); + +EFI_CONFIGURATION_TABLE efi_cfgtab[] = { + { ACPI_20_TABLE_GUID, &acpi_root }, + { SAL_SYSTEM_TABLE_GUID, &sal_systab } +}; + + +static EFI_STATUS GetTime(EFI_TIME *, EFI_TIME_CAPABILITIES *); +static EFI_STATUS SetTime(EFI_TIME *); +static EFI_STATUS GetWakeupTime(BOOLEAN *, BOOLEAN *, EFI_TIME *); +static EFI_STATUS SetWakeupTime(BOOLEAN, EFI_TIME *); + +static EFI_STATUS SetVirtualAddressMap(UINTN, UINTN, UINT32, + EFI_MEMORY_DESCRIPTOR*); +static EFI_STATUS ConvertPointer(UINTN, VOID **); + +static EFI_STATUS GetVariable(CHAR16 *, EFI_GUID *, UINT32 *, UINTN *, VOID *); +static EFI_STATUS GetNextVariableName(UINTN *, CHAR16 *, EFI_GUID *); +static EFI_STATUS SetVariable(CHAR16 *, EFI_GUID *, UINT32, UINTN, VOID *); + +static EFI_STATUS GetNextHighMonotonicCount(UINT32 *); +static EFI_STATUS ResetSystem(EFI_RESET_TYPE, EFI_STATUS, UINTN, CHAR16 *); + +EFI_RUNTIME_SERVICES efi_rttab = { + /* Header. */ + { EFI_RUNTIME_SERVICES_SIGNATURE, + EFI_RUNTIME_SERVICES_REVISION, + 0, /* XXX HeaderSize */ + 0, /* XXX CRC32 */ + }, + + /* Time services */ + GetTime, + SetTime, + GetWakeupTime, + SetWakeupTime, + + /* Virtual memory services */ + SetVirtualAddressMap, + ConvertPointer, + + /* Variable services */ + GetVariable, + GetNextVariableName, + SetVariable, + + /* Misc */ + GetNextHighMonotonicCount, + ResetSystem +}; + +EFI_SYSTEM_TABLE efi_systab = { + /* Header. */ + { EFI_SYSTEM_TABLE_SIGNATURE, + EFI_SYSTEM_TABLE_REVISION, + 0, /* XXX HeaderSize */ + 0, /* XXX CRC32 */ + }, + + /* Firmware info. */ + L"FreeBSD", 0, + + /* Console stuff. */ + NULL, NULL, + NULL, NULL, + NULL, NULL, + + /* Services (runtime first). */ + &efi_rttab, + NULL, + + /* Configuration tables. */ + sizeof(efi_cfgtab)/sizeof(EFI_CONFIGURATION_TABLE), + efi_cfgtab +}; + +static EFI_STATUS +unsupported(const char *func) +{ + printf("EFI: %s not supported\n", func); + return (EFI_UNSUPPORTED); +} + +static EFI_STATUS +GetTime(EFI_TIME *time, EFI_TIME_CAPABILITIES *caps) +{ + UINT32 comps[8]; + + ssc((UINT64)comps, 0, 0, 0, SSC_GET_RTC); + time->Year = comps[0] + 1900; + time->Month = comps[1] + 1; + time->Day = comps[2]; + time->Hour = comps[3]; + time->Minute = comps[4]; + time->Second = comps[5]; + time->Pad1 = time->Pad2 = 0; + time->Nanosecond = 0; + time->TimeZone = 0; + time->Daylight = 0; + return (EFI_SUCCESS); +} + +static EFI_STATUS +SetTime(EFI_TIME *time) +{ + return (EFI_SUCCESS); +} + +static EFI_STATUS +GetWakeupTime(BOOLEAN *enabled, BOOLEAN *pending, EFI_TIME *time) +{ + return (unsupported(__func__)); +} + +static EFI_STATUS +SetWakeupTime(BOOLEAN enable, EFI_TIME *time) +{ + return (unsupported(__func__)); +} + +static void +Reloc(void *addr, UINT64 delta) +{ + UINT64 **fpp = addr; + + *fpp[0] += delta; + *fpp[1] += delta; + *fpp += delta >> 3; +} + +static EFI_STATUS +SetVirtualAddressMap(UINTN mapsz, UINTN descsz, UINT32 version, + EFI_MEMORY_DESCRIPTOR *memmap) +{ + UINT64 delta; + + delta = memmap->VirtualStart - memmap->PhysicalStart; + Reloc(&efi_rttab.GetTime, delta); + Reloc(&efi_rttab.SetTime, delta); + return (EFI_SUCCESS); /* Hah... */ +} + +static EFI_STATUS +ConvertPointer(UINTN debug, VOID **addr) +{ + return (unsupported(__func__)); +} + +static EFI_STATUS +GetVariable(CHAR16 *name, EFI_GUID *vendor, UINT32 *attrs, UINTN *datasz, + VOID *data) +{ + return (unsupported(__func__)); +} + +static EFI_STATUS +GetNextVariableName(UINTN *namesz, CHAR16 *name, EFI_GUID *vendor) +{ + return (unsupported(__func__)); +} + +static EFI_STATUS +SetVariable(CHAR16 *name, EFI_GUID *vendor, UINT32 attrs, UINTN datasz, + VOID *data) +{ + return (unsupported(__func__)); +} + +static EFI_STATUS +GetNextHighMonotonicCount(UINT32 *high) +{ + static UINT32 counter = 0; + + *high = counter++; + return (EFI_SUCCESS); +} + +static EFI_STATUS +ResetSystem(EFI_RESET_TYPE type, EFI_STATUS status, UINTN datasz, + CHAR16 *data) +{ + return (unsupported(__func__)); +} + +int +ski_init_stubs(struct bootinfo *bi) +{ + EFI_MEMORY_DESCRIPTOR *memp; + + /* Describe the SKI memory map. */ + bi->bi_memmap = (u_int64_t)(bi + 1); + bi->bi_memmap_size = 4 * sizeof(EFI_MEMORY_DESCRIPTOR); + bi->bi_memdesc_size = sizeof(EFI_MEMORY_DESCRIPTOR); + bi->bi_memdesc_version = 1; + + memp = (EFI_MEMORY_DESCRIPTOR *)bi->bi_memmap; + + memp[0].Type = EfiPalCode; + memp[0].PhysicalStart = 0x100000; + memp[0].VirtualStart = 0; + memp[0].NumberOfPages = (4L*1024*1024)>>12; + memp[0].Attribute = EFI_MEMORY_WB | EFI_MEMORY_RUNTIME; + + memp[1].Type = EfiConventionalMemory; + memp[1].PhysicalStart = 5L*1024*1024; + memp[1].VirtualStart = 0; + memp[1].NumberOfPages = (128L*1024*1024)>>12; + memp[1].Attribute = EFI_MEMORY_WB; + + memp[2].Type = EfiConventionalMemory; + memp[2].PhysicalStart = 4L*1024*1024*1024; + memp[2].VirtualStart = 0; + memp[2].NumberOfPages = (64L*1024*1024)>>12; + memp[2].Attribute = EFI_MEMORY_WB; + + memp[3].Type = EfiMemoryMappedIOPortSpace; + memp[3].PhysicalStart = 0xffffc000000; + memp[3].VirtualStart = 0; + memp[3].NumberOfPages = (64L*1024*1024)>>12; + memp[3].Attribute = EFI_MEMORY_UC; + + bi->bi_systab = (u_int64_t)&efi_systab; + + sal_stub_init(); + acpi_stub_init(); + + return (0); +} diff --git a/sys/boot/ia64/libski/elf_freebsd.c b/sys/boot/ia64/libski/elf_freebsd.c new file mode 100644 index 0000000..85a8ea6 --- /dev/null +++ b/sys/boot/ia64/libski/elf_freebsd.c @@ -0,0 +1,206 @@ +/* $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 <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <stand.h> +#include <string.h> + +#include <sys/param.h> +#include <sys/linker.h> +#include <machine/elf.h> +#include <machine/bootinfo.h> +#include <machine/ia64_cpu.h> +#include <machine/vmparam.h> + +#include "bootstrap.h" +#include "libski.h" + +#define _KERNEL + +static int elf64_exec(struct preloaded_file *amp); + +struct file_format ia64_elf = { elf64_loadfile, elf64_exec }; + +#define PTE_MA_WB 0 +#define PTE_MA_UC 4 +#define PTE_MA_UCE 5 +#define PTE_MA_WC 6 +#define PTE_MA_NATPAGE 7 + +#define PTE_PL_KERN 0 +#define PTE_PL_USER 3 + +#define PTE_AR_R 0 +#define PTE_AR_RX 1 +#define PTE_AR_RW 2 +#define PTE_AR_RWX 3 +#define PTE_AR_R_RW 4 +#define PTE_AR_RX_RWX 5 +#define PTE_AR_RWX_RW 6 +#define PTE_AR_X_RX 7 + +/* + * A short-format VHPT entry. Also matches the TLB insertion format. + */ +struct ia64_pte { + u_int64_t pte_p :1; /* bits 0..0 */ + u_int64_t pte_rv1 :1; /* bits 1..1 */ + u_int64_t pte_ma :3; /* bits 2..4 */ + u_int64_t pte_a :1; /* bits 5..5 */ + u_int64_t pte_d :1; /* bits 6..6 */ + u_int64_t pte_pl :2; /* bits 7..8 */ + u_int64_t pte_ar :3; /* bits 9..11 */ + u_int64_t pte_ppn :38; /* bits 12..49 */ + u_int64_t pte_rv2 :2; /* bits 50..51 */ + u_int64_t pte_ed :1; /* bits 52..52 */ + u_int64_t pte_ig :11; /* bits 53..63 */ +}; + +static struct bootinfo bootinfo; + +void +enter_kernel(const char* filename, u_int64_t start, struct bootinfo *bi) +{ + printf("Entering %s at 0x%lx...\n", filename, start); + + while (*filename == '/') + filename++; + ssc(0, (u_int64_t) filename, 0, 0, SSC_LOAD_SYMBOLS); + + __asm __volatile("mov cr.ipsr=%0" + :: "r"(IA64_PSR_IC + | IA64_PSR_DT + | IA64_PSR_RT + | IA64_PSR_IT + | IA64_PSR_BN)); + __asm __volatile("mov cr.iip=%0" :: "r"(start)); + __asm __volatile("mov cr.ifs=r0;;"); + __asm __volatile("mov r8=%0" :: "r" (bi)); + __asm __volatile("rfi;;"); +} + +static int +elf64_exec(struct preloaded_file *fp) +{ + struct file_metadata *md; + Elf_Ehdr *hdr; + struct ia64_pte pte; + struct bootinfo *bi; + + if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) + return(EFTYPE); /* XXX actually EFUCKUP */ + hdr = (Elf_Ehdr *)&(md->md_data); + + /* + * Ugly hack, similar to linux. Dump the bootinfo into a + * special page reserved in the link map. + */ + bi = &bootinfo; + bzero(bi, sizeof(struct bootinfo)); + bi_load(bi, fp); + + /* + * Region 6 is direct mapped UC and region 7 is direct mapped + * WC. The details of this is controlled by the Alt {I,D}TLB + * handlers. Here we just make sure that they have the largest + * possible page size to minimise TLB usage. + */ + ia64_set_rr(IA64_RR_BASE(6), (6 << 8) | (28 << 2)); + ia64_set_rr(IA64_RR_BASE(7), (7 << 8) | (28 << 2)); + + bzero(&pte, sizeof(pte)); + pte.pte_p = 1; + pte.pte_ma = PTE_MA_WB; + pte.pte_a = 1; + pte.pte_d = 1; + pte.pte_pl = PTE_PL_KERN; + pte.pte_ar = PTE_AR_RWX; + pte.pte_ppn = 0; + + __asm __volatile("mov cr.ifa=%0" :: "r"(IA64_RR_BASE(7))); + __asm __volatile("mov cr.itir=%0" :: "r"(28 << 2)); + __asm __volatile("srlz.i;;"); + __asm __volatile("itr.i itr[%0]=%1;;" + :: "r"(0), "r"(*(u_int64_t*)&pte)); + __asm __volatile("srlz.i;;"); + __asm __volatile("itr.d dtr[%0]=%1;;" + :: "r"(0), "r"(*(u_int64_t*)&pte)); + __asm __volatile("srlz.i;;"); + + enter_kernel(fp->f_name, hdr->e_entry, bi); +} diff --git a/sys/boot/ia64/libski/exit.c b/sys/boot/ia64/libski/exit.c new file mode 100644 index 0000000..aeac67c --- /dev/null +++ b/sys/boot/ia64/libski/exit.c @@ -0,0 +1,42 @@ +/*- + * Copyright (c) 2000 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/time.h> +#include <stddef.h> +#include <stand.h> +#include <stdarg.h> + +#include "libski.h" + +void +exit(int code) +{ + ssc(code, 0, 0, 0, SSC_EXIT); +} diff --git a/sys/boot/ia64/libski/libski.h b/sys/boot/ia64/libski/libski.h new file mode 100644 index 0000000..043177c --- /dev/null +++ b/sys/boot/ia64/libski/libski.h @@ -0,0 +1,96 @@ +/*- + * 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$ + */ + +/* + * SKI fully-qualified device descriptor + */ +struct ski_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; + } skidisk; + struct { + int unit; /* XXX net layer lives over these? */ + } netif; + } d_kind; +}; + +extern int ski_getdev(void **vdev, const char *devspec, const char **path); +extern char *ski_fmtdev(void *vdev); +extern int ski_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 skifs_dev; +extern struct devsw ski_disk; +extern struct netif_driver ski_net; + +/* Wrapper over SKI filesystems. */ +extern struct fs_ops ski_fsops; + +/* this is in startup code */ +extern void delay(int); +extern void reboot(void); + +extern ssize_t ski_copyin(const void *src, vm_offset_t dest, size_t len); +extern ssize_t ski_copyout(const vm_offset_t src, void *dest, size_t len); +extern ssize_t ski_readin(int fd, vm_offset_t dest, size_t len); + +extern int ski_boot(void); +extern int ski_autoload(void); + +struct bootinfo; +struct preloaded_file; +extern int bi_load(struct bootinfo *, struct preloaded_file *); + +#define SSC_CONSOLE_INIT 20 +#define SSC_GETCHAR 21 +#define SSC_PUTCHAR 31 +#define SSC_OPEN 50 +#define SSC_CLOSE 51 +#define SSC_READ 52 +#define SSC_WRITE 53 +#define SSC_GET_COMPLETION 54 +#define SSC_WAIT_COMPLETION 55 +#define SSC_GET_RTC 65 +#define SSC_EXIT 66 +#define SSC_LOAD_SYMBOLS 69 +#define SSC_SAL_SET_VECTORS 120 + +u_int64_t ssc(u_int64_t in0, u_int64_t in1, u_int64_t in2, u_int64_t in3, + int which); diff --git a/sys/boot/ia64/libski/module.c b/sys/boot/ia64/libski/module.c new file mode 100644 index 0000000..57f697c --- /dev/null +++ b/sys/boot/ia64/libski/module.c @@ -0,0 +1,40 @@ +/*- + * 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <stand.h> + +/* + * Use voodoo to load modules required by current hardware. + */ +int +ski_autoload(void) +{ + /* XXX use PnP to locate stuff here */ + return (0); +} diff --git a/sys/boot/ia64/libski/pal_stub.S b/sys/boot/ia64/libski/pal_stub.S new file mode 100644 index 0000000..e247661 --- /dev/null +++ b/sys/boot/ia64/libski/pal_stub.S @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2003 Marcel Moolenaar + * 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$ + */ + +#include <machine/asm.h> + + .text +ENTRY(PalProc, 0) + cmp.eq p6,p0=6,r28 // PAL_PTCE_INFO +(p6) br.cond.dptk pal_ptce_info + ;; + cmp.eq p6,p0=8,r28 // PAL_VM_SUMMARY +(p6) br.cond.dptk pal_vm_summary + ;; + cmp.eq p6,p0=14,r28 // PAL_FREQ_RATIOS +(p6) br.cond.dptk pal_freq_ratios + ;; + cmp.eq p6,p0=29,r28 // PAL_HALT_LIGHT +(p6) br.cond.dptk pal_halt_light + ;; + mov r15=66 // EXIT + break.i 0x80000 // SSC + ;; +pal_ptce_info: + mov r8=0 + mov r9=0 // base + movl r10=0x0000000100000001 // loop counts (outer|inner) + mov r11=0x0000000000000000 // loop strides (outer|inner) + br.sptk b0 +pal_vm_summary: + mov r8=0 + movl r9=(8<<40)|(8<<32) // VM info 1 + mov r10=(18<<8)|(41<<0) // VM info 2 + mov r11=0 + br.sptk b0 +pal_freq_ratios: + mov r8=0 + movl r9=0x0000000B00000002 // processor ratio 11/2 + movl r10=0x0000000100000001 // bus ratio 1/1 + movl r11=0x0000000B00000002 // ITC ratio 11/2 + br.sptk b0 +pal_halt_light: + mov r8=0 + mov r9=0 + mov r10=0 + mov r11=0 + br.sptk b0 +END(PalProc) diff --git a/sys/boot/ia64/libski/sal_stub.c b/sys/boot/ia64/libski/sal_stub.c new file mode 100644 index 0000000..b5661a3 --- /dev/null +++ b/sys/boot/ia64/libski/sal_stub.c @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2003 Marcel Moolenaar + * 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 ``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 <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <machine/md_var.h> +#include <machine/sal.h> +#include <stand.h> +#include "libski.h" + +extern void PalProc(void); +static sal_entry_t SalProc; + +struct { + struct sal_system_table header; + struct sal_entrypoint_descriptor entry; + struct sal_ap_wakeup_descriptor wakeup; +} sal_systab = { + /* Header. */ + { + SAL_SIGNATURE, + sizeof(sal_systab), + { 00, 03 }, /* Revision 3.0. */ + 2, /* Number of decsriptors. */ + 0, /* XXX checksum. */ + { 0 }, + { 00, 00 }, /* XXX SAL_A version. */ + { 00, 00 }, /* XXX SAL_B version. */ + "FreeBSD", + "Ski loader", + { 0 } + }, + /* Entrypoint. */ + { + 0, /* Type=entrypoint descr. */ + { 0 }, + 0, /* XXX PalProc. */ + 0, /* XXX SalProc. */ + 0, /* XXX SalProc GP. */ + { 0 } + }, + /* AP wakeup. */ + { + 5, /* Type=AP wakeup descr. */ + 0, /* External interrupt. */ + { 0 }, + 255 /* Wakeup vector. */ + } +}; + +static inline void +puts(const char *s) +{ + s = (const char *)((7UL << 61) | (u_long)s); + while (*s) + ski_cons_putchar(*s++); +} + +static struct ia64_sal_result +SalProc(u_int64_t a1, u_int64_t a2, u_int64_t a3, u_int64_t a4, u_int64_t a5, + u_int64_t a6, u_int64_t a7, u_int64_t a8) +{ + struct ia64_sal_result res; + + res.sal_status = -3; + res.sal_result[0] = 0; + res.sal_result[1] = 0; + res.sal_result[2] = 0; + + if (a1 == SAL_FREQ_BASE) { + res.sal_status = 0; + res.sal_result[0] = 133338184; + } else if (a1 == SAL_SET_VECTORS) { + /* XXX unofficial SSC function. */ + ssc(a2, a3, a4, a5, SSC_SAL_SET_VECTORS); + } else if (a1 != SAL_GET_STATE_INFO_SIZE) { + puts("SAL: unimplemented function called\n"); + } + + return (res); +} + +void +sal_stub_init(void) +{ + struct ia64_fdesc *fd; + + fd = (void*)PalProc; + sal_systab.entry.sale_pal_proc = fd->func; + fd = (void*)SalProc; + sal_systab.entry.sale_sal_proc = fd->func; + sal_systab.entry.sale_sal_gp = fd->gp; +} diff --git a/sys/boot/ia64/libski/skiconsole.c b/sys/boot/ia64/libski/skiconsole.c new file mode 100644 index 0000000..e5cea3d --- /dev/null +++ b/sys/boot/ia64/libski/skiconsole.c @@ -0,0 +1,96 @@ +/*- + * Copyright (c) 2000 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <stand.h> + +#include "bootstrap.h" +#include "libski.h" + +static void +ski_cons_probe(struct console *cp) +{ + cp->c_flags |= C_PRESENTIN | C_PRESENTOUT; +} + +static int +ski_cons_init(int arg) +{ + ssc(0, 0, 0, 0, SSC_CONSOLE_INIT); + return 0; +} + +void +ski_cons_putchar(int c) +{ + ssc(c, 0, 0, 0, SSC_PUTCHAR); +} + +static int pollchar = -1; + +int +ski_cons_getchar() +{ + int c; + + if (pollchar > 0) { + c = pollchar; + pollchar = -1; + return c; + } + + do { + c = ssc(0, 0, 0, 0, SSC_GETCHAR); + } while (c == 0); + + return c; +} + +int +ski_cons_poll() +{ + int c; + if (pollchar > 0) + return 1; + c = ssc(0, 0, 0, 0, SSC_GETCHAR); + if (!c) + return 0; + pollchar = c; + return 1; +} + +struct console ski_console = { + "ski", + "ia64 SKI console", + 0, + ski_cons_probe, + ski_cons_init, + ski_cons_putchar, + ski_cons_getchar, + ski_cons_poll +}; diff --git a/sys/boot/ia64/libski/skifs.c b/sys/boot/ia64/libski/skifs.c new file mode 100644 index 0000000..5a272c7 --- /dev/null +++ b/sys/boot/ia64/libski/skifs.c @@ -0,0 +1,193 @@ +/*- + * 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/time.h> +#include <stddef.h> +#include <stand.h> +#include <stdarg.h> + +#include "libski.h" + +struct disk_req { + unsigned long addr; + unsigned len; +}; + +struct disk_stat { + int fd; + unsigned count; +}; + +static int +skifs_open(const char *path, struct open_file *f) +{ + int fd; + + /* + * Skip leading '/' so that our pretend filesystem starts in + * the current working directory. + */ + while (*path == '/') + path++; + + fd = ssc((u_int64_t) path, 1, 0, 0, SSC_OPEN); + if (fd > 0) { + f->f_fsdata = (void*)(u_int64_t) fd; + return 0; + } + return ENOENT; +} + +static int +skifs_close(struct open_file *f) +{ + ssc((u_int64_t) f->f_fsdata, 0, 0, 0, SSC_CLOSE); + return 0; +} + +static int +skifs_read(struct open_file *f, void *buf, size_t size, size_t *resid) +{ + struct disk_req req; + struct disk_stat stat; + + req.len = size; + req.addr = (u_int64_t) buf; + ssc((u_int64_t) f->f_fsdata, 1, (u_int64_t) &req, f->f_offset, SSC_READ); + stat.fd = (u_int64_t) f->f_fsdata; + ssc((u_int64_t)&stat, 0, 0, 0, SSC_WAIT_COMPLETION); + + *resid = size - stat.count; + f->f_offset += stat.count; + return 0; +} + +static off_t +skifs_seek(struct open_file *f, off_t offset, int where) +{ + u_int64_t base; + + switch (where) { + case SEEK_SET: + base = 0; + break; + + case SEEK_CUR: + base = f->f_offset; + break; + + case SEEK_END: + printf("can't find end of file in SKI\n"); + base = f->f_offset; + break; + } + + f->f_offset = base + offset; + return base; +} + +static int +skifs_stat(struct open_file *f, struct stat *sb) +{ + bzero(sb, sizeof(*sb)); + sb->st_mode = S_IFREG | S_IRUSR; + return 0; +} + +static int +skifs_readdir(struct open_file *f, struct dirent *d) +{ + return ENOENT; +} + +struct fs_ops ski_fsops = { + "fs", + skifs_open, + skifs_close, + skifs_read, + null_write, + skifs_seek, + skifs_stat, + skifs_readdir +}; + +static int +skifs_dev_init(void) +{ + return 0; +} + +/* + * Print information about disks + */ +static void +skifs_dev_print(int verbose) +{ +} + +/* + * 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 +skifs_dev_open(struct open_file *f, ...) +{ + return 0; +} + +static int +skifs_dev_close(struct open_file *f) +{ + + return 0; +} + +static int +skifs_dev_strategy(void *devdata, int rw, daddr_t dblk, size_t size, char *buf, size_t *rsize) +{ + return 0; +} + +struct devsw skifs_dev = { + "fs", + DEVT_DISK, + skifs_dev_init, + skifs_dev_strategy, + skifs_dev_open, + skifs_dev_close, + noioctl, + skifs_dev_print +}; diff --git a/sys/boot/ia64/libski/ssc.c b/sys/boot/ia64/libski/ssc.c new file mode 100644 index 0000000..e1f871c --- /dev/null +++ b/sys/boot/ia64/libski/ssc.c @@ -0,0 +1,53 @@ +/*- + * 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <stand.h> +#include "libski.h" + +/* + * Ugh... Work around a bug in the Linux version of ski for SSC_GET_RTC. The + * PSR.dt register is not preserved properly and causes further memory + * references to be done without translation. All we need to do is preserve + * PSR.dt across the SSC call. We do this by saving and restoring psr.l + * completely. + */ +u_int64_t +ssc(u_int64_t in0, u_int64_t in1, u_int64_t in2, u_int64_t in3, int which) +{ + register u_int64_t psr; + register u_int64_t ret0 __asm("r8"); + + __asm __volatile("mov %0=psr;;" : "=r"(psr)); + __asm __volatile("mov r15=%1\n\t" + "break 0x80000;;" + : "=r"(ret0) + : "r"(which), "r"(in0), "r"(in1), "r"(in2), "r"(in3)); + __asm __volatile("mov psr.l=%0;; srlz.d" :: "r"(psr)); + return ret0; +} diff --git a/sys/boot/ia64/libski/time.c b/sys/boot/ia64/libski/time.c new file mode 100644 index 0000000..c66bdee --- /dev/null +++ b/sys/boot/ia64/libski/time.c @@ -0,0 +1,174 @@ +/* + * Copyright (c) 1999, 2000 + * Intel Corporation. + * 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 Intel Corporation and + * its contributors. + * + * 4. Neither the name of Intel Corporation or its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION 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 INTEL CORPORATION 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/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <time.h> +#include <sys/time.h> +#include <stand.h> + +#include "libski.h" + +/* +// Accurate only for the past couple of centuries; +// that will probably do. +// +// (#defines From FreeBSD 3.2 lib/libc/stdtime/tzfile.h) +*/ + +#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0)) +#define SECSPERHOUR ( 60*60 ) +#define SECSPERDAY (24 * SECSPERHOUR) + +struct ssc_time { + int Year; + int Month; + int Day; + int Hour; + int Minute; + int Second; + int Msec; + int Wday; +}; + +time_t +EfiTimeToUnixTime(struct ssc_time *ETime) +{ + /* + // These arrays give the cumulative number of days up to the first of the + // month number used as the index (1 -> 12) for regular and leap years. + // The value at index 13 is for the whole year. + */ + static time_t CumulativeDays[2][14] = { + {0, + 0, + 31, + 31 + 28, + 31 + 28 + 31, + 31 + 28 + 31 + 30, + 31 + 28 + 31 + 30 + 31, + 31 + 28 + 31 + 30 + 31 + 30, + 31 + 28 + 31 + 30 + 31 + 30 + 31, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 }, + {0, + 0, + 31, + 31 + 29, + 31 + 29 + 31, + 31 + 29 + 31 + 30, + 31 + 29 + 31 + 30 + 31, + 31 + 29 + 31 + 30 + 31 + 30, + 31 + 29 + 31 + 30 + 31 + 30 + 31, + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31, + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30, + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31, + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30, + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 }}; + + time_t UTime; + int Year; + + ETime->Year += 1900; + + /* + // Do a santity check + */ + if ( ETime->Year < 1998 || ETime->Year > 2099 || + ETime->Month == 0 || ETime->Month > 12 || + ETime->Day == 0 || ETime->Month > 31 || + ETime->Hour > 23 || + ETime->Minute > 59 || + ETime->Second > 59 ) { + return (0); + } + + /* + // Years + */ + UTime = 0; + for (Year = 1970; Year != ETime->Year; ++Year) { + UTime += (CumulativeDays[isleap(Year)][13] * SECSPERDAY); + } + + /* + // UTime should now be set to 00:00:00 on Jan 1 of the file's year. + // + // Months + */ + UTime += (CumulativeDays[isleap(ETime->Year)][ETime->Month] * SECSPERDAY); + + /* + // UTime should now be set to 00:00:00 on the first of the file's month and year + // + // Days -- Don't count the file's day + */ + UTime += (((ETime->Day > 0) ? ETime->Day-1:0) * SECSPERDAY); + + /* + // Hours + */ + UTime += (ETime->Hour * SECSPERHOUR); + + /* + // Minutes + */ + UTime += (ETime->Minute * 60); + + /* + // Seconds + */ + UTime += ETime->Second; + + return UTime; +} + +time_t +time(time_t *tloc) +{ + struct ssc_time time; + + ssc((u_int64_t) &time, 0, 0, 0, SSC_GET_RTC); + + return *tloc = EfiTimeToUnixTime(&time); +} diff --git a/sys/boot/ia64/ski/Makefile b/sys/boot/ia64/ski/Makefile new file mode 100644 index 0000000..5d89340 --- /dev/null +++ b/sys/boot/ia64/ski/Makefile @@ -0,0 +1,85 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../common + +PROG= skiload +NOMAN= +NEWVERSWHAT= "ia64 SKI boot" ${MACHINE_ARCH} +BINDIR?= /boot +STRIP= # We must not strip skiload at install time. + +SRCS+= conf.c main.c start.S + +CFLAGS+= -ffreestanding + +.if !defined(NOFORTH) +# Enable BootForth +BOOT_FORTH= yes +CFLAGS+= -DBOOT_FORTH +CFLAGS+= -I${.CURDIR}/../../ficl -I${.CURDIR}/../../ficl/${MACHINE_ARCH} +.if exists(${.OBJDIR}/../../ficl/libficl.a) +LIBFICL= ${.OBJDIR}/../../ficl/libficl.a +.else +LIBFICL= ${.CURDIR}/../../ficl/libficl.a +.endif +.endif + +# where to get libstand from +.if exists(${.OBJDIR}/../../../../lib/libstand/libstand.a) +LIBSTAND= ${.OBJDIR}/../../../../lib/libstand/libstand.a +.else +LIBSTAND= ${.CURDIR}/../../../../lib/libstand/libstand.a +.endif + +.if exists(${.OBJDIR}/../libski/libski.a) +LIBSKI= ${.OBJDIR}/../libski/libski.a +.else +LIBSKI= ${.CURDIR}/../libski/libski.a +.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}/../libski +CFLAGS+= -DLOADER + +LDFLAGS= -nostdlib -T ${.CURDIR}/ldscript.ia64 + +CLEANFILES+= vers.c vers.o ${PROG}.list +CLEANFILES+= loader.help +CLEANFILES+= machine + +all: ${PROG} + +vers.o: ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version + sh ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version ${NEWVERSWHAT} + ${CC} -c vers.c + +${PROG}.help: help.common help.efi + cat ${.ALLSRC} | awk -f ${.CURDIR}/../../common/merge_help.awk \ + > ${.TARGET} + +beforeinstall: +.if exists(${.OBJDIR}/${PROG}.help) + ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \ + ${.OBJDIR}/${PROG}.help ${DESTDIR}/boot +.endif + +machine: + ln -sf ${.CURDIR}/../../../${MACHINE_ARCH}/include machine + +${PROG}: ${OBJS} ${LIBFICL} ${LIBSKI} ${LIBSTAND} vers.o + ${LD} ${LDFLAGS} -o ${PROG} -M \ + ${OBJS} vers.o \ + ${LIBFICL} ${LIBSTAND} ${LIBSKI} ${LIBSTAND} \ + > ${.OBJDIR}/${PROG}.list + +.include <bsd.prog.mk> + +beforedepend ${OBJS}: machine diff --git a/sys/boot/ia64/ski/acpi_stub.c b/sys/boot/ia64/ski/acpi_stub.c new file mode 100644 index 0000000..3e044e6 --- /dev/null +++ b/sys/boot/ia64/ski/acpi_stub.c @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2003 Marcel Moolenaar + * 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 ``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 <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <contrib/dev/acpica/acpi.h> + +#define APIC_IO_SAPIC 6 +#define APIC_LOCAL_SAPIC 7 + +#pragma pack(1) + +typedef struct /* LOCAL SAPIC */ +{ + APIC_HEADER Header; + UINT8 ProcessorId; /* ACPI processor id */ + UINT8 LocalSapicId; /* Processor local SAPIC id */ + UINT8 LocalSapicEid; /* Processor local SAPIC eid */ + UINT8 Reserved[3]; + UINT32 ProcessorEnabled: 1; + UINT32 FlagsReserved: 31; +} LOCAL_SAPIC; + +typedef struct /* IO SAPIC */ +{ + APIC_HEADER Header; + UINT8 IoSapicId; /* I/O SAPIC ID */ + UINT8 Reserved; /* reserved - must be zero */ + UINT32 Vector; /* interrupt base */ + UINT64 IoSapicAddress; /* SAPIC's physical address */ +} IO_SAPIC; + +/* + */ + +struct { + MULTIPLE_APIC_TABLE Header; + MADT_LOCAL_SAPIC cpu0; + MADT_LOCAL_SAPIC cpu1; + MADT_LOCAL_SAPIC cpu2; + MADT_LOCAL_SAPIC cpu3; + MADT_IO_SAPIC sapic; +} apic = { + /* Header. */ + { + APIC_SIG, /* Signature. */ + sizeof(apic), /* Length of table. */ + 0, /* ACPI minor revision. */ + 0, /* XXX checksum. */ + "FBSD", /* OEM Id. */ + "SKI", /* OEM table Id. */ + 0, /* OEM revision. */ + "FBSD", /* ASL compiler Id. */ + 0, /* ASL revision. */ + 0xfee00000, + }, + /* cpu0. */ + { + APIC_LOCAL_SAPIC, /* Type. */ + sizeof(apic.cpu0), /* Length. */ + 0, /* ACPI processor id */ + 0, /* Processor local SAPIC id */ + 0, /* Processor local SAPIC eid */ + { 0, 0, 0 }, + 1, /* FL: Enabled. */ + }, + /* cpu1. */ + { + APIC_LOCAL_SAPIC, /* Type. */ + sizeof(apic.cpu1), /* Length. */ + 1, /* ACPI processor id */ + 0, /* Processor local SAPIC id */ + 1, /* Processor local SAPIC eid */ + { 0, 0, 0 }, + 1, /* FL: Enabled. */ + }, + /* cpu2. */ + { + APIC_LOCAL_SAPIC, /* Type. */ + sizeof(apic.cpu2), /* Length. */ + 2, /* ACPI processor id */ + 1, /* Processor local SAPIC id */ + 0, /* Processor local SAPIC eid */ + { 0, 0, 0 }, + 0, /* FL: Enabled. */ + }, + /* cpu3. */ + { + APIC_LOCAL_SAPIC, /* Type. */ + sizeof(apic.cpu3), /* Length. */ + 3, /* ACPI processor id */ + 1, /* Processor local SAPIC id */ + 1, /* Processor local SAPIC eid */ + { 0, 0, 0 }, + 0, /* FL: Enabled. */ + }, + /* sapic. */ + { + APIC_IO_SAPIC, /* Type. */ + sizeof(apic.sapic), /* Length. */ + 4, /* IO SAPIC id. */ + 0, + 16, /* Interrupt base. */ + 0xfec00000 /* IO SAPIC address. */ + } +}; + +struct { + ACPI_TABLE_HEADER Header; + UINT64 apic_tbl; +} xsdt = { + { + XSDT_SIG, /* Signature. */ + sizeof(xsdt), /* Length of table. */ + 0, /* ACPI minor revision. */ + 0, /* XXX checksum. */ + "FBSD", /* OEM Id. */ + "SKI", /* OEM table Id. */ + 0, /* OEM revision. */ + "FBSD", /* ASL compiler Id. */ + 0 /* ASL revision. */ + }, + NULL /* XXX APIC table address. */ +}; + +RSDP_DESCRIPTOR acpi_root = { + RSDP_SIG, + 0, /* XXX checksum. */ + "FBSD", + 2, /* ACPI Rev 2.0. */ + NULL, + sizeof(xsdt), /* XSDT length. */ + NULL, /* XXX PA of XSDT. */ + 0, /* XXX Extended checksum. */ +}; + +static void +cksum(void *addr, int sz, UINT8 *sum) +{ + UINT8 *p, s; + + p = addr; + s = 0; + while (sz--) + s += *p++; + *sum = -s; +} + +void +acpi_stub_init(void) +{ + acpi_root.XsdtPhysicalAddress = (UINT64)&xsdt; + cksum(&acpi_root, 20, &acpi_root.Checksum); + cksum(&acpi_root, sizeof(acpi_root), &acpi_root.ExtendedChecksum); + + xsdt.apic_tbl = (UINT32)&apic; + cksum(&xsdt, sizeof(xsdt), &xsdt.Header.Checksum); +} diff --git a/sys/boot/ia64/ski/bootinfo.c b/sys/boot/ia64/ski/bootinfo.c new file mode 100644 index 0000000..dbc4673 --- /dev/null +++ b/sys/boot/ia64/ski/bootinfo.c @@ -0,0 +1,316 @@ +/*- + * 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <stand.h> +#include <string.h> +#include <sys/param.h> +#include <sys/reboot.h> +#include <sys/linker.h> +#include <machine/elf.h> +#include <machine/bootinfo.h> + +#include "bootstrap.h" + +/* + * Return a 'boothowto' value corresponding to the kernel arguments in + * (kargs) and any relevant environment variables. + */ +static struct +{ + const char *ev; + int mask; +} howto_names[] = { + {"boot_askname", RB_ASKNAME}, + {"boot_cdrom", RB_CDROM}, + {"boot_userconfig", RB_CONFIG}, + {"boot_ddb", RB_KDB}, + {"boot_gdb", RB_GDB}, + {"boot_single", RB_SINGLE}, + {"boot_verbose", RB_VERBOSE}, + {"boot_multicons", RB_MULTIPLE}, + {"boot_serial", RB_SERIAL}, + {NULL, 0} +}; + +extern char *ski_fmtdev(void *vdev); +extern int ski_init_stubs(struct bootinfo *); + +int +bi_getboothowto(char *kargs) +{ + char *cp; + int howto; + int active; + int i; + + /* Parse kargs */ + howto = 0; + if (kargs != NULL) { + cp = kargs; + active = 0; + while (*cp != 0) { + if (!active && (*cp == '-')) { + active = 1; + } else if (active) + switch (*cp) { + case 'a': + howto |= RB_ASKNAME; + break; + case 'c': + howto |= RB_CONFIG; + break; + case 'C': + howto |= RB_CDROM; + break; + case 'd': + howto |= RB_KDB; + break; + case 'm': + howto |= RB_MUTE; + break; + case 'g': + howto |= RB_GDB; + break; + case 'h': + howto |= RB_SERIAL; + break; + case 'r': + howto |= RB_DFLTROOT; + break; + case 's': + howto |= RB_SINGLE; + break; + case 'v': + howto |= RB_VERBOSE; + break; + default: + active = 0; + break; + } + cp++; + } + } + /* get equivalents from the environment */ + for (i = 0; howto_names[i].ev != NULL; i++) + if (getenv(howto_names[i].ev) != NULL) + howto |= howto_names[i].mask; + if (!strcmp(getenv("console"), "comconsole")) + howto |= RB_SERIAL; + if (!strcmp(getenv("console"), "nullconsole")) + howto |= RB_MUTE; + return(howto); +} + +/* + * 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) { + ski_copyin(ep->ev_name, addr, strlen(ep->ev_name)); + addr += strlen(ep->ev_name); + ski_copyin("=", addr, 1); + addr++; + if (ep->ev_value != NULL) { + ski_copyin(ep->ev_value, addr, strlen(ep->ev_value)); + addr += strlen(ep->ev_value); + } + ski_copyin("", addr, 1); + addr++; + } + ski_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); \ + ski_copyin(&x, a, sizeof(x)); \ + a += sizeof(x); \ +} + +#define MOD_STR(t, a, s) { \ + COPY32(t, a); \ + COPY32(strlen(s) + 1, a); \ + ski_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); \ + ski_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); \ + ski_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 *bi, struct preloaded_file *fp, char *args) +{ + char *rootdevname; + struct ski_devdesc *rootdev; + struct preloaded_file *xp; + vm_offset_t addr, bootinfo_addr; + char *kernelname; + vm_offset_t ssym, esym; + struct file_metadata *md; + + /* + * Version 1 bootinfo. + */ + bi->bi_magic = BOOTINFO_MAGIC; + bi->bi_version = 1; + + /* + * Calculate boothowto. + */ + bi->bi_boothowto = bi_getboothowto(fp->f_args); + + /* + * 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"); + ski_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(ski_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->bi_symtab = ssym; + bi->bi_esymtab = 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 */ + addr = (addr + PAGE_MASK) & ~PAGE_MASK; + + /* copy our environment */ + bi->bi_envp = addr; + addr = bi_copyenv(addr); + + /* pad to a page boundary */ + addr = (addr + PAGE_MASK) & ~PAGE_MASK; + + /* copy module list and metadata */ + bi->bi_modulep = addr; + addr = bi_copymodules(addr); + + /* all done copying stuff in, save end of loaded object space */ + bi->bi_kernend = addr; + + return (ski_init_stubs(bi)); +} diff --git a/sys/boot/ia64/ski/conf.c b/sys/boot/ia64/ski/conf.c new file mode 100644 index 0000000..5066a77 --- /dev/null +++ b/sys/boot/ia64/ski/conf.c @@ -0,0 +1,86 @@ +/* + * 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. + * + * $NetBSD: conf.c,v 1.2 1997/03/22 09:03:29 thorpej Exp $ + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <stand.h> + +#include "libski.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[] = { + &skifs_dev, + NULL +}; + +struct fs_ops *file_system[] = { + &ski_fsops, + &ufs_fsops, + &gzipfs_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 ski_console; + +struct console *consoles[] = { + &ski_console, + NULL +}; diff --git a/sys/boot/ia64/ski/copy.c b/sys/boot/ia64/ski/copy.c new file mode 100644 index 0000000..d86537a --- /dev/null +++ b/sys/boot/ia64/ski/copy.c @@ -0,0 +1,58 @@ +/*- + * 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +/* + * MD primitives supporting placement of module data + * + * XXX should check load address/size against memory top. + */ +#include <stand.h> + +#include <machine/ia64_cpu.h> +#include <machine/vmparam.h> + +int +ski_copyin(void *src, vm_offset_t dest, size_t len) +{ + bcopy(src, (void*) IA64_RR_MASK(dest), len); + return (len); +} + +int +ski_copyout(vm_offset_t src, void *dest, size_t len) +{ + bcopy((void*) IA64_RR_MASK(src), dest, len); + return (len); +} + +int +ski_readin(int fd, vm_offset_t dest, size_t len) +{ + return (read(fd, (void*) IA64_RR_MASK(dest), len)); +} diff --git a/sys/boot/ia64/ski/delay.c b/sys/boot/ia64/ski/delay.c new file mode 100644 index 0000000..2389603 --- /dev/null +++ b/sys/boot/ia64/ski/delay.c @@ -0,0 +1,34 @@ +/*- + * 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +void +delay(int usecs) +{ + return; +} diff --git a/sys/boot/ia64/ski/devicename.c b/sys/boot/ia64/ski/devicename.c new file mode 100644 index 0000000..b01bf18 --- /dev/null +++ b/sys/boot/ia64/ski/devicename.c @@ -0,0 +1,238 @@ +/*- + * 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <stand.h> +#include <string.h> +#include <sys/disklabel.h> +#include "bootstrap.h" +#include "libski.h" + +static int ski_parsedev(struct ski_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 +ski_getdev(void **vdev, const char *devspec, const char **path) +{ + struct ski_devdesc **dev = (struct ski_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 = ski_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(ski_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 +ski_parsedev(struct ski_devdesc **dev, const char *devspec, const char **path) +{ + struct ski_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 ski_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.skidisk.unit = unit; + idev->d_kind.skidisk.slice = slice; + idev->d_kind.skidisk.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 * +ski_fmtdev(void *vdev) +{ + struct ski_devdesc *dev = (struct ski_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.skidisk.unit); + if (dev->d_kind.skidisk.slice > 0) + cp += sprintf(cp, "s%d", dev->d_kind.skidisk.slice); + if (dev->d_kind.skidisk.partition >= 0) + cp += sprintf(cp, "%c", dev->d_kind.skidisk.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 +ski_setcurrdev(struct env_var *ev, int flags, void *value) +{ + struct ski_devdesc *ncurr; + int rv; + + if ((rv = ski_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/ski/efi_stub.c b/sys/boot/ia64/ski/efi_stub.c new file mode 100644 index 0000000..f2a1dff --- /dev/null +++ b/sys/boot/ia64/ski/efi_stub.c @@ -0,0 +1,268 @@ +/* + * Copyright (c) 2003 Marcel Moolenaar + * 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 ``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 <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <machine/bootinfo.h> +#include <efi.h> +#include <stand.h> +#include "libski.h" + +extern void acpi_root; +extern void sal_systab; + +extern void acpi_stub_init(void); +extern void sal_stub_init(void); + +EFI_CONFIGURATION_TABLE efi_cfgtab[] = { + { ACPI_20_TABLE_GUID, &acpi_root }, + { SAL_SYSTEM_TABLE_GUID, &sal_systab } +}; + + +static EFI_STATUS GetTime(EFI_TIME *, EFI_TIME_CAPABILITIES *); +static EFI_STATUS SetTime(EFI_TIME *); +static EFI_STATUS GetWakeupTime(BOOLEAN *, BOOLEAN *, EFI_TIME *); +static EFI_STATUS SetWakeupTime(BOOLEAN, EFI_TIME *); + +static EFI_STATUS SetVirtualAddressMap(UINTN, UINTN, UINT32, + EFI_MEMORY_DESCRIPTOR*); +static EFI_STATUS ConvertPointer(UINTN, VOID **); + +static EFI_STATUS GetVariable(CHAR16 *, EFI_GUID *, UINT32 *, UINTN *, VOID *); +static EFI_STATUS GetNextVariableName(UINTN *, CHAR16 *, EFI_GUID *); +static EFI_STATUS SetVariable(CHAR16 *, EFI_GUID *, UINT32, UINTN, VOID *); + +static EFI_STATUS GetNextHighMonotonicCount(UINT32 *); +static EFI_STATUS ResetSystem(EFI_RESET_TYPE, EFI_STATUS, UINTN, CHAR16 *); + +EFI_RUNTIME_SERVICES efi_rttab = { + /* Header. */ + { EFI_RUNTIME_SERVICES_SIGNATURE, + EFI_RUNTIME_SERVICES_REVISION, + 0, /* XXX HeaderSize */ + 0, /* XXX CRC32 */ + }, + + /* Time services */ + GetTime, + SetTime, + GetWakeupTime, + SetWakeupTime, + + /* Virtual memory services */ + SetVirtualAddressMap, + ConvertPointer, + + /* Variable services */ + GetVariable, + GetNextVariableName, + SetVariable, + + /* Misc */ + GetNextHighMonotonicCount, + ResetSystem +}; + +EFI_SYSTEM_TABLE efi_systab = { + /* Header. */ + { EFI_SYSTEM_TABLE_SIGNATURE, + EFI_SYSTEM_TABLE_REVISION, + 0, /* XXX HeaderSize */ + 0, /* XXX CRC32 */ + }, + + /* Firmware info. */ + L"FreeBSD", 0, + + /* Console stuff. */ + NULL, NULL, + NULL, NULL, + NULL, NULL, + + /* Services (runtime first). */ + &efi_rttab, + NULL, + + /* Configuration tables. */ + sizeof(efi_cfgtab)/sizeof(EFI_CONFIGURATION_TABLE), + efi_cfgtab +}; + +static EFI_STATUS +unsupported(const char *func) +{ + printf("EFI: %s not supported\n", func); + return (EFI_UNSUPPORTED); +} + +static EFI_STATUS +GetTime(EFI_TIME *time, EFI_TIME_CAPABILITIES *caps) +{ + UINT32 comps[8]; + + ssc((UINT64)comps, 0, 0, 0, SSC_GET_RTC); + time->Year = comps[0] + 1900; + time->Month = comps[1] + 1; + time->Day = comps[2]; + time->Hour = comps[3]; + time->Minute = comps[4]; + time->Second = comps[5]; + time->Pad1 = time->Pad2 = 0; + time->Nanosecond = 0; + time->TimeZone = 0; + time->Daylight = 0; + return (EFI_SUCCESS); +} + +static EFI_STATUS +SetTime(EFI_TIME *time) +{ + return (EFI_SUCCESS); +} + +static EFI_STATUS +GetWakeupTime(BOOLEAN *enabled, BOOLEAN *pending, EFI_TIME *time) +{ + return (unsupported(__func__)); +} + +static EFI_STATUS +SetWakeupTime(BOOLEAN enable, EFI_TIME *time) +{ + return (unsupported(__func__)); +} + +static void +Reloc(void *addr, UINT64 delta) +{ + UINT64 **fpp = addr; + + *fpp[0] += delta; + *fpp[1] += delta; + *fpp += delta >> 3; +} + +static EFI_STATUS +SetVirtualAddressMap(UINTN mapsz, UINTN descsz, UINT32 version, + EFI_MEMORY_DESCRIPTOR *memmap) +{ + UINT64 delta; + + delta = memmap->VirtualStart - memmap->PhysicalStart; + Reloc(&efi_rttab.GetTime, delta); + Reloc(&efi_rttab.SetTime, delta); + return (EFI_SUCCESS); /* Hah... */ +} + +static EFI_STATUS +ConvertPointer(UINTN debug, VOID **addr) +{ + return (unsupported(__func__)); +} + +static EFI_STATUS +GetVariable(CHAR16 *name, EFI_GUID *vendor, UINT32 *attrs, UINTN *datasz, + VOID *data) +{ + return (unsupported(__func__)); +} + +static EFI_STATUS +GetNextVariableName(UINTN *namesz, CHAR16 *name, EFI_GUID *vendor) +{ + return (unsupported(__func__)); +} + +static EFI_STATUS +SetVariable(CHAR16 *name, EFI_GUID *vendor, UINT32 attrs, UINTN datasz, + VOID *data) +{ + return (unsupported(__func__)); +} + +static EFI_STATUS +GetNextHighMonotonicCount(UINT32 *high) +{ + static UINT32 counter = 0; + + *high = counter++; + return (EFI_SUCCESS); +} + +static EFI_STATUS +ResetSystem(EFI_RESET_TYPE type, EFI_STATUS status, UINTN datasz, + CHAR16 *data) +{ + return (unsupported(__func__)); +} + +int +ski_init_stubs(struct bootinfo *bi) +{ + EFI_MEMORY_DESCRIPTOR *memp; + + /* Describe the SKI memory map. */ + bi->bi_memmap = (u_int64_t)(bi + 1); + bi->bi_memmap_size = 4 * sizeof(EFI_MEMORY_DESCRIPTOR); + bi->bi_memdesc_size = sizeof(EFI_MEMORY_DESCRIPTOR); + bi->bi_memdesc_version = 1; + + memp = (EFI_MEMORY_DESCRIPTOR *)bi->bi_memmap; + + memp[0].Type = EfiPalCode; + memp[0].PhysicalStart = 0x100000; + memp[0].VirtualStart = 0; + memp[0].NumberOfPages = (4L*1024*1024)>>12; + memp[0].Attribute = EFI_MEMORY_WB | EFI_MEMORY_RUNTIME; + + memp[1].Type = EfiConventionalMemory; + memp[1].PhysicalStart = 5L*1024*1024; + memp[1].VirtualStart = 0; + memp[1].NumberOfPages = (128L*1024*1024)>>12; + memp[1].Attribute = EFI_MEMORY_WB; + + memp[2].Type = EfiConventionalMemory; + memp[2].PhysicalStart = 4L*1024*1024*1024; + memp[2].VirtualStart = 0; + memp[2].NumberOfPages = (64L*1024*1024)>>12; + memp[2].Attribute = EFI_MEMORY_WB; + + memp[3].Type = EfiMemoryMappedIOPortSpace; + memp[3].PhysicalStart = 0xffffc000000; + memp[3].VirtualStart = 0; + memp[3].NumberOfPages = (64L*1024*1024)>>12; + memp[3].Attribute = EFI_MEMORY_UC; + + bi->bi_systab = (u_int64_t)&efi_systab; + + sal_stub_init(); + acpi_stub_init(); + + return (0); +} diff --git a/sys/boot/ia64/ski/elf_freebsd.c b/sys/boot/ia64/ski/elf_freebsd.c new file mode 100644 index 0000000..85a8ea6 --- /dev/null +++ b/sys/boot/ia64/ski/elf_freebsd.c @@ -0,0 +1,206 @@ +/* $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 <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <stand.h> +#include <string.h> + +#include <sys/param.h> +#include <sys/linker.h> +#include <machine/elf.h> +#include <machine/bootinfo.h> +#include <machine/ia64_cpu.h> +#include <machine/vmparam.h> + +#include "bootstrap.h" +#include "libski.h" + +#define _KERNEL + +static int elf64_exec(struct preloaded_file *amp); + +struct file_format ia64_elf = { elf64_loadfile, elf64_exec }; + +#define PTE_MA_WB 0 +#define PTE_MA_UC 4 +#define PTE_MA_UCE 5 +#define PTE_MA_WC 6 +#define PTE_MA_NATPAGE 7 + +#define PTE_PL_KERN 0 +#define PTE_PL_USER 3 + +#define PTE_AR_R 0 +#define PTE_AR_RX 1 +#define PTE_AR_RW 2 +#define PTE_AR_RWX 3 +#define PTE_AR_R_RW 4 +#define PTE_AR_RX_RWX 5 +#define PTE_AR_RWX_RW 6 +#define PTE_AR_X_RX 7 + +/* + * A short-format VHPT entry. Also matches the TLB insertion format. + */ +struct ia64_pte { + u_int64_t pte_p :1; /* bits 0..0 */ + u_int64_t pte_rv1 :1; /* bits 1..1 */ + u_int64_t pte_ma :3; /* bits 2..4 */ + u_int64_t pte_a :1; /* bits 5..5 */ + u_int64_t pte_d :1; /* bits 6..6 */ + u_int64_t pte_pl :2; /* bits 7..8 */ + u_int64_t pte_ar :3; /* bits 9..11 */ + u_int64_t pte_ppn :38; /* bits 12..49 */ + u_int64_t pte_rv2 :2; /* bits 50..51 */ + u_int64_t pte_ed :1; /* bits 52..52 */ + u_int64_t pte_ig :11; /* bits 53..63 */ +}; + +static struct bootinfo bootinfo; + +void +enter_kernel(const char* filename, u_int64_t start, struct bootinfo *bi) +{ + printf("Entering %s at 0x%lx...\n", filename, start); + + while (*filename == '/') + filename++; + ssc(0, (u_int64_t) filename, 0, 0, SSC_LOAD_SYMBOLS); + + __asm __volatile("mov cr.ipsr=%0" + :: "r"(IA64_PSR_IC + | IA64_PSR_DT + | IA64_PSR_RT + | IA64_PSR_IT + | IA64_PSR_BN)); + __asm __volatile("mov cr.iip=%0" :: "r"(start)); + __asm __volatile("mov cr.ifs=r0;;"); + __asm __volatile("mov r8=%0" :: "r" (bi)); + __asm __volatile("rfi;;"); +} + +static int +elf64_exec(struct preloaded_file *fp) +{ + struct file_metadata *md; + Elf_Ehdr *hdr; + struct ia64_pte pte; + struct bootinfo *bi; + + if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) + return(EFTYPE); /* XXX actually EFUCKUP */ + hdr = (Elf_Ehdr *)&(md->md_data); + + /* + * Ugly hack, similar to linux. Dump the bootinfo into a + * special page reserved in the link map. + */ + bi = &bootinfo; + bzero(bi, sizeof(struct bootinfo)); + bi_load(bi, fp); + + /* + * Region 6 is direct mapped UC and region 7 is direct mapped + * WC. The details of this is controlled by the Alt {I,D}TLB + * handlers. Here we just make sure that they have the largest + * possible page size to minimise TLB usage. + */ + ia64_set_rr(IA64_RR_BASE(6), (6 << 8) | (28 << 2)); + ia64_set_rr(IA64_RR_BASE(7), (7 << 8) | (28 << 2)); + + bzero(&pte, sizeof(pte)); + pte.pte_p = 1; + pte.pte_ma = PTE_MA_WB; + pte.pte_a = 1; + pte.pte_d = 1; + pte.pte_pl = PTE_PL_KERN; + pte.pte_ar = PTE_AR_RWX; + pte.pte_ppn = 0; + + __asm __volatile("mov cr.ifa=%0" :: "r"(IA64_RR_BASE(7))); + __asm __volatile("mov cr.itir=%0" :: "r"(28 << 2)); + __asm __volatile("srlz.i;;"); + __asm __volatile("itr.i itr[%0]=%1;;" + :: "r"(0), "r"(*(u_int64_t*)&pte)); + __asm __volatile("srlz.i;;"); + __asm __volatile("itr.d dtr[%0]=%1;;" + :: "r"(0), "r"(*(u_int64_t*)&pte)); + __asm __volatile("srlz.i;;"); + + enter_kernel(fp->f_name, hdr->e_entry, bi); +} diff --git a/sys/boot/ia64/ski/exit.c b/sys/boot/ia64/ski/exit.c new file mode 100644 index 0000000..aeac67c --- /dev/null +++ b/sys/boot/ia64/ski/exit.c @@ -0,0 +1,42 @@ +/*- + * Copyright (c) 2000 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/time.h> +#include <stddef.h> +#include <stand.h> +#include <stdarg.h> + +#include "libski.h" + +void +exit(int code) +{ + ssc(code, 0, 0, 0, SSC_EXIT); +} diff --git a/sys/boot/ia64/ski/ldscript.ia64 b/sys/boot/ia64/ski/ldscript.ia64 new file mode 100644 index 0000000..e4e1dad --- /dev/null +++ b/sys/boot/ia64/ski/ldscript.ia64 @@ -0,0 +1,61 @@ +/* $FreeBSD$ */ +OUTPUT_FORMAT("elf64-ia64-little", "elf64-ia64-little", "elf64-ia64-little") +OUTPUT_ARCH(ia64) +ENTRY(_start) +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = 0x100000; + .text : { + *(.text .stub .text.* .gnu.linkonce.t.*) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + *(.plt) + } =0x00300000010070000002000001000400 + .data : { + *(.rodata .rodata.* .gnu.linkonce.r.*) + *(.rodata1) + *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) + *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) + *(.opd) + *(.IA_64.unwind_info* .gnu.linkonce.ia64unwi.*) + *(.IA_64.unwind* .gnu.linkonce.ia64unw.*) + __start_set_Xcommand_set = .; + *(set_Xcommand_set) + __stop_set_Xcommand_set = .; + *(.data .data.* .gnu.linkonce.d.*) + *(.data1) + *(.plabel) + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + } + __gp = .; + .sdata : { + *(.got.plt .got) + *(.IA_64.pltoff) + *(.sdata .sdata.* .gnu.linkonce.s.*) + *(dynsbss) + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + } + .dynamic : { *(.dynamic) } + .rela : { + *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) + *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) + *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) + *(.rela.got) + *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) + *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) + *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) + *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) + *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) + *(.rela.plt) + *(.rela.IA_64.pltoff) + *(.relaset_*) + *(.rela.dyn .rela.dyn.*) + } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } +} diff --git a/sys/boot/ia64/ski/libski.h b/sys/boot/ia64/ski/libski.h new file mode 100644 index 0000000..043177c --- /dev/null +++ b/sys/boot/ia64/ski/libski.h @@ -0,0 +1,96 @@ +/*- + * 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$ + */ + +/* + * SKI fully-qualified device descriptor + */ +struct ski_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; + } skidisk; + struct { + int unit; /* XXX net layer lives over these? */ + } netif; + } d_kind; +}; + +extern int ski_getdev(void **vdev, const char *devspec, const char **path); +extern char *ski_fmtdev(void *vdev); +extern int ski_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 skifs_dev; +extern struct devsw ski_disk; +extern struct netif_driver ski_net; + +/* Wrapper over SKI filesystems. */ +extern struct fs_ops ski_fsops; + +/* this is in startup code */ +extern void delay(int); +extern void reboot(void); + +extern ssize_t ski_copyin(const void *src, vm_offset_t dest, size_t len); +extern ssize_t ski_copyout(const vm_offset_t src, void *dest, size_t len); +extern ssize_t ski_readin(int fd, vm_offset_t dest, size_t len); + +extern int ski_boot(void); +extern int ski_autoload(void); + +struct bootinfo; +struct preloaded_file; +extern int bi_load(struct bootinfo *, struct preloaded_file *); + +#define SSC_CONSOLE_INIT 20 +#define SSC_GETCHAR 21 +#define SSC_PUTCHAR 31 +#define SSC_OPEN 50 +#define SSC_CLOSE 51 +#define SSC_READ 52 +#define SSC_WRITE 53 +#define SSC_GET_COMPLETION 54 +#define SSC_WAIT_COMPLETION 55 +#define SSC_GET_RTC 65 +#define SSC_EXIT 66 +#define SSC_LOAD_SYMBOLS 69 +#define SSC_SAL_SET_VECTORS 120 + +u_int64_t ssc(u_int64_t in0, u_int64_t in1, u_int64_t in2, u_int64_t in3, + int which); diff --git a/sys/boot/ia64/ski/main.c b/sys/boot/ia64/ski/main.c new file mode 100644 index 0000000..f336d17 --- /dev/null +++ b/sys/boot/ia64/ski/main.c @@ -0,0 +1,128 @@ +/*- + * 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <stand.h> +#include <string.h> +#include <setjmp.h> +#include <machine/fpu.h> + +#include "bootstrap.h" +#include "libski.h" + +extern char bootprog_name[]; +extern char bootprog_rev[]; +extern char bootprog_date[]; +extern char bootprog_maker[]; + +struct ski_devdesc currdev; /* our current device */ +struct arch_switch archsw; /* MI/MD interface boundary */ + +void +ski_main(void) +{ + static char malloc[512*1024]; + int i; + + /* + * 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 *)malloc, (void *)(malloc + 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 + + /* XXX presumes that biosdisk is first in devsw */ + currdev.d_dev = devsw[0]; + currdev.d_type = currdev.d_dev->dv_type; + currdev.d_kind.skidisk.unit = 0; + /* XXX should be able to detect this, default to autoprobe */ + currdev.d_kind.skidisk.slice = -1; + /* default to 'a' */ + currdev.d_kind.skidisk.partition = 0; + +#if 0 + /* Create arc-specific variables */ + bootfile = GetEnvironmentVariable(ARCENV_BOOTFILE); + if (bootfile) + setenv("bootfile", bootfile, 1); +#endif + + env_setenv("currdev", EV_VOLATILE, ski_fmtdev(&currdev), + ski_setcurrdev, env_nounset); + env_setenv("loaddev", EV_VOLATILE, ski_fmtdev(&currdev), env_noset, + env_nounset); + + setenv("LINES", "24", 1); /* optional */ + + archsw.arch_autoload = ski_autoload; + archsw.arch_getdev = ski_getdev; + archsw.arch_copyin = ski_copyin; + archsw.arch_copyout = ski_copyout; + archsw.arch_readin = ski_readin; + + interact(); /* doesn't return */ + + exit(0); +} + +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/ski/pal_stub.S b/sys/boot/ia64/ski/pal_stub.S new file mode 100644 index 0000000..e247661 --- /dev/null +++ b/sys/boot/ia64/ski/pal_stub.S @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2003 Marcel Moolenaar + * 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$ + */ + +#include <machine/asm.h> + + .text +ENTRY(PalProc, 0) + cmp.eq p6,p0=6,r28 // PAL_PTCE_INFO +(p6) br.cond.dptk pal_ptce_info + ;; + cmp.eq p6,p0=8,r28 // PAL_VM_SUMMARY +(p6) br.cond.dptk pal_vm_summary + ;; + cmp.eq p6,p0=14,r28 // PAL_FREQ_RATIOS +(p6) br.cond.dptk pal_freq_ratios + ;; + cmp.eq p6,p0=29,r28 // PAL_HALT_LIGHT +(p6) br.cond.dptk pal_halt_light + ;; + mov r15=66 // EXIT + break.i 0x80000 // SSC + ;; +pal_ptce_info: + mov r8=0 + mov r9=0 // base + movl r10=0x0000000100000001 // loop counts (outer|inner) + mov r11=0x0000000000000000 // loop strides (outer|inner) + br.sptk b0 +pal_vm_summary: + mov r8=0 + movl r9=(8<<40)|(8<<32) // VM info 1 + mov r10=(18<<8)|(41<<0) // VM info 2 + mov r11=0 + br.sptk b0 +pal_freq_ratios: + mov r8=0 + movl r9=0x0000000B00000002 // processor ratio 11/2 + movl r10=0x0000000100000001 // bus ratio 1/1 + movl r11=0x0000000B00000002 // ITC ratio 11/2 + br.sptk b0 +pal_halt_light: + mov r8=0 + mov r9=0 + mov r10=0 + mov r11=0 + br.sptk b0 +END(PalProc) diff --git a/sys/boot/ia64/ski/sal_stub.c b/sys/boot/ia64/ski/sal_stub.c new file mode 100644 index 0000000..b5661a3 --- /dev/null +++ b/sys/boot/ia64/ski/sal_stub.c @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2003 Marcel Moolenaar + * 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 ``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 <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <machine/md_var.h> +#include <machine/sal.h> +#include <stand.h> +#include "libski.h" + +extern void PalProc(void); +static sal_entry_t SalProc; + +struct { + struct sal_system_table header; + struct sal_entrypoint_descriptor entry; + struct sal_ap_wakeup_descriptor wakeup; +} sal_systab = { + /* Header. */ + { + SAL_SIGNATURE, + sizeof(sal_systab), + { 00, 03 }, /* Revision 3.0. */ + 2, /* Number of decsriptors. */ + 0, /* XXX checksum. */ + { 0 }, + { 00, 00 }, /* XXX SAL_A version. */ + { 00, 00 }, /* XXX SAL_B version. */ + "FreeBSD", + "Ski loader", + { 0 } + }, + /* Entrypoint. */ + { + 0, /* Type=entrypoint descr. */ + { 0 }, + 0, /* XXX PalProc. */ + 0, /* XXX SalProc. */ + 0, /* XXX SalProc GP. */ + { 0 } + }, + /* AP wakeup. */ + { + 5, /* Type=AP wakeup descr. */ + 0, /* External interrupt. */ + { 0 }, + 255 /* Wakeup vector. */ + } +}; + +static inline void +puts(const char *s) +{ + s = (const char *)((7UL << 61) | (u_long)s); + while (*s) + ski_cons_putchar(*s++); +} + +static struct ia64_sal_result +SalProc(u_int64_t a1, u_int64_t a2, u_int64_t a3, u_int64_t a4, u_int64_t a5, + u_int64_t a6, u_int64_t a7, u_int64_t a8) +{ + struct ia64_sal_result res; + + res.sal_status = -3; + res.sal_result[0] = 0; + res.sal_result[1] = 0; + res.sal_result[2] = 0; + + if (a1 == SAL_FREQ_BASE) { + res.sal_status = 0; + res.sal_result[0] = 133338184; + } else if (a1 == SAL_SET_VECTORS) { + /* XXX unofficial SSC function. */ + ssc(a2, a3, a4, a5, SSC_SAL_SET_VECTORS); + } else if (a1 != SAL_GET_STATE_INFO_SIZE) { + puts("SAL: unimplemented function called\n"); + } + + return (res); +} + +void +sal_stub_init(void) +{ + struct ia64_fdesc *fd; + + fd = (void*)PalProc; + sal_systab.entry.sale_pal_proc = fd->func; + fd = (void*)SalProc; + sal_systab.entry.sale_sal_proc = fd->func; + sal_systab.entry.sale_sal_gp = fd->gp; +} diff --git a/sys/boot/ia64/ski/skiconsole.c b/sys/boot/ia64/ski/skiconsole.c new file mode 100644 index 0000000..e5cea3d --- /dev/null +++ b/sys/boot/ia64/ski/skiconsole.c @@ -0,0 +1,96 @@ +/*- + * Copyright (c) 2000 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <stand.h> + +#include "bootstrap.h" +#include "libski.h" + +static void +ski_cons_probe(struct console *cp) +{ + cp->c_flags |= C_PRESENTIN | C_PRESENTOUT; +} + +static int +ski_cons_init(int arg) +{ + ssc(0, 0, 0, 0, SSC_CONSOLE_INIT); + return 0; +} + +void +ski_cons_putchar(int c) +{ + ssc(c, 0, 0, 0, SSC_PUTCHAR); +} + +static int pollchar = -1; + +int +ski_cons_getchar() +{ + int c; + + if (pollchar > 0) { + c = pollchar; + pollchar = -1; + return c; + } + + do { + c = ssc(0, 0, 0, 0, SSC_GETCHAR); + } while (c == 0); + + return c; +} + +int +ski_cons_poll() +{ + int c; + if (pollchar > 0) + return 1; + c = ssc(0, 0, 0, 0, SSC_GETCHAR); + if (!c) + return 0; + pollchar = c; + return 1; +} + +struct console ski_console = { + "ski", + "ia64 SKI console", + 0, + ski_cons_probe, + ski_cons_init, + ski_cons_putchar, + ski_cons_getchar, + ski_cons_poll +}; diff --git a/sys/boot/ia64/ski/skifs.c b/sys/boot/ia64/ski/skifs.c new file mode 100644 index 0000000..5a272c7 --- /dev/null +++ b/sys/boot/ia64/ski/skifs.c @@ -0,0 +1,193 @@ +/*- + * 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/time.h> +#include <stddef.h> +#include <stand.h> +#include <stdarg.h> + +#include "libski.h" + +struct disk_req { + unsigned long addr; + unsigned len; +}; + +struct disk_stat { + int fd; + unsigned count; +}; + +static int +skifs_open(const char *path, struct open_file *f) +{ + int fd; + + /* + * Skip leading '/' so that our pretend filesystem starts in + * the current working directory. + */ + while (*path == '/') + path++; + + fd = ssc((u_int64_t) path, 1, 0, 0, SSC_OPEN); + if (fd > 0) { + f->f_fsdata = (void*)(u_int64_t) fd; + return 0; + } + return ENOENT; +} + +static int +skifs_close(struct open_file *f) +{ + ssc((u_int64_t) f->f_fsdata, 0, 0, 0, SSC_CLOSE); + return 0; +} + +static int +skifs_read(struct open_file *f, void *buf, size_t size, size_t *resid) +{ + struct disk_req req; + struct disk_stat stat; + + req.len = size; + req.addr = (u_int64_t) buf; + ssc((u_int64_t) f->f_fsdata, 1, (u_int64_t) &req, f->f_offset, SSC_READ); + stat.fd = (u_int64_t) f->f_fsdata; + ssc((u_int64_t)&stat, 0, 0, 0, SSC_WAIT_COMPLETION); + + *resid = size - stat.count; + f->f_offset += stat.count; + return 0; +} + +static off_t +skifs_seek(struct open_file *f, off_t offset, int where) +{ + u_int64_t base; + + switch (where) { + case SEEK_SET: + base = 0; + break; + + case SEEK_CUR: + base = f->f_offset; + break; + + case SEEK_END: + printf("can't find end of file in SKI\n"); + base = f->f_offset; + break; + } + + f->f_offset = base + offset; + return base; +} + +static int +skifs_stat(struct open_file *f, struct stat *sb) +{ + bzero(sb, sizeof(*sb)); + sb->st_mode = S_IFREG | S_IRUSR; + return 0; +} + +static int +skifs_readdir(struct open_file *f, struct dirent *d) +{ + return ENOENT; +} + +struct fs_ops ski_fsops = { + "fs", + skifs_open, + skifs_close, + skifs_read, + null_write, + skifs_seek, + skifs_stat, + skifs_readdir +}; + +static int +skifs_dev_init(void) +{ + return 0; +} + +/* + * Print information about disks + */ +static void +skifs_dev_print(int verbose) +{ +} + +/* + * 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 +skifs_dev_open(struct open_file *f, ...) +{ + return 0; +} + +static int +skifs_dev_close(struct open_file *f) +{ + + return 0; +} + +static int +skifs_dev_strategy(void *devdata, int rw, daddr_t dblk, size_t size, char *buf, size_t *rsize) +{ + return 0; +} + +struct devsw skifs_dev = { + "fs", + DEVT_DISK, + skifs_dev_init, + skifs_dev_strategy, + skifs_dev_open, + skifs_dev_close, + noioctl, + skifs_dev_print +}; diff --git a/sys/boot/ia64/ski/skiload.cmd b/sys/boot/ia64/ski/skiload.cmd new file mode 100644 index 0000000..48b77e1 --- /dev/null +++ b/sys/boot/ia64/ski/skiload.cmd @@ -0,0 +1,16 @@ +# $FreeBSD$ +iar +fr +pa +b enter_kernel +c +b printf +c +b rp +c +b ssc +c +b rp +c +bD +s 11 diff --git a/sys/boot/ia64/ski/ssc.c b/sys/boot/ia64/ski/ssc.c new file mode 100644 index 0000000..e1f871c --- /dev/null +++ b/sys/boot/ia64/ski/ssc.c @@ -0,0 +1,53 @@ +/*- + * 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <stand.h> +#include "libski.h" + +/* + * Ugh... Work around a bug in the Linux version of ski for SSC_GET_RTC. The + * PSR.dt register is not preserved properly and causes further memory + * references to be done without translation. All we need to do is preserve + * PSR.dt across the SSC call. We do this by saving and restoring psr.l + * completely. + */ +u_int64_t +ssc(u_int64_t in0, u_int64_t in1, u_int64_t in2, u_int64_t in3, int which) +{ + register u_int64_t psr; + register u_int64_t ret0 __asm("r8"); + + __asm __volatile("mov %0=psr;;" : "=r"(psr)); + __asm __volatile("mov r15=%1\n\t" + "break 0x80000;;" + : "=r"(ret0) + : "r"(which), "r"(in0), "r"(in1), "r"(in2), "r"(in3)); + __asm __volatile("mov psr.l=%0;; srlz.d" :: "r"(psr)); + return ret0; +} diff --git a/sys/boot/ia64/ski/start.S b/sys/boot/ia64/ski/start.S new file mode 100644 index 0000000..bb0266f --- /dev/null +++ b/sys/boot/ia64/ski/start.S @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2003 Marcel Moolenaar + * 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 ``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. + * + * $FreeBSD$ + */ + +#include <machine/fpu.h> + +#define STACKSIZE 16384 +#define FPSR_DEFAULT 0x0009804c0270033f + + .text + .global _start + .proc _start +_start: +{ .mlx + mov ar.rsc=0 + movl gp=__gp + ;; +} +{ .mlx + add r2=@gprel(stack),gp + movl r14=FPSR_DEFAULT + ;; +} +{ .mib + mov ar.bspstore=r2 + add r12=STACKSIZE-16,r2 + bsw.1 + ;; +} +{ .mmb + mov ar.rsc=3 + mov ar.fpsr=r14 + br.sptk ski_main + ;; +} + .endp _start + + .data + .align 16 +stack: .skip STACKSIZE diff --git a/sys/boot/ia64/ski/time.c b/sys/boot/ia64/ski/time.c new file mode 100644 index 0000000..c66bdee --- /dev/null +++ b/sys/boot/ia64/ski/time.c @@ -0,0 +1,174 @@ +/* + * Copyright (c) 1999, 2000 + * Intel Corporation. + * 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 Intel Corporation and + * its contributors. + * + * 4. Neither the name of Intel Corporation or its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION 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 INTEL CORPORATION 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/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <time.h> +#include <sys/time.h> +#include <stand.h> + +#include "libski.h" + +/* +// Accurate only for the past couple of centuries; +// that will probably do. +// +// (#defines From FreeBSD 3.2 lib/libc/stdtime/tzfile.h) +*/ + +#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0)) +#define SECSPERHOUR ( 60*60 ) +#define SECSPERDAY (24 * SECSPERHOUR) + +struct ssc_time { + int Year; + int Month; + int Day; + int Hour; + int Minute; + int Second; + int Msec; + int Wday; +}; + +time_t +EfiTimeToUnixTime(struct ssc_time *ETime) +{ + /* + // These arrays give the cumulative number of days up to the first of the + // month number used as the index (1 -> 12) for regular and leap years. + // The value at index 13 is for the whole year. + */ + static time_t CumulativeDays[2][14] = { + {0, + 0, + 31, + 31 + 28, + 31 + 28 + 31, + 31 + 28 + 31 + 30, + 31 + 28 + 31 + 30 + 31, + 31 + 28 + 31 + 30 + 31 + 30, + 31 + 28 + 31 + 30 + 31 + 30 + 31, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 }, + {0, + 0, + 31, + 31 + 29, + 31 + 29 + 31, + 31 + 29 + 31 + 30, + 31 + 29 + 31 + 30 + 31, + 31 + 29 + 31 + 30 + 31 + 30, + 31 + 29 + 31 + 30 + 31 + 30 + 31, + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31, + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30, + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31, + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30, + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 }}; + + time_t UTime; + int Year; + + ETime->Year += 1900; + + /* + // Do a santity check + */ + if ( ETime->Year < 1998 || ETime->Year > 2099 || + ETime->Month == 0 || ETime->Month > 12 || + ETime->Day == 0 || ETime->Month > 31 || + ETime->Hour > 23 || + ETime->Minute > 59 || + ETime->Second > 59 ) { + return (0); + } + + /* + // Years + */ + UTime = 0; + for (Year = 1970; Year != ETime->Year; ++Year) { + UTime += (CumulativeDays[isleap(Year)][13] * SECSPERDAY); + } + + /* + // UTime should now be set to 00:00:00 on Jan 1 of the file's year. + // + // Months + */ + UTime += (CumulativeDays[isleap(ETime->Year)][ETime->Month] * SECSPERDAY); + + /* + // UTime should now be set to 00:00:00 on the first of the file's month and year + // + // Days -- Don't count the file's day + */ + UTime += (((ETime->Day > 0) ? ETime->Day-1:0) * SECSPERDAY); + + /* + // Hours + */ + UTime += (ETime->Hour * SECSPERHOUR); + + /* + // Minutes + */ + UTime += (ETime->Minute * 60); + + /* + // Seconds + */ + UTime += ETime->Second; + + return UTime; +} + +time_t +time(time_t *tloc) +{ + struct ssc_time time; + + ssc((u_int64_t) &time, 0, 0, 0, SSC_GET_RTC); + + return *tloc = EfiTimeToUnixTime(&time); +} diff --git a/sys/boot/ia64/ski/version b/sys/boot/ia64/ski/version new file mode 100644 index 0000000..6f4fc3c --- /dev/null +++ b/sys/boot/ia64/ski/version @@ -0,0 +1,8 @@ +$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.2: Pass the address of the bootinfo block to the kernel in register + r8. Keep it at the hardwired address for now. +0.1: Initial SKI version. diff --git a/sys/boot/ia64/skiload/Makefile b/sys/boot/ia64/skiload/Makefile new file mode 100644 index 0000000..5d89340 --- /dev/null +++ b/sys/boot/ia64/skiload/Makefile @@ -0,0 +1,85 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../common + +PROG= skiload +NOMAN= +NEWVERSWHAT= "ia64 SKI boot" ${MACHINE_ARCH} +BINDIR?= /boot +STRIP= # We must not strip skiload at install time. + +SRCS+= conf.c main.c start.S + +CFLAGS+= -ffreestanding + +.if !defined(NOFORTH) +# Enable BootForth +BOOT_FORTH= yes +CFLAGS+= -DBOOT_FORTH +CFLAGS+= -I${.CURDIR}/../../ficl -I${.CURDIR}/../../ficl/${MACHINE_ARCH} +.if exists(${.OBJDIR}/../../ficl/libficl.a) +LIBFICL= ${.OBJDIR}/../../ficl/libficl.a +.else +LIBFICL= ${.CURDIR}/../../ficl/libficl.a +.endif +.endif + +# where to get libstand from +.if exists(${.OBJDIR}/../../../../lib/libstand/libstand.a) +LIBSTAND= ${.OBJDIR}/../../../../lib/libstand/libstand.a +.else +LIBSTAND= ${.CURDIR}/../../../../lib/libstand/libstand.a +.endif + +.if exists(${.OBJDIR}/../libski/libski.a) +LIBSKI= ${.OBJDIR}/../libski/libski.a +.else +LIBSKI= ${.CURDIR}/../libski/libski.a +.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}/../libski +CFLAGS+= -DLOADER + +LDFLAGS= -nostdlib -T ${.CURDIR}/ldscript.ia64 + +CLEANFILES+= vers.c vers.o ${PROG}.list +CLEANFILES+= loader.help +CLEANFILES+= machine + +all: ${PROG} + +vers.o: ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version + sh ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version ${NEWVERSWHAT} + ${CC} -c vers.c + +${PROG}.help: help.common help.efi + cat ${.ALLSRC} | awk -f ${.CURDIR}/../../common/merge_help.awk \ + > ${.TARGET} + +beforeinstall: +.if exists(${.OBJDIR}/${PROG}.help) + ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \ + ${.OBJDIR}/${PROG}.help ${DESTDIR}/boot +.endif + +machine: + ln -sf ${.CURDIR}/../../../${MACHINE_ARCH}/include machine + +${PROG}: ${OBJS} ${LIBFICL} ${LIBSKI} ${LIBSTAND} vers.o + ${LD} ${LDFLAGS} -o ${PROG} -M \ + ${OBJS} vers.o \ + ${LIBFICL} ${LIBSTAND} ${LIBSKI} ${LIBSTAND} \ + > ${.OBJDIR}/${PROG}.list + +.include <bsd.prog.mk> + +beforedepend ${OBJS}: machine diff --git a/sys/boot/ia64/skiload/conf.c b/sys/boot/ia64/skiload/conf.c new file mode 100644 index 0000000..5066a77 --- /dev/null +++ b/sys/boot/ia64/skiload/conf.c @@ -0,0 +1,86 @@ +/* + * 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. + * + * $NetBSD: conf.c,v 1.2 1997/03/22 09:03:29 thorpej Exp $ + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <stand.h> + +#include "libski.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[] = { + &skifs_dev, + NULL +}; + +struct fs_ops *file_system[] = { + &ski_fsops, + &ufs_fsops, + &gzipfs_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 ski_console; + +struct console *consoles[] = { + &ski_console, + NULL +}; diff --git a/sys/boot/ia64/skiload/ldscript.ia64 b/sys/boot/ia64/skiload/ldscript.ia64 new file mode 100644 index 0000000..e4e1dad --- /dev/null +++ b/sys/boot/ia64/skiload/ldscript.ia64 @@ -0,0 +1,61 @@ +/* $FreeBSD$ */ +OUTPUT_FORMAT("elf64-ia64-little", "elf64-ia64-little", "elf64-ia64-little") +OUTPUT_ARCH(ia64) +ENTRY(_start) +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = 0x100000; + .text : { + *(.text .stub .text.* .gnu.linkonce.t.*) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + *(.plt) + } =0x00300000010070000002000001000400 + .data : { + *(.rodata .rodata.* .gnu.linkonce.r.*) + *(.rodata1) + *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) + *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) + *(.opd) + *(.IA_64.unwind_info* .gnu.linkonce.ia64unwi.*) + *(.IA_64.unwind* .gnu.linkonce.ia64unw.*) + __start_set_Xcommand_set = .; + *(set_Xcommand_set) + __stop_set_Xcommand_set = .; + *(.data .data.* .gnu.linkonce.d.*) + *(.data1) + *(.plabel) + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + } + __gp = .; + .sdata : { + *(.got.plt .got) + *(.IA_64.pltoff) + *(.sdata .sdata.* .gnu.linkonce.s.*) + *(dynsbss) + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + } + .dynamic : { *(.dynamic) } + .rela : { + *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) + *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) + *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) + *(.rela.got) + *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) + *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) + *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) + *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) + *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) + *(.rela.plt) + *(.rela.IA_64.pltoff) + *(.relaset_*) + *(.rela.dyn .rela.dyn.*) + } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } +} diff --git a/sys/boot/ia64/skiload/main.c b/sys/boot/ia64/skiload/main.c new file mode 100644 index 0000000..f336d17 --- /dev/null +++ b/sys/boot/ia64/skiload/main.c @@ -0,0 +1,128 @@ +/*- + * 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <stand.h> +#include <string.h> +#include <setjmp.h> +#include <machine/fpu.h> + +#include "bootstrap.h" +#include "libski.h" + +extern char bootprog_name[]; +extern char bootprog_rev[]; +extern char bootprog_date[]; +extern char bootprog_maker[]; + +struct ski_devdesc currdev; /* our current device */ +struct arch_switch archsw; /* MI/MD interface boundary */ + +void +ski_main(void) +{ + static char malloc[512*1024]; + int i; + + /* + * 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 *)malloc, (void *)(malloc + 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 + + /* XXX presumes that biosdisk is first in devsw */ + currdev.d_dev = devsw[0]; + currdev.d_type = currdev.d_dev->dv_type; + currdev.d_kind.skidisk.unit = 0; + /* XXX should be able to detect this, default to autoprobe */ + currdev.d_kind.skidisk.slice = -1; + /* default to 'a' */ + currdev.d_kind.skidisk.partition = 0; + +#if 0 + /* Create arc-specific variables */ + bootfile = GetEnvironmentVariable(ARCENV_BOOTFILE); + if (bootfile) + setenv("bootfile", bootfile, 1); +#endif + + env_setenv("currdev", EV_VOLATILE, ski_fmtdev(&currdev), + ski_setcurrdev, env_nounset); + env_setenv("loaddev", EV_VOLATILE, ski_fmtdev(&currdev), env_noset, + env_nounset); + + setenv("LINES", "24", 1); /* optional */ + + archsw.arch_autoload = ski_autoload; + archsw.arch_getdev = ski_getdev; + archsw.arch_copyin = ski_copyin; + archsw.arch_copyout = ski_copyout; + archsw.arch_readin = ski_readin; + + interact(); /* doesn't return */ + + exit(0); +} + +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/skiload/skiload.cmd b/sys/boot/ia64/skiload/skiload.cmd new file mode 100644 index 0000000..48b77e1 --- /dev/null +++ b/sys/boot/ia64/skiload/skiload.cmd @@ -0,0 +1,16 @@ +# $FreeBSD$ +iar +fr +pa +b enter_kernel +c +b printf +c +b rp +c +b ssc +c +b rp +c +bD +s 11 diff --git a/sys/boot/ia64/skiload/start.S b/sys/boot/ia64/skiload/start.S new file mode 100644 index 0000000..bb0266f --- /dev/null +++ b/sys/boot/ia64/skiload/start.S @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2003 Marcel Moolenaar + * 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 ``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. + * + * $FreeBSD$ + */ + +#include <machine/fpu.h> + +#define STACKSIZE 16384 +#define FPSR_DEFAULT 0x0009804c0270033f + + .text + .global _start + .proc _start +_start: +{ .mlx + mov ar.rsc=0 + movl gp=__gp + ;; +} +{ .mlx + add r2=@gprel(stack),gp + movl r14=FPSR_DEFAULT + ;; +} +{ .mib + mov ar.bspstore=r2 + add r12=STACKSIZE-16,r2 + bsw.1 + ;; +} +{ .mmb + mov ar.rsc=3 + mov ar.fpsr=r14 + br.sptk ski_main + ;; +} + .endp _start + + .data + .align 16 +stack: .skip STACKSIZE diff --git a/sys/boot/ia64/skiload/version b/sys/boot/ia64/skiload/version new file mode 100644 index 0000000..6f4fc3c --- /dev/null +++ b/sys/boot/ia64/skiload/version @@ -0,0 +1,8 @@ +$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.2: Pass the address of the bootinfo block to the kernel in register + r8. Keep it at the hardwired address for now. +0.1: Initial SKI version. |