Blame view
lib/efi_selftest/efi_selftest_events.c
5.15 KB
bd126692d efi_selftest: pro... |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
/* * efi_selftest_events * * Copyright (c) 2017 Heinrich Schuchardt <xypron.glpk@gmx.de> * * SPDX-License-Identifier: GPL-2.0+ * * This unit test uses timer events to check the implementation * of the following boottime services: * CreateEvent, CloseEvent, WaitForEvent, CheckEvent, SetTimer. */ #include <efi_selftest.h> static struct efi_event *event_notify; static struct efi_event *event_wait; |
e67e7249c efi_selftest: mak... |
17 |
static unsigned int timer_ticks; |
bd126692d efi_selftest: pro... |
18 19 20 |
static struct efi_boot_services *boottime; /* |
e67e7249c efi_selftest: mak... |
21 22 |
* Notification function, increments the notfication count if parameter * context is provided. |
bd126692d efi_selftest: pro... |
23 24 |
* * @event notified event |
e67e7249c efi_selftest: mak... |
25 |
* @context pointer to the notification count |
bd126692d efi_selftest: pro... |
26 27 28 |
*/ static void EFIAPI notify(struct efi_event *event, void *context) { |
e67e7249c efi_selftest: mak... |
29 30 31 32 |
unsigned int *count = context; if (count) ++*count; |
bd126692d efi_selftest: pro... |
33 34 35 36 37 38 39 40 41 42 |
} /* * Setup unit test. * * Create two timer events. * One with EVT_NOTIFY_SIGNAL, the other with EVT_NOTIFY_WAIT. * * @handle: handle of the loaded image * @systable: system table |
e67e7249c efi_selftest: mak... |
43 |
* @return: EFI_ST_SUCCESS for success |
bd126692d efi_selftest: pro... |
44 45 46 47 48 49 50 51 52 |
*/ static int setup(const efi_handle_t handle, const struct efi_system_table *systable) { efi_status_t ret; boottime = systable->boottime; ret = boottime->create_event(EVT_TIMER | EVT_NOTIFY_SIGNAL, |
e67e7249c efi_selftest: mak... |
53 |
TPL_CALLBACK, notify, (void *)&timer_ticks, |
bd126692d efi_selftest: pro... |
54 55 56 57 |
&event_notify); if (ret != EFI_SUCCESS) { efi_st_error("could not create event "); |
e67e7249c efi_selftest: mak... |
58 |
return EFI_ST_FAILURE; |
bd126692d efi_selftest: pro... |
59 60 61 62 63 64 |
} ret = boottime->create_event(EVT_TIMER | EVT_NOTIFY_WAIT, TPL_CALLBACK, notify, NULL, &event_wait); if (ret != EFI_SUCCESS) { efi_st_error("could not create event "); |
e67e7249c efi_selftest: mak... |
65 |
return EFI_ST_FAILURE; |
bd126692d efi_selftest: pro... |
66 |
} |
e67e7249c efi_selftest: mak... |
67 |
return EFI_ST_SUCCESS; |
bd126692d efi_selftest: pro... |
68 69 70 71 72 73 |
} /* * Tear down unit test. * * Close the events created in setup. |
e67e7249c efi_selftest: mak... |
74 75 |
* * @return: EFI_ST_SUCCESS for success |
bd126692d efi_selftest: pro... |
76 77 78 79 80 81 82 83 84 85 86 |
*/ static int teardown(void) { efi_status_t ret; if (event_notify) { ret = boottime->close_event(event_notify); event_notify = NULL; if (ret != EFI_SUCCESS) { efi_st_error("could not close event "); |
e67e7249c efi_selftest: mak... |
87 |
return EFI_ST_FAILURE; |
bd126692d efi_selftest: pro... |
88 89 90 91 92 93 94 95 |
} } if (event_wait) { ret = boottime->close_event(event_wait); event_wait = NULL; if (ret != EFI_SUCCESS) { efi_st_error("could not close event "); |
e67e7249c efi_selftest: mak... |
96 |
return EFI_ST_FAILURE; |
bd126692d efi_selftest: pro... |
97 98 |
} } |
e67e7249c efi_selftest: mak... |
99 |
return EFI_ST_SUCCESS; |
bd126692d efi_selftest: pro... |
100 101 102 103 104 105 106 107 108 109 |
} /* * Execute unit test. * * Run a 10 ms periodic timer and check that it is called 10 times * while waiting for 100 ms single shot timer. * * Run a 100 ms single shot timer and check that it is called once * while waiting for 100 ms periodic timer for two periods. |
e67e7249c efi_selftest: mak... |
110 111 |
* * @return: EFI_ST_SUCCESS for success |
bd126692d efi_selftest: pro... |
112 113 114 |
*/ static int execute(void) { |
f5a2a9389 efi_loader: consi... |
115 |
efi_uintn_t index; |
bd126692d efi_selftest: pro... |
116 117 118 |
efi_status_t ret; /* Set 10 ms timer */ |
e67e7249c efi_selftest: mak... |
119 |
timer_ticks = 0; |
bd126692d efi_selftest: pro... |
120 121 122 123 |
ret = boottime->set_timer(event_notify, EFI_TIMER_PERIODIC, 100000); if (ret != EFI_SUCCESS) { efi_st_error("Could not set timer "); |
e67e7249c efi_selftest: mak... |
124 |
return EFI_ST_FAILURE; |
bd126692d efi_selftest: pro... |
125 126 127 128 129 130 |
} /* Set 100 ms timer */ ret = boottime->set_timer(event_wait, EFI_TIMER_RELATIVE, 1000000); if (ret != EFI_SUCCESS) { efi_st_error("Could not set timer "); |
e67e7249c efi_selftest: mak... |
131 |
return EFI_ST_FAILURE; |
bd126692d efi_selftest: pro... |
132 |
} |
e67e7249c efi_selftest: mak... |
133 |
/* Set some arbitrary non-zero value to make change detectable. */ |
bd126692d efi_selftest: pro... |
134 135 136 137 138 |
index = 5; ret = boottime->wait_for_event(1, &event_wait, &index); if (ret != EFI_SUCCESS) { efi_st_error("Could not wait for event "); |
e67e7249c efi_selftest: mak... |
139 |
return EFI_ST_FAILURE; |
bd126692d efi_selftest: pro... |
140 141 142 143 144 145 146 |
} ret = boottime->check_event(event_wait); if (ret != EFI_NOT_READY) { efi_st_error("Signaled state was not cleared. "); efi_st_printf("ret = %u ", (unsigned int)ret); |
e67e7249c efi_selftest: mak... |
147 |
return EFI_ST_FAILURE; |
bd126692d efi_selftest: pro... |
148 149 150 151 |
} if (index != 0) { efi_st_error("WaitForEvent returned wrong index "); |
e67e7249c efi_selftest: mak... |
152 |
return EFI_ST_FAILURE; |
bd126692d efi_selftest: pro... |
153 |
} |
e67e7249c efi_selftest: mak... |
154 |
if (timer_ticks < 8 || timer_ticks > 12) { |
ad50dcf8c efi_selftest: avo... |
155 156 |
efi_st_printf("Notification count periodic: %u ", timer_ticks); |
bd126692d efi_selftest: pro... |
157 158 |
efi_st_error("Incorrect timing of events "); |
e67e7249c efi_selftest: mak... |
159 |
return EFI_ST_FAILURE; |
bd126692d efi_selftest: pro... |
160 161 162 163 164 |
} ret = boottime->set_timer(event_notify, EFI_TIMER_STOP, 0); if (index != 0) { efi_st_error("Could not cancel timer "); |
e67e7249c efi_selftest: mak... |
165 |
return EFI_ST_FAILURE; |
bd126692d efi_selftest: pro... |
166 167 |
} /* Set 10 ms timer */ |
e67e7249c efi_selftest: mak... |
168 |
timer_ticks = 0; |
bd126692d efi_selftest: pro... |
169 170 171 172 |
ret = boottime->set_timer(event_notify, EFI_TIMER_RELATIVE, 100000); if (index != 0) { efi_st_error("Could not set timer "); |
e67e7249c efi_selftest: mak... |
173 |
return EFI_ST_FAILURE; |
bd126692d efi_selftest: pro... |
174 175 176 177 178 179 |
} /* Set 100 ms timer */ ret = boottime->set_timer(event_wait, EFI_TIMER_PERIODIC, 1000000); if (index != 0) { efi_st_error("Could not set timer "); |
e67e7249c efi_selftest: mak... |
180 |
return EFI_ST_FAILURE; |
bd126692d efi_selftest: pro... |
181 182 183 184 185 |
} ret = boottime->wait_for_event(1, &event_wait, &index); if (ret != EFI_SUCCESS) { efi_st_error("Could not wait for event "); |
e67e7249c efi_selftest: mak... |
186 |
return EFI_ST_FAILURE; |
bd126692d efi_selftest: pro... |
187 |
} |
e67e7249c efi_selftest: mak... |
188 |
if (timer_ticks != 1) { |
ad50dcf8c efi_selftest: avo... |
189 190 191 |
efi_st_printf("Notification count single shot: %u ", timer_ticks); |
bd126692d efi_selftest: pro... |
192 193 |
efi_st_error("Single shot timer failed "); |
e67e7249c efi_selftest: mak... |
194 |
return EFI_ST_FAILURE; |
bd126692d efi_selftest: pro... |
195 196 197 198 199 |
} ret = boottime->wait_for_event(1, &event_wait, &index); if (ret != EFI_SUCCESS) { efi_st_error("Could not wait for event "); |
e67e7249c efi_selftest: mak... |
200 |
return EFI_ST_FAILURE; |
bd126692d efi_selftest: pro... |
201 |
} |
e67e7249c efi_selftest: mak... |
202 |
if (timer_ticks != 1) { |
ad50dcf8c efi_selftest: avo... |
203 204 205 |
efi_st_printf("Notification count stopped timer: %u ", timer_ticks); |
bd126692d efi_selftest: pro... |
206 207 |
efi_st_error("Stopped timer fired "); |
e67e7249c efi_selftest: mak... |
208 |
return EFI_ST_FAILURE; |
bd126692d efi_selftest: pro... |
209 210 |
} ret = boottime->set_timer(event_wait, EFI_TIMER_STOP, 0); |
abe994633 efi_selftest: cor... |
211 |
if (ret != EFI_SUCCESS) { |
bd126692d efi_selftest: pro... |
212 213 |
efi_st_error("Could not cancel timer "); |
e67e7249c efi_selftest: mak... |
214 |
return EFI_ST_FAILURE; |
bd126692d efi_selftest: pro... |
215 |
} |
e67e7249c efi_selftest: mak... |
216 |
return EFI_ST_SUCCESS; |
bd126692d efi_selftest: pro... |
217 218 219 220 221 222 223 224 225 |
} EFI_UNIT_TEST(events) = { .name = "event services", .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT, .setup = setup, .execute = execute, .teardown = teardown, }; |