summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Kconfig11
-rw-r--r--lib/abuf.c58
-rw-r--r--lib/binman.c16
-rw-r--r--lib/ecdsa/ecdsa-libcrypto.c176
-rw-r--r--lib/efi_loader/Kconfig9
-rw-r--r--lib/efi_loader/Makefile2
-rw-r--r--lib/efi_loader/dbginfodump.c356
-rw-r--r--lib/efi_loader/efi_bootmgr.c1
-rw-r--r--lib/efi_loader/efi_boottime.c9
-rw-r--r--lib/efi_loader/efi_debug_support.c183
-rw-r--r--lib/efi_loader/efi_device_path.c1
-rw-r--r--lib/efi_loader/efi_disk.c39
-rw-r--r--lib/efi_loader/efi_file.c2
-rw-r--r--lib/efi_loader/efi_firmware.c1
-rw-r--r--lib/efi_loader/efi_http.c9
-rw-r--r--lib/efi_loader/efi_memory.c80
-rw-r--r--lib/efi_loader/efi_net.c3
-rw-r--r--lib/efi_loader/efi_setup.c18
-rw-r--r--lib/efi_selftest/Makefile2
-rw-r--r--lib/efi_selftest/efi_selftest_block_device.c30
-rw-r--r--lib/efi_selftest/efi_selftest_debug_support.c40
-rw-r--r--lib/fwu_updates/fwu_v1.c1
-rw-r--r--lib/fwu_updates/fwu_v2.c1
-rw-r--r--lib/linux_string.c6
-rw-r--r--lib/lmb.c184
-rw-r--r--lib/lwip/Makefile1
-rw-r--r--lib/lwip/u-boot/arch/cc.h4
-rw-r--r--lib/lwip/u-boot/lwipopts.h8
-rw-r--r--lib/mbedtls/external/mbedtls/library/ecp_curves_new.c46
-rw-r--r--lib/of_live.c3
-rw-r--r--lib/rsa/rsa-sign.c4
-rw-r--r--lib/slre.c78
-rw-r--r--lib/tiny-printf.c48
-rw-r--r--lib/tpm-v2.c2
-rw-r--r--lib/trace.c4
35 files changed, 1243 insertions, 193 deletions
diff --git a/lib/Kconfig b/lib/Kconfig
index b2aecd8a49e..6a89f797bef 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -253,6 +253,14 @@ config VPL_USE_TINY_PRINTF
The supported format specifiers are %c, %s, %u/%d and %x.
+config SPL_USE_TINY_PRINTF_POINTER_SUPPORT
+ bool "Extend tiny printf with the pointer formatting %p"
+ depends on SPL_USE_TINY_PRINTF
+ help
+ This option enables the formatting of pointers %p. It supports
+ %p and %pa / %pap. If this option is selected by SPL_NET
+ it also supports the formatting with %pm, %pM and %pI4.
+
config PANIC_HANG
bool "Do not reset the system on fatal error"
help
@@ -275,7 +283,8 @@ config REGEX
choice
prompt "Pseudo-random library support type"
depends on NET_RANDOM_ETHADDR || RANDOM_UUID || CMD_UUID || \
- RNG_SANDBOX || UT_LIB && AES || FAT_WRITE
+ RNG_SANDBOX || UT_LIB && AES || FAT_WRITE || CMD_BOOTP || \
+ CMD_DHCP || CMD_DHCP6
default LIB_RAND
help
Select the library to provide pseudo-random number generator
diff --git a/lib/abuf.c b/lib/abuf.c
index 61adf7fc6b1..3a2fd1782e9 100644
--- a/lib/abuf.c
+++ b/lib/abuf.c
@@ -10,8 +10,11 @@
#include <malloc.h>
#include <mapmem.h>
#include <string.h>
+#include <vsprintf.h>
#endif
+#include <errno.h>
+#include <stdarg.h>
#include <abuf.h>
void abuf_set(struct abuf *abuf, void *data, size_t size)
@@ -119,6 +122,61 @@ void abuf_init_set(struct abuf *abuf, void *data, size_t size)
abuf_set(abuf, data, size);
}
+bool abuf_init_size(struct abuf *buf, size_t size)
+{
+ abuf_init(buf);
+ if (!abuf_realloc(buf, size))
+ return false;
+
+ return true;
+}
+
+bool abuf_copy(const struct abuf *old, struct abuf *copy)
+{
+ char *data;
+
+ data = malloc(old->size);
+ if (!data)
+ return false;
+ memcpy(data, old->data, old->size);
+ abuf_init_set(copy, data, old->size);
+ copy->alloced = true;
+
+ return true;
+}
+
+int abuf_printf(struct abuf *buf, const char *fmt, ...)
+{
+ int maxlen = buf->size;
+ va_list args;
+ int len;
+
+ va_start(args, fmt);
+ len = vsnprintf(buf->data, buf->size, fmt, args);
+ va_end(args);
+
+ /* add the terminator */
+ len++;
+
+ if (len > 4096)
+ return -E2BIG;
+ if (len > maxlen) {
+ /* make more space and try again */
+ maxlen = len;
+ if (!abuf_realloc(buf, maxlen))
+ return -ENOMEM;
+ va_start(args, fmt);
+ len = vsnprintf(buf->data, maxlen, fmt, args);
+ va_end(args);
+
+ /* check there isn't anything strange going on */
+ if (len > maxlen)
+ return -EFAULT;
+ }
+
+ return len;
+}
+
void abuf_init_const(struct abuf *abuf, const void *data, size_t size)
{
/* for now there is no flag indicating that the abuf data is constant */
diff --git a/lib/binman.c b/lib/binman.c
index 9047f5275f3..a594fe4c2ca 100644
--- a/lib/binman.c
+++ b/lib/binman.c
@@ -16,12 +16,15 @@
* struct binman_info - Information needed by the binman library
*
* @image: Node describing the image we are running from
+ * @skip_at_start: Number of bytes skipped at the start of the image. This is
+ * the value of the skip-at-start property for the image
* @rom_offset: Offset from an image_pos to the memory-mapped address, or
* ROM_OFFSET_NONE if the ROM is not memory-mapped. Can be positive or
* negative
*/
struct binman_info {
ofnode image;
+ uint skip_at_start;
int rom_offset;
};
@@ -80,7 +83,14 @@ static int binman_entry_find_internal(ofnode node, const char *name,
int binman_entry_find(const char *name, struct binman_entry *entry)
{
- return binman_entry_find_internal(binman->image, name, entry);
+ int ret;
+
+ ret = binman_entry_find_internal(binman->image, name, entry);
+ if (ret)
+ return log_msg_ret("bef", ret);
+ entry->image_pos -= binman->skip_at_start;
+
+ return 0;
}
int binman_entry_map(ofnode parent, const char *name, void **bufp, int *sizep)
@@ -107,7 +117,7 @@ ofnode binman_section_find_node(const char *name)
void binman_set_rom_offset(int rom_offset)
{
- binman->rom_offset = rom_offset;
+ binman->rom_offset = rom_offset - binman->skip_at_start;
}
int binman_get_rom_offset(void)
@@ -140,10 +150,12 @@ int binman_init(void)
binman = malloc(sizeof(struct binman_info));
if (!binman)
return log_msg_ret("space for binman", -ENOMEM);
+ memset(binman, '\0', sizeof(struct binman_info));
ret = find_image_node(&binman->image);
if (ret)
return log_msg_ret("node", -ENOENT);
binman_set_rom_offset(ROM_OFFSET_NONE);
+ ofnode_read_u32(binman->image, "skip-at-start", &binman->skip_at_start);
log_debug("binman: Selected image node '%s'\n",
ofnode_get_name(binman->image));
diff --git a/lib/ecdsa/ecdsa-libcrypto.c b/lib/ecdsa/ecdsa-libcrypto.c
index f0095e9dbcf..7415d685ee1 100644
--- a/lib/ecdsa/ecdsa-libcrypto.c
+++ b/lib/ecdsa/ecdsa-libcrypto.c
@@ -34,6 +34,112 @@ struct signer {
void *signature; /* Pointer to output signature. Do not free()!*/
};
+struct ecdsa_public_key {
+ const char *curve_name;
+ const uint8_t *x;
+ const uint8_t *y;
+ int size_bits;
+};
+
+static int fdt_get_key(struct ecdsa_public_key *key, const void *fdt, int node)
+{
+ int x_len;
+ int y_len;
+
+ key->curve_name = fdt_getprop(fdt, node, "ecdsa,curve", NULL);
+ if (!key->curve_name)
+ return -ENOMSG;
+
+ if (!strcmp(key->curve_name, "prime256v1"))
+ key->size_bits = 256;
+ else if (!strcmp(key->curve_name, "secp384r1"))
+ key->size_bits = 384;
+ else
+ return -EINVAL;
+
+ key->x = fdt_getprop(fdt, node, "ecdsa,x-point", &x_len);
+ key->y = fdt_getprop(fdt, node, "ecdsa,y-point", &y_len);
+
+ if (!key->x || !key->y)
+ return -EINVAL;
+
+ if (x_len != key->size_bits / 8 || y_len != key->size_bits / 8)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int read_key_from_fdt(struct signer *ctx, const void *fdt, int node)
+{
+ struct ecdsa_public_key pubkey;
+ const EC_GROUP *group;
+ EC_POINT *point;
+ EC_KEY *ec_key;
+ int ret;
+ int nid;
+ int len;
+
+ ret = fdt_get_key(&pubkey, fdt, node);
+ if (ret) {
+ fprintf(stderr, "Failed to parse ECDSA key from FDT node %d (ret=%d)\n", node, ret);
+ return ret;
+ }
+
+ if (!strcmp(pubkey.curve_name, "prime256v1")) {
+ nid = NID_X9_62_prime256v1;
+ } else if (!strcmp(pubkey.curve_name, "secp384r1")) {
+ nid = NID_secp384r1;
+ } else {
+ fprintf(stderr, "Unsupported curve name: '%s'\n", pubkey.curve_name);
+ return -EINVAL;
+ }
+
+ fprintf(stderr, "Loading ECDSA key: curve=%s, bits=%d\n", pubkey.curve_name,
+ pubkey.size_bits);
+
+ ec_key = EC_KEY_new_by_curve_name(nid);
+ if (!ec_key) {
+ fprintf(stderr, "Failed to allocate EC_KEY for curve %s\n", pubkey.curve_name);
+ return -ENOMEM;
+ }
+
+ group = EC_KEY_get0_group(ec_key);
+ point = EC_POINT_new(group);
+ if (!point) {
+ fprintf(stderr, "Failed to allocate EC_POINT\n");
+ EC_KEY_free(ec_key);
+ return -ENOMEM;
+ }
+
+ len = pubkey.size_bits / 8;
+
+ uint8_t buf[1 + len * 2];
+
+ /* uncompressed */
+ buf[0] = 0x04;
+ memcpy(&buf[1], pubkey.x, len);
+ memcpy(&buf[1 + len], pubkey.y, len);
+ if (!EC_POINT_oct2point(group, point, buf, sizeof(buf), NULL)) {
+ fprintf(stderr, "Failed to convert (x,y) point to EC_POINT\n");
+ EC_POINT_free(point);
+ EC_KEY_free(ec_key);
+ return -EINVAL;
+ }
+
+ if (!EC_KEY_set_public_key(ec_key, point)) {
+ fprintf(stderr, "Failed to set EC_POINT as public key\n");
+ EC_POINT_free(point);
+ EC_KEY_free(ec_key);
+ return -EINVAL;
+ }
+
+ fprintf(stderr, "Successfully loaded ECDSA key from FDT node %d\n", node);
+ EC_POINT_free(point);
+ ctx->ecdsa_key = ec_key;
+
+ return 0;
+}
+
static int alloc_ctx(struct signer *ctx, const struct image_sign_info *info)
{
memset(ctx, 0, sizeof(*ctx));
@@ -153,6 +259,72 @@ static int read_key(struct signer *ctx, const char *key_name)
return (ctx->ecdsa_key) ? 0 : -EINVAL;
}
+static int load_key_from_fdt(struct signer *ctx, const struct image_sign_info *info)
+{
+ const void *fdt = info->fdt_blob;
+ char name[128];
+ int sig_node;
+ int key_node;
+ int key_len;
+ int ret;
+
+ if (!fdt)
+ return -EINVAL;
+
+ ret = alloc_ctx(ctx, info);
+ if (ret)
+ return ret;
+
+ sig_node = fdt_subnode_offset(fdt, 0, FIT_SIG_NODENAME);
+ if (sig_node < 0) {
+ fprintf(stderr, "No /signature node found\n");
+ return -ENOENT;
+ }
+
+ /* Case 1: explicitly specified key node */
+ if (info->required_keynode >= 0) {
+ ret = read_key_from_fdt(ctx, fdt, info->required_keynode);
+ if (ret == 0)
+ goto check_key_len;
+
+ fprintf(stderr, "Failed to load required keynode %d\n", info->required_keynode);
+ return ret;
+ }
+
+ /* Case 2: use keyname hint */
+ if (info->keyname) {
+ snprintf(name, sizeof(name), "%s", info->keyname);
+ key_node = fdt_subnode_offset(fdt, sig_node, name);
+ if (key_node >= 0) {
+ ret = read_key_from_fdt(ctx, fdt, key_node);
+ if (ret == 0)
+ goto check_key_len;
+
+ fprintf(stderr, "Key hint '%s' found but failed to load\n", info->keyname);
+ }
+ }
+
+ /* Case 3: try all subnodes */
+ fdt_for_each_subnode(key_node, fdt, sig_node) {
+ ret = read_key_from_fdt(ctx, fdt, key_node);
+ if (ret == 0)
+ goto check_key_len;
+ }
+
+ fprintf(stderr, "Failed to load any usable ECDSA key from FDT\n");
+ return -EINVAL;
+
+check_key_len:
+ key_len = ecdsa_key_size_bytes(ctx->ecdsa_key);
+ if (key_len != info->crypto->key_len) {
+ fprintf(stderr, "Expected %u-bit key, got %u-bit key\n",
+ info->crypto->key_len * 8, key_len * 8);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
/* Prepare a 'signer' context that's ready to sign and verify. */
static int prepare_ctx(struct signer *ctx, const struct image_sign_info *info)
{
@@ -161,7 +333,9 @@ static int prepare_ctx(struct signer *ctx, const struct image_sign_info *info)
memset(ctx, 0, sizeof(*ctx));
- if (info->keyfile) {
+ if (info->fdt_blob) {
+ return load_key_from_fdt(ctx, info);
+ } else if (info->keyfile) {
snprintf(kname, sizeof(kname), "%s", info->keyfile);
} else if (info->keydir && info->keyname) {
snprintf(kname, sizeof(kname), "%s/%s.pem", info->keydir,
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
index 3dadbc54b58..077466f01f0 100644
--- a/lib/efi_loader/Kconfig
+++ b/lib/efi_loader/Kconfig
@@ -71,6 +71,15 @@ config EFI_SECURE_BOOT
config EFI_SIGNATURE_SUPPORT
bool
+config EFI_DEBUG_SUPPORT
+ bool "EFI Debug Support"
+ default y if !HAS_BOARD_SIZE_LIMIT
+ help
+ Select this option if you want to setup the EFI Debug Support
+ Table and the EFI_SYSTEM_TABLE_POINTER which is used by the debug
+ agent or an external debugger to determine loaded image information
+ in a quiescent manner.
+
menu "UEFI services"
config EFI_GET_TIME
diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile
index cf050e5385d..bfa607c8827 100644
--- a/lib/efi_loader/Makefile
+++ b/lib/efi_loader/Makefile
@@ -21,6 +21,7 @@ ifeq ($(CONFIG_GENERATE_ACPI_TABLE),)
apps-y += dtbdump
endif
apps-$(CONFIG_BOOTEFI_TESTAPP_COMPILE) += testapp
+apps-y += dbginfodump
obj-$(CONFIG_CMD_BOOTEFI_HELLO) += helloworld_efi.o
obj-$(CONFIG_EFI_BOOTMGR) += efi_bootmgr.o
@@ -70,6 +71,7 @@ obj-$(CONFIG_EFI_RISCV_BOOT_PROTOCOL) += efi_riscv.o
obj-$(CONFIG_EFI_LOAD_FILE2_INITRD) += efi_load_initrd.o
obj-$(CONFIG_EFI_SIGNATURE_SUPPORT) += efi_signature.o
obj-$(CONFIG_EFI_ECPT) += efi_conformance.o
+obj-$(CONFIG_EFI_DEBUG_SUPPORT) += efi_debug_support.o
EFI_VAR_SEED_FILE := $(subst $\",,$(CONFIG_EFI_VAR_SEED_FILE))
$(obj)/efi_var_seed.o: $(srctree)/$(EFI_VAR_SEED_FILE)
diff --git a/lib/efi_loader/dbginfodump.c b/lib/efi_loader/dbginfodump.c
new file mode 100644
index 00000000000..adbbd5060cc
--- /dev/null
+++ b/lib/efi_loader/dbginfodump.c
@@ -0,0 +1,356 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright 2025, Heinrich Schuchardt <xypron.glpk@gmx.de>
+ *
+ * dbginfodump.efi prints out the content of the EFI_DEBUG_IMAGE_INFO_TABLE.
+ */
+
+#include <efi_api.h>
+
+/**
+ * BUFFER_SIZE - size of the command line input buffer
+ */
+#define BUFFER_SIZE 64
+
+static struct efi_simple_text_output_protocol *cerr;
+static struct efi_simple_text_output_protocol *cout;
+static struct efi_simple_text_input_protocol *cin;
+static efi_handle_t handle;
+static struct efi_system_table *systable;
+static struct efi_boot_services *bs;
+
+static efi_guid_t guid_device_path_to_text_protocol =
+ EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID;
+
+static struct efi_device_path_to_text_protocol *device_path_to_text;
+
+/* EFI_DEBUG_IMAGE_INFO_TABLE_GUID */
+static const efi_guid_t dbg_info_guid =
+ EFI_GUID(0x49152E77, 0x1ADA, 0x4764, 0xB7, 0xA2,
+ 0x7A, 0xFE, 0xFE, 0xD9, 0x5E, 0x8B);
+
+/* EFI_DEBUG_IMAGE_INFO_NORMAL */
+struct dbg_info {
+ u32 type;
+ struct efi_loaded_image *info;
+ efi_handle_t handle;
+};
+
+/* FI_DEBUG_IMAGE_INFO_TABLE_HEADER */
+struct dbg_info_header {
+ u32 status;
+ u32 size;
+ struct dbg_info **info;
+};
+
+/**
+ * print() - print string
+ *
+ * @string: text
+ */
+static void print(u16 *string)
+{
+ cout->output_string(cout, string);
+}
+
+/**
+ * error() - print error string
+ *
+ * @string: error text
+ */
+static void error(u16 *string)
+{
+ cout->set_attribute(cout, EFI_LIGHTRED | EFI_BACKGROUND_BLACK);
+ print(string);
+ cout->set_attribute(cout, EFI_LIGHTBLUE | EFI_BACKGROUND_BLACK);
+}
+
+/**
+ * printu() - print unsigned
+ *
+ * @val: value to print
+ */
+static void printu(u32 val)
+{
+ u16 str[19] = u"0x";
+ u16 *ptr = &str[2];
+ u16 ch;
+
+ for (ssize_t i = 8 * sizeof(u32) - 4; i >= 0; i -= 4) {
+ ch = (val >> i & 0xf) + '0';
+ if (ch > '9')
+ ch += 'a' - '9' - 1;
+ *ptr++ = ch;
+ }
+ *ptr = 0;
+ print(str);
+}
+
+/**
+ * printp() - print pointer
+ *
+ * @p: pointer
+ */
+static void printp(void *p)
+{
+ u16 str[19] = u"0x";
+ u16 *ptr = &str[2];
+ u16 ch;
+
+ for (ssize_t i = 8 * sizeof(void *) - 4; i >= 0; i -= 4) {
+ ch = ((uintptr_t)p >> i & 0xf) + '0';
+ if (ch > '9')
+ ch += 'a' - '9' - 1;
+ *ptr++ = ch;
+ }
+ *ptr = 0;
+ print(str);
+}
+
+/**
+ * efi_input() - read string from console
+ *
+ * @buffer: input buffer
+ * @buffer_size: buffer size
+ * Return: status code
+ */
+static efi_status_t efi_input(u16 *buffer, efi_uintn_t buffer_size)
+{
+ struct efi_input_key key = {0};
+ efi_uintn_t index;
+ efi_uintn_t pos = 0;
+ u16 outbuf[2] = u" ";
+ efi_status_t ret;
+
+ /* Drain the console input */
+ ret = cin->reset(cin, true);
+ *buffer = 0;
+ for (;;) {
+ ret = bs->wait_for_event(1, &cin->wait_for_key, &index);
+ if (ret != EFI_SUCCESS)
+ continue;
+ ret = cin->read_key_stroke(cin, &key);
+ if (ret != EFI_SUCCESS)
+ continue;
+ switch (key.scan_code) {
+ case 0x17: /* Escape */
+ print(u"\r\nAborted\r\n");
+ return EFI_ABORTED;
+ default:
+ break;
+ }
+ switch (key.unicode_char) {
+ case 0x08: /* Backspace */
+ if (pos) {
+ buffer[pos--] = 0;
+ print(u"\b \b");
+ }
+ break;
+ case 0x0a: /* Linefeed */
+ case 0x0d: /* Carriage return */
+ print(u"\r\n");
+ return EFI_SUCCESS;
+ default:
+ break;
+ }
+ /* Ignore surrogate codes */
+ if (key.unicode_char >= 0xD800 && key.unicode_char <= 0xDBFF)
+ continue;
+ if (key.unicode_char >= 0x20 &&
+ pos < buffer_size - 1) {
+ *outbuf = key.unicode_char;
+ buffer[pos++] = key.unicode_char;
+ buffer[pos] = 0;
+ print(outbuf);
+ }
+ }
+}
+
+/**
+ * skip_whitespace() - skip over leading whitespace
+ *
+ * @pos: UTF-16 string
+ * Return: pointer to first non-whitespace
+ */
+static u16 *skip_whitespace(u16 *pos)
+{
+ for (; *pos && *pos <= 0x20; ++pos)
+ ;
+ return pos;
+}
+
+/**
+ * starts_with() - check if @string starts with @keyword
+ *
+ * @string: string to search for keyword
+ * @keyword: keyword to be searched
+ * Return: true fi @string starts with the keyword
+ */
+static bool starts_with(u16 *string, u16 *keyword)
+{
+ for (; *keyword; ++string, ++keyword) {
+ if (*string != *keyword)
+ return false;
+ }
+ return true;
+}
+
+/**
+ * do_help() - print help
+ */
+static void do_help(void)
+{
+ error(u"dump - print debug info table\r\n");
+ error(u"exit - exit the shell\r\n");
+}
+
+/**
+ * get_dbg_info_table() - get debug info table
+ *
+ * Return: debug info table or NULL
+ */
+static void *get_dbg_info(void)
+{
+ void *dbg = NULL;
+ efi_uintn_t i;
+
+ for (i = 0; i < systable->nr_tables; ++i) {
+ if (!memcmp(&systable->tables[i].guid, &dbg_info_guid,
+ sizeof(efi_guid_t))) {
+ dbg = systable->tables[i].table;
+ break;
+ }
+ }
+ return dbg;
+}
+
+/**
+ * print_info() - print loaded image protocol
+ */
+static void print_info(struct efi_loaded_image *info)
+{
+ print(u" Address: [");
+ printp(info->image_base);
+ print(u", ");
+ printp(info->image_base + info->image_size - 1);
+ print(u"]\r\n");
+ if (device_path_to_text && info->file_path) {
+ u16 *string;
+
+ string = device_path_to_text->convert_device_path_to_text(
+ info->file_path, true, false);
+ if (!string) {
+ error(u"ConvertDevicePathToText failed");
+ } else {
+ print(u" File: ");
+ print(string);
+ }
+ print(u"\r\n");
+ }
+}
+
+/**
+ * do_dump() - print debug info table
+ */
+static efi_status_t do_dump(void)
+{
+ struct dbg_info_header *dbg;
+ u32 count;
+
+ dbg = get_dbg_info();
+ if (!dbg) {
+ error(u"Debug info table not found\r\n");
+ return EFI_NOT_FOUND;
+ }
+ if (dbg->status & 0x01) {
+ error(u"Update in progress\r\n");
+ return EFI_LOAD_ERROR;
+ }
+ if (dbg->status & 0x02)
+ print(u"Modified\r\n");
+ print(u"Number of entries: ");
+ printu(dbg->size);
+ print(u"\r\n");
+
+ count = dbg->size;
+ for (u32 i = 0; count; ++i) {
+ struct dbg_info *info = dbg->info[i];
+
+ /*
+ * The EDK II implementation decreases the size field and
+ * writes a NULL value when deleting an entry which is not
+ * backed by the UEFI specification.
+ */
+ if (!info) {
+ print(u"Deleted entry\r\n");
+ continue;
+ }
+ --count;
+ print(u"Info type ");
+ printu(info->type);
+ print(u"\r\n");
+ if (info->type != 1)
+ continue;
+ print_info(info->info);
+ print(u" Handle: ");
+ printp(info->handle);
+ print(u"\r\n");
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ * efi_main() - entry point of the EFI application.
+ *
+ * @handle: handle of the loaded image
+ * @systab: system table
+ * Return: status code
+ */
+efi_status_t EFIAPI efi_main(efi_handle_t image_handle,
+ struct efi_system_table *systab)
+{
+ efi_status_t ret;
+
+ handle = image_handle;
+ systable = systab;
+ cerr = systable->std_err;
+ cout = systable->con_out;
+ cin = systable->con_in;
+ bs = systable->boottime;
+
+ cout->set_attribute(cout, EFI_LIGHTBLUE | EFI_BACKGROUND_BLACK);
+ cout->clear_screen(cout);
+ cout->set_attribute(cout, EFI_WHITE | EFI_BACKGROUND_BLACK);
+ print(u"Debug Info Table Dump\r\n=====================\r\n\r\n");
+ cout->set_attribute(cout, EFI_LIGHTBLUE | EFI_BACKGROUND_BLACK);
+
+ ret = bs->locate_protocol(&guid_device_path_to_text_protocol,
+ NULL, (void **)&device_path_to_text);
+ if (ret != EFI_SUCCESS) {
+ error(u"No device path to text protocol\r\n");
+ device_path_to_text = NULL;
+ }
+
+ for (;;) {
+ u16 command[BUFFER_SIZE];
+ u16 *pos;
+ efi_uintn_t ret;
+
+ print(u"=> ");
+ ret = efi_input(command, sizeof(command));
+ if (ret == EFI_ABORTED)
+ break;
+ pos = skip_whitespace(command);
+ if (starts_with(pos, u"exit"))
+ break;
+ else if (starts_with(pos, u"dump"))
+ do_dump();
+ else
+ do_help();
+ }
+
+ cout->set_attribute(cout, EFI_LIGHTGRAY | EFI_BACKGROUND_BLACK);
+ cout->clear_screen(cout);
+ return EFI_SUCCESS;
+}
diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c
index 83f4a3525bd..662993fb809 100644
--- a/lib/efi_loader/efi_bootmgr.c
+++ b/lib/efi_loader/efi_bootmgr.c
@@ -13,6 +13,7 @@
#include <dm.h>
#include <efi.h>
#include <efi_device_path.h>
+#include <env.h>
#include <log.h>
#include <malloc.h>
#include <net.h>
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index 24b0e52a2a2..ddc935d2240 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -58,7 +58,7 @@ static efi_handle_t current_image;
* restriction so we need to manually swap its and our view of that register on
* EFI callback entry/exit.
*/
-static volatile gd_t *efi_gd, *app_gd;
+static gd_t *efi_gd, *app_gd;
#endif
efi_status_t efi_uninstall_protocol
@@ -2130,6 +2130,11 @@ efi_status_t EFIAPI efi_load_image(bool boot_policy,
*image_handle = NULL;
free(info);
}
+
+ if (IS_ENABLED(CONFIG_EFI_DEBUG_SUPPORT) && *image_handle)
+ efi_core_new_debug_image_info_entry(EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL,
+ info,
+ *image_handle);
error:
return EFI_EXIT(ret);
}
@@ -3360,6 +3365,8 @@ efi_status_t EFIAPI efi_unload_image(efi_handle_t image_handle)
ret = EFI_INVALID_PARAMETER;
goto out;
}
+ if (IS_ENABLED(CONFIG_EFI_DEBUG_SUPPORT))
+ efi_core_remove_debug_image_info_entry(image_handle);
switch (efiobj->type) {
case EFI_OBJECT_TYPE_STARTED_IMAGE:
/* Call the unload function */
diff --git a/lib/efi_loader/efi_debug_support.c b/lib/efi_loader/efi_debug_support.c
new file mode 100644
index 00000000000..186bdbce750
--- /dev/null
+++ b/lib/efi_loader/efi_debug_support.c
@@ -0,0 +1,183 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * EFI debug support
+ *
+ * Copyright (c) 2025 Ying-Chun Liu, Linaro Ltd. <paul.liu@linaro.org>
+ */
+
+#include <efi_loader.h>
+#include <linux/sizes.h>
+#include <u-boot/crc.h>
+
+struct efi_system_table_pointer __efi_runtime_data * systab_pointer = NULL;
+
+struct efi_debug_image_info_table_header efi_m_debug_info_table_header = {
+ 0,
+ 0,
+ NULL
+};
+
+/* efi_m_max_table_entries is the maximum entries allocated for
+ * the efi_m_debug_info_table_header.efi_debug_image_info_table.
+ */
+static u32 efi_m_max_table_entries;
+
+#define EFI_DEBUG_TABLE_ENTRY_SIZE (sizeof(union efi_debug_image_info *))
+
+/**
+ * efi_initialize_system_table_pointer() - Initialize system table pointer
+ *
+ * Return: status code
+ */
+efi_status_t efi_initialize_system_table_pointer(void)
+{
+ /* Allocate efi_system_table_pointer structure with 4MB alignment. */
+ systab_pointer = efi_alloc_aligned_pages(sizeof(struct efi_system_table_pointer),
+ EFI_RUNTIME_SERVICES_DATA,
+ SZ_4M);
+
+ if (!systab_pointer) {
+ log_err("Installing EFI system table pointer failed\n");
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ systab_pointer->crc32 = 0;
+
+ systab_pointer->signature = EFI_SYSTEM_TABLE_SIGNATURE;
+ systab_pointer->efi_system_table_base = (uintptr_t)&systab;
+ systab_pointer->crc32 = crc32(0,
+ (const unsigned char *)systab_pointer,
+ sizeof(struct efi_system_table_pointer));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ * efi_core_new_debug_image_info_entry() - Add a new efi_loaded_image structure to the
+ * efi_debug_image_info table.
+ *
+ * @image_info_type: type of debug image information
+ * @loaded_image: pointer to the loaded image protocol for the image
+ * being loaded
+ * @image_handle: image handle for the image being loaded
+ *
+ * Re-Allocates the table if it's not large enough to accommodate another
+ * entry.
+ *
+ * Return: status code
+ **/
+efi_status_t efi_core_new_debug_image_info_entry(u32 image_info_type,
+ struct efi_loaded_image *loaded_image,
+ efi_handle_t image_handle)
+{
+ union efi_debug_image_info **table;
+ u32 index;
+ u32 table_size;
+ efi_status_t ret;
+
+ /* Set the flag indicating that we're in the process of updating
+ * the table.
+ */
+ efi_m_debug_info_table_header.update_status |=
+ EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
+
+ table = &efi_m_debug_info_table_header.efi_debug_image_info_table;
+
+ if (efi_m_debug_info_table_header.table_size >= efi_m_max_table_entries) {
+ /* table is full, re-allocate the buffer increasing the size
+ * by 4 KiB.
+ */
+ table_size = efi_m_max_table_entries * EFI_DEBUG_TABLE_ENTRY_SIZE;
+
+ ret = efi_realloc((void **)table, table_size + EFI_PAGE_SIZE);
+
+ if (ret != EFI_SUCCESS) {
+ efi_m_debug_info_table_header.update_status &=
+ ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
+ return ret;
+ }
+
+ /* Enlarge the max table entries and set the first empty
+ * entry index to be the original max table entries.
+ */
+ efi_m_max_table_entries +=
+ EFI_PAGE_SIZE / EFI_DEBUG_TABLE_ENTRY_SIZE;
+ }
+
+ /* We always put the next entry at the end of the currently consumed
+ * table (i.e. first free entry)
+ */
+ index = efi_m_debug_info_table_header.table_size;
+
+ /* Allocate data for new entry. */
+ ret = efi_allocate_pool(EFI_BOOT_SERVICES_DATA,
+ sizeof(union efi_debug_image_info),
+ (void **)(&(*table)[index].normal_image));
+ if (ret == EFI_SUCCESS && (*table)[index].normal_image) {
+ /* Update the entry. */
+ (*table)[index].normal_image->image_info_type = image_info_type;
+ (*table)[index].normal_image->loaded_image_protocol_instance =
+ loaded_image;
+ (*table)[index].normal_image->image_handle = image_handle;
+
+ /* Increase the number of EFI_DEBUG_IMAGE_INFO elements and
+ * set the efi_m_debug_info_table_header in modified status.
+ */
+ efi_m_debug_info_table_header.table_size++;
+ efi_m_debug_info_table_header.update_status |=
+ EFI_DEBUG_IMAGE_INFO_TABLE_MODIFIED;
+ } else {
+ log_err("Adding new efi_debug_image_info failed\n");
+ return ret;
+ }
+
+ efi_m_debug_info_table_header.update_status &=
+ ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ * efi_core_remove_debug_image_info_entry() - Remove an efi_debug_image_info entry.
+ *
+ * @image_handle: image handle for the image being removed
+ **/
+void efi_core_remove_debug_image_info_entry(efi_handle_t image_handle)
+{
+ union efi_debug_image_info *table;
+ u32 index;
+
+ efi_m_debug_info_table_header.update_status |=
+ EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
+
+ table = efi_m_debug_info_table_header.efi_debug_image_info_table;
+
+ for (index = 0; index < efi_m_max_table_entries; index++) {
+ if (table[index].normal_image &&
+ table[index].normal_image->image_handle == image_handle) {
+ /* Found a match. Free up the table entry.
+ * Move the tail of the table one slot to the front.
+ */
+ efi_free_pool(table[index].normal_image);
+
+ memmove(&table[index],
+ &table[index + 1],
+ (efi_m_debug_info_table_header.table_size -
+ index - 1) * EFI_DEBUG_TABLE_ENTRY_SIZE);
+
+ /* Decrease the number of EFI_DEBUG_IMAGE_INFO
+ * elements and set the efi_m_debug_info_table_header
+ * in modified status.
+ */
+ efi_m_debug_info_table_header.table_size--;
+ table[efi_m_debug_info_table_header.table_size].normal_image =
+ NULL;
+ efi_m_debug_info_table_header.update_status |=
+ EFI_DEBUG_IMAGE_INFO_TABLE_MODIFIED;
+ break;
+ }
+ }
+
+ efi_m_debug_info_table_header.update_status &=
+ ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
+}
diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c
index 7316a76f462..b3fb20b2501 100644
--- a/lib/efi_loader/efi_device_path.c
+++ b/lib/efi_loader/efi_device_path.c
@@ -11,6 +11,7 @@
#include <dm.h>
#include <dm/root.h>
#include <efi_device_path.h>
+#include <ide.h>
#include <log.h>
#include <net.h>
#include <usb.h>
diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c
index 47b583cc5e1..130c4db9606 100644
--- a/lib/efi_loader/efi_disk.c
+++ b/lib/efi_loader/efi_disk.c
@@ -26,6 +26,7 @@ struct efi_system_partition efi_system_partition = {
const efi_guid_t efi_block_io_guid = EFI_BLOCK_IO_PROTOCOL_GUID;
const efi_guid_t efi_system_partition_guid = PARTITION_SYSTEM_GUID;
+const efi_guid_t efi_partition_info_guid = EFI_PARTITION_INFO_PROTOCOL_GUID;
/**
* struct efi_disk_obj - EFI disk object
@@ -35,6 +36,7 @@ const efi_guid_t efi_system_partition_guid = PARTITION_SYSTEM_GUID;
* @media: block I/O media information
* @dp: device path to the block device
* @volume: simple file system protocol of the partition
+ * @info: EFI partition info protocol interface
*/
struct efi_disk_obj {
struct efi_object header;
@@ -42,6 +44,7 @@ struct efi_disk_obj {
struct efi_block_io_media media;
struct efi_device_path *dp;
struct efi_simple_file_system_protocol *volume;
+ struct efi_partition_info info;
};
/**
@@ -426,6 +429,7 @@ static efi_status_t efi_disk_add_dev(
/* Fill in object data */
if (part_info) {
struct efi_device_path *node = efi_dp_part_node(desc, part);
+ struct efi_partition_info *info = &diskobj->info;
struct efi_handler *handler;
void *protocol_interface;
@@ -454,18 +458,48 @@ static efi_status_t efi_disk_add_dev(
goto error;
}
+ info->revision = EFI_PARTITION_INFO_PROTOCOL_REVISION;
+
+ switch (desc->part_type) {
+#if CONFIG_IS_ENABLED(EFI_PARTITION)
+ case PART_TYPE_EFI:
+ info->type = PARTITION_TYPE_GPT;
+ ret = part_get_gpt_pte(desc, part, &info->info.gpt);
+ if (ret) {
+ log_debug("get PTE for part %d failed %ld\n",
+ part, ret);
+ goto error;
+ }
+ break;
+#endif
+#if CONFIG_IS_ENABLED(DOS_PARTITION)
+ case PART_TYPE_DOS:
+ info->type = PARTITION_TYPE_MBR;
+
+ /* TODO: implement support for MBR partition types */
+ log_debug("EFI_PARTITION_INFO_PROTOCOL doesn't support MBR\n");
+ break;
+#endif
+ default:
+ info->type = PARTITION_TYPE_OTHER;
+ break;
+ }
+
diskobj->dp = efi_dp_append_node(dp_parent, node);
efi_free_pool(node);
diskobj->media.last_block = part_info->size - 1;
- if (part_info->bootable & PART_EFI_SYSTEM_PARTITION)
+ if (part_info->bootable & PART_EFI_SYSTEM_PARTITION) {
esp_guid = &efi_system_partition_guid;
+ info->system = 1;
+ }
+
} else {
diskobj->dp = efi_dp_from_part(desc, part);
diskobj->media.last_block = desc->lba - 1;
}
/*
- * Install the device path and the block IO protocol.
+ * Install the device path, the block IO and partition info protocols.
*
* InstallMultipleProtocolInterfaces() checks if the device path is
* already installed on an other handle and returns EFI_ALREADY_STARTED
@@ -476,6 +510,7 @@ static efi_status_t efi_disk_add_dev(
&handle,
&efi_guid_device_path, diskobj->dp,
&efi_block_io_guid, &diskobj->ops,
+ &efi_partition_info_guid, &diskobj->info,
/*
* esp_guid must be last entry as it
* can be NULL. Its interface is NULL.
diff --git a/lib/efi_loader/efi_file.c b/lib/efi_loader/efi_file.c
index 7d81da8f2d8..19b43c4a625 100644
--- a/lib/efi_loader/efi_file.c
+++ b/lib/efi_loader/efi_file.c
@@ -248,7 +248,7 @@ static struct efi_file_handle *file_open(struct file_system *fs,
return &fh->base;
error:
- free(fh->path);
+ free(path);
free(fh);
return NULL;
}
diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c
index d44dc09813e..75501e21557 100644
--- a/lib/efi_loader/efi_firmware.c
+++ b/lib/efi_loader/efi_firmware.c
@@ -12,6 +12,7 @@
#include <dfu.h>
#include <efi_loader.h>
#include <efi_variable.h>
+#include <env.h>
#include <fwu.h>
#include <image.h>
#include <signatures.h>
diff --git a/lib/efi_loader/efi_http.c b/lib/efi_loader/efi_http.c
index 189317fe2d2..9a0f2675132 100644
--- a/lib/efi_loader/efi_http.c
+++ b/lib/efi_loader/efi_http.c
@@ -453,7 +453,6 @@ static efi_status_t EFIAPI efi_http_service_binding_destroy_child(
efi_status_t ret = EFI_SUCCESS;
struct efi_http_instance *http_instance;
struct efi_handler *phandler;
- void *protocol_interface;
if (num_instances == 0)
return EFI_EXIT(EFI_NOT_FOUND);
@@ -463,18 +462,18 @@ static efi_status_t EFIAPI efi_http_service_binding_destroy_child(
efi_search_protocol(child_handle, &efi_http_guid, &phandler);
- if (phandler)
- protocol_interface = phandler->protocol_interface;
+ if (!phandler)
+ return EFI_EXIT(EFI_UNSUPPORTED);
ret = efi_delete_handle(child_handle);
if (ret != EFI_SUCCESS)
return EFI_EXIT(ret);
- http_instance = (struct efi_http_instance *)protocol_interface;
+ http_instance = phandler->protocol_interface;
efi_free_pool(http_instance->http_load_addr);
http_instance->http_load_addr = NULL;
- free(protocol_interface);
+ free(phandler->protocol_interface);
num_instances--;
diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
index 0abb1f6159a..6dfc698a247 100644
--- a/lib/efi_loader/efi_memory.c
+++ b/lib/efi_loader/efi_memory.c
@@ -454,6 +454,7 @@ efi_status_t efi_allocate_pages(enum efi_allocate_type type,
enum efi_memory_type memory_type,
efi_uintn_t pages, uint64_t *memory)
{
+ int err;
u64 efi_addr, len;
uint flags;
efi_status_t ret;
@@ -475,17 +476,18 @@ efi_status_t efi_allocate_pages(enum efi_allocate_type type,
switch (type) {
case EFI_ALLOCATE_ANY_PAGES:
/* Any page */
- addr = (u64)lmb_alloc_base(len, EFI_PAGE_SIZE,
- LMB_ALLOC_ANYWHERE, flags);
- if (!addr)
+ err = lmb_alloc_mem(LMB_MEM_ALLOC_ANY, EFI_PAGE_SIZE, &addr,
+ len, flags);
+ if (err)
return EFI_OUT_OF_RESOURCES;
break;
case EFI_ALLOCATE_MAX_ADDRESS:
/* Max address */
addr = map_to_sysmem((void *)(uintptr_t)*memory);
- addr = (u64)lmb_alloc_base(len, EFI_PAGE_SIZE, addr,
- flags);
- if (!addr)
+
+ err = lmb_alloc_mem(LMB_MEM_ALLOC_MAX, EFI_PAGE_SIZE, &addr,
+ len, flags);
+ if (err)
return EFI_OUT_OF_RESOURCES;
break;
case EFI_ALLOCATE_ADDRESS:
@@ -493,7 +495,7 @@ efi_status_t efi_allocate_pages(enum efi_allocate_type type,
return EFI_NOT_FOUND;
addr = map_to_sysmem((void *)(uintptr_t)*memory);
- if (lmb_alloc_addr(addr, len, flags))
+ if (lmb_alloc_mem(LMB_MEM_ALLOC_ADDR, 0, &addr, len, flags))
return EFI_NOT_FOUND;
break;
default:
@@ -506,7 +508,7 @@ efi_status_t efi_allocate_pages(enum efi_allocate_type type,
ret = efi_update_memory_map(efi_addr, pages, memory_type, true, false);
if (ret != EFI_SUCCESS) {
/* Map would overlap, bail out */
- lmb_free_flags(addr, (u64)pages << EFI_PAGE_SHIFT, flags);
+ lmb_free(addr, (u64)pages << EFI_PAGE_SHIFT, flags);
unmap_sysmem((void *)(uintptr_t)efi_addr);
return EFI_OUT_OF_RESOURCES;
}
@@ -546,8 +548,8 @@ efi_status_t efi_free_pages(uint64_t memory, efi_uintn_t pages)
* been mapped with map_sysmem() from efi_allocate_pages(). Convert
* it back to an address LMB understands
*/
- status = lmb_free_flags(map_to_sysmem((void *)(uintptr_t)memory), len,
- LMB_NOOVERWRITE);
+ status = lmb_free(map_to_sysmem((void *)(uintptr_t)memory), len,
+ LMB_NOOVERWRITE);
if (status)
return EFI_NOT_FOUND;
@@ -667,6 +669,64 @@ void *efi_alloc(size_t size)
}
/**
+ * efi_realloc() - reallocate boot services data pool memory
+ *
+ * Reallocate memory from pool for a new size and copy the data from old one.
+ *
+ * @ptr: pointer to old buffer
+ * @size: number of bytes to allocate
+ * Return: EFI status to indicate success or not
+ */
+efi_status_t efi_realloc(void **ptr, size_t size)
+{
+ efi_status_t ret;
+ void *new_ptr;
+ struct efi_pool_allocation *alloc;
+ u64 num_pages = efi_size_in_pages(size +
+ sizeof(struct efi_pool_allocation));
+ size_t old_size;
+
+ if (!*ptr) {
+ *ptr = efi_alloc(size);
+ if (*ptr)
+ return EFI_SUCCESS;
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ ret = efi_check_allocated((uintptr_t)*ptr, true);
+ if (ret != EFI_SUCCESS)
+ return ret;
+
+ alloc = container_of(*ptr, struct efi_pool_allocation, data);
+
+ /* Check that this memory was allocated by efi_allocate_pool() */
+ if (((uintptr_t)alloc & EFI_PAGE_MASK) ||
+ alloc->checksum != checksum(alloc)) {
+ printf("%s: illegal realloc 0x%p\n", __func__, *ptr);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ /* Don't realloc. The actual size in pages is the same. */
+ if (alloc->num_pages == num_pages)
+ return EFI_SUCCESS;
+
+ old_size = alloc->num_pages * EFI_PAGE_SIZE -
+ sizeof(struct efi_pool_allocation);
+
+ new_ptr = efi_alloc(size);
+
+ /* copy old data to new alloced buffer */
+ memcpy(new_ptr, *ptr, min(size, old_size));
+
+ /* free the old buffer */
+ efi_free_pool(*ptr);
+
+ *ptr = new_ptr;
+
+ return EFI_SUCCESS;
+}
+
+/**
* efi_free_pool() - free memory from pool
*
* @buffer: start of memory to be freed
diff --git a/lib/efi_loader/efi_net.c b/lib/efi_loader/efi_net.c
index 8e708d8d350..b8a6e08ba8e 100644
--- a/lib/efi_loader/efi_net.c
+++ b/lib/efi_loader/efi_net.c
@@ -19,6 +19,7 @@
#include <efi_device_path.h>
#include <efi_loader.h>
+#include <env.h>
#include <dm.h>
#include <linux/sizes.h>
#include <malloc.h>
@@ -1130,7 +1131,7 @@ efi_status_t efi_net_register(struct udevice *dev)
struct efi_net_obj *netobj;
void *transmit_buffer = NULL;
uchar **receive_buffer = NULL;
- size_t *receive_lengths;
+ size_t *receive_lengths = NULL;
int i, j;
if (!dev) {
diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c
index 48f91da5df7..f06cf49e443 100644
--- a/lib/efi_loader/efi_setup.c
+++ b/lib/efi_loader/efi_setup.c
@@ -18,6 +18,9 @@
efi_status_t efi_obj_list_initialized = OBJ_LIST_NOT_INITIALIZED;
+const efi_guid_t efi_debug_image_info_table_guid =
+ EFI_DEBUG_IMAGE_INFO_TABLE_GUID;
+
/*
* Allow unaligned memory access.
*
@@ -278,6 +281,21 @@ efi_status_t efi_init_obj_list(void)
if (ret != EFI_SUCCESS)
goto out;
+ /* Initialize system table pointer */
+ if (IS_ENABLED(CONFIG_EFI_DEBUG_SUPPORT)) {
+ efi_guid_t debug_image_info_table_guid =
+ efi_debug_image_info_table_guid;
+
+ ret = efi_initialize_system_table_pointer();
+ if (ret != EFI_SUCCESS)
+ goto out;
+
+ ret = efi_install_configuration_table(&debug_image_info_table_guid,
+ &efi_m_debug_info_table_header);
+ if (ret != EFI_SUCCESS)
+ goto out;
+ }
+
if (IS_ENABLED(CONFIG_EFI_ECPT)) {
ret = efi_ecpt_register();
if (ret != EFI_SUCCESS)
diff --git a/lib/efi_selftest/Makefile b/lib/efi_selftest/Makefile
index d78bf7d6191..842433f68aa 100644
--- a/lib/efi_selftest/Makefile
+++ b/lib/efi_selftest/Makefile
@@ -78,6 +78,8 @@ endif
obj-$(CONFIG_EFI_ESRT) += efi_selftest_esrt.o
+obj-$(CONFIG_EFI_DEBUG_SUPPORT) += efi_selftest_debug_support.o
+
targets += \
efi_miniapp_file_image_exception.h \
efi_miniapp_file_image_exit.h \
diff --git a/lib/efi_selftest/efi_selftest_block_device.c b/lib/efi_selftest/efi_selftest_block_device.c
index a367e8b89d1..f145e58a267 100644
--- a/lib/efi_selftest/efi_selftest_block_device.c
+++ b/lib/efi_selftest/efi_selftest_block_device.c
@@ -18,6 +18,7 @@
#include <efi_selftest.h>
#include "efi_selftest_disk_image.h"
#include <asm/cache.h>
+#include <part_efi.h>
/* Block size of compressed disk image */
#define COMPRESSED_DISK_IMAGE_BLOCK_SIZE 8
@@ -29,6 +30,7 @@ static struct efi_boot_services *boottime;
static const efi_guid_t block_io_protocol_guid = EFI_BLOCK_IO_PROTOCOL_GUID;
static const efi_guid_t guid_device_path = EFI_DEVICE_PATH_PROTOCOL_GUID;
+static const efi_guid_t partition_info_guid = EFI_PARTITION_INFO_PROTOCOL_GUID;
static const efi_guid_t guid_simple_file_system_protocol =
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;
static const efi_guid_t guid_file_system_info = EFI_FILE_SYSTEM_INFO_GUID;
@@ -310,6 +312,7 @@ static int execute(void)
struct efi_file_system_info info;
u16 label[12];
} system_info;
+ struct efi_partition_info *part_info;
efi_uintn_t buf_size;
char buf[16] __aligned(ARCH_DMA_MINALIGN);
u32 part1_size;
@@ -375,6 +378,33 @@ static int execute(void)
part1_size - 1);
return EFI_ST_FAILURE;
}
+
+ /* Open the partition information protocol */
+ ret = boottime->open_protocol(handle_partition,
+ &partition_info_guid,
+ (void **)&part_info, NULL, NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Failed to open partition information protocol\n");
+ return EFI_ST_FAILURE;
+ }
+ /* Check that cached partition information is the expected */
+ if (part_info->revision != EFI_PARTITION_INFO_PROTOCOL_REVISION) {
+ efi_st_error("Partition info revision %x, expected %x\n",
+ part_info->revision, EFI_PARTITION_INFO_PROTOCOL_REVISION);
+ return EFI_ST_FAILURE;
+ }
+ if (part_info->type != PARTITION_TYPE_MBR) {
+ efi_st_error("Partition info type %x, expected %x\n",
+ part_info->type, PARTITION_TYPE_MBR);
+ return EFI_ST_FAILURE;
+ }
+ if (part_info->system != 0) {
+ efi_st_error("Partition info system %x, expected 0\n",
+ part_info->system);
+ return EFI_ST_FAILURE;
+ }
+
/* Open the simple file system protocol */
ret = boottime->open_protocol(handle_partition,
&guid_simple_file_system_protocol,
diff --git a/lib/efi_selftest/efi_selftest_debug_support.c b/lib/efi_selftest/efi_selftest_debug_support.c
new file mode 100644
index 00000000000..9ca8b3f82f5
--- /dev/null
+++ b/lib/efi_selftest/efi_selftest_debug_support.c
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * efi_selftest_debug_support
+ *
+ * Copyright (c) 2025 Ying-Chun Liu, Linaro Ltd. <paul.liu@linaro.org>
+ *
+ * Test the EFI_DEBUG_SUPPORT
+ */
+
+#include <efi_loader.h>
+#include <efi_selftest.h>
+
+/**
+ * efi_st_debug_support_execute() - execute test
+ *
+ * Test EFI_DEBUG_SUPPORT tables.
+ *
+ * Return: status code
+ */
+static int efi_st_debug_support_execute(void)
+{
+ struct efi_debug_image_info_table_header *efi_st_debug_info_table_header = NULL;
+ efi_guid_t efi_debug_image_info_table_guid = EFI_DEBUG_IMAGE_INFO_TABLE_GUID;
+
+ /* get EFI_DEBUG_IMAGE_INFO_TABLE */
+ efi_st_debug_info_table_header = efi_st_get_config_table(&efi_debug_image_info_table_guid);
+
+ if (!efi_st_debug_info_table_header) {
+ efi_st_error("Missing EFI_DEBUG_IMAGE_INFO_TABLE\n");
+ return EFI_ST_FAILURE;
+ }
+
+ return EFI_ST_SUCCESS;
+}
+
+EFI_UNIT_TEST(debug_support) = {
+ .name = "debug_support",
+ .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
+ .execute = efi_st_debug_support_execute,
+};
diff --git a/lib/fwu_updates/fwu_v1.c b/lib/fwu_updates/fwu_v1.c
index c311a8857a6..974abf216f6 100644
--- a/lib/fwu_updates/fwu_v1.c
+++ b/lib/fwu_updates/fwu_v1.c
@@ -3,6 +3,7 @@
* Copyright (c) 2024, Linaro Limited
*/
+#include <errno.h>
#include <fwu.h>
#include <fwu_mdata.h>
diff --git a/lib/fwu_updates/fwu_v2.c b/lib/fwu_updates/fwu_v2.c
index ce46904ff2e..159315b45b9 100644
--- a/lib/fwu_updates/fwu_v2.c
+++ b/lib/fwu_updates/fwu_v2.c
@@ -3,6 +3,7 @@
* Copyright (c) 2024, Linaro Limited
*/
+#include <errno.h>
#include <fwu.h>
#include <fwu_mdata.h>
#include <log.h>
diff --git a/lib/linux_string.c b/lib/linux_string.c
index d5a5e08d98c..4b92cd923f2 100644
--- a/lib/linux_string.c
+++ b/lib/linux_string.c
@@ -31,13 +31,15 @@ char *skip_spaces(const char *str)
* Note that the first trailing whitespace is replaced with a %NUL-terminator
* in the given string @s. Returns a pointer to the first non-whitespace
* character in @s.
+ *
+ * Note that if the string consist of only spaces, then the terminator is placed
+ * at the start of the string, with the return value pointing there also.
*/
char *strim(char *s)
{
size_t size;
char *end;
- s = skip_spaces(s);
size = strlen(s);
if (!size)
return s;
@@ -47,5 +49,5 @@ char *strim(char *s)
end--;
*(end + 1) = '\0';
- return s;
+ return skip_spaces(s);
}
diff --git a/lib/lmb.c b/lib/lmb.c
index bb6f232f6bc..e5a0677e3f9 100644
--- a/lib/lmb.c
+++ b/lib/lmb.c
@@ -317,8 +317,34 @@ static long _lmb_free(struct alist *lmb_rgn_lst, phys_addr_t base,
rgn[i].flags);
}
-static long lmb_overlaps_region(struct alist *lmb_rgn_lst, phys_addr_t base,
- phys_size_t size)
+/**
+ * lmb_overlap_checks() - perform checks to see if region can be allocated or reserved
+ * @lmb_rgn_lst: list of LMB regions
+ * @base: base address of region to be checked
+ * @size: size of region to be checked
+ * @flags: flag of the region to be checked (only for reservation requests)
+ * @alloc: if checks are to be done for allocation or reservation request
+ *
+ * Check if the region passed to the function overlaps with any one of
+ * the regions of the passed lmb region list.
+ *
+ * If the @alloc flag is set to true, this check stops as soon an
+ * overlapping region is found. The function can also be called to
+ * check if a reservation request can be satisfied, by setting
+ * @alloc to false. In that case, the function then iterates through
+ * all the regions in the list passed to ensure that the requested
+ * region does not overlap with any existing regions. An overlap is
+ * allowed only when the flag of the requested region and the existing
+ * region is LMB_NONE.
+ *
+ * Return: index of the overlapping region, -1 if no overlap is found
+ *
+ * When the function is called for a reservation request check, -1 will
+ * also be returned when there is an allowed overlap, i.e. requested
+ * region and existing regions have flags as LMB_NONE.
+ */
+static long lmb_overlap_checks(struct alist *lmb_rgn_lst, phys_addr_t base,
+ phys_size_t size, u32 flags, bool alloc)
{
unsigned long i;
struct lmb_region *rgn = lmb_rgn_lst->data;
@@ -326,9 +352,12 @@ static long lmb_overlaps_region(struct alist *lmb_rgn_lst, phys_addr_t base,
for (i = 0; i < lmb_rgn_lst->count; i++) {
phys_addr_t rgnbase = rgn[i].base;
phys_size_t rgnsize = rgn[i].size;
+ u32 rgnflags = rgn[i].flags;
- if (lmb_addrs_overlap(base, size, rgnbase, rgnsize))
- break;
+ if (lmb_addrs_overlap(base, size, rgnbase, rgnsize)) {
+ if (alloc || flags != LMB_NONE || flags != rgnflags)
+ break;
+ }
}
return (i < lmb_rgn_lst->count) ? i : -1;
@@ -390,7 +419,8 @@ phys_addr_t io_lmb_alloc(struct lmb *io_lmb, phys_size_t size, ulong align)
base = ALIGN_DOWN(lmbbase + lmbsize - size, align);
while (base && lmbbase <= base) {
- rgn = lmb_overlaps_region(&io_lmb->used_mem, base, size);
+ rgn = lmb_overlap_checks(&io_lmb->used_mem, base, size,
+ LMB_NOOVERWRITE, true);
if (rgn < 0) {
/* This area isn't reserved, take it */
if (lmb_add_region_flags(&io_lmb->used_mem, base,
@@ -488,6 +518,21 @@ void lmb_dump_all(void)
#endif
}
+static long lmb_reserve(phys_addr_t base, phys_size_t size, u32 flags)
+{
+ long ret = 0;
+ struct alist *lmb_rgn_lst = &lmb.used_mem;
+
+ if (lmb_overlap_checks(lmb_rgn_lst, base, size, flags, false) != -1)
+ return -EEXIST;
+
+ ret = lmb_add_region_flags(lmb_rgn_lst, base, size, flags);
+ if (ret)
+ return ret;
+
+ return lmb_map_update_notify(base, size, LMB_MAP_OP_RESERVE, flags);
+}
+
static void lmb_reserve_uboot_region(void)
{
int bank;
@@ -557,40 +602,7 @@ static __maybe_unused void lmb_reserve_common_spl(void)
}
}
-/**
- * lmb_can_reserve_region() - check if the region can be reserved
- * @base: base address of region to be reserved
- * @size: size of region to be reserved
- * @flags: flag of the region to be reserved
- *
- * Go through all the reserved regions and ensure that the requested
- * region does not overlap with any existing regions. An overlap is
- * allowed only when the flag of the request region and the existing
- * region is LMB_NONE.
- *
- * Return: true if region can be reserved, false otherwise
- */
-static bool lmb_can_reserve_region(phys_addr_t base, phys_size_t size,
- u32 flags)
-{
- uint i;
- struct lmb_region *lmb_reserved = lmb.used_mem.data;
-
- for (i = 0; i < lmb.used_mem.count; i++) {
- u32 rgnflags = lmb_reserved[i].flags;
- phys_addr_t rgnbase = lmb_reserved[i].base;
- phys_size_t rgnsize = lmb_reserved[i].size;
-
- if (lmb_addrs_overlap(base, size, rgnbase, rgnsize)) {
- if (flags != LMB_NONE || flags != rgnflags)
- return false;
- }
- }
-
- return true;
-}
-
-void lmb_add_memory(void)
+static void lmb_add_memory(void)
{
int i;
phys_addr_t bank_end;
@@ -640,8 +652,7 @@ long lmb_add(phys_addr_t base, phys_size_t size)
return lmb_map_update_notify(base, size, LMB_MAP_OP_ADD, LMB_NONE);
}
-long lmb_free_flags(phys_addr_t base, phys_size_t size,
- uint flags)
+long lmb_free(phys_addr_t base, phys_size_t size, u32 flags)
{
long ret;
@@ -652,36 +663,18 @@ long lmb_free_flags(phys_addr_t base, phys_size_t size,
return lmb_map_update_notify(base, size, LMB_MAP_OP_FREE, flags);
}
-long lmb_free(phys_addr_t base, phys_size_t size)
-{
- return lmb_free_flags(base, size, LMB_NONE);
-}
-
-long lmb_reserve(phys_addr_t base, phys_size_t size, u32 flags)
-{
- long ret = 0;
- struct alist *lmb_rgn_lst = &lmb.used_mem;
-
- if (!lmb_can_reserve_region(base, size, flags))
- return -EEXIST;
-
- ret = lmb_add_region_flags(lmb_rgn_lst, base, size, flags);
- if (ret)
- return ret;
-
- return lmb_map_update_notify(base, size, LMB_MAP_OP_RESERVE, flags);
-}
-
-static phys_addr_t _lmb_alloc_base(phys_size_t size, ulong align,
- phys_addr_t max_addr, u32 flags)
+static int _lmb_alloc_base(phys_size_t size, ulong align,
+ phys_addr_t *addr, u32 flags)
{
int ret;
long i, rgn;
+ phys_addr_t max_addr;
phys_addr_t base = 0;
phys_addr_t res_base;
struct lmb_region *lmb_used = lmb.used_mem.data;
struct lmb_region *lmb_memory = lmb.available_mem.data;
+ max_addr = *addr;
for (i = lmb.available_mem.count - 1; i >= 0; i--) {
phys_addr_t lmbbase = lmb_memory[i].base;
phys_size_t lmbsize = lmb_memory[i].size;
@@ -702,7 +695,8 @@ static phys_addr_t _lmb_alloc_base(phys_size_t size, ulong align,
}
while (base && lmbbase <= base) {
- rgn = lmb_overlaps_region(&lmb.used_mem, base, size);
+ rgn = lmb_overlap_checks(&lmb.used_mem, base, size,
+ LMB_NOOVERWRITE, true);
if (rgn < 0) {
/* This area isn't reserved, take it */
if (lmb_add_region_flags(&lmb.used_mem, base,
@@ -714,8 +708,8 @@ static phys_addr_t _lmb_alloc_base(phys_size_t size, ulong align,
flags);
if (ret)
return ret;
-
- return base;
+ *addr = base;
+ return 0;
}
res_base = lmb_used[rgn].base;
@@ -728,27 +722,17 @@ static phys_addr_t _lmb_alloc_base(phys_size_t size, ulong align,
log_debug("%s: Failed to allocate 0x%lx bytes below 0x%lx\n",
__func__, (ulong)size, (ulong)max_addr);
- return 0;
-}
-
-phys_addr_t lmb_alloc(phys_size_t size, ulong align)
-{
- return _lmb_alloc_base(size, align, LMB_ALLOC_ANYWHERE, LMB_NONE);
-}
-
-phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr,
- uint flags)
-{
- return _lmb_alloc_base(size, align, max_addr, flags);
+ return -1;
}
-int lmb_alloc_addr(phys_addr_t base, phys_size_t size, u32 flags)
+static int _lmb_alloc_addr(phys_addr_t base, phys_size_t size, u32 flags)
{
long rgn;
struct lmb_region *lmb_memory = lmb.available_mem.data;
/* Check if the requested address is in one of the memory regions */
- rgn = lmb_overlaps_region(&lmb.available_mem, base, size);
+ rgn = lmb_overlap_checks(&lmb.available_mem, base, size,
+ LMB_NOOVERWRITE, true);
if (rgn >= 0) {
/*
* Check if the requested end address is in the same memory
@@ -756,14 +740,41 @@ int lmb_alloc_addr(phys_addr_t base, phys_size_t size, u32 flags)
*/
if (lmb_addrs_overlap(lmb_memory[rgn].base,
lmb_memory[rgn].size,
- base + size - 1, 1)) {
+ base + size - 1, 1))
/* ok, reserve the memory */
- if (!lmb_reserve(base, size, flags))
- return 0;
- }
+ return lmb_reserve(base, size, flags);
}
- return -1;
+ return -EINVAL;
+}
+
+int lmb_alloc_mem(enum lmb_mem_type type, u64 align, phys_addr_t *addr,
+ phys_size_t size, u32 flags)
+{
+ int ret = -1;
+
+ if (!size)
+ return 0;
+
+ if (!addr)
+ return -EINVAL;
+
+ switch (type) {
+ case LMB_MEM_ALLOC_ANY:
+ *addr = LMB_ALLOC_ANYWHERE;
+ fallthrough;
+ case LMB_MEM_ALLOC_MAX:
+ ret = _lmb_alloc_base(size, align, addr, flags);
+ break;
+ case LMB_MEM_ALLOC_ADDR:
+ ret = _lmb_alloc_addr(*addr, size, flags);
+ break;
+ default:
+ log_debug("%s: Invalid memory allocation type requested %d\n",
+ __func__, type);
+ }
+
+ return ret;
}
/* Return number of bytes from a given address that are free */
@@ -775,7 +786,8 @@ phys_size_t lmb_get_free_size(phys_addr_t addr)
struct lmb_region *lmb_memory = lmb.available_mem.data;
/* check if the requested address is in the memory regions */
- rgn = lmb_overlaps_region(&lmb.available_mem, addr, 1);
+ rgn = lmb_overlap_checks(&lmb.available_mem, addr, 1, LMB_NOOVERWRITE,
+ true);
if (rgn >= 0) {
for (i = 0; i < lmb.used_mem.count; i++) {
if (addr < lmb_used[i].base) {
diff --git a/lib/lwip/Makefile b/lib/lwip/Makefile
index e9e8caee93a..c3f0e916f66 100644
--- a/lib/lwip/Makefile
+++ b/lib/lwip/Makefile
@@ -13,6 +13,7 @@ obj-y += \
lwip/src/api/sockets.o \
lwip/src/api/tcpip.o \
lwip/src/apps/http/http_client.o \
+ lwip/src/apps/sntp/sntp.o \
lwip/src/apps/tftp/tftp.o \
lwip/src/core/altcp_alloc.o \
lwip/src/core/altcp.o \
diff --git a/lib/lwip/u-boot/arch/cc.h b/lib/lwip/u-boot/arch/cc.h
index 6104c296f6f..f91127ac565 100644
--- a/lib/lwip/u-boot/arch/cc.h
+++ b/lib/lwip/u-boot/arch/cc.h
@@ -43,4 +43,8 @@
#define BYTE_ORDER BIG_ENDIAN
#endif
+#define SNTP_STARTUP_DELAY 0
+void sntp_set_system_time(uint32_t sec);
+#define SNTP_SET_SYSTEM_TIME(sec) sntp_set_system_time(sec)
+
#endif /* LWIP_ARCH_CC_H */
diff --git a/lib/lwip/u-boot/lwipopts.h b/lib/lwip/u-boot/lwipopts.h
index edac74ff7a2..46af91f9410 100644
--- a/lib/lwip/u-boot/lwipopts.h
+++ b/lib/lwip/u-boot/lwipopts.h
@@ -72,8 +72,8 @@
#define IP_FORWARD 0
#define IP_OPTIONS_ALLOWED 1
-#define IP_REASSEMBLY 0
-#define IP_FRAG 0
+#define IP_REASSEMBLY 1
+#define IP_FRAG 1
#define IP_REASS_MAXAGE 3
#define IP_REASS_MAX_PBUFS 4
#define IP_FRAG_USES_STATIC_BUF 0
@@ -162,4 +162,8 @@
#define LWIP_ALTCP_TLS_MBEDTLS 1
#endif
+#if defined(CONFIG_CMD_SNTP)
+#define LWIP_DHCP_GET_NTP_SRV 1
+#endif
+
#endif /* LWIP_UBOOT_LWIPOPTS_H */
diff --git a/lib/mbedtls/external/mbedtls/library/ecp_curves_new.c b/lib/mbedtls/external/mbedtls/library/ecp_curves_new.c
index 035b23a1b41..0275661887b 100644
--- a/lib/mbedtls/external/mbedtls/library/ecp_curves_new.c
+++ b/lib/mbedtls/external/mbedtls/library/ecp_curves_new.c
@@ -4644,17 +4644,17 @@ static const mbedtls_mpi_sint curve25519_a24 = 0x01DB42;
/* P = 2^255 - 19 */
static const mbedtls_mpi_uint curve25519_p[] = {
- MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF),
- MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF),
- MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF),
- MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X7F)
+ MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F)
};
/* N = 2^252 + 27742317777372353535851937790883648493 */
static const mbedtls_mpi_uint curve25519_n[] = {
- MBEDTLS_BYTES_TO_T_UINT_8(0XED, 0XD3, 0XF5, 0X5C, 0X1A, 0X63, 0X12, 0X58),
- MBEDTLS_BYTES_TO_T_UINT_8(0XD6, 0X9C, 0XF7, 0XA2, 0XDE, 0XF9, 0XDE, 0X14),
- MBEDTLS_BYTES_TO_T_UINT_8(0X00, 0X00, 0X00, 0X00, 0x00, 0x00, 0x00, 0x00),
+ MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0xD3, 0xF5, 0x5C, 0x1A, 0x63, 0x12, 0x58),
+ MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0x9C, 0xF7, 0xA2, 0xDE, 0xF9, 0xDE, 0x14),
+ MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10)
};
@@ -4698,26 +4698,26 @@ static const mbedtls_mpi_sint curve448_a24 = 0x98AA;
/* P = 2^448 - 2^224 - 1 */
static const mbedtls_mpi_uint curve448_p[] = {
- MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF),
- MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF),
- MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF),
- MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFE, 0XFF, 0XFF, 0XFF),
- MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF),
- MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF),
- MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF),
- MBEDTLS_BYTES_TO_T_UINT_8(0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00)
+ MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF),
+ MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
};
/* N = 2^446 - 13818066809895115352007386748515426880336692474882178609894547503885 */
static const mbedtls_mpi_uint curve448_n[] = {
- MBEDTLS_BYTES_TO_T_UINT_8(0XF3, 0X44, 0X58, 0XAB, 0X92, 0XC2, 0X78, 0X23),
- MBEDTLS_BYTES_TO_T_UINT_8(0X55, 0X8F, 0XC5, 0X8D, 0X72, 0XC2, 0X6C, 0X21),
- MBEDTLS_BYTES_TO_T_UINT_8(0X90, 0X36, 0XD6, 0XAE, 0X49, 0XDB, 0X4E, 0XC4),
- MBEDTLS_BYTES_TO_T_UINT_8(0XE9, 0X23, 0XCA, 0X7C, 0XFF, 0XFF, 0XFF, 0XFF),
- MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF),
- MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF),
- MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X3F),
- MBEDTLS_BYTES_TO_T_UINT_8(0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00)
+ MBEDTLS_BYTES_TO_T_UINT_8(0xF3, 0x44, 0x58, 0xAB, 0x92, 0xC2, 0x78, 0x23),
+ MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0x8F, 0xC5, 0x8D, 0x72, 0xC2, 0x6C, 0x21),
+ MBEDTLS_BYTES_TO_T_UINT_8(0x90, 0x36, 0xD6, 0xAE, 0x49, 0xDB, 0x4E, 0xC4),
+ MBEDTLS_BYTES_TO_T_UINT_8(0xE9, 0x23, 0xCA, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF),
+ MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
+ MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F),
+ MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
};
/*
diff --git a/lib/of_live.c b/lib/of_live.c
index c1620616513..24200b948a6 100644
--- a/lib/of_live.c
+++ b/lib/of_live.c
@@ -448,8 +448,7 @@ int of_live_flatten(const struct device_node *root, struct abuf *buf)
{
int ret;
- abuf_init(buf);
- if (!abuf_realloc(buf, BUF_STEP))
+ if (!abuf_init_size(buf, BUF_STEP))
return log_msg_ret("ini", -ENOMEM);
ret = fdt_create(abuf_data(buf), abuf_size(buf));
diff --git a/lib/rsa/rsa-sign.c b/lib/rsa/rsa-sign.c
index fa9e143b4ca..92b9d7876e5 100644
--- a/lib/rsa/rsa-sign.c
+++ b/lib/rsa/rsa-sign.c
@@ -122,7 +122,7 @@ static int rsa_engine_get_pub_key(const char *keydir, const char *name,
fprintf(stderr, "WARNING: Legacy URI specified. Please add '%s'.\n", pkcs11_schema);
}
- if (strstr(keydir, "object="))
+ if (strstr(keydir, "object=") || strstr(keydir, "id="))
snprintf(key_id, sizeof(key_id),
"%s%s;type=public",
pkcs11_uri_prepend, keydir);
@@ -253,7 +253,7 @@ static int rsa_engine_get_priv_key(const char *keydir, const char *name,
fprintf(stderr, "WARNING: Legacy URI specified. Please add '%s'.\n", pkcs11_schema);
}
- if (strstr(keydir, "object="))
+ if (strstr(keydir, "object=") || strstr(keydir, "id="))
snprintf(key_id, sizeof(key_id),
"%s%s;type=private",
pkcs11_uri_prepend, keydir);
diff --git a/lib/slre.c b/lib/slre.c
index 277a59a03a7..117815a6d60 100644
--- a/lib/slre.c
+++ b/lib/slre.c
@@ -30,7 +30,7 @@
#include <slre.h>
enum {END, BRANCH, ANY, EXACT, ANYOF, ANYBUT, OPEN, CLOSE, BOL, EOL,
- STAR, PLUS, STARQ, PLUSQ, QUEST, SPACE, NONSPACE, DIGIT};
+ STAR, PLUS, STARQ, PLUSQ, QUEST, SPACE, NONSPACE, DIGIT, RANGE};
#ifdef SLRE_TEST
static struct {
@@ -55,7 +55,8 @@ static struct {
{"QUEST", 1, "o"}, /* Match zero or one time, "?" */
{"SPACE", 0, ""}, /* Match whitespace, "\s" */
{"NONSPACE", 0, ""}, /* Match non-space, "\S" */
- {"DIGIT", 0, ""} /* Match digit, "\d" */
+ {"DIGIT", 0, ""}, /* Match digit, "\d" */
+ {"RANGE", 0, ""}, /* Range separator - */
};
#endif /* SLRE_TEST */
@@ -260,6 +261,15 @@ anyof(struct slre *r, const char **re)
return;
/* NOTREACHED */
break;
+ case '-':
+ if (r->data_size == old_data_size || **re == ']') {
+ /* First or last character, just match - itself. */
+ store_char_in_data(r, '-');
+ break;
+ }
+ store_char_in_data(r, 0);
+ store_char_in_data(r, RANGE);
+ break;
case '\\':
esc = get_escape_char(re);
if ((esc & 0xff) == 0) {
@@ -413,10 +423,7 @@ int
slre_compile(struct slre *r, const char *re)
{
r->err_str = NULL;
- r->code_size = r->data_size = r->num_caps = r->anchored = 0;
-
- if (*re == '^')
- r->anchored++;
+ r->code_size = r->data_size = r->num_caps = 0;
emit(r, OPEN); /* This will capture what matches full RE */
emit(r, 0);
@@ -475,29 +482,54 @@ is_any_of(const unsigned char *p, int len, const char *s, int *ofs)
ch = s[*ofs];
- for (i = 0; i < len; i++)
- if (p[i] == ch) {
- (*ofs)++;
- return 1;
+ for (i = 0; i < len; i++) {
+ if (p[i] == '\0') {
+ switch (p[++i]) {
+ case NONSPACE:
+ if (!isspace(ch))
+ goto match;
+ break;
+ case SPACE:
+ if (isspace(ch))
+ goto match;
+ break;
+ case DIGIT:
+ if (isdigit(ch))
+ goto match;
+ break;
+ case RANGE:
+ /*
+ * a-z is represented in the data array as {'a', \0, RANGE, 'z'}
+ */
+ ++i;
+ if (p[i - 3] <= (unsigned char)ch && (unsigned char)ch <= p[i])
+ goto match;
+ break;
+ }
+ continue;
}
+ if (p[i] == ch)
+ goto match;
+ }
return 0;
+
+match:
+ (*ofs)++;
+ return 1;
}
static int
is_any_but(const unsigned char *p, int len, const char *s, int *ofs)
{
- int i, ch;
-
- ch = s[*ofs];
+ int dummy = *ofs;
- for (i = 0; i < len; i++) {
- if (p[i] == ch)
- return 0;
+ if (is_any_of(p, len, s, &dummy)) {
+ return 0;
+ } else {
+ (*ofs)++;
+ return 1;
}
-
- (*ofs)++;
- return 1;
}
static int
@@ -650,13 +682,9 @@ slre_match(const struct slre *r, const char *buf, int len,
{
int i, ofs = 0, res = 0;
- if (r->anchored) {
+ for (i = 0; i <= len && res == 0; i++) {
+ ofs = i;
res = match(r, 0, buf, len, &ofs, caps);
- } else {
- for (i = 0; i < len && res == 0; i++) {
- ofs = i;
- res = match(r, 0, buf, len, &ofs, caps);
- }
}
return res;
diff --git a/lib/tiny-printf.c b/lib/tiny-printf.c
index 2a7a4d286c0..411ae6189f2 100644
--- a/lib/tiny-printf.c
+++ b/lib/tiny-printf.c
@@ -141,7 +141,7 @@ static void ip4_addr_string(struct printf_info *info, u8 *addr)
string(info, ip4_addr);
}
-#endif
+#endif /* CONFIG_SPL_NET */
/*
* Show a '%p' thing. A kernel extension is that the '%p' is followed
@@ -157,18 +157,14 @@ static void ip4_addr_string(struct printf_info *info, u8 *addr)
* decimal).
*/
-static void __maybe_unused pointer(struct printf_info *info, const char *fmt,
- void *ptr)
+#if defined(CONFIG_SPL_USE_TINY_PRINTF_POINTER_SUPPORT) || defined(DEBUG)
+static void pointer(struct printf_info *info, const char *fmt, void *ptr)
{
-#ifdef DEBUG
unsigned long num = (uintptr_t)ptr;
unsigned long div;
-#endif
switch (*fmt) {
-#ifdef DEBUG
case 'a':
-
switch (fmt[1]) {
case 'p':
default:
@@ -176,7 +172,6 @@ static void __maybe_unused pointer(struct printf_info *info, const char *fmt,
break;
}
break;
-#endif
#ifdef CONFIG_SPL_NET
case 'm':
return mac_address_string(info, ptr, false);
@@ -185,16 +180,22 @@ static void __maybe_unused pointer(struct printf_info *info, const char *fmt,
case 'I':
if (fmt[1] == '4')
return ip4_addr_string(info, ptr);
+#else
+ case 'm':
+ case 'M':
+ case 'I':
+ out(info, '?');
+ return;
#endif
default:
break;
}
-#ifdef DEBUG
+
div = 1UL << (sizeof(long) * 8 - 4);
for (; div; div /= 0x10)
div_out(info, &num, div);
-#endif
}
+#endif
static int _vprintf(struct printf_info *info, const char *fmt, va_list va)
{
@@ -269,21 +270,18 @@ static int _vprintf(struct printf_info *info, const char *fmt, va_list va)
div_out(info, &num, div);
}
break;
+#if defined(CONFIG_SPL_USE_TINY_PRINTF_POINTER_SUPPORT) || defined(DEBUG)
case 'p':
- if (CONFIG_IS_ENABLED(NET) ||
- CONFIG_IS_ENABLED(NET_LWIP) || _DEBUG) {
- pointer(info, fmt, va_arg(va, void *));
- /*
- * Skip this because it pulls in _ctype which is
- * 256 bytes, and we don't generally implement
- * pointer anyway
- */
- while (isalnum(fmt[0]))
- fmt++;
- break;
- }
- islong = true;
- fallthrough;
+ pointer(info, fmt, va_arg(va, void *));
+ /*
+ * Skip this because it pulls in _ctype which is
+ * 256 bytes, and we don't generally implement
+ * pointer anyway
+ */
+ while (isalnum(fmt[0]))
+ fmt++;
+ break;
+#endif
case 'x':
case 'X':
if (islong) {
@@ -310,7 +308,9 @@ static int _vprintf(struct printf_info *info, const char *fmt, va_list va)
break;
case '%':
out(info, '%');
+ break;
default:
+ out(info, '?');
break;
}
diff --git a/lib/tpm-v2.c b/lib/tpm-v2.c
index 9ca7933c094..5b21c57ae42 100644
--- a/lib/tpm-v2.c
+++ b/lib/tpm-v2.c
@@ -1141,7 +1141,7 @@ enum tpm2_algorithms tpm2_name_to_algorithm(const char *name)
}
printf("%s: unsupported algorithm %s\n", __func__, name);
- return -EINVAL;
+ return TPM2_ALG_INVAL;
}
const char *tpm2_algorithm_name(enum tpm2_algorithms algo)
diff --git a/lib/trace.c b/lib/trace.c
index 1d5f7dec979..3d54dfaddc0 100644
--- a/lib/trace.c
+++ b/lib/trace.c
@@ -66,7 +66,7 @@ static inline uintptr_t __attribute__((no_instrument_function))
/**
* trace_gd - the value of the gd register
*/
-static volatile gd_t *trace_gd;
+static gd_t *trace_gd;
/**
* trace_save_gd() - save the value of the gd register
@@ -86,7 +86,7 @@ static void notrace trace_save_gd(void)
*/
static void notrace trace_swap_gd(void)
{
- volatile gd_t *temp_gd = trace_gd;
+ gd_t *temp_gd = trace_gd;
trace_gd = gd;
set_gd(temp_gd);