* [U-Boot] [PATCH v3 01/16] efi_selftest: colored test output
2018-01-11 7:15 [U-Boot] [PATCH v3 00/16] efi_loader: implement driver management Heinrich Schuchardt
@ 2018-01-11 7:15 ` Heinrich Schuchardt
2018-01-16 14:56 ` Simon Glass
2018-01-11 7:15 ` [U-Boot] [PATCH v3 02/16] efi_loader: simplify efi_remove_all_protocols Heinrich Schuchardt
` (14 subsequent siblings)
15 siblings, 1 reply; 22+ messages in thread
From: Heinrich Schuchardt @ 2018-01-11 7:15 UTC (permalink / raw)
To: u-boot
Add color coding to output:
test section blue
success green
errors red
todo yellow
summary white
others light gray
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
---
v3
add more comments for function parameters
v2
no change
---
include/efi_selftest.h | 27 +++++++++++++++++----------
lib/efi_selftest/efi_selftest.c | 25 ++++++++++++++-----------
lib/efi_selftest/efi_selftest_console.c | 13 +++++++++----
3 files changed, 40 insertions(+), 25 deletions(-)
diff --git a/include/efi_selftest.h b/include/efi_selftest.h
index be5ba4bfa9..08dd8e43ad 100644
--- a/include/efi_selftest.h
+++ b/include/efi_selftest.h
@@ -18,14 +18,20 @@
#define EFI_ST_SUCCESS 0
#define EFI_ST_FAILURE 1
+/*
+ * Prints a message.
+ */
+#define efi_st_printf(...) \
+ (efi_st_printc(-1, __VA_ARGS__))
+
/*
* Prints an error message.
*
* @... format string followed by fields to print
*/
#define efi_st_error(...) \
- (efi_st_printf("%s(%u):\nERROR: ", __FILE__, __LINE__), \
- efi_st_printf(__VA_ARGS__)) \
+ (efi_st_printc(EFI_LIGHTRED, "%s(%u):\nERROR: ", __FILE__, __LINE__), \
+ efi_st_printc(EFI_LIGHTRED, __VA_ARGS__))
/*
* Prints a TODO message.
@@ -33,8 +39,8 @@
* @... format string followed by fields to print
*/
#define efi_st_todo(...) \
- (efi_st_printf("%s(%u):\nTODO: ", __FILE__, __LINE__), \
- efi_st_printf(__VA_ARGS__)) \
+ (efi_st_printc(EFI_YELLOW, "%s(%u):\nTODO: ", __FILE__, __LINE__), \
+ efi_st_printc(EFI_YELLOW, __VA_ARGS__)) \
/*
* A test may be setup and executed at boottime,
@@ -61,14 +67,15 @@ extern struct efi_simple_input_interface *con_in;
void efi_st_exit_boot_services(void);
/*
- * Print a pointer to an u16 string
+ * Print a colored message
*
- * @pointer: pointer
- * @buf: pointer to buffer address
- * on return position of terminating zero word
+ * @color color, see constants in efi_api.h, use -1 for no color
+ * @fmt printf format
+ * @... arguments to be printed
+ * on return position of terminating zero word
*/
-void efi_st_printf(const char *fmt, ...)
- __attribute__ ((format (__printf__, 1, 2)));
+void efi_st_printc(int color, const char *fmt, ...)
+ __attribute__ ((format (__printf__, 2, 3)));
/*
* Compare memory.
diff --git a/lib/efi_selftest/efi_selftest.c b/lib/efi_selftest/efi_selftest.c
index 4e5a12c47c..fc5ef254a1 100644
--- a/lib/efi_selftest/efi_selftest.c
+++ b/lib/efi_selftest/efi_selftest.c
@@ -65,7 +65,7 @@ void efi_st_exit_boot_services(void)
efi_st_error("ExitBootServices did not return EFI_SUCCESS\n");
return;
}
- efi_st_printf("\nBoot services terminated\n");
+ efi_st_printc(EFI_WHITE, "\nBoot services terminated\n");
}
/*
@@ -81,13 +81,14 @@ static int setup(struct efi_unit_test *test, unsigned int *failures)
if (!test->setup)
return EFI_ST_SUCCESS;
- efi_st_printf("\nSetting up '%s'\n", test->name);
+ efi_st_printc(EFI_LIGHTBLUE, "\nSetting up '%s'\n", test->name);
ret = test->setup(handle, systable);
if (ret != EFI_ST_SUCCESS) {
efi_st_error("Setting up '%s' failed\n", test->name);
++*failures;
} else {
- efi_st_printf("Setting up '%s' succeeded\n", test->name);
+ efi_st_printc(EFI_LIGHTGREEN,
+ "Setting up '%s' succeeded\n", test->name);
}
return ret;
}
@@ -105,13 +106,14 @@ static int execute(struct efi_unit_test *test, unsigned int *failures)
if (!test->execute)
return EFI_ST_SUCCESS;
- efi_st_printf("\nExecuting '%s'\n", test->name);
+ efi_st_printc(EFI_LIGHTBLUE, "\nExecuting '%s'\n", test->name);
ret = test->execute();
if (ret != EFI_ST_SUCCESS) {
efi_st_error("Executing '%s' failed\n", test->name);
++*failures;
} else {
- efi_st_printf("Executing '%s' succeeded\n", test->name);
+ efi_st_printc(EFI_LIGHTGREEN,
+ "Executing '%s' succeeded\n", test->name);
}
return ret;
}
@@ -129,13 +131,14 @@ static int teardown(struct efi_unit_test *test, unsigned int *failures)
if (!test->teardown)
return EFI_ST_SUCCESS;
- efi_st_printf("\nTearing down '%s'\n", test->name);
+ efi_st_printc(EFI_LIGHTBLUE, "\nTearing down '%s'\n", test->name);
ret = test->teardown();
if (ret != EFI_ST_SUCCESS) {
efi_st_error("Tearing down '%s' failed\n", test->name);
++*failures;
} else {
- efi_st_printf("Tearing down '%s' succeeded\n", test->name);
+ efi_st_printc(EFI_LIGHTGREEN,
+ "Tearing down '%s' succeeded\n", test->name);
}
return ret;
}
@@ -262,12 +265,12 @@ efi_status_t EFIAPI efi_selftest(efi_handle_t image_handle,
}
}
- efi_st_printf("\nTesting EFI API implementation\n");
+ efi_st_printc(EFI_WHITE, "\nTesting EFI API implementation\n");
if (testname)
- efi_st_printf("\nSelected test: '%ps'\n", testname);
+ efi_st_printc(EFI_WHITE, "\nSelected test: '%ps'\n", testname);
else
- efi_st_printf("\nNumber of tests to execute: %u\n",
+ efi_st_printc(EFI_WHITE, "\nNumber of tests to execute: %u\n",
ll_entry_count(struct efi_unit_test,
efi_unit_test));
@@ -291,7 +294,7 @@ efi_status_t EFIAPI efi_selftest(efi_handle_t image_handle,
&failures);
/* Give feedback */
- efi_st_printf("\nSummary: %u failures\n\n", failures);
+ efi_st_printc(EFI_WHITE, "\nSummary: %u failures\n\n", failures);
/* Reset system */
efi_st_printf("Preparing for reset. Press any key.\n");
diff --git a/lib/efi_selftest/efi_selftest_console.c b/lib/efi_selftest/efi_selftest_console.c
index 6a7fd20da5..d528fc56ff 100644
--- a/lib/efi_selftest/efi_selftest_console.c
+++ b/lib/efi_selftest/efi_selftest_console.c
@@ -130,12 +130,13 @@ static void int2dec(s32 value, u16 **buf)
}
/*
- * Print a formatted string to the EFI console
+ * Print a colored formatted string to the EFI console
*
- * @fmt: format string
- * @...: optional arguments
+ * @color color, see constants in efi_api.h, use -1 for no color
+ * @fmt format string
+ * @... optional arguments
*/
-void efi_st_printf(const char *fmt, ...)
+void efi_st_printc(int color, const char *fmt, ...)
{
va_list args;
u16 buf[160];
@@ -215,7 +216,11 @@ void efi_st_printf(const char *fmt, ...)
}
va_end(args);
*pos = 0;
+ if (color >= 0)
+ con_out->set_attribute(con_out, (unsigned long)color);
con_out->output_string(con_out, buf);
+ if (color >= 0)
+ con_out->set_attribute(con_out, EFI_LIGHTGRAY);
}
/*
--
2.14.2
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [U-Boot] [PATCH v3 01/16] efi_selftest: colored test output
2018-01-11 7:15 ` [U-Boot] [PATCH v3 01/16] efi_selftest: colored test output Heinrich Schuchardt
@ 2018-01-16 14:56 ` Simon Glass
0 siblings, 0 replies; 22+ messages in thread
From: Simon Glass @ 2018-01-16 14:56 UTC (permalink / raw)
To: u-boot
On 10 January 2018 at 23:15, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote:
> Add color coding to output:
> test section blue
> success green
> errors red
> todo yellow
> summary white
> others light gray
>
> Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
> ---
> v3
> add more comments for function parameters
> v2
> no change
> ---
> include/efi_selftest.h | 27 +++++++++++++++++----------
> lib/efi_selftest/efi_selftest.c | 25 ++++++++++++++-----------
> lib/efi_selftest/efi_selftest_console.c | 13 +++++++++----
> 3 files changed, 40 insertions(+), 25 deletions(-)
Reviewed-by: Simon Glass <sjg@chromium.org>
^ permalink raw reply [flat|nested] 22+ messages in thread
* [U-Boot] [PATCH v3 02/16] efi_loader: simplify efi_remove_all_protocols
2018-01-11 7:15 [U-Boot] [PATCH v3 00/16] efi_loader: implement driver management Heinrich Schuchardt
2018-01-11 7:15 ` [U-Boot] [PATCH v3 01/16] efi_selftest: colored test output Heinrich Schuchardt
@ 2018-01-11 7:15 ` Heinrich Schuchardt
2018-01-16 14:56 ` Simon Glass
2018-01-11 7:15 ` [U-Boot] [PATCH v3 03/16] efi_selftest: do not try to close device path protocol Heinrich Schuchardt
` (13 subsequent siblings)
15 siblings, 1 reply; 22+ messages in thread
From: Heinrich Schuchardt @ 2018-01-11 7:15 UTC (permalink / raw)
To: u-boot
Replace list_for_each_safe() and list_entry() by
list_for_each_entry_safe().
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
---
v3
no change
v2
no change
---
lib/efi_loader/efi_boottime.c | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index 02bc9fdcf0..99eb36c306 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -425,18 +425,15 @@ efi_status_t efi_remove_protocol(const void *handle, const efi_guid_t *protocol,
efi_status_t efi_remove_all_protocols(const void *handle)
{
struct efi_object *efiobj;
- struct list_head *lhandle;
- struct list_head *pos;
+ struct efi_handler *protocol;
+ struct efi_handler *pos;
efiobj = efi_search_obj(handle);
if (!efiobj)
return EFI_INVALID_PARAMETER;
- list_for_each_safe(lhandle, pos, &efiobj->protocols) {
- struct efi_handler *protocol;
+ list_for_each_entry_safe(protocol, pos, &efiobj->protocols, link) {
efi_status_t ret;
- protocol = list_entry(lhandle, struct efi_handler, link);
-
ret = efi_remove_protocol(handle, protocol->guid,
protocol->protocol_interface);
if (ret != EFI_SUCCESS)
--
2.14.2
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [U-Boot] [PATCH v3 03/16] efi_selftest: do not try to close device path protocol
2018-01-11 7:15 [U-Boot] [PATCH v3 00/16] efi_loader: implement driver management Heinrich Schuchardt
2018-01-11 7:15 ` [U-Boot] [PATCH v3 01/16] efi_selftest: colored test output Heinrich Schuchardt
2018-01-11 7:15 ` [U-Boot] [PATCH v3 02/16] efi_loader: simplify efi_remove_all_protocols Heinrich Schuchardt
@ 2018-01-11 7:15 ` Heinrich Schuchardt
2018-01-16 14:56 ` Simon Glass
2018-01-11 7:15 ` [U-Boot] [PATCH v3 04/16] efi_loader: list of open protocol infos Heinrich Schuchardt
` (12 subsequent siblings)
15 siblings, 1 reply; 22+ messages in thread
From: Heinrich Schuchardt @ 2018-01-11 7:15 UTC (permalink / raw)
To: u-boot
CloseProtocol cannot be called without agent handle.
There is no need to close the device path protocol if
it has been opened without agent handle.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
---
v3
no change
v2
no change
---
lib/efi_selftest/efi_selftest_devicepath.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/lib/efi_selftest/efi_selftest_devicepath.c b/lib/efi_selftest/efi_selftest_devicepath.c
index 1ab54ebb37..d9a6697892 100644
--- a/lib/efi_selftest/efi_selftest_devicepath.c
+++ b/lib/efi_selftest/efi_selftest_devicepath.c
@@ -299,10 +299,10 @@ static int execute(void)
efi_st_error("FreePool failed\n");
return EFI_ST_FAILURE;
}
- ret = boottime->close_protocol(handles[i], &guid_device_path,
- NULL, NULL);
- if (ret != EFI_SUCCESS)
- efi_st_todo("Cannot close device path protocol.\n");
+ /*
+ * CloseProtocol cannot be called without agent handle.
+ * There is no need to close the device path protocol.
+ */
}
ret = boottime->free_pool(handles);
if (ret != EFI_SUCCESS) {
--
2.14.2
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [U-Boot] [PATCH v3 04/16] efi_loader: list of open protocol infos
2018-01-11 7:15 [U-Boot] [PATCH v3 00/16] efi_loader: implement driver management Heinrich Schuchardt
` (2 preceding siblings ...)
2018-01-11 7:15 ` [U-Boot] [PATCH v3 03/16] efi_selftest: do not try to close device path protocol Heinrich Schuchardt
@ 2018-01-11 7:15 ` Heinrich Schuchardt
2018-01-11 7:15 ` [U-Boot] [PATCH v3 05/16] efi_loader: open_info in OpenProtocol Heinrich Schuchardt
` (11 subsequent siblings)
15 siblings, 0 replies; 22+ messages in thread
From: Heinrich Schuchardt @ 2018-01-11 7:15 UTC (permalink / raw)
To: u-boot
Add a list of open protocol infos to each protocol of a handle.
Provide helper functions to access the list items.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
---
v3
no change
v2
no change
---
include/efi_loader.h | 15 ++++++++++++++-
lib/efi_loader/efi_boottime.c | 35 +++++++++++++++++++++++++++++++++++
2 files changed, 49 insertions(+), 1 deletion(-)
diff --git a/include/efi_loader.h b/include/efi_loader.h
index 6185055e78..637e6e166d 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -96,15 +96,28 @@ extern const efi_guid_t efi_file_info_guid;
extern unsigned int __efi_runtime_start, __efi_runtime_stop;
extern unsigned int __efi_runtime_rel_start, __efi_runtime_rel_stop;
+/*
+ * When a protocol is opened a open protocol info entry is created.
+ * These are maintained in a list.
+ */
+struct efi_open_protocol_info_item {
+ /* Link to the list of open protocol info entries of a protocol */
+ struct list_head link;
+ struct efi_open_protocol_info_entry info;
+};
+
/*
* 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 */
+ * protocol GUID to the respective protocol interface
+ */
struct efi_handler {
/* Link to the list of protocols of a handle */
struct list_head link;
const efi_guid_t *guid;
void *protocol_interface;
+ /* Link to the list of open protocol info items */
+ struct list_head open_infos;
};
/*
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index 99eb36c306..f5ec2a8866 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -814,6 +814,40 @@ struct efi_object *efi_search_obj(const void *handle)
return NULL;
}
+/*
+ * Create open protocol info entry and add it to a protocol.
+ *
+ * @handler handler of a protocol
+ * @return open protocol info entry
+ */
+static struct efi_open_protocol_info_entry *efi_create_open_info(
+ struct efi_handler *handler)
+{
+ struct efi_open_protocol_info_item *item;
+
+ item = calloc(1, sizeof(struct efi_open_protocol_info_item));
+ if (!item)
+ return NULL;
+ /* Append the item to the open protocol info list. */
+ list_add_tail(&item->link, &handler->open_infos);
+
+ return &item->info;
+}
+
+/*
+ * Remove an open protocol info entry from a protocol.
+ *
+ * @handler handler of a protocol
+ * @return status code
+ */
+static efi_status_t efi_delete_open_info(
+ struct efi_open_protocol_info_item *item)
+{
+ list_del(&item->link);
+ free(item);
+ return EFI_SUCCESS;
+}
+
/*
* Install new protocol on a handle.
*
@@ -840,6 +874,7 @@ efi_status_t efi_add_protocol(const void *handle, const efi_guid_t *protocol,
return EFI_OUT_OF_RESOURCES;
handler->guid = protocol;
handler->protocol_interface = protocol_interface;
+ INIT_LIST_HEAD(&handler->open_infos);
list_add_tail(&handler->link, &efiobj->protocols);
return EFI_SUCCESS;
}
--
2.14.2
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [U-Boot] [PATCH v3 05/16] efi_loader: open_info in OpenProtocol
2018-01-11 7:15 [U-Boot] [PATCH v3 00/16] efi_loader: implement driver management Heinrich Schuchardt
` (3 preceding siblings ...)
2018-01-11 7:15 ` [U-Boot] [PATCH v3 04/16] efi_loader: list of open protocol infos Heinrich Schuchardt
@ 2018-01-11 7:15 ` Heinrich Schuchardt
2018-01-11 7:15 ` [U-Boot] [PATCH v3 06/16] efi_loader: open_info in CloseProtocol Heinrich Schuchardt
` (10 subsequent siblings)
15 siblings, 0 replies; 22+ messages in thread
From: Heinrich Schuchardt @ 2018-01-11 7:15 UTC (permalink / raw)
To: u-boot
efi_open_protocol has to keep track of opened protocols.
OpenProtocol enters the agent and controller handle
information into this list.
A unit test is supplied with a subsequent patch.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
---
v3
no change
v2
no change
---
lib/efi_loader/efi_boottime.c | 107 ++++++++++++++++++++++++++++++++++++++++--
1 file changed, 103 insertions(+), 4 deletions(-)
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index f5ec2a8866..bb80c6066a 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -2100,6 +2100,101 @@ static void EFIAPI efi_set_mem(void *buffer, size_t size, uint8_t value)
EFI_EXIT(EFI_SUCCESS);
}
+/*
+ * Open protocol interface on a handle.
+ *
+ * @handler handler of a protocol
+ * @protocol_interface interface implementing the protocol
+ * @agent_handle handle of the driver
+ * @controller_handle handle of the controller
+ * @attributes attributes indicating how to open the protocol
+ * @return status code
+ */
+static efi_status_t efi_protocol_open(
+ struct efi_handler *handler,
+ void **protocol_interface, void *agent_handle,
+ void *controller_handle, uint32_t attributes)
+{
+ struct efi_open_protocol_info_item *item;
+ struct efi_open_protocol_info_entry *match = NULL;
+ bool opened_by_driver = false;
+ bool opened_exclusive = false;
+
+ /* If there is no agent, only return the interface */
+ if (!agent_handle)
+ goto out;
+
+ /* For TEST_PROTOCOL ignore interface attribute */
+ if (attributes != EFI_OPEN_PROTOCOL_TEST_PROTOCOL)
+ *protocol_interface = NULL;
+
+ /*
+ * Check if the protocol is already opened by a driver with the same
+ * attributes or opened exclusively
+ */
+ list_for_each_entry(item, &handler->open_infos, link) {
+ if (item->info.agent_handle == agent_handle) {
+ if ((attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) &&
+ (item->info.attributes == attributes))
+ return EFI_ALREADY_STARTED;
+ }
+ if (item->info.attributes & EFI_OPEN_PROTOCOL_EXCLUSIVE)
+ opened_exclusive = true;
+ }
+
+ /* Only one controller can open the protocol exclusively */
+ if (opened_exclusive && attributes &
+ (EFI_OPEN_PROTOCOL_EXCLUSIVE | EFI_OPEN_PROTOCOL_BY_DRIVER))
+ return EFI_ACCESS_DENIED;
+
+ /* Prepare exclusive opening */
+ if (attributes & EFI_OPEN_PROTOCOL_EXCLUSIVE) {
+ /* Try to disconnect controllers */
+ list_for_each_entry(item, &handler->open_infos, link) {
+ if (item->info.attributes ==
+ EFI_OPEN_PROTOCOL_BY_DRIVER)
+ EFI_CALL(efi_disconnect_controller(
+ item->info.controller_handle,
+ item->info.agent_handle,
+ NULL));
+ }
+ opened_by_driver = false;
+ /* Check if all controllers are disconnected */
+ list_for_each_entry(item, &handler->open_infos, link) {
+ if (item->info.attributes & EFI_OPEN_PROTOCOL_BY_DRIVER)
+ opened_by_driver = true;
+ }
+ /* Only one controller can be conncected */
+ if (opened_by_driver)
+ return EFI_ACCESS_DENIED;
+ }
+
+ /* Find existing entry */
+ list_for_each_entry(item, &handler->open_infos, link) {
+ if (item->info.agent_handle == agent_handle &&
+ item->info.controller_handle == controller_handle)
+ match = &item->info;
+ }
+ /* None found, create one */
+ if (!match) {
+ match = efi_create_open_info(handler);
+ if (!match)
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ match->agent_handle = agent_handle;
+ match->controller_handle = controller_handle;
+ match->attributes = attributes;
+ match->open_count++;
+
+out:
+ /* For TEST_PROTOCOL ignore interface attribute. */
+ if (attributes != EFI_OPEN_PROTOCOL_TEST_PROTOCOL)
+ *protocol_interface = handler->protocol_interface;
+
+ return EFI_SUCCESS;
+}
+
/*
* Open protocol interface on a handle.
*
@@ -2141,12 +2236,16 @@ static efi_status_t EFIAPI efi_open_protocol(
case EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER:
if (controller_handle == handle)
goto out;
+ /* fall-through */
case EFI_OPEN_PROTOCOL_BY_DRIVER:
case EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE:
- if (controller_handle == NULL)
+ /* Check that the controller handle is valid */
+ if (!efi_search_obj(controller_handle))
goto out;
+ /* fall-through */
case EFI_OPEN_PROTOCOL_EXCLUSIVE:
- if (agent_handle == NULL)
+ /* Check that the agent handle is valid */
+ if (!efi_search_obj(agent_handle))
goto out;
break;
default:
@@ -2157,8 +2256,8 @@ static efi_status_t EFIAPI efi_open_protocol(
if (r != EFI_SUCCESS)
goto out;
- if (attributes != EFI_OPEN_PROTOCOL_TEST_PROTOCOL)
- *protocol_interface = handler->protocol_interface;
+ r = efi_protocol_open(handler, protocol_interface, agent_handle,
+ controller_handle, attributes);
out:
return EFI_EXIT(r);
}
--
2.14.2
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [U-Boot] [PATCH v3 06/16] efi_loader: open_info in CloseProtocol
2018-01-11 7:15 [U-Boot] [PATCH v3 00/16] efi_loader: implement driver management Heinrich Schuchardt
` (4 preceding siblings ...)
2018-01-11 7:15 ` [U-Boot] [PATCH v3 05/16] efi_loader: open_info in OpenProtocol Heinrich Schuchardt
@ 2018-01-11 7:15 ` Heinrich Schuchardt
2018-01-11 7:16 ` [U-Boot] [PATCH v3 07/16] efi_loader: implement OpenProtocolInformation Heinrich Schuchardt
` (9 subsequent siblings)
15 siblings, 0 replies; 22+ messages in thread
From: Heinrich Schuchardt @ 2018-01-11 7:15 UTC (permalink / raw)
To: u-boot
efi_open_protocol and efi_close_protocol have to keep track of
opened protocols.
Check if the protocol was opened for the same agent and
controller.
Remove all open protocol information for this pair.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
---
v3
no change
v2
no change
---
lib/efi_loader/efi_boottime.c | 26 +++++++++++++++++++++++++-
1 file changed, 25 insertions(+), 1 deletion(-)
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index bb80c6066a..a527e33141 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -1675,9 +1675,33 @@ static efi_status_t EFIAPI efi_close_protocol(void *handle,
void *agent_handle,
void *controller_handle)
{
+ struct efi_handler *handler;
+ struct efi_open_protocol_info_item *item;
+ struct efi_open_protocol_info_item *pos;
+ efi_status_t r;
+
EFI_ENTRY("%p, %pUl, %p, %p", handle, protocol, agent_handle,
controller_handle);
- return EFI_EXIT(EFI_NOT_FOUND);
+
+ if (!agent_handle) {
+ r = EFI_INVALID_PARAMETER;
+ goto out;
+ }
+ r = efi_search_protocol(handle, protocol, &handler);
+ if (r != EFI_SUCCESS)
+ goto out;
+
+ r = EFI_NOT_FOUND;
+ list_for_each_entry_safe(item, pos, &handler->open_infos, link) {
+ if (item->info.agent_handle == agent_handle &&
+ item->info.controller_handle == controller_handle) {
+ efi_delete_open_info(item);
+ r = EFI_SUCCESS;
+ break;
+ }
+ }
+out:
+ return EFI_EXIT(r);
}
/*
--
2.14.2
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [U-Boot] [PATCH v3 07/16] efi_loader: implement OpenProtocolInformation
2018-01-11 7:15 [U-Boot] [PATCH v3 00/16] efi_loader: implement driver management Heinrich Schuchardt
` (5 preceding siblings ...)
2018-01-11 7:15 ` [U-Boot] [PATCH v3 06/16] efi_loader: open_info in CloseProtocol Heinrich Schuchardt
@ 2018-01-11 7:16 ` Heinrich Schuchardt
2018-01-19 16:30 ` Alexander Graf
2018-01-11 7:16 ` [U-Boot] [PATCH v3 08/16] efi_loader: debug output installed device path Heinrich Schuchardt
` (8 subsequent siblings)
15 siblings, 1 reply; 22+ messages in thread
From: Heinrich Schuchardt @ 2018-01-11 7:16 UTC (permalink / raw)
To: u-boot
efi_open_protocol_information provides the agent and controller
handles as well as the attributes and open count of an protocol
on a handle.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
---
v3
no change
v2
no change
---
lib/efi_loader/efi_boottime.c | 41 ++++++++++++++++++++++++++++++++++++++++-
1 file changed, 40 insertions(+), 1 deletion(-)
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index a527e33141..44c9da0a7c 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -1722,9 +1722,48 @@ static efi_status_t EFIAPI efi_open_protocol_information(efi_handle_t handle,
struct efi_open_protocol_info_entry **entry_buffer,
efi_uintn_t *entry_count)
{
+ unsigned long buffer_size;
+ unsigned long count;
+ struct efi_handler *handler;
+ struct efi_open_protocol_info_item *item;
+ efi_status_t r;
+
EFI_ENTRY("%p, %pUl, %p, %p", handle, protocol, entry_buffer,
entry_count);
- return EFI_EXIT(EFI_NOT_FOUND);
+
+ /* Check parameters */
+ if (!entry_buffer) {
+ r = EFI_INVALID_PARAMETER;
+ goto out;
+ }
+ r = efi_search_protocol(handle, protocol, &handler);
+ if (r != EFI_SUCCESS)
+ goto out;
+
+ /* Count entries */
+ count = 0;
+ list_for_each_entry(item, &handler->open_infos, link) {
+ ++count;
+ }
+ *entry_count = count;
+ *entry_buffer = NULL;
+ if (!count) {
+ r = EFI_SUCCESS;
+ goto out;
+ }
+
+ /* Copy entries */
+ buffer_size = count * sizeof(struct efi_open_protocol_info_entry);
+ r = efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES, buffer_size,
+ (void **)entry_buffer);
+ if (r != EFI_SUCCESS)
+ goto out;
+ list_for_each_entry_reverse(item, &handler->open_infos, link) {
+ if (item->info.open_count)
+ (*entry_buffer)[--count] = item->info;
+ }
+out:
+ return EFI_EXIT(r);
}
/*
--
2.14.2
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [U-Boot] [PATCH v3 07/16] efi_loader: implement OpenProtocolInformation
2018-01-11 7:16 ` [U-Boot] [PATCH v3 07/16] efi_loader: implement OpenProtocolInformation Heinrich Schuchardt
@ 2018-01-19 16:30 ` Alexander Graf
0 siblings, 0 replies; 22+ messages in thread
From: Alexander Graf @ 2018-01-19 16:30 UTC (permalink / raw)
To: u-boot
On 11.01.18 08:16, Heinrich Schuchardt wrote:
> efi_open_protocol_information provides the agent and controller
> handles as well as the attributes and open count of an protocol
> on a handle.
>
> Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
> ---
> v3
> no change
> v2
> no change
> ---
> lib/efi_loader/efi_boottime.c | 41 ++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 40 insertions(+), 1 deletion(-)
>
> diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
> index a527e33141..44c9da0a7c 100644
> --- a/lib/efi_loader/efi_boottime.c
> +++ b/lib/efi_loader/efi_boottime.c
> @@ -1722,9 +1722,48 @@ static efi_status_t EFIAPI efi_open_protocol_information(efi_handle_t handle,
> struct efi_open_protocol_info_entry **entry_buffer,
> efi_uintn_t *entry_count)
> {
> + unsigned long buffer_size;
> + unsigned long count;
> + struct efi_handler *handler;
> + struct efi_open_protocol_info_item *item;
> + efi_status_t r;
> +
> EFI_ENTRY("%p, %pUl, %p, %p", handle, protocol, entry_buffer,
> entry_count);
> - return EFI_EXIT(EFI_NOT_FOUND);
> +
> + /* Check parameters */
> + if (!entry_buffer) {
> + r = EFI_INVALID_PARAMETER;
> + goto out;
> + }
> + r = efi_search_protocol(handle, protocol, &handler);
> + if (r != EFI_SUCCESS)
> + goto out;
> +
> + /* Count entries */
> + count = 0;
> + list_for_each_entry(item, &handler->open_infos, link) {
> + ++count;
^
> + }
> + *entry_count = count;
> + *entry_buffer = NULL;
> + if (!count) {
> + r = EFI_SUCCESS;
> + goto out;
> + }
> +
> + /* Copy entries */
> + buffer_size = count * sizeof(struct efi_open_protocol_info_entry);
> + r = efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES, buffer_size,
> + (void **)entry_buffer);
> + if (r != EFI_SUCCESS)
> + goto out;
> + list_for_each_entry_reverse(item, &handler->open_infos, link) {
> + if (item->info.open_count)
> + (*entry_buffer)[--count] = item->info;
The count resulting here is different from the first count, as here you
also check item->info.open_count. Shouldn't that also get checked above?
Alex
> + }
> +out:
> + return EFI_EXIT(r);
> }
>
> /*
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* [U-Boot] [PATCH v3 08/16] efi_loader: debug output installed device path
2018-01-11 7:15 [U-Boot] [PATCH v3 00/16] efi_loader: implement driver management Heinrich Schuchardt
` (6 preceding siblings ...)
2018-01-11 7:16 ` [U-Boot] [PATCH v3 07/16] efi_loader: implement OpenProtocolInformation Heinrich Schuchardt
@ 2018-01-11 7:16 ` Heinrich Schuchardt
2018-01-11 7:16 ` [U-Boot] [PATCH v3 09/16] efi_loader: implement ConnectController Heinrich Schuchardt
` (7 subsequent siblings)
15 siblings, 0 replies; 22+ messages in thread
From: Heinrich Schuchardt @ 2018-01-11 7:16 UTC (permalink / raw)
To: u-boot
When a device path protocol is installed write the device
path to the console in debug mode.
For printing the new macro EFI_PRINT is used, which can be reused
for future diagnostic output.
Remove unused EFI_PRINT_GUID macro
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
---
v3
Avoid memory leak. Use printf("%pD") for device path output.
v2
Remove unused EFI_PRINT_GUID macro.
Use new macro EFI_PRINT to output device path.
---
include/efi_loader.h | 7 ++++---
lib/efi_loader/efi_boottime.c | 2 ++
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/include/efi_loader.h b/include/efi_loader.h
index 637e6e166d..4198329230 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -69,10 +69,11 @@ const char *__efi_nesting_dec(void);
} while(0)
/*
- * Write GUID
+ * Write an indented message with EFI prefix
*/
-#define EFI_PRINT_GUID(txt, guid) ({ \
- debug("%sEFI: %s %pUl\n", __efi_nesting(), txt, guid); \
+#define EFI_PRINT(format, ...) ({ \
+ debug("%sEFI: " format, __efi_nesting(), \
+ ##__VA_ARGS__); \
})
extern struct efi_runtime_services efi_runtime_services;
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index 44c9da0a7c..d232ed2c70 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -876,6 +876,8 @@ efi_status_t efi_add_protocol(const void *handle, const efi_guid_t *protocol,
handler->protocol_interface = protocol_interface;
INIT_LIST_HEAD(&handler->open_infos);
list_add_tail(&handler->link, &efiobj->protocols);
+ if (!guidcmp(&efi_guid_device_path, protocol))
+ EFI_PRINT("installed device path '%pD'\n", protocol_interface);
return EFI_SUCCESS;
}
--
2.14.2
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [U-Boot] [PATCH v3 09/16] efi_loader: implement ConnectController
2018-01-11 7:15 [U-Boot] [PATCH v3 00/16] efi_loader: implement driver management Heinrich Schuchardt
` (7 preceding siblings ...)
2018-01-11 7:16 ` [U-Boot] [PATCH v3 08/16] efi_loader: debug output installed device path Heinrich Schuchardt
@ 2018-01-11 7:16 ` Heinrich Schuchardt
2018-01-11 7:16 ` [U-Boot] [PATCH v3 10/16] efi_loader: fix signature of efi_disconnect_controller Heinrich Schuchardt
` (6 subsequent siblings)
15 siblings, 0 replies; 22+ messages in thread
From: Heinrich Schuchardt @ 2018-01-11 7:16 UTC (permalink / raw)
To: u-boot
Implement the ConnectController boot service.
A unit test is supplied in a subsequent patch.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
---
v3
Add more code comments.
v2
no change
---
include/efi_api.h | 22 +++++
include/efi_loader.h | 2 +
lib/efi_loader/efi_boottime.c | 187 ++++++++++++++++++++++++++++++++++++------
3 files changed, 187 insertions(+), 24 deletions(-)
diff --git a/include/efi_api.h b/include/efi_api.h
index 46963f2891..81e580dbbc 100644
--- a/include/efi_api.h
+++ b/include/efi_api.h
@@ -805,4 +805,26 @@ struct efi_file_info {
s16 file_name[0];
};
+#define EFI_DRIVER_BINDING_PROTOCOL_GUID \
+ EFI_GUID(0x18a031ab, 0xb443, 0x4d1a,\
+ 0xa5, 0xc0, 0x0c, 0x09, 0x26, 0x1e, 0x9f, 0x71)
+struct efi_driver_binding_protocol {
+ efi_status_t (EFIAPI * supported)(
+ struct efi_driver_binding_protocol *this,
+ efi_handle_t controller_handle,
+ struct efi_device_path *remaining_device_path);
+ efi_status_t (EFIAPI * start)(
+ struct efi_driver_binding_protocol *this,
+ efi_handle_t controller_handle,
+ struct efi_device_path *remaining_device_path);
+ efi_status_t (EFIAPI * stop)(
+ struct efi_driver_binding_protocol *this,
+ efi_handle_t controller_handle,
+ efi_uintn_t number_of_children,
+ efi_handle_t *child_handle_buffer);
+ u32 version;
+ efi_handle_t image_handle;
+ efi_handle_t driver_binding_handle;
+};
+
#endif
diff --git a/include/efi_loader.h b/include/efi_loader.h
index 4198329230..6726c44c47 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -89,6 +89,8 @@ uint16_t *efi_dp_str(struct efi_device_path *dp);
extern const efi_guid_t efi_global_variable_guid;
extern const efi_guid_t efi_guid_console_control;
extern const efi_guid_t efi_guid_device_path;
+/* GUID of the EFI_DRIVER_BINDING_PROTOCOL */
+extern const efi_guid_t efi_guid_driver_binding_protocol;
extern const efi_guid_t efi_guid_loaded_image;
extern const efi_guid_t efi_guid_device_path_to_text_protocol;
extern const efi_guid_t efi_simple_file_system_protocol_guid;
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index f82c0ba602..0687ded7f0 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -56,6 +56,9 @@ static volatile void *efi_gd, *app_gd;
static int entry_count;
static int nesting_level;
+/* GUID of the EFI_DRIVER_BINDING_PROTOCOL */
+const efi_guid_t efi_guid_driver_binding_protocol =
+ EFI_DRIVER_BINDING_PROTOCOL_GUID;
/* Called on every callback entry */
int __efi_entry_check(void)
@@ -1615,30 +1618,6 @@ static efi_status_t EFIAPI efi_set_watchdog_timer(unsigned long timeout,
return EFI_EXIT(efi_set_watchdog(timeout));
}
-/*
- * Connect a controller to a driver.
- *
- * This function implements the ConnectController service.
- * See the Unified Extensible Firmware Interface (UEFI) specification
- * for details.
- *
- * @controller_handle handle of the controller
- * @driver_image_handle handle of the driver
- * @remain_device_path device path of a child controller
- * @recursive true to connect all child controllers
- * @return status code
- */
-static efi_status_t EFIAPI efi_connect_controller(
- efi_handle_t controller_handle,
- efi_handle_t *driver_image_handle,
- struct efi_device_path *remain_device_path,
- bool recursive)
-{
- EFI_ENTRY("%p, %p, %p, %d", controller_handle, driver_image_handle,
- remain_device_path, recursive);
- return EFI_EXIT(EFI_NOT_FOUND);
-}
-
/*
* Disconnect a controller from a driver.
*
@@ -2348,6 +2327,166 @@ static efi_status_t EFIAPI efi_handle_protocol(void *handle,
NULL, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
}
+static efi_status_t efi_bind_controller(
+ efi_handle_t controller_handle,
+ efi_handle_t driver_image_handle,
+ struct efi_device_path *remain_device_path)
+{
+ struct efi_driver_binding_protocol *binding_protocol;
+ efi_status_t r;
+
+ r = EFI_CALL(efi_open_protocol(driver_image_handle,
+ &efi_guid_driver_binding_protocol,
+ (void **)&binding_protocol,
+ driver_image_handle, NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL));
+ if (r != EFI_SUCCESS)
+ return r;
+ r = EFI_CALL(binding_protocol->supported(binding_protocol,
+ controller_handle,
+ remain_device_path));
+ if (r == EFI_SUCCESS)
+ r = EFI_CALL(binding_protocol->start(binding_protocol,
+ controller_handle,
+ remain_device_path));
+ EFI_CALL(efi_close_protocol(driver_image_handle,
+ &efi_guid_driver_binding_protocol,
+ driver_image_handle, NULL));
+ return r;
+}
+
+static efi_status_t efi_connect_single_controller(
+ efi_handle_t controller_handle,
+ efi_handle_t *driver_image_handle,
+ struct efi_device_path *remain_device_path)
+{
+ efi_handle_t *buffer;
+ size_t count;
+ size_t i;
+ efi_status_t r;
+ size_t connected = 0;
+
+ /* Get buffer with all handles with driver binding protocol */
+ r = EFI_CALL(efi_locate_handle_buffer(BY_PROTOCOL,
+ &efi_guid_driver_binding_protocol,
+ NULL, &count, &buffer));
+ if (r != EFI_SUCCESS)
+ return r;
+
+ /* Context Override */
+ if (driver_image_handle) {
+ for (; *driver_image_handle; ++driver_image_handle) {
+ for (i = 0; i < count; ++i) {
+ if (buffer[i] == *driver_image_handle) {
+ buffer[i] = NULL;
+ r = efi_bind_controller(
+ controller_handle,
+ *driver_image_handle,
+ remain_device_path);
+ /*
+ * For drivers that do not support the
+ * controller or are already connected
+ * we receive an error code here.
+ */
+ if (r == EFI_SUCCESS)
+ ++connected;
+ }
+ }
+ }
+ }
+
+ /*
+ * TODO: Some overrides are not yet implemented:
+ * - Platform Driver Override
+ * - Driver Family Override Search
+ * - Bus Specific Driver Override
+ */
+
+ /* Driver Binding Search */
+ for (i = 0; i < count; ++i) {
+ if (buffer[i]) {
+ r = efi_bind_controller(controller_handle,
+ buffer[i],
+ remain_device_path);
+ if (r == EFI_SUCCESS)
+ ++connected;
+ }
+ }
+
+ efi_free_pool(buffer);
+ if (!connected)
+ return EFI_NOT_FOUND;
+ return EFI_SUCCESS;
+}
+
+/*
+ * Connect a controller to a driver.
+ *
+ * This function implements the ConnectController service.
+ * See the Unified Extensible Firmware Interface (UEFI) specification
+ * for details.
+ *
+ * First all driver binding protocol handles are tried for binding drivers.
+ * Afterwards all handles that have openened a protocol of the controller
+ * with EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER are connected to drivers.
+ *
+ * @controller_handle handle of the controller
+ * @driver_image_handle handle of the driver
+ * @remain_device_path device path of a child controller
+ * @recursive true to connect all child controllers
+ * @return status code
+ */
+static efi_status_t EFIAPI efi_connect_controller(
+ efi_handle_t controller_handle,
+ efi_handle_t *driver_image_handle,
+ struct efi_device_path *remain_device_path,
+ bool recursive)
+{
+ efi_status_t r;
+ efi_status_t ret = EFI_NOT_FOUND;
+ struct efi_object *efiobj;
+
+ EFI_ENTRY("%p, %p, %p, %d", controller_handle, driver_image_handle,
+ remain_device_path, recursive);
+
+ efiobj = efi_search_obj(controller_handle);
+ if (!efiobj) {
+ ret = EFI_INVALID_PARAMETER;
+ goto out;
+ }
+
+ r = efi_connect_single_controller(controller_handle,
+ driver_image_handle,
+ remain_device_path);
+ if (r == EFI_SUCCESS)
+ ret = EFI_SUCCESS;
+ if (recursive) {
+ struct efi_handler *handler;
+ struct efi_open_protocol_info_item *item;
+
+ list_for_each_entry(handler, &efiobj->protocols, link) {
+ list_for_each_entry(item, &handler->open_infos, link) {
+ if (item->info.attributes &
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) {
+ r = EFI_CALL(efi_connect_controller(
+ item->info.controller_handle,
+ driver_image_handle,
+ remain_device_path,
+ recursive));
+ if (r == EFI_SUCCESS)
+ ret = EFI_SUCCESS;
+ }
+ }
+ }
+ }
+ /* Check for child controller specified by end node */
+ if (ret != EFI_SUCCESS && remain_device_path &&
+ remain_device_path->type == DEVICE_PATH_TYPE_END)
+ ret = EFI_SUCCESS;
+out:
+ return EFI_EXIT(ret);
+}
+
static const struct efi_boot_services efi_boot_services = {
.hdr = {
.headersize = sizeof(struct efi_table_hdr),
--
2.14.2
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [U-Boot] [PATCH v3 10/16] efi_loader: fix signature of efi_disconnect_controller
2018-01-11 7:15 [U-Boot] [PATCH v3 00/16] efi_loader: implement driver management Heinrich Schuchardt
` (8 preceding siblings ...)
2018-01-11 7:16 ` [U-Boot] [PATCH v3 09/16] efi_loader: implement ConnectController Heinrich Schuchardt
@ 2018-01-11 7:16 ` Heinrich Schuchardt
2018-01-11 7:16 ` [U-Boot] [PATCH v3 11/16] efi_loader: implement DisconnectController Heinrich Schuchardt
` (5 subsequent siblings)
15 siblings, 0 replies; 22+ messages in thread
From: Heinrich Schuchardt @ 2018-01-11 7:16 UTC (permalink / raw)
To: u-boot
Handles should be passed as efi_handle_t and not as void *.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
---
v3
no change
v2
no change
---
include/efi_api.h | 6 ++++--
lib/efi_loader/efi_boottime.c | 7 ++++---
2 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/include/efi_api.h b/include/efi_api.h
index 81e580dbbc..7164492f83 100644
--- a/include/efi_api.h
+++ b/include/efi_api.h
@@ -125,8 +125,10 @@ struct efi_boot_services {
efi_handle_t *driver_image_handle,
struct efi_device_path *remaining_device_path,
bool recursive);
- efi_status_t (EFIAPI *disconnect_controller)(void *controller_handle,
- void *driver_image_handle, void *child_handle);
+ efi_status_t (EFIAPI *disconnect_controller)(
+ efi_handle_t controller_handle,
+ efi_handle_t driver_image_handle,
+ efi_handle_t child_handle);
#define EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL 0x00000001
#define EFI_OPEN_PROTOCOL_GET_PROTOCOL 0x00000002
#define EFI_OPEN_PROTOCOL_TEST_PROTOCOL 0x00000004
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index 0687ded7f0..8f9d24f6a7 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -1630,9 +1630,10 @@ static efi_status_t EFIAPI efi_set_watchdog_timer(unsigned long timeout,
* @child_handle handle of the child to destroy
* @return status code
*/
-static efi_status_t EFIAPI efi_disconnect_controller(void *controller_handle,
- void *driver_image_handle,
- void *child_handle)
+static efi_status_t EFIAPI efi_disconnect_controller(
+ efi_handle_t controller_handle,
+ efi_handle_t driver_image_handle,
+ efi_handle_t child_handle)
{
EFI_ENTRY("%p, %p, %p", controller_handle, driver_image_handle,
child_handle);
--
2.14.2
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [U-Boot] [PATCH v3 11/16] efi_loader: implement DisconnectController
2018-01-11 7:15 [U-Boot] [PATCH v3 00/16] efi_loader: implement driver management Heinrich Schuchardt
` (9 preceding siblings ...)
2018-01-11 7:16 ` [U-Boot] [PATCH v3 10/16] efi_loader: fix signature of efi_disconnect_controller Heinrich Schuchardt
@ 2018-01-11 7:16 ` Heinrich Schuchardt
2018-01-11 7:16 ` [U-Boot] [PATCH v3 12/16] efi_loader: disconnect controllers in UninstallProtocol Heinrich Schuchardt
` (4 subsequent siblings)
15 siblings, 0 replies; 22+ messages in thread
From: Heinrich Schuchardt @ 2018-01-11 7:16 UTC (permalink / raw)
To: u-boot
Unfortunately we need a forward declaration because both
OpenProtocol and CloseProtocol have to call DisconnectController.
And DisconnectController calls both OpenProtcol and CloseProtocol.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
---
v3
no change
v2
Return EFI_NOT_FOUND in disconnect_all_drivers if no
driver is disconnected.
---
lib/efi_loader/efi_boottime.c | 284 ++++++++++++++++++++++++++++++++++++++----
1 file changed, 262 insertions(+), 22 deletions(-)
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index 8f9d24f6a7..7e16a3f2cf 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -60,6 +60,10 @@ static int nesting_level;
const efi_guid_t efi_guid_driver_binding_protocol =
EFI_DRIVER_BINDING_PROTOCOL_GUID;
+static efi_status_t EFIAPI efi_disconnect_controller(void *controller_handle,
+ void *driver_image_handle,
+ void *child_handle);
+
/* Called on every callback entry */
int __efi_entry_check(void)
{
@@ -954,6 +958,109 @@ static efi_status_t EFIAPI efi_reinstall_protocol_interface(void *handle,
return EFI_EXIT(EFI_ACCESS_DENIED);
}
+/*
+ * Get all drivers associated to a controller.
+ * The allocated buffer has to be freed with free().
+ *
+ * @efiobj handle of the controller
+ * @protocol protocol guid (optional)
+ * @number_of_drivers number of child controllers
+ * @driver_handle_buffer handles of the the drivers
+ * @return status code
+ */
+static efi_status_t efi_get_drivers(struct efi_object *efiobj,
+ const efi_guid_t *protocol,
+ efi_uintn_t *number_of_drivers,
+ efi_handle_t **driver_handle_buffer)
+{
+ struct efi_handler *handler;
+ struct efi_open_protocol_info_item *item;
+ efi_uintn_t count = 0, i;
+ bool duplicate;
+
+ /* Count all driver associations */
+ list_for_each_entry(handler, &efiobj->protocols, link) {
+ if (protocol && guidcmp(handler->guid, protocol))
+ continue;
+ list_for_each_entry(item, &handler->open_infos, link) {
+ if (item->info.attributes &
+ EFI_OPEN_PROTOCOL_BY_DRIVER)
+ ++count;
+ }
+ }
+ /*
+ * Create buffer. In case of duplicate driver assignments the buffer
+ * will be too large. But that does not harm.
+ */
+ *number_of_drivers = 0;
+ *driver_handle_buffer = calloc(count, sizeof(efi_handle_t));
+ if (!*driver_handle_buffer)
+ return EFI_OUT_OF_RESOURCES;
+ /* Collect unique driver handles */
+ list_for_each_entry(handler, &efiobj->protocols, link) {
+ if (protocol && guidcmp(handler->guid, protocol))
+ continue;
+ list_for_each_entry(item, &handler->open_infos, link) {
+ if (item->info.attributes &
+ EFI_OPEN_PROTOCOL_BY_DRIVER) {
+ /* Check this is a new driver */
+ duplicate = false;
+ for (i = 0; i < *number_of_drivers; ++i) {
+ if ((*driver_handle_buffer)[i] ==
+ item->info.agent_handle)
+ duplicate = true;
+ }
+ /* Copy handle to buffer */
+ if (!duplicate) {
+ i = (*number_of_drivers)++;
+ (*driver_handle_buffer)[i] =
+ item->info.agent_handle;
+ }
+ }
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+/*
+ * Disconnect all drivers from a controller.
+ *
+ * This function implements the DisconnectController service.
+ * See the Unified Extensible Firmware Interface (UEFI) specification
+ * for details.
+ *
+ * @efiobj handle of the controller
+ * @protocol protocol guid (optional)
+ * @child_handle handle of the child to destroy
+ * @return status code
+ */
+static efi_status_t efi_disconnect_all_drivers(
+ struct efi_object *efiobj,
+ const efi_guid_t *protocol,
+ efi_handle_t child_handle)
+{
+ efi_uintn_t number_of_drivers;
+ efi_handle_t *driver_handle_buffer;
+ efi_status_t r, ret;
+
+ ret = efi_get_drivers(efiobj, protocol, &number_of_drivers,
+ &driver_handle_buffer);
+ if (ret != EFI_SUCCESS)
+ return ret;
+
+ ret = EFI_NOT_FOUND;
+ while (number_of_drivers) {
+ r = EFI_CALL(efi_disconnect_controller(
+ efiobj->handle,
+ driver_handle_buffer[--number_of_drivers],
+ child_handle));
+ if (r == EFI_SUCCESS)
+ ret = r;
+ }
+ free(driver_handle_buffer);
+ return ret;
+}
+
/*
* Uninstall protocol interface.
*
@@ -1618,28 +1725,6 @@ static efi_status_t EFIAPI efi_set_watchdog_timer(unsigned long timeout,
return EFI_EXIT(efi_set_watchdog(timeout));
}
-/*
- * Disconnect a controller from a driver.
- *
- * This function implements the DisconnectController service.
- * See the Unified Extensible Firmware Interface (UEFI) specification
- * for details.
- *
- * @controller_handle handle of the controller
- * @driver_image_handle handle of the driver
- * @child_handle handle of the child to destroy
- * @return status code
- */
-static efi_status_t EFIAPI efi_disconnect_controller(
- efi_handle_t controller_handle,
- efi_handle_t driver_image_handle,
- efi_handle_t child_handle)
-{
- EFI_ENTRY("%p, %p, %p", controller_handle, driver_image_handle,
- child_handle);
- return EFI_EXIT(EFI_INVALID_PARAMETER);
-}
-
/*
* Close a protocol.
*
@@ -2488,6 +2573,161 @@ out:
return EFI_EXIT(ret);
}
+/*
+ * Get all child controllers associated to a driver.
+ * The allocated buffer has to be freed with free().
+ *
+ * @efiobj handle of the controller
+ * @driver_handle handle of the driver
+ * @number_of_children number of child controllers
+ * @child_handle_buffer handles of the the child controllers
+ */
+static efi_status_t efi_get_child_controllers(
+ struct efi_object *efiobj,
+ efi_handle_t driver_handle,
+ efi_uintn_t *number_of_children,
+ efi_handle_t **child_handle_buffer)
+{
+ struct efi_handler *handler;
+ struct efi_open_protocol_info_item *item;
+ efi_uintn_t count = 0, i;
+ bool duplicate;
+
+ /* Count all child controller associations */
+ list_for_each_entry(handler, &efiobj->protocols, link) {
+ list_for_each_entry(item, &handler->open_infos, link) {
+ if (item->info.agent_handle == driver_handle &&
+ item->info.attributes &
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER)
+ ++count;
+ }
+ }
+ /*
+ * Create buffer. In case of duplicate child controller assignments
+ * the buffer will be too large. But that does not harm.
+ */
+ *number_of_children = 0;
+ *child_handle_buffer = calloc(count, sizeof(efi_handle_t));
+ if (!*child_handle_buffer)
+ return EFI_OUT_OF_RESOURCES;
+ /* Copy unique child handles */
+ list_for_each_entry(handler, &efiobj->protocols, link) {
+ list_for_each_entry(item, &handler->open_infos, link) {
+ if (item->info.agent_handle == driver_handle &&
+ item->info.attributes &
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) {
+ /* Check this is a new child controller */
+ duplicate = false;
+ for (i = 0; i < *number_of_children; ++i) {
+ if ((*child_handle_buffer)[i] ==
+ item->info.controller_handle)
+ duplicate = true;
+ }
+ /* Copy handle to buffer */
+ if (!duplicate) {
+ i = (*number_of_children)++;
+ (*child_handle_buffer)[i] =
+ item->info.controller_handle;
+ }
+ }
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+/*
+ * Disconnect a controller from a driver.
+ *
+ * This function implements the DisconnectController service.
+ * See the Unified Extensible Firmware Interface (UEFI) specification
+ * for details.
+ *
+ * @controller_handle handle of the controller
+ * @driver_image_handle handle of the driver
+ * @child_handle handle of the child to destroy
+ * @return status code
+ */
+static efi_status_t EFIAPI efi_disconnect_controller(
+ efi_handle_t controller_handle,
+ efi_handle_t driver_image_handle,
+ efi_handle_t child_handle)
+{
+ struct efi_driver_binding_protocol *binding_protocol;
+ efi_handle_t *child_handle_buffer = NULL;
+ size_t number_of_children = 0;
+ efi_status_t r;
+ size_t stop_count = 0;
+ struct efi_object *efiobj;
+
+ EFI_ENTRY("%p, %p, %p", controller_handle, driver_image_handle,
+ child_handle);
+
+ efiobj = efi_search_obj(controller_handle);
+ if (!efiobj) {
+ r = EFI_INVALID_PARAMETER;
+ goto out;
+ }
+
+ if (child_handle && !efi_search_obj(child_handle)) {
+ r = EFI_INVALID_PARAMETER;
+ goto out;
+ }
+
+ /* If no driver handle is supplied, disconnect all drivers */
+ if (!driver_image_handle) {
+ r = efi_disconnect_all_drivers(efiobj, NULL, child_handle);
+ goto out;
+ }
+
+ /* Create list of child handles */
+ if (child_handle) {
+ number_of_children = 1;
+ child_handle_buffer = &child_handle;
+ } else {
+ efi_get_child_controllers(efiobj,
+ driver_image_handle,
+ &number_of_children,
+ &child_handle_buffer);
+ }
+
+ /* Get the driver binding protocol */
+ r = EFI_CALL(efi_open_protocol(driver_image_handle,
+ &efi_guid_driver_binding_protocol,
+ (void **)&binding_protocol,
+ driver_image_handle, NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL));
+ if (r != EFI_SUCCESS)
+ goto out;
+ /* Remove the children */
+ if (number_of_children) {
+ r = EFI_CALL(binding_protocol->stop(binding_protocol,
+ controller_handle,
+ number_of_children,
+ child_handle_buffer));
+ if (r == EFI_SUCCESS)
+ ++stop_count;
+ }
+ /* Remove the driver */
+ if (!child_handle)
+ r = EFI_CALL(binding_protocol->stop(binding_protocol,
+ controller_handle,
+ 0, NULL));
+ if (r == EFI_SUCCESS)
+ ++stop_count;
+ EFI_CALL(efi_close_protocol(driver_image_handle,
+ &efi_guid_driver_binding_protocol,
+ driver_image_handle, NULL));
+
+ if (stop_count)
+ r = EFI_SUCCESS;
+ else
+ r = EFI_NOT_FOUND;
+out:
+ if (!child_handle)
+ free(child_handle_buffer);
+ return EFI_EXIT(r);
+}
+
static const struct efi_boot_services efi_boot_services = {
.hdr = {
.headersize = sizeof(struct efi_table_hdr),
--
2.14.2
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [U-Boot] [PATCH v3 12/16] efi_loader: disconnect controllers in UninstallProtocol
2018-01-11 7:15 [U-Boot] [PATCH v3 00/16] efi_loader: implement driver management Heinrich Schuchardt
` (10 preceding siblings ...)
2018-01-11 7:16 ` [U-Boot] [PATCH v3 11/16] efi_loader: implement DisconnectController Heinrich Schuchardt
@ 2018-01-11 7:16 ` Heinrich Schuchardt
2018-01-11 7:16 ` [U-Boot] [PATCH v3 13/16] efi_selftest: remove todo in manage protocols Heinrich Schuchardt
` (3 subsequent siblings)
15 siblings, 0 replies; 22+ messages in thread
From: Heinrich Schuchardt @ 2018-01-11 7:16 UTC (permalink / raw)
To: u-boot
The UninstallProtocol boot service should first try to
disconnect controllers that have been connected with
EFI_OPEN_PROTOCOL_BY_DRIVER.
If the protocol is still opened by an agent, it should be
closed.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
---
v3
no change
v2
no change
---
lib/efi_loader/efi_boottime.c | 29 +++++++++++++++++++++++------
1 file changed, 23 insertions(+), 6 deletions(-)
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index 7e16a3f2cf..ecf395f40b 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -1077,26 +1077,43 @@ static efi_status_t EFIAPI efi_uninstall_protocol_interface(
void *handle, const efi_guid_t *protocol,
void *protocol_interface)
{
+ struct efi_object *efiobj;
struct efi_handler *handler;
+ struct efi_open_protocol_info_item *item;
+ struct efi_open_protocol_info_item *pos;
efi_status_t r;
EFI_ENTRY("%p, %pUl, %p", handle, protocol, protocol_interface);
- if (!handle || !protocol) {
+ /* Check handle */
+ efiobj = efi_search_obj(handle);
+ if (!efiobj) {
r = EFI_INVALID_PARAMETER;
goto out;
}
-
/* Find the protocol on the handle */
r = efi_search_protocol(handle, protocol, &handler);
if (r != EFI_SUCCESS)
goto out;
- if (handler->protocol_interface) {
- /* TODO disconnect controllers */
+ /* Disconnect controllers */
+ efi_disconnect_all_drivers(efiobj, protocol, NULL);
+ if (!list_empty(&handler->open_infos)) {
r = EFI_ACCESS_DENIED;
- } else {
- r = efi_remove_protocol(handle, protocol, protocol_interface);
+ goto out;
+ }
+ /* Close protocol */
+ list_for_each_entry_safe(item, pos, &handler->open_infos, link) {
+ if (item->info.attributes ==
+ EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL ||
+ item->info.attributes == EFI_OPEN_PROTOCOL_GET_PROTOCOL ||
+ item->info.attributes == EFI_OPEN_PROTOCOL_TEST_PROTOCOL)
+ list_del(&item->link);
+ }
+ if (!list_empty(&handler->open_infos)) {
+ r = EFI_ACCESS_DENIED;
+ goto out;
}
+ r = efi_remove_protocol(handle, protocol, protocol_interface);
out:
return EFI_EXIT(r);
}
--
2.14.2
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [U-Boot] [PATCH v3 13/16] efi_selftest: remove todo in manage protocols
2018-01-11 7:15 [U-Boot] [PATCH v3 00/16] efi_loader: implement driver management Heinrich Schuchardt
` (11 preceding siblings ...)
2018-01-11 7:16 ` [U-Boot] [PATCH v3 12/16] efi_loader: disconnect controllers in UninstallProtocol Heinrich Schuchardt
@ 2018-01-11 7:16 ` Heinrich Schuchardt
2018-01-11 7:16 ` [U-Boot] [PATCH v3 14/16] efi_selftest: remove todo in device path test Heinrich Schuchardt
` (2 subsequent siblings)
15 siblings, 0 replies; 22+ messages in thread
From: Heinrich Schuchardt @ 2018-01-11 7:16 UTC (permalink / raw)
To: u-boot
The installation of UninstallProtocols is functional now.
So we do not expect errors when calling it.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
---
v3
no change
v2
no change
---
lib/efi_selftest/efi_selftest_manageprotocols.c | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/lib/efi_selftest/efi_selftest_manageprotocols.c b/lib/efi_selftest/efi_selftest_manageprotocols.c
index f20f1528d4..874f86102d 100644
--- a/lib/efi_selftest/efi_selftest_manageprotocols.c
+++ b/lib/efi_selftest/efi_selftest_manageprotocols.c
@@ -194,7 +194,7 @@ static int execute(void)
&guid3, &interface3,
NULL);
if (ret == EFI_SUCCESS) {
- efi_st_todo("UninstallMultipleProtocolInterfaces did not catch error\n");
+ efi_st_error("UninstallMultipleProtocolInterfaces did not catch error\n");
return EFI_ST_FAILURE;
}
@@ -273,8 +273,8 @@ static int execute(void)
&guid2, &interface2,
NULL);
if (ret != EFI_SUCCESS) {
- efi_st_todo("UninstallMultipleProtocolInterfaces failed\n");
- /* This test is known to fail due to missing implementation */
+ efi_st_error("UninstallMultipleProtocolInterfaces failed\n");
+ return EFI_ST_FAILURE;
}
/*
* Check that the protocols are really uninstalled.
@@ -287,8 +287,8 @@ static int execute(void)
return EFI_ST_FAILURE;
}
if (count != 1) {
- efi_st_todo("UninstallMultipleProtocolInterfaces failed to uninstall protocols\n");
- /* This test is known to fail due to missing implementation */
+ efi_st_error("UninstallMultipleProtocolInterfaces failed to uninstall protocols\n");
+ return EFI_ST_FAILURE;
}
ret = find_in_buffer(handle1, count, buffer);
if (ret != EFI_SUCCESS) {
@@ -327,19 +327,19 @@ static int execute(void)
ret = boottime->uninstall_protocol_interface(handle1, &guid1,
&interface1);
if (ret != EFI_SUCCESS) {
- efi_st_todo("UninstallProtocolInterface failed\n");
- /* This test is known to fail due to missing implementation */
+ efi_st_error("UninstallProtocolInterface failed\n");
+ return EFI_ST_FAILURE;
}
ret = boottime->handle_protocol(handle1, &guid1, (void **)&interface);
if (ret == EFI_SUCCESS) {
- efi_st_todo("UninstallProtocolInterface failed\n");
- /* This test is known to fail due to missing implementation */
+ efi_st_error("UninstallProtocolInterface failed\n");
+ return EFI_ST_FAILURE;
}
ret = boottime->uninstall_protocol_interface(handle1, &guid3,
&interface1);
if (ret != EFI_SUCCESS) {
- efi_st_todo("UninstallProtocolInterface failed\n");
- /* This test is known to fail due to missing implementation */
+ efi_st_error("UninstallProtocolInterface failed\n");
+ return EFI_ST_FAILURE;
}
return EFI_ST_SUCCESS;
--
2.14.2
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [U-Boot] [PATCH v3 14/16] efi_selftest: remove todo in device path test
2018-01-11 7:15 [U-Boot] [PATCH v3 00/16] efi_loader: implement driver management Heinrich Schuchardt
` (12 preceding siblings ...)
2018-01-11 7:16 ` [U-Boot] [PATCH v3 13/16] efi_selftest: remove todo in manage protocols Heinrich Schuchardt
@ 2018-01-11 7:16 ` Heinrich Schuchardt
2018-01-11 7:16 ` [U-Boot] [PATCH v3 15/16] efi_selftest: test for (Dis)ConnectController Heinrich Schuchardt
2018-01-11 7:16 ` [U-Boot] [PATCH v3 16/16] efi_loader: consistently use efi_handle_t for handles Heinrich Schuchardt
15 siblings, 0 replies; 22+ messages in thread
From: Heinrich Schuchardt @ 2018-01-11 7:16 UTC (permalink / raw)
To: u-boot
The installation of UninstallProtocol is functional now.
So we do not expect errors when calling it.
Call UninstallProtocol with correct level of indirection
for parameter handle.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
---
v3
no change
v2
no change
---
lib/efi_selftest/efi_selftest_devicepath.c | 40 +++++++++++++++++++-----------
1 file changed, 25 insertions(+), 15 deletions(-)
diff --git a/lib/efi_selftest/efi_selftest_devicepath.c b/lib/efi_selftest/efi_selftest_devicepath.c
index d9a6697892..2f8f3c7f15 100644
--- a/lib/efi_selftest/efi_selftest_devicepath.c
+++ b/lib/efi_selftest/efi_selftest_devicepath.c
@@ -192,31 +192,41 @@ static int teardown(void)
{
efi_status_t ret;
- ret = boottime->uninstall_protocol_interface(&handle1,
+ ret = boottime->uninstall_protocol_interface(handle1,
&guid_device_path,
dp1);
- if (ret != EFI_SUCCESS)
- efi_st_todo("UninstallProtocolInterface failed\n");
- ret = boottime->uninstall_protocol_interface(&handle1,
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("UninstallProtocolInterface failed\n");
+ return EFI_ST_FAILURE;
+ }
+ ret = boottime->uninstall_protocol_interface(handle1,
&guid_protocol,
&interface);
- if (ret != EFI_SUCCESS)
- efi_st_todo("UninstallProtocolInterface failed\n");
- ret = boottime->uninstall_protocol_interface(&handle2,
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("UninstallProtocolInterface failed\n");
+ return EFI_ST_FAILURE;
+ }
+ ret = boottime->uninstall_protocol_interface(handle2,
&guid_device_path,
dp2);
- if (ret != EFI_SUCCESS)
- efi_st_todo("UninstallProtocolInterface failed\n");
- ret = boottime->uninstall_protocol_interface(&handle2,
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("UninstallProtocolInterface failed\n");
+ return EFI_ST_FAILURE;
+ }
+ ret = boottime->uninstall_protocol_interface(handle2,
&guid_protocol,
&interface);
- if (ret != EFI_SUCCESS)
- efi_st_todo("UninstallProtocolInterface failed\n");
- ret = boottime->uninstall_protocol_interface(&handle3,
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("UninstallProtocolInterface failed\n");
+ return EFI_ST_FAILURE;
+ }
+ ret = boottime->uninstall_protocol_interface(handle3,
&guid_device_path,
dp3);
- if (ret != EFI_SUCCESS)
- efi_st_todo("UninstallProtocolInterface failed\n");
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("UninstallProtocolInterface failed\n");
+ return EFI_ST_FAILURE;
+ }
if (dp1) {
ret = boottime->free_pool(dp1);
if (ret != EFI_SUCCESS) {
--
2.14.2
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [U-Boot] [PATCH v3 15/16] efi_selftest: test for (Dis)ConnectController
2018-01-11 7:15 [U-Boot] [PATCH v3 00/16] efi_loader: implement driver management Heinrich Schuchardt
` (13 preceding siblings ...)
2018-01-11 7:16 ` [U-Boot] [PATCH v3 14/16] efi_selftest: remove todo in device path test Heinrich Schuchardt
@ 2018-01-11 7:16 ` Heinrich Schuchardt
2018-01-11 7:16 ` [U-Boot] [PATCH v3 16/16] efi_loader: consistently use efi_handle_t for handles Heinrich Schuchardt
15 siblings, 0 replies; 22+ messages in thread
From: Heinrich Schuchardt @ 2018-01-11 7:16 UTC (permalink / raw)
To: u-boot
This unit test checks the following protocol services:
ConnectController, DisconnectController,
InstallProtocol, UninstallProtocol,
OpenProtocol, CloseProtcol, OpenProtocolInformation
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
---
v3
no change
v2
define binding_interface as static struct
---
lib/efi_selftest/Makefile | 1 +
lib/efi_selftest/efi_selftest_controllers.c | 385 ++++++++++++++++++++++++++++
2 files changed, 386 insertions(+)
create mode 100644 lib/efi_selftest/efi_selftest_controllers.c
diff --git a/lib/efi_selftest/Makefile b/lib/efi_selftest/Makefile
index 837e86228e..e549553c82 100644
--- a/lib/efi_selftest/Makefile
+++ b/lib/efi_selftest/Makefile
@@ -9,6 +9,7 @@
obj-$(CONFIG_CMD_BOOTEFI_SELFTEST) += \
efi_selftest.o \
+efi_selftest_controllers.o \
efi_selftest_console.o \
efi_selftest_devicepath.o \
efi_selftest_events.o \
diff --git a/lib/efi_selftest/efi_selftest_controllers.c b/lib/efi_selftest/efi_selftest_controllers.c
new file mode 100644
index 0000000000..1a22aba6f4
--- /dev/null
+++ b/lib/efi_selftest/efi_selftest_controllers.c
@@ -0,0 +1,385 @@
+/*
+ * efi_selftest_controllers
+ *
+ * Copyright (c) 2017 Heinrich Schuchardt <xypron.glpk@gmx.de>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * This unit test checks the following protocol services:
+ * ConnectController, DisconnectController,
+ * InstallProtocol, UninstallProtocol,
+ * OpenProtocol, CloseProtcol, OpenProtocolInformation
+ */
+
+#include <efi_selftest.h>
+
+#define NUMBER_OF_CHILD_CONTROLLERS 4
+
+static struct efi_boot_services *boottime;
+const efi_guid_t guid_driver_binding_protocol =
+ EFI_DRIVER_BINDING_PROTOCOL_GUID;
+static efi_guid_t guid_controller =
+ EFI_GUID(0xe6ab1d96, 0x6bff, 0xdb42,
+ 0xaa, 0x05, 0xc8, 0x1f, 0x7f, 0x45, 0x26, 0x34);
+static efi_guid_t guid_child_controller =
+ EFI_GUID(0x1d41f6f5, 0x2c41, 0xddfb,
+ 0xe2, 0x9b, 0xb8, 0x0e, 0x2e, 0xe8, 0x3a, 0x85);
+static efi_handle_t handle_controller;
+static efi_handle_t handle_child_controller[NUMBER_OF_CHILD_CONTROLLERS];
+static efi_handle_t handle_driver;
+
+/*
+ * Count child controllers
+ *
+ * @handle handle on which child controllers are installed
+ * @protocol protocol for which the child controlles where installed
+ * @count number of child controllers
+ * @return status code
+ */
+static efi_status_t count_child_controllers(efi_handle_t handle,
+ efi_guid_t *protocol,
+ efi_uintn_t *count)
+{
+ efi_status_t ret;
+ efi_uintn_t entry_count;
+ struct efi_open_protocol_info_entry *entry_buffer;
+
+ *count = 0;
+ ret = boottime->open_protocol_information(handle, protocol,
+ &entry_buffer, &entry_count);
+ if (ret != EFI_SUCCESS)
+ return ret;
+ if (!entry_count)
+ return EFI_SUCCESS;
+ while (entry_count) {
+ if (entry_buffer[--entry_count].attributes &
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER)
+ ++*count;
+ }
+ ret = boottime->free_pool(entry_buffer);
+ if (ret != EFI_SUCCESS)
+ efi_st_error("Cannot free buffer\n");
+ return ret;
+}
+
+/*
+ * Check if the driver supports the controller.
+ *
+ * @this driver binding protocol
+ * @controller_handle handle of the controller
+ * @remaining_device_path path specifying the child controller
+ * @return status code
+ */
+static efi_status_t EFIAPI supported(
+ struct efi_driver_binding_protocol *this,
+ efi_handle_t controller_handle,
+ struct efi_device_path *remaining_device_path)
+{
+ efi_status_t ret;
+ void *interface;
+
+ ret = boottime->open_protocol(
+ controller_handle, &guid_controller,
+ &interface, handle_driver,
+ controller_handle, EFI_OPEN_PROTOCOL_BY_DRIVER);
+ switch (ret) {
+ case EFI_ACCESS_DENIED:
+ case EFI_ALREADY_STARTED:
+ return ret;
+ case EFI_SUCCESS:
+ break;
+ default:
+ return EFI_UNSUPPORTED;
+ }
+ ret = boottime->close_protocol(
+ controller_handle, &guid_controller,
+ handle_driver, controller_handle);
+ if (ret != EFI_SUCCESS)
+ ret = EFI_UNSUPPORTED;
+ return ret;
+}
+
+/*
+ * Create child controllers and attach driver.
+ *
+ * @this driver binding protocol
+ * @controller_handle handle of the controller
+ * @remaining_device_path path specifying the child controller
+ * @return status code
+ */
+static efi_status_t EFIAPI start(
+ struct efi_driver_binding_protocol *this,
+ efi_handle_t controller_handle,
+ struct efi_device_path *remaining_device_path)
+{
+ size_t i;
+ efi_status_t ret;
+ void *interface;
+
+ /* Attach driver to controller */
+ ret = boottime->open_protocol(
+ controller_handle, &guid_controller,
+ &interface, handle_driver,
+ controller_handle, EFI_OPEN_PROTOCOL_BY_DRIVER);
+ switch (ret) {
+ case EFI_ACCESS_DENIED:
+ case EFI_ALREADY_STARTED:
+ return ret;
+ case EFI_SUCCESS:
+ break;
+ default:
+ return EFI_UNSUPPORTED;
+ }
+
+ /* Create child controllers */
+ for (i = 0; i < NUMBER_OF_CHILD_CONTROLLERS; ++i) {
+ ret = boottime->install_protocol_interface(
+ &handle_child_controller[i], &guid_child_controller,
+ EFI_NATIVE_INTERFACE, NULL);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("InstallProtocolInterface failed\n");
+ return EFI_ST_FAILURE;
+ }
+ ret = boottime->open_protocol(
+ controller_handle, &guid_controller,
+ &interface, handle_child_controller[i],
+ handle_child_controller[i],
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("OpenProtocol failed\n");
+ return EFI_ST_FAILURE;
+ }
+ }
+ return ret;
+}
+
+/*
+ * Remove a single child controller from the parent controller.
+ *
+ * @controller_handle parent controller
+ * @child_handle child controller
+ * @return status code
+ */
+static efi_status_t disconnect_child(efi_handle_t controller_handle,
+ efi_handle_t child_handle)
+{
+ efi_status_t ret;
+
+ ret = boottime->close_protocol(
+ controller_handle, &guid_controller,
+ child_handle, child_handle);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Cannot close protocol\n");
+ return ret;
+ }
+ ret = boottime->uninstall_protocol_interface(
+ child_handle, &guid_child_controller, NULL);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Cannot uninstall protocol interface\n");
+ return ret;
+ }
+ return ret;
+}
+
+/*
+ * Remove child controllers and disconnect the controller.
+ *
+ * @this driver binding protocol
+ * @controller_handle handle of the controller
+ * @number_of_children number of child controllers to remove
+ * @child_handle_buffer handles of the child controllers to remove
+ * @return status code
+ */
+static efi_status_t EFIAPI stop(
+ struct efi_driver_binding_protocol *this,
+ efi_handle_t controller_handle,
+ size_t number_of_children,
+ efi_handle_t *child_handle_buffer)
+{
+ efi_status_t ret;
+ efi_uintn_t count;
+ struct efi_open_protocol_info_entry *entry_buffer;
+
+ /* Destroy provided child controllers */
+ if (number_of_children) {
+ efi_uintn_t i;
+
+ for (i = 0; i < number_of_children; ++i) {
+ ret = disconnect_child(controller_handle,
+ child_handle_buffer[i]);
+ if (ret != EFI_SUCCESS)
+ return ret;
+ }
+ return EFI_SUCCESS;
+ }
+
+ /* Destroy all children */
+ ret = boottime->open_protocol_information(
+ controller_handle, &guid_controller,
+ &entry_buffer, &count);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("OpenProtocolInformation failed\n");
+ return ret;
+ }
+ while (count) {
+ if (entry_buffer[--count].attributes &
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) {
+ ret = disconnect_child(
+ controller_handle,
+ entry_buffer[count].agent_handle);
+ if (ret != EFI_SUCCESS)
+ return ret;
+ }
+ }
+ ret = boottime->free_pool(entry_buffer);
+ if (ret != EFI_SUCCESS)
+ efi_st_error("Cannot free buffer\n");
+
+ /* Detach driver from controller */
+ ret = boottime->close_protocol(
+ controller_handle, &guid_controller,
+ handle_driver, controller_handle);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Cannot close protocol\n");
+ return ret;
+ }
+ return EFI_SUCCESS;
+}
+
+/* Driver binding protocol interface */
+static struct efi_driver_binding_protocol binding_interface = {
+ supported,
+ start,
+ stop,
+ 0xffffffff,
+ NULL,
+ NULL,
+ };
+
+/*
+ * Setup unit test.
+ *
+ * @handle handle of the loaded image
+ * @systable system table
+ */
+static int setup(const efi_handle_t img_handle,
+ const struct efi_system_table *systable)
+{
+ efi_status_t ret;
+
+ boottime = systable->boottime;
+
+ /* Create controller handle */
+ ret = boottime->install_protocol_interface(
+ &handle_controller, &guid_controller,
+ EFI_NATIVE_INTERFACE, NULL);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("InstallProtocolInterface failed\n");
+ return EFI_ST_FAILURE;
+ }
+ /* Create driver handle */
+ ret = boottime->install_protocol_interface(
+ &handle_driver, &guid_driver_binding_protocol,
+ EFI_NATIVE_INTERFACE, &binding_interface);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("InstallProtocolInterface failed\n");
+ return EFI_ST_FAILURE;
+ }
+
+ return EFI_ST_SUCCESS;
+}
+
+/*
+ * Execute unit test.
+ *
+ * The number of child controllers is checked after each of the following
+ * actions:
+ *
+ * Connect a controller to a driver.
+ * Disconnect and destroy a child controller.
+ * Disconnect and destroy the remaining child controllers.
+ *
+ * Connect a controller to a driver.
+ * Uninstall the driver protocol from the controller.
+ */
+static int execute(void)
+{
+ efi_status_t ret;
+ efi_uintn_t count;
+
+ /* Connect controller to driver */
+ ret = boottime->connect_controller(handle_controller, NULL, NULL, 1);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Failed to connect controller\n");
+ return EFI_ST_FAILURE;
+ }
+ /* Check number of child controllers */
+ ret = count_child_controllers(handle_controller, &guid_controller,
+ &count);
+ if (ret != EFI_SUCCESS || count != NUMBER_OF_CHILD_CONTROLLERS) {
+ efi_st_error("Number of children %u != %u\n",
+ (unsigned int)count, NUMBER_OF_CHILD_CONTROLLERS);
+ }
+ /* Destroy second child controller */
+ ret = boottime->disconnect_controller(handle_controller,
+ handle_driver,
+ handle_child_controller[1]);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Failed to disconnect child controller\n");
+ return EFI_ST_FAILURE;
+ }
+ /* Check number of child controllers */
+ ret = count_child_controllers(handle_controller, &guid_controller,
+ &count);
+ if (ret != EFI_SUCCESS || count != NUMBER_OF_CHILD_CONTROLLERS - 1) {
+ efi_st_error("Destroying single child controller failed\n");
+ return EFI_ST_FAILURE;
+ }
+ /* Destroy remaining child controllers and disconnect controller */
+ ret = boottime->disconnect_controller(handle_controller, NULL, NULL);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Failed to disconnect controller\n");
+ return EFI_ST_FAILURE;
+ }
+ /* Check number of child controllers */
+ ret = count_child_controllers(handle_controller, &guid_controller,
+ &count);
+ if (ret != EFI_SUCCESS || count) {
+ efi_st_error("Destroying child controllers failed\n");
+ return EFI_ST_FAILURE;
+ }
+
+ /* Connect controller to driver */
+ ret = boottime->connect_controller(handle_controller, NULL, NULL, 1);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Failed to connect controller\n");
+ return EFI_ST_FAILURE;
+ }
+ /* Check number of child controllers */
+ ret = count_child_controllers(handle_controller, &guid_controller,
+ &count);
+ if (ret != EFI_SUCCESS || count != NUMBER_OF_CHILD_CONTROLLERS) {
+ efi_st_error("Number of children %u != %u\n",
+ (unsigned int)count, NUMBER_OF_CHILD_CONTROLLERS);
+ }
+ /* Uninstall controller protocol */
+ ret = boottime->uninstall_protocol_interface(handle_controller,
+ &guid_controller, NULL);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Failed to uninstall protocols\n");
+ return EFI_ST_FAILURE;
+ }
+ /* Check number of child controllers */
+ ret = count_child_controllers(handle_controller, &guid_controller,
+ &count);
+ if (ret == EFI_SUCCESS)
+ efi_st_error("Uninstall failed\n");
+ return EFI_ST_SUCCESS;
+}
+
+EFI_UNIT_TEST(controllers) = {
+ .name = "controllers",
+ .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
+ .setup = setup,
+ .execute = execute,
+};
--
2.14.2
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [U-Boot] [PATCH v3 16/16] efi_loader: consistently use efi_handle_t for handles
2018-01-11 7:15 [U-Boot] [PATCH v3 00/16] efi_loader: implement driver management Heinrich Schuchardt
` (14 preceding siblings ...)
2018-01-11 7:16 ` [U-Boot] [PATCH v3 15/16] efi_selftest: test for (Dis)ConnectController Heinrich Schuchardt
@ 2018-01-11 7:16 ` Heinrich Schuchardt
2018-01-16 14:56 ` Simon Glass
15 siblings, 1 reply; 22+ messages in thread
From: Heinrich Schuchardt @ 2018-01-11 7:16 UTC (permalink / raw)
To: u-boot
We should consistently use the efi_handle_t typedef when
referring to handles.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
---
v3
no change
v2
no change
---
cmd/bootefi.c | 10 ++++-----
include/efi_api.h | 20 ++++++++++--------
include/efi_loader.h | 14 +++++++------
lib/efi_loader/efi_boottime.c | 49 +++++++++++++++++++++++--------------------
lib/efi_loader/efi_console.c | 6 +++---
5 files changed, 53 insertions(+), 46 deletions(-)
diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index 78ff109835..97a4f269ae 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -122,8 +122,8 @@ static void *copy_fdt(void *fdt)
}
static efi_status_t efi_do_enter(
- void *image_handle, struct efi_system_table *st,
- asmlinkage ulong (*entry)(void *image_handle,
+ efi_handle_t image_handle, struct efi_system_table *st,
+ asmlinkage ulong (*entry)(efi_handle_t image_handle,
struct efi_system_table *st))
{
efi_status_t ret = EFI_LOAD_ERROR;
@@ -136,8 +136,8 @@ static efi_status_t efi_do_enter(
#ifdef CONFIG_ARM64
static efi_status_t efi_run_in_el2(asmlinkage ulong (*entry)(
- void *image_handle, struct efi_system_table *st),
- void *image_handle, struct efi_system_table *st)
+ efi_handle_t image_handle, struct efi_system_table *st),
+ efi_handle_t image_handle, struct efi_system_table *st)
{
/* Enable caches again */
dcache_enable();
@@ -159,7 +159,7 @@ static efi_status_t do_bootefi_exec(void *efi, void *fdt,
struct efi_device_path *memdp = NULL;
ulong ret;
- ulong (*entry)(void *image_handle, struct efi_system_table *st)
+ ulong (*entry)(efi_handle_t image_handle, struct efi_system_table *st)
asmlinkage;
ulong fdt_pages, fdt_size, fdt_start, fdt_end;
const efi_guid_t fdt_guid = EFI_FDT_GUID;
diff --git a/include/efi_api.h b/include/efi_api.h
index 7164492f83..502fffed20 100644
--- a/include/efi_api.h
+++ b/include/efi_api.h
@@ -84,11 +84,12 @@ struct efi_boot_services {
efi_status_t (EFIAPI *reinstall_protocol_interface)(
void *handle, const efi_guid_t *protocol,
void *old_interface, void *new_interface);
- efi_status_t (EFIAPI *uninstall_protocol_interface)(void *handle,
- const efi_guid_t *protocol, void *protocol_interface);
- efi_status_t (EFIAPI *handle_protocol)(efi_handle_t,
- const efi_guid_t *protocol,
- void **protocol_interface);
+ efi_status_t (EFIAPI *uninstall_protocol_interface)(
+ efi_handle_t handle, const efi_guid_t *protocol,
+ void *protocol_interface);
+ efi_status_t (EFIAPI *handle_protocol)(
+ efi_handle_t handle, const efi_guid_t *protocol,
+ void **protocol_interface);
void *reserved;
efi_status_t (EFIAPI *register_protocol_notify)(
const efi_guid_t *protocol, struct efi_event *event,
@@ -113,7 +114,7 @@ struct efi_boot_services {
efi_status_t (EFIAPI *exit)(efi_handle_t handle,
efi_status_t exit_status,
unsigned long exitdata_size, s16 *exitdata);
- efi_status_t (EFIAPI *unload_image)(void *image_handle);
+ efi_status_t (EFIAPI *unload_image)(efi_handle_t image_handle);
efi_status_t (EFIAPI *exit_boot_services)(efi_handle_t, unsigned long);
efi_status_t (EFIAPI *get_next_monotonic_count)(u64 *count);
@@ -139,9 +140,10 @@ struct efi_boot_services {
const efi_guid_t *protocol, void **interface,
efi_handle_t agent_handle,
efi_handle_t controller_handle, u32 attributes);
- efi_status_t (EFIAPI *close_protocol)(void *handle,
- const efi_guid_t *protocol, void *agent_handle,
- void *controller_handle);
+ efi_status_t (EFIAPI *close_protocol)(
+ efi_handle_t handle, const efi_guid_t *protocol,
+ efi_handle_t agent_handle,
+ efi_handle_t controller_handle);
efi_status_t(EFIAPI *open_protocol_information)(efi_handle_t handle,
const efi_guid_t *protocol,
struct efi_open_protocol_info_entry **entry_buffer,
diff --git a/include/efi_loader.h b/include/efi_loader.h
index 6726c44c47..37389c33cc 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -205,23 +205,25 @@ void efi_set_bootdev(const char *dev, const char *devnr, const char *path);
/* Add a new object to the object list. */
void efi_add_handle(struct efi_object *obj);
/* Create handle */
-efi_status_t efi_create_handle(void **handle);
+efi_status_t efi_create_handle(efi_handle_t *handle);
/* Delete handle */
void efi_delete_handle(struct efi_object *obj);
/* Call this to validate a handle and find the EFI object for it */
-struct efi_object *efi_search_obj(const void *handle);
+struct efi_object *efi_search_obj(const efi_handle_t handle);
/* Find a protocol on a handle */
-efi_status_t efi_search_protocol(const void *handle,
+efi_status_t efi_search_protocol(const efi_handle_t handle,
const efi_guid_t *protocol_guid,
struct efi_handler **handler);
/* Install new protocol on a handle */
-efi_status_t efi_add_protocol(const void *handle, const efi_guid_t *protocol,
+efi_status_t efi_add_protocol(const efi_handle_t handle,
+ const efi_guid_t *protocol,
void *protocol_interface);
/* Delete protocol from a handle */
-efi_status_t efi_remove_protocol(const void *handle, const efi_guid_t *protocol,
+efi_status_t efi_remove_protocol(const efi_handle_t handle,
+ const efi_guid_t *protocol,
void *protocol_interface);
/* Delete all protocols from a handle */
-efi_status_t efi_remove_all_protocols(const void *handle);
+efi_status_t efi_remove_all_protocols(const efi_handle_t handle);
/* Call this to create an event */
efi_status_t efi_create_event(uint32_t type, efi_uintn_t notify_tpl,
void (EFIAPI *notify_function) (
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index ecf395f40b..3e6d0f1dbc 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -60,9 +60,10 @@ static int nesting_level;
const efi_guid_t efi_guid_driver_binding_protocol =
EFI_DRIVER_BINDING_PROTOCOL_GUID;
-static efi_status_t EFIAPI efi_disconnect_controller(void *controller_handle,
- void *driver_image_handle,
- void *child_handle);
+static efi_status_t EFIAPI efi_disconnect_controller(
+ efi_handle_t controller_handle,
+ efi_handle_t driver_image_handle,
+ efi_handle_t child_handle);
/* Called on every callback entry */
int __efi_entry_check(void)
@@ -351,7 +352,7 @@ void efi_add_handle(struct efi_object *obj)
* @handle new handle
* @return status code
*/
-efi_status_t efi_create_handle(void **handle)
+efi_status_t efi_create_handle(efi_handle_t *handle)
{
struct efi_object *obj;
efi_status_t r;
@@ -374,7 +375,7 @@ efi_status_t efi_create_handle(void **handle)
* @handler reference to the protocol
* @return status code
*/
-efi_status_t efi_search_protocol(const void *handle,
+efi_status_t efi_search_protocol(const efi_handle_t handle,
const efi_guid_t *protocol_guid,
struct efi_handler **handler)
{
@@ -407,7 +408,8 @@ efi_status_t efi_search_protocol(const void *handle,
* @protocol_interface interface of the protocol implementation
* @return status code
*/
-efi_status_t efi_remove_protocol(const void *handle, const efi_guid_t *protocol,
+efi_status_t efi_remove_protocol(const efi_handle_t handle,
+ const efi_guid_t *protocol,
void *protocol_interface)
{
struct efi_handler *handler;
@@ -429,7 +431,7 @@ efi_status_t efi_remove_protocol(const void *handle, const efi_guid_t *protocol,
* @handle handle from which the protocols shall be deleted
* @return status code
*/
-efi_status_t efi_remove_all_protocols(const void *handle)
+efi_status_t efi_remove_all_protocols(const efi_handle_t handle)
{
struct efi_object *efiobj;
struct efi_handler *protocol;
@@ -809,7 +811,7 @@ static efi_status_t EFIAPI efi_check_event(struct efi_event *event)
* @handle handle to find
* @return EFI object
*/
-struct efi_object *efi_search_obj(const void *handle)
+struct efi_object *efi_search_obj(const efi_handle_t handle)
{
struct efi_object *efiobj;
@@ -863,7 +865,8 @@ static efi_status_t efi_delete_open_info(
* @protocol_interface interface of the protocol implementation
* @return status code
*/
-efi_status_t efi_add_protocol(const void *handle, const efi_guid_t *protocol,
+efi_status_t efi_add_protocol(const efi_handle_t handle,
+ const efi_guid_t *protocol,
void *protocol_interface)
{
struct efi_object *efiobj;
@@ -949,9 +952,9 @@ out:
* @new_interface interface to be installed
* @return status code
*/
-static efi_status_t EFIAPI efi_reinstall_protocol_interface(void *handle,
- const efi_guid_t *protocol, void *old_interface,
- void *new_interface)
+static efi_status_t EFIAPI efi_reinstall_protocol_interface(
+ efi_handle_t handle, const efi_guid_t *protocol,
+ void *old_interface, void *new_interface)
{
EFI_ENTRY("%p, %pUl, %p, %p", handle, protocol, old_interface,
new_interface);
@@ -1074,7 +1077,7 @@ static efi_status_t efi_disconnect_all_drivers(
* @return status code
*/
static efi_status_t EFIAPI efi_uninstall_protocol_interface(
- void *handle, const efi_guid_t *protocol,
+ efi_handle_t handle, const efi_guid_t *protocol,
void *protocol_interface)
{
struct efi_object *efiobj;
@@ -1531,7 +1534,7 @@ static efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle,
unsigned long *exit_data_size,
s16 **exit_data)
{
- ulong (*entry)(void *image_handle, struct efi_system_table *st);
+ ulong (*entry)(efi_handle_t image_handle, struct efi_system_table *st);
struct efi_loaded_image *info = image_handle;
EFI_ENTRY("%p, %p, %p", image_handle, exit_data_size, exit_data);
@@ -1613,7 +1616,7 @@ static efi_status_t EFIAPI efi_exit(efi_handle_t image_handle,
* @image_handle handle of the image to be unloaded
* @return status code
*/
-static efi_status_t EFIAPI efi_unload_image(void *image_handle)
+static efi_status_t EFIAPI efi_unload_image(efi_handle_t image_handle)
{
struct efi_object *efiobj;
@@ -1651,7 +1654,7 @@ static void efi_exit_caches(void)
* @map_key key of the memory map
* @return status code
*/
-static efi_status_t EFIAPI efi_exit_boot_services(void *image_handle,
+static efi_status_t EFIAPI efi_exit_boot_services(efi_handle_t image_handle,
unsigned long map_key)
{
int i;
@@ -1755,10 +1758,10 @@ static efi_status_t EFIAPI efi_set_watchdog_timer(unsigned long timeout,
* @controller_handle handle of the controller
* @return status code
*/
-static efi_status_t EFIAPI efi_close_protocol(void *handle,
+static efi_status_t EFIAPI efi_close_protocol(efi_handle_t handle,
const efi_guid_t *protocol,
- void *agent_handle,
- void *controller_handle)
+ efi_handle_t agent_handle,
+ efi_handle_t controller_handle)
{
struct efi_handler *handler;
struct efi_open_protocol_info_item *item;
@@ -1863,8 +1866,8 @@ out:
* @protocol_buffer_count number of entries in the buffer
* @return status code
*/
-static efi_status_t EFIAPI efi_protocols_per_handle(void *handle,
- efi_guid_t ***protocol_buffer,
+static efi_status_t EFIAPI efi_protocols_per_handle(
+ efi_handle_t handle, efi_guid_t ***protocol_buffer,
efi_uintn_t *protocol_buffer_count)
{
unsigned long buffer_size;
@@ -1954,7 +1957,7 @@ static efi_status_t EFIAPI efi_locate_handle_buffer(
r = efi_locate_handle(search_type, protocol, search_key, &buffer_size,
*buffer);
if (r == EFI_SUCCESS)
- *no_handles = buffer_size / sizeof(void *);
+ *no_handles = buffer_size / sizeof(efi_handle_t);
out:
return EFI_EXIT(r);
}
@@ -2422,7 +2425,7 @@ out:
* @protocol_interface interface implementing the protocol
* @return status code
*/
-static efi_status_t EFIAPI efi_handle_protocol(void *handle,
+static efi_status_t EFIAPI efi_handle_protocol(efi_handle_t handle,
const efi_guid_t *protocol,
void **protocol_interface)
{
diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c
index 98497db612..56b079cee8 100644
--- a/lib/efi_loader/efi_console.c
+++ b/lib/efi_loader/efi_console.c
@@ -503,21 +503,21 @@ int efi_console_register(void)
struct efi_object *efi_console_input_obj;
/* Create handles */
- r = efi_create_handle((void **)&efi_console_control_obj);
+ r = efi_create_handle((efi_handle_t *)&efi_console_control_obj);
if (r != EFI_SUCCESS)
goto out_of_memory;
r = efi_add_protocol(efi_console_control_obj->handle,
&efi_guid_console_control, &efi_console_control);
if (r != EFI_SUCCESS)
goto out_of_memory;
- r = efi_create_handle((void **)&efi_console_output_obj);
+ r = efi_create_handle((efi_handle_t *)&efi_console_output_obj);
if (r != EFI_SUCCESS)
goto out_of_memory;
r = efi_add_protocol(efi_console_output_obj->handle,
&efi_guid_text_output_protocol, &efi_con_out);
if (r != EFI_SUCCESS)
goto out_of_memory;
- r = efi_create_handle((void **)&efi_console_input_obj);
+ r = efi_create_handle((efi_handle_t *)&efi_console_input_obj);
if (r != EFI_SUCCESS)
goto out_of_memory;
r = efi_add_protocol(efi_console_input_obj->handle,
--
2.14.2
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [U-Boot] [PATCH v3 16/16] efi_loader: consistently use efi_handle_t for handles
2018-01-11 7:16 ` [U-Boot] [PATCH v3 16/16] efi_loader: consistently use efi_handle_t for handles Heinrich Schuchardt
@ 2018-01-16 14:56 ` Simon Glass
0 siblings, 0 replies; 22+ messages in thread
From: Simon Glass @ 2018-01-16 14:56 UTC (permalink / raw)
To: u-boot
On 10 January 2018 at 23:16, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote:
> We should consistently use the efi_handle_t typedef when
> referring to handles.
>
> Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
> ---
> v3
> no change
> v2
> no change
> ---
> cmd/bootefi.c | 10 ++++-----
> include/efi_api.h | 20 ++++++++++--------
> include/efi_loader.h | 14 +++++++------
> lib/efi_loader/efi_boottime.c | 49 +++++++++++++++++++++++--------------------
> lib/efi_loader/efi_console.c | 6 +++---
> 5 files changed, 53 insertions(+), 46 deletions(-)
Reviewed-by: Simon Glass <sjg@chromium.org>
^ permalink raw reply [flat|nested] 22+ messages in thread