aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Kconfig10
-rw-r--r--lib/Makefile2
-rw-r--r--lib/acpi/Makefile6
-rw-r--r--lib/acpi/acpi.c45
-rw-r--r--lib/efi_loader/efi_bootmgr.c13
-rw-r--r--lib/efi_loader/efi_device_path.c99
-rw-r--r--lib/efi_loader/helloworld.c8
-rw-r--r--lib/efi_selftest/efi_selftest_register_notify.c16
-rw-r--r--lib/fwu_updates/Kconfig2
9 files changed, 118 insertions, 83 deletions
diff --git a/lib/Kconfig b/lib/Kconfig
index d8dac09ea8..c8b3ec1ec9 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -281,9 +281,17 @@ config SUPPORT_ACPI
U-Boot can generate these tables and pass them to the Operating
System.
+config ACPI
+ bool "Enable support for ACPI libraries"
+ depends on SUPPORT_ACPI
+ help
+ Provides library functions for dealing with ACPI tables. This does
+ not necessarily include generation of tables
+ (see GENERATE_ACPI_TABLE), but allows for tables to be located.
+
config GENERATE_ACPI_TABLE
bool "Generate an ACPI (Advanced Configuration and Power Interface) table"
- depends on SUPPORT_ACPI
+ depends on ACPI
select QFW if QEMU
help
The Advanced Configuration and Power Interface (ACPI) specification
diff --git a/lib/Makefile b/lib/Makefile
index 10aa7ac029..8d8ccc8bbc 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -66,7 +66,7 @@ obj-$(CONFIG_$(SPL_TPL_)CRC8) += crc8.o
obj-y += crypto/
-obj-$(CONFIG_$(SPL_TPL_)GENERATE_ACPI_TABLE) += acpi/
+obj-$(CONFIG_$(SPL_TPL_)ACPI) += acpi/
obj-$(CONFIG_$(SPL_)MD5) += md5.o
obj-$(CONFIG_ECDSA) += ecdsa/
obj-$(CONFIG_$(SPL_)RSA) += rsa/
diff --git a/lib/acpi/Makefile b/lib/acpi/Makefile
index 956b5a0d72..c1c9675b5d 100644
--- a/lib/acpi/Makefile
+++ b/lib/acpi/Makefile
@@ -1,6 +1,10 @@
# SPDX-License-Identifier: GPL-2.0+
#
+obj-y += acpi.o
+
+ifdef CONFIG_$(SPL_TPL_)GENERATE_ACPI_TABLE
+
obj-$(CONFIG_$(SPL_)ACPIGEN) += acpigen.o
obj-$(CONFIG_$(SPL_)ACPIGEN) += acpi_device.o
obj-$(CONFIG_$(SPL_)ACPIGEN) += acpi_dp.o
@@ -21,3 +25,5 @@ endif
obj-y += facs.o
obj-y += ssdt.o
endif
+
+endif # GENERATE_ACPI_TABLE
diff --git a/lib/acpi/acpi.c b/lib/acpi/acpi.c
new file mode 100644
index 0000000000..14b15754f4
--- /dev/null
+++ b/lib/acpi/acpi.c
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Utility functions for ACPI
+ *
+ * Copyright 2023 Google LLC
+ */
+
+#include <common.h>
+#include <mapmem.h>
+#include <acpi/acpi_table.h>
+#include <asm/global_data.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct acpi_table_header *acpi_find_table(const char *sig)
+{
+ struct acpi_rsdp *rsdp;
+ struct acpi_rsdt *rsdt;
+ int len, i, count;
+
+ rsdp = map_sysmem(gd_acpi_start(), 0);
+ if (!rsdp)
+ return NULL;
+ rsdt = map_sysmem(rsdp->rsdt_address, 0);
+ len = rsdt->header.length - sizeof(rsdt->header);
+ count = len / sizeof(u32);
+ for (i = 0; i < count; i++) {
+ struct acpi_table_header *hdr;
+
+ hdr = map_sysmem(rsdt->entry[i], 0);
+ if (!memcmp(hdr->signature, sig, ACPI_NAME_LEN))
+ return hdr;
+ if (!memcmp(hdr->signature, "FACP", ACPI_NAME_LEN)) {
+ struct acpi_fadt *fadt = (struct acpi_fadt *)hdr;
+
+ if (!memcmp(sig, "DSDT", ACPI_NAME_LEN) && fadt->dsdt)
+ return map_sysmem(fadt->dsdt, 0);
+ if (!memcmp(sig, "FACS", ACPI_NAME_LEN) &&
+ fadt->firmware_ctrl)
+ return map_sysmem(fadt->firmware_ctrl, 0);
+ }
+ }
+
+ return NULL;
+}
diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c
index 4b24b41047..7ac5f89f76 100644
--- a/lib/efi_loader/efi_bootmgr.c
+++ b/lib/efi_loader/efi_bootmgr.c
@@ -47,7 +47,7 @@ const efi_guid_t efi_guid_bootmenu_auto_generated =
static
struct efi_device_path *expand_media_path(struct efi_device_path *device_path)
{
- struct efi_device_path *dp, *rem, *full_path;
+ struct efi_device_path *rem, *full_path;
efi_handle_t handle;
if (!device_path)
@@ -58,15 +58,12 @@ struct efi_device_path *expand_media_path(struct efi_device_path *device_path)
* simple file system protocol, append a default file name to support
* booting from removable media.
*/
- dp = device_path;
- handle = efi_dp_find_obj(dp, &efi_simple_file_system_protocol_guid,
- &rem);
+ handle = efi_dp_find_obj(device_path,
+ &efi_simple_file_system_protocol_guid, &rem);
if (handle) {
if (rem->type == DEVICE_PATH_TYPE_END) {
- dp = efi_dp_from_file(NULL, 0,
- "/EFI/BOOT/" BOOTEFI_NAME);
- full_path = efi_dp_append(device_path, dp);
- efi_free_pool(dp);
+ full_path = efi_dp_from_file(device_path,
+ "/EFI/BOOT/" BOOTEFI_NAME);
} else {
full_path = efi_dp_dup(device_path);
}
diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c
index e2e98a39be..04ebb449ca 100644
--- a/lib/efi_loader/efi_device_path.c
+++ b/lib/efi_loader/efi_device_path.c
@@ -843,12 +843,17 @@ static unsigned dp_part_size(struct blk_desc *desc, int part)
* @buf buffer to which the device path is written
* @desc block device descriptor
* @part partition number, 0 identifies a block device
+ *
+ * Return: pointer to position after the node
*/
static void *dp_part_node(void *buf, struct blk_desc *desc, int part)
{
struct disk_partition info;
+ int ret;
- part_get_info(desc, part, &info);
+ ret = part_get_info(desc, part, &info);
+ if (ret < 0)
+ return buf;
if (desc->part_type == PART_TYPE_ISO) {
struct efi_device_path_cdrom_path *cddp = buf;
@@ -1002,59 +1007,45 @@ static void path_to_uefi(void *uefi, const char *src)
}
/**
- * efi_dp_from_file() - create device path for file
- *
- * The function creates a device path from the block descriptor @desc and the
- * partition number @part and appends a device path node created describing the
- * file path @path.
+ * efi_dp_from_file() - append file path node to device path.
*
- * If @desc is NULL, the device path will not contain nodes describing the
- * partition.
- * If @path is an empty string "", the device path will not contain a node
- * for the file path.
- *
- * @desc: block device descriptor or NULL
- * @part: partition number
- * @path: file path on partition or ""
+ * @dp: device path or NULL
+ * @path: file path or NULL
* Return: device path or NULL in case of an error
*/
-struct efi_device_path *efi_dp_from_file(struct blk_desc *desc, int part,
- const char *path)
+struct efi_device_path *efi_dp_from_file(const struct efi_device_path *dp,
+ const char *path)
{
struct efi_device_path_file_path *fp;
- void *buf, *start;
- size_t dpsize = 0, fpsize;
-
- if (desc)
- dpsize = dp_part_size(desc, part);
+ void *buf, *pos;
+ size_t dpsize, fpsize;
+ dpsize = efi_dp_size(dp);
fpsize = sizeof(struct efi_device_path) +
2 * (utf8_utf16_strlen(path) + 1);
if (fpsize > U16_MAX)
return NULL;
- dpsize += fpsize;
-
- start = buf = efi_alloc(dpsize + sizeof(END));
+ buf = efi_alloc(dpsize + fpsize + sizeof(END));
if (!buf)
return NULL;
- if (desc)
- buf = dp_part_fill(buf, desc, part);
+ memcpy(buf, dp, dpsize);
+ pos = buf + dpsize;
/* add file-path: */
if (*path) {
- fp = buf;
+ fp = pos;
fp->dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE;
fp->dp.sub_type = DEVICE_PATH_SUB_TYPE_FILE_PATH;
fp->dp.length = (u16)fpsize;
path_to_uefi(fp->str, path);
- buf += fpsize;
+ pos += fpsize;
}
- *((struct efi_device_path *)buf) = END;
+ memcpy(pos, &END, sizeof(END));
- return start;
+ return buf;
}
struct efi_device_path *efi_dp_from_uart(void)
@@ -1079,8 +1070,7 @@ struct efi_device_path *efi_dp_from_uart(void)
return buf;
}
-#ifdef CONFIG_NETDEVICES
-struct efi_device_path *efi_dp_from_eth(void)
+struct efi_device_path __maybe_unused *efi_dp_from_eth(void)
{
void *buf, *start;
unsigned dpsize = 0;
@@ -1099,7 +1089,6 @@ struct efi_device_path *efi_dp_from_eth(void)
return start;
}
-#endif
/* Construct a device-path for memory-mapped image */
struct efi_device_path *efi_dp_from_mem(uint32_t memory_type,
@@ -1185,58 +1174,42 @@ efi_status_t efi_dp_from_name(const char *dev, const char *devnr,
struct efi_device_path **file)
{
struct blk_desc *desc = NULL;
+ struct efi_device_path *dp;
struct disk_partition fs_partition;
size_t image_size;
void *image_addr;
int part = 0;
- char *filename;
- char *s;
if (path && !file)
return EFI_INVALID_PARAMETER;
- if (!strcmp(dev, "Net")) {
-#ifdef CONFIG_NETDEVICES
- if (device)
- *device = efi_dp_from_eth();
-#endif
- } else if (!strcmp(dev, "Uart")) {
- if (device)
- *device = efi_dp_from_uart();
- } else if (!strcmp(dev, "Mem")) {
+ if (!strcmp(dev, "Mem") || !strcmp(dev, "hostfs")) {
+ /* loadm command and semihosting */
efi_get_image_parameters(&image_addr, &image_size);
- if (device)
- *device = efi_dp_from_mem(EFI_RESERVED_MEMORY_TYPE,
- (uintptr_t)image_addr,
- image_size);
+ dp = efi_dp_from_mem(EFI_RESERVED_MEMORY_TYPE,
+ (uintptr_t)image_addr, image_size);
+ } else if (IS_ENABLED(CONFIG_NETDEVICES) && !strcmp(dev, "Net")) {
+ dp = efi_dp_from_eth();
+ } else if (!strcmp(dev, "Uart")) {
+ dp = efi_dp_from_uart();
} else {
part = blk_get_device_part_str(dev, devnr, &desc, &fs_partition,
1);
if (part < 0 || !desc)
return EFI_INVALID_PARAMETER;
- if (device)
- *device = efi_dp_from_part(desc, part);
+ dp = efi_dp_from_part(desc, part);
}
+ if (device)
+ *device = dp;
if (!path)
return EFI_SUCCESS;
- filename = calloc(1, strlen(path) + 1);
- if (!filename)
- return EFI_OUT_OF_RESOURCES;
-
- sprintf(filename, "%s", path);
- /* DOS style file path: */
- s = filename;
- while ((s = strchr(s, '/')))
- *s++ = '\\';
- *file = efi_dp_from_file(desc, part, filename);
- free(filename);
-
+ *file = efi_dp_from_file(dp, path);
if (!*file)
- return EFI_INVALID_PARAMETER;
+ return EFI_OUT_OF_RESOURCES;
return EFI_SUCCESS;
}
diff --git a/lib/efi_loader/helloworld.c b/lib/efi_loader/helloworld.c
index 6405f58ec3..bd72822c0b 100644
--- a/lib/efi_loader/helloworld.c
+++ b/lib/efi_loader/helloworld.c
@@ -216,6 +216,10 @@ efi_status_t EFIAPI efi_main(efi_handle_t handle,
(con_out, u"Cannot open device path to text protocol\r\n");
goto out;
}
+ con_out->output_string(con_out, u"File path: ");
+ ret = print_device_path(loaded_image->file_path, device_path_to_text);
+ if (ret != EFI_SUCCESS)
+ goto out;
if (!loaded_image->device_handle) {
con_out->output_string
(con_out, u"Missing device handle\r\n");
@@ -234,10 +238,6 @@ efi_status_t EFIAPI efi_main(efi_handle_t handle,
ret = print_device_path(device_path, device_path_to_text);
if (ret != EFI_SUCCESS)
goto out;
- con_out->output_string(con_out, u"File path: ");
- ret = print_device_path(loaded_image->file_path, device_path_to_text);
- if (ret != EFI_SUCCESS)
- goto out;
out:
boottime->exit(handle, ret, 0, NULL);
diff --git a/lib/efi_selftest/efi_selftest_register_notify.c b/lib/efi_selftest/efi_selftest_register_notify.c
index ad763dd6cb..ad4bcce1a1 100644
--- a/lib/efi_selftest/efi_selftest_register_notify.c
+++ b/lib/efi_selftest/efi_selftest_register_notify.c
@@ -24,6 +24,7 @@ struct context {
efi_uintn_t notify_count;
efi_uintn_t handle_count;
efi_handle_t *handles;
+ efi_status_t ret;
};
static struct efi_boot_services *boottime;
@@ -46,17 +47,18 @@ static struct efi_event *event;
static void EFIAPI notify(struct efi_event *event, void *context)
{
struct context *cp = context;
- efi_status_t ret;
efi_uintn_t handle_count;
efi_handle_t *handles;
cp->notify_count++;
for (;;) {
- ret = boottime->locate_handle_buffer(BY_REGISTER_NOTIFY, NULL,
- cp->registration_key,
- &handle_count, &handles);
- if (ret != EFI_SUCCESS)
+ cp->ret = boottime->locate_handle_buffer(BY_REGISTER_NOTIFY,
+ NULL,
+ cp->registration_key,
+ &handle_count,
+ &handles);
+ if (cp->ret != EFI_SUCCESS)
break;
cp->handle_count += handle_count;
cp->handles = handles;
@@ -204,6 +206,10 @@ static int execute(void)
efi_st_error("LocateHandle failed\n");
return EFI_ST_FAILURE;
}
+ if (context.ret != EFI_NOT_FOUND) {
+ efi_st_error("LocateHandle did not return EFI_NOT_FOUND\n");
+ return EFI_ST_FAILURE;
+ }
ret = boottime->free_pool(context.handles);
if (ret != EFI_SUCCESS) {
efi_st_error("FreePool failed\n");
diff --git a/lib/fwu_updates/Kconfig b/lib/fwu_updates/Kconfig
index 78759e6618..71f34793d9 100644
--- a/lib/fwu_updates/Kconfig
+++ b/lib/fwu_updates/Kconfig
@@ -2,7 +2,7 @@ config FWU_MULTI_BANK_UPDATE
bool "Enable FWU Multi Bank Update Feature"
depends on EFI_CAPSULE_ON_DISK
select PARTITION_TYPE_GUID
- select EFI_SETUP_EARLY
+ select FWU_MDATA
imply EFI_CAPSULE_ON_DISK_EARLY
select EVENT
help