summaryrefslogtreecommitdiffstats
path: root/stand/efi
diff options
context:
space:
mode:
authorkevans <kevans@FreeBSD.org>2018-04-06 21:37:25 +0000
committerkevans <kevans@FreeBSD.org>2018-04-06 21:37:25 +0000
commit883f323de4b8a7c082d104c900d77da04fb6869c (patch)
tree8883a8e2e75a488b83da075775f097a0edb434a1 /stand/efi
parent8b6d58da477582eaf6b2510f34d30b581ad2b6b5 (diff)
downloadFreeBSD-src-883f323de4b8a7c082d104c900d77da04fb6869c.zip
FreeBSD-src-883f323de4b8a7c082d104c900d77da04fb6869c.tar.gz
MFC r330806-r330815, r330837, r330864, r330883
pc98 changes associated with the named commits are also included in this commit, despite not having been made with the original commits due to its removal in head. r330806: Minor cosmetic changes. Make sure { on the same line as struct for all struct *devdesc. Move some type definitions to next to the dv_type define, since that's what sets the d_type. r330807: We can't use d_opendata for blkio storage. open_disk uses d_opendata for it's own purpse. We can't store blkio there. Fortunately, blkio is stored elsewhere and we never actually retrieve blkio from d_opendata. Eliminate it as a source of confusion. Eliminate all stores of d_opendata in efi since this layer doesn't own that field. r330808: Make struct libi386_devdesc match the struct devdesc better Move data to top and call it d_opendata. r330809: Use the actual struct devdesc at the start of all *_devdesc structs The current system is fragile and requires very careful layout of all *_devdesc structures. It also makes it hard to change the base devdesc. Take a page from CAM and put the 'header' in all the derived classes and adjust the code to match. For OFW, move the iHandle h_handle out of a slot conflicting with d_opendata. Due to quirks in the alignment rules, this worked. However changing the code to use d_opendata storage now that it's a pointer is hard, so just have a separate field for it. All other cleanups were to make the *_devdesc structures match where they'd taken some liberties that were none-the-less compatible enough to work. r330810: Remove d_type from devdesc. It's not needed as we can fetch it from d_dev->dv_type when we need it. r330811: GC unused routines. Sponsored by: Netflix r330812: Use the one-line-per-file pattern here, and sort the file names. Sponsored by: Netflix r330813: Move the env convenience routines out of boot1.c. These routines are more generally useful. Even though boot1 is on its way out, it's better to make these common during the transition than copy them. r330814: Star BootCurrent entry when booting. Sponsored by: Netflix r330815: Print the load and device path as well as BootCurrent and BootOrder Sponsored by: Netflix r330837: biosdisk.c should not set d_opendata. Same as 330807, d_opendata is owned by open_disk and we should not set it. M stand/i386/libi386/biosdisk.c r330864: Prefer uintXX_t to u_intXX_t A foolish consistency is the hobgoblin of little minds, adored by little statesmen and philosophers and divines. With consistency a great soul has simply nothing to do. -- Ralph Waldo Emerson r330883: Fix typo that misteriously passes compilation.
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