mirror of
https://github.com/brain-hackers/u-boot-brain
synced 2024-08-24 02:48:51 +09:00
![Tom Rini](/assets/img/avatar_default.png)
When U-Boot started using SPDX tags we were among the early adopters and there weren't a lot of other examples to borrow from. So we picked the area of the file that usually had a full license text and replaced it with an appropriate SPDX-License-Identifier: entry. Since then, the Linux Kernel has adopted SPDX tags and they place it as the very first line in a file (except where shebangs are used, then it's second line) and with slightly different comment styles than us. In part due to community overlap, in part due to better tag visibility and in part for other minor reasons, switch over to that style. This commit changes all instances where we have a single declared license in the tag as both the before and after are identical in tag contents. There's also a few places where I found we did not have a tag and have introduced one. Signed-off-by: Tom Rini <trini@konsulko.com>
354 lines
9.4 KiB
C
354 lines
9.4 KiB
C
// SPDX-License-Identifier: GPL-2.0+
|
|
/*
|
|
* efi_selftest_manageprotocols
|
|
*
|
|
* Copyright (c) 2017 Heinrich Schuchardt <xypron.glpk@gmx.de>
|
|
*
|
|
* 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;
|
|
efi_uintn_t count = 0;
|
|
efi_guid_t **prot_buffer;
|
|
efi_uintn_t 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_error("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_error("UninstallMultipleProtocolInterfaces failed\n");
|
|
return EFI_ST_FAILURE;
|
|
}
|
|
/*
|
|
* 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_error("UninstallMultipleProtocolInterfaces failed to uninstall protocols\n");
|
|
return EFI_ST_FAILURE;
|
|
}
|
|
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_error("UninstallProtocolInterface failed\n");
|
|
return EFI_ST_FAILURE;
|
|
}
|
|
ret = boottime->handle_protocol(handle1, &guid1, (void **)&interface);
|
|
if (ret == EFI_SUCCESS) {
|
|
efi_st_error("UninstallProtocolInterface failed\n");
|
|
return EFI_ST_FAILURE;
|
|
}
|
|
ret = boottime->uninstall_protocol_interface(handle1, &guid3,
|
|
&interface1);
|
|
if (ret != EFI_SUCCESS) {
|
|
efi_st_error("UninstallProtocolInterface failed\n");
|
|
return EFI_ST_FAILURE;
|
|
}
|
|
|
|
return EFI_ST_SUCCESS;
|
|
}
|
|
|
|
EFI_UNIT_TEST(protserv) = {
|
|
.name = "manage protocols",
|
|
.phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
|
|
.setup = setup,
|
|
.execute = execute,
|
|
.teardown = teardown,
|
|
};
|