1 /*++
2
3 Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 Event.c
15
16 Abstract:
17
18 Support for Event lib fucntions.
19
20 --*/
21
22 #include "Tiano.h"
23 #include "EfiRuntimeLib.h"
24
25 EFI_EVENT
RtEfiLibCreateProtocolNotifyEvent(IN EFI_GUID * ProtocolGuid,IN EFI_TPL NotifyTpl,IN EFI_EVENT_NOTIFY NotifyFunction,IN VOID * NotifyContext,OUT VOID ** Registration)26 RtEfiLibCreateProtocolNotifyEvent (
27 IN EFI_GUID *ProtocolGuid,
28 IN EFI_TPL NotifyTpl,
29 IN EFI_EVENT_NOTIFY NotifyFunction,
30 IN VOID *NotifyContext,
31 OUT VOID **Registration
32 )
33 /*++
34
35 Routine Description:
36
37 Create a protocol notification event and return it.
38
39 Arguments:
40
41 ProtocolGuid - Protocol to register notification event on.
42
43 NotifyTpl - Maximum TPL to single the NotifyFunction.
44
45 NotifyFunction - EFI notification routine.
46
47 NotifyContext - Context passed into Event when it is created.
48
49 Registration - Registration key returned from RegisterProtocolNotify().
50
51 Returns:
52
53 The EFI_EVENT that has been registered to be signaled when a ProtocolGuid
54 is added to the system.
55
56 --*/
57 {
58 EFI_STATUS Status;
59 EFI_EVENT Event;
60
61 //
62 // Create the event
63 //
64 Status = gBS->CreateEvent (
65 EFI_EVENT_NOTIFY_SIGNAL,
66 NotifyTpl,
67 NotifyFunction,
68 NotifyContext,
69 &Event
70 );
71 ASSERT (!EFI_ERROR (Status));
72
73 //
74 // Register for protocol notifactions on this event
75 //
76 Status = gBS->RegisterProtocolNotify (
77 ProtocolGuid,
78 Event,
79 Registration
80 );
81
82 ASSERT (!EFI_ERROR (Status));
83
84 //
85 // Kick the event so we will perform an initial pass of
86 // current installed drivers
87 //
88 gBS->SignalEvent (Event);
89 return Event;
90 }
91
92 EFI_STATUS
EfiLibGetSystemConfigurationTable(IN EFI_GUID * TableGuid,IN OUT VOID ** Table)93 EfiLibGetSystemConfigurationTable (
94 IN EFI_GUID *TableGuid,
95 IN OUT VOID **Table
96 )
97 /*++
98
99 Routine Description:
100
101 Return the EFI 1.0 System Tabl entry with TableGuid
102
103 Arguments:
104
105 TableGuid - Name of entry to return in the system table
106 Table - Pointer in EFI system table associated with TableGuid
107
108 Returns:
109
110 EFI_SUCCESS - Table returned;
111 EFI_NOT_FOUND - TableGuid not in EFI system table
112
113 --*/
114 {
115 UINTN Index;
116
117 for (Index = 0; Index < gST->NumberOfTableEntries; Index++) {
118 if (EfiCompareGuid (TableGuid, &(gST->ConfigurationTable[Index].VendorGuid))) {
119 *Table = gST->ConfigurationTable[Index].VendorTable;
120 return EFI_SUCCESS;
121 }
122 }
123
124 return EFI_NOT_FOUND;
125 }
126
127 EFI_STATUS
EfiConvertList(IN UINTN DebugDisposition,IN OUT EFI_LIST_ENTRY * ListHead)128 EfiConvertList (
129 IN UINTN DebugDisposition,
130 IN OUT EFI_LIST_ENTRY *ListHead
131 )
132 /*++
133
134 Routine Description:
135
136 Conver the standard Lib double linked list to a virtual mapping.
137
138 Arguments:
139
140 DebugDisposition - Argument to EfiConvertPointer (EFI 1.0 API)
141
142 ListHead - Head of linked list to convert
143
144 Returns:
145
146 EFI_SUCCESS
147
148 --*/
149 {
150 EFI_LIST_ENTRY *Link;
151 EFI_LIST_ENTRY *NextLink;
152
153 //
154 // Convert all the ForwardLink & BackLink pointers in the list
155 //
156 Link = ListHead;
157 do {
158 NextLink = Link->ForwardLink;
159
160 EfiConvertPointer (
161 Link->ForwardLink == ListHead ? DebugDisposition : 0,
162 (VOID **) &Link->ForwardLink
163 );
164
165 EfiConvertPointer (
166 Link->BackLink == ListHead ? DebugDisposition : 0,
167 (VOID **) &Link->BackLink
168 );
169
170 Link = NextLink;
171 } while (Link != ListHead);
172 return EFI_SUCCESS;
173 }
174
175 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
176
177 STATIC
178 VOID
179 EFIAPI
EventNotifySignalAllNullEvent(IN EFI_EVENT Event,IN VOID * Context)180 EventNotifySignalAllNullEvent (
181 IN EFI_EVENT Event,
182 IN VOID *Context
183 )
184 {
185 //
186 // This null event is a size efficent way to enusre that
187 // EFI_EVENT_NOTIFY_SIGNAL_ALL is error checked correctly.
188 // EFI_EVENT_NOTIFY_SIGNAL_ALL is now mapped into
189 // CreateEventEx() and this function is used to make the
190 // old error checking in CreateEvent() for Tiano extensions
191 // function.
192 //
193 return;
194 }
195
196 #endif
197
198 EFI_STATUS
199 EFIAPI
RtEfiCreateEventLegacyBoot(IN EFI_TPL NotifyTpl,IN EFI_EVENT_NOTIFY NotifyFunction,IN VOID * NotifyContext,OUT EFI_EVENT * LegacyBootEvent)200 RtEfiCreateEventLegacyBoot (
201 IN EFI_TPL NotifyTpl,
202 IN EFI_EVENT_NOTIFY NotifyFunction,
203 IN VOID *NotifyContext,
204 OUT EFI_EVENT *LegacyBootEvent
205 )
206 /*++
207
208 Routine Description:
209 Create a Legacy Boot Event.
210 Tiano extended the CreateEvent Type enum to add a legacy boot event type.
211 This was bad as Tiano did not own the enum. In UEFI 2.0 CreateEventEx was
212 added and now it's possible to not voilate the UEFI specification by
213 declaring a GUID for the legacy boot event class. This library supports
214 the EFI 1.10 form and UEFI 2.0 form and allows common code to work both ways.
215
216 Arguments:
217 LegacyBootEvent Returns the EFI event returned from gBS->CreateEvent(Ex)
218
219 Returns:
220 EFI_SUCCESS Event was created.
221 Other Event was not created.
222
223 --*/
224 {
225 EFI_STATUS Status;
226 UINT32 EventType;
227 EFI_EVENT_NOTIFY WorkerNotifyFunction;
228
229 #if (EFI_SPECIFICATION_VERSION < 0x00020000)
230
231 if (NotifyFunction == NULL) {
232 EventType = EFI_EVENT_SIGNAL_LEGACY_BOOT | EFI_EVENT_NOTIFY_SIGNAL_ALL;
233 } else {
234 EventType = EFI_EVENT_SIGNAL_LEGACY_BOOT;
235 }
236 WorkerNotifyFunction = NotifyFunction;
237
238 //
239 // prior to UEFI 2.0 use Tiano extension to EFI
240 //
241 Status = gBS->CreateEvent (
242 EventType,
243 NotifyTpl,
244 WorkerNotifyFunction,
245 NotifyContext,
246 LegacyBootEvent
247 );
248 #else
249
250 EventType = EFI_EVENT_NOTIFY_SIGNAL;
251 if (NotifyFunction == NULL) {
252 //
253 // CreatEventEx will check NotifyFunction is NULL or not
254 //
255 WorkerNotifyFunction = EventNotifySignalAllNullEvent;
256 } else {
257 WorkerNotifyFunction = NotifyFunction;
258 }
259
260 //
261 // For UEFI 2.0 and the future use an Event Group
262 //
263 Status = gBS->CreateEventEx (
264 EventType,
265 NotifyTpl,
266 WorkerNotifyFunction,
267 NotifyContext,
268 &gEfiEventLegacyBootGuid,
269 LegacyBootEvent
270 );
271 #endif
272 return Status;
273 }
274
275 EFI_STATUS
276 EFIAPI
RtEfiCreateEventReadyToBoot(IN EFI_TPL NotifyTpl,IN EFI_EVENT_NOTIFY NotifyFunction,IN VOID * NotifyContext,OUT EFI_EVENT * ReadyToBootEvent)277 RtEfiCreateEventReadyToBoot (
278 IN EFI_TPL NotifyTpl,
279 IN EFI_EVENT_NOTIFY NotifyFunction,
280 IN VOID *NotifyContext,
281 OUT EFI_EVENT *ReadyToBootEvent
282 )
283 /*++
284
285 Routine Description:
286 Create a Read to Boot Event.
287
288 Tiano extended the CreateEvent Type enum to add a ready to boot event type.
289 This was bad as Tiano did not own the enum. In UEFI 2.0 CreateEventEx was
290 added and now it's possible to not voilate the UEFI specification and use
291 the ready to boot event class defined in UEFI 2.0. This library supports
292 the EFI 1.10 form and UEFI 2.0 form and allows common code to work both ways.
293
294 Arguments:
295 ReadyToBootEvent Returns the EFI event returned from gBS->CreateEvent(Ex)
296
297 Return:
298 EFI_SUCCESS - Event was created.
299 Other - Event was not created.
300
301 --*/
302 {
303 EFI_STATUS Status;
304 UINT32 EventType;
305 EFI_EVENT_NOTIFY WorkerNotifyFunction;
306
307 #if (EFI_SPECIFICATION_VERSION < 0x00020000)
308
309 if (NotifyFunction == NULL) {
310 EventType = EFI_EVENT_SIGNAL_READY_TO_BOOT | EFI_EVENT_NOTIFY_SIGNAL_ALL;
311 } else {
312 EventType = EFI_EVENT_SIGNAL_READY_TO_BOOT;
313 }
314 WorkerNotifyFunction = NotifyFunction;
315
316 //
317 // prior to UEFI 2.0 use Tiano extension to EFI
318 //
319 Status = gBS->CreateEvent (
320 EventType,
321 NotifyTpl,
322 WorkerNotifyFunction,
323 NotifyContext,
324 ReadyToBootEvent
325 );
326 #else
327
328 EventType = EFI_EVENT_NOTIFY_SIGNAL;
329 if (NotifyFunction == NULL) {
330 //
331 // CreatEventEx will check NotifyFunction is NULL or not
332 //
333 WorkerNotifyFunction = EventNotifySignalAllNullEvent;
334 } else {
335 WorkerNotifyFunction = NotifyFunction;
336 }
337
338 //
339 // For UEFI 2.0 and the future use an Event Group
340 //
341 Status = gBS->CreateEventEx (
342 EventType,
343 NotifyTpl,
344 WorkerNotifyFunction,
345 NotifyContext,
346 &gEfiEventReadyToBootGuid,
347 ReadyToBootEvent
348 );
349 #endif
350 return Status;
351 }
352