diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Kconfig | 10 | ||||
-rw-r--r-- | lib/Makefile | 2 | ||||
-rw-r--r-- | lib/acpi/Makefile | 6 | ||||
-rw-r--r-- | lib/acpi/acpi.c | 45 | ||||
-rw-r--r-- | lib/efi_loader/efi_bootmgr.c | 13 | ||||
-rw-r--r-- | lib/efi_loader/efi_device_path.c | 99 | ||||
-rw-r--r-- | lib/efi_loader/helloworld.c | 8 | ||||
-rw-r--r-- | lib/efi_selftest/efi_selftest_register_notify.c | 16 | ||||
-rw-r--r-- | lib/fwu_updates/Kconfig | 2 |
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 |