From: Heinrich Schuchardt Date: Fri, 4 Dec 2020 02:02:03 +0000 (+0100) Subject: efi_loader: resequence functions in efi_boottime.c X-Git-Url: http://git.dujemihanovic.xyz/%22http:/www.sics.se/static/git-logo.png?a=commitdiff_plain;h=0e9d2d7bc25bd3114e8f6ff0d18cdf9ee675909c;p=u-boot.git efi_loader: resequence functions in efi_boottime.c For implementing support for the EFI_LOAD_FILE_PROTOCOL in the LoadImage() service we will have to call the LocateDevicePath() service. To avoid a forward declaration resequence the functions. Signed-off-by: Heinrich Schuchardt --- diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 246b59d3b3..4f7479d4df 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -1769,6 +1769,88 @@ failure: return ret; } +/** + * efi_locate_device_path() - Get the device path and handle of an device + * implementing a protocol + * @protocol: GUID of the protocol + * @device_path: device path + * @device: handle of the device + * + * This function implements the LocateDevicePath service. + * + * See the Unified Extensible Firmware Interface (UEFI) specification for + * details. + * + * Return: status code + */ +static efi_status_t EFIAPI efi_locate_device_path( + const efi_guid_t *protocol, + struct efi_device_path **device_path, + efi_handle_t *device) +{ + struct efi_device_path *dp; + size_t i; + struct efi_handler *handler; + efi_handle_t *handles; + size_t len, len_dp; + size_t len_best = 0; + efi_uintn_t no_handles; + u8 *remainder; + efi_status_t ret; + + EFI_ENTRY("%pUl, %p, %p", protocol, device_path, device); + + if (!protocol || !device_path || !*device_path) { + ret = EFI_INVALID_PARAMETER; + goto out; + } + + /* Find end of device path */ + len = efi_dp_instance_size(*device_path); + + /* Get all handles implementing the protocol */ + ret = EFI_CALL(efi_locate_handle_buffer(BY_PROTOCOL, protocol, NULL, + &no_handles, &handles)); + if (ret != EFI_SUCCESS) + goto out; + + for (i = 0; i < no_handles; ++i) { + /* Find the device path protocol */ + ret = efi_search_protocol(handles[i], &efi_guid_device_path, + &handler); + if (ret != EFI_SUCCESS) + continue; + dp = (struct efi_device_path *)handler->protocol_interface; + len_dp = efi_dp_instance_size(dp); + /* + * This handle can only be a better fit + * if its device path length is longer than the best fit and + * if its device path length is shorter of equal the searched + * device path. + */ + if (len_dp <= len_best || len_dp > len) + continue; + /* Check if dp is a subpath of device_path */ + if (memcmp(*device_path, dp, len_dp)) + continue; + if (!device) { + ret = EFI_INVALID_PARAMETER; + goto out; + } + *device = handles[i]; + len_best = len_dp; + } + if (len_best) { + remainder = (u8 *)*device_path + len_best; + *device_path = (struct efi_device_path *)remainder; + ret = EFI_SUCCESS; + } else { + ret = EFI_NOT_FOUND; + } +out: + return EFI_EXIT(ret); +} + /** * efi_load_image_from_path() - load an image using a file path * @@ -2403,88 +2485,6 @@ found: return EFI_EXIT(EFI_SUCCESS); } -/** - * efi_locate_device_path() - Get the device path and handle of an device - * implementing a protocol - * @protocol: GUID of the protocol - * @device_path: device path - * @device: handle of the device - * - * This function implements the LocateDevicePath service. - * - * See the Unified Extensible Firmware Interface (UEFI) specification for - * details. - * - * Return: status code - */ -static efi_status_t EFIAPI efi_locate_device_path( - const efi_guid_t *protocol, - struct efi_device_path **device_path, - efi_handle_t *device) -{ - struct efi_device_path *dp; - size_t i; - struct efi_handler *handler; - efi_handle_t *handles; - size_t len, len_dp; - size_t len_best = 0; - efi_uintn_t no_handles; - u8 *remainder; - efi_status_t ret; - - EFI_ENTRY("%pUl, %p, %p", protocol, device_path, device); - - if (!protocol || !device_path || !*device_path) { - ret = EFI_INVALID_PARAMETER; - goto out; - } - - /* Find end of device path */ - len = efi_dp_instance_size(*device_path); - - /* Get all handles implementing the protocol */ - ret = EFI_CALL(efi_locate_handle_buffer(BY_PROTOCOL, protocol, NULL, - &no_handles, &handles)); - if (ret != EFI_SUCCESS) - goto out; - - for (i = 0; i < no_handles; ++i) { - /* Find the device path protocol */ - ret = efi_search_protocol(handles[i], &efi_guid_device_path, - &handler); - if (ret != EFI_SUCCESS) - continue; - dp = (struct efi_device_path *)handler->protocol_interface; - len_dp = efi_dp_instance_size(dp); - /* - * This handle can only be a better fit - * if its device path length is longer than the best fit and - * if its device path length is shorter of equal the searched - * device path. - */ - if (len_dp <= len_best || len_dp > len) - continue; - /* Check if dp is a subpath of device_path */ - if (memcmp(*device_path, dp, len_dp)) - continue; - if (!device) { - ret = EFI_INVALID_PARAMETER; - goto out; - } - *device = handles[i]; - len_best = len_dp; - } - if (len_best) { - remainder = (u8 *)*device_path + len_best; - *device_path = (struct efi_device_path *)remainder; - ret = EFI_SUCCESS; - } else { - ret = EFI_NOT_FOUND; - } -out: - return EFI_EXIT(ret); -} - /** * efi_install_multiple_protocol_interfaces() - Install multiple protocol * interfaces