
From: Simon Glass <sjg@chromium.org> The abuf interface provides a nicer abstraction of the data and size of EFI variables. Create a new efi_read_var() function and export it so it can be used elsewhere. Adjust the existing efi_dump_single_var() to use it. Signed-off-by: Simon Glass <sjg@chromium.org> --- cmd/nvedit_efi.c | 62 ++++++++++++++++++++++++++++++++---------------- include/efi.h | 15 ++++++++++++ 2 files changed, 56 insertions(+), 21 deletions(-) diff --git a/cmd/nvedit_efi.c b/cmd/nvedit_efi.c index 5616e73bcfd..45d6a8ef67a 100644 --- a/cmd/nvedit_efi.c +++ b/cmd/nvedit_efi.c @@ -5,6 +5,7 @@ * Copyright (c) 2018 AKASHI Takahiro, Linaro Limited */ +#include <abuf.h> #include <charset.h> #include <command.h> #include <efi_loader.h> @@ -50,6 +51,36 @@ struct var_info { efi_guid_t guid; }; +int efi_read_var(const u16 *name, const efi_guid_t *guid, u32 *attrp, + struct abuf *buf, u64 *timep) +{ + efi_uintn_t size; + efi_status_t eret; + u32 attr; + u64 time; + + abuf_init(buf); + size = 0; + eret = efi_get_variable_int(name, guid, &attr, &size, NULL, &time); + if (eret == EFI_BUFFER_TOO_SMALL) { + if (!abuf_realloc(buf, size)) + return -ENOMEM; + + eret = efi_get_variable_int(name, guid, &attr, &size, buf->data, + &time); + } + if (eret == EFI_NOT_FOUND) + return -ENOENT; + if (eret != EFI_SUCCESS) + return -EBADF; + if (attrp) + *attrp = attr; + if (timep) + *timep = time; + + return 0; +} + /** * efi_dump_single_var() - show information about a UEFI variable * @@ -63,30 +94,19 @@ struct var_info { static void efi_dump_single_var(u16 *name, const efi_guid_t *guid, bool verbose, bool nodump) { - u32 attributes; - u8 *data; - u64 time; struct rtc_time tm; - efi_uintn_t size; + u32 attributes; + struct abuf buf; int count, i; - efi_status_t ret; - - data = NULL; - size = 0; - ret = efi_get_variable_int(name, guid, &attributes, &size, data, &time); - if (ret == EFI_BUFFER_TOO_SMALL) { - data = malloc(size); - if (!data) - goto out; + u64 time; + int ret; - ret = efi_get_variable_int(name, guid, &attributes, &size, - data, &time); - } - if (ret == EFI_NOT_FOUND) { + ret = efi_read_var(name, guid, &attributes, &buf, &time); + if (ret == -ENOENT) { printf("Error: \"%ls\" not defined\n", name); goto out; } - if (ret != EFI_SUCCESS) + if (ret) goto out; if (verbose) { @@ -103,16 +123,16 @@ static void efi_dump_single_var(u16 *name, const efi_guid_t *guid, count++; puts(efi_var_attrs[i].text); } - printf(", DataSize = 0x%zx\n", size); + printf(", DataSize = 0x%zx\n", buf.size); if (!nodump) print_hex_dump(" ", DUMP_PREFIX_OFFSET, 16, 1, - data, size, true); + buf.data, buf.size, true); } else { printf("%ls\n", name); } out: - free(data); + abuf_uninit(&buf); } static bool match_name(int argc, char *const argv[], u16 *var_name16) diff --git a/include/efi.h b/include/efi.h index c07717811da..07d07050c01 100644 --- a/include/efi.h +++ b/include/efi.h @@ -23,6 +23,7 @@ #include <net.h> #endif +struct abuf; struct udevice; /* Type INTN in UEFI specification */ @@ -863,4 +864,18 @@ efi_status_t efi_run_image(void *source_buffer, efi_uintn_t source_size, int efi_dp_from_bootdev(const struct udevice *dev, const struct efi_device_path **dpp); +/** + * efi_read_var() - Read an EFI variable + * + * @name: Name of variable to read + * @guid: GUID for the variable + * @attrp: Returns variable attributes if non-NULL, on success + * @buf: Returns allocated buffer containing the value + * @timep: Returns the timestamp for the variable if non_NULL + * Return: 0 if OK, -ENOENT if the variable was not found, -EBADF if something + * went wrong when reading + */ +int efi_read_var(const u16 *name, const efi_guid_t *guid, u32 *attrp, + struct abuf *buf, u64 *timep); + #endif /* _LINUX_EFI_H */ -- 2.43.0