diff options
author | xypron.glpk@gmx.de <xypron.glpk@gmx.de> | 2017-07-11 22:06:24 +0200 |
---|---|---|
committer | Alexander Graf <agraf@suse.de> | 2017-07-19 14:14:40 +0200 |
commit | 88adae5ef057845f6bc69c63123df4332fe835b1 (patch) | |
tree | 349755e54709b23c59264acedea2cd510615727b | |
parent | 011f432745ae7fdb645e16c03382a4181d262619 (diff) |
efi_loader: reimplement efi_locate_protocol
The UEFI specification requires that LocateProtol finds the first
handle supporting the protocol and to return a pointer to its
interface.
So we have to assign the protocols to an efi_object and not use
any separate storage.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
-rw-r--r-- | cmd/bootefi.c | 4 | ||||
-rw-r--r-- | include/efi_loader.h | 10 | ||||
-rw-r--r-- | lib/efi_loader/efi_boottime.c | 32 |
3 files changed, 24 insertions, 22 deletions
diff --git a/cmd/bootefi.c b/cmd/bootefi.c index 2a56ad7f58..8453d90b2c 100644 --- a/cmd/bootefi.c +++ b/cmd/bootefi.c @@ -80,6 +80,10 @@ static struct efi_object loaded_image_info_obj = { .guid = &efi_guid_device_path, .protocol_interface = bootefi_device_path, }, + { + .guid = &efi_guid_console_control, + .protocol_interface = (void *) &efi_console_control + }, }, }; diff --git a/include/efi_loader.h b/include/efi_loader.h index 989e5809ba..6ea6e9ee4d 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -37,16 +37,6 @@ extern unsigned int __efi_runtime_start, __efi_runtime_stop; extern unsigned int __efi_runtime_rel_start, __efi_runtime_rel_stop; /* - * While UEFI objects can have callbacks, you can also call functions on - * protocols (classes) themselves. This struct maps a protocol GUID to its - * interface (usually a struct with callback functions). - */ -struct efi_class_map { - const efi_guid_t *guid; - const void *interface; -}; - -/* * When the UEFI payload wants to open a protocol on an object to get its * interface (usually a struct with callback functions), this struct maps the * protocol GUID to the respective protocol interface */ diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 6f093290eb..339fe55cde 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -786,27 +786,35 @@ out: return EFI_EXIT(r); } -static struct efi_class_map efi_class_maps[] = { - { - .guid = &efi_guid_console_control, - .interface = &efi_console_control - }, -}; - static efi_status_t EFIAPI efi_locate_protocol(efi_guid_t *protocol, void *registration, void **protocol_interface) { + struct list_head *lhandle; int i; EFI_ENTRY("%p, %p, %p", protocol, registration, protocol_interface); - for (i = 0; i < ARRAY_SIZE(efi_class_maps); i++) { - struct efi_class_map *curmap = &efi_class_maps[i]; - if (!guidcmp(protocol, curmap->guid)) { - *protocol_interface = (void*)curmap->interface; - return EFI_EXIT(EFI_SUCCESS); + + if (!protocol || !protocol_interface) + return EFI_EXIT(EFI_INVALID_PARAMETER); + + list_for_each(lhandle, &efi_obj_list) { + struct efi_object *efiobj; + + efiobj = list_entry(lhandle, struct efi_object, link); + for (i = 0; i < ARRAY_SIZE(efiobj->protocols); i++) { + struct efi_handler *handler = &efiobj->protocols[i]; + + if (!handler->guid) + continue; + if (!guidcmp(handler->guid, protocol)) { + *protocol_interface = + handler->protocol_interface; + return EFI_EXIT(EFI_SUCCESS); + } } } + *protocol_interface = NULL; return EFI_EXIT(EFI_NOT_FOUND); } |