diff options
author | kevans <kevans@FreeBSD.org> | 2018-04-06 21:37:25 +0000 |
---|---|---|
committer | kevans <kevans@FreeBSD.org> | 2018-04-06 21:37:25 +0000 |
commit | 883f323de4b8a7c082d104c900d77da04fb6869c (patch) | |
tree | 8883a8e2e75a488b83da075775f097a0edb434a1 /stand/efi | |
parent | 8b6d58da477582eaf6b2510f34d30b581ad2b6b5 (diff) | |
download | FreeBSD-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.c | 45 | ||||
-rw-r--r-- | stand/efi/boot1/ufs_module.c | 2 | ||||
-rw-r--r-- | stand/efi/include/efilib.h | 11 | ||||
-rw-r--r-- | stand/efi/libefi/Makefile | 17 | ||||
-rw-r--r-- | stand/efi/libefi/devicename.c | 3 | ||||
-rw-r--r-- | stand/efi/libefi/efienv.c | 87 | ||||
-rw-r--r-- | stand/efi/libefi/efipart.c | 15 | ||||
-rw-r--r-- | stand/efi/libefi/efizfs.c | 3 | ||||
-rw-r--r-- | stand/efi/libefi/env.c | 29 | ||||
-rw-r--r-- | stand/efi/loader/arch/arm/exec.c | 2 | ||||
-rw-r--r-- | stand/efi/loader/main.c | 52 |
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; |