xref: /openbmc/u-boot/lib/efi_selftest/efi_selftest_hii.c (revision 9755e3db8b1223699954146dfb171df75ec89ab3)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * efi_selftest_hii
4  *
5  * Copyright (c) 2018 AKASHI Takahiro, Linaro Limited
6  *
7  * Test HII database protocols
8  */
9 
10 #include <efi_selftest.h>
11 #include <malloc.h>
12 #include "efi_selftest_hii_data.c"
13 
14 #define PRINT_TESTNAME efi_st_printf("%s:\n", __func__)
15 
16 static struct efi_boot_services *boottime;
17 
18 static const efi_guid_t hii_database_protocol_guid =
19 	EFI_HII_DATABASE_PROTOCOL_GUID;
20 static const efi_guid_t hii_string_protocol_guid =
21 	EFI_HII_STRING_PROTOCOL_GUID;
22 
23 static struct efi_hii_database_protocol *hii_database_protocol;
24 static struct efi_hii_string_protocol *hii_string_protocol;
25 
26 /*
27  * Setup unit test.
28  *
29  * @handle:	handle of the loaded image
30  * @systable:	system table
31  *
32  * @return:	EFI_ST_SUCCESS for success
33  */
34 static int setup(const efi_handle_t handle,
35 		 const struct efi_system_table *systable)
36 {
37 	efi_status_t ret;
38 
39 	boottime = systable->boottime;
40 
41 	/* HII database protocol */
42 	ret = boottime->locate_protocol(&hii_database_protocol_guid, NULL,
43 					(void **)&hii_database_protocol);
44 	if (ret != EFI_SUCCESS) {
45 		hii_database_protocol = NULL;
46 		efi_st_error("HII database protocol is not available.\n");
47 		return EFI_ST_FAILURE;
48 	}
49 
50 	/* HII string protocol */
51 	ret = boottime->locate_protocol(&hii_string_protocol_guid, NULL,
52 					(void **)&hii_string_protocol);
53 	if (ret != EFI_SUCCESS) {
54 		hii_string_protocol = NULL;
55 		efi_st_error("HII string protocol is not available.\n");
56 		return EFI_ST_FAILURE;
57 	}
58 
59 	return EFI_ST_SUCCESS;
60 }
61 
62 /*
63  * HII database protocol tests
64  */
65 
66 /**
67  * test_hii_database_new_package_list() - test creation and removal of
68  *	package list
69  *
70  * This test adds a new package list and then tries to remove it using
71  * the provided handle.
72  *
73  * @Return:     status code
74  */
75 static int test_hii_database_new_package_list(void)
76 {
77 	efi_hii_handle_t handle;
78 	efi_status_t ret;
79 
80 	PRINT_TESTNAME;
81 	ret = hii_database_protocol->new_package_list(hii_database_protocol,
82 			(struct efi_hii_package_list_header *)packagelist1,
83 			NULL, &handle);
84 	if (ret != EFI_SUCCESS || !handle) {
85 		efi_st_error("new_package_list returned %u\n",
86 			     (unsigned int)ret);
87 		return EFI_ST_FAILURE;
88 	}
89 
90 	ret = hii_database_protocol->remove_package_list(hii_database_protocol,
91 			handle);
92 	if (ret != EFI_SUCCESS) {
93 		efi_st_error("remove_package_list returned %u\n",
94 			     (unsigned int)ret);
95 		return EFI_ST_FAILURE;
96 	}
97 
98 	return EFI_ST_SUCCESS;
99 }
100 
101 /**
102  * test_hii_database_update_package_list() - test update of package list
103  *
104  * This test adds a new package list and then tries to update it using
105  * another package list.
106  *
107  * @Return:     status code
108  */
109 static int test_hii_database_update_package_list(void)
110 {
111 	efi_hii_handle_t handle = NULL;
112 	efi_status_t ret;
113 	int result = EFI_ST_FAILURE;
114 
115 	PRINT_TESTNAME;
116 	ret = hii_database_protocol->new_package_list(hii_database_protocol,
117 			(struct efi_hii_package_list_header *)packagelist1,
118 			NULL, &handle);
119 	if (ret != EFI_SUCCESS || !handle) {
120 		efi_st_error("new_package_list returned %u\n",
121 			     (unsigned int)ret);
122 		return EFI_ST_FAILURE;
123 	}
124 
125 	ret = hii_database_protocol->update_package_list(hii_database_protocol,
126 			handle,
127 			(struct efi_hii_package_list_header *)packagelist2);
128 	if (ret != EFI_SUCCESS || !handle) {
129 		efi_st_error("new_package_list returned %u\n",
130 			     (unsigned int)ret);
131 		goto out;
132 	}
133 
134 	result = EFI_ST_SUCCESS;
135 
136 out:
137 	if (handle) {
138 		ret = hii_database_protocol->remove_package_list(
139 				hii_database_protocol, handle);
140 		if (ret != EFI_SUCCESS) {
141 			efi_st_error("remove_package_list returned %u\n",
142 				     (unsigned int)ret);
143 			return EFI_ST_FAILURE;
144 		}
145 	}
146 
147 	return result;
148 }
149 
150 /**
151  * test_hii_database_list_package_lists() - test listing of package lists
152  *
153  * This test adds two package lists and then tries to enumerate them
154  * against different package types. We will get an array of handles.
155  *
156  * @Return:     status code
157  */
158 static int test_hii_database_list_package_lists(void)
159 {
160 	efi_hii_handle_t handle1 = NULL, handle2 = NULL, *handles;
161 	efi_uintn_t handles_size;
162 	efi_status_t ret;
163 	int result = EFI_ST_FAILURE;
164 
165 	PRINT_TESTNAME;
166 	ret = hii_database_protocol->new_package_list(hii_database_protocol,
167 			(struct efi_hii_package_list_header *)packagelist1,
168 			NULL, &handle1);
169 	if (ret != EFI_SUCCESS || !handle1) {
170 		efi_st_error("new_package_list returned %u\n",
171 			     (unsigned int)ret);
172 		goto out;
173 	}
174 
175 	ret = hii_database_protocol->new_package_list(hii_database_protocol,
176 			(struct efi_hii_package_list_header *)packagelist2,
177 			NULL, &handle2);
178 	if (ret != EFI_SUCCESS || !handle2) {
179 		efi_st_error("new_package_list returned %u\n",
180 			     (unsigned int)ret);
181 		goto out;
182 	}
183 
184 	/* TYPE_ALL */
185 	handles = NULL;
186 	handles_size = 0;
187 	ret = hii_database_protocol->list_package_lists(hii_database_protocol,
188 			EFI_HII_PACKAGE_TYPE_ALL, NULL,
189 			&handles_size, handles);
190 	if (ret != EFI_BUFFER_TOO_SMALL) {
191 		efi_st_error("list_package_lists returned %u\n",
192 			     (unsigned int)ret);
193 		goto out;
194 	}
195 	handles = malloc(handles_size);
196 	if (!handles) {
197 		efi_st_error("malloc failed\n");
198 		goto out;
199 	}
200 	ret = hii_database_protocol->list_package_lists(hii_database_protocol,
201 			EFI_HII_PACKAGE_TYPE_ALL, NULL,
202 			&handles_size, handles);
203 	if (ret != EFI_SUCCESS) {
204 		efi_st_error("list_package_lists returned %u\n",
205 			     (unsigned int)ret);
206 		goto out;
207 	}
208 	free(handles);
209 
210 	/* STRINGS */
211 	handles = NULL;
212 	handles_size = 0;
213 	ret = hii_database_protocol->list_package_lists(hii_database_protocol,
214 			EFI_HII_PACKAGE_STRINGS, NULL,
215 			&handles_size, handles);
216 	if (ret != EFI_BUFFER_TOO_SMALL) {
217 		efi_st_error("list_package_lists returned %u\n",
218 			     (unsigned int)ret);
219 		ret = EFI_ST_FAILURE;
220 		goto out;
221 	}
222 	handles = malloc(handles_size);
223 	if (!handles) {
224 		efi_st_error("malloc failed\n");
225 		ret = EFI_ST_FAILURE;
226 		goto out;
227 	}
228 	ret = hii_database_protocol->list_package_lists(hii_database_protocol,
229 			EFI_HII_PACKAGE_STRINGS, NULL,
230 			&handles_size, handles);
231 	if (ret != EFI_SUCCESS) {
232 		efi_st_error("list_package_lists returned %u\n",
233 			     (unsigned int)ret);
234 		ret = EFI_ST_FAILURE;
235 		goto out;
236 	}
237 	free(handles);
238 
239 	/* GUID */
240 	handles = NULL;
241 	handles_size = 0;
242 	ret = hii_database_protocol->list_package_lists(hii_database_protocol,
243 			EFI_HII_PACKAGE_TYPE_GUID, &package_guid,
244 			&handles_size, handles);
245 	if (ret != EFI_BUFFER_TOO_SMALL) {
246 		efi_st_error("list_package_lists returned %u\n",
247 			     (unsigned int)ret);
248 		ret = EFI_ST_FAILURE;
249 		goto out;
250 	}
251 	handles = malloc(handles_size);
252 	if (!handles) {
253 		efi_st_error("malloc failed\n");
254 		ret = EFI_ST_FAILURE;
255 		goto out;
256 	}
257 	ret = hii_database_protocol->list_package_lists(hii_database_protocol,
258 			EFI_HII_PACKAGE_TYPE_GUID, &package_guid,
259 			&handles_size, handles);
260 	if (ret != EFI_SUCCESS) {
261 		efi_st_error("list_package_lists returned %u\n",
262 			     (unsigned int)ret);
263 		ret = EFI_ST_FAILURE;
264 		goto out;
265 	}
266 	free(handles);
267 
268 	/* KEYBOARD_LAYOUT */
269 	handles = NULL;
270 	handles_size = 0;
271 	ret = hii_database_protocol->list_package_lists(hii_database_protocol,
272 			EFI_HII_PACKAGE_KEYBOARD_LAYOUT, NULL,
273 			&handles_size, handles);
274 	if (ret != EFI_BUFFER_TOO_SMALL) {
275 		efi_st_error("list_package_lists returned %u\n",
276 			     (unsigned int)ret);
277 		ret = EFI_ST_FAILURE;
278 		goto out;
279 	}
280 	handles = malloc(handles_size);
281 	if (!handles) {
282 		efi_st_error("malloc failed\n");
283 		ret = EFI_ST_FAILURE;
284 		goto out;
285 	}
286 	ret = hii_database_protocol->list_package_lists(hii_database_protocol,
287 			EFI_HII_PACKAGE_KEYBOARD_LAYOUT, NULL,
288 			&handles_size, handles);
289 	if (ret != EFI_SUCCESS) {
290 		efi_st_error("list_package_lists returned %u\n",
291 			     (unsigned int)ret);
292 		ret = EFI_ST_FAILURE;
293 		goto out;
294 	}
295 	free(handles);
296 
297 	result = EFI_ST_SUCCESS;
298 
299 out:
300 	if (handle1) {
301 		ret = hii_database_protocol->remove_package_list(
302 				hii_database_protocol, handle1);
303 		if (ret != EFI_SUCCESS)
304 			efi_st_error("remove_package_list returned %u\n",
305 				     (unsigned int)ret);
306 	}
307 	if (handle2) {
308 		ret = hii_database_protocol->remove_package_list(
309 				hii_database_protocol, handle2);
310 		if (ret != EFI_SUCCESS)
311 			efi_st_error("remove_package_list returned %u\n",
312 				     (unsigned int)ret);
313 	}
314 
315 	return result;
316 }
317 
318 /**
319  * test_hii_database_export_package_lists() - test export of package lists
320  *
321  * @Return:     status code
322  */
323 static int test_hii_database_export_package_lists(void)
324 {
325 	PRINT_TESTNAME;
326 	/* export_package_lists() not implemented yet */
327 	return EFI_ST_SUCCESS;
328 }
329 
330 /**
331  * test_hii_database_register_package_notify() - test registration of
332  *	notification function
333  *
334  * @Return:     status code
335  */
336 static int test_hii_database_register_package_notify(void)
337 {
338 	PRINT_TESTNAME;
339 	/* register_package_notify() not implemented yet */
340 	return EFI_ST_SUCCESS;
341 }
342 
343 /**
344  * test_hii_database_unregister_package_notify() - test removal of
345  *	notification function
346  *
347  * @Return:     status code
348  */
349 static int test_hii_database_unregister_package_notify(void)
350 {
351 	PRINT_TESTNAME;
352 	/* unregsiter_package_notify() not implemented yet */
353 	return EFI_ST_SUCCESS;
354 }
355 
356 /**
357  * test_hii_database_find_keyboard_layouts() - test listing of
358  *	all the keyboard layouts in the system
359  *
360  * This test adds two package lists, each of which has two keyboard layouts
361  * and then tries to enumerate them. We will get an array of handles.
362  *
363  * @Return:     status code
364  */
365 static int test_hii_database_find_keyboard_layouts(void)
366 {
367 	efi_hii_handle_t handle1 = NULL, handle2 = NULL;
368 	efi_guid_t *guids;
369 	u16 guids_size;
370 	efi_status_t ret;
371 	int result = EFI_ST_FAILURE;
372 
373 	PRINT_TESTNAME;
374 	ret = hii_database_protocol->new_package_list(hii_database_protocol,
375 			(struct efi_hii_package_list_header *)packagelist1,
376 			NULL, &handle1);
377 	if (ret != EFI_SUCCESS || !handle1) {
378 		efi_st_error("new_package_list returned %u\n",
379 			     (unsigned int)ret);
380 		goto out;
381 	}
382 
383 	ret = hii_database_protocol->new_package_list(hii_database_protocol,
384 			(struct efi_hii_package_list_header *)packagelist2,
385 			NULL, &handle2);
386 	if (ret != EFI_SUCCESS || !handle2) {
387 		efi_st_error("new_package_list returned %u\n",
388 			     (unsigned int)ret);
389 		goto out;
390 	}
391 
392 	guids = NULL;
393 	guids_size = 0;
394 	ret = hii_database_protocol->find_keyboard_layouts(
395 			hii_database_protocol, &guids_size, guids);
396 	if (ret != EFI_BUFFER_TOO_SMALL) {
397 		efi_st_error("find_keyboard_layouts returned %u\n",
398 			     (unsigned int)ret);
399 		goto out;
400 	}
401 	guids = malloc(guids_size);
402 	if (!guids) {
403 		efi_st_error("malloc failed\n");
404 		goto out;
405 	}
406 	ret = hii_database_protocol->find_keyboard_layouts(
407 			hii_database_protocol, &guids_size, guids);
408 	if (ret != EFI_SUCCESS) {
409 		efi_st_error("find_keyboard_layouts returned %u\n",
410 			     (unsigned int)ret);
411 		goto out;
412 	}
413 	free(guids);
414 
415 	result = EFI_ST_SUCCESS;
416 
417 out:
418 	if (handle1) {
419 		ret = hii_database_protocol->remove_package_list(
420 				hii_database_protocol, handle1);
421 		if (ret != EFI_SUCCESS)
422 			efi_st_error("remove_package_list returned %u\n",
423 				     (unsigned int)ret);
424 	}
425 	if (handle2) {
426 		ret = hii_database_protocol->remove_package_list(
427 				hii_database_protocol, handle2);
428 		if (ret != EFI_SUCCESS)
429 			efi_st_error("remove_package_list returned %u\n",
430 				     (unsigned int)ret);
431 	}
432 
433 	return result;
434 }
435 
436 /**
437  * test_hii_database_get_keyboard_layout() - test retrieval of keyboard layout
438  *
439  * This test adds two package lists, each of which has two keyboard layouts
440  * and then tries to get a handle to keyboard layout with a specific guid
441  * and the current one.
442  *
443  * @Return:     status code
444  */
445 static int test_hii_database_get_keyboard_layout(void)
446 {
447 	efi_hii_handle_t handle1 = NULL, handle2 = NULL;
448 	struct efi_hii_keyboard_layout *kb_layout;
449 	u16 kb_layout_size;
450 	efi_status_t ret;
451 	int result = EFI_ST_FAILURE;
452 
453 	PRINT_TESTNAME;
454 	ret = hii_database_protocol->new_package_list(hii_database_protocol,
455 			(struct efi_hii_package_list_header *)packagelist1,
456 			NULL, &handle1);
457 	if (ret != EFI_SUCCESS || !handle1) {
458 		efi_st_error("new_package_list returned %u\n",
459 			     (unsigned int)ret);
460 		goto out;
461 	}
462 
463 	ret = hii_database_protocol->new_package_list(hii_database_protocol,
464 			(struct efi_hii_package_list_header *)packagelist2,
465 			NULL, &handle2);
466 	if (ret != EFI_SUCCESS || !handle2) {
467 		efi_st_error("new_package_list returned %u\n",
468 			     (unsigned int)ret);
469 		goto out;
470 	}
471 
472 	/* specific keyboard_layout(guid11) */
473 	kb_layout = NULL;
474 	kb_layout_size = 0;
475 	ret = hii_database_protocol->get_keyboard_layout(hii_database_protocol,
476 			&kb_layout_guid11, &kb_layout_size, kb_layout);
477 	if (ret != EFI_BUFFER_TOO_SMALL) {
478 		efi_st_error("get_keyboard_layout returned %u\n",
479 			     (unsigned int)ret);
480 		goto out;
481 	}
482 	kb_layout = malloc(kb_layout_size);
483 	if (!kb_layout) {
484 		efi_st_error("malloc failed\n");
485 		goto out;
486 	}
487 	ret = hii_database_protocol->get_keyboard_layout(hii_database_protocol,
488 			&kb_layout_guid11, &kb_layout_size, kb_layout);
489 	if (ret != EFI_SUCCESS) {
490 		efi_st_error("get_keyboard_layout returned %u\n",
491 			     (unsigned int)ret);
492 		goto out;
493 	}
494 	free(kb_layout);
495 
496 	/* current */
497 	kb_layout = NULL;
498 	kb_layout_size = 0;
499 	ret = hii_database_protocol->get_keyboard_layout(hii_database_protocol,
500 			NULL, &kb_layout_size, kb_layout);
501 	if (ret != EFI_INVALID_PARAMETER) {
502 		efi_st_error("get_keyboard_layout returned %u\n",
503 			     (unsigned int)ret);
504 		goto out;
505 	}
506 
507 	result = EFI_ST_SUCCESS;
508 
509 out:
510 	if (handle1) {
511 		ret = hii_database_protocol->remove_package_list(
512 				hii_database_protocol, handle1);
513 		if (ret != EFI_SUCCESS)
514 			efi_st_error("remove_package_list returned %u\n",
515 				     (unsigned int)ret);
516 	}
517 	if (handle2) {
518 		ret = hii_database_protocol->remove_package_list(
519 				hii_database_protocol, handle2);
520 		if (ret != EFI_SUCCESS)
521 			efi_st_error("remove_package_list returned %u\n",
522 				     (unsigned int)ret);
523 	}
524 
525 	return result;
526 }
527 
528 /**
529  * test_hii_database_set_keyboard_layout() - test change of
530  *	current keyboard layout
531  *
532  * @Return:     status code
533  */
534 static int test_hii_database_set_keyboard_layout(void)
535 {
536 	PRINT_TESTNAME;
537 	/* set_keyboard_layout() not implemented yet */
538 	return EFI_ST_SUCCESS;
539 }
540 
541 /**
542  * test_hii_database_get_package_list_handle() - test retrieval of
543  *	driver associated with a package list
544  *
545  * This test adds a package list, and then tries to get a handle to driver
546  * which is associated with a package list.
547  *
548  * @Return:     status code
549  */
550 static int test_hii_database_get_package_list_handle(void)
551 {
552 	efi_hii_handle_t handle = NULL;
553 	efi_handle_t driver_handle;
554 	efi_status_t ret;
555 	int result = EFI_ST_FAILURE;
556 
557 	PRINT_TESTNAME;
558 	driver_handle = (efi_handle_t)0x12345678; /* dummy */
559 	ret = hii_database_protocol->new_package_list(hii_database_protocol,
560 			(struct efi_hii_package_list_header *)packagelist1,
561 			driver_handle, &handle);
562 	if (ret != EFI_SUCCESS || !handle) {
563 		efi_st_error("new_package_list returned %u\n",
564 			     (unsigned int)ret);
565 		return EFI_ST_FAILURE;
566 	}
567 
568 	driver_handle = NULL;
569 	ret = hii_database_protocol->get_package_list_handle(
570 			hii_database_protocol, handle, &driver_handle);
571 	if (ret != EFI_SUCCESS || driver_handle != (efi_handle_t)0x12345678) {
572 		efi_st_error("get_package_list_handle returned %u, driver:%p\n",
573 			     (unsigned int)ret, driver_handle);
574 		goto out;
575 	}
576 
577 	result = EFI_ST_SUCCESS;
578 
579 out:
580 	if (handle) {
581 		ret = hii_database_protocol->remove_package_list(
582 				hii_database_protocol, handle);
583 		if (ret != EFI_SUCCESS) {
584 			efi_st_error("remove_package_list returned %u\n",
585 				     (unsigned int)ret);
586 			return EFI_ST_FAILURE;
587 		}
588 	}
589 
590 	return result;
591 }
592 
593 static int test_hii_database_protocol(void)
594 {
595 	int ret;
596 
597 	ret = test_hii_database_new_package_list();
598 	if (ret != EFI_ST_SUCCESS)
599 		return EFI_ST_FAILURE;
600 
601 	ret = test_hii_database_update_package_list();
602 	if (ret != EFI_ST_SUCCESS)
603 		return EFI_ST_FAILURE;
604 
605 	ret = test_hii_database_list_package_lists();
606 	if (ret != EFI_ST_SUCCESS)
607 		return EFI_ST_FAILURE;
608 
609 	ret = test_hii_database_export_package_lists();
610 	if (ret != EFI_ST_SUCCESS)
611 		return EFI_ST_FAILURE;
612 
613 	ret = test_hii_database_register_package_notify();
614 	if (ret != EFI_ST_SUCCESS)
615 		return EFI_ST_FAILURE;
616 
617 	ret = test_hii_database_unregister_package_notify();
618 	if (ret != EFI_ST_SUCCESS)
619 		return EFI_ST_FAILURE;
620 
621 	ret = test_hii_database_find_keyboard_layouts();
622 	if (ret != EFI_ST_SUCCESS)
623 		return EFI_ST_FAILURE;
624 
625 	ret = test_hii_database_get_keyboard_layout();
626 	if (ret != EFI_ST_SUCCESS)
627 		return EFI_ST_FAILURE;
628 
629 	ret = test_hii_database_set_keyboard_layout();
630 	if (ret != EFI_ST_SUCCESS)
631 		return EFI_ST_FAILURE;
632 
633 	ret = test_hii_database_get_package_list_handle();
634 	if (ret != EFI_ST_SUCCESS)
635 		return EFI_ST_FAILURE;
636 
637 	return EFI_ST_SUCCESS;
638 }
639 
640 /*
641  * HII string protocol tests
642  */
643 
644 /**
645  * test_hii_string_new_string() - test creation of a new string entry
646  *
647  * This test adds a package list, and then tries to add a new string
648  * entry for a specific language.
649  *
650  * @Return:     status code
651  */
652 static int test_hii_string_new_string(void)
653 {
654 	efi_hii_handle_t handle = NULL;
655 	efi_string_id_t id;
656 	efi_status_t ret;
657 	int result = EFI_ST_FAILURE;
658 
659 	PRINT_TESTNAME;
660 	ret = hii_database_protocol->new_package_list(hii_database_protocol,
661 			(struct efi_hii_package_list_header *)packagelist1,
662 			NULL, &handle);
663 	if (ret != EFI_SUCCESS || !handle) {
664 		efi_st_error("new_package_list returned %u\n",
665 			     (unsigned int)ret);
666 		return EFI_ST_FAILURE;
667 	}
668 
669 	ret = hii_string_protocol->new_string(hii_string_protocol, handle,
670 					      &id, (u8 *)"en-US",
671 					      L"Japanese", L"Japanese", NULL);
672 	if (ret != EFI_SUCCESS) {
673 		efi_st_error("new_string returned %u\n",
674 			     (unsigned int)ret);
675 		goto out;
676 	}
677 	efi_st_printf("new string id is %u\n", id);
678 
679 	result = EFI_ST_SUCCESS;
680 
681 out:
682 	if (handle) {
683 		ret = hii_database_protocol->remove_package_list(
684 				hii_database_protocol, handle);
685 		if (ret != EFI_SUCCESS) {
686 			efi_st_error("remove_package_list returned %u\n",
687 				     (unsigned int)ret);
688 			return EFI_ST_FAILURE;
689 		}
690 	}
691 
692 	return result;
693 }
694 
695 /**
696  * test_hii_string_get_string() - test retrieval of a string entry
697  *
698  * This test adds a package list, create a new string entry and then tries
699  * to get it with its string id.
700  *
701  * @Return:     status code
702  */
703 static int test_hii_string_get_string(void)
704 {
705 	efi_hii_handle_t handle = NULL;
706 	efi_string_id_t id;
707 	efi_string_t string;
708 	efi_uintn_t string_len;
709 	efi_status_t ret;
710 	int result = EFI_ST_FAILURE;
711 
712 	PRINT_TESTNAME;
713 	ret = hii_database_protocol->new_package_list(hii_database_protocol,
714 			(struct efi_hii_package_list_header *)packagelist1,
715 			NULL, &handle);
716 	if (ret != EFI_SUCCESS || !handle) {
717 		efi_st_error("new_package_list returned %u\n",
718 			     (unsigned int)ret);
719 		return EFI_ST_FAILURE;
720 	}
721 
722 	ret = hii_string_protocol->new_string(hii_string_protocol, handle,
723 					      &id, (u8 *)"en-US",
724 					      L"Japanese", L"Japanese", NULL);
725 	if (ret != EFI_SUCCESS) {
726 		efi_st_error("new_string returned %u\n",
727 			     (unsigned int)ret);
728 		goto out;
729 	}
730 
731 	string = NULL;
732 	string_len = 0;
733 	ret = hii_string_protocol->get_string(hii_string_protocol,
734 			(u8 *)"en-US", handle, id, string, &string_len, NULL);
735 	if (ret != EFI_BUFFER_TOO_SMALL) {
736 		efi_st_error("get_string returned %u\n",
737 			     (unsigned int)ret);
738 		goto out;
739 	}
740 	string_len += sizeof(u16);
741 	string = malloc(string_len);
742 	if (!string) {
743 		efi_st_error("malloc failed\n");
744 		goto out;
745 	}
746 	ret = hii_string_protocol->get_string(hii_string_protocol,
747 			(u8 *)"en-US", handle, id, string, &string_len, NULL);
748 	if (ret != EFI_SUCCESS) {
749 		efi_st_error("get_string returned %u\n",
750 			     (unsigned int)ret);
751 		goto out;
752 	}
753 
754 #if 1
755 	u16 *c1, *c2;
756 
757 	for (c1 = string, c2 = L"Japanese"; *c1 == *c2; c1++, c2++)
758 		;
759 	if (!*c1 && !*c2)
760 		result = EFI_ST_SUCCESS;
761 	else
762 		result = EFI_ST_FAILURE;
763 #else
764 	/* TODO: %ls */
765 	efi_st_printf("got string is %s (can be wrong)\n", string);
766 #endif
767 
768 	result = EFI_ST_SUCCESS;
769 
770 out:
771 	if (handle) {
772 		ret = hii_database_protocol->remove_package_list(
773 				hii_database_protocol, handle);
774 		if (ret != EFI_SUCCESS) {
775 			efi_st_error("remove_package_list returned %u\n",
776 				     (unsigned int)ret);
777 			return EFI_ST_FAILURE;
778 		}
779 	}
780 
781 	return result;
782 }
783 
784 /**
785  * test_hii_string_set_string() - test change of a string entry
786  *
787  * This test adds a package list, create a new string entry and then tries
788  * to modify it.
789  *
790  * @Return:     status code
791  */
792 static int test_hii_string_set_string(void)
793 {
794 	efi_hii_handle_t handle = NULL;
795 	efi_string_id_t id;
796 	efi_status_t ret;
797 	int result = EFI_ST_FAILURE;
798 
799 	PRINT_TESTNAME;
800 	ret = hii_database_protocol->new_package_list(hii_database_protocol,
801 			(struct efi_hii_package_list_header *)packagelist1,
802 			NULL, &handle);
803 	if (ret != EFI_SUCCESS || !handle) {
804 		efi_st_error("new_package_list returned %u\n",
805 			     (unsigned int)ret);
806 		return EFI_ST_FAILURE;
807 	}
808 
809 	ret = hii_string_protocol->new_string(hii_string_protocol, handle,
810 					      &id, (u8 *)"en-US",
811 					      L"Japanese", L"Japanese", NULL);
812 	if (ret != EFI_SUCCESS) {
813 		efi_st_error("new_string returned %u\n",
814 			     (unsigned int)ret);
815 		goto out;
816 	}
817 
818 	ret = hii_string_protocol->set_string(hii_string_protocol, handle,
819 					      id, (u8 *)"en-US",
820 					      L"Nihongo", NULL);
821 	if (ret != EFI_SUCCESS) {
822 		efi_st_error("set_string returned %u\n",
823 			     (unsigned int)ret);
824 		goto out;
825 	}
826 
827 	result = EFI_ST_SUCCESS;
828 
829 out:
830 	if (handle) {
831 		ret = hii_database_protocol->remove_package_list(
832 				hii_database_protocol, handle);
833 		if (ret != EFI_SUCCESS) {
834 			efi_st_error("remove_package_list returned %u\n",
835 				     (unsigned int)ret);
836 			return EFI_ST_FAILURE;
837 		}
838 	}
839 
840 	return result;
841 }
842 
843 /**
844  * test_hii_string_get_languages() - test listing of languages
845  *
846  * This test adds a package list, and then tries to enumerate languages
847  * in it. We will get an string of language names.
848  *
849  * @Return:     status code
850  */
851 static int test_hii_string_get_languages(void)
852 {
853 	efi_hii_handle_t handle = NULL;
854 	u8 *languages;
855 	efi_uintn_t languages_len;
856 	efi_status_t ret;
857 	int result = EFI_ST_FAILURE;
858 
859 	PRINT_TESTNAME;
860 	ret = hii_database_protocol->new_package_list(hii_database_protocol,
861 			(struct efi_hii_package_list_header *)packagelist1,
862 			NULL, &handle);
863 	if (ret != EFI_SUCCESS || !handle) {
864 		efi_st_error("new_package_list returned %u\n",
865 			     (unsigned int)ret);
866 		return EFI_ST_FAILURE;
867 	}
868 
869 	languages = NULL;
870 	languages_len = 0;
871 	ret = hii_string_protocol->get_languages(hii_string_protocol, handle,
872 			languages, &languages_len);
873 	if (ret != EFI_BUFFER_TOO_SMALL) {
874 		efi_st_error("get_languages returned %u\n",
875 			     (unsigned int)ret);
876 		goto out;
877 	}
878 	languages = malloc(languages_len);
879 	if (!languages) {
880 		efi_st_error("malloc failed\n");
881 		goto out;
882 	}
883 	ret = hii_string_protocol->get_languages(hii_string_protocol, handle,
884 			languages, &languages_len);
885 	if (ret != EFI_SUCCESS) {
886 		efi_st_error("get_languages returned %u\n",
887 			     (unsigned int)ret);
888 		goto out;
889 	}
890 
891 	efi_st_printf("got languages are %s\n", languages);
892 
893 	result = EFI_ST_SUCCESS;
894 
895 out:
896 	if (handle) {
897 		ret = hii_database_protocol->remove_package_list(
898 				hii_database_protocol, handle);
899 		if (ret != EFI_SUCCESS) {
900 			efi_st_error("remove_package_list returned %u\n",
901 				     (unsigned int)ret);
902 			return EFI_ST_FAILURE;
903 		}
904 	}
905 
906 	return result;
907 }
908 
909 /**
910  * test_hii_string_get_secondary_languages() - test listing of secondary
911  *	languages
912  *
913  * This test adds a package list, and then tries to enumerate secondary
914  * languages with a specific language. We will get an string of language names.
915  *
916  * @Return:     status code
917  */
918 static int test_hii_string_get_secondary_languages(void)
919 {
920 	efi_hii_handle_t handle = NULL;
921 	u8 *languages;
922 	efi_uintn_t languages_len;
923 	efi_status_t ret;
924 	int result = EFI_ST_FAILURE;
925 
926 	PRINT_TESTNAME;
927 	ret = hii_database_protocol->new_package_list(hii_database_protocol,
928 			(struct efi_hii_package_list_header *)packagelist1,
929 			NULL, &handle);
930 	if (ret != EFI_SUCCESS || !handle) {
931 		efi_st_error("new_package_list returned %u\n",
932 			     (unsigned int)ret);
933 		return EFI_ST_FAILURE;
934 	}
935 
936 	languages = NULL;
937 	languages_len = 0;
938 	ret = hii_string_protocol->get_secondary_languages(hii_string_protocol,
939 			handle, (u8 *)"en-US", languages, &languages_len);
940 	if (ret == EFI_NOT_FOUND) {
941 		efi_st_printf("no secondary languages\n");
942 		result = EFI_ST_SUCCESS;
943 		goto out;
944 	}
945 	if (ret != EFI_BUFFER_TOO_SMALL) {
946 		efi_st_error("get_secondary_languages returned %u\n",
947 			     (unsigned int)ret);
948 		goto out;
949 	}
950 	languages = malloc(languages_len);
951 	if (!languages) {
952 		efi_st_error("malloc failed\n");
953 		goto out;
954 	}
955 	ret = hii_string_protocol->get_secondary_languages(hii_string_protocol,
956 			handle, (u8 *)"en-US", languages, &languages_len);
957 	if (ret != EFI_SUCCESS) {
958 		efi_st_error("get_secondary_languages returned %u\n",
959 			     (unsigned int)ret);
960 		goto out;
961 	}
962 
963 	efi_st_printf("got secondary languages are %s\n", languages);
964 
965 	result = EFI_ST_SUCCESS;
966 
967 out:
968 	if (handle) {
969 		ret = hii_database_protocol->remove_package_list(
970 				hii_database_protocol, handle);
971 		if (ret != EFI_SUCCESS) {
972 			efi_st_error("remove_package_list returned %u\n",
973 				     (unsigned int)ret);
974 			return EFI_ST_FAILURE;
975 		}
976 	}
977 
978 	return result;
979 }
980 
981 static int test_hii_string_protocol(void)
982 {
983 	int ret;
984 
985 	ret = test_hii_string_new_string();
986 	if (ret != EFI_ST_SUCCESS)
987 		return EFI_ST_FAILURE;
988 
989 	ret = test_hii_string_get_string();
990 	if (ret != EFI_ST_SUCCESS)
991 		return EFI_ST_FAILURE;
992 
993 	ret = test_hii_string_set_string();
994 	if (ret != EFI_ST_SUCCESS)
995 		return EFI_ST_FAILURE;
996 
997 	ret = test_hii_string_get_languages();
998 	if (ret != EFI_ST_SUCCESS)
999 		return EFI_ST_FAILURE;
1000 
1001 	ret = test_hii_string_get_secondary_languages();
1002 	if (ret != EFI_ST_SUCCESS)
1003 		return EFI_ST_FAILURE;
1004 
1005 	return EFI_ST_SUCCESS;
1006 }
1007 
1008 /*
1009  * Execute unit test.
1010  *
1011  * @return:	EFI_ST_SUCCESS for success, EFI_ST_FAILURE for failure
1012  */
1013 static int execute(void)
1014 {
1015 	int ret;
1016 
1017 	/* HII database protocol */
1018 	ret = test_hii_database_protocol();
1019 	if (ret != EFI_ST_SUCCESS)
1020 		return EFI_ST_FAILURE;
1021 
1022 	/* HII string protocol */
1023 	ret = test_hii_string_protocol();
1024 	if (ret != EFI_ST_SUCCESS)
1025 		return EFI_ST_FAILURE;
1026 
1027 	return EFI_ST_SUCCESS;
1028 }
1029 
1030 EFI_UNIT_TEST(hii) = {
1031 	.name = "HII database protocols",
1032 	.phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
1033 	.setup = setup,
1034 	.execute = execute,
1035 };
1036