diff options
-rw-r--r-- | usr/src/boot/sys/boot/efi/include/efi.h | 5 | ||||
-rw-r--r-- | usr/src/boot/sys/boot/efi/include/efilib.h | 13 | ||||
-rw-r--r-- | usr/src/boot/sys/boot/efi/libefi/Makefile | 1 | ||||
-rw-r--r-- | usr/src/boot/sys/boot/efi/libefi/efienv.c | 85 | ||||
-rw-r--r-- | usr/src/boot/sys/boot/efi/libefi/env.c | 55 |
5 files changed, 142 insertions, 17 deletions
diff --git a/usr/src/boot/sys/boot/efi/include/efi.h b/usr/src/boot/sys/boot/efi/include/efi.h index 6815446a26..b844d16010 100644 --- a/usr/src/boot/sys/boot/efi/include/efi.h +++ b/usr/src/boot/sys/boot/efi/include/efi.h @@ -61,4 +61,9 @@ Revision History #include "efipoint.h" #include "efiuga.h" +/* + * illumos UUID + */ +#define ILLUMOS_BOOT_VAR_GUID \ + { 0x8B54B311, 0x7163, 0x40d3, {0xA6, 0x7B, 0xE7, 0xB2, 0x95, 0x1B, 0x3D, 0x56} } #endif diff --git a/usr/src/boot/sys/boot/efi/include/efilib.h b/usr/src/boot/sys/boot/efi/include/efilib.h index e6fd4ee8ab..d477bf6f1b 100644 --- a/usr/src/boot/sys/boot/efi/include/efilib.h +++ b/usr/src/boot/sys/boot/efi/include/efilib.h @@ -1,4 +1,4 @@ -/*- +/* * Copyright (c) 2000 Doug Rabson * Copyright (c) 2006 Marcel Moolenaar * All rights reserved. @@ -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 illumos specific variables. + */ + +EFI_STATUS efi_illumos_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_illumos_wcs(const char *varname, CHAR16 *valstr); + /* guids and names */ bool efi_guid_to_str(const EFI_GUID *, char **); bool efi_str_to_guid(const char *, EFI_GUID *); diff --git a/usr/src/boot/sys/boot/efi/libefi/Makefile b/usr/src/boot/sys/boot/efi/libefi/Makefile index b8b4c5e6d6..0886f0f352 100644 --- a/usr/src/boot/sys/boot/efi/libefi/Makefile +++ b/usr/src/boot/sys/boot/efi/libefi/Makefile @@ -30,6 +30,7 @@ SRCS= delay.c \ efi_console.c \ efi_driver_utils.c \ efichar.c \ + efienv.c \ efinet.c \ efipart.c \ efizfs.c \ diff --git a/usr/src/boot/sys/boot/efi/libefi/efienv.c b/usr/src/boot/sys/boot/efi/libefi/efienv.c new file mode 100644 index 0000000000..253d525c1a --- /dev/null +++ b/usr/src/boot/sys/boot/efi/libefi/efienv.c @@ -0,0 +1,85 @@ +/* + * 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> + +#include <stand.h> +#include <efi.h> +#include <efichar.h> +#include <efilib.h> + +static EFI_GUID illumosBootVarGUID = ILLUMOS_BOOT_VAR_GUID; +static EFI_GUID GlobalBootVarGUID = EFI_GLOBAL_VARIABLE; + +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_illumos_getenv(const char *v, void *data, size_t *len) +{ + + return (efi_getenv(&illumosBootVarGUID, v, data, len)); +} + +EFI_STATUS +efi_setenv_illumos_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, &illumosBootVarGUID, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + (ucs2len(valstr) + 1) * sizeof (CHAR16), valstr); + free(var); + return (rv); +} diff --git a/usr/src/boot/sys/boot/efi/libefi/env.c b/usr/src/boot/sys/boot/efi/libefi/env.c index 663d343bf3..c43e4b118b 100644 --- a/usr/src/boot/sys/boot/efi/libefi/env.c +++ b/usr/src/boot/sys/boot/efi/libefi/env.c @@ -28,6 +28,7 @@ #include <stand.h> #include <string.h> #include <efi.h> +#include <efichar.h> #include <efilib.h> #include <efigpt.h> /* Partition GUIDS */ #include <Guid/MemoryTypeInformation.h> @@ -46,6 +47,7 @@ static struct efi_uuid_mapping { EFI_GUID efi_guid; } efi_uuid_mapping[] = { { .efi_guid_name = "global", .efi_guid = EFI_GLOBAL_VARIABLE }, + { .efi_guid_name = "illumos", .efi_guid = ILLUMOS_BOOT_VAR_GUID }, /* EFI Systab entry names. */ { .efi_guid_name = "MPS Table", .efi_guid = MPS_TABLE_GUID }, { .efi_guid_name = "ACPI Table", .efi_guid = ACPI_TABLE_GUID }, @@ -102,12 +104,12 @@ static struct efi_uuid_mapping { { .efi_guid_name = "loaded image device path", .efi_guid = EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL_GUID }, { .efi_guid_name = "ISA io", .efi_guid = EFI_ISA_IO_PROTOCOL_GUID }, - { .efi_guid_name = "IDE controller init", + { .efi_guid_name = "IDE controller init", .efi_guid = EFI_IDE_CONTROLLER_INIT_PROTOCOL_GUID }, - { .efi_guid_name = "ISA ACPI", .efi_guid = EFI_ISA_ACPI_PROTOCOL_GUID }, - { .efi_guid_name = "PCI", .efi_guid = EFI_PCI_IO_PROTOCOL_GUID }, - { .efi_guid_name = "PCI root", .efi_guid = EFI_PCI_ROOT_IO_GUID }, - { .efi_guid_name = "PCI enumeration", + { .efi_guid_name = "ISA ACPI", .efi_guid = EFI_ISA_ACPI_PROTOCOL_GUID }, + { .efi_guid_name = "PCI", .efi_guid = EFI_PCI_IO_PROTOCOL_GUID }, + { .efi_guid_name = "PCI root", .efi_guid = EFI_PCI_ROOT_IO_GUID }, + { .efi_guid_name = "PCI enumeration", .efi_guid = EFI_PCI_ENUMERATION_COMPLETE_GUID }, { .efi_guid_name = "Driver diagnostics", .efi_guid = EFI_DRIVER_DIAGNOSTICS_PROTOCOL_GUID }, @@ -443,24 +445,43 @@ efi_print_mem_type(const CHAR16 *varnamearg, uint8_t *data, UINTN datasz) return (CMD_OK); } -/* Print global variables. */ +/* + * Print illumos variables. + * We have LoaderPath and LoaderDev as CHAR16 strings. + */ static int -efi_print_global(const CHAR16 *varnamearg, uint8_t *data, UINTN datasz) +efi_print_illumos(const CHAR16 *varnamearg, uint8_t *data, UINTN datasz) { - int len; int rv = -1; - char *var; + char *var = NULL; + + if (ucs2_to_utf8(varnamearg, &var) != 0) + return (CMD_ERROR); + + if (strcmp("LoaderPath", var) == 0 || + strcmp("LoaderDev", var) == 0) { + printf(" = "); + printf("%S", (CHAR16 *)data); + + if (pager_output("\n")) + rv = CMD_WARN; + else + rv = CMD_OK; + } - for (len = 0; varnamearg[len] != 0; len++) - ; + free(var); + return (rv); +} - if (len == 0) - return (CMD_OK); - len++; +/* Print global variables. */ +static int +efi_print_global(const CHAR16 *varnamearg, uint8_t *data, UINTN datasz) +{ + int rv = -1; + char *var = NULL; - if ((var = malloc(len)) == NULL) + if (ucs2_to_utf8(varnamearg, &var) != 0) return (CMD_ERROR); - cpy16to8(varnamearg, var, len); if (strcmp("AuditMode", var) == 0) { printf(" = "); @@ -667,6 +688,8 @@ efi_print_var(CHAR16 *varnamearg, EFI_GUID *matchguid, int lflag) if (lflag == 0) { if (strcmp(str, "global") == 0) rv = efi_print_global(varnamearg, data, datasz); + else if (strcmp(str, "illumos") == 0) + rv = efi_print_illumos(varnamearg, data, datasz); else if (strcmp(str, EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME) == 0) rv = efi_print_mem_type(varnamearg, data, datasz); |