diff mbox

[U-Boot,v3,3/3] efi_loader: implement OpenProtocolInformation

Message ID 20170805203230.19796-4-xypron.glpk@gmx.de
State Superseded
Delegated to: Alexander Graf
Headers show

Commit Message

Heinrich Schuchardt Aug. 5, 2017, 8:32 p.m. UTC
efi_open_protocol_information provides the agent and controller
handles as well as the attributes and open count of an protocol
on a handle.

Cc: Rob Clark <robdclark@gmail.com>
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
---
v3:
	use list_for_each_entry
	correct indention
v2:
	new patch
---
 lib/efi_loader/efi_boottime.c | 74 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 73 insertions(+), 1 deletion(-)

Comments

Alexander Graf Aug. 12, 2017, 1:38 p.m. UTC | #1
On 05.08.17 22:32, 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.
> 
> Cc: Rob Clark <robdclark@gmail.com>
> Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>

Do you have an application that leverages these interfaces? Would it be 
possible to add that application to our travis tests?


Alex
Heinrich Schuchardt Aug. 13, 2017, 11:17 a.m. UTC | #2
On 08/12/2017 03:38 PM, Alexander Graf wrote:
> 
> 
> On 05.08.17 22:32, 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.
>>
>> Cc: Rob Clark <robdclark@gmail.com>
>> Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
> 
> Do you have an application that leverages these interfaces? Would it be
> possible to add that application to our travis tests?
> 
> 
> Alex
> 

iPXE (snp.efi) uses the functions but there are other things missing to
make it really working.

Putting new tests into the executable created by
CMD_BOOTEFI_HELLO_COMPILE would be possible but that seems messy to me.

Should we replace CMD_BOOTEFI_HELLO_COMPILE by an option that creates
multiple executables for the different EFI API functions we have to test?

Each test then should consist of:
- start QEMU system
- download dtb and test executable from tftp server
- start the test executable
- evaluate console output
- shutdown QEMU system

Regards

Heinrich
Alexander Graf Aug. 13, 2017, 7:24 p.m. UTC | #3
On 13.08.17 13:17, Heinrich Schuchardt wrote:
> On 08/12/2017 03:38 PM, Alexander Graf wrote:
>>
>>
>> On 05.08.17 22:32, 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.
>>>
>>> Cc: Rob Clark <robdclark@gmail.com>
>>> Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
>>
>> Do you have an application that leverages these interfaces? Would it be
>> possible to add that application to our travis tests?
>>
>>
>> Alex
>>
> 
> iPXE (snp.efi) uses the functions but there are other things missing to
> make it really working.

Ah, I see. How much is missing to make that one work for real?

> Putting new tests into the executable created by
> CMD_BOOTEFI_HELLO_COMPILE would be possible but that seems messy to me.
> 
> Should we replace CMD_BOOTEFI_HELLO_COMPILE by an option that creates
> multiple executables for the different EFI API functions we have to test?
> 
> Each test then should consist of:
> - start QEMU system
> - download dtb and test executable from tftp server
> - start the test executable
> - evaluate console output
> - shutdown QEMU system

We have most of the above already in travis today. All we would need is 
to extend it to download a built iPXE binaries and add test snippets to 
tests/py for iPXE functionality.


Alex
Heinrich Schuchardt Aug. 13, 2017, 7:32 p.m. UTC | #4
On 08/13/2017 09:24 PM, Alexander Graf wrote:
> 
> 
> On 13.08.17 13:17, Heinrich Schuchardt wrote:
>> On 08/12/2017 03:38 PM, Alexander Graf wrote:
>>>
>>>
>>> On 05.08.17 22:32, 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.
>>>>
>>>> Cc: Rob Clark <robdclark@gmail.com>
>>>> Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
>>>
>>> Do you have an application that leverages these interfaces? Would it be
>>> possible to add that application to our travis tests?
>>>
>>>
>>> Alex
>>>
>>
>> iPXE (snp.efi) uses the functions but there are other things missing to
>> make it really working.
> 
> Ah, I see. How much is missing to make that one work for real?

Before reaching the input prompt ConnectController and
DisconnectController fail for the Simple Network Protocol.

So I am not able to say if the network connection will work.

For testing we will need an iSCSI target.

> 
>> Putting new tests into the executable created by
>> CMD_BOOTEFI_HELLO_COMPILE would be possible but that seems messy to me.
>>
>> Should we replace CMD_BOOTEFI_HELLO_COMPILE by an option that creates
>> multiple executables for the different EFI API functions we have to test?
>>
>> Each test then should consist of:
>> - start QEMU system
>> - download dtb and test executable from tftp server
>> - start the test executable
>> - evaluate console output
>> - shutdown QEMU system
> 
> We have most of the above already in travis today. All we would need is
> to extend it to download a built iPXE binaries and add test snippets to
> tests/py for iPXE functionality.

Proving that some binary runs is not enough to test the different corner
cases of this complex API.

I would prefer to have a bunch of test binaries compiled from the U-Boot
git tree.

