diff options
author | Tom Rini <trini@konsulko.com> | 2023-03-25 17:34:34 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2023-03-25 17:34:34 -0400 |
commit | fde439219ff53a46bdd5dff69e049ccd4be57310 (patch) | |
tree | 423643707fad940e0845cbebf74d545b05b3d336 /lib | |
parent | 4b635046b5e92e419fbd1bf93e5b0ef86dbcadc2 (diff) | |
parent | 93e3364804ffd4a5d4a0df9c750a1859f9fe298b (diff) |
Merge tag 'efi-next-20230325' of https://source.denx.de/u-boot/custodians/u-boot-efi into next
Pull request for efi-next-20230325
Documenation:
* add man-page for efi command
UEFI:
* Let EFI app call ExitBootServices() before legacy booting kernel
* Support zboot and bootm in the EFI app
* Let efi command show configuration tables
* Support booting a 64-bit kernel from 64-bit EFI app
* Allocate device-tree copy from high memory
* simplify efi_str_to_u16()
Diffstat (limited to 'lib')
-rw-r--r-- | lib/efi_loader/efi_device_path.c | 85 | ||||
-rw-r--r-- | lib/efi_loader/efi_device_path_to_text.c | 12 | ||||
-rw-r--r-- | lib/efi_loader/efi_memory.c | 46 | ||||
-rw-r--r-- | lib/uuid.c | 10 |
4 files changed, 89 insertions, 64 deletions
diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c index 3b267b713e98..d5cc49583041 100644 --- a/lib/efi_loader/efi_device_path.c +++ b/lib/efi_loader/efi_device_path.c @@ -63,20 +63,6 @@ static bool is_sd(struct blk_desc *desc) } #endif -static void *dp_alloc(size_t sz) -{ - void *buf; - - if (efi_allocate_pool(EFI_BOOT_SERVICES_DATA, sz, &buf) != - EFI_SUCCESS) { - debug("EFI: ERROR: out of memory in %s\n", __func__); - return NULL; - } - - memset(buf, 0, sz); - return buf; -} - /* * Iterate to next block in device-path, terminating (returning NULL) * at /End* node. @@ -147,7 +133,7 @@ struct efi_device_path *efi_dp_shorten(struct efi_device_path *dp) * in practice fallback.efi just uses MEDIA:HARD_DRIVE * so not sure when we would see these other cases. */ - if (EFI_DP_TYPE(dp, MESSAGING_DEVICE, MSG_USB_CLASS) || + if (EFI_DP_TYPE(dp, MESSAGING_DEVICE, MSG_USB) || EFI_DP_TYPE(dp, MEDIA_DEVICE, HARD_DRIVE_PATH) || EFI_DP_TYPE(dp, MEDIA_DEVICE, FILE_PATH)) return dp; @@ -302,7 +288,7 @@ struct efi_device_path *efi_dp_dup(const struct efi_device_path *dp) if (!dp) return NULL; - ndp = dp_alloc(sz); + ndp = efi_alloc(sz); if (!ndp) return NULL; memcpy(ndp, dp, sz); @@ -346,7 +332,7 @@ efi_device_path *efi_dp_append_or_concatenate(const struct efi_device_path *dp1, /* both dp1 and dp2 are non-null */ unsigned sz1 = efi_dp_size(dp1); unsigned sz2 = efi_dp_size(dp2); - void *p = dp_alloc(sz1 + sz2 + end_size); + void *p = efi_alloc(sz1 + sz2 + end_size); if (!p) return NULL; ret = p; @@ -409,7 +395,7 @@ struct efi_device_path *efi_dp_append_node(const struct efi_device_path *dp, ret = efi_dp_dup(dp); } else if (!dp) { size_t sz = node->length; - void *p = dp_alloc(sz + sizeof(END)); + void *p = efi_alloc(sz + sizeof(END)); if (!p) return NULL; memcpy(p, node, sz); @@ -418,7 +404,7 @@ struct efi_device_path *efi_dp_append_node(const struct efi_device_path *dp, } else { /* both dp and node are non-null */ size_t sz = efi_dp_size(dp); - void *p = dp_alloc(sz + node->length + sizeof(END)); + void *p = efi_alloc(sz + node->length + sizeof(END)); if (!p) return NULL; memcpy(p, dp, sz); @@ -439,7 +425,7 @@ struct efi_device_path *efi_dp_create_device_node(const u8 type, if (length < sizeof(struct efi_device_path)) return NULL; - ret = dp_alloc(length); + ret = efi_alloc(length); if (!ret) return ret; ret->type = type; @@ -461,7 +447,7 @@ struct efi_device_path *efi_dp_append_instance( return efi_dp_dup(dpi); sz = efi_dp_size(dp); szi = efi_dp_instance_size(dpi); - p = dp_alloc(sz + szi + 2 * sizeof(END)); + p = efi_alloc(sz + szi + 2 * sizeof(END)); if (!p) return NULL; ret = p; @@ -486,7 +472,7 @@ struct efi_device_path *efi_dp_get_next_instance(struct efi_device_path **dp, if (!dp || !*dp) return NULL; sz = efi_dp_instance_size(*dp); - p = dp_alloc(sz + sizeof(END)); + p = efi_alloc(sz + sizeof(END)); if (!p) return NULL; memcpy(p, *dp, sz + sizeof(END)); @@ -564,6 +550,11 @@ __maybe_unused static unsigned int dp_size(struct udevice *dev) return dp_size(dev->parent) + sizeof(struct efi_device_path_vendor) + 1; #endif +#ifdef CONFIG_USB + case UCLASS_MASS_STORAGE: + return dp_size(dev->parent) + + sizeof(struct efi_device_path_controller); +#endif #ifdef CONFIG_VIRTIO_BLK case UCLASS_VIRTIO: /* @@ -585,7 +576,7 @@ __maybe_unused static unsigned int dp_size(struct udevice *dev) case UCLASS_MASS_STORAGE: case UCLASS_USB_HUB: return dp_size(dev->parent) + - sizeof(struct efi_device_path_usb_class); + sizeof(struct efi_device_path_usb); default: /* just skip over unknown classes: */ return dp_size(dev->parent); @@ -742,6 +733,19 @@ __maybe_unused static void *dp_fill(void *buf, struct udevice *dev) return &dp[1]; } #endif +#if defined(CONFIG_USB) + case UCLASS_MASS_STORAGE: { + struct blk_desc *desc = desc = dev_get_uclass_plat(dev); + struct efi_device_path_controller *dp = + dp_fill(buf, dev->parent); + + dp->dp.type = DEVICE_PATH_TYPE_HARDWARE_DEVICE; + dp->dp.sub_type = DEVICE_PATH_SUB_TYPE_CONTROLLER; + dp->dp.length = sizeof(*dp); + dp->controller_number = desc->lun; + return &dp[1]; + } +#endif default: debug("%s(%u) %s: unhandled parent class: %s (%u)\n", __FILE__, __LINE__, __func__, @@ -767,19 +771,22 @@ __maybe_unused static void *dp_fill(void *buf, struct udevice *dev) #endif case UCLASS_MASS_STORAGE: case UCLASS_USB_HUB: { - struct efi_device_path_usb_class *udp = - dp_fill(buf, dev->parent); - struct usb_device *udev = dev_get_parent_priv(dev); - struct usb_device_descriptor *desc = &udev->descriptor; + struct efi_device_path_usb *udp = dp_fill(buf, dev->parent); + switch (device_get_uclass_id(dev->parent)) { + case UCLASS_USB_HUB: { + struct usb_device *udev = dev_get_parent_priv(dev); + + udp->parent_port_number = udev->portnr; + break; + } + default: + udp->parent_port_number = 0; + } udp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE; - udp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_USB_CLASS; + udp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_USB; udp->dp.length = sizeof(*udp); - udp->vendor_id = desc->idVendor; - udp->product_id = desc->idProduct; - udp->device_class = desc->bDeviceClass; - udp->device_subclass = desc->bDeviceSubClass; - udp->device_protocol = desc->bDeviceProtocol; + udp->usb_interface = 0; return &udp[1]; } @@ -906,7 +913,7 @@ struct efi_device_path *efi_dp_from_part(struct blk_desc *desc, int part) { void *buf, *start; - start = buf = dp_alloc(dp_part_size(desc, part) + sizeof(END)); + start = buf = efi_alloc(dp_part_size(desc, part) + sizeof(END)); if (!buf) return NULL; @@ -933,7 +940,7 @@ struct efi_device_path *efi_dp_part_node(struct blk_desc *desc, int part) dpsize = sizeof(struct efi_device_path_cdrom_path); else dpsize = sizeof(struct efi_device_path_hard_drive_path); - buf = dp_alloc(dpsize); + buf = efi_alloc(dpsize); if (buf) dp_part_node(buf, desc, part); @@ -1007,7 +1014,7 @@ struct efi_device_path *efi_dp_from_file(struct blk_desc *desc, int part, dpsize += fpsize; - start = buf = dp_alloc(dpsize + sizeof(END)); + start = buf = efi_alloc(dpsize + sizeof(END)); if (!buf) return NULL; @@ -1035,7 +1042,7 @@ struct efi_device_path *efi_dp_from_uart(void) struct efi_device_path_uart *uart; size_t dpsize = sizeof(ROOT) + sizeof(*uart) + sizeof(END); - buf = dp_alloc(dpsize); + buf = efi_alloc(dpsize); if (!buf) return NULL; pos = buf; @@ -1061,7 +1068,7 @@ struct efi_device_path *efi_dp_from_eth(void) dpsize += dp_size(eth_get_dev()); - start = buf = dp_alloc(dpsize + sizeof(END)); + start = buf = efi_alloc(dpsize + sizeof(END)); if (!buf) return NULL; @@ -1081,7 +1088,7 @@ struct efi_device_path *efi_dp_from_mem(uint32_t memory_type, struct efi_device_path_memory *mdp; void *buf, *start; - start = buf = dp_alloc(sizeof(*mdp) + sizeof(END)); + start = buf = efi_alloc(sizeof(*mdp) + sizeof(END)); if (!buf) return NULL; diff --git a/lib/efi_loader/efi_device_path_to_text.c b/lib/efi_loader/efi_device_path_to_text.c index 9062058ac229..8c76d8be605d 100644 --- a/lib/efi_loader/efi_device_path_to_text.c +++ b/lib/efi_loader/efi_device_path_to_text.c @@ -32,11 +32,10 @@ static u16 *efi_str_to_u16(char *str) { efi_uintn_t len; u16 *out, *dst; - efi_status_t ret; len = sizeof(u16) * (utf8_utf16_strlen(str) + 1); - ret = efi_allocate_pool(EFI_BOOT_SERVICES_DATA, len, (void **)&out); - if (ret != EFI_SUCCESS) + out = efi_alloc(len); + if (!out) return NULL; dst = out; utf8_utf16_strcpy(&dst, str); @@ -77,6 +76,13 @@ static char *dp_hardware(char *s, struct efi_device_path *dp) s += sprintf(s, ")"); break; } + case DEVICE_PATH_SUB_TYPE_CONTROLLER: { + struct efi_device_path_controller *cdp = + (struct efi_device_path_controller *)dp; + + s += sprintf(s, "Ctrl(0x%0x)", cdp->controller_number); + break; + } default: s = dp_unknown(s, dp); break; diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c index b7bee98f79c3..8f82496740fa 100644 --- a/lib/efi_loader/efi_memory.c +++ b/lib/efi_loader/efi_memory.c @@ -5,9 +5,12 @@ * Copyright (c) 2016 Alexander Graf */ +#define LOG_CATEGORY LOGC_EFI + #include <common.h> #include <efi_loader.h> #include <init.h> +#include <log.h> #include <malloc.h> #include <mapmem.h> #include <watchdog.h> @@ -534,27 +537,6 @@ efi_status_t efi_allocate_pages(enum efi_allocate_type type, } /** - * efi_alloc() - allocate memory pages - * - * @len: size of the memory to be allocated - * @memory_type: usage type of the allocated memory - * Return: pointer to the allocated memory area or NULL - */ -void *efi_alloc(uint64_t len, int memory_type) -{ - uint64_t ret = 0; - uint64_t pages = efi_size_in_pages(len); - efi_status_t r; - - r = efi_allocate_pages(EFI_ALLOCATE_ANY_PAGES, memory_type, pages, - &ret); - if (r == EFI_SUCCESS) - return (void*)(uintptr_t)ret; - - return NULL; -} - -/** * efi_free_pages() - free memory pages * * @memory: start of the memory area to be freed @@ -673,6 +655,28 @@ efi_status_t efi_allocate_pool(enum efi_memory_type pool_type, efi_uintn_t size, } /** + * efi_alloc() - allocate boot services data pool memory + * + * Allocate memory from pool and zero it out. + * + * @size: number of bytes to allocate + * Return: pointer to allocated memory or NULL + */ +void *efi_alloc(size_t size) +{ + void *buf; + + if (efi_allocate_pool(EFI_BOOT_SERVICES_DATA, size, &buf) != + EFI_SUCCESS) { + log_err("out of memory"); + return NULL; + } + memset(buf, 0, size); + + return buf; +} + +/** * efi_free_pool() - free memory from pool * * @buffer: start of memory to be freed diff --git a/lib/uuid.c b/lib/uuid.c index 465e1ac38f57..96e1af3c8b00 100644 --- a/lib/uuid.c +++ b/lib/uuid.c @@ -102,7 +102,7 @@ static const struct { {"lvm", PARTITION_LINUX_LVM_GUID}, {"u-boot-env", PARTITION_U_BOOT_ENVIRONMENT}, #endif -#ifdef CONFIG_CMD_EFIDEBUG +#if defined(CONFIG_CMD_EFIDEBUG) || defined(CONFIG_EFI) { "Device Path", EFI_DEVICE_PATH_PROTOCOL_GUID, @@ -255,6 +255,14 @@ static const struct { EFI_CERT_TYPE_PKCS7_GUID, }, #endif +#ifdef CONFIG_EFI + { "EFI_LZMA_COMPRESSED", EFI_LZMA_COMPRESSED }, + { "EFI_DXE_SERVICES", EFI_DXE_SERVICES }, + { "EFI_HOB_LIST", EFI_HOB_LIST }, + { "EFI_MEMORY_TYPE", EFI_MEMORY_TYPE }, + { "EFI_MEM_STATUS_CODE_REC", EFI_MEM_STATUS_CODE_REC }, + { "EFI_GUID_EFI_ACPI1", EFI_GUID_EFI_ACPI1 }, +#endif }; /* |