1
2
3
4
5
6
7
8
9
10
11
12#include <efi_selftest.h>
13
14static struct efi_boot_services *boottime;
15static struct efi_event *event_notify;
16static unsigned int notification_count;
17
18
19
20
21
22
23
24static void EFIAPI notify(struct efi_event *event, void *context)
25{
26 unsigned int *count = context;
27
28 ++*count;
29}
30
31
32
33
34
35
36
37
38
39
40static 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 *)¬ification_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
61
62
63
64
65
66static 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
83
84
85
86
87
88
89
90
91
92static 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
106EFI_UNIT_TEST(exitbootservices) = {
107 .name = "ExitBootServices",
108 .phase = EFI_SETUP_BEFORE_BOOTTIME_EXIT,
109 .setup = setup,
110 .execute = execute,
111 .teardown = teardown,
112};
113