Best regards

Heinrich
Alexander Graf Aug. 13, 2017, 8:37 p.m. UTC | #5
On 13.08.17 21:32, Heinrich Schuchardt wrote:
> On 08/13/2017 09:24 PM, Alexander Graf wrote:
>>
>>
>> On 13.08.17 13:17, Heinrich Schuchardt wrote:
>>> On 08/12/2017 03:38 PM, Alexander Graf wrote:
>>>>
>>>>
>>>> On 05.08.17 22:32, 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.
>>>>>
>>>>> Cc: Rob Clark <robdclark@gmail.com>
>>>>> Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
>>>>
>>>> Do you have an application that leverages these interfaces? Would it be
>>>> possible to add that application to our travis tests?
>>>>
>>>>
>>>> Alex
>>>>
>>>
>>> iPXE (snp.efi) uses the functions but there are other things missing to
>>> make it really working.
>>
>> Ah, I see. How much is missing to make that one work for real?
> 
> Before reaching the input prompt ConnectController and
> DisconnectController fail for the Simple Network Protocol.
> 
> So I am not able to say if the network connection will work.
> 
> For testing we will need an iSCSI target.
> 
>>
>>> Putting new tests into the executable created by
>>> CMD_BOOTEFI_HELLO_COMPILE would be possible but that seems messy to me.
>>>
>>> Should we replace CMD_BOOTEFI_HELLO_COMPILE by an option that creates
>>> multiple executables for the different EFI API functions we have to test?
>>>
>>> Each test then should consist of:
>>> - start QEMU system
>>> - download dtb and test executable from tftp server
>>> - start the test executable
>>> - evaluate console output
>>> - shutdown QEMU system
>>
>> We have most of the above already in travis today. All we would need is
>> to extend it to download a built iPXE binaries and add test snippets to
>> tests/py for iPXE functionality.
> 
> Proving that some binary runs is not enough to test the different corner
> cases of this complex API.
> 
> I would prefer to have a bunch of test binaries compiled from the U-Boot
> git tree.

Sure, even better in my book ;). Ideally we would have both. Unit tests 
to check individual interfaces and integration tests to make sure we 
don't regress real world use cases.


Alex
diff mbox

Patch

diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index 65a7a79dc1..fa9b74d465 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -984,14 +984,86 @@  out:
 	return EFI_EXIT(r);
 }
 
+static efi_status_t efi_copy_open_protocol_information(
+			struct efi_handler *protocol,
+			struct efi_open_protocol_info_entry **entry_buffer,
+			unsigned long *entry_count)
+{
+	unsigned long buffer_size;
+	unsigned long count = 0;
+	size_t i;
+	efi_status_t r;
+
+	*entry_buffer = NULL;
+
+	/* Count entries */
+	for (i = 0; i < ARRAY_SIZE(protocol->open_info); ++i) {
+		struct efi_open_protocol_info_entry *open_info =
+			&protocol->open_info[i];
+
+		if (open_info->open_count)
+			++count;
+	}
+	*entry_count = count;
+	if (!count)
+		return EFI_SUCCESS;
+
+	/* 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)
+		return r;
+	count = 0;
+	for (i = 0; i < ARRAY_SIZE(protocol->open_info); ++i) {
+		struct efi_open_protocol_info_entry *open_info =
+			&protocol->open_info[i];
+
+		if (!open_info->open_count)
+			continue;
+		(*entry_buffer)[count] = *open_info;
+		++count;
+	}
+
+	return EFI_SUCCESS;
+}
+
 static efi_status_t EFIAPI efi_open_protocol_information(efi_handle_t handle,
 			efi_guid_t *protocol,
 			struct efi_open_protocol_info_entry **entry_buffer,
 			unsigned long *entry_count)
 {
+	struct efi_object *efiobj;
+	size_t i;
+	efi_status_t r = EFI_NOT_FOUND;
+
 	EFI_ENTRY("%p, %p, %p, %p", handle, protocol, entry_buffer,
 		  entry_count);
-	return EFI_EXIT(EFI_NOT_FOUND);
+
+	if (!handle || !protocol || !entry_buffer)
+		EFI_EXIT(EFI_INVALID_PARAMETER);
+
+	EFI_PRINT_GUID("protocol:", protocol);
+
+	list_for_each_entry(efiobj, &efi_obj_list, link) {
+		if (efiobj->handle != handle)
+			continue;
+
+		for (i = 0; i < ARRAY_SIZE(efiobj->protocols); i++) {
+			struct efi_handler *handler = &efiobj->protocols[i];
+			const efi_guid_t *hprotocol = handler->guid;
+			if (!hprotocol)
+				continue;
+			if (!guidcmp(hprotocol, protocol)) {
+				r = efi_copy_open_protocol_information(
+					handler, entry_buffer, entry_count);
+				goto out;
+			}
+		}
+		goto out;
+	}
+out:
+	return EFI_EXIT(r);
 }
 
 static efi_status_t EFIAPI efi_protocols_per_handle(void *handle,