efi: Use abuf when reading EFI variables

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>
This commit is contained in:
Simon Glass
2025-08-27 13:52:28 -06:00
parent b0025aa2b0
commit f73b3aaab8
2 changed files with 56 additions and 21 deletions

View File

@@ -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;
u64 time;
int 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;
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)

View File

@@ -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 */