summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr/src/boot/sys/boot/efi/include/efi.h5
-rw-r--r--usr/src/boot/sys/boot/efi/include/efilib.h13
-rw-r--r--usr/src/boot/sys/boot/efi/libefi/Makefile1
-rw-r--r--usr/src/boot/sys/boot/efi/libefi/efienv.c85
-rw-r--r--usr/src/boot/sys/boot/efi/libefi/env.c55
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);