summaryrefslogtreecommitdiffstats
path: root/stand/efi
diff options
context:
space:
mode:
Diffstat (limited to 'stand/efi')
-rw-r--r--stand/efi/boot1/boot1.c45
-rw-r--r--stand/efi/boot1/ufs_module.c2
-rw-r--r--stand/efi/include/efilib.h11
-rw-r--r--stand/efi/libefi/Makefile17
-rw-r--r--stand/efi/libefi/devicename.c3
-rw-r--r--stand/efi/libefi/efienv.c87
-rw-r--r--stand/efi/libefi/efipart.c15
-rw-r--r--stand/efi/libefi/efizfs.c3
-rw-r--r--stand/efi/libefi/env.c29
-rw-r--r--stand/efi/loader/arch/arm/exec.c2
-rw-r--r--stand/efi/loader/main.c52
11 files changed, 169 insertions, 97 deletions
diff --git a/stand/efi/boot1/boot1.c b/stand/efi/boot1/boot1.c
index 35f3332d..887370d 100644
--- a/stand/efi/boot1/boot1.c
+++ b/stand/efi/boot1/boot1.c
@@ -54,8 +54,6 @@ static EFI_GUID BlockIoProtocolGUID = BLOCK_IO_PROTOCOL;
static EFI_GUID DevicePathGUID = DEVICE_PATH_PROTOCOL;
static EFI_GUID LoadedImageGUID = LOADED_IMAGE_PROTOCOL;
static EFI_GUID ConsoleControlGUID = EFI_CONSOLE_CONTROL_PROTOCOL_GUID;
-static EFI_GUID FreeBSDBootVarGUID = FREEBSD_BOOT_VAR_GUID;
-static EFI_GUID GlobalBootVarGUID = UEFI_BOOT_VAR_GUID;
/*
* Provide Malloc / Free backed by EFIs AllocatePool / FreePool which ensures
@@ -80,42 +78,6 @@ Free(void *buf, const char *file __unused, int line __unused)
(void)BS->FreePool(buf);
}
-static EFI_STATUS
-efi_getenv(EFI_GUID *g, const char *v, void *data, size_t *len)
-{
- size_t ul;
- CHAR16 *uv;
- UINT32 attr;
- UINTN dl;
- EFI_STATUS rv;
-
- uv = NULL;
- if (utf8_to_ucs2(v, &uv, &ul) != 0)
- return (EFI_OUT_OF_RESOURCES);
- dl = *len;
- rv = RS->GetVariable(uv, g, &attr, &dl, data);
- if (rv == EFI_SUCCESS)
- *len = dl;
- free(uv);
- return (rv);
-}
-
-static EFI_STATUS
-efi_setenv_freebsd_wcs(const char *varname, CHAR16 *valstr)
-{
- CHAR16 *var = NULL;
- size_t len;
- EFI_STATUS rv;
-
- if (utf8_to_ucs2(varname, &var, &len) != 0)
- return (EFI_OUT_OF_RESOURCES);
- rv = RS->SetVariable(var, &FreeBSDBootVarGUID,
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
- (ucs2len(valstr) + 1) * sizeof(efi_char), valstr);
- free(var);
- return (rv);
-}
-
/*
* nodes_match returns TRUE if the imgpath isn't NULL and the nodes match,
* FALSE otherwise.
@@ -505,14 +467,15 @@ efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE *Xsystab)
boot_current = 0;
sz = sizeof(boot_current);
- efi_getenv(&GlobalBootVarGUID, "BootCurrent", &boot_current, &sz);
+ efi_global_getenv("BootCurrent", &boot_current, &sz);
printf(" BootCurrent: %04x\n", boot_current);
sz = sizeof(boot_order);
- efi_getenv(&GlobalBootVarGUID, "BootOrder", &boot_order, &sz);
+ efi_global_getenv("BootOrder", &boot_order, &sz);
printf(" BootOrder:");
for (i = 0; i < sz / sizeof(boot_order[0]); i++)
- printf(" %04x", boot_order[i]);
+ printf(" %04x%s", boot_order[i],
+ boot_order[i] == boot_current ? "[*]" : "");
printf("\n");
#ifdef TEST_FAILURE
diff --git a/stand/efi/boot1/ufs_module.c b/stand/efi/boot1/ufs_module.c
index 4a8016f..76c15e4 100644
--- a/stand/efi/boot1/ufs_module.c
+++ b/stand/efi/boot1/ufs_module.c
@@ -44,7 +44,7 @@ static dev_info_t *devinfo;
static dev_info_t *devices;
static int
-dskread(void *buf, u_int64_t lba, int nblk)
+dskread(void *buf, uint64_t lba, int nblk)
{
int size;
EFI_STATUS status;
diff --git a/stand/efi/include/efilib.h b/stand/efi/include/efilib.h
index 2a07ec4..f2ca9ca 100644
--- a/stand/efi/include/efilib.h
+++ b/stand/efi/include/efilib.h
@@ -106,6 +106,17 @@ int wcscmp(CHAR16 *, CHAR16 *);
void cpy8to16(const char *, CHAR16 *, size_t);
void cpy16to8(const CHAR16 *, char *, size_t);
+/*
+ * Routines for interacting with EFI's env vars in a more unix-like
+ * way than the standard APIs. In addition, convenience routines for
+ * the loader setting / getting FreeBSD specific variables.
+ */
+
+EFI_STATUS efi_freebsd_getenv(const char *v, void *data, __size_t *len);
+EFI_STATUS efi_getenv(EFI_GUID *g, const char *v, void *data, __size_t *len);
+EFI_STATUS efi_global_getenv(const char *v, void *data, __size_t *len);
+EFI_STATUS efi_setenv_freebsd_wcs(const char *varname, CHAR16 *valstr);
+
/* efipart.c */
int efipart_inithandles(void);
diff --git a/stand/efi/libefi/Makefile b/stand/efi/libefi/Makefile
index c88eb4d..f45f3a7 100644
--- a/stand/efi/libefi/Makefile
+++ b/stand/efi/libefi/Makefile
@@ -5,8 +5,21 @@
LIB= efi
WARNS?= 2
-SRCS= delay.c devpath.c efi_console.c efichar.c efinet.c efipart.c env.c errno.c \
- handles.c wchar.c libefi.c efi_driver_utils.c efizfs.c devicename.c
+SRCS= delay.c \
+ devicename.c \
+ devpath.c \
+ efi_console.c \
+ efi_driver_utils.c \
+ efichar.c \
+ efienv.c \
+ efinet.c \
+ efipart.c \
+ efizfs.c \
+ env.c \
+ errno.c \
+ handles.c \
+ libefi.c \
+ wchar.c
.if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386"
SRCS+= time.c
diff --git a/stand/efi/libefi/devicename.c b/stand/efi/libefi/devicename.c
index 52e4799..e5d11a1 100644
--- a/stand/efi/libefi/devicename.c
+++ b/stand/efi/libefi/devicename.c
@@ -161,7 +161,6 @@ efi_parsedev(struct devdesc **dev, const char *devspec, const char **path)
}
idev->d_dev = dv;
- idev->d_type = dv->dv_type;
if (dev != NULL)
*dev = idev;
@@ -180,7 +179,7 @@ efi_fmtdev(void *vdev)
struct devdesc *dev = (struct devdesc *)vdev;
static char buf[SPECNAMELEN + 1];
- switch(dev->d_type) {
+ switch(dev->d_dev->dv_type) {
case DEVT_NONE:
strcpy(buf, "(no device)");
break;
diff --git a/stand/efi/libefi/efienv.c b/stand/efi/libefi/efienv.c
new file mode 100644
index 0000000..cc9f370
--- /dev/null
+++ b/stand/efi/libefi/efienv.c
@@ -0,0 +1,87 @@
+/*-
+ * Copyright (c) 2018 Netflix, Inc.
+ * 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 <efi.h>
+#include <efichar.h>
+#include <efilib.h>
+
+static EFI_GUID FreeBSDBootVarGUID = FREEBSD_BOOT_VAR_GUID;
+static EFI_GUID GlobalBootVarGUID = UEFI_BOOT_VAR_GUID;
+
+EFI_STATUS
+efi_getenv(EFI_GUID *g, const char *v, void *data, size_t *len)
+{
+ size_t ul;
+ CHAR16 *uv;
+ UINT32 attr;
+ UINTN dl;
+ EFI_STATUS rv;
+
+ uv = NULL;
+ if (utf8_to_ucs2(v, &uv, &ul) != 0)
+ return (EFI_OUT_OF_RESOURCES);
+ dl = *len;
+ rv = RS->GetVariable(uv, g, &attr, &dl, data);
+ if (rv == EFI_SUCCESS)
+ *len = dl;
+ free(uv);
+ return (rv);
+}
+
+EFI_STATUS
+efi_global_getenv(const char *v, void *data, size_t *len)
+{
+
+ return (efi_getenv(&GlobalBootVarGUID, v, data, len));
+}
+
+EFI_STATUS
+efi_freebsd_getenv(const char *v, void *data, size_t *len)
+{
+
+ return (efi_getenv(&FreeBSDBootVarGUID, v, data, len));
+}
+
+EFI_STATUS
+efi_setenv_freebsd_wcs(const char *varname, CHAR16 *valstr)
+{
+ CHAR16 *var = NULL;
+ size_t len;
+ EFI_STATUS rv;
+
+ if (utf8_to_ucs2(varname, &var, &len) != 0)
+ return (EFI_OUT_OF_RESOURCES);
+ rv = RS->SetVariable(var, &FreeBSDBootVarGUID,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ (ucs2len(valstr) + 1) * sizeof(efi_char), valstr);
+ free(var);
+ return (rv);
+}
+
diff --git a/stand/efi/libefi/efipart.c b/stand/efi/libefi/efipart.c
index f40fbd2..6838693 100644
--- a/stand/efi/libefi/efipart.c
+++ b/stand/efi/libefi/efipart.c
@@ -744,11 +744,10 @@ efipart_print_common(struct devsw *dev, pdinfo_list_t *pdlist, int verbose)
continue;
pd->pd_blkio = blkio;
- pd_dev.d_dev = dev;
- pd_dev.d_unit = pd->pd_unit;
+ pd_dev.dd.d_dev = dev;
+ pd_dev.dd.d_unit = pd->pd_unit;
pd_dev.d_slice = -1;
pd_dev.d_partition = -1;
- pd_dev.d_opendata = blkio;
ret = disk_open(&pd_dev, blkio->Media->BlockSize *
(blkio->Media->LastBlock + 1),
blkio->Media->BlockSize);
@@ -821,7 +820,7 @@ efipart_open(struct open_file *f, ...)
if (pd->pd_bcache == NULL)
pd->pd_bcache = bcache_allocate();
- if (dev->d_dev->dv_type == DEVT_DISK) {
+ if (dev->dd.d_dev->dv_type == DEVT_DISK) {
int rc;
rc = disk_open(dev,
@@ -860,7 +859,7 @@ efipart_close(struct open_file *f)
bcache_free(pd->pd_bcache);
pd->pd_bcache = NULL;
}
- if (dev->d_dev->dv_type == DEVT_DISK)
+ if (dev->dd.d_dev->dv_type == DEVT_DISK)
return (disk_close(dev));
return (0);
}
@@ -880,7 +879,7 @@ efipart_ioctl(struct open_file *f, u_long cmd, void *data)
if (pd == NULL)
return (EINVAL);
- if (dev->d_dev->dv_type == DEVT_DISK) {
+ if (dev->dd.d_dev->dv_type == DEVT_DISK) {
rc = disk_ioctl(dev, cmd, data);
if (rc != ENOTTY)
return (rc);
@@ -967,7 +966,7 @@ efipart_strategy(void *devdata, int rw, daddr_t blk, size_t size,
bcd.dv_devdata = devdata;
bcd.dv_cache = pd->pd_bcache;
- if (dev->d_dev->dv_type == DEVT_DISK) {
+ if (dev->dd.d_dev->dv_type == DEVT_DISK) {
daddr_t offset;
offset = dev->d_offset * pd->pd_blkio->Media->BlockSize;
@@ -1011,7 +1010,7 @@ efipart_realstrategy(void *devdata, int rw, daddr_t blk, size_t size,
* partition.
*/
disk_blocks = 0;
- if (dev->d_dev->dv_type == DEVT_DISK) {
+ if (dev->dd.d_dev->dv_type == DEVT_DISK) {
if (disk_ioctl(dev, DIOCGMEDIASIZE, &disk_blocks) == 0) {
/* DIOCGMEDIASIZE does return bytes. */
disk_blocks /= blkio->Media->BlockSize;
diff --git a/stand/efi/libefi/efizfs.c b/stand/efi/libefi/efizfs.c
index 58a0d66..3d5400f 100644
--- a/stand/efi/libefi/efizfs.c
+++ b/stand/efi/libefi/efizfs.c
@@ -29,8 +29,7 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
-#include <sys/disk.h>
-#include <stdint.h>
+#include <stand.h>
#ifdef EFI_ZFS_BOOT
#include <libzfs.h>
diff --git a/stand/efi/libefi/env.c b/stand/efi/libefi/env.c
index 6b2d176..0008232 100644
--- a/stand/efi/libefi/env.c
+++ b/stand/efi/libefi/env.c
@@ -35,35 +35,6 @@ __FBSDID("$FreeBSD$");
#include <stdbool.h>
#include "bootstrap.h"
-/*
- * Simple wrappers to the underlying UEFI functions.
- * See http://wiki.phoenix.com/wiki/index.php/EFI_RUNTIME_SERVICES
- * for details.
- */
-EFI_STATUS
-efi_get_next_variable_name(UINTN *variable_name_size, CHAR16 *variable_name,
- EFI_GUID *vendor_guid)
-{
- return (RS->GetNextVariableName(variable_name_size, variable_name,
- vendor_guid));
-}
-
-EFI_STATUS
-efi_get_variable(CHAR16 *variable_name, EFI_GUID *vendor_guid,
- UINT32 *attributes, UINTN *data_size, void *data)
-{
- return (RS->GetVariable(variable_name, vendor_guid, attributes,
- data_size, data));
-}
-
-EFI_STATUS
-efi_set_variable(CHAR16 *variable_name, EFI_GUID *vendor_guid,
- UINT32 attributes, UINTN data_size, void *data)
-{
- return (RS->SetVariable(variable_name, vendor_guid, attributes,
- data_size, data));
-}
-
void
efi_init_environment(void)
{
diff --git a/stand/efi/loader/arch/arm/exec.c b/stand/efi/loader/arch/arm/exec.c
index 83d3f2b..2de99a0 100644
--- a/stand/efi/loader/arch/arm/exec.c
+++ b/stand/efi/loader/arch/arm/exec.c
@@ -47,7 +47,7 @@ extern vm_offset_t md_load(char *, vm_offset_t *);
extern int bi_load(char *, vm_offset_t *, vm_offset_t *);
static int
-__elfN(arm_load)(char *filename, u_int64_t dest,
+__elfN(arm_load)(char *filename, uint64_t dest,
struct preloaded_file **result)
{
int r;
diff --git a/stand/efi/loader/main.c b/stand/efi/loader/main.c
index cd831c4..d313cb8 100644
--- a/stand/efi/loader/main.c
+++ b/stand/efi/loader/main.c
@@ -175,9 +175,7 @@ set_devdesc_currdev(struct devsw *dev, int unit)
char *devname;
currdev.d_dev = dev;
- currdev.d_type = currdev.d_dev->dv_type;
currdev.d_unit = unit;
- currdev.d_opendata = NULL;
devname = efi_fmtdev(&currdev);
env_setenv("currdev", EV_VOLATILE, devname, efi_setcurrdev,
@@ -202,10 +200,8 @@ find_currdev(EFI_LOADED_IMAGE *img)
if (pool_guid != 0) {
struct zfs_devdesc currdev;
- currdev.d_dev = &zfs_dev;
- currdev.d_unit = 0;
- currdev.d_type = currdev.d_dev->dv_type;
- currdev.d_opendata = NULL;
+ currdev.dd.d_dev = &zfs_dev;
+ currdev.dd.d_unit = 0;
currdev.pool_guid = pool_guid;
currdev.root_guid = 0;
devname = efi_fmtdev(&currdev);
@@ -224,10 +220,8 @@ find_currdev(EFI_LOADED_IMAGE *img)
STAILQ_FOREACH(dp, pdi_list, pd_link) {
struct disk_devdesc currdev;
- currdev.d_dev = &efipart_hddev;
- currdev.d_type = currdev.d_dev->dv_type;
- currdev.d_unit = dp->pd_unit;
- currdev.d_opendata = NULL;
+ currdev.dd.d_dev = &efipart_hddev;
+ currdev.dd.d_unit = dp->pd_unit;
currdev.d_slice = -1;
currdev.d_partition = -1;
@@ -318,6 +312,12 @@ main(int argc, CHAR16 *argv[])
int i, j, vargood, howto;
UINTN k;
int has_kbd;
+ CHAR16 *text;
+ UINT16 boot_current;
+ size_t sz;
+ UINT16 boot_order[100];
+ EFI_DEVICE_PATH *imgpath;
+ EFI_STATUS status;
#if !defined(__arm__)
char buf[40];
#endif
@@ -479,6 +479,36 @@ main(int argc, CHAR16 *argv[])
printf("\n%s", bootprog_info);
+ text = efi_devpath_name(img->FilePath);
+ if (text != NULL) {
+ printf(" Load Path: %S\n", text);
+ efi_setenv_freebsd_wcs("LoaderPath", text);
+ efi_free_devpath_name(text);
+ }
+
+ status = BS->HandleProtocol(img->DeviceHandle, &devid, (void **)&imgpath);
+ if (status == EFI_SUCCESS) {
+ text = efi_devpath_name(imgpath);
+ if (text != NULL) {
+ printf(" Load Device: %S\n", text);
+ efi_setenv_freebsd_wcs("LoaderDev", text);
+ efi_free_devpath_name(text);
+ }
+ }
+
+ boot_current = 0;
+ sz = sizeof(boot_current);
+ efi_global_getenv("BootCurrent", &boot_current, &sz);
+ printf(" BootCurrent: %04x\n", boot_current);
+
+ sz = sizeof(boot_order);
+ efi_global_getenv("BootOrder", &boot_order, &sz);
+ printf(" BootOrder:");
+ for (i = 0; i < sz / sizeof(boot_order[0]); i++)
+ printf(" %04x%s", boot_order[i],
+ boot_order[i] == boot_current ? "[*]" : "");
+ printf("\n");
+
/*
* Disable the watchdog timer. By default the boot manager sets
* the timer to 5 minutes before invoking a boot option. If we
@@ -848,7 +878,7 @@ command_chain(int argc, char *argv[])
struct disk_devdesc *d_dev;
pdinfo_t *hd, *pd;
- switch (dev->d_type) {
+ switch (dev->d_dev->dv_type) {
#ifdef EFI_ZFS_BOOT
case DEVT_ZFS:
z_dev = (struct zfs_devdesc *)dev;
OpenPOWER on IntegriCloud