These functions have nothing specific to the payload apart from hardcoding RT. Make use of the new efi_get_runtime_services(), so the code is equally usable from the upcoming loader support.
Signed-off-by: Ahmad Fatoum <[email protected]> --- drivers/efi/efi-device.c | 1 + efi/Makefile | 2 +- efi/efivar.c | 130 ++++++++++++++++++++++++++++++++++++++ efi/payload/handover.c | 1 + efi/payload/image.c | 1 + efi/payload/init.c | 102 +----------------------------- include/efi/efi-mode.h | 1 + include/efi/efi-payload.h | 13 +--- include/efi/variable.h | 23 +++++++ 9 files changed, 160 insertions(+), 114 deletions(-) create mode 100644 efi/efivar.c create mode 100644 include/efi/variable.h diff --git a/drivers/efi/efi-device.c b/drivers/efi/efi-device.c index 78f42a463400..1ddf01658ee9 100644 --- a/drivers/efi/efi-device.c +++ b/drivers/efi/efi-device.c @@ -18,6 +18,7 @@ #include <efi.h> #include <efi/efi-payload.h> #include <efi/efi-device.h> +#include <efi/variable.h> #include <efi/device-path.h> #include <linux/err.h> diff --git a/efi/Makefile b/efi/Makefile index 2b188bafa0a4..508c07c9b536 100644 --- a/efi/Makefile +++ b/efi/Makefile @@ -3,4 +3,4 @@ obj-$(CONFIG_EFI_PAYLOAD) += payload/ obj-$(CONFIG_EFI_GUID) += guid.o obj-$(CONFIG_EFI_DEVICEPATH) += devicepath.o -obj-y += errno.o efivar-filename.o +obj-y += errno.o efivar.o efivar-filename.o diff --git a/efi/efivar.c b/efi/efivar.c new file mode 100644 index 000000000000..a51f3b2d1d8e --- /dev/null +++ b/efi/efivar.c @@ -0,0 +1,130 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * init.c - barebox EFI payload support + * + * Copyright (c) 2014 Sascha Hauer <[email protected]>, Pengutronix + */ + +#define pr_fmt(fmt) "efi-var: " fmt + +#include <efi/efi-mode.h> +#include <efi/variable.h> +#include <efi.h> +#include <efi/efi-util.h> +#include <efi/variable.h> +#include <wchar.h> +#include <xfuncs.h> +#include <linux/sprintf.h> + +void *efi_get_variable(char *name, efi_guid_t *vendor, int *var_size) +{ + struct efi_runtime_services *rt = efi_get_runtime_services(); + efi_status_t efiret; + void *buf; + size_t size = 0; + s16 *name16; + + if (!rt) + return ERR_PTR(-ENODEV); + + name16 = xstrdup_char_to_wchar(name); + + efiret = rt->get_variable(name16, vendor, NULL, &size, NULL); + + if (EFI_ERROR(efiret) && efiret != EFI_BUFFER_TOO_SMALL) { + buf = ERR_PTR(-efi_errno(efiret)); + goto out; + } + + buf = malloc(size); + if (!buf) { + buf = ERR_PTR(-ENOMEM); + goto out; + } + + efiret = rt->get_variable(name16, vendor, NULL, &size, buf); + if (EFI_ERROR(efiret)) { + free(buf); + buf = ERR_PTR(-efi_errno(efiret)); + goto out; + } + + if (var_size) + *var_size = size; + +out: + free(name16); + + return buf; +} + +int efi_set_variable(char *name, efi_guid_t *vendor, uint32_t attributes, + void *buf, size_t size) +{ + struct efi_runtime_services *rt = efi_get_runtime_services(); + efi_status_t efiret = EFI_SUCCESS; + s16 *name16; + + if (!rt) + return -ENODEV; + + name16 = xstrdup_char_to_wchar(name); + + efiret = rt->set_variable(name16, vendor, attributes, size, buf); + + free(name16); + + return -efi_errno(efiret); +} + +int efi_set_variable_usec(char *name, efi_guid_t *vendor, uint64_t usec) +{ + char buf[20]; + wchar_t buf16[40]; + + snprintf(buf, sizeof(buf), "%lld", usec); + strcpy_char_to_wchar(buf16, buf); + + return efi_set_variable(name, vendor, + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, buf16, + (strlen(buf)+1) * sizeof(wchar_t)); +} + +int efi_set_variable_printf(char *name, efi_guid_t *vendor, const char *fmt, ...) +{ + va_list args; + char *buf; + wchar_t *buf16; + + va_start(args, fmt); + buf = xvasprintf(fmt, args); + va_end(args); + buf16 = xstrdup_char_to_wchar(buf); + + return efi_set_variable(name, vendor, + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, buf16, + (strlen(buf)+1) * sizeof(wchar_t)); + free(buf); + free(buf16); +} + +int efi_set_variable_uint64_le(char *name, efi_guid_t *vendor, uint64_t value) +{ + uint8_t buf[8]; + + buf[0] = (uint8_t)(value >> 0U & 0xFF); + buf[1] = (uint8_t)(value >> 8U & 0xFF); + buf[2] = (uint8_t)(value >> 16U & 0xFF); + buf[3] = (uint8_t)(value >> 24U & 0xFF); + buf[4] = (uint8_t)(value >> 32U & 0xFF); + buf[5] = (uint8_t)(value >> 40U & 0xFF); + buf[6] = (uint8_t)(value >> 48U & 0xFF); + buf[7] = (uint8_t)(value >> 56U & 0xFF); + + return efi_set_variable(name, vendor, + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, buf, + sizeof(buf)); +} diff --git a/efi/payload/handover.c b/efi/payload/handover.c index 68180d820e53..0bbac598542d 100644 --- a/efi/payload/handover.c +++ b/efi/payload/handover.c @@ -29,6 +29,7 @@ #include <wchar.h> #include <efi/efi-payload.h> #include <efi/efi-device.h> +#include <efi/variable.h> #include "image.h" diff --git a/efi/payload/image.c b/efi/payload/image.c index ed4307aab909..2dd545fc0d79 100644 --- a/efi/payload/image.c +++ b/efi/payload/image.c @@ -27,6 +27,7 @@ #include <wchar.h> #include <efi/efi-payload.h> #include <efi/efi-device.h> +#include <efi/variable.h> #include "image.h" diff --git a/efi/payload/init.c b/efi/payload/init.c index 5b827c57ed1f..7e407991b4a0 100644 --- a/efi/payload/init.c +++ b/efi/payload/init.c @@ -36,6 +36,7 @@ #include <envfs.h> #include <efi/efi-payload.h> #include <efi/efi-device.h> +#include <efi/variable.h> #include <libfile.h> #include <state.h> #include <bbu.h> @@ -48,107 +49,6 @@ efi_handle_t efi_parent_image; struct efi_device_path *efi_device_path; struct efi_loaded_image *efi_loaded_image; -void *efi_get_variable(char *name, efi_guid_t *vendor, int *var_size) -{ - efi_status_t efiret; - void *buf; - size_t size = 0; - s16 *name16 = xstrdup_char_to_wchar(name); - - efiret = RT->get_variable(name16, vendor, NULL, &size, NULL); - - if (EFI_ERROR(efiret) && efiret != EFI_BUFFER_TOO_SMALL) { - buf = ERR_PTR(-efi_errno(efiret)); - goto out; - } - - buf = malloc(size); - if (!buf) { - buf = ERR_PTR(-ENOMEM); - goto out; - } - - efiret = RT->get_variable(name16, vendor, NULL, &size, buf); - if (EFI_ERROR(efiret)) { - free(buf); - buf = ERR_PTR(-efi_errno(efiret)); - goto out; - } - - if (var_size) - *var_size = size; - -out: - free(name16); - - return buf; -} - -int efi_set_variable(char *name, efi_guid_t *vendor, uint32_t attributes, - void *buf, size_t size) -{ - efi_status_t efiret = EFI_SUCCESS; - s16 *name16 = xstrdup_char_to_wchar(name); - - efiret = RT->set_variable(name16, vendor, attributes, size, buf); - - free(name16); - - return -efi_errno(efiret); -} - -int efi_set_variable_usec(char *name, efi_guid_t *vendor, uint64_t usec) -{ - char buf[20]; - wchar_t buf16[40]; - - snprintf(buf, sizeof(buf), "%lld", usec); - strcpy_char_to_wchar(buf16, buf); - - return efi_set_variable(name, vendor, - EFI_VARIABLE_BOOTSERVICE_ACCESS | - EFI_VARIABLE_RUNTIME_ACCESS, buf16, - (strlen(buf)+1) * sizeof(wchar_t)); -} - -static int efi_set_variable_printf(char *name, efi_guid_t *vendor, const char *fmt, ...) -{ - va_list args; - char *buf; - wchar_t *buf16; - - va_start(args, fmt); - buf = xvasprintf(fmt, args); - va_end(args); - buf16 = xstrdup_char_to_wchar(buf); - - return efi_set_variable(name, vendor, - EFI_VARIABLE_BOOTSERVICE_ACCESS | - EFI_VARIABLE_RUNTIME_ACCESS, buf16, - (strlen(buf)+1) * sizeof(wchar_t)); - free(buf); - free(buf16); -} - -static int efi_set_variable_uint64_le(char *name, efi_guid_t *vendor, uint64_t value) -{ - uint8_t buf[8]; - - buf[0] = (uint8_t)(value >> 0U & 0xFF); - buf[1] = (uint8_t)(value >> 8U & 0xFF); - buf[2] = (uint8_t)(value >> 16U & 0xFF); - buf[3] = (uint8_t)(value >> 24U & 0xFF); - buf[4] = (uint8_t)(value >> 32U & 0xFF); - buf[5] = (uint8_t)(value >> 40U & 0xFF); - buf[6] = (uint8_t)(value >> 48U & 0xFF); - buf[7] = (uint8_t)(value >> 56U & 0xFF); - - return efi_set_variable(name, vendor, - EFI_VARIABLE_BOOTSERVICE_ACCESS | - EFI_VARIABLE_RUNTIME_ACCESS, buf, - sizeof(buf)); -} - struct efi_boot { u32 attributes; u16 file_path_len; diff --git a/include/efi/efi-mode.h b/include/efi/efi-mode.h index 696ab78acd50..f398d80d932f 100644 --- a/include/efi/efi-mode.h +++ b/include/efi/efi-mode.h @@ -5,6 +5,7 @@ #include <linux/stddef.h> #include <linux/types.h> +#include <efi/types.h> struct efi_boot_services; struct efi_runtime_services; diff --git a/include/efi/efi-payload.h b/include/efi/efi-payload.h index 337471117d5a..644620062aad 100644 --- a/include/efi/efi-payload.h +++ b/include/efi/efi-payload.h @@ -5,6 +5,7 @@ #include <efi/types.h> #include <efi/efi-util.h> #include <efi/memtype.h> +#include <efi/variable.h> struct efi_system_table; struct efi_loaded_image; @@ -19,18 +20,6 @@ extern efi_handle_t efi_parent_image; extern struct efi_device_path *efi_device_path; extern struct efi_loaded_image *efi_loaded_image; -void *efi_get_variable(char *name, efi_guid_t *vendor, int *var_size); - -static inline void *efi_get_global_var(char *name, int *var_size) -{ - extern efi_guid_t efi_global_variable_guid; - return efi_get_variable(name, &efi_global_variable_guid, var_size); -} - -int efi_set_variable(char *name, efi_guid_t *vendor, uint32_t attributes, - void *buf, size_t size); -int efi_set_variable_usec(char *name, efi_guid_t *vendor, uint64_t usec); - void *efi_earlymem_alloc(const struct efi_system_table *sys_table, size_t memsize, enum efi_memory_type mem_type); diff --git a/include/efi/variable.h b/include/efi/variable.h new file mode 100644 index 000000000000..c53b295eefe8 --- /dev/null +++ b/include/efi/variable.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __EFI_VARIABLE_H +#define __EFI_VARIABLE_H + +#include <efi/types.h> + +void *efi_get_variable(char *name, efi_guid_t *vendor, int *var_size); + +int efi_set_variable(char *name, efi_guid_t *vendor, uint32_t attributes, + void *buf, size_t size); + +int efi_set_variable_usec(char *name, efi_guid_t *vendor, uint64_t usec); +int efi_set_variable_printf(char *name, efi_guid_t *vendor, const char *fmt, ...); +int efi_set_variable_uint64_le(char *name, efi_guid_t *vendor, uint64_t value); + +static inline void *efi_get_global_var(char *name, int *var_size) +{ + extern efi_guid_t efi_global_variable_guid; + return efi_get_variable(name, &efi_global_variable_guid, var_size); +} + +#endif -- 2.47.3
