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