aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGene Cumm <gene.cumm@gmail.com>2015-07-19 19:37:30 -0400
committerGene Cumm <gene.cumm@gmail.com>2015-07-19 19:37:30 -0400
commitf858a5428ed992388da00c5dc7e4f73195d4efb0 (patch)
treea7ae0ad495d0c7cc4a3c1a00ce952b6d7cd344c5
parente3fe9e942a7e6b4257e0262c140b35f41de5d17d (diff)
downloadsyslinux-f858a5428ed992388da00c5dc7e4f73195d4efb0.tar.gz
syslinux-f858a5428ed992388da00c5dc7e4f73195d4efb0.tar.xz
syslinux-f858a5428ed992388da00c5dc7e4f73195d4efb0.zip
efi: Hunt for service binding handle if needed
Signed-off-by: Gene Cumm <gene.cumm@gmail.com>
-rw-r--r--efi/main.c46
1 files changed, 39 insertions, 7 deletions
diff --git a/efi/main.c b/efi/main.c
index 45748e96..4a3be4ce 100644
--- a/efi/main.c
+++ b/efi/main.c
@@ -33,6 +33,8 @@ char aux_seg[256];
static jmp_buf load_error_buf;
+EFI_HANDLE image_handle, image_device_handle, mnpsb_handle;
+
static inline EFI_STATUS
efi_close_protocol(EFI_HANDLE handle, EFI_GUID *guid, EFI_HANDLE agent,
EFI_HANDLE controller)
@@ -82,16 +84,48 @@ struct efi_binding *efi_create_binding(EFI_GUID *bguid, EFI_GUID *pguid)
EFI_SERVICE_BINDING *sbp;
struct efi_binding *b;
EFI_STATUS status;
- EFI_HANDLE protocol, child;
+ EFI_HANDLE sb_handle, protocol, child;
b = malloc(sizeof(*b));
if (!b)
return NULL;
- status = uefi_call_wrapper(BS->OpenProtocol, 6, image_device_handle,
+ sb_handle = (mnpsb_handle ? mnpsb_handle : image_device_handle);
+ status = uefi_call_wrapper(BS->OpenProtocol, 6, sb_handle,
bguid, (void **)&sbp,
- image_handle, image_device_handle,
+ image_handle, sb_handle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+ if (status != EFI_SUCCESS) {
+ EFI_HANDLE *handles = NULL;
+ UINTN i, nr_handles = 0;
+ EFI_DEVICE_PATH *DevicePath = NULL;
+ uint8_t mac_1[PXE_MAC_LENGTH], mac_2[PXE_MAC_LENGTH];
+ DevicePath = DevicePathFromHandle(image_device_handle);
+ if (DevicePath == NULL) {
+ status = EFI_UNSUPPORTED;
+ goto free_binding;
+ }
+ efi_get_MAC(DevicePath, &mac_1, PXE_MAC_LENGTH);
+ status = LibLocateHandle(ByProtocol, bguid, NULL, &nr_handles, &handles);
+ if (status != EFI_SUCCESS)
+ goto free_binding;
+ for (i = 0; i < nr_handles; i++) {
+ DevicePath = DevicePathFromHandle(handles[i]);
+ if (efi_get_MAC(DevicePath, &mac_2, PXE_MAC_LENGTH)
+ && memcmp(mac_1, mac_2, PXE_MAC_LENGTH) == 0) {
+ sb_handle = handles[i];
+ status = uefi_call_wrapper(BS->OpenProtocol, 6, sb_handle,
+ bguid, (void **)&sbp,
+ image_handle, sb_handle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+ if (status == EFI_SUCCESS) {
+ mnpsb_handle = sb_handle;
+ break;
+ }
+ }
+
+ }
+ }
if (status != EFI_SUCCESS)
goto free_binding;
@@ -119,8 +153,8 @@ destroy_child:
uefi_call_wrapper(sbp->DestroyChild, 2, sbp, child);
close_protocol:
- uefi_call_wrapper(BS->CloseProtocol, 4, image_device_handle, bguid,
- image_handle, image_device_handle);
+ uefi_call_wrapper(BS->CloseProtocol, 4, sb_handle, bguid,
+ image_handle, sb_handle);
free_binding:
free(b);
@@ -478,8 +512,6 @@ get_mem_desc(unsigned long memmap, UINTN desc_sz, int i)
return (EFI_MEMORY_DESCRIPTOR *)(memmap + (i * desc_sz));
}
-EFI_HANDLE image_handle, image_device_handle, mnpsb_handle;
-
static inline UINT64 round_up(UINT64 x, UINT64 y)
{
return (((x - 1) | (y - 1)) + 1);