efi_loader: implement InstallProtocolInterface

efi_install_protocol_interface up to now only returned an error code.

The patch implements the UEFI specification for InstallProtocolInterface
with the exception that it will not create new handles.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
This commit is contained in:
xypron.glpk@gmx.de 2017-07-11 22:06:16 +02:00 committed by Alexander Graf
parent 69baec6781
commit e0549f8a17
2 changed files with 54 additions and 2 deletions

View File

@ -58,7 +58,7 @@ struct efi_boot_services {
efi_status_t (EFIAPI *signal_event)(void *event);
efi_status_t (EFIAPI *close_event)(void *event);
efi_status_t (EFIAPI *check_event)(void *event);
#define EFI_NATIVE_INTERFACE 0x00000000
efi_status_t (EFIAPI *install_protocol_interface)(
void **handle, efi_guid_t *protocol,
int protocol_interface_type, void *protocol_interface);

View File

@ -303,10 +303,62 @@ static efi_status_t EFIAPI efi_install_protocol_interface(void **handle,
efi_guid_t *protocol, int protocol_interface_type,
void *protocol_interface)
{
struct list_head *lhandle;
int i;
efi_status_t r;
EFI_ENTRY("%p, %p, %d, %p", handle, protocol, protocol_interface_type,
protocol_interface);
return EFI_EXIT(EFI_OUT_OF_RESOURCES);
if (!handle || !protocol ||
protocol_interface_type != EFI_NATIVE_INTERFACE) {
r = EFI_INVALID_PARAMETER;
goto out;
}
/* Create new handle if requested. */
if (!*handle) {
r = EFI_OUT_OF_RESOURCES;
goto out;
}
/* Find object. */
list_for_each(lhandle, &efi_obj_list) {
struct efi_object *efiobj;
efiobj = list_entry(lhandle, struct efi_object, link);
if (efiobj->handle != *handle)
continue;
/* Check if protocol is already installed on the handle. */
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)) {
r = EFI_INVALID_PARAMETER;
goto out;
}
}
/* Install protocol in first empty slot. */
for (i = 0; i < ARRAY_SIZE(efiobj->protocols); i++) {
struct efi_handler *handler = &efiobj->protocols[i];
if (handler->guid)
continue;
handler->guid = protocol;
handler->protocol_interface = protocol_interface;
r = EFI_SUCCESS;
goto out;
}
r = EFI_OUT_OF_RESOURCES;
goto out;
}
r = EFI_INVALID_PARAMETER;
out:
return EFI_EXIT(r);
}
static efi_status_t EFIAPI efi_reinstall_protocol_interface(void *handle,
efi_guid_t *protocol, void *old_interface,
void *new_interface)