1 // SPDX-License-Identifier: GPL-2.0+
3 * efi_selftest_open_protocol
5 * Copyright (c) 2019 Heinrich Schuchardt <xypron.glpk@gmx.de>
7 * This unit test checks that open protocol information is correctly updated
9 * HandleProtocol, OpenProtocol, OpenProtocolInformation, CloseProtocol.
12 #include <efi_selftest.h>
15 * The test currently does not actually call the interface function.
16 * So this is just a dummy structure.
19 void (EFIAPI *inc)(void);
22 static struct efi_boot_services *boottime;
23 static efi_guid_t guid1 =
24 EFI_GUID(0x492a0e38, 0x1442, 0xf819,
25 0x14, 0xaa, 0x4b, 0x8d, 0x09, 0xfe, 0x5a, 0xb9);
26 static efi_handle_t handle1;
27 static struct interface interface1;
32 * Create a handle and install a protocol interface on it.
34 * @handle: handle of the loaded image
35 * @systable: system table
37 static int setup(const efi_handle_t img_handle,
38 const struct efi_system_table *systable)
42 boottime = systable->boottime;
44 ret = boottime->install_protocol_interface(&handle1, &guid1,
47 if (ret != EFI_SUCCESS) {
48 efi_st_error("InstallProtocolInterface failed\n");
49 return EFI_ST_FAILURE;
53 ("InstallProtocolInterface failed to create handle\n");
54 return EFI_ST_FAILURE;
56 return EFI_ST_SUCCESS;
60 * Tear down unit test.
63 static int teardown(void)
68 ret = boottime->uninstall_protocol_interface(handle1, &guid1,
70 if (ret != EFI_SUCCESS) {
71 efi_st_error("UninstallProtocolInterface failed\n");
72 return EFI_ST_FAILURE;
75 return EFI_ST_SUCCESS;
81 * Open the installed protocol twice via HandleProtocol() and once via
82 * OpenProtocol(EFI_OPEN_PROTOCOL_GET_PROTOCOL). Read the open protocol
83 * information and check the open counts. Finally close the protocol and
86 static int execute(void)
89 struct efi_open_protocol_info_entry *entry_buffer;
90 efi_uintn_t entry_count;
91 efi_handle_t firmware_handle;
94 ret = boottime->handle_protocol(handle1, &guid1, &interface);
95 if (ret != EFI_SUCCESS) {
96 efi_st_error("HandleProtocol failed\n");
97 return EFI_ST_FAILURE;
99 if (interface != &interface1) {
100 efi_st_error("HandleProtocol returned wrong interface\n");
101 return EFI_ST_FAILURE;
103 ret = boottime->open_protocol_information(handle1, &guid1,
104 &entry_buffer, &entry_count);
105 if (ret != EFI_SUCCESS) {
106 efi_st_error("OpenProtocolInformation failed\n");
107 return EFI_ST_FAILURE;
109 if (entry_count != 1) {
110 efi_st_error("Incorrect OpenProtocolInformation count\n");
111 efi_st_printf("Expected 1, got %u\n",
112 (unsigned int)entry_count);
113 return EFI_ST_FAILURE;
115 ret = boottime->free_pool(entry_buffer);
116 if (ret != EFI_SUCCESS) {
117 efi_st_error("FreePool failed\n");
118 return EFI_ST_FAILURE;
120 ret = boottime->handle_protocol(handle1, &guid1, &interface);
121 if (ret != EFI_SUCCESS) {
122 efi_st_error("HandleProtocol failed\n");
123 return EFI_ST_FAILURE;
125 ret = boottime->open_protocol_information(handle1, &guid1,
126 &entry_buffer, &entry_count);
127 if (ret != EFI_SUCCESS) {
128 efi_st_error("OpenProtocolInformation failed\n");
129 return EFI_ST_FAILURE;
131 if (entry_count != 1) {
132 efi_st_error("Incorrect OpenProtocolInformation count\n");
133 efi_st_printf("Expected 1, got %u\n",
134 (unsigned int)entry_count);
135 return EFI_ST_FAILURE;
137 if (entry_buffer[0].open_count != 2) {
138 efi_st_error("Incorrect open count: expected 2 got %u\n",
139 entry_buffer[0].open_count);
140 return EFI_ST_FAILURE;
142 firmware_handle = entry_buffer[0].agent_handle;
143 ret = boottime->free_pool(entry_buffer);
144 if (ret != EFI_SUCCESS) {
145 efi_st_error("FreePool failed\n");
146 return EFI_ST_FAILURE;
148 ret = boottime->open_protocol(handle1, &guid1, &interface,
149 firmware_handle, NULL,
150 EFI_OPEN_PROTOCOL_GET_PROTOCOL);
151 if (ret != EFI_SUCCESS) {
152 efi_st_error("OpenProtocol failed\n");
153 return EFI_ST_FAILURE;
155 ret = boottime->open_protocol_information(handle1, &guid1,
156 &entry_buffer, &entry_count);
157 if (ret != EFI_SUCCESS) {
158 efi_st_error("OpenProtocolInformation failed\n");
159 return EFI_ST_FAILURE;
161 if (entry_count != 2) {
162 efi_st_error("Incorrect OpenProtocolInformation count\n");
163 efi_st_printf("Expected 2, got %u\n",
164 (unsigned int)entry_count);
165 return EFI_ST_FAILURE;
167 if (entry_buffer[0].open_count + entry_buffer[1].open_count != 3) {
168 efi_st_error("Incorrect open count: expected 3 got %u\n",
169 entry_buffer[0].open_count +
170 entry_buffer[1].open_count);
171 return EFI_ST_FAILURE;
173 ret = boottime->free_pool(entry_buffer);
174 if (ret != EFI_SUCCESS) {
175 efi_st_error("FreePool failed\n");
176 return EFI_ST_FAILURE;
178 ret = boottime->close_protocol(handle1, &guid1, firmware_handle, NULL);
179 if (ret != EFI_SUCCESS) {
180 efi_st_error("CloseProtocol failed\n");
181 return EFI_ST_FAILURE;
183 ret = boottime->open_protocol_information(handle1, &guid1,
184 &entry_buffer, &entry_count);
185 if (ret != EFI_SUCCESS) {
186 efi_st_error("OpenProtocolInformation failed\n");
187 return EFI_ST_FAILURE;
190 efi_st_error("Incorrect OpenProtocolInformation count\n");
191 efi_st_printf("Expected 0, got %u\n",
192 (unsigned int)entry_count);
193 return EFI_ST_FAILURE;
196 return EFI_ST_SUCCESS;
199 EFI_UNIT_TEST(openprot) = {
200 .name = "open protocol",
201 .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
204 .teardown = teardown,