]> git.sur5r.net Git - u-boot/blob - lib/efi_selftest/efi_selftest_exitbootservices.c
efi_loader: no support for ARMV7_NONSEC=y
[u-boot] / lib / efi_selftest / efi_selftest_exitbootservices.c
1 /*
2  * efi_selftest_exitbootservices
3  *
4  * Copyright (c) 2017 Heinrich Schuchardt <xypron.glpk@gmx.de>
5  *
6  * SPDX-License-Identifier:     GPL-2.0+
7  *
8  * This unit test checks that the notification function of an
9  * EVT_SIGNAL_EXIT_BOOT_SERVICES event is called exactly once.
10  */
11
12 #include <efi_selftest.h>
13
14 static struct efi_boot_services *boottime;
15 static struct efi_event *event_notify;
16 static unsigned int notification_count;
17
18 /*
19  * Notification function, increments the notification count.
20  *
21  * @event       notified event
22  * @context     pointer to the notification count
23  */
24 static void EFIAPI notify(struct efi_event *event, void *context)
25 {
26         unsigned int *count = context;
27
28         ++*count;
29 }
30
31 /*
32  * Setup unit test.
33  *
34  * Create an EVT_SIGNAL_EXIT_BOOT_SERVICES event.
35  *
36  * @handle:     handle of the loaded image
37  * @systable:   system table
38  * @return:     EFI_ST_SUCCESS for success
39  */
40 static int setup(const efi_handle_t handle,
41                  const struct efi_system_table *systable)
42 {
43         efi_status_t ret;
44
45         boottime = systable->boottime;
46
47         notification_count = 0;
48         ret = boottime->create_event(EVT_SIGNAL_EXIT_BOOT_SERVICES,
49                                      TPL_CALLBACK, notify,
50                                      (void *)&notification_count,
51                                      &event_notify);
52         if (ret != EFI_SUCCESS) {
53                 efi_st_error("could not create event\n");
54                 return EFI_ST_FAILURE;
55         }
56         return EFI_ST_SUCCESS;
57 }
58
59 /*
60  * Tear down unit test.
61  *
62  * Close the event created in setup.
63  *
64  * @return:     EFI_ST_SUCCESS for success
65  */
66 static int teardown(void)
67 {
68         efi_status_t ret;
69
70         if (event_notify) {
71                 ret = boottime->close_event(event_notify);
72                 event_notify = NULL;
73                 if (ret != EFI_SUCCESS) {
74                         efi_st_error("could not close event\n");
75                         return EFI_ST_FAILURE;
76                 }
77         }
78         return EFI_ST_SUCCESS;
79 }
80
81 /*
82  * Execute unit test.
83  *
84  * Check that the notification function of the EVT_SIGNAL_EXIT_BOOT_SERVICES
85  * event has been called.
86  *
87  * Call ExitBootServices again and check that the notification function is
88  * not called again.
89  *
90  * @return:     EFI_ST_SUCCESS for success
91  */
92 static int execute(void)
93 {
94         if (notification_count != 1) {
95                 efi_st_error("ExitBootServices was not notified\n");
96                 return EFI_ST_FAILURE;
97         }
98         efi_st_exit_boot_services();
99         if (notification_count != 1) {
100                 efi_st_error("ExitBootServices was notified twice\n");
101                 return EFI_ST_FAILURE;
102         }
103         return EFI_ST_SUCCESS;
104 }
105
106 EFI_UNIT_TEST(exitbootservices) = {
107         .name = "ExitBootServices",
108         .phase = EFI_SETUP_BEFORE_BOOTTIME_EXIT,
109         .setup = setup,
110         .execute = execute,
111         .teardown = teardown,
112 };