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