mirror of
https://github.com/u-boot/u-boot.git
synced 2025-05-09 03:21:51 +00:00
efi_loader: refactor efi_open_protocol
efi_open_protocol was implemented to call a protocol specific open function to retrieve the protocol interface. The UEFI specification does not know of such a function. It is not possible to implement InstallProtocolInterface with the current design. With the patch the protocol interface itself is stored in the list of installed protocols of an efi_object instead of an open function. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> [agraf: fix efi gop support] Signed-off-by: Alexander Graf <agraf@suse.de>
This commit is contained in:
parent
8d3a25685e
commit
b5349f742a
7 changed files with 26 additions and 92 deletions
|
@ -54,14 +54,6 @@ static struct efi_device_path_file_path bootefi_device_path[] = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static efi_status_t EFIAPI bootefi_open_dp(void *handle, efi_guid_t *protocol,
|
|
||||||
void **protocol_interface, void *agent_handle,
|
|
||||||
void *controller_handle, uint32_t attributes)
|
|
||||||
{
|
|
||||||
*protocol_interface = bootefi_device_path;
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The EFI loaded_image interface for the image executed via "bootefi" */
|
/* The EFI loaded_image interface for the image executed via "bootefi" */
|
||||||
static struct efi_loaded_image loaded_image_info = {
|
static struct efi_loaded_image loaded_image_info = {
|
||||||
.device_handle = bootefi_device_path,
|
.device_handle = bootefi_device_path,
|
||||||
|
@ -78,7 +70,7 @@ static struct efi_object loaded_image_info_obj = {
|
||||||
* return handle which points to loaded_image_info
|
* return handle which points to loaded_image_info
|
||||||
*/
|
*/
|
||||||
.guid = &efi_guid_loaded_image,
|
.guid = &efi_guid_loaded_image,
|
||||||
.open = &efi_return_handle,
|
.protocol_interface = &loaded_image_info,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -86,7 +78,7 @@ static struct efi_object loaded_image_info_obj = {
|
||||||
* bootefi_device_path
|
* bootefi_device_path
|
||||||
*/
|
*/
|
||||||
.guid = &efi_guid_device_path,
|
.guid = &efi_guid_device_path,
|
||||||
.open = &bootefi_open_dp,
|
.protocol_interface = bootefi_device_path,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -99,7 +91,7 @@ static struct efi_object bootefi_device_obj = {
|
||||||
/* When asking for the device path interface, return
|
/* When asking for the device path interface, return
|
||||||
* bootefi_device_path */
|
* bootefi_device_path */
|
||||||
.guid = &efi_guid_device_path,
|
.guid = &efi_guid_device_path,
|
||||||
.open = &bootefi_open_dp,
|
.protocol_interface = bootefi_device_path
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -49,15 +49,10 @@ struct efi_class_map {
|
||||||
/*
|
/*
|
||||||
* When the UEFI payload wants to open a protocol on an object to get its
|
* 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
|
* interface (usually a struct with callback functions), this struct maps the
|
||||||
* protocol GUID to the respective protocol handler open function for that
|
* protocol GUID to the respective protocol interface */
|
||||||
* object protocol combination.
|
|
||||||
*/
|
|
||||||
struct efi_handler {
|
struct efi_handler {
|
||||||
const efi_guid_t *guid;
|
const efi_guid_t *guid;
|
||||||
efi_status_t (EFIAPI *open)(void *handle,
|
void *protocol_interface;
|
||||||
efi_guid_t *protocol, void **protocol_interface,
|
|
||||||
void *agent_handle, void *controller_handle,
|
|
||||||
uint32_t attributes);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -91,14 +86,6 @@ void efi_smbios_register(void);
|
||||||
/* Called by networking code to memorize the dhcp ack package */
|
/* Called by networking code to memorize the dhcp ack package */
|
||||||
void efi_net_set_dhcp_ack(void *pkt, int len);
|
void efi_net_set_dhcp_ack(void *pkt, int len);
|
||||||
|
|
||||||
/*
|
|
||||||
* Stub implementation for a protocol opener that just returns the handle as
|
|
||||||
* interface
|
|
||||||
*/
|
|
||||||
efi_status_t EFIAPI efi_return_handle(void *handle,
|
|
||||||
efi_guid_t *protocol, void **protocol_interface,
|
|
||||||
void *agent_handle, void *controller_handle,
|
|
||||||
uint32_t attributes);
|
|
||||||
/* Called from places to check whether a timer expired */
|
/* Called from places to check whether a timer expired */
|
||||||
void efi_timer_check(void);
|
void efi_timer_check(void);
|
||||||
/* PE loader implementation */
|
/* PE loader implementation */
|
||||||
|
|
|
@ -442,7 +442,6 @@ static efi_status_t EFIAPI efi_load_image(bool boot_policy,
|
||||||
.protocols = {
|
.protocols = {
|
||||||
{
|
{
|
||||||
.guid = &efi_guid_loaded_image,
|
.guid = &efi_guid_loaded_image,
|
||||||
.open = &efi_return_handle,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -452,6 +451,7 @@ static efi_status_t EFIAPI efi_load_image(bool boot_policy,
|
||||||
EFI_ENTRY("%d, %p, %p, %p, %ld, %p", boot_policy, parent_image,
|
EFI_ENTRY("%d, %p, %p, %p, %ld, %p", boot_policy, parent_image,
|
||||||
file_path, source_buffer, source_size, image_handle);
|
file_path, source_buffer, source_size, image_handle);
|
||||||
info = malloc(sizeof(*info));
|
info = malloc(sizeof(*info));
|
||||||
|
loaded_image_info_obj.protocols[0].protocol_interface = info;
|
||||||
obj = malloc(sizeof(loaded_image_info_obj));
|
obj = malloc(sizeof(loaded_image_info_obj));
|
||||||
memset(info, 0, sizeof(*info));
|
memset(info, 0, sizeof(*info));
|
||||||
memcpy(obj, &loaded_image_info_obj, sizeof(loaded_image_info_obj));
|
memcpy(obj, &loaded_image_info_obj, sizeof(loaded_image_info_obj));
|
||||||
|
@ -723,6 +723,13 @@ static efi_status_t EFIAPI efi_open_protocol(
|
||||||
EFI_ENTRY("%p, %p, %p, %p, %p, 0x%x", handle, protocol,
|
EFI_ENTRY("%p, %p, %p, %p, %p, 0x%x", handle, protocol,
|
||||||
protocol_interface, agent_handle, controller_handle,
|
protocol_interface, agent_handle, controller_handle,
|
||||||
attributes);
|
attributes);
|
||||||
|
|
||||||
|
if (!protocol_interface && attributes !=
|
||||||
|
EFI_OPEN_PROTOCOL_TEST_PROTOCOL) {
|
||||||
|
r = EFI_INVALID_PARAMETER;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
list_for_each(lhandle, &efi_obj_list) {
|
list_for_each(lhandle, &efi_obj_list) {
|
||||||
struct efi_object *efiobj;
|
struct efi_object *efiobj;
|
||||||
efiobj = list_entry(lhandle, struct efi_object, link);
|
efiobj = list_entry(lhandle, struct efi_object, link);
|
||||||
|
@ -736,9 +743,12 @@ static efi_status_t EFIAPI efi_open_protocol(
|
||||||
if (!hprotocol)
|
if (!hprotocol)
|
||||||
break;
|
break;
|
||||||
if (!guidcmp(hprotocol, protocol)) {
|
if (!guidcmp(hprotocol, protocol)) {
|
||||||
r = handler->open(handle, protocol,
|
if (attributes !=
|
||||||
protocol_interface, agent_handle,
|
EFI_OPEN_PROTOCOL_TEST_PROTOCOL) {
|
||||||
controller_handle, attributes);
|
*protocol_interface =
|
||||||
|
handler->protocol_interface;
|
||||||
|
}
|
||||||
|
r = EFI_SUCCESS;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,29 +35,6 @@ struct efi_disk_obj {
|
||||||
const struct blk_desc *desc;
|
const struct blk_desc *desc;
|
||||||
};
|
};
|
||||||
|
|
||||||
static efi_status_t EFIAPI efi_disk_open_block(void *handle,
|
|
||||||
efi_guid_t *protocol, void **protocol_interface,
|
|
||||||
void *agent_handle, void *controller_handle,
|
|
||||||
uint32_t attributes)
|
|
||||||
{
|
|
||||||
struct efi_disk_obj *diskobj = handle;
|
|
||||||
|
|
||||||
*protocol_interface = &diskobj->ops;
|
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static efi_status_t EFIAPI efi_disk_open_dp(void *handle, efi_guid_t *protocol,
|
|
||||||
void **protocol_interface, void *agent_handle,
|
|
||||||
void *controller_handle, uint32_t attributes)
|
|
||||||
{
|
|
||||||
struct efi_disk_obj *diskobj = handle;
|
|
||||||
|
|
||||||
*protocol_interface = diskobj->dp;
|
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static efi_status_t EFIAPI efi_disk_reset(struct efi_block_io *this,
|
static efi_status_t EFIAPI efi_disk_reset(struct efi_block_io *this,
|
||||||
char extended_verification)
|
char extended_verification)
|
||||||
{
|
{
|
||||||
|
@ -210,10 +187,11 @@ static void efi_disk_add_dev(const char *name,
|
||||||
diskobj = calloc(1, objlen);
|
diskobj = calloc(1, objlen);
|
||||||
|
|
||||||
/* Fill in object data */
|
/* Fill in object data */
|
||||||
|
dp = (void *)&diskobj[1];
|
||||||
diskobj->parent.protocols[0].guid = &efi_block_io_guid;
|
diskobj->parent.protocols[0].guid = &efi_block_io_guid;
|
||||||
diskobj->parent.protocols[0].open = efi_disk_open_block;
|
diskobj->parent.protocols[0].protocol_interface = &diskobj->ops;
|
||||||
diskobj->parent.protocols[1].guid = &efi_guid_device_path;
|
diskobj->parent.protocols[1].guid = &efi_guid_device_path;
|
||||||
diskobj->parent.protocols[1].open = efi_disk_open_dp;
|
diskobj->parent.protocols[1].protocol_interface = dp;
|
||||||
diskobj->parent.handle = diskobj;
|
diskobj->parent.handle = diskobj;
|
||||||
diskobj->ops = block_io_disk_template;
|
diskobj->ops = block_io_disk_template;
|
||||||
diskobj->ifname = if_typename;
|
diskobj->ifname = if_typename;
|
||||||
|
@ -230,7 +208,6 @@ static void efi_disk_add_dev(const char *name,
|
||||||
diskobj->ops.media = &diskobj->media;
|
diskobj->ops.media = &diskobj->media;
|
||||||
|
|
||||||
/* Fill in device path */
|
/* Fill in device path */
|
||||||
dp = (void*)&diskobj[1];
|
|
||||||
diskobj->dp = dp;
|
diskobj->dp = dp;
|
||||||
dp[0].dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE;
|
dp[0].dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE;
|
||||||
dp[0].dp.sub_type = DEVICE_PATH_SUB_TYPE_FILE_PATH;
|
dp[0].dp.sub_type = DEVICE_PATH_SUB_TYPE_FILE_PATH;
|
||||||
|
|
|
@ -172,7 +172,7 @@ int efi_gop_register(void)
|
||||||
|
|
||||||
/* Fill in object data */
|
/* Fill in object data */
|
||||||
gopobj->parent.protocols[0].guid = &efi_gop_guid;
|
gopobj->parent.protocols[0].guid = &efi_gop_guid;
|
||||||
gopobj->parent.protocols[0].open = efi_return_handle;
|
gopobj->parent.protocols[0].protocol_interface = &gopobj->ops;
|
||||||
gopobj->parent.handle = &gopobj->ops;
|
gopobj->parent.handle = &gopobj->ops;
|
||||||
gopobj->ops.query_mode = gop_query_mode;
|
gopobj->ops.query_mode = gop_query_mode;
|
||||||
gopobj->ops.set_mode = gop_set_mode;
|
gopobj->ops.set_mode = gop_set_mode;
|
||||||
|
|
|
@ -18,14 +18,6 @@ DECLARE_GLOBAL_DATA_PTR;
|
||||||
const efi_guid_t efi_guid_device_path = DEVICE_PATH_GUID;
|
const efi_guid_t efi_guid_device_path = DEVICE_PATH_GUID;
|
||||||
const efi_guid_t efi_guid_loaded_image = LOADED_IMAGE_GUID;
|
const efi_guid_t efi_guid_loaded_image = LOADED_IMAGE_GUID;
|
||||||
|
|
||||||
efi_status_t EFIAPI efi_return_handle(void *handle, efi_guid_t *protocol,
|
|
||||||
void **protocol_interface, void *agent_handle,
|
|
||||||
void *controller_handle, uint32_t attributes)
|
|
||||||
{
|
|
||||||
*protocol_interface = handle;
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static efi_status_t efi_loader_relocate(const IMAGE_BASE_RELOCATION *rel,
|
static efi_status_t efi_loader_relocate(const IMAGE_BASE_RELOCATION *rel,
|
||||||
unsigned long rel_size, void *efi_reloc)
|
unsigned long rel_size, void *efi_reloc)
|
||||||
{
|
{
|
||||||
|
|
|
@ -199,30 +199,6 @@ static efi_status_t EFIAPI efi_net_receive(struct efi_simple_network *this,
|
||||||
return EFI_EXIT(EFI_SUCCESS);
|
return EFI_EXIT(EFI_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static efi_status_t EFIAPI efi_net_open_dp(void *handle, efi_guid_t *protocol,
|
|
||||||
void **protocol_interface, void *agent_handle,
|
|
||||||
void *controller_handle, uint32_t attributes)
|
|
||||||
{
|
|
||||||
struct efi_simple_network *net = handle;
|
|
||||||
struct efi_net_obj *netobj = container_of(net, struct efi_net_obj, net);
|
|
||||||
|
|
||||||
*protocol_interface = &netobj->dp_mac;
|
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static efi_status_t EFIAPI efi_net_open_pxe(void *handle, efi_guid_t *protocol,
|
|
||||||
void **protocol_interface, void *agent_handle,
|
|
||||||
void *controller_handle, uint32_t attributes)
|
|
||||||
{
|
|
||||||
struct efi_simple_network *net = handle;
|
|
||||||
struct efi_net_obj *netobj = container_of(net, struct efi_net_obj, net);
|
|
||||||
|
|
||||||
*protocol_interface = &netobj->pxe;
|
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
void efi_net_set_dhcp_ack(void *pkt, int len)
|
void efi_net_set_dhcp_ack(void *pkt, int len)
|
||||||
{
|
{
|
||||||
int maxsize = sizeof(*dhcp_ack);
|
int maxsize = sizeof(*dhcp_ack);
|
||||||
|
@ -258,11 +234,11 @@ int efi_net_register(void **handle)
|
||||||
|
|
||||||
/* Fill in object data */
|
/* Fill in object data */
|
||||||
netobj->parent.protocols[0].guid = &efi_net_guid;
|
netobj->parent.protocols[0].guid = &efi_net_guid;
|
||||||
netobj->parent.protocols[0].open = efi_return_handle;
|
netobj->parent.protocols[0].protocol_interface = &netobj->net;
|
||||||
netobj->parent.protocols[1].guid = &efi_guid_device_path;
|
netobj->parent.protocols[1].guid = &efi_guid_device_path;
|
||||||
netobj->parent.protocols[1].open = efi_net_open_dp;
|
netobj->parent.protocols[1].protocol_interface = &netobj->dp_mac;
|
||||||
netobj->parent.protocols[2].guid = &efi_pxe_guid;
|
netobj->parent.protocols[2].guid = &efi_pxe_guid;
|
||||||
netobj->parent.protocols[2].open = efi_net_open_pxe;
|
netobj->parent.protocols[2].protocol_interface = &netobj->pxe;
|
||||||
netobj->parent.handle = &netobj->net;
|
netobj->parent.handle = &netobj->net;
|
||||||
netobj->net.start = efi_net_start;
|
netobj->net.start = efi_net_start;
|
||||||
netobj->net.stop = efi_net_stop;
|
netobj->net.stop = efi_net_stop;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue