efi_selftest: fix HII tests
[oweals/u-boot.git] / lib / efi_selftest / efi_selftest_hii.c
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 };