summaryrefslogtreecommitdiffstats
path: root/sys/boot/ia64
diff options
context:
space:
mode:
Diffstat (limited to 'sys/boot/ia64')
-rw-r--r--sys/boot/ia64/Makefile5
-rw-r--r--sys/boot/ia64/Makefile.inc4
-rw-r--r--sys/boot/ia64/common/bootinfo.c348
-rw-r--r--sys/boot/ia64/common/copy.c68
-rw-r--r--sys/boot/ia64/common/devicename.c240
-rw-r--r--sys/boot/ia64/common/exec.c223
-rw-r--r--sys/boot/ia64/efi/Makefile123
-rw-r--r--sys/boot/ia64/efi/conf.c95
-rw-r--r--sys/boot/ia64/efi/ldscript.ia6473
-rw-r--r--sys/boot/ia64/efi/main.c562
-rw-r--r--sys/boot/ia64/efi/start.S305
-rw-r--r--sys/boot/ia64/efi/version16
-rw-r--r--sys/boot/ia64/libski/Makefile36
-rw-r--r--sys/boot/ia64/libski/acpi_stub.c182
-rw-r--r--sys/boot/ia64/libski/bootinfo.c316
-rw-r--r--sys/boot/ia64/libski/copy.c58
-rw-r--r--sys/boot/ia64/libski/delay.c34
-rw-r--r--sys/boot/ia64/libski/devicename.c238
-rw-r--r--sys/boot/ia64/libski/efi_stub.c268
-rw-r--r--sys/boot/ia64/libski/elf_freebsd.c206
-rw-r--r--sys/boot/ia64/libski/exit.c42
-rw-r--r--sys/boot/ia64/libski/libski.h96
-rw-r--r--sys/boot/ia64/libski/module.c40
-rw-r--r--sys/boot/ia64/libski/pal_stub.S74
-rw-r--r--sys/boot/ia64/libski/sal_stub.c118
-rw-r--r--sys/boot/ia64/libski/skiconsole.c96
-rw-r--r--sys/boot/ia64/libski/skifs.c193
-rw-r--r--sys/boot/ia64/libski/ssc.c53
-rw-r--r--sys/boot/ia64/libski/time.c174
-rw-r--r--sys/boot/ia64/ski/Makefile85
-rw-r--r--sys/boot/ia64/ski/acpi_stub.c182
-rw-r--r--sys/boot/ia64/ski/bootinfo.c316
-rw-r--r--sys/boot/ia64/ski/conf.c86
-rw-r--r--sys/boot/ia64/ski/copy.c58
-rw-r--r--sys/boot/ia64/ski/delay.c34
-rw-r--r--sys/boot/ia64/ski/devicename.c238
-rw-r--r--sys/boot/ia64/ski/efi_stub.c268
-rw-r--r--sys/boot/ia64/ski/elf_freebsd.c206
-rw-r--r--sys/boot/ia64/ski/exit.c42
-rw-r--r--sys/boot/ia64/ski/ldscript.ia6461
-rw-r--r--sys/boot/ia64/ski/libski.h96
-rw-r--r--sys/boot/ia64/ski/main.c128
-rw-r--r--sys/boot/ia64/ski/pal_stub.S74
-rw-r--r--sys/boot/ia64/ski/sal_stub.c118
-rw-r--r--sys/boot/ia64/ski/skiconsole.c96
-rw-r--r--sys/boot/ia64/ski/skifs.c193
-rw-r--r--sys/boot/ia64/ski/skiload.cmd16
-rw-r--r--sys/boot/ia64/ski/ssc.c53
-rw-r--r--sys/boot/ia64/ski/start.S64
-rw-r--r--sys/boot/ia64/ski/time.c174
-rw-r--r--sys/boot/ia64/ski/version8
-rw-r--r--sys/boot/ia64/skiload/Makefile85
-rw-r--r--sys/boot/ia64/skiload/conf.c86
-rw-r--r--sys/boot/ia64/skiload/ldscript.ia6461
-rw-r--r--sys/boot/ia64/skiload/main.c128
-rw-r--r--sys/boot/ia64/skiload/skiload.cmd16
-rw-r--r--sys/boot/ia64/skiload/start.S64
-rw-r--r--sys/boot/ia64/skiload/version8
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.
OpenPOWER on IntegriCloud