All of lore.kernel.org
 help / color / mirror / Atom feed
From: Heinrich Schuchardt <xypron.glpk@gmx.de>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v2 2/9] efi_selftest: test protocol management
Date: Mon,  6 Nov 2017 21:17:43 +0100	[thread overview]
Message-ID: <20171106201750.18898-3-xypron.glpk@gmx.de> (raw)
In-Reply-To: <20171106201750.18898-1-xypron.glpk@gmx.de>

This unit test checks the following protocol services:
InstallProtocolInterface, UninstallProtocolInterface,
InstallMultipleProtocolsInterfaces,
UninstallMultipleProtocolsInterfaces,
HandleProtocol, ProtocolsPerHandle,
LocateHandle, LocateHandleBuffer.

As UninstallProtocolInterface and UninstallMultipleProtocolsInterfaces
are not completely implemented a TODO message will shown for
their failure.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
---
v2
	remove superfluous definitions
---
 include/efi_selftest.h                          |   9 +
 lib/efi_selftest/Makefile                       |   3 +
 lib/efi_selftest/efi_selftest_manageprotocols.c | 354 ++++++++++++++++++++++++
 3 files changed, 366 insertions(+)
 create mode 100644 lib/efi_selftest/efi_selftest_manageprotocols.c

diff --git a/include/efi_selftest.h b/include/efi_selftest.h
index 5cc8d4f600..be5ba4bfa9 100644
--- a/include/efi_selftest.h
+++ b/include/efi_selftest.h
@@ -28,6 +28,15 @@
 	efi_st_printf(__VA_ARGS__)) \
 
 /*
+ * Prints a TODO message.
+ *
+ * @...	format string followed by fields to print
+ */
+#define efi_st_todo(...) \
+	(efi_st_printf("%s(%u):\nTODO: ", __FILE__, __LINE__), \
+	efi_st_printf(__VA_ARGS__)) \
+
+/*
  * A test may be setup and executed at boottime,
  * it may be setup at boottime and executed at runtime,
  * or it may be setup and executed at runtime.
diff --git a/lib/efi_selftest/Makefile b/lib/efi_selftest/Makefile
index 88b998bd4c..acd184db4b 100644
--- a/lib/efi_selftest/Makefile
+++ b/lib/efi_selftest/Makefile
@@ -15,6 +15,8 @@ CFLAGS_efi_selftest_events.o := $(CFLAGS_EFI)
 CFLAGS_REMOVE_efi_selftest_events.o := $(CFLAGS_NON_EFI)
 CFLAGS_efi_selftest_exitbootservices.o := $(CFLAGS_EFI)
 CFLAGS_REMOVE_efi_selftest_exitbootservices.o := $(CFLAGS_NON_EFI)
+CFLAGS_efi_selftest_manageprotocols.o := $(CFLAGS_EFI)
+CFLAGS_REMOVE_efi_selftest_manageprotocols.o := $(CFLAGS_NON_EFI)
 CFLAGS_efi_selftest_snp.o := $(CFLAGS_EFI)
 CFLAGS_REMOVE_efi_selftest_snp.o := $(CFLAGS_NON_EFI)
 CFLAGS_efi_selftest_textoutput.o := $(CFLAGS_EFI)
@@ -31,6 +33,7 @@ efi_selftest.o \
 efi_selftest_console.o \
 efi_selftest_events.o \
 efi_selftest_exitbootservices.o \
+efi_selftest_manageprotocols.o \
 efi_selftest_snp.o \
 efi_selftest_textoutput.o \
 efi_selftest_tpl.o \
diff --git a/lib/efi_selftest/efi_selftest_manageprotocols.c b/lib/efi_selftest/efi_selftest_manageprotocols.c
new file mode 100644
index 0000000000..d64d03d396
--- /dev/null
+++ b/lib/efi_selftest/efi_selftest_manageprotocols.c
@@ -0,0 +1,354 @@
+/*
+ * efi_selftest_manageprotocols
+ *
+ * Copyright (c) 2017 Heinrich Schuchardt <xypron.glpk@gmx.de>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ *
+ * This unit test checks the following protocol services:
+ * InstallProtocolInterface, UninstallProtocolInterface,
+ * InstallMultipleProtocolsInterfaces, UninstallMultipleProtocolsInterfaces,
+ * HandleProtocol, ProtocolsPerHandle,
+ * LocateHandle, LocateHandleBuffer.
+ */
+
+#include <efi_selftest.h>
+
+/*
+ * The test currently does not actually call the interface function.
+ * So this is just a dummy structure.
+ */
+struct interface {
+	void (EFIAPI * inc)(void);
+};
+
+static struct efi_boot_services *boottime;
+static efi_guid_t guid1 =
+	EFI_GUID(0x2e7ca819, 0x21d3, 0x0a3a,
+		 0xf7, 0x91, 0x82, 0x1f, 0x7a, 0x83, 0x67, 0xaf);
+static efi_guid_t guid2 =
+	EFI_GUID(0xf909f2bb, 0x90a8, 0x0d77,
+		 0x94, 0x0c, 0x3e, 0xa8, 0xea, 0x38, 0xd6, 0x6f);
+static efi_guid_t guid3 =
+	EFI_GUID(0x06d641a3, 0xf4e7, 0xe0c9,
+		 0xe7, 0x8d, 0x41, 0x2d, 0x72, 0xa6, 0xb1, 0x24);
+static efi_handle_t handle1;
+static efi_handle_t handle2;
+static struct interface interface1;
+static struct interface interface2;
+static struct interface interface3;
+static struct interface interface4;
+
+/*
+ * Find a handle in an array.
+ *
+ * @handle:	handle to find
+ * @count:	number of entries in the array
+ * @buffer:	array to search
+ */
+efi_status_t find_in_buffer(efi_handle_t handle, size_t count,
+			    efi_handle_t *buffer)
+{
+	size_t i;
+
+	for (i = 0; i < count; ++i) {
+		if (buffer[i] == handle)
+			return EFI_SUCCESS;
+	}
+	return EFI_NOT_FOUND;
+}
+
+/*
+ * Setup unit test.
+ *
+ * Create two handles and install two out of three protocol interfaces on each
+ * of them:
+ *
+ * handle1
+ *   guid1 interface1
+ *   guid3 interface3
+ * handle2
+ *   guid1 interface4
+ *   guid2 interface2
+ *
+ * @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;
+	efi_handle_t handle;
+
+	boottime = systable->boottime;
+
+	ret = boottime->install_protocol_interface(&handle1, &guid3,
+						   EFI_NATIVE_INTERFACE,
+						   &interface3);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("InstallProtocolInterface failed\n");
+		return EFI_ST_FAILURE;
+	}
+	if (!handle1) {
+		efi_st_error("InstallProtocolInterface failed to create handle\n");
+		return EFI_ST_FAILURE;
+	}
+	handle = handle1;
+	ret = boottime->install_protocol_interface(&handle1, &guid1,
+						   EFI_NATIVE_INTERFACE,
+						   &interface1);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("InstallProtocolInterface failed\n");
+		return EFI_ST_FAILURE;
+	}
+	if (handle != handle1) {
+		efi_st_error("InstallProtocolInterface failed to use handle\n");
+		return EFI_ST_FAILURE;
+	}
+	ret = boottime->install_multiple_protocol_interfaces(&handle2,
+			&guid1, &interface4, &guid2, &interface2, NULL);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("InstallMultipleProtocolInterfaces failed\n");
+		return EFI_ST_FAILURE;
+	}
+	if (!handle2 || handle1 == handle2) {
+		efi_st_error("InstallMultipleProtocolInterfaces failed to create handle\n");
+		return EFI_ST_FAILURE;
+	}
+
+	return EFI_ST_SUCCESS;
+}
+
+/*
+ * Tear down unit test.
+ *
+ */
+static int teardown(void)
+{
+	return EFI_ST_SUCCESS;
+}
+
+/*
+ * Execute unit test.
+ *
+ */
+static int execute(void)
+{
+	struct interface *interface;
+	efi_status_t ret;
+	efi_handle_t *buffer;
+	size_t buffer_size;
+	unsigned long int count = 0;
+	efi_guid_t **prot_buffer;
+	unsigned long int prot_count;
+
+	/*
+	 * Test HandleProtocol
+	 */
+	ret = boottime->handle_protocol(handle1, &guid3, (void **)&interface);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("HandleProtocol failed to retrieve interface\n");
+		return EFI_ST_FAILURE;
+	}
+	if (interface != &interface3) {
+		efi_st_error("HandleProtocol returned wrong interface\n");
+		return EFI_ST_FAILURE;
+	}
+	ret = boottime->handle_protocol(handle1, &guid2, (void **)&interface);
+	if (ret == EFI_SUCCESS) {
+		efi_st_error("HandleProtocol returned not installed interface\n");
+		return EFI_ST_FAILURE;
+	}
+
+	/*
+	 * Test LocateHandleBuffer with AllHandles
+	 */
+	ret = boottime->locate_handle_buffer(ALL_HANDLES, NULL, NULL,
+					     &count, &buffer);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("LocateHandleBuffer with AllHandles failed\n");
+		return EFI_ST_FAILURE;
+	}
+	buffer_size = count;
+	ret = find_in_buffer(handle1, count, buffer);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("LocateHandleBuffer failed to locate new handle\n");
+		return EFI_ST_FAILURE;
+	}
+	ret = find_in_buffer(handle2, count, buffer);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("LocateHandleBuffer failed to locate new handle\n");
+		return EFI_ST_FAILURE;
+	}
+	boottime->set_mem(buffer, sizeof(efi_handle_t) * buffer_size, 0);
+
+	/*
+	 * Test error handling in UninstallMultipleProtocols
+	 *
+	 * Try to uninstall more protocols than there are installed.
+	 */
+	ret = boottime->uninstall_multiple_protocol_interfaces(
+						handle2,
+						&guid1, &interface4,
+						&guid2, &interface2,
+						&guid3, &interface3,
+						NULL);
+	if (ret == EFI_SUCCESS) {
+		efi_st_todo("UninstallMultipleProtocolInterfaces did not catch error\n");
+		return EFI_ST_FAILURE;
+	}
+
+	/*
+	 * Test LocateHandleBuffer with ByProtocol
+	 */
+	count = buffer_size;
+	ret = boottime->locate_handle_buffer(BY_PROTOCOL, &guid1, NULL,
+					     &count, &buffer);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("LocateHandleBuffer failed to locate new handles\n");
+		return EFI_ST_FAILURE;
+	}
+	if (count != 2) {
+		efi_st_error("LocateHandleBuffer failed to locate new handles\n");
+		return EFI_ST_FAILURE;
+	}
+	ret = find_in_buffer(handle1, count, buffer);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("LocateHandleBuffer failed to locate new handle\n");
+		return EFI_ST_FAILURE;
+	}
+	ret = find_in_buffer(handle2, count, buffer);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("LocateHandleBuffer failed to locate new handle\n");
+		return EFI_ST_FAILURE;
+	}
+	boottime->set_mem(buffer, sizeof(efi_handle_t) * buffer_size, 0);
+
+	/*
+	 * Test LocateHandle with ByProtocol
+	 */
+	count = buffer_size * sizeof(efi_handle_t);
+	ret = boottime->locate_handle(BY_PROTOCOL, &guid1, NULL,
+				      &count, buffer);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("LocateHandle with ByProtocol failed\n");
+		return EFI_ST_FAILURE;
+	}
+	if (count / sizeof(efi_handle_t) != 2) {
+		efi_st_error("LocateHandle failed to locate new handles\n");
+		return EFI_ST_FAILURE;
+	}
+	buffer_size = count;
+	ret = find_in_buffer(handle1, count, buffer);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("LocateHandle failed to locate new handles\n");
+		return EFI_ST_FAILURE;
+	}
+	ret = find_in_buffer(handle2, count, buffer);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("LocateHandle failed to locate new handles\n");
+		return EFI_ST_FAILURE;
+	}
+	boottime->set_mem(buffer, sizeof(efi_handle_t) * buffer_size, 0);
+
+	/*
+	 * Test LocateProtocol
+	 */
+	ret = boottime->locate_protocol(&guid1, NULL, (void **)&interface);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("LocateProtocol failed\n");
+		return EFI_ST_FAILURE;
+	}
+	if (interface != &interface1 && interface != &interface4) {
+		efi_st_error("LocateProtocol failed to locate protocol\n");
+		return EFI_ST_FAILURE;
+	}
+
+	/*
+	 * Test UninstallMultipleProtocols
+	 */
+	ret = boottime->uninstall_multiple_protocol_interfaces(
+						handle2,
+						&guid1, &interface4,
+						&guid2, &interface2,
+						NULL);
+	if (ret != EFI_SUCCESS) {
+		efi_st_todo("UninstallMultipleProtocolInterfaces failed\n");
+		/* This test is known to fail due to missing implementation */
+	}
+	/*
+	 * Check that the protocols are really uninstalled.
+	 */
+	count = buffer_size;
+	ret = boottime->locate_handle_buffer(BY_PROTOCOL, &guid1, NULL,
+					     &count, &buffer);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("LocateHandleBuffer failed\n");
+		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 */
+	}
+	ret = find_in_buffer(handle1, count, buffer);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("Failed to locate new handle\n");
+		return EFI_ST_FAILURE;
+	}
+	boottime->set_mem(buffer, sizeof(efi_handle_t) * buffer_size, 0);
+
+	/*
+	 * Test ProtocolsPerHandle
+	 */
+	ret = boottime->protocols_per_handle(handle1,
+					     &prot_buffer, &prot_count);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("Failed to get protocols per handle\n");
+		return EFI_ST_FAILURE;
+	}
+	if (prot_count != 2) {
+		efi_st_error("Failed to get protocols per handle\n");
+		return EFI_ST_FAILURE;
+	}
+	if (efi_st_memcmp(prot_buffer[0], &guid1, 16) &&
+	    efi_st_memcmp(prot_buffer[1], &guid1, 16)) {
+		efi_st_error("Failed to get protocols per handle\n");
+		return EFI_ST_FAILURE;
+	}
+	if (efi_st_memcmp(prot_buffer[0], &guid3, 16) &&
+	    efi_st_memcmp(prot_buffer[1], &guid3, 16)) {
+		efi_st_error("Failed to get protocols per handle\n");
+		return EFI_ST_FAILURE;
+	}
+
+	/*
+	 * Uninstall remaining protocols
+	 */
+	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 */
+	}
+	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 */
+	}
+	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 */
+	}
+
+	return EFI_ST_SUCCESS;
+}
+
+EFI_UNIT_TEST(protserv) = {
+	.name = "manage protocols",
+	.phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
+	.setup = setup,
+	.execute = execute,
+	.teardown = teardown,
+};
-- 
2.11.0

  parent reply	other threads:[~2017-11-06 20:17 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-11-06 20:17 [U-Boot] [PATCH v2 0/9] efi_loader: clean up protocol services Heinrich Schuchardt
2017-11-06 20:17 ` [U-Boot] [PATCH v2 1/9] efi_loader: capitalize EFI_LOCATE_SEARCH_TYPE values Heinrich Schuchardt
2017-11-06 20:17 ` Heinrich Schuchardt [this message]
2017-11-17 14:07   ` [U-Boot] [PATCH v2 2/9] efi_selftest: test protocol management Simon Glass
2017-11-06 20:17 ` [U-Boot] [PATCH v2 3/9] efi_loader: eliminate efi_install_protocol_interface_ext Heinrich Schuchardt
2017-11-06 20:17 ` [U-Boot] [PATCH v2 4/9] efi_loader: eliminate efi_uninstall_protocol_interface_ext Heinrich Schuchardt
2017-11-06 20:17 ` [U-Boot] [PATCH v2 5/9] efi_loader: remove unused typedef for INTN Heinrich Schuchardt
2017-11-06 20:17 ` [U-Boot] [PATCH v2 6/9] efi_loader: replace UINTN by efi_uintn_t Heinrich Schuchardt
2017-11-06 20:17 ` [U-Boot] [PATCH v2 7/9] efi_loader: consistently use efi_uintn_t in boot services Heinrich Schuchardt
2017-11-17 14:07   ` Simon Glass
2017-11-06 20:17 ` [U-Boot] [PATCH v2 8/9] efi_loader: rework efi_locate_handle Heinrich Schuchardt
2017-11-06 20:17 ` [U-Boot] [PATCH v2 9/9] efi_loader: rework efi_search_obj Heinrich Schuchardt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20171106201750.18898-3-xypron.glpk@gmx.de \
    --to=xypron.glpk@gmx.de \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.