summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2006-11-05 22:03:04 +0000
committermarcel <marcel@FreeBSD.org>2006-11-05 22:03:04 +0000
commit9ef7e5e3afc0c9daef60848d3b4b44df597298c1 (patch)
tree36bde112cc1780aa7082179e805aad052645807b /sys
parenta74874add4b6735fe168a33b970b50a6e9d6024a (diff)
downloadFreeBSD-src-9ef7e5e3afc0c9daef60848d3b4b44df597298c1.zip
FreeBSD-src-9ef7e5e3afc0c9daef60848d3b4b44df597298c1.tar.gz
Major rework of the ia64 loaders. The two primary objectives are:
1. Make libefi portable by removing ia64 specific code and build it on i386 and amd64 by default to prevent regressions. These changes include fixes and improvements over previous code to establish or improve APIs where none existed or when the amount of kluging was unacceptably high. 2. Increase the amount of sharing between the efi and ski loaders to improve maintainability of the loaders and simplify making changes to the loader-kernel handshaking in the future. The version of the efi and ski loaders are now both changed to 1.2 as user visible improvements and changes have been made.
Diffstat (limited to 'sys')
-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