From patchwork Wed Jul 5 16:18:47 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heinrich Schuchardt X-Patchwork-Id: 784720 X-Patchwork-Delegate: agraf@suse.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 3x2mMw4mnqz9s71 for ; Thu, 6 Jul 2017 02:21:32 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 63F18C21EF2; Wed, 5 Jul 2017 16:21:01 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2 autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id BAFEEC21ED4; Wed, 5 Jul 2017 16:20:19 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id A630BC21E27; Wed, 5 Jul 2017 16:20:16 +0000 (UTC) Received: from mout.gmx.net (mout.gmx.net [212.227.15.15]) by lists.denx.de (Postfix) with ESMTPS id 54052C21E57 for ; Wed, 5 Jul 2017 16:20:16 +0000 (UTC) Received: from workstation4.fritz.box ([88.152.145.149]) by mail.gmx.com (mrgmx003 [212.227.17.184]) with ESMTPSA (Nemesis) id 0MTSrf-1dJH410VOR-00SSXR; Wed, 05 Jul 2017 18:19:30 +0200 From: Heinrich Schuchardt To: Alexander Graf Date: Wed, 5 Jul 2017 18:18:47 +0200 Message-Id: <20170705161855.20124-2-xypron.glpk@gmx.de> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170705161855.20124-1-xypron.glpk@gmx.de> References: <20170705161855.20124-1-xypron.glpk@gmx.de> X-Provags-ID: V03:K0:MhOjw/V4uEJvV1Qwm5p3lu2om8h99P4OYSeUvpLPEWMfSlTaMUV w2oq0YbnSLSimvDOrewzVxm536ln9ssMDOJjZTmnZF9nepDohnhzKkXTDKoMpXU7e+r9O+f KTeC6RUeIrZXt9JiX+4x3MsBWIAh7YeFi82JRPNy7lEgwtnHhZLGUeh4KXZgG8B3lCPufw4 0YChcQf0NYOPWKl4+7yzA== X-UI-Out-Filterresults: notjunk:1; V01:K0:nqLs8+F+vaw=:2shde3BYTnHB5fO9BR4vXF GvGmK++YnnHziHmF4flx+tQo4s6/XIYdbx7XEZl5zF1UctTSpgffaEo1qdr50QLJmu5XrnbPN Q3g13L2lyZ0kB50T319cQgaJhu5gBd0SdzpALhCtCb9W+fu+Kj6z7wwTdD9vMHoVa94nflT4S Vlsdr576T2RNaIGUT6UZcabCxVc41mS+uv5srOJom/kH0Bxf38H3HNVoQHvPTBnBxIzYWMcbM xtlC+AU32zgLKNwGKIt+8o3bief/PMHmDakE+czjO6f3ACqzd0ssQgUi2Aub0AWKL3K+vHQBb wonMUDP5x2+XlRUNbUcKZtp8lmr6fzwgzsqyRGF/ayOsYBixm4FvUXwheWJA4ffE5uco9v4a1 Ct75Ip/c9F2Xv7BOmSJhsYL7Q9U0ma5FtiAl4WXjVUjM1/jLw0OZqM4gMwIGHAvQ1w5o0tZ7Q rbNJ3wf5X5Y9wvUfCL1R6+07Ce6et11Wn2GDHufoiAgDXd8co0CQegbaSeBQfwYyh94P2JWOZ ZprEVdCCSBFS0RaGVDZH5HWZg9oo7BLfnkrm00ksftZOyj6pIONd/Gmpf7ent7H/nMDmsbEl7 6lvbbfg1XJASNRHhR54HlqVzsXIo3pD31rNt2m46In/q6Hie1xa9t7Hxft9QyZ2+frZ6+XxsN UtDR4qPfWarFk0c92hNRmtgDj6YfhzUtxsV+lR8Jr823LsB4Nvg0ZsrTPDKn50ZSjr9BZX8xT +0vxNm/y5TlAToiFBZ5Q8AmjmkSZjnvdAQ16ktq78uUskwpBhKI2SkAK71s= Cc: u-boot@lists.denx.de, Heinrich Schuchardt Subject: [U-Boot] [PATCH 1/9] efi_loader: refactor efi_open_protocol X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" 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 --- cmd/bootefi.c | 14 +++----------- include/efi_loader.h | 17 ++--------------- lib/efi_loader/efi_boottime.c | 18 ++++++++++++++---- lib/efi_loader/efi_disk.c | 29 +++-------------------------- lib/efi_loader/efi_gop.c | 2 +- lib/efi_loader/efi_net.c | 30 +++--------------------------- 6 files changed, 26 insertions(+), 84 deletions(-) diff --git a/cmd/bootefi.c b/cmd/bootefi.c index 90ecde65d1..d80cb0723f 100644 --- a/cmd/bootefi.c +++ b/cmd/bootefi.c @@ -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" */ static struct efi_loaded_image loaded_image_info = { .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 */ .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 */ .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 * bootefi_device_path */ .guid = &efi_guid_device_path, - .open = &bootefi_open_dp, + .protocol_interface = bootefi_device_path } }, }; diff --git a/include/efi_loader.h b/include/efi_loader.h index 99619f53a9..c620652307 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -49,15 +49,10 @@ struct efi_class_map { /* * 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 handler open function for that - * object protocol combination. - */ + * protocol GUID to the respective protocol interface */ struct efi_handler { const efi_guid_t *guid; - efi_status_t (EFIAPI *open)(void *handle, - efi_guid_t *protocol, void **protocol_interface, - void *agent_handle, void *controller_handle, - uint32_t attributes); + void *protocol_interface; }; /* @@ -91,14 +86,6 @@ void efi_smbios_register(void); /* Called by networking code to memorize the dhcp ack package */ 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 */ void efi_timer_check(void); /* PE loader implementation */ diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 27e51a253f..5c72f92474 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -442,7 +442,6 @@ static efi_status_t EFIAPI efi_load_image(bool boot_policy, .protocols = { { .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, file_path, source_buffer, source_size, image_handle); info = malloc(sizeof(*info)); + loaded_image_info_obj.protocols[0].protocol_interface = info; obj = malloc(sizeof(loaded_image_info_obj)); memset(info, 0, sizeof(*info)); 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, protocol_interface, agent_handle, controller_handle, attributes); + + if (!protocol_interface && attributes != + EFI_OPEN_PROTOCOL_TEST_PROTOCOL) { + r = EFI_INVALID_PARAMETER; + goto out; + } + list_for_each(lhandle, &efi_obj_list) { struct efi_object *efiobj; efiobj = list_entry(lhandle, struct efi_object, link); @@ -736,9 +743,12 @@ static efi_status_t EFIAPI efi_open_protocol( if (!hprotocol) break; if (!guidcmp(hprotocol, protocol)) { - r = handler->open(handle, protocol, - protocol_interface, agent_handle, - controller_handle, attributes); + if (attributes != + EFI_OPEN_PROTOCOL_TEST_PROTOCOL) { + *protocol_interface = + handler->protocol_interface; + } + r = EFI_SUCCESS; goto out; } } diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c index 39e602a868..3ad7706472 100644 --- a/lib/efi_loader/efi_disk.c +++ b/lib/efi_loader/efi_disk.c @@ -35,29 +35,6 @@ struct efi_disk_obj { 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, char extended_verification) { @@ -210,10 +187,11 @@ static void efi_disk_add_dev(const char *name, diskobj = calloc(1, objlen); /* Fill in object data */ + dp = (void *)&diskobj[1]; 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].open = efi_disk_open_dp; + diskobj->parent.protocols[1].protocol_interface = dp; diskobj->parent.handle = diskobj; diskobj->ops = block_io_disk_template; diskobj->ifname = if_typename; @@ -230,7 +208,6 @@ static void efi_disk_add_dev(const char *name, diskobj->ops.media = &diskobj->media; /* Fill in device path */ - dp = (void*)&diskobj[1]; diskobj->dp = dp; dp[0].dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE; dp[0].dp.sub_type = DEVICE_PATH_SUB_TYPE_FILE_PATH; diff --git a/lib/efi_loader/efi_gop.c b/lib/efi_loader/efi_gop.c index 286ad83097..c491ca0815 100644 --- a/lib/efi_loader/efi_gop.c +++ b/lib/efi_loader/efi_gop.c @@ -172,7 +172,7 @@ int efi_gop_register(void) /* Fill in object data */ gopobj->parent.protocols[0].guid = &efi_gop_guid; - gopobj->parent.protocols[0].open = efi_return_handle; + gopobj->parent.protocols[0].open = &gopobj->ops; gopobj->parent.handle = &gopobj->ops; gopobj->ops.query_mode = gop_query_mode; gopobj->ops.set_mode = gop_set_mode; diff --git a/lib/efi_loader/efi_net.c b/lib/efi_loader/efi_net.c index 604ac6e040..0b949d86e8 100644 --- a/lib/efi_loader/efi_net.c +++ b/lib/efi_loader/efi_net.c @@ -199,30 +199,6 @@ static efi_status_t EFIAPI efi_net_receive(struct efi_simple_network *this, 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) { int maxsize = sizeof(*dhcp_ack); @@ -258,11 +234,11 @@ int efi_net_register(void **handle) /* Fill in object data */ 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].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].open = efi_net_open_pxe; + netobj->parent.protocols[2].protocol_interface = &netobj->pxe; netobj->parent.handle = &netobj->net; netobj->net.start = efi_net_start; netobj->net.stop = efi_net_stop;