Most of these utility functions are useful for the app, so move them into the common directory. Move the GUIDs used by this file from their various other location, so they are available to the app, even if it doesn't enabled EFI_LOADER Fix the rather large number of checkpath warnings in this file, except for the lwip one, best left to the maintainer to sort out. One noteable change is adding a return value to dp_fill() for the case where an option is not enabled but its uclass is referenced. This presuambly never happens during execution, since if the uclass is not supported there can be no device in that uclass and therefore nothing will ever request its path. So just handle this like an invalid device. Signed-off-by: Simon Glass <sjg@chromium.org>
101 lines
2.3 KiB
C
101 lines
2.3 KiB
C
// SPDX-License-Identifier: GPL-2.0+
|
|
/*
|
|
* EFI device path from u-boot device-model mapping
|
|
*
|
|
* (C) Copyright 2017 Rob Clark
|
|
*/
|
|
|
|
#define LOG_CATEGORY LOGC_EFI
|
|
|
|
#include <blk.h>
|
|
#include <dm.h>
|
|
#include <dm/root.h>
|
|
#include <efi_device_path.h>
|
|
#include <log.h>
|
|
#include <mapmem.h>
|
|
#include <net.h>
|
|
#include <usb.h>
|
|
#include <mmc.h>
|
|
#include <nvme.h>
|
|
#include <efi_loader.h>
|
|
#include <part.h>
|
|
#include <u-boot/uuid.h>
|
|
#include <asm-generic/unaligned.h>
|
|
#include <linux/compat.h> /* U16_MAX */
|
|
|
|
/**
|
|
* find_handle() - find handle by device path and installed protocol
|
|
*
|
|
* If @rem is provided, the handle with the longest partial match is returned.
|
|
*
|
|
* @dp: device path to search
|
|
* @guid: GUID of protocol that must be installed on path or NULL
|
|
* @short_path: use short form device path for matching
|
|
* @rem: pointer to receive remaining device path
|
|
* Return: matching handle
|
|
*/
|
|
static efi_handle_t find_handle(struct efi_device_path *dp,
|
|
const efi_guid_t *guid, bool short_path,
|
|
struct efi_device_path **rem)
|
|
{
|
|
efi_handle_t handle, best_handle = NULL;
|
|
efi_uintn_t len, best_len = 0;
|
|
|
|
len = efi_dp_instance_size(dp);
|
|
|
|
list_for_each_entry(handle, &efi_obj_list, link) {
|
|
struct efi_handler *handler;
|
|
struct efi_device_path *dp_current;
|
|
efi_uintn_t len_current;
|
|
efi_status_t ret;
|
|
|
|
if (guid) {
|
|
ret = efi_search_protocol(handle, guid, &handler);
|
|
if (ret != EFI_SUCCESS)
|
|
continue;
|
|
}
|
|
ret = efi_search_protocol(handle, &efi_guid_device_path,
|
|
&handler);
|
|
if (ret != EFI_SUCCESS)
|
|
continue;
|
|
dp_current = handler->protocol_interface;
|
|
if (short_path) {
|
|
dp_current = efi_dp_shorten(dp_current);
|
|
if (!dp_current)
|
|
continue;
|
|
}
|
|
len_current = efi_dp_instance_size(dp_current);
|
|
if (rem) {
|
|
if (len_current > len)
|
|
continue;
|
|
} else {
|
|
if (len_current != len)
|
|
continue;
|
|
}
|
|
if (memcmp(dp_current, dp, len_current))
|
|
continue;
|
|
if (!rem)
|
|
return handle;
|
|
if (len_current > best_len) {
|
|
best_len = len_current;
|
|
best_handle = handle;
|
|
*rem = (void*)((u8 *)dp + len_current);
|
|
}
|
|
}
|
|
return best_handle;
|
|
}
|
|
|
|
efi_handle_t efi_dp_find_obj(struct efi_device_path *dp,
|
|
const efi_guid_t *guid,
|
|
struct efi_device_path **rem)
|
|
{
|
|
efi_handle_t handle;
|
|
|
|
handle = find_handle(dp, guid, false, rem);
|
|
if (!handle)
|
|
/* Match short form device path */
|
|
handle = find_handle(dp, guid, true, rem);
|
|
|
|
return handle;
|
|
}
|