Prepare v2023.10
[platform/kernel/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                 goto out;
224         }
225         ret = boottime->allocate_pool(EFI_LOADER_DATA, handles_size,
226                                       (void **)&handles);
227         if (ret != EFI_SUCCESS) {
228                 efi_st_error("AllocatePool failed\n");
229                 goto out;
230         }
231         ret = hii_database_protocol->list_package_lists(hii_database_protocol,
232                         EFI_HII_PACKAGE_STRINGS, NULL,
233                         &handles_size, handles);
234         if (ret != EFI_SUCCESS) {
235                 efi_st_error("list_package_lists returned %u\n",
236                              (unsigned int)ret);
237                 goto out;
238         }
239         ret = boottime->free_pool(handles);
240         if (ret != EFI_SUCCESS) {
241                 efi_st_error("FreePool failed\n");
242                 goto out;
243         }
244
245         /* GUID */
246         handles = NULL;
247         handles_size = 0;
248         ret = hii_database_protocol->list_package_lists(hii_database_protocol,
249                         EFI_HII_PACKAGE_TYPE_GUID, &package_guid,
250                         &handles_size, handles);
251         if (ret != EFI_BUFFER_TOO_SMALL) {
252                 efi_st_error("list_package_lists returned %u\n",
253                              (unsigned int)ret);
254                 goto out;
255         }
256         ret = boottime->allocate_pool(EFI_LOADER_DATA, handles_size,
257                                       (void **)&handles);
258         if (ret != EFI_SUCCESS) {
259                 efi_st_error("AllocatePool failed\n");
260                 goto out;
261         }
262         ret = hii_database_protocol->list_package_lists(hii_database_protocol,
263                         EFI_HII_PACKAGE_TYPE_GUID, &package_guid,
264                         &handles_size, handles);
265         if (ret != EFI_SUCCESS) {
266                 efi_st_error("list_package_lists returned %u\n",
267                              (unsigned int)ret);
268                 goto out;
269         }
270         ret = boottime->free_pool(handles);
271         if (ret != EFI_SUCCESS) {
272                 efi_st_error("FreePool failed\n");
273                 goto out;
274         }
275
276         /* KEYBOARD_LAYOUT */
277         handles = NULL;
278         handles_size = 0;
279         ret = hii_database_protocol->list_package_lists(hii_database_protocol,
280                         EFI_HII_PACKAGE_KEYBOARD_LAYOUT, NULL,
281                         &handles_size, handles);
282         if (ret != EFI_BUFFER_TOO_SMALL) {
283                 efi_st_error("list_package_lists returned %u\n",
284                              (unsigned int)ret);
285                 goto out;
286         }
287         ret = boottime->allocate_pool(EFI_LOADER_DATA, handles_size,
288                                       (void **)&handles);
289         if (ret != EFI_SUCCESS) {
290                 efi_st_error("AllocatePool failed\n");
291                 goto out;
292         }
293         ret = hii_database_protocol->list_package_lists(hii_database_protocol,
294                         EFI_HII_PACKAGE_KEYBOARD_LAYOUT, NULL,
295                         &handles_size, handles);
296         if (ret != EFI_SUCCESS) {
297                 efi_st_error("list_package_lists returned %u\n",
298                              (unsigned int)ret);
299                 goto out;
300         }
301         ret = boottime->free_pool(handles);
302         if (ret != EFI_SUCCESS) {
303                 efi_st_error("FreePool failed\n");
304                 goto out;
305         }
306
307         result = EFI_ST_SUCCESS;
308
309 out:
310         if (handle1) {
311                 ret = hii_database_protocol->remove_package_list(
312                                 hii_database_protocol, handle1);
313                 if (ret != EFI_SUCCESS)
314                         efi_st_error("remove_package_list returned %u\n",
315                                      (unsigned int)ret);
316         }
317         if (handle2) {
318                 ret = hii_database_protocol->remove_package_list(
319                                 hii_database_protocol, handle2);
320                 if (ret != EFI_SUCCESS)
321                         efi_st_error("remove_package_list returned %u\n",
322                                      (unsigned int)ret);
323         }
324
325         return result;
326 }
327
328 /**
329  * test_hii_database_export_package_lists() - test export of package lists
330  *
331  * @Return:     status code
332  */
333 static int test_hii_database_export_package_lists(void)
334 {
335         PRINT_TESTNAME;
336         /* export_package_lists() not implemented yet */
337         return EFI_ST_SUCCESS;
338 }
339
340 /**
341  * test_hii_database_register_package_notify() - test registration of
342  *      notification function
343  *
344  * @Return:     status code
345  */
346 static int test_hii_database_register_package_notify(void)
347 {
348         PRINT_TESTNAME;
349         /* register_package_notify() not implemented yet */
350         return EFI_ST_SUCCESS;
351 }
352
353 /**
354  * test_hii_database_unregister_package_notify() - test removal of
355  *      notification function
356  *
357  * @Return:     status code
358  */
359 static int test_hii_database_unregister_package_notify(void)
360 {
361         PRINT_TESTNAME;
362         /* unregsiter_package_notify() not implemented yet */
363         return EFI_ST_SUCCESS;
364 }
365
366 /**
367  * test_hii_database_find_keyboard_layouts() - test listing of
368  *      all the keyboard layouts in the system
369  *
370  * This test adds two package lists, each of which has two keyboard layouts
371  * and then tries to enumerate them. We will get an array of handles.
372  *
373  * @Return:     status code
374  */
375 static int test_hii_database_find_keyboard_layouts(void)
376 {
377         efi_hii_handle_t handle1 = NULL, handle2 = NULL;
378         efi_guid_t *guids;
379         u16 guids_size;
380         efi_status_t ret;
381         int result = EFI_ST_FAILURE;
382
383         PRINT_TESTNAME;
384         ret = hii_database_protocol->new_package_list(hii_database_protocol,
385                         (struct efi_hii_package_list_header *)packagelist1,
386                         NULL, &handle1);
387         if (ret != EFI_SUCCESS || !handle1) {
388                 efi_st_error("new_package_list returned %u\n",
389                              (unsigned int)ret);
390                 goto out;
391         }
392
393         ret = hii_database_protocol->new_package_list(hii_database_protocol,
394                         (struct efi_hii_package_list_header *)packagelist2,
395                         NULL, &handle2);
396         if (ret != EFI_SUCCESS || !handle2) {
397                 efi_st_error("new_package_list returned %u\n",
398                              (unsigned int)ret);
399                 goto out;
400         }
401
402         guids = NULL;
403         guids_size = 0;
404         ret = hii_database_protocol->find_keyboard_layouts(
405                         hii_database_protocol, &guids_size, guids);
406         if (ret != EFI_BUFFER_TOO_SMALL) {
407                 efi_st_error("find_keyboard_layouts returned %u\n",
408                              (unsigned int)ret);
409                 goto out;
410         }
411         ret = boottime->allocate_pool(EFI_LOADER_DATA, guids_size,
412                                       (void **)&guids);
413         if (ret != EFI_SUCCESS) {
414                 efi_st_error("AllocatePool failed\n");
415                 goto out;
416         }
417         ret = hii_database_protocol->find_keyboard_layouts(
418                         hii_database_protocol, &guids_size, guids);
419         if (ret != EFI_SUCCESS) {
420                 efi_st_error("find_keyboard_layouts returned %u\n",
421                              (unsigned int)ret);
422                 goto out;
423         }
424         ret = boottime->free_pool(guids);
425         if (ret != EFI_SUCCESS) {
426                 efi_st_error("FreePool failed\n");
427                 goto out;
428         }
429
430         result = EFI_ST_SUCCESS;
431
432 out:
433         if (handle1) {
434                 ret = hii_database_protocol->remove_package_list(
435                                 hii_database_protocol, handle1);
436                 if (ret != EFI_SUCCESS)
437                         efi_st_error("remove_package_list returned %u\n",
438                                      (unsigned int)ret);
439         }
440         if (handle2) {
441                 ret = hii_database_protocol->remove_package_list(
442                                 hii_database_protocol, handle2);
443                 if (ret != EFI_SUCCESS)
444                         efi_st_error("remove_package_list returned %u\n",
445                                      (unsigned int)ret);
446         }
447
448         return result;
449 }
450
451 /**
452  * test_hii_database_get_keyboard_layout() - test retrieval of keyboard layout
453  *
454  * This test adds two package lists, each of which has two keyboard layouts
455  * and then tries to get a handle to keyboard layout with a specific guid
456  * and the current one.
457  *
458  * @Return:     status code
459  */
460 static int test_hii_database_get_keyboard_layout(void)
461 {
462         efi_hii_handle_t handle1 = NULL, handle2 = NULL;
463         struct efi_hii_keyboard_layout *kb_layout;
464         u16 kb_layout_size;
465         efi_status_t ret;
466         int result = EFI_ST_FAILURE;
467
468         PRINT_TESTNAME;
469         ret = hii_database_protocol->new_package_list(hii_database_protocol,
470                         (struct efi_hii_package_list_header *)packagelist1,
471                         NULL, &handle1);
472         if (ret != EFI_SUCCESS || !handle1) {
473                 efi_st_error("new_package_list returned %u\n",
474                              (unsigned int)ret);
475                 goto out;
476         }
477
478         ret = hii_database_protocol->new_package_list(hii_database_protocol,
479                         (struct efi_hii_package_list_header *)packagelist2,
480                         NULL, &handle2);
481         if (ret != EFI_SUCCESS || !handle2) {
482                 efi_st_error("new_package_list returned %u\n",
483                              (unsigned int)ret);
484                 goto out;
485         }
486
487         /* specific keyboard_layout(guid11) */
488         kb_layout = NULL;
489         kb_layout_size = 0;
490         ret = hii_database_protocol->get_keyboard_layout(hii_database_protocol,
491                         &kb_layout_guid11, &kb_layout_size, kb_layout);
492         if (ret != EFI_BUFFER_TOO_SMALL) {
493                 efi_st_error("get_keyboard_layout returned %u\n",
494                              (unsigned int)ret);
495                 goto out;
496         }
497         ret = boottime->allocate_pool(EFI_LOADER_DATA, kb_layout_size,
498                                       (void **)&kb_layout);
499         if (ret != EFI_SUCCESS) {
500                 efi_st_error("AllocatePool failed\n");
501                 goto out;
502         }
503         ret = hii_database_protocol->get_keyboard_layout(hii_database_protocol,
504                         &kb_layout_guid11, &kb_layout_size, kb_layout);
505         if (ret != EFI_SUCCESS) {
506                 efi_st_error("get_keyboard_layout returned %u\n",
507                              (unsigned int)ret);
508                 goto out;
509         }
510         ret = boottime->free_pool(kb_layout);
511         if (ret != EFI_SUCCESS) {
512                 efi_st_error("FreePool failed\n");
513                 goto out;
514         }
515
516         /* current */
517         kb_layout = NULL;
518         kb_layout_size = 0;
519         ret = hii_database_protocol->get_keyboard_layout(hii_database_protocol,
520                         NULL, &kb_layout_size, kb_layout);
521         if (ret != EFI_INVALID_PARAMETER) {
522                 efi_st_error("get_keyboard_layout returned %u\n",
523                              (unsigned int)ret);
524                 goto out;
525         }
526
527         result = EFI_ST_SUCCESS;
528
529 out:
530         if (handle1) {
531                 ret = hii_database_protocol->remove_package_list(
532                                 hii_database_protocol, handle1);
533                 if (ret != EFI_SUCCESS)
534                         efi_st_error("remove_package_list returned %u\n",
535                                      (unsigned int)ret);
536         }
537         if (handle2) {
538                 ret = hii_database_protocol->remove_package_list(
539                                 hii_database_protocol, handle2);
540                 if (ret != EFI_SUCCESS)
541                         efi_st_error("remove_package_list returned %u\n",
542                                      (unsigned int)ret);
543         }
544
545         return result;
546 }
547
548 /**
549  * test_hii_database_set_keyboard_layout() - test change of
550  *      current keyboard layout
551  *
552  * @Return:     status code
553  */
554 static int test_hii_database_set_keyboard_layout(void)
555 {
556         efi_status_t ret;
557
558         PRINT_TESTNAME;
559
560         /* Invalid key guid. */
561         ret = hii_database_protocol->set_keyboard_layout(
562                         hii_database_protocol, NULL);
563         if (ret != EFI_INVALID_PARAMETER) {
564                 efi_st_error("set_keyboard_layout returned %u not invalid\n",
565                              (unsigned int)ret);
566                 return EFI_ST_FAILURE;
567         }
568
569         /* set_keyboard_layout() not implemented yet */
570         return EFI_ST_SUCCESS;
571 }
572
573 /**
574  * test_hii_database_get_package_list_handle() - test retrieval of
575  *      driver associated with a package list
576  *
577  * This test adds a package list, and then tries to get a handle to driver
578  * which is associated with a package list.
579  *
580  * @Return:     status code
581  */
582 static int test_hii_database_get_package_list_handle(void)
583 {
584         efi_hii_handle_t handle = NULL;
585         efi_handle_t driver_handle;
586         efi_status_t ret;
587         int result = EFI_ST_FAILURE;
588
589         PRINT_TESTNAME;
590         driver_handle = (efi_handle_t)0x12345678; /* dummy */
591         ret = hii_database_protocol->new_package_list(hii_database_protocol,
592                         (struct efi_hii_package_list_header *)packagelist1,
593                         driver_handle, &handle);
594         if (ret != EFI_SUCCESS || !handle) {
595                 efi_st_error("new_package_list returned %u\n",
596                              (unsigned int)ret);
597                 return EFI_ST_FAILURE;
598         }
599
600         driver_handle = NULL;
601         ret = hii_database_protocol->get_package_list_handle(
602                         hii_database_protocol, handle, &driver_handle);
603         if (ret != EFI_SUCCESS || driver_handle != (efi_handle_t)0x12345678) {
604                 efi_st_error("get_package_list_handle returned %u, driver:%p\n",
605                              (unsigned int)ret, driver_handle);
606                 goto out;
607         }
608
609         result = EFI_ST_SUCCESS;
610
611 out:
612         if (handle) {
613                 ret = hii_database_protocol->remove_package_list(
614                                 hii_database_protocol, handle);
615                 if (ret != EFI_SUCCESS) {
616                         efi_st_error("remove_package_list returned %u\n",
617                                      (unsigned int)ret);
618                         return EFI_ST_FAILURE;
619                 }
620         }
621
622         return result;
623 }
624
625 static int test_hii_database_protocol(void)
626 {
627         int ret;
628
629         ret = test_hii_database_new_package_list();
630         if (ret != EFI_ST_SUCCESS)
631                 return EFI_ST_FAILURE;
632
633         ret = test_hii_database_update_package_list();
634         if (ret != EFI_ST_SUCCESS)
635                 return EFI_ST_FAILURE;
636
637         ret = test_hii_database_list_package_lists();
638         if (ret != EFI_ST_SUCCESS)
639                 return EFI_ST_FAILURE;
640
641         ret = test_hii_database_export_package_lists();
642         if (ret != EFI_ST_SUCCESS)
643                 return EFI_ST_FAILURE;
644
645         ret = test_hii_database_register_package_notify();
646         if (ret != EFI_ST_SUCCESS)
647                 return EFI_ST_FAILURE;
648
649         ret = test_hii_database_unregister_package_notify();
650         if (ret != EFI_ST_SUCCESS)
651                 return EFI_ST_FAILURE;
652
653         ret = test_hii_database_find_keyboard_layouts();
654         if (ret != EFI_ST_SUCCESS)
655                 return EFI_ST_FAILURE;
656
657         ret = test_hii_database_get_keyboard_layout();
658         if (ret != EFI_ST_SUCCESS)
659                 return EFI_ST_FAILURE;
660
661         ret = test_hii_database_set_keyboard_layout();
662         if (ret != EFI_ST_SUCCESS)
663                 return EFI_ST_FAILURE;
664
665         ret = test_hii_database_get_package_list_handle();
666         if (ret != EFI_ST_SUCCESS)
667                 return EFI_ST_FAILURE;
668
669         return EFI_ST_SUCCESS;
670 }
671
672 /*
673  * HII string protocol tests
674  */
675
676 /**
677  * test_hii_string_new_string() - test creation of a new string entry
678  *
679  * This test adds a package list, and then tries to add a new string
680  * entry for a specific language.
681  *
682  * @Return:     status code
683  */
684 static int test_hii_string_new_string(void)
685 {
686         efi_hii_handle_t handle = NULL;
687         efi_string_id_t id;
688         efi_status_t ret;
689         int result = EFI_ST_FAILURE;
690
691         PRINT_TESTNAME;
692         ret = hii_database_protocol->new_package_list(hii_database_protocol,
693                         (struct efi_hii_package_list_header *)packagelist1,
694                         NULL, &handle);
695         if (ret != EFI_SUCCESS || !handle) {
696                 efi_st_error("new_package_list returned %u\n",
697                              (unsigned int)ret);
698                 return EFI_ST_FAILURE;
699         }
700
701         ret = hii_string_protocol->new_string(hii_string_protocol, handle,
702                                               &id, (u8 *)"en-US",
703                                               u"Japanese", u"Japanese", NULL);
704         if (ret != EFI_SUCCESS) {
705                 efi_st_error("new_string returned %u\n",
706                              (unsigned int)ret);
707                 goto out;
708         }
709         efi_st_printf("new string id is %u\n", id);
710
711         result = EFI_ST_SUCCESS;
712
713 out:
714         if (handle) {
715                 ret = hii_database_protocol->remove_package_list(
716                                 hii_database_protocol, handle);
717                 if (ret != EFI_SUCCESS) {
718                         efi_st_error("remove_package_list returned %u\n",
719                                      (unsigned int)ret);
720                         return EFI_ST_FAILURE;
721                 }
722         }
723
724         return result;
725 }
726
727 /**
728  * test_hii_string_get_string() - test retrieval of a string entry
729  *
730  * This test adds a package list, create a new string entry and then tries
731  * to get it with its string id.
732  *
733  * @Return:     status code
734  */
735 static int test_hii_string_get_string(void)
736 {
737         efi_hii_handle_t handle = NULL;
738         efi_string_id_t id;
739         efi_string_t string;
740         efi_uintn_t string_len;
741         efi_status_t ret;
742         int result = EFI_ST_FAILURE;
743
744         PRINT_TESTNAME;
745         ret = hii_database_protocol->new_package_list(hii_database_protocol,
746                         (struct efi_hii_package_list_header *)packagelist1,
747                         NULL, &handle);
748         if (ret != EFI_SUCCESS || !handle) {
749                 efi_st_error("new_package_list returned %u\n",
750                              (unsigned int)ret);
751                 return EFI_ST_FAILURE;
752         }
753
754         ret = hii_string_protocol->new_string(hii_string_protocol, handle,
755                                               &id, (u8 *)"en-US",
756                                               u"Japanese", u"Japanese", NULL);
757         if (ret != EFI_SUCCESS) {
758                 efi_st_error("new_string returned %u\n",
759                              (unsigned int)ret);
760                 goto out;
761         }
762
763         string = NULL;
764         string_len = 0;
765         ret = hii_string_protocol->get_string(hii_string_protocol,
766                         (u8 *)"en-US", handle, id, string, &string_len, NULL);
767         if (ret != EFI_BUFFER_TOO_SMALL) {
768                 efi_st_error("get_string returned %u\n",
769                              (unsigned int)ret);
770                 goto out;
771         }
772         string_len += sizeof(u16);
773         ret = boottime->allocate_pool(EFI_LOADER_DATA, string_len,
774                                       (void **)&string);
775         if (ret != EFI_SUCCESS) {
776                 efi_st_error("AllocatePool failed\n");
777                 goto out;
778         }
779         ret = hii_string_protocol->get_string(hii_string_protocol,
780                         (u8 *)"en-US", handle, id, string, &string_len, NULL);
781         if (ret != EFI_SUCCESS) {
782                 efi_st_error("get_string returned %u\n",
783                              (unsigned int)ret);
784                 goto out;
785         }
786
787         if (efi_st_strcmp_16_8(string, "Japanese")) {
788                 efi_st_error("get_string returned incorrect string\n");
789                 goto out;
790         }
791
792         result = EFI_ST_SUCCESS;
793
794 out:
795         if (handle) {
796                 ret = hii_database_protocol->remove_package_list(
797                                 hii_database_protocol, handle);
798                 if (ret != EFI_SUCCESS) {
799                         efi_st_error("remove_package_list returned %u\n",
800                                      (unsigned int)ret);
801                         return EFI_ST_FAILURE;
802                 }
803         }
804
805         return result;
806 }
807
808 /**
809  * test_hii_string_set_string() - test change of a string entry
810  *
811  * This test adds a package list, create a new string entry and then tries
812  * to modify it.
813  *
814  * @Return:     status code
815  */
816 static int test_hii_string_set_string(void)
817 {
818         efi_hii_handle_t handle = NULL;
819         efi_string_id_t id;
820         efi_status_t ret;
821         int result = EFI_ST_FAILURE;
822
823         PRINT_TESTNAME;
824         ret = hii_database_protocol->new_package_list(hii_database_protocol,
825                         (struct efi_hii_package_list_header *)packagelist1,
826                         NULL, &handle);
827         if (ret != EFI_SUCCESS || !handle) {
828                 efi_st_error("new_package_list returned %u\n",
829                              (unsigned int)ret);
830                 return EFI_ST_FAILURE;
831         }
832
833         ret = hii_string_protocol->new_string(hii_string_protocol, handle,
834                                               &id, (u8 *)"en-US",
835                                               u"Japanese", u"Japanese", NULL);
836         if (ret != EFI_SUCCESS) {
837                 efi_st_error("new_string returned %u\n",
838                              (unsigned int)ret);
839                 goto out;
840         }
841
842         ret = hii_string_protocol->set_string(hii_string_protocol, handle,
843                                               id, (u8 *)"en-US",
844                                               u"Nihongo", NULL);
845         if (ret != EFI_SUCCESS) {
846                 efi_st_error("set_string returned %u\n",
847                              (unsigned int)ret);
848                 goto out;
849         }
850
851         result = EFI_ST_SUCCESS;
852
853 out:
854         if (handle) {
855                 ret = hii_database_protocol->remove_package_list(
856                                 hii_database_protocol, handle);
857                 if (ret != EFI_SUCCESS) {
858                         efi_st_error("remove_package_list returned %u\n",
859                                      (unsigned int)ret);
860                         return EFI_ST_FAILURE;
861                 }
862         }
863
864         return result;
865 }
866
867 /**
868  * test_hii_string_get_languages() - test listing of languages
869  *
870  * This test adds a package list, and then tries to enumerate languages
871  * in it. We will get an string of language names.
872  *
873  * @Return:     status code
874  */
875 static int test_hii_string_get_languages(void)
876 {
877         efi_hii_handle_t handle = NULL;
878         u8 *languages;
879         efi_uintn_t languages_len;
880         efi_status_t ret;
881         int result = EFI_ST_FAILURE;
882
883         PRINT_TESTNAME;
884         ret = hii_database_protocol->new_package_list(hii_database_protocol,
885                         (struct efi_hii_package_list_header *)packagelist1,
886                         NULL, &handle);
887         if (ret != EFI_SUCCESS || !handle) {
888                 efi_st_error("new_package_list returned %u\n",
889                              (unsigned int)ret);
890                 return EFI_ST_FAILURE;
891         }
892
893         languages = NULL;
894         languages_len = 0;
895         ret = hii_string_protocol->get_languages(hii_string_protocol, handle,
896                         languages, &languages_len);
897         if (ret != EFI_BUFFER_TOO_SMALL) {
898                 efi_st_error("get_languages returned %u\n",
899                              (unsigned int)ret);
900                 goto out;
901         }
902         ret = boottime->allocate_pool(EFI_LOADER_DATA, languages_len,
903                                       (void **)&languages);
904         if (ret != EFI_SUCCESS) {
905                 efi_st_error("AllocatePool failed\n");
906                 goto out;
907         }
908         ret = hii_string_protocol->get_languages(hii_string_protocol, handle,
909                         languages, &languages_len);
910         if (ret != EFI_SUCCESS) {
911                 efi_st_error("get_languages returned %u\n",
912                              (unsigned int)ret);
913                 goto out;
914         }
915
916         efi_st_printf("got languages are %s\n", languages);
917
918         result = EFI_ST_SUCCESS;
919
920 out:
921         if (handle) {
922                 ret = hii_database_protocol->remove_package_list(
923                                 hii_database_protocol, handle);
924                 if (ret != EFI_SUCCESS) {
925                         efi_st_error("remove_package_list returned %u\n",
926                                      (unsigned int)ret);
927                         return EFI_ST_FAILURE;
928                 }
929         }
930
931         return result;
932 }
933
934 /**
935  * test_hii_string_get_secondary_languages() - test listing of secondary
936  *      languages
937  *
938  * This test adds a package list, and then tries to enumerate secondary
939  * languages with a specific language. We will get an string of language names.
940  *
941  * @Return:     status code
942  */
943 static int test_hii_string_get_secondary_languages(void)
944 {
945         efi_hii_handle_t handle = NULL;
946         u8 *languages;
947         efi_uintn_t languages_len;
948         efi_status_t ret;
949         int result = EFI_ST_FAILURE;
950
951         PRINT_TESTNAME;
952         ret = hii_database_protocol->new_package_list(hii_database_protocol,
953                         (struct efi_hii_package_list_header *)packagelist1,
954                         NULL, &handle);
955         if (ret != EFI_SUCCESS || !handle) {
956                 efi_st_error("new_package_list returned %u\n",
957                              (unsigned int)ret);
958                 return EFI_ST_FAILURE;
959         }
960
961         languages = NULL;
962         languages_len = 0;
963         ret = hii_string_protocol->get_secondary_languages(hii_string_protocol,
964                         handle, (u8 *)"en-US", languages, &languages_len);
965         if (ret == EFI_NOT_FOUND) {
966                 efi_st_printf("no secondary languages\n");
967                 result = EFI_ST_SUCCESS;
968                 goto out;
969         }
970         if (ret != EFI_BUFFER_TOO_SMALL) {
971                 efi_st_error("get_secondary_languages returned %u\n",
972                              (unsigned int)ret);
973                 goto out;
974         }
975         ret = boottime->allocate_pool(EFI_LOADER_DATA, languages_len,
976                                       (void **)&languages);
977         if (ret != EFI_SUCCESS) {
978                 efi_st_error("AllocatePool failed\n");
979                 goto out;
980         }
981         ret = hii_string_protocol->get_secondary_languages(hii_string_protocol,
982                         handle, (u8 *)"en-US", languages, &languages_len);
983         if (ret != EFI_SUCCESS) {
984                 efi_st_error("get_secondary_languages returned %u\n",
985                              (unsigned int)ret);
986                 goto out;
987         }
988
989         efi_st_printf("got secondary languages are %s\n", languages);
990
991         result = EFI_ST_SUCCESS;
992
993 out:
994         if (handle) {
995                 ret = hii_database_protocol->remove_package_list(
996                                 hii_database_protocol, handle);
997                 if (ret != EFI_SUCCESS) {
998                         efi_st_error("remove_package_list returned %u\n",
999                                      (unsigned int)ret);
1000                         return EFI_ST_FAILURE;
1001                 }
1002         }
1003
1004         return result;
1005 }
1006
1007 static int test_hii_string_protocol(void)
1008 {
1009         int ret;
1010
1011         ret = test_hii_string_new_string();
1012         if (ret != EFI_ST_SUCCESS)
1013                 return EFI_ST_FAILURE;
1014
1015         ret = test_hii_string_get_string();
1016         if (ret != EFI_ST_SUCCESS)
1017                 return EFI_ST_FAILURE;
1018
1019         ret = test_hii_string_set_string();
1020         if (ret != EFI_ST_SUCCESS)
1021                 return EFI_ST_FAILURE;
1022
1023         ret = test_hii_string_get_languages();
1024         if (ret != EFI_ST_SUCCESS)
1025                 return EFI_ST_FAILURE;
1026
1027         ret = test_hii_string_get_secondary_languages();
1028         if (ret != EFI_ST_SUCCESS)
1029                 return EFI_ST_FAILURE;
1030
1031         return EFI_ST_SUCCESS;
1032 }
1033
1034 /*
1035  * Execute unit test.
1036  *
1037  * Return:      EFI_ST_SUCCESS for success, EFI_ST_FAILURE for failure
1038  */
1039 static int execute(void)
1040 {
1041         int ret;
1042
1043         /* HII database protocol */
1044         ret = test_hii_database_protocol();
1045         if (ret != EFI_ST_SUCCESS)
1046                 return EFI_ST_FAILURE;
1047
1048         /* HII string protocol */
1049         ret = test_hii_string_protocol();
1050         if (ret != EFI_ST_SUCCESS)
1051                 return EFI_ST_FAILURE;
1052
1053         return EFI_ST_SUCCESS;
1054 }
1055
1056 EFI_UNIT_TEST(hii) = {
1057         .name = "HII database protocols",
1058         .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
1059         .setup = setup,
1060         .execute = execute,
1061 };