1 // SPDX-License-Identifier: GPL-2.0+
3 * efi_selftest_manageprotocols
5 * Copyright (c) 2017 Heinrich Schuchardt <xypron.glpk@gmx.de>
7 * This unit test checks the following protocol services:
8 * InstallProtocolInterface, UninstallProtocolInterface,
9 * InstallMultipleProtocolsInterfaces, UninstallMultipleProtocolsInterfaces,
10 * HandleProtocol, ProtocolsPerHandle,
11 * LocateHandle, LocateHandleBuffer.
14 #include <efi_selftest.h>
17 * The test currently does not actually call the interface function.
18 * So this is just a dummy structure.
21 void (EFIAPI
* inc
)(void);
24 static struct efi_boot_services
*boottime
;
25 static efi_guid_t guid1
=
26 EFI_GUID(0x2e7ca819, 0x21d3, 0x0a3a,
27 0xf7, 0x91, 0x82, 0x1f, 0x7a, 0x83, 0x67, 0xaf);
28 static efi_guid_t guid2
=
29 EFI_GUID(0xf909f2bb, 0x90a8, 0x0d77,
30 0x94, 0x0c, 0x3e, 0xa8, 0xea, 0x38, 0xd6, 0x6f);
31 static efi_guid_t guid3
=
32 EFI_GUID(0x06d641a3, 0xf4e7, 0xe0c9,
33 0xe7, 0x8d, 0x41, 0x2d, 0x72, 0xa6, 0xb1, 0x24);
34 static efi_handle_t handle1
;
35 static efi_handle_t handle2
;
36 static struct interface interface1
;
37 static struct interface interface2
;
38 static struct interface interface3
;
39 static struct interface interface4
;
42 * Find a handle in an array.
44 * @handle: handle to find
45 * @count: number of entries in the array
46 * @buffer: array to search
48 efi_status_t
find_in_buffer(efi_handle_t handle
, size_t count
,
53 for (i
= 0; i
< count
; ++i
) {
54 if (buffer
[i
] == handle
)
63 * Create two handles and install two out of three protocol interfaces on each
73 * @handle: handle of the loaded image
74 * @systable: system table
76 static int setup(const efi_handle_t img_handle
,
77 const struct efi_system_table
*systable
)
82 boottime
= systable
->boottime
;
84 ret
= boottime
->install_protocol_interface(&handle1
, &guid3
,
87 if (ret
!= EFI_SUCCESS
) {
88 efi_st_error("InstallProtocolInterface failed\n");
89 return EFI_ST_FAILURE
;
92 efi_st_error("InstallProtocolInterface failed to create handle\n");
93 return EFI_ST_FAILURE
;
96 ret
= boottime
->install_protocol_interface(&handle1
, &guid1
,
99 if (ret
!= EFI_SUCCESS
) {
100 efi_st_error("InstallProtocolInterface failed\n");
101 return EFI_ST_FAILURE
;
103 if (handle
!= handle1
) {
104 efi_st_error("InstallProtocolInterface failed to use handle\n");
105 return EFI_ST_FAILURE
;
107 ret
= boottime
->install_multiple_protocol_interfaces(&handle2
,
108 &guid1
, &interface4
, &guid2
, &interface2
, NULL
);
109 if (ret
!= EFI_SUCCESS
) {
110 efi_st_error("InstallMultipleProtocolInterfaces failed\n");
111 return EFI_ST_FAILURE
;
113 if (!handle2
|| handle1
== handle2
) {
114 efi_st_error("InstallMultipleProtocolInterfaces failed to create handle\n");
115 return EFI_ST_FAILURE
;
118 return EFI_ST_SUCCESS
;
122 * Tear down unit test.
125 static int teardown(void)
127 return EFI_ST_SUCCESS
;
134 static int execute(void)
136 struct interface
*interface
;
138 efi_handle_t
*buffer
;
140 efi_uintn_t count
= 0;
141 efi_guid_t
**prot_buffer
;
142 efi_uintn_t prot_count
;
145 * Test HandleProtocol
147 ret
= boottime
->handle_protocol(handle1
, &guid3
, (void **)&interface
);
148 if (ret
!= EFI_SUCCESS
) {
149 efi_st_error("HandleProtocol failed to retrieve interface\n");
150 return EFI_ST_FAILURE
;
152 if (interface
!= &interface3
) {
153 efi_st_error("HandleProtocol returned wrong interface\n");
154 return EFI_ST_FAILURE
;
156 ret
= boottime
->handle_protocol(handle1
, &guid2
, (void **)&interface
);
157 if (ret
== EFI_SUCCESS
) {
158 efi_st_error("HandleProtocol returned not installed interface\n");
159 return EFI_ST_FAILURE
;
163 * Test LocateHandleBuffer with AllHandles
165 ret
= boottime
->locate_handle_buffer(ALL_HANDLES
, NULL
, NULL
,
167 if (ret
!= EFI_SUCCESS
) {
168 efi_st_error("LocateHandleBuffer with AllHandles failed\n");
169 return EFI_ST_FAILURE
;
172 ret
= find_in_buffer(handle1
, count
, buffer
);
173 if (ret
!= EFI_SUCCESS
) {
174 efi_st_error("LocateHandleBuffer failed to locate new handle\n");
175 return EFI_ST_FAILURE
;
177 ret
= find_in_buffer(handle2
, count
, buffer
);
178 if (ret
!= EFI_SUCCESS
) {
179 efi_st_error("LocateHandleBuffer failed to locate new handle\n");
180 return EFI_ST_FAILURE
;
182 boottime
->set_mem(buffer
, sizeof(efi_handle_t
) * buffer_size
, 0);
185 * Test error handling in UninstallMultipleProtocols
187 * Try to uninstall more protocols than there are installed.
189 ret
= boottime
->uninstall_multiple_protocol_interfaces(
195 if (ret
== EFI_SUCCESS
) {
196 efi_st_error("UninstallMultipleProtocolInterfaces did not catch error\n");
197 return EFI_ST_FAILURE
;
201 * Test LocateHandleBuffer with ByProtocol
204 ret
= boottime
->locate_handle_buffer(BY_PROTOCOL
, &guid1
, NULL
,
206 if (ret
!= EFI_SUCCESS
) {
207 efi_st_error("LocateHandleBuffer failed to locate new handles\n");
208 return EFI_ST_FAILURE
;
211 efi_st_error("LocateHandleBuffer failed to locate new handles\n");
212 return EFI_ST_FAILURE
;
214 ret
= find_in_buffer(handle1
, count
, buffer
);
215 if (ret
!= EFI_SUCCESS
) {
216 efi_st_error("LocateHandleBuffer failed to locate new handle\n");
217 return EFI_ST_FAILURE
;
219 ret
= find_in_buffer(handle2
, count
, buffer
);
220 if (ret
!= EFI_SUCCESS
) {
221 efi_st_error("LocateHandleBuffer failed to locate new handle\n");
222 return EFI_ST_FAILURE
;
224 boottime
->set_mem(buffer
, sizeof(efi_handle_t
) * buffer_size
, 0);
227 * Test LocateHandle with ByProtocol
229 count
= buffer_size
* sizeof(efi_handle_t
);
230 ret
= boottime
->locate_handle(BY_PROTOCOL
, &guid1
, NULL
,
232 if (ret
!= EFI_SUCCESS
) {
233 efi_st_error("LocateHandle with ByProtocol failed\n");
234 return EFI_ST_FAILURE
;
236 if (count
/ sizeof(efi_handle_t
) != 2) {
237 efi_st_error("LocateHandle failed to locate new handles\n");
238 return EFI_ST_FAILURE
;
241 ret
= find_in_buffer(handle1
, count
, buffer
);
242 if (ret
!= EFI_SUCCESS
) {
243 efi_st_error("LocateHandle failed to locate new handles\n");
244 return EFI_ST_FAILURE
;
246 ret
= find_in_buffer(handle2
, count
, buffer
);
247 if (ret
!= EFI_SUCCESS
) {
248 efi_st_error("LocateHandle failed to locate new handles\n");
249 return EFI_ST_FAILURE
;
251 boottime
->set_mem(buffer
, sizeof(efi_handle_t
) * buffer_size
, 0);
254 * Test LocateProtocol
256 ret
= boottime
->locate_protocol(&guid1
, NULL
, (void **)&interface
);
257 if (ret
!= EFI_SUCCESS
) {
258 efi_st_error("LocateProtocol failed\n");
259 return EFI_ST_FAILURE
;
261 if (interface
!= &interface1
&& interface
!= &interface4
) {
262 efi_st_error("LocateProtocol failed to locate protocol\n");
263 return EFI_ST_FAILURE
;
267 * Test UninstallMultipleProtocols
269 ret
= boottime
->uninstall_multiple_protocol_interfaces(
274 if (ret
!= EFI_SUCCESS
) {
275 efi_st_error("UninstallMultipleProtocolInterfaces failed\n");
276 return EFI_ST_FAILURE
;
279 * Check that the protocols are really uninstalled.
282 ret
= boottime
->locate_handle_buffer(BY_PROTOCOL
, &guid1
, NULL
,
284 if (ret
!= EFI_SUCCESS
) {
285 efi_st_error("LocateHandleBuffer failed\n");
286 return EFI_ST_FAILURE
;
289 efi_st_error("UninstallMultipleProtocolInterfaces failed to uninstall protocols\n");
290 return EFI_ST_FAILURE
;
292 ret
= find_in_buffer(handle1
, count
, buffer
);
293 if (ret
!= EFI_SUCCESS
) {
294 efi_st_error("Failed to locate new handle\n");
295 return EFI_ST_FAILURE
;
297 boottime
->set_mem(buffer
, sizeof(efi_handle_t
) * buffer_size
, 0);
300 * Test ProtocolsPerHandle
302 ret
= boottime
->protocols_per_handle(handle1
,
303 &prot_buffer
, &prot_count
);
304 if (ret
!= EFI_SUCCESS
) {
305 efi_st_error("Failed to get protocols per handle\n");
306 return EFI_ST_FAILURE
;
308 if (prot_count
!= 2) {
309 efi_st_error("Failed to get protocols per handle\n");
310 return EFI_ST_FAILURE
;
312 if (efi_st_memcmp(prot_buffer
[0], &guid1
, 16) &&
313 efi_st_memcmp(prot_buffer
[1], &guid1
, 16)) {
314 efi_st_error("Failed to get protocols per handle\n");
315 return EFI_ST_FAILURE
;
317 if (efi_st_memcmp(prot_buffer
[0], &guid3
, 16) &&
318 efi_st_memcmp(prot_buffer
[1], &guid3
, 16)) {
319 efi_st_error("Failed to get protocols per handle\n");
320 return EFI_ST_FAILURE
;
324 * Uninstall remaining protocols
326 ret
= boottime
->uninstall_protocol_interface(handle1
, &guid1
,
328 if (ret
!= EFI_SUCCESS
) {
329 efi_st_error("UninstallProtocolInterface failed\n");
330 return EFI_ST_FAILURE
;
332 ret
= boottime
->handle_protocol(handle1
, &guid1
, (void **)&interface
);
333 if (ret
== EFI_SUCCESS
) {
334 efi_st_error("UninstallProtocolInterface failed\n");
335 return EFI_ST_FAILURE
;
337 ret
= boottime
->uninstall_protocol_interface(handle1
, &guid3
,
339 if (ret
!= EFI_SUCCESS
) {
340 efi_st_error("UninstallProtocolInterface failed\n");
341 return EFI_ST_FAILURE
;
344 return EFI_ST_SUCCESS
;
347 EFI_UNIT_TEST(protserv
) = {
348 .name
= "manage protocols",
349 .phase
= EFI_EXECUTE_BEFORE_BOOTTIME_EXIT
,
352 .teardown
= teardown
,