summaryrefslogtreecommitdiffstats
path: root/sys/boot/efi
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/boot/efi
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/boot/efi')
-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
14 files changed, 530 insertions, 1318 deletions
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; */
/*
OpenPOWER on IntegriCloud