summaryrefslogtreecommitdiffstats
path: root/sys/boot
diff options
context:
space:
mode:
Diffstat (limited to 'sys/boot')
-rw-r--r--sys/boot/Makefile2
-rw-r--r--sys/boot/efi/include/efilib.h20
-rw-r--r--sys/boot/efi/libefi/Makefile17
-rw-r--r--sys/boot/efi/libefi/bootinfo.c351
-rw-r--r--sys/boot/efi/libefi/copy.c55
-rw-r--r--sys/boot/efi/libefi/devicename.c241
-rw-r--r--sys/boot/efi/libefi/efiboot.h91
-rw-r--r--sys/boot/efi/libefi/efifpswa.c60
-rw-r--r--sys/boot/efi/libefi/efifs.c396
-rw-r--r--sys/boot/efi/libefi/efinet.c171
-rw-r--r--sys/boot/efi/libefi/elf_freebsd.c212
-rw-r--r--sys/boot/efi/libefi/errno.c94
-rw-r--r--sys/boot/efi/libefi/handles.c90
-rw-r--r--sys/boot/efi/libefi/module.c40
-rw-r--r--sys/boot/efi/libefi/time.c10
-rw-r--r--sys/boot/ia64/Makefile2
-rw-r--r--sys/boot/ia64/common/Makefile40
-rw-r--r--sys/boot/ia64/common/autoload.c35
-rw-r--r--sys/boot/ia64/common/bootinfo.c385
-rw-r--r--sys/boot/ia64/common/copy.c113
-rw-r--r--sys/boot/ia64/common/devicename.c202
-rw-r--r--sys/boot/ia64/common/exec.c146
-rw-r--r--sys/boot/ia64/common/libia64.h61
-rw-r--r--sys/boot/ia64/efi/Makefile51
-rw-r--r--sys/boot/ia64/efi/conf.c13
-rw-r--r--sys/boot/ia64/efi/efimd.c108
-rw-r--r--sys/boot/ia64/efi/main.c41
-rw-r--r--sys/boot/ia64/efi/version1
-rw-r--r--sys/boot/ia64/ski/Makefile47
-rw-r--r--sys/boot/ia64/ski/bootinfo.c321
-rw-r--r--sys/boot/ia64/ski/copy.c58
-rw-r--r--sys/boot/ia64/ski/devicename.c238
-rw-r--r--sys/boot/ia64/ski/efi_stub.c14
-rw-r--r--sys/boot/ia64/ski/elf_freebsd.c202
-rw-r--r--sys/boot/ia64/ski/libski.h26
-rw-r--r--sys/boot/ia64/ski/main.c35
-rw-r--r--sys/boot/ia64/ski/skifs.c1
-rw-r--r--sys/boot/ia64/ski/skimd.c74
-rw-r--r--sys/boot/ia64/ski/version3
39 files changed, 1269 insertions, 2798 deletions
diff --git a/sys/boot/Makefile b/sys/boot/Makefile
index bf76176..8d8ffed 100644
--- a/sys/boot/Makefile
+++ b/sys/boot/Makefile
@@ -8,7 +8,7 @@ SUBDIR+= ficl
.endif
# Build EFI library.
-.if ${MACHINE_ARCH} == "ia64"
+.if ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "i386" || ${MACHINE_ARCH} == "ia64"
SUBDIR+= efi
.endif
diff --git a/sys/boot/efi/include/efilib.h b/sys/boot/efi/include/efilib.h
index acb1c31..220e01a 100644
--- a/sys/boot/efi/include/efilib.h
+++ b/sys/boot/efi/include/efilib.h
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 2000 Doug Rabson
+ * Copyright (c) 2006 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -23,24 +24,31 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD$
+ * $FreeBSD$
*/
-#include <efifpswa.h>
+#include <stand.h>
extern EFI_HANDLE IH;
extern EFI_SYSTEM_TABLE *ST;
extern EFI_BOOT_SERVICES *BS;
extern EFI_RUNTIME_SERVICES *RS;
-/* DIG64 Headless Console & Debug Port Table. */
-#define HCDP_TABLE_GUID \
- {0xf951938d,0x620b,0x42ef,{0x82,0x79,0xa8,0x4b,0x79,0x61,0x78,0x98}}
+extern struct devsw efifs_dev;
+extern struct fs_ops efifs_fsops;
+
+extern struct devsw efinet_dev;
+extern struct netif_driver efinetif;
void *efi_get_table(EFI_GUID *tbl);
void efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table);
-EFI_PHYSICAL_ADDRESS efimd_va2pa(EFI_VIRTUAL_ADDRESS);
+int efi_register_handles(struct devsw *, EFI_HANDLE *, int);
+EFI_HANDLE efi_find_handle(struct devsw *, int);
+int efi_handle_lookup(EFI_HANDLE, struct devsw **, int *);
+
+int efi_status_to_errno(EFI_STATUS);
+time_t efi_time(EFI_TIME *);
EFI_STATUS main(int argc, CHAR16 *argv[]);
void exit(EFI_STATUS status);
diff --git a/sys/boot/efi/libefi/Makefile b/sys/boot/efi/libefi/Makefile
index c52ffc9..5c504a3 100644
--- a/sys/boot/efi/libefi/Makefile
+++ b/sys/boot/efi/libefi/Makefile
@@ -1,27 +1,16 @@
# $FreeBSD$
-.PATH: ${.CURDIR}/../../../${MACHINE_ARCH}/${MACHINE_ARCH}
-
LIB= efi
INTERNALLIB=
-SRCS= bootinfo.c copy.c delay.c devicename.c efi_console.c efifs.c efinet.c \
- elf_freebsd.c libefi.c module.c time.c
-
-.if ${MACHINE_ARCH} == "ia64"
-SRCS+= efifpswa.c pal.S
-.endif
+SRCS= delay.c efi_console.c efifs.c efinet.c errno.c handles.c libefi.c \
+ time.c
CFLAGS+= -I${.CURDIR}/../include
-CFLAGS+= -I${.CURDIR}/../include/${MACHINE_ARCH}
+CFLAGS+= -I${.CURDIR}/../include/${MACHINE_ARCH:S/amd64/i386/}
CFLAGS+= -I${.CURDIR}/../../../../lib/libstand
# Pick up the bootstrap header for some interface items
CFLAGS+= -I${.CURDIR}/../../common
-# Make the disk code more talkative
-.if defined(BOOT_DISK_DEBUG)
-CFLAGS+= -DDISK_DEBUG
-.endif
-
.include <bsd.lib.mk>
diff --git a/sys/boot/efi/libefi/bootinfo.c b/sys/boot/efi/libefi/bootinfo.c
deleted file mode 100644
index bfda81d..0000000
--- a/sys/boot/efi/libefi/bootinfo.c
+++ /dev/null
@@ -1,351 +0,0 @@
-/*-
- * 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 <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_ddb", RB_KDB},
- {"boot_dfltroot", RB_DFLTROOT},
- {"boot_gdb", RB_GDB},
- {"boot_multicons", RB_MULTIPLE},
- {"boot_mute", RB_MUTE},
- {"boot_pause", RB_PAUSE},
- {"boot_serial", RB_SERIAL},
- {"boot_single", RB_SINGLE},
- {"boot_verbose", RB_VERBOSE},
- {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_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 'p':
- howto |= RB_PAUSE;
- 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 the 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/efi/libefi/copy.c b/sys/boot/efi/libefi/copy.c
deleted file mode 100644
index 4b4b9bd..0000000
--- a/sys/boot/efi/libefi/copy.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*-
- * 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 <efi.h>
-#include <efilib.h>
-#include <stand.h>
-
-int
-efi_copyin(void *src, vm_offset_t va, size_t len)
-{
-
- bcopy(src, (void *)efimd_va2pa(va), len);
- return (len);
-}
-
-int
-efi_copyout(vm_offset_t va, void *dst, size_t len)
-{
-
- bcopy((void *)efimd_va2pa(va), dst, len);
- return (len);
-}
-
-int
-efi_readin(int fd, vm_offset_t va, size_t len)
-{
-
- return (read(fd, (void *)efimd_va2pa(va), len));
-}
diff --git a/sys/boot/efi/libefi/devicename.c b/sys/boot/efi/libefi/devicename.c
deleted file mode 100644
index 62c943a..0000000
--- a/sys/boot/efi/libefi/devicename.c
+++ /dev/null
@@ -1,241 +0,0 @@
-/*-
- * 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 <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_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_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_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_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/efi/libefi/efiboot.h b/sys/boot/efi/libefi/efiboot.h
deleted file mode 100644
index 74e659a..0000000
--- a/sys/boot/efi/libefi/efiboot.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*-
- * Copyright (c) 1996
- * Matthias Drochner. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed for the NetBSD Project
- * by Matthias Drochner.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-/*
- * EFI fully-qualified device descriptor
- */
-struct efi_devdesc {
- struct devsw *d_dev;
- int d_type;
-#define DEVT_NONE 0
-#define DEVT_DISK 1
-#define DEVT_NET 2
- int d_unit;
- EFI_HANDLE d_handle;
- union {
- struct {
- int slice;
- int partition;
- } efidisk;
- } d_kind;
-};
-
-extern int efi_getdev(void **vdev, const char *devspec, const char **path);
-extern char *efi_fmtdev(void *vdev);
-extern int efi_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 efifs_dev;
-extern struct devsw efi_disk;
-extern struct netif_driver efi_net;
-
-/* Find EFI network resources */
-extern void efinet_init_driver(void);
-
-/* Map handles to units */
-int efifs_get_unit(EFI_HANDLE);
-
-/* Wrapper over EFI filesystems. */
-extern struct fs_ops efi_fsops;
-
-/* this is in startup code */
-extern void delay(int);
-extern void reboot(void);
-
-extern ssize_t efi_copyin(const void *src, vm_offset_t dest, size_t len);
-extern ssize_t efi_copyout(const vm_offset_t src, void *dest, size_t len);
-extern ssize_t efi_readin(int fd, vm_offset_t dest, size_t len);
-
-extern int efi_boot(void);
-extern int efi_autoload(void);
-
-extern int fpswa_init(u_int64_t *fpswa_interface);
-
-struct bootinfo;
-struct preloaded_file;
-extern int bi_load(struct bootinfo *, struct preloaded_file *,
- UINTN *mapkey, UINTN pages);
diff --git a/sys/boot/efi/libefi/efifpswa.c b/sys/boot/efi/libefi/efifpswa.c
deleted file mode 100644
index f7d5147..0000000
--- a/sys/boot/efi/libefi/efifpswa.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*-
- * Copyright (c) 2001 Peter Wemm <peter@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 <sys/param.h>
-#include <sys/time.h>
-#include <stddef.h>
-#include <stand.h>
-#include <stdarg.h>
-
-#include <efi.h>
-#include <efilib.h>
-#include "efiboot.h"
-
-int
-fpswa_init(u_int64_t *fpswa_interface)
-{
- EFI_STATUS status;
- static EFI_GUID fpswaid = EFI_INTEL_FPSWA;
- UINTN sz;
- EFI_HANDLE fpswa_handle;
- FPSWA_INTERFACE *fpswa;
-
- *fpswa_interface = 0;
- sz = sizeof(EFI_HANDLE);
- status = BS->LocateHandle(ByProtocol, &fpswaid, 0, &sz, &fpswa_handle);
- if (EFI_ERROR(status))
- return ENOENT;
-
- status = BS->HandleProtocol(fpswa_handle, &fpswaid, (VOID **)&fpswa);
- if (EFI_ERROR(status))
- return ENOENT;
- *fpswa_interface = (u_int64_t)fpswa;
- return 0;
-}
diff --git a/sys/boot/efi/libefi/efifs.c b/sys/boot/efi/libefi/efifs.c
index ce20a6e..716102c 100644
--- a/sys/boot/efi/libefi/efifs.c
+++ b/sys/boot/efi/libefi/efifs.c
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 2001 Doug Rabson
+ * Copyright (c) 2006 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -22,88 +23,100 @@
* 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
#include <sys/param.h>
#include <sys/time.h>
#include <stddef.h>
-#include <stand.h>
#include <stdarg.h>
+#include <bootstrap.h>
+
#include <efi.h>
#include <efilib.h>
-#include "efiboot.h"
+#include <efiprot.h>
/* Perform I/O in blocks of size EFI_BLOCK_SIZE. */
#define EFI_BLOCK_SIZE (1024 * 1024)
+union fileinfo {
+ EFI_FILE_INFO info;
+ char bytes[sizeof(EFI_FILE_INFO) + 508];
+};
+
+static EFI_GUID sfs_guid = SIMPLE_FILE_SYSTEM_PROTOCOL;
+static EFI_GUID fs_guid = EFI_FILE_SYSTEM_INFO_ID;
+static EFI_GUID fi_guid = EFI_FILE_INFO_ID;
+
static int
efifs_open(const char *upath, struct open_file *f)
{
- struct efi_devdesc *dev = f->f_devdata;
- static EFI_GUID sfsid = SIMPLE_FILE_SYSTEM_PROTOCOL;
- EFI_FILE_IO_INTERFACE *sfs;
- EFI_FILE *root;
- EFI_FILE *file;
+ struct devdesc *dev = f->f_devdata;
+ EFI_FILE_IO_INTERFACE *fsif;
+ EFI_FILE *file, *root;
+ EFI_HANDLE h;
EFI_STATUS status;
- CHAR16 *cp;
- CHAR16 *path;
-
- /*
- * We cannot blindly assume that f->f_devdata points to a
- * efi_devdesc structure. Before we dereference 'dev', make
- * sure that the underlying device is ours.
- */
- if (f->f_dev != &efifs_dev || dev->d_handle == NULL)
- return ENOENT;
-
- status = BS->HandleProtocol(dev->d_handle, &sfsid, (VOID **)&sfs);
+ CHAR16 *cp, *path;
+
+ if (f->f_dev != &efifs_dev || dev->d_unit < 0)
+ return (EINVAL);
+
+ h = efi_find_handle(f->f_dev, dev->d_unit);
+ if (h == NULL)
+ return (EINVAL);
+
+ status = BS->HandleProtocol(h, &sfs_guid, (VOID **)&fsif);
if (EFI_ERROR(status))
- return ENOENT;
+ return (efi_status_to_errno(status));
- /*
- * Find the root directory.
- */
- status = sfs->OpenVolume(sfs, &root);
+ /* Get the root directory. */
+ status = fsif->OpenVolume(fsif, &root);
+ if (EFI_ERROR(status))
+ return (efi_status_to_errno(status));
- /*
- * Convert path to CHAR16, skipping leading separators.
- */
while (*upath == '/')
upath++;
- if (!*upath) {
- /* Opening the root directory, */
+
+ /* Special case: opening the root directory. */
+ if (*upath == '\0') {
f->f_fsdata = root;
- return 0;
+ return (0);
+ }
+
+ path = malloc((strlen(upath) + 1) * sizeof(CHAR16));
+ if (path == NULL) {
+ root->Close(root);
+ return (ENOMEM);
}
- cp = path = malloc((strlen(upath) + 1) * sizeof(CHAR16));
- if (path == NULL)
- return ENOMEM;
- while (*upath) {
- if (*upath == '/')
+
+ cp = path;
+ while (*upath != '\0') {
+ if (*upath == '/') {
*cp = '\\';
- else
+ while (upath[1] == '/')
+ upath++;
+ } else
*cp = *upath;
upath++;
cp++;
}
- *cp++ = 0;
+ *cp = 0;
- /*
- * Try to open it.
- */
- status = root->Open(root, &file, path, EFI_FILE_MODE_READ, 0);
+ /* Open the file. */
+ status = root->Open(root, &file, path,
+ EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE, 0);
+ if (status == EFI_ACCESS_DENIED || status == EFI_WRITE_PROTECTED)
+ status = root->Open(root, &file, path, EFI_FILE_MODE_READ, 0);
free(path);
- if (EFI_ERROR(status)) {
- root->Close(root);
- return ENOENT;
- }
-
root->Close(root);
+ if (EFI_ERROR(status))
+ return (efi_status_to_errno(status));
+
f->f_fsdata = file;
- return 0;
+ return (0);
}
static int
@@ -111,8 +124,12 @@ efifs_close(struct open_file *f)
{
EFI_FILE *file = f->f_fsdata;
+ if (file == NULL)
+ return (EBADF);
+
file->Close(file);
- return 0;
+ f->f_fsdata = NULL;
+ return (0);
}
static int
@@ -123,15 +140,17 @@ efifs_read(struct open_file *f, void *buf, size_t size, size_t *resid)
UINTN sz = size;
char *bufp;
+ if (file == NULL)
+ return (EBADF);
+
bufp = buf;
while (size > 0) {
sz = size;
if (sz > EFI_BLOCK_SIZE)
sz = EFI_BLOCK_SIZE;
status = file->Read(file, &sz, bufp);
- twiddle();
if (EFI_ERROR(status))
- return EIO;
+ return (efi_status_to_errno(status));
if (sz == 0)
break;
size -= sz;
@@ -139,7 +158,7 @@ efifs_read(struct open_file *f, void *buf, size_t size, size_t *resid)
}
if (resid)
*resid = size;
- return 0;
+ return (0);
}
static int
@@ -150,15 +169,17 @@ efifs_write(struct open_file *f, void *buf, size_t size, size_t *resid)
UINTN sz = size;
char *bufp;
+ if (file == NULL)
+ return (EBADF);
+
bufp = buf;
while (size > 0) {
sz = size;
if (sz > EFI_BLOCK_SIZE)
sz = EFI_BLOCK_SIZE;
status = file->Write(file, &sz, bufp);
- twiddle();
if (EFI_ERROR(status))
- return EIO;
+ return (efi_status_to_errno(status));
if (sz == 0)
break;
size -= sz;
@@ -166,7 +187,7 @@ efifs_write(struct open_file *f, void *buf, size_t size, size_t *resid)
}
if (resid)
*resid = size;
- return 0;
+ return (0);
}
static off_t
@@ -175,156 +196,139 @@ efifs_seek(struct open_file *f, off_t offset, int where)
EFI_FILE *file = f->f_fsdata;
EFI_STATUS status;
UINT64 base;
- UINTN sz;
- static EFI_GUID infoid = EFI_FILE_INFO_ID;
- EFI_FILE_INFO info;
+
+ if (file == NULL)
+ return (EBADF);
switch (where) {
case SEEK_SET:
- base = 0;
break;
+ case SEEK_END:
+ status = file->SetPosition(file, ~0ULL);
+ if (EFI_ERROR(status))
+ return (-1);
+ /* FALLTHROUGH */
+
case SEEK_CUR:
status = file->GetPosition(file, &base);
if (EFI_ERROR(status))
- return -1;
+ return (-1);
+ offset = (off_t)(base + offset);
break;
- case SEEK_END:
- sz = sizeof(info);
- status = file->GetInfo(file, &infoid, &sz, &info);
- if (EFI_ERROR(status))
- return -1;
- base = info.FileSize;
- break;
+ default:
+ return (-1);
}
+ if (offset < 0)
+ return (-1);
- status = file->SetPosition(file, base + offset);
- if (EFI_ERROR(status))
- return -1;
- file->GetPosition(file, &base);
-
- return base;
+ status = file->SetPosition(file, (UINT64)offset);
+ return (EFI_ERROR(status) ? -1 : offset);
}
static int
efifs_stat(struct open_file *f, struct stat *sb)
{
EFI_FILE *file = f->f_fsdata;
+ union fileinfo fi;
EFI_STATUS status;
- char *buf;
UINTN sz;
- static EFI_GUID infoid = EFI_FILE_INFO_ID;
- EFI_FILE_INFO *info;
- bzero(sb, sizeof(*sb));
+ if (file == NULL)
+ return (EBADF);
- buf = malloc(1024);
- sz = 1024;
-
- status = file->GetInfo(file, &infoid, &sz, buf);
- if (EFI_ERROR(status)) {
- free(buf);
- return -1;
- }
+ bzero(sb, sizeof(*sb));
- info = (EFI_FILE_INFO *) buf;
+ sz = sizeof(fi);
+ status = file->GetInfo(file, &fi_guid, &sz, &fi);
+ if (EFI_ERROR(status))
+ return (efi_status_to_errno(status));
- if (info->Attribute & EFI_FILE_READ_ONLY)
- sb->st_mode = S_IRUSR;
- else
- sb->st_mode = S_IRUSR | S_IWUSR;
- if (info->Attribute & EFI_FILE_DIRECTORY)
+ sb->st_mode = S_IRUSR | S_IRGRP | S_IROTH;
+ if ((fi.info.Attribute & EFI_FILE_READ_ONLY) == 0)
+ sb->st_mode |= S_IWUSR | S_IWGRP | S_IWOTH;
+ if (fi.info.Attribute & EFI_FILE_DIRECTORY)
sb->st_mode |= S_IFDIR;
else
sb->st_mode |= S_IFREG;
- sb->st_size = info->FileSize;
-
- free(buf);
- return 0;
+ sb->st_nlink = 1;
+ sb->st_atime = efi_time(&fi.info.LastAccessTime);
+ sb->st_mtime = efi_time(&fi.info.ModificationTime);
+ sb->st_ctime = efi_time(&fi.info.CreateTime);
+ sb->st_size = fi.info.FileSize;
+ sb->st_blocks = fi.info.PhysicalSize / S_BLKSIZE;
+ sb->st_blksize = S_BLKSIZE;
+ sb->st_birthtime = sb->st_ctime;
+ return (0);
}
static int
efifs_readdir(struct open_file *f, struct dirent *d)
{
EFI_FILE *file = f->f_fsdata;
+ union fileinfo fi;
EFI_STATUS status;
- char *buf;
UINTN sz;
- EFI_FILE_INFO *info;
int i;
- buf = malloc(1024);
- sz = 1024;
-
- status = file->Read(file, &sz, buf);
- if (EFI_ERROR(status) || sz < offsetof(EFI_FILE_INFO, FileName))
- return ENOENT;
+ if (file == NULL)
+ return (EBADF);
- info = (EFI_FILE_INFO *) buf;
+ sz = sizeof(fi);
+ status = file->Read(file, &sz, &fi);
+ if (EFI_ERROR(status))
+ return (efi_status_to_errno(status));
+ if (sz == 0)
+ return (ENOENT);
d->d_fileno = 0;
d->d_reclen = sizeof(*d);
- if (info->Attribute & EFI_FILE_DIRECTORY)
+ if (fi.info.Attribute & EFI_FILE_DIRECTORY)
d->d_type = DT_DIR;
else
d->d_type = DT_REG;
- d->d_namlen = ((info->Size - offsetof(EFI_FILE_INFO, FileName))
- / sizeof(CHAR16));
- for (i = 0; i < d->d_namlen; i++)
- d->d_name[i] = info->FileName[i];
+ for (i = 0; fi.info.FileName[i] != 0; i++)
+ d->d_name[i] = fi.info.FileName[i];
d->d_name[i] = 0;
-
- free(buf);
- return 0;
+ d->d_namlen = i;
+ return (0);
}
-struct fs_ops efi_fsops = {
- "fs",
- efifs_open,
- efifs_close,
- efifs_read,
- efifs_write,
- efifs_seek,
- efifs_stat,
- efifs_readdir
+struct fs_ops efifs_fsops = {
+ .fs_name = "efifs",
+ .fo_open = efifs_open,
+ .fo_close = efifs_close,
+ .fo_read = efifs_read,
+ .fo_write = efifs_write,
+ .fo_seek = efifs_seek,
+ .fo_stat = efifs_stat,
+ .fo_readdir = efifs_readdir
};
-static EFI_HANDLE *fs_handles;
-UINTN fs_handle_count;
-
-int
-efifs_get_unit(EFI_HANDLE h)
-{
- UINTN u;
-
- u = 0;
- while (u < fs_handle_count && fs_handles[u] != h)
- u++;
- return ((u < fs_handle_count) ? u : -1);
-}
-
static int
efifs_dev_init(void)
{
- EFI_STATUS status;
- UINTN sz;
- static EFI_GUID sfsid = SIMPLE_FILE_SYSTEM_PROTOCOL;
+ EFI_HANDLE *handles;
+ EFI_STATUS status;
+ UINTN sz;
+ int err;
sz = 0;
- status = BS->LocateHandle(ByProtocol, &sfsid, 0, &sz, 0);
- if (status != EFI_BUFFER_TOO_SMALL)
- return ENOENT;
- fs_handles = (EFI_HANDLE *) malloc(sz);
- status = BS->LocateHandle(ByProtocol, &sfsid, 0,
- &sz, fs_handles);
- if (EFI_ERROR(status)) {
- free(fs_handles);
- return ENOENT;
+ status = BS->LocateHandle(ByProtocol, &sfs_guid, 0, &sz, 0);
+ if (status == EFI_BUFFER_TOO_SMALL) {
+ handles = (EFI_HANDLE *)malloc(sz);
+ status = BS->LocateHandle(ByProtocol, &sfs_guid, 0, &sz,
+ handles);
+ if (EFI_ERROR(status))
+ free(handles);
}
- fs_handle_count = sz / sizeof(EFI_HANDLE);
-
- return 0;
+ if (EFI_ERROR(status))
+ return (efi_status_to_errno(status));
+ err = efi_register_handles(&efifs_dev, handles,
+ sz / sizeof(EFI_HANDLE));
+ free(handles);
+ return (err);
}
/*
@@ -333,14 +337,55 @@ efifs_dev_init(void)
static void
efifs_dev_print(int verbose)
{
- int i;
- char line[80];
+ union {
+ EFI_FILE_SYSTEM_INFO info;
+ char buffer[1024];
+ } fi;
+ char line[80];
+ EFI_FILE_IO_INTERFACE *fsif;
+ EFI_FILE *volume;
+ EFI_HANDLE h;
+ EFI_STATUS status;
+ UINTN sz;
+ int i, unit;
- for (i = 0; i < fs_handle_count; i++) {
- sprintf(line, " fs%d: EFI filesystem", i);
+ for (unit = 0, h = efi_find_handle(&efifs_dev, 0);
+ h != NULL; h = efi_find_handle(&efifs_dev, ++unit)) {
+ sprintf(line, " %s%d: ", efifs_dev.dv_name, unit);
pager_output(line);
- /* XXX more detail? */
+
+ status = BS->HandleProtocol(h, &sfs_guid, (VOID **)&fsif);
+ if (EFI_ERROR(status))
+ goto err;
+
+ status = fsif->OpenVolume(fsif, &volume);
+ if (EFI_ERROR(status))
+ goto err;
+
+ sz = sizeof(fi);
+ status = volume->GetInfo(volume, &fs_guid, &sz, &fi);
+ volume->Close(volume);
+ if (EFI_ERROR(status))
+ goto err;
+
+ if (fi.info.ReadOnly)
+ pager_output("[RO] ");
+ else
+ pager_output(" ");
+ for (i = 0; fi.info.VolumeLabel[i] != 0; i++)
+ fi.buffer[i] = fi.info.VolumeLabel[i];
+ fi.buffer[i] = 0;
+ if (fi.buffer[0] != 0)
+ pager_output(fi.buffer);
+ else
+ pager_output("EFI filesystem");
pager_output("\n");
+ continue;
+
+ err:
+ sprintf(line, "[--] error %d: unable to obtain information\n",
+ efi_status_to_errno(status));
+ pager_output(line);
}
}
@@ -357,45 +402,40 @@ efifs_dev_print(int verbose)
static int
efifs_dev_open(struct open_file *f, ...)
{
- va_list args;
- struct efi_devdesc *dev;
- int unit;
+ va_list args;
+ struct devdesc *dev;
va_start(args, f);
- dev = va_arg(args, struct efi_devdesc*);
+ dev = va_arg(args, struct devdesc*);
va_end(args);
- unit = dev->d_unit;
- if (unit < 0 || unit >= fs_handle_count) {
- printf("attempt to open nonexistent EFI filesystem\n");
+ if (dev->d_unit < 0)
return(ENXIO);
- }
-
- dev->d_handle = fs_handles[unit];
-
- return 0;
+ return (0);
}
static int
efifs_dev_close(struct open_file *f)
{
- return 0;
+ return (0);
}
static int
efifs_dev_strategy(void *devdata, int rw, daddr_t dblk, size_t size, char *buf, size_t *rsize)
{
- return 0;
+
+ return (ENOSYS);
}
struct devsw efifs_dev = {
- "fs",
- DEVT_DISK,
- efifs_dev_init,
- efifs_dev_strategy,
- efifs_dev_open,
- efifs_dev_close,
- noioctl,
- efifs_dev_print
+ .dv_name = "fs",
+ .dv_type = DEVT_DISK,
+ .dv_init = efifs_dev_init,
+ .dv_strategy = efifs_dev_strategy,
+ .dv_open = efifs_dev_open,
+ .dv_close = efifs_dev_close,
+ .dv_ioctl = noioctl,
+ .dv_print = efifs_dev_print,
+ .dv_cleanup = NULL
};
diff --git a/sys/boot/efi/libefi/efinet.c b/sys/boot/efi/libefi/efinet.c
index c6fc523..1eea860 100644
--- a/sys/boot/efi/libefi/efinet.c
+++ b/sys/boot/efi/libefi/efinet.c
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 2001 Doug Rabson
+ * Copyright (c) 2002, 2006 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -35,10 +36,31 @@ __FBSDID("$FreeBSD$");
#include <net.h>
#include <netif.h>
+#include <dev_net.c>
+
#include <efi.h>
#include <efilib.h>
-extern struct netif_driver efi_net;
+static EFI_GUID sn_guid = EFI_SIMPLE_NETWORK_PROTOCOL;
+
+static void efinet_end(struct netif *);
+static int efinet_get(struct iodesc *, void *, size_t, time_t);
+static void efinet_init(struct iodesc *, void *);
+static int efinet_match(struct netif *, void *);
+static int efinet_probe(struct netif *, void *);
+static int efinet_put(struct iodesc *, void *, size_t);
+
+struct netif_driver efinetif = {
+ .netif_bname = "efinet",
+ .netif_match = efinet_match,
+ .netif_probe = efinet_probe,
+ .netif_init = efinet_init,
+ .netif_get = efinet_get,
+ .netif_put = efinet_put,
+ .netif_end = efinet_end,
+ .netif_ifs = NULL,
+ .netif_nifs = 0
+};
#ifdef EFINET_DEBUG
static void
@@ -74,21 +96,21 @@ dump_mode(EFI_SIMPLE_NETWORK_MODE *mode)
}
#endif
-int
+static int
efinet_match(struct netif *nif, void *machdep_hint)
{
return (1);
}
-int
+static int
efinet_probe(struct netif *nif, void *machdep_hint)
{
return (0);
}
-int
+static int
efinet_put(struct iodesc *desc, void *pkt, size_t len)
{
struct netif *nif = desc->io_netif;
@@ -100,7 +122,7 @@ efinet_put(struct iodesc *desc, void *pkt, size_t len)
status = net->Transmit(net, 0, len, pkt, 0, 0, 0);
if (status != EFI_SUCCESS)
- return -1;
+ return (-1);
/* Wait for the buffer to be transmitted */
do {
@@ -113,11 +135,10 @@ efinet_put(struct iodesc *desc, void *pkt, size_t len)
} while (status == EFI_SUCCESS && buf == 0);
/* XXX How do we deal with status != EFI_SUCCESS now? */
- return (status == EFI_SUCCESS) ? len : -1;
+ return ((status == EFI_SUCCESS) ? len : -1);
}
-
-int
+static int
efinet_get(struct iodesc *desc, void *pkt, size_t len, time_t timeout)
{
struct netif *nif = desc->io_netif;
@@ -143,30 +164,37 @@ efinet_get(struct iodesc *desc, void *pkt, size_t len, time_t timeout)
if (bufsz > len)
bufsz = len;
bcopy(buf, pkt, bufsz);
- return bufsz;
+ return (bufsz);
}
if (status != EFI_NOT_READY)
- return 0;
+ return (0);
}
- return 0;
+ return (0);
}
-void
+static void
efinet_init(struct iodesc *desc, void *machdep_hint)
{
struct netif *nif = desc->io_netif;
EFI_SIMPLE_NETWORK *net;
+ EFI_HANDLE h;
EFI_STATUS status;
- net = nif->nif_driver->netif_ifs[nif->nif_unit].dif_private;
- nif->nif_devdata = net;
+ h = nif->nif_driver->netif_ifs[nif->nif_unit].dif_private;
+ status = BS->HandleProtocol(h, &sn_guid, (VOID **)&nif->nif_devdata);
+ if (status != EFI_SUCCESS) {
+ printf("net%d: cannot start interface (status=%ld)\n",
+ nif->nif_unit, (long)status);
+ return;
+ }
+ net = nif->nif_devdata;
if (net->Mode->State == EfiSimpleNetworkStopped) {
status = net->Start(net);
if (status != EFI_SUCCESS) {
printf("net%d: cannot start interface (status=%ld)\n",
- nif->nif_unit, status);
+ nif->nif_unit, (long)status);
return;
}
}
@@ -175,7 +203,7 @@ efinet_init(struct iodesc *desc, void *machdep_hint)
status = net->Initialize(net, 0, 0);
if (status != EFI_SUCCESS) {
printf("net%d: cannot init. interface (status=%ld)\n",
- nif->nif_unit, status);
+ nif->nif_unit, (long)status);
return;
}
}
@@ -187,7 +215,7 @@ efinet_init(struct iodesc *desc, void *machdep_hint)
status = net->ReceiveFilters(net, mask, 0, FALSE, 0, 0);
if (status != EFI_SUCCESS) {
printf("net%d: cannot set rx. filters (status=%ld)\n",
- nif->nif_unit, status);
+ nif->nif_unit, (long)status);
return;
}
}
@@ -198,71 +226,84 @@ efinet_init(struct iodesc *desc, void *machdep_hint)
bcopy(net->Mode->CurrentAddress.Addr, desc->myea, 6);
desc->xid = 1;
+}
+
+static void
+efinet_end(struct netif *nif)
+{
+ EFI_SIMPLE_NETWORK *net = nif->nif_devdata;
- return;
+ net->Shutdown(net);
}
-void
-efinet_init_driver()
+static int efinet_dev_init(void);
+static void efinet_dev_print(int);
+
+struct devsw efinet_dev = {
+ .dv_name = "net",
+ .dv_type = DEVT_NET,
+ .dv_init = efinet_dev_init,
+ .dv_strategy = net_strategy,
+ .dv_open = net_open,
+ .dv_close = net_close,
+ .dv_ioctl = noioctl,
+ .dv_print = efinet_dev_print,
+ .dv_cleanup = NULL
+};
+
+static int
+efinet_dev_init()
{
- EFI_STATUS status;
- UINTN sz;
- static EFI_GUID netid = EFI_SIMPLE_NETWORK_PROTOCOL;
- EFI_HANDLE *handles;
- int nifs, i;
-#define MAX_INTERFACES 4
- static struct netif_dif difs[MAX_INTERFACES];
- static struct netif_stats stats[MAX_INTERFACES];
+ struct netif_dif *dif;
+ struct netif_stats *stats;
+ EFI_HANDLE *handles;
+ EFI_STATUS status;
+ UINTN sz;
+ int err, i, nifs;
sz = 0;
- status = BS->LocateHandle(ByProtocol, &netid, 0, &sz, 0);
- if (status != EFI_BUFFER_TOO_SMALL)
- return;
- handles = (EFI_HANDLE *) malloc(sz);
- status = BS->LocateHandle(ByProtocol, &netid, 0, &sz, handles);
- if (EFI_ERROR(status)) {
- free(handles);
- return;
+ status = BS->LocateHandle(ByProtocol, &sn_guid, 0, &sz, 0);
+ if (status == EFI_BUFFER_TOO_SMALL) {
+ handles = (EFI_HANDLE *)malloc(sz);
+ status = BS->LocateHandle(ByProtocol, &sn_guid, 0, &sz,
+ handles);
+ if (EFI_ERROR(status))
+ free(handles);
}
-
+ if (EFI_ERROR(status))
+ return (efi_status_to_errno(status));
nifs = sz / sizeof(EFI_HANDLE);
- if (nifs > MAX_INTERFACES)
- nifs = MAX_INTERFACES;
+ err = efi_register_handles(&efinet_dev, handles, nifs);
+ free(handles);
+ if (err != 0)
+ return (err);
- efi_net.netif_nifs = nifs;
- efi_net.netif_ifs = difs;
+ efinetif.netif_nifs = nifs;
+ efinetif.netif_ifs = calloc(nifs, sizeof(struct netif_dif));
+
+ stats = calloc(nifs, sizeof(struct netif_stats));
- bzero(stats, sizeof(stats));
for (i = 0; i < nifs; i++) {
- struct netif_dif *dif = &efi_net.netif_ifs[i];
+ dif = &efinetif.netif_ifs[i];
dif->dif_unit = i;
dif->dif_nsel = 1;
dif->dif_stats = &stats[i];
-
- BS->HandleProtocol(handles[i], &netid,
- (VOID**) &dif->dif_private);
+ dif->dif_private = efi_find_handle(&efinet_dev, i);
}
- return;
+ return (0);
}
-void
-efinet_end(struct netif *nif)
+static void
+efinet_dev_print(int verbose)
{
- EFI_SIMPLE_NETWORK *net = nif->nif_devdata;
-
- net->Shutdown(net);
+ char line[80];
+ EFI_HANDLE h;
+ int unit;
+
+ for (unit = 0, h = efi_find_handle(&efinet_dev, 0);
+ h != NULL; h = efi_find_handle(&efinet_dev, ++unit)) {
+ sprintf(line, " %s%d:\n", efinet_dev.dv_name, unit);
+ pager_output(line);
+ }
}
-
-struct netif_driver efi_net = {
- "net", /* netif_bname */
- efinet_match, /* netif_match */
- efinet_probe, /* netif_probe */
- efinet_init, /* netif_init */
- efinet_get, /* netif_get */
- efinet_put, /* netif_put */
- efinet_end, /* netif_end */
- 0, /* netif_ifs */
- 0 /* netif_nifs */
-};
-
diff --git a/sys/boot/efi/libefi/elf_freebsd.c b/sys/boot/efi/libefi/elf_freebsd.c
deleted file mode 100644
index 93cfdbd..0000000
--- a/sys/boot/efi/libefi/elf_freebsd.c
+++ /dev/null
@@ -1,212 +0,0 @@
-/* $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.
- * 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/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;
- pt_entry_t 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));
-
- pte = PTE_PRESENT | PTE_MA_WB | PTE_ACCESSED | PTE_DIRTY |
- PTE_PL_KERN | PTE_AR_RWX;
-
- __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"(pte));
- __asm __volatile("srlz.i;;");
- __asm __volatile("itr.d dtr[%0]=%1;;" :: "r"(0), "r"(pte));
- __asm __volatile("srlz.i;;");
-
- enter_kernel(hdr->e_entry, bi);
-
- restore_ic(psr);
-}
diff --git a/sys/boot/efi/libefi/errno.c b/sys/boot/efi/libefi/errno.c
new file mode 100644
index 0000000..fac903f
--- /dev/null
+++ b/sys/boot/efi/libefi/errno.c
@@ -0,0 +1,94 @@
+/*-
+ * Copyright (c) 2006 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 <efi.h>
+#include <efilib.h>
+
+int
+efi_status_to_errno(EFI_STATUS status)
+{
+ int errno;
+
+ switch (status) {
+ case EFI_ACCESS_DENIED:
+ errno = EPERM;
+ break;
+
+ case EFI_BUFFER_TOO_SMALL:
+ errno = EOVERFLOW;
+ break;
+
+ case EFI_DEVICE_ERROR:
+ case EFI_VOLUME_CORRUPTED:
+ errno = EIO;
+ break;
+
+ case EFI_INVALID_PARAMETER:
+ errno = EINVAL;
+ break;
+
+ case EFI_MEDIA_CHANGED:
+ errno = ESTALE;
+ break;
+
+ case EFI_NO_MEDIA:
+ errno = ENXIO;
+ break;
+
+ case EFI_NOT_FOUND:
+ errno = ENOENT;
+ break;
+
+ case EFI_OUT_OF_RESOURCES:
+ errno = ENOMEM;
+ break;
+
+ case EFI_UNSUPPORTED:
+ errno = ENODEV;
+ break;
+
+ case EFI_VOLUME_FULL:
+ errno = ENOSPC;
+ break;
+
+ case EFI_WRITE_PROTECTED:
+ errno = EACCES;
+ break;
+
+ case 0:
+ errno = 0;
+ break;
+
+ default:
+ errno = EDOOFUS;
+ break;
+ }
+
+ return (errno);
+}
diff --git a/sys/boot/efi/libefi/handles.c b/sys/boot/efi/libefi/handles.c
new file mode 100644
index 0000000..7c78a15
--- /dev/null
+++ b/sys/boot/efi/libefi/handles.c
@@ -0,0 +1,90 @@
+/*-
+ * Copyright (c) 2006 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 <efi.h>
+#include <efilib.h>
+
+struct entry {
+ EFI_HANDLE handle;
+ struct devsw *dev;
+ int unit;
+};
+
+struct entry *entry;
+int nentries;
+
+int
+efi_register_handles(struct devsw *sw, EFI_HANDLE *handles, int count)
+{
+ size_t sz;
+ int idx, unit;
+
+ idx = nentries;
+ nentries += count;
+ sz = nentries * sizeof(struct entry);
+ entry = (entry == NULL) ? malloc(sz) : realloc(entry, sz);
+ for (unit = 0; idx < nentries; idx++, unit++) {
+ entry[idx].handle = handles[unit];
+ entry[idx].dev = sw;
+ entry[idx].unit = unit;
+ }
+ return (0);
+}
+
+EFI_HANDLE
+efi_find_handle(struct devsw *dev, int unit)
+{
+ int idx;
+
+ for (idx = 0; idx < nentries; idx++) {
+ if (entry[idx].dev != dev)
+ continue;
+ if (entry[idx].unit != unit)
+ continue;
+ return (entry[idx].handle);
+ }
+ return (NULL);
+}
+
+int
+efi_handle_lookup(EFI_HANDLE h, struct devsw **dev, int *unit)
+{
+ int idx;
+
+ for (idx = 0; idx < nentries; idx++) {
+ if (entry[idx].handle != h)
+ continue;
+ if (dev != NULL)
+ *dev = entry[idx].dev;
+ if (unit != NULL)
+ *unit = entry[idx].unit;
+ return (0);
+ }
+ return (ENOENT);
+}
diff --git a/sys/boot/efi/libefi/module.c b/sys/boot/efi/libefi/module.c
deleted file mode 100644
index 7a3f4b2..0000000
--- a/sys/boot/efi/libefi/module.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/*-
- * 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
-efi_autoload(void)
-{
- /* XXX use PnP to locate stuff here */
- return (0);
-}
diff --git a/sys/boot/efi/libefi/time.c b/sys/boot/efi/libefi/time.c
index 4cdba6b..5c39415 100644
--- a/sys/boot/efi/libefi/time.c
+++ b/sys/boot/efi/libefi/time.c
@@ -59,7 +59,7 @@ __FBSDID("$FreeBSD$");
#define SECSPERDAY (24 * SECSPERHOUR)
time_t
-EfiTimeToUnixTime(EFI_TIME *ETime)
+efi_time(EFI_TIME *ETime)
{
/*
// These arrays give the cumulative number of days up to the first of the
@@ -170,15 +170,15 @@ EFI_GetTimeOfDay(
OUT struct timezone *tzp
)
{
- EFI_TIME EfiTime;
+ EFI_TIME EfiTime;
EFI_TIME_CAPABILITIES Capabilities;
- EFI_STATUS Status;
+ EFI_STATUS Status;
/*
// Get time from EFI
*/
- Status = RS->GetTime( &EfiTime, &Capabilities );
+ Status = RS->GetTime(&EfiTime, &Capabilities);
if (EFI_ERROR(Status))
return (-1);
@@ -186,7 +186,7 @@ EFI_GetTimeOfDay(
// Convert to UNIX time (ie seconds since the epoch
*/
- tp->tv_sec = EfiTimeToUnixTime( &EfiTime );
+ tp->tv_sec = efi_time( &EfiTime );
tp->tv_usec = 0; /* EfiTime.Nanosecond * 1000; */
/*
diff --git a/sys/boot/ia64/Makefile b/sys/boot/ia64/Makefile
index 7d19869..eb07ab8 100644
--- a/sys/boot/ia64/Makefile
+++ b/sys/boot/ia64/Makefile
@@ -1,5 +1,5 @@
# $FreeBSD$
-SUBDIR= efi ski
+SUBDIR= common efi ski
.include <bsd.subdir.mk>
diff --git a/sys/boot/ia64/common/Makefile b/sys/boot/ia64/common/Makefile
new file mode 100644
index 0000000..b410bd8
--- /dev/null
+++ b/sys/boot/ia64/common/Makefile
@@ -0,0 +1,40 @@
+# $FreeBSD$
+
+.include <bsd.own.mk>
+
+LIB= ia64
+INTERNALLIB=
+
+SRCS= autoload.c bootinfo.c copy.c devicename.c exec.c
+
+CFLAGS+= -I${.CURDIR}/../../efi/include
+CFLAGS+= -I${.CURDIR}/../../efi/include/${MACHINE_ARCH}
+CFLAGS+= -I${.CURDIR}/../../..
+CFLAGS+= -I${.CURDIR}/../../../../lib/libstand
+
+.if ${MK_FORTH} != "no"
+BOOT_FORTH= yes
+CFLAGS+= -DBOOT_FORTH
+CFLAGS+= -I${.CURDIR}/../../ficl
+CFLAGS+= -I${.CURDIR}/../../ficl/${MACHINE_ARCH}
+.endif
+
+.PATH: ${.CURDIR}/../../common
+.include "${.CURDIR}/../../common/Makefile.inc"
+
+CFLAGS+= -I${.CURDIR}/../../common
+
+FILES+= loader.help
+CLEANFILES+= loader.help
+loader.help: help.common
+ cat ${.ALLSRC} | awk -f ${.CURDIR}/../../common/merge_help.awk \
+ > ${.TARGET}
+
+.PATH: ${.CURDIR}/../../forth
+FILES+= loader.4th support.4th loader.conf
+.if !exists(${DESTDIR}/boot/loader.rc)
+FILES+= loader.rc
+.endif
+FILESDIR_loader.conf= /boot/defaults
+
+.include <bsd.lib.mk>
diff --git a/sys/boot/ia64/common/autoload.c b/sys/boot/ia64/common/autoload.c
new file mode 100644
index 0000000..ea334b9
--- /dev/null
+++ b/sys/boot/ia64/common/autoload.c
@@ -0,0 +1,35 @@
+/*-
+ * Copyright (c) 2006 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$");
+
+int
+ia64_autoload(void)
+{
+
+ return (0);
+}
diff --git a/sys/boot/ia64/common/bootinfo.c b/sys/boot/ia64/common/bootinfo.c
index bfda81d..6f892a9 100644
--- a/sys/boot/ia64/common/bootinfo.c
+++ b/sys/boot/ia64/common/bootinfo.c
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * Copyright (c) 2006 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -32,15 +33,11 @@ __FBSDID("$FreeBSD$");
#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;
+#include "libia64.h"
/*
* Return a 'boothowto' value corresponding to the kernel arguments in
@@ -48,92 +45,60 @@ static EFI_GUID hcdp = HCDP_TABLE_GUID;
*/
static struct
{
- const char *ev;
- int mask;
+ const char *ev;
+ int mask;
} howto_names[] = {
- {"boot_askname", RB_ASKNAME},
- {"boot_cdrom", RB_CDROM},
- {"boot_ddb", RB_KDB},
- {"boot_dfltroot", RB_DFLTROOT},
- {"boot_gdb", RB_GDB},
- {"boot_multicons", RB_MULTIPLE},
- {"boot_mute", RB_MUTE},
- {"boot_pause", RB_PAUSE},
- {"boot_serial", RB_SERIAL},
- {"boot_single", RB_SINGLE},
- {"boot_verbose", RB_VERBOSE},
- {NULL, 0}
+ { "boot_askname", RB_ASKNAME},
+ { "boot_cdrom", RB_CDROM},
+ { "boot_ddb", RB_KDB},
+ { "boot_dfltroot", RB_DFLTROOT},
+ { "boot_gdb", RB_GDB},
+ { "boot_multicons", RB_MULTIPLE},
+ { "boot_mute", RB_MUTE},
+ { "boot_pause", RB_PAUSE},
+ { "boot_serial", RB_SERIAL},
+ { "boot_single", RB_SINGLE},
+ { "boot_verbose", RB_VERBOSE},
+ { NULL, 0}
};
-extern char *efi_fmtdev(void *vdev);
+static const char howto_switches[] = "aCdrgDmphsv";
+static int howto_masks[] = {
+ RB_ASKNAME, RB_CDROM, RB_KDB, RB_DFLTROOT, RB_GDB, RB_MULTIPLE,
+ RB_MUTE, RB_PAUSE, RB_SERIAL, RB_SINGLE, RB_VERBOSE
+};
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_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 'p':
- howto |= RB_PAUSE;
- break;
- case 'r':
- howto |= RB_DFLTROOT;
- break;
- case 's':
- howto |= RB_SINGLE;
- break;
- case 'v':
- howto |= RB_VERBOSE;
- break;
- default:
- active = 0;
- break;
+ const char *sw;
+ char *opts;
+ int howto, i;
+
+ howto = 0;
+
+ /* Get the boot options from the environment first. */
+ for (i = 0; howto_names[i].ev != NULL; i++) {
+ if (getenv(howto_names[i].ev) != NULL)
+ howto |= howto_names[i].mask;
+ }
+
+ /* Parse kargs */
+ if (kargs == NULL)
+ return (howto);
+
+ opts = strchr(kargs, '-');
+ while (opts != NULL) {
+ while (*(++opts) != '\0') {
+ sw = strchr(howto_switches, *opts);
+ if (sw == NULL)
+ break;
+ howto |= howto_masks[sw - howto_switches];
}
- cp++;
+ opts = strchr(opts, '-');
}
- }
- /* 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);
+
+ return (howto);
}
/*
@@ -142,26 +107,37 @@ bi_getboothowto(char *kargs)
* separating each variable, and a double nul terminating the environment.
*/
vm_offset_t
-bi_copyenv(vm_offset_t addr)
+bi_copyenv(vm_offset_t start)
{
- 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);
+ struct env_var *ep;
+ vm_offset_t addr, last;
+ size_t len;
+
+ addr = last = start;
+
+ /* Traverse the environment. */
+ for (ep = environ; ep != NULL; ep = ep->ev_next) {
+ len = strlen(ep->ev_name);
+ if (ia64_copyin(ep->ev_name, addr, len) != len)
+ break;
+ addr += len;
+ if (ia64_copyin("=", addr, 1) != 1)
+ break;
+ addr++;
+ if (ep->ev_value != NULL) {
+ len = strlen(ep->ev_value);
+ if (ia64_copyin(ep->ev_value, addr, len) != len)
+ break;
+ addr += len;
+ }
+ if (ia64_copyin("", addr, 1) != 1)
+ break;
+ last = ++addr;
}
- efi_copyin("", addr, 1);
- addr++;
- }
- efi_copyin("", addr, 1);
- addr++;
- return(addr);
+
+ if (ia64_copyin("", last++, 1) != 1)
+ last = start;
+ return(last);
}
/*
@@ -182,14 +158,14 @@ bi_copyenv(vm_offset_t addr)
*/
#define COPY32(v, a) { \
u_int32_t x = (v); \
- efi_copyin(&x, a, sizeof(x)); \
+ ia64_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); \
+ ia64_copyin(s, a, strlen(s) + 1); \
a += roundup(strlen(s) + 1, sizeof(u_int64_t));\
}
@@ -200,7 +176,7 @@ bi_copyenv(vm_offset_t addr)
#define MOD_VAR(t, a, s) { \
COPY32(t, a); \
COPY32(sizeof(s), a); \
- efi_copyin(&s, a, sizeof(s)); \
+ ia64_copyin(&s, a, sizeof(s)); \
a += roundup(sizeof(s), sizeof(u_int64_t)); \
}
@@ -210,7 +186,7 @@ bi_copyenv(vm_offset_t addr)
#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); \
+ ia64_copyin(mm->md_data, a, mm->md_size); \
a += roundup(mm->md_size, sizeof(u_int64_t));\
}
@@ -222,24 +198,25 @@ bi_copyenv(vm_offset_t addr)
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);
+ 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) {
+ /* The name field must come first. */
+ MOD_NAME(addr, fp->f_name);
+ 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);
}
/*
@@ -249,103 +226,71 @@ bi_copymodules(vm_offset_t addr)
* - Module metadata are formatted and placed in kernel space.
*/
int
-bi_load(struct bootinfo *bi, struct preloaded_file *fp, UINTN *mapkey,
- UINTN pages)
+bi_load(struct preloaded_file *fp, uint64_t *bi_addr)
{
- 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);
+ struct bootinfo bi;
+ struct preloaded_file *xp;
+ struct file_metadata *md;
+ struct devdesc *rootdev;
+ char *rootdevname;
+ vm_offset_t addr, ssym, esym;
+
+ bzero(&bi, sizeof(struct bootinfo));
+ bi.bi_magic = BOOTINFO_MAGIC;
+ bi.bi_version = 1;
+ 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");
+ ia64_getdev((void**)&rootdev, rootdevname, NULL);
+ if (rootdev != NULL) {
+ /* Try reading /etc/fstab to select the root device. */
+ getrootmount(ia64_fmtdev(rootdev));
+ free(rootdev);
+ }
+
+ md = file_findmetadata(fp, MODINFOMD_SSYM);
+ ssym = (md != NULL) ? *((vm_offset_t *)&(md->md_data)) : 0;
+ md = file_findmetadata(fp, MODINFOMD_ESYM);
+ esym = (md != NULL) ? *((vm_offset_t *)&(md->md_data)) : 0;
+ if (ssym != 0 && esym != 0) {
+ 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;
+ }
+
+ addr = (addr + 15) & ~15;
+
+ /* Copy module list and metadata. */
+ bi.bi_modulep = addr;
+ addr = bi_copymodules(addr);
+ if (addr <= bi.bi_modulep) {
+ addr = bi.bi_modulep;
+ bi.bi_modulep = 0;
+ }
+
+ addr = (addr + 15) & ~15;
+
+ /* Copy our environment. */
+ bi.bi_envp = addr;
+ addr = bi_copyenv(addr);
+ if (addr <= bi.bi_envp) {
+ addr = bi.bi_envp;
+ bi.bi_envp = 0;
+ }
+
+ addr = (addr + PAGE_MASK) & ~PAGE_MASK;
+ bi.bi_kernend = addr;
+
+ return (ldr_bootinfo(&bi, bi_addr));
}
diff --git a/sys/boot/ia64/common/copy.c b/sys/boot/ia64/common/copy.c
index 4b4b9bd..5583b15 100644
--- a/sys/boot/ia64/common/copy.c
+++ b/sys/boot/ia64/common/copy.c
@@ -1,55 +1,118 @@
/*-
- * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * Copyright (c) 2006 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 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.
+ * 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 <efi.h>
-#include <efilib.h>
#include <stand.h>
+#include <ia64/include/vmparam.h>
+
+#include "libia64.h"
+
+#define LDR_LOG2_PGSZ 20
+
+uint64_t *ia64_pgtbl;
+uint32_t ia64_pgtblsz;
+
+static void *
+va2pa(vm_offset_t va, size_t *len)
+{
+ uint64_t pa;
+
+ if (va >= IA64_RR_BASE(7)) {
+ pa = IA64_RR_MASK(va);
+ return ((void *)pa);
+ }
+
+ printf("\n%s: va=%lx, *len=%lx\n", __func__, va, *len);
+ *len = 0;
+ return (NULL);
+}
-int
-efi_copyin(void *src, vm_offset_t va, size_t len)
+ssize_t
+ia64_copyin(const void *src, vm_offset_t va, size_t len)
{
+ void *pa;
+ ssize_t res;
+ size_t sz;
- bcopy(src, (void *)efimd_va2pa(va), len);
- return (len);
+ res = 0;
+ while (len > 0) {
+ sz = len;
+ pa = va2pa(va, &sz);
+ if (sz == 0)
+ break;
+ bcopy(src, pa, sz);
+ len -= sz;
+ res += sz;
+ va += sz;
+ }
+ return (res);
}
-int
-efi_copyout(vm_offset_t va, void *dst, size_t len)
+ssize_t
+ia64_copyout(vm_offset_t va, void *dst, size_t len)
{
+ void *pa;
+ ssize_t res;
+ size_t sz;
- bcopy((void *)efimd_va2pa(va), dst, len);
- return (len);
+ res = 0;
+ while (len > 0) {
+ sz = len;
+ pa = va2pa(va, &sz);
+ if (sz == 0)
+ break;
+ bcopy(pa, dst, sz);
+ len -= sz;
+ res += sz;
+ va += sz;
+ }
+ return (res);
}
-int
-efi_readin(int fd, vm_offset_t va, size_t len)
+ssize_t
+ia64_readin(int fd, vm_offset_t va, size_t len)
{
+ void *pa;
+ ssize_t res, s;
+ size_t sz;
- return (read(fd, (void *)efimd_va2pa(va), len));
+ res = 0;
+ while (len > 0) {
+ sz = len;
+ pa = va2pa(va, &sz);
+ if (sz == 0)
+ break;
+ s = read(fd, pa, sz);
+ if (s <= 0)
+ break;
+ len -= s;
+ res += s;
+ va += s;
+ }
+ return (res);
}
diff --git a/sys/boot/ia64/common/devicename.c b/sys/boot/ia64/common/devicename.c
index 62c943a..08d9b54 100644
--- a/sys/boot/ia64/common/devicename.c
+++ b/sys/boot/ia64/common/devicename.c
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * Copyright (c) 2006 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -34,9 +35,8 @@ __FBSDID("$FreeBSD$");
#include <efi.h>
#include <efilib.h>
-#include "efiboot.h"
-static int efi_parsedev(struct efi_devdesc **dev, const char *devspec, const char **path);
+static int ia64_parsedev(struct devdesc **, const char *, const char **);
/*
* Point (dev) at an allocated device specifier for the device matching the
@@ -44,29 +44,24 @@ static int efi_parsedev(struct efi_devdesc **dev, const char *devspec, const cha
* use that. If not, use the default device.
*/
int
-efi_getdev(void **vdev, const char *devspec, const char **path)
+ia64_getdev(void **vdev, const char *devspec, const char **path)
{
- struct efi_devdesc **dev = (struct efi_devdesc **)vdev;
- int rv;
-
+ struct devdesc **dev = (struct devdesc **)vdev;
+ int rv;
+
/*
- * If it looks like this is just a path and no
- * device, go with the current device.
+ * If it looks like this is just a path and no device, then
+ * use the current device instead.
*/
- if ((devspec == NULL) ||
- (devspec[0] == '/') ||
- (strchr(devspec, ':') == NULL)) {
-
- if (((rv = efi_parsedev(dev, getenv("currdev"), NULL)) == 0) &&
- (path != NULL))
+ if (devspec == NULL || *devspec == '/' || !strchr(devspec, ':')) {
+ rv = ia64_parsedev(dev, getenv("currdev"), NULL);
+ if (rv == 0 && path != NULL)
*path = devspec;
- return(rv);
+ return (rv);
}
-
- /*
- * Try to parse the device name off the beginning of the devspec
- */
- return(efi_parsedev(dev, devspec, path));
+
+ /* Parse the device name off the beginning of the devspec. */
+ return (ia64_parsedev(dev, devspec, path));
}
/*
@@ -80,162 +75,95 @@ efi_getdev(void **vdev, const char *devspec, const char **path)
*
* For disk-type devices, the syntax is:
*
- * disk<unit>[s<slice>][<partition>]:
- *
+ * fs<unit>:
*/
static int
-efi_parsedev(struct efi_devdesc **dev, const char *devspec, const char **path)
+ia64_parsedev(struct 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;
+ struct devdesc *idev;
+ struct devsw *dv;
+ char *cp;
+ const char *np;
+ int i, err;
/* minimum length check */
if (strlen(devspec) < 2)
- return(EINVAL);
+ 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];
+ for (i = 0; devsw[i] != NULL; i++) {
+ dv = devsw[i];
+ if (!strncmp(devspec, dv->dv_name, strlen(dv->dv_name)))
break;
- }
}
+ if (devsw[i] == NULL)
+ return (ENOENT);
- 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 = malloc(sizeof(struct devdesc));
+ if (idev == NULL)
+ return (ENOMEM);
- idev->d_unit = unit;
- idev->d_kind.efidisk.slice = slice;
- idev->d_kind.efidisk.partition = partition;
+ idev->d_dev = dv;
+ idev->d_type = dv->dv_type;
+ idev->d_unit = -1;
- 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;
+ err = 0;
+ np = devspec + strlen(dv->dv_name);
+ if (*np != '\0' && *np != ':') {
+ idev->d_unit = strtol(np, &cp, 0);
+ if (cp == np) {
+ idev->d_unit = -1;
+ free(idev);
+ return (EUNIT);
}
-
- idev->d_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) {
+ if (*cp != '\0' && *cp != ':') {
free(idev);
- } else {
- *dev = idev;
+ return (EINVAL);
}
- return(0);
- fail:
- free(idev);
- return(err);
+ if (path != NULL)
+ *path = (*cp == 0) ? cp : cp + 1;
+ if (dev != NULL)
+ *dev = idev;
+ else
+ free(idev);
+ return (0);
}
-
char *
-efi_fmtdev(void *vdev)
+ia64_fmtdev(void *vdev)
{
- struct efi_devdesc *dev = (struct efi_devdesc *)vdev;
- static char buf[128]; /* XXX device length constant? */
- char *cp;
-
+ struct devdesc *dev = (struct devdesc *)vdev;
+ static char buf[32]; /* XXX device length constant? */
+
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_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:
+ default:
sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_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)
+ia64_setcurrdev(struct env_var *ev, int flags, const void *value)
{
- struct efi_devdesc *ncurr;
- int rv;
-
- if ((rv = efi_parsedev(&ncurr, value, NULL)) != 0)
+ struct devdesc *ncurr;
+ int rv;
+
+ rv = ia64_parsedev(&ncurr, value, NULL);
+ if (rv != 0)
return(rv);
+
free(ncurr);
env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL);
- return(0);
+ return (0);
}
-
diff --git a/sys/boot/ia64/common/exec.c b/sys/boot/ia64/common/exec.c
index 93cfdbd..a5a02d4 100644
--- a/sys/boot/ia64/common/exec.c
+++ b/sys/boot/ia64/common/exec.c
@@ -1,73 +1,27 @@
-/* $NetBSD: loadfile.c,v 1.10 1998/06/25 06:45:46 ross Exp $ */
-
/*-
- * Copyright (c) 1997 The NetBSD Foundation, Inc.
+ * Copyright (c) 2006 Marcel Moolenaar
* 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.
- * 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
+ * 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>
@@ -79,10 +33,11 @@ __FBSDID("$FreeBSD$");
#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 <ia64/include/bootinfo.h>
+#include <ia64/include/vmparam.h>
#include <efi.h>
#include <efilib.h>
@@ -95,28 +50,12 @@ 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)
+enter_kernel(uint64_t start, uint64_t bi)
{
- u_int64_t psr;
__asm __volatile("srlz.i;;");
__asm __volatile("mov cr.ipsr=%0"
@@ -130,6 +69,8 @@ enter_kernel(u_int64_t start, struct bootinfo *bi)
__asm __volatile("mov ar.rsc=0;; flushrs;;");
__asm __volatile("mov r8=%0" :: "r" (bi));
__asm __volatile("rfi;;");
+
+ /* NOTREACHED */
}
static int
@@ -138,51 +79,21 @@ elf64_exec(struct preloaded_file *fp)
struct file_metadata *md;
Elf_Ehdr *hdr;
pt_entry_t 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 */
+ uint64_t bi_addr;
+
+ md = file_findmetadata(fp, MODINFOMD_ELFHDR);
+ if (md == NULL)
+ return (EINVAL);
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);
+ bi_load(fp, &bi_addr);
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);
- }
+ ldr_enter(fp->f_name);
- psr = disable_ic();
+ __asm __volatile("rsm psr.ic|psr.i;;");
+ __asm __volatile("srlz.i;;");
/*
* Region 6 is direct mapped UC and region 7 is direct mapped
@@ -206,7 +117,8 @@ elf64_exec(struct preloaded_file *fp)
__asm __volatile("itr.d dtr[%0]=%1;;" :: "r"(0), "r"(pte));
__asm __volatile("srlz.i;;");
- enter_kernel(hdr->e_entry, bi);
+ enter_kernel(hdr->e_entry, bi_addr);
- restore_ic(psr);
+ /* NOTREACHED */
+ return (0);
}
diff --git a/sys/boot/ia64/common/libia64.h b/sys/boot/ia64/common/libia64.h
new file mode 100644
index 0000000..53de341
--- /dev/null
+++ b/sys/boot/ia64/common/libia64.h
@@ -0,0 +1,61 @@
+/*-
+ * Copyright (c) 2006 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$
+ */
+
+#ifndef _LIBIA64_H_
+#define _LIBIA64_H_
+
+#include <bootstrap.h>
+#include <ia64/include/bootinfo.h>
+
+/*
+ * Portability functions provided by the loader
+ * implementation specific to the platform.
+ */
+extern uint64_t ldr_alloc(vm_offset_t);
+extern int ldr_bootinfo(struct bootinfo *, uint64_t *);
+extern int ldr_enter(const char *);
+
+/*
+ * Functions and variables provided by the ia64 common code
+ * and shared by all loader implementations.
+ */
+
+extern uint64_t *ia64_pgtbl;
+extern uint32_t ia64_pgtblsz;
+
+extern int ia64_autoload(void);
+
+extern ssize_t ia64_copyin(const void *, vm_offset_t, size_t);
+extern ssize_t ia64_copyout(vm_offset_t, void *, size_t);
+extern ssize_t ia64_readin(int, vm_offset_t, size_t);
+
+extern char *ia64_fmtdev(struct devdesc *);
+extern int ia64_getdev(void **, const char *, const char **);
+extern int ia64_setcurrdev(struct env_var *, int, const void *);
+
+#endif /* !_LIBIA64_H_ */
diff --git a/sys/boot/ia64/efi/Makefile b/sys/boot/ia64/efi/Makefile
index f5fed73..0c07610 100644
--- a/sys/boot/ia64/efi/Makefile
+++ b/sys/boot/ia64/efi/Makefile
@@ -6,44 +6,22 @@ NO_MAN=
PROG= loader.sym
INTERNALPROG=
-SRCS= conf.c dev_net.c efimd.c main.c start.S vers.c
+SRCS= conf.c efimd.c main.c pal.S start.S vers.c
-CFLAGS+= -DLOADER
+.PATH: ${.CURDIR}/../../../${MACHINE_ARCH}/${MACHINE_ARCH}
+
+CFLAGS+= -I${.CURDIR}/../common
+CFLAGS+= -I${.CURDIR}/../../common
CFLAGS+= -I${.CURDIR}/../../efi/include
CFLAGS+= -I${.CURDIR}/../../efi/include/${MACHINE_ARCH}
-CFLAGS+= -I${.CURDIR}/../../efi/libefi
+CFLAGS+= -I${.CURDIR}/../../..
CFLAGS+= -I${.CURDIR}/../../../../lib/libstand
-.if ${MK_FORTH} != "no"
-BOOT_FORTH= yes
-CFLAGS+= -DBOOT_FORTH
-CFLAGS+= -I${.CURDIR}/../../ficl
-CFLAGS+= -I${.CURDIR}/../../ficl/${MACHINE_ARCH}
-LIBFICL= ${.OBJDIR}/../../ficl/libficl.a
-.endif
-
-# Always add MI sources
-.PATH: ${.CURDIR}/../../common
-.include "${.CURDIR}/../../common/Makefile.inc"
-
-CFLAGS+= -I${.CURDIR}/../../common
-
-.PATH: ${.CURDIR}/../../forth
-FILES= loader.efi loader.help loader.4th support.4th loader.conf
-FILESMODE_loader.efi= ${BINMODE}
-FILESDIR_loader.conf= /boot/defaults
-
-.if !exists(${DESTDIR}/boot/loader.rc)
-FILES+= loader.rc
-.endif
-
LDSCRIPT= ${.CURDIR}/ldscript.${MACHINE_ARCH}
LDFLAGS= -Wl,-T${LDSCRIPT} -shared -symbolic
${PROG}: ${LDSCRIPT}
-CLEANFILES= vers.c loader.efi loader.help
-
NEWVERSWHAT= "EFI boot" ${MACHINE_ARCH}
vers.c: ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version
@@ -52,22 +30,29 @@ vers.c: ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version
OBJCOPY?= objcopy
OBJDUMP?= objdump
+FILES= loader.efi
+FILESMODE_loader.efi= ${BINMODE}
+
loader.efi: loader.sym
if [ `${OBJDUMP} -t ${.ALLSRC} | fgrep '*UND*' | wc -l` != 0 ]; then \
${OBJDUMP} -t ${.ALLSRC} | fgrep '*UND*'; \
+ rm ${.ALLSRC}; \
exit 1; \
fi
${OBJCOPY} -j .data -j .dynamic -j .dynstr -j .dynsym -j .hash \
-j .rela.dyn -j .reloc -j .sdata -j .text \
--target=efi-app-${MACHINE_ARCH} ${.ALLSRC} ${.TARGET}
-loader.help: help.common
- cat ${.ALLSRC} | awk -f ${.CURDIR}/../../common/merge_help.awk \
- > ${.TARGET}
+CLEANFILES= vers.c loader.efi
+LIBIA64= ${.OBJDIR}/../common/libia64.a
LIBEFI= ${.OBJDIR}/../../efi/libefi/libefi.a
+.if ${MK_FORTH} != "no"
+LIBFICL= ${.OBJDIR}/../../ficl/libficl.a
+.endif
-DPADD= ${LIBFICL} ${LIBEFI} ${LIBSTAND}
-LDADD= ${LIBFICL} ${LIBEFI} -lstand
+DPADD= ${LIBIA64} ${LIBFICL} ${LIBEFI} ${LIBSTAND}
+LDADD= -Wl,--whole-archive ${LIBIA64} -Wl,--no-whole-archive \
+ ${LIBFICL} ${LIBEFI} -lstand
.include <bsd.prog.mk>
diff --git a/sys/boot/ia64/efi/conf.c b/sys/boot/ia64/efi/conf.c
index 8a250e6..a72f79f 100644
--- a/sys/boot/ia64/efi/conf.c
+++ b/sys/boot/ia64/efi/conf.c
@@ -38,8 +38,6 @@ __FBSDID("$FreeBSD$");
#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
@@ -52,24 +50,23 @@ __FBSDID("$FreeBSD$");
/* Exported for libstand */
struct devsw *devsw[] = {
&efifs_dev,
- &netdev,
+ &efinet_dev,
NULL
};
struct fs_ops *file_system[] = {
- &efi_fsops,
-/* &ufs_fsops, */
+ &efifs_fsops,
&nfs_fsops,
+ &ufs_fsops,
&gzipfs_fsops,
NULL
};
struct netif_driver *netif_drivers[] = {
- &efi_net,
- NULL,
+ &efinetif,
+ NULL
};
-/* Exported for ia64 only */
/*
* Sort formats so that those that can detect based on arguments
* rather than reading the file go first.
diff --git a/sys/boot/ia64/efi/efimd.c b/sys/boot/ia64/efi/efimd.c
index accf6c2..8a1e0c7 100644
--- a/sys/boot/ia64/efi/efimd.c
+++ b/sys/boot/ia64/efi/efimd.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2004 Marcel Moolenaar
+ * Copyright (c) 2004, 2006 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -27,14 +27,112 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include <stand.h>
+
#include <efi.h>
#include <efilib.h>
-#include <machine/vmparam.h>
+#include <libia64.h>
+
+#define EFI_INTEL_FPSWA \
+ {0xc41b6531,0x97b9,0x11d3,{0x9a,0x29,0x00,0x90,0x27,0x3f,0xc1,0x4d}}
+
+static EFI_GUID fpswa_guid = EFI_INTEL_FPSWA;
+
+/* DIG64 Headless Console & Debug Port Table. */
+#define HCDP_TABLE_GUID \
+ {0xf951938d,0x620b,0x42ef,{0x82,0x79,0xa8,0x4b,0x79,0x61,0x78,0x98}}
+
+static EFI_GUID hcdp_guid = HCDP_TABLE_GUID;
+
+static UINTN mapkey;
+
+uint64_t
+ldr_alloc(vm_offset_t va)
+{
+
+ return (0);
+}
+
+int
+ldr_bootinfo(struct bootinfo *bi, uint64_t *bi_addr)
+{
+ VOID *fpswa;
+ EFI_MEMORY_DESCRIPTOR *mm;
+ EFI_PHYSICAL_ADDRESS addr;
+ EFI_HANDLE handle;
+ EFI_STATUS status;
+ size_t bisz;
+ UINTN mmsz, pages, sz;
+ UINT32 mmver;
+
+ bi->bi_systab = (uint64_t)ST;
+ bi->bi_hcdp = (uint64_t)efi_get_table(&hcdp_guid);
+
+ sz = sizeof(EFI_HANDLE);
+ status = BS->LocateHandle(ByProtocol, &fpswa_guid, 0, &sz, &handle);
+ if (status == 0)
+ status = BS->HandleProtocol(handle, &fpswa_guid, &fpswa);
+ bi->bi_fpswa = (status == 0) ? (uint64_t)fpswa : 0;
+
+ bisz = (sizeof(struct bootinfo) + 0x0f) & ~0x0f;
-EFI_PHYSICAL_ADDRESS
-efimd_va2pa(EFI_VIRTUAL_ADDRESS va)
+ /*
+ * 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.
+ */
+ sz = 0;
+ BS->GetMemoryMap(&sz, NULL, &mapkey, &mmsz, &mmver);
+ sz += mmsz;
+ sz = (sz + 15) & ~15;
+ pages = EFI_SIZE_TO_PAGES(sz + bisz);
+ status = BS->AllocatePages(AllocateAnyPages, EfiLoaderData, pages,
+ &addr);
+ if (EFI_ERROR(status)) {
+ printf("%s: AllocatePages() returned 0x%lx\n", __func__,
+ (long)status);
+ return (ENOMEM);
+ }
+
+ /*
+ * Read the memory map and stash it after bootinfo. Align the
+ * memory map on a 16-byte boundary (the bootinfo block is page
+ * aligned).
+ */
+ *bi_addr = addr;
+ mm = (void *)(addr + bisz);
+ sz = (EFI_PAGE_SIZE * pages) - bisz;
+ status = BS->GetMemoryMap(&sz, mm, &mapkey, &mmsz, &mmver);
+ if (EFI_ERROR(status)) {
+ printf("%s: GetMemoryMap() returned 0x%lx\n", __func__,
+ (long)status);
+ return (EINVAL);
+ }
+ bi->bi_memmap = (uint64_t)mm;
+ bi->bi_memmap_size = sz;
+ bi->bi_memdesc_size = mmsz;
+ bi->bi_memdesc_version = mmver;
+
+ bcopy(bi, (void *)(*bi_addr), sizeof(*bi));
+ return (0);
+}
+
+int
+ldr_enter(const char *kernel)
{
+ EFI_STATUS status;
+
+ status = BS->ExitBootServices(IH, mapkey);
+ if (EFI_ERROR(status)) {
+ printf("%s: ExitBootServices() returned 0x%lx\n", __func__,
+ (long)status);
+ return (EINVAL);
+ }
- return (IA64_RR_MASK(va));
+ return (0);
}
diff --git a/sys/boot/ia64/efi/main.c b/sys/boot/ia64/efi/main.c
index 2d11bed..9419903 100644
--- a/sys/boot/ia64/efi/main.c
+++ b/sys/boot/ia64/efi/main.c
@@ -39,16 +39,19 @@ __FBSDID("$FreeBSD$");
#include <efi.h>
#include <efilib.h>
-#include "bootstrap.h"
-#include "efiboot.h"
+#include <libia64.h>
+/* DIG64 Headless Console & Debug Port Table. */
+#define HCDP_TABLE_GUID \
+ {0xf951938d,0x620b,0x42ef,{0x82,0x79,0xa8,0x4b,0x79,0x61,0x78,0x98}}
+
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 */
+struct devdesc currdev; /* our current device */
+struct arch_switch archsw; /* MI/MD interface boundary */
extern u_int64_t ia64_pal_entry;
@@ -121,8 +124,6 @@ main(int argc, CHAR16 *argv[])
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);
@@ -132,17 +133,7 @@ main(int argc, CHAR16 *argv[])
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_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_unit = 0; /* XXX */
- }
+ efi_handle_lookup(img->DeviceHandle, &currdev.d_dev, &currdev.d_unit);
currdev.d_type = currdev.d_dev->dv_type;
/*
@@ -156,18 +147,18 @@ main(int argc, CHAR16 *argv[])
*/
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_setenv("currdev", EV_VOLATILE, ia64_fmtdev(&currdev),
+ ia64_setcurrdev, env_nounset);
+ env_setenv("loaddev", EV_VOLATILE, ia64_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;
+ archsw.arch_autoload = ia64_autoload;
+ archsw.arch_getdev = ia64_getdev;
+ archsw.arch_copyin = ia64_copyin;
+ archsw.arch_copyout = ia64_copyout;
+ archsw.arch_readin = ia64_readin;
interact(); /* doesn't return */
diff --git a/sys/boot/ia64/efi/version b/sys/boot/ia64/efi/version
index 71f9400..7d7f566 100644
--- a/sys/boot/ia64/efi/version
+++ b/sys/boot/ia64/efi/version
@@ -3,6 +3,7 @@ $FreeBSD$
NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this
file is important. Make sure the current version number is on line 6.
+1.2: Restructured. Has some user visible differences.
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
diff --git a/sys/boot/ia64/ski/Makefile b/sys/boot/ia64/ski/Makefile
index 84b06dc..42d24d1 100644
--- a/sys/boot/ia64/ski/Makefile
+++ b/sys/boot/ia64/ski/Makefile
@@ -5,45 +5,34 @@ NO_MAN=
.include <bsd.own.mk>
PROG= skiload
-NEWVERSWHAT= "ia64 SKI boot" ${MACHINE_ARCH}
STRIP= # We must not strip skiload at install time.
-SRCS= acpi_stub.c bootinfo.c conf.c copy.c delay.c devicename.c \
- efi_stub.c elf_freebsd.c exit.c main.c pal_stub.S sal_stub.c \
- skiconsole.c skifs.c ssc.c start.S time.c vers.c
+SRCS= acpi_stub.c conf.c delay.c efi_stub.c exit.c main.c \
+ pal_stub.S sal_stub.c skiconsole.c skifs.c skimd.c \
+ ssc.c start.S time.c vers.c
-CFLAGS+= -DLOADER
-CFLAGS+= -I${.CURDIR}
-CFLAGS+= -I${.CURDIR}/../../..
-CFLAGS+= -I${.CURDIR}/../../efi/include
-CFLAGS+= -I${.CURDIR}/../../efi/include/${MACHINE_ARCH}
-LDFLAGS= -Wl,-T${.CURDIR}/ldscript.ia64
-
-.if ${MK_FORTH} != "no"
-CFLAGS+= -DBOOT_FORTH
-CFLAGS+= -I${.CURDIR}/../../ficl
-CFLAGS+= -I${.CURDIR}/../../ficl/${MACHINE_ARCH}
-LIBFICL= ${.OBJDIR}/../../ficl/libficl.a
-BOOT_FORTH= yes
-.endif
-
-# Always add MI sources (needs BOOT_FORTH)
-.PATH: ${.CURDIR}/../../common
+CFLAGS+= -I${.CURDIR}/../common
CFLAGS+= -I${.CURDIR}/../../common
-.include "${.CURDIR}/../../common/Makefile.inc"
+CFLAGS+= -I${.CURDIR}/../../..
+CFLAGS+= -I${.CURDIR}/../../../../lib/libstand
-DPADD= ${LIBFICL} ${LIBSTAND}
-LDADD= ${LIBFICL} -lstand
+LDSCRIPT= ${.CURDIR}/ldscript.${MACHINE_ARCH}
+LDFLAGS= -Wl,-T${LDSCRIPT}
-CLEANFILES= vers.c ${PROG}.help
+NEWVERSWHAT= "SKI boot" ${MACHINE_ARCH}
vers.c: ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version
sh ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version ${NEWVERSWHAT}
-${PROG}.help: help.common
- cat ${.ALLSRC} | awk -f ${.CURDIR}/../../common/merge_help.awk \
- > ${.TARGET}
+CLEANFILES= vers.c
+
+LIBIA64= ${.OBJDIR}/../common/libia64.a
+.if ${MK_FORTH} != "no"
+LIBFICL= ${.OBJDIR}/../../ficl/libficl.a
+.endif
-FILES= ${PROG}.help
+DPADD= ${LIBIA64} ${LIBFICL} ${LIBSTAND}
+LDADD= -Wl,--whole-archive ${LIBIA64} -Wl,--no-whole-archive \
+ ${LIBFICL} -lstand
.include <bsd.prog.mk>
diff --git a/sys/boot/ia64/ski/bootinfo.c b/sys/boot/ia64/ski/bootinfo.c
deleted file mode 100644
index 4c19d22..0000000
--- a/sys/boot/ia64/ski/bootinfo.c
+++ /dev/null
@@ -1,321 +0,0 @@
-/*-
- * 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_ddb", RB_KDB},
- {"boot_dfltroot", RB_DFLTROOT},
- {"boot_gdb", RB_GDB},
- {"boot_multicons", RB_MULTIPLE},
- {"boot_mute", RB_MUTE},
- {"boot_pause", RB_PAUSE},
- {"boot_serial", RB_SERIAL},
- {"boot_single", RB_SINGLE},
- {"boot_verbose", RB_VERBOSE},
- {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_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 'p':
- howto |= RB_PAUSE;
- 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 the 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/copy.c b/sys/boot/ia64/ski/copy.c
deleted file mode 100644
index d86537a..0000000
--- a/sys/boot/ia64/ski/copy.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/*-
- * 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/devicename.c b/sys/boot/ia64/ski/devicename.c
deleted file mode 100644
index 1a3a75d..0000000
--- a/sys/boot/ia64/ski/devicename.c
+++ /dev/null
@@ -1,238 +0,0 @@
-/*-
- * 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_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_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_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_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
index 20a20b4..3c7a099 100644
--- a/sys/boot/ia64/ski/efi_stub.c
+++ b/sys/boot/ia64/ski/efi_stub.c
@@ -28,17 +28,14 @@
__FBSDID("$FreeBSD$");
#include <sys/types.h>
-#include <machine/bootinfo.h>
#include <machine/efi.h>
+#include <ia64/include/bootinfo.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);
-
struct efi_cfgtbl efi_cfgtab[] = {
{ EFI_TABLE_ACPI20, (intptr_t)&acpi_root },
{ EFI_TABLE_SAL, (intptr_t)&sal_systab }
@@ -223,8 +220,8 @@ ResetSystem(enum efi_reset type, efi_status status, u_long datasz,
return (unsupported(__func__));
}
-int
-ski_init_stubs(struct bootinfo *bi)
+void
+efi_stub_init(struct bootinfo *bi)
{
struct efi_md *memp;
@@ -261,9 +258,4 @@ ski_init_stubs(struct bootinfo *bi)
memp[3].md_attr = EFI_MD_ATTR_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
deleted file mode 100644
index 42481d6..0000000
--- a/sys/boot/ia64/ski/elf_freebsd.c
+++ /dev/null
@@ -1,202 +0,0 @@
-/* $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.
- * 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/libski.h b/sys/boot/ia64/ski/libski.h
index 595e59a..5bbc6de 100644
--- a/sys/boot/ia64/ski/libski.h
+++ b/sys/boot/ia64/ski/libski.h
@@ -26,28 +26,6 @@
* $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
- int d_unit;
- union {
- struct {
- int slice;
- int partition;
- } skidisk;
- } 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;
@@ -64,10 +42,6 @@ extern struct fs_ops ski_fsops;
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);
struct bootinfo;
diff --git a/sys/boot/ia64/ski/main.c b/sys/boot/ia64/ski/main.c
index 604553c..6cfa25b 100644
--- a/sys/boot/ia64/ski/main.c
+++ b/sys/boot/ia64/ski/main.c
@@ -33,7 +33,7 @@ __FBSDID("$FreeBSD$");
#include <setjmp.h>
#include <machine/fpu.h>
-#include "bootstrap.h"
+#include <libia64.h>
#include "libski.h"
extern char bootprog_name[];
@@ -41,15 +41,8 @@ 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 */
-
-static int
-ski_autoload(void)
-{
-
- return (0);
-}
+struct devdesc currdev; /* our current device */
+struct arch_switch archsw; /* MI/MD interface boundary */
void
ski_main(void)
@@ -85,15 +78,11 @@ ski_main(void)
#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_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 */
@@ -102,18 +91,18 @@ ski_main(void)
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_setenv("currdev", EV_VOLATILE, ia64_fmtdev(&currdev),
+ ia64_setcurrdev, env_nounset);
+ env_setenv("loaddev", EV_VOLATILE, ia64_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;
+ archsw.arch_autoload = ia64_autoload;
+ archsw.arch_getdev = ia64_getdev;
+ archsw.arch_copyin = ia64_copyin;
+ archsw.arch_copyout = ia64_copyout;
+ archsw.arch_readin = ia64_readin;
interact(); /* doesn't return */
diff --git a/sys/boot/ia64/ski/skifs.c b/sys/boot/ia64/ski/skifs.c
index 5a272c7..72276fe 100644
--- a/sys/boot/ia64/ski/skifs.c
+++ b/sys/boot/ia64/ski/skifs.c
@@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$");
#include <stand.h>
#include <stdarg.h>
+#include <bootstrap.h>
#include "libski.h"
struct disk_req {
diff --git a/sys/boot/ia64/ski/skimd.c b/sys/boot/ia64/ski/skimd.c
new file mode 100644
index 0000000..bec2ec0
--- /dev/null
+++ b/sys/boot/ia64/ski/skimd.c
@@ -0,0 +1,74 @@
+/*-
+ * Copyright (c) 2006 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 <stand.h>
+
+#include <libia64.h>
+
+#include "libski.h"
+
+#define PHYS_START (4L*1024*1024*1024)
+#define PHYS_SIZE (64L*1024*1024 - 4L*1024)
+
+extern void acpi_stub_init(void);
+extern void efi_stub_init(struct bootinfo *);
+extern void sal_stub_init(void);
+
+uint64_t
+ldr_alloc(vm_offset_t va)
+{
+
+ if (va >= PHYS_SIZE)
+ return (0);
+ return (va + PHYS_START);
+}
+
+int
+ldr_bootinfo(struct bootinfo *bi, uint64_t *bi_addr)
+{
+ static struct bootinfo bootinfo;
+
+ efi_stub_init(bi);
+ sal_stub_init();
+ acpi_stub_init();
+
+ *bi_addr = (uint64_t)(&bootinfo);
+ bootinfo = *bi;
+ return (0);
+}
+
+int
+ldr_enter(const char *kernel)
+{
+
+ while (*kernel == '/')
+ kernel++;
+ ssc(0, (uint64_t)kernel, 0, 0, SSC_LOAD_SYMBOLS);
+ return (0);
+}
diff --git a/sys/boot/ia64/ski/version b/sys/boot/ia64/ski/version
index 6f4fc3c..afa69ea 100644
--- a/sys/boot/ia64/ski/version
+++ b/sys/boot/ia64/ski/version
@@ -3,6 +3,9 @@ $FreeBSD$
NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this
file is important. Make sure the current version number is on line 6.
+1.2: Restructured. Has some user visible differences. Due to code
+ sharing, has been given the same version number as the EFI
+ loader.
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