• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2   Library functions that abstract areas of conflict between framework and UEFI 2.0.
3 
4   Help Port Framework code that has conflicts with UEFI 2.0 by hiding the
5   old conflicts with library functions and supporting implementations of the old
6   (EDK/EFI 1.10) and new (EDK II/UEFI 2.0) way. This module is a DXE driver as
7   it contains DXE enum extensions for EFI event services.
8 
9 Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
10 This program and the accompanying materials
11 are licensed and made available under the terms and conditions of the BSD License
12 which accompanies this distribution.  The full text of the license may be found at
13 http://opensource.org/licenses/bsd-license.php
14 
15 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
16 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 
18 **/
19 
20 
21 
22 #include "UefiLibInternal.h"
23 
24 /**
25   An empty function to pass error checking of CreateEventEx ().
26 
27   This empty function ensures that EVT_NOTIFY_SIGNAL_ALL is error
28   checked correctly since it is now mapped into CreateEventEx() in UEFI 2.0.
29 
30   @param  Event                 Event whose notification function is being invoked.
31   @param  Context               The pointer to the notification function's context,
32                                 which is implementation-dependent.
33 
34 **/
35 VOID
36 EFIAPI
InternalEmptyFunction(IN EFI_EVENT Event,IN VOID * Context)37 InternalEmptyFunction (
38   IN EFI_EVENT                Event,
39   IN VOID                     *Context
40   )
41 {
42   return;
43 }
44 
45 /**
46   Creates an EFI event in the Legacy Boot Event Group.
47 
48   Prior to UEFI 2.0 this was done via a non blessed UEFI extensions and this library
49   abstracts the implementation mechanism of this event from the caller. This function
50   abstracts the creation of the Legacy Boot Event. The Framework moved from a proprietary
51   to UEFI 2.0 based mechanism.  This library abstracts the caller from how this event
52   is created to prevent to code form having to change with the version of the
53   specification supported.
54   If LegacyBootEvent is NULL, then ASSERT().
55 
56   @param  LegacyBootEvent   Returns the EFI event returned from gBS->CreateEvent(Ex).
57 
58   @retval EFI_SUCCESS       Event was created.
59   @retval Other             Event was not created.
60 
61 **/
62 EFI_STATUS
63 EFIAPI
EfiCreateEventLegacyBoot(OUT EFI_EVENT * LegacyBootEvent)64 EfiCreateEventLegacyBoot (
65   OUT EFI_EVENT  *LegacyBootEvent
66   )
67 {
68   return EfiCreateEventLegacyBootEx (
69            TPL_CALLBACK,
70            InternalEmptyFunction,
71            NULL,
72            LegacyBootEvent
73            );
74 }
75 
76 /**
77   Create an EFI event in the Legacy Boot Event Group and allows
78   the caller to specify a notification function.
79 
80   This function abstracts the creation of the Legacy Boot Event.
81   The Framework moved from a proprietary to UEFI 2.0 based mechanism.
82   This library abstracts the caller from how this event is created to prevent
83   to code form having to change with the version of the specification supported.
84   If LegacyBootEvent is NULL, then ASSERT().
85 
86   @param  NotifyTpl         The task priority level of the event.
87   @param  NotifyFunction    The notification function to call when the event is signaled.
88   @param  NotifyContext     The content to pass to NotifyFunction when the event is signaled.
89   @param  LegacyBootEvent   Returns the EFI event returned from gBS->CreateEvent(Ex).
90 
91   @retval EFI_SUCCESS       Event was created.
92   @retval Other             Event was not created.
93 
94 **/
95 EFI_STATUS
96 EFIAPI
EfiCreateEventLegacyBootEx(IN EFI_TPL NotifyTpl,IN EFI_EVENT_NOTIFY NotifyFunction,OPTIONAL IN VOID * NotifyContext,OPTIONAL OUT EFI_EVENT * LegacyBootEvent)97 EfiCreateEventLegacyBootEx (
98   IN  EFI_TPL           NotifyTpl,
99   IN  EFI_EVENT_NOTIFY  NotifyFunction,  OPTIONAL
100   IN  VOID              *NotifyContext,  OPTIONAL
101   OUT EFI_EVENT         *LegacyBootEvent
102   )
103 {
104   EFI_STATUS        Status;
105   EFI_EVENT_NOTIFY  WorkerNotifyFunction;
106 
107   ASSERT (LegacyBootEvent != NULL);
108 
109   if (gST->Hdr.Revision < EFI_2_00_SYSTEM_TABLE_REVISION) {
110     DEBUG ((EFI_D_ERROR, "EFI1.1 can't support LegacyBootEvent!"));
111     ASSERT (FALSE);
112 
113     return EFI_UNSUPPORTED;
114   } else {
115     //
116     // For UEFI 2.0 and the future use an Event Group
117     //
118     if (NotifyFunction == NULL) {
119       //
120       // CreateEventEx will check NotifyFunction is NULL or not and return error.
121       // Use dummy routine for the case NotifyFunction is NULL.
122       //
123       WorkerNotifyFunction = InternalEmptyFunction;
124     } else {
125       WorkerNotifyFunction = NotifyFunction;
126     }
127     Status = gBS->CreateEventEx (
128                     EVT_NOTIFY_SIGNAL,
129                     NotifyTpl,
130                     WorkerNotifyFunction,
131                     NotifyContext,
132                     &gEfiEventLegacyBootGuid,
133                     LegacyBootEvent
134                     );
135   }
136 
137   return Status;
138 }
139 
140 /**
141   Create an EFI event in the Ready To Boot Event Group.
142 
143   Prior to UEFI 2.0 this was done via a non-standard UEFI extension, and this library
144   abstracts the implementation mechanism of this event from the caller.
145   This function abstracts the creation of the Ready to Boot Event.  The Framework
146   moved from a proprietary to UEFI 2.0-based mechanism.  This library abstracts
147   the caller from how this event is created to prevent the code form having to
148   change with the version of the specification supported.
149   If ReadyToBootEvent is NULL, then ASSERT().
150 
151   @param  ReadyToBootEvent  Returns the EFI event returned from gBS->CreateEvent(Ex).
152 
153   @retval EFI_SUCCESS       Event was created.
154   @retval Other             Event was not created.
155 
156 **/
157 EFI_STATUS
158 EFIAPI
EfiCreateEventReadyToBoot(OUT EFI_EVENT * ReadyToBootEvent)159 EfiCreateEventReadyToBoot (
160   OUT EFI_EVENT  *ReadyToBootEvent
161   )
162 {
163   return EfiCreateEventReadyToBootEx (
164            TPL_CALLBACK,
165            InternalEmptyFunction,
166            NULL,
167            ReadyToBootEvent
168            );
169 }
170 
171 /**
172   Create an EFI event in the Ready To Boot Event Group and allows
173   the caller to specify a notification function.
174 
175   This function abstracts the creation of the Ready to Boot Event.
176   The Framework moved from a proprietary to UEFI 2.0 based mechanism.
177   This library abstracts the caller from how this event is created to prevent
178   to code form having to change with the version of the specification supported.
179   If ReadyToBootEvent is NULL, then ASSERT().
180 
181   @param  NotifyTpl         The task priority level of the event.
182   @param  NotifyFunction    The notification function to call when the event is signaled.
183   @param  NotifyContext     The content to pass to NotifyFunction when the event is signaled.
184   @param  ReadyToBootEvent  Returns the EFI event returned from gBS->CreateEvent(Ex).
185 
186   @retval EFI_SUCCESS       Event was created.
187   @retval Other             Event was not created.
188 
189 **/
190 EFI_STATUS
191 EFIAPI
EfiCreateEventReadyToBootEx(IN EFI_TPL NotifyTpl,IN EFI_EVENT_NOTIFY NotifyFunction,OPTIONAL IN VOID * NotifyContext,OPTIONAL OUT EFI_EVENT * ReadyToBootEvent)192 EfiCreateEventReadyToBootEx (
193   IN  EFI_TPL           NotifyTpl,
194   IN  EFI_EVENT_NOTIFY  NotifyFunction,  OPTIONAL
195   IN  VOID              *NotifyContext,  OPTIONAL
196   OUT EFI_EVENT         *ReadyToBootEvent
197   )
198 {
199   EFI_STATUS        Status;
200   EFI_EVENT_NOTIFY  WorkerNotifyFunction;
201 
202   ASSERT (ReadyToBootEvent != NULL);
203 
204   if (gST->Hdr.Revision < EFI_2_00_SYSTEM_TABLE_REVISION) {
205     DEBUG ((EFI_D_ERROR, "EFI1.1 can't support ReadyToBootEvent!"));
206     ASSERT (FALSE);
207 
208     return EFI_UNSUPPORTED;
209   } else {
210     //
211     // For UEFI 2.0 and the future use an Event Group
212     //
213     if (NotifyFunction == NULL) {
214       //
215       // CreateEventEx will check NotifyFunction is NULL or not and return error.
216       // Use dummy routine for the case NotifyFunction is NULL.
217       //
218       WorkerNotifyFunction = InternalEmptyFunction;
219     } else {
220       WorkerNotifyFunction = NotifyFunction;
221     }
222     Status = gBS->CreateEventEx (
223                     EVT_NOTIFY_SIGNAL,
224                     NotifyTpl,
225                     WorkerNotifyFunction,
226                     NotifyContext,
227                     &gEfiEventReadyToBootGuid,
228                     ReadyToBootEvent
229                     );
230   }
231 
232   return Status;
233 }
234 
235 
236 /**
237   Create, Signal, and Close the Ready to Boot event using EfiSignalEventReadyToBoot().
238 
239   This function abstracts the signaling of the Ready to Boot Event. The Framework moved
240   from a proprietary to UEFI 2.0 based mechanism. This library abstracts the caller
241   from how this event is created to prevent to code form having to change with the
242   version of the specification supported.
243 
244 **/
245 VOID
246 EFIAPI
EfiSignalEventReadyToBoot(VOID)247 EfiSignalEventReadyToBoot (
248   VOID
249   )
250 {
251   EFI_STATUS    Status;
252   EFI_EVENT     ReadyToBootEvent;
253 
254   Status = EfiCreateEventReadyToBoot (&ReadyToBootEvent);
255   if (!EFI_ERROR (Status)) {
256     gBS->SignalEvent (ReadyToBootEvent);
257     gBS->CloseEvent (ReadyToBootEvent);
258   }
259 }
260 
261 /**
262   Create, Signal, and Close the Ready to Boot event using EfiSignalEventLegacyBoot().
263 
264   This function abstracts the signaling of the Legacy Boot Event. The Framework moved from
265   a proprietary to UEFI 2.0 based mechanism.  This library abstracts the caller from how
266   this event is created to prevent to code form having to change with the version of the
267   specification supported.
268 
269 **/
270 VOID
271 EFIAPI
EfiSignalEventLegacyBoot(VOID)272 EfiSignalEventLegacyBoot (
273   VOID
274   )
275 {
276   EFI_STATUS    Status;
277   EFI_EVENT     LegacyBootEvent;
278 
279   Status = EfiCreateEventLegacyBoot (&LegacyBootEvent);
280   if (!EFI_ERROR (Status)) {
281     gBS->SignalEvent (LegacyBootEvent);
282     gBS->CloseEvent (LegacyBootEvent);
283   }
284 }
285 
286 
287 /**
288   Check to see if the Firmware Volume (FV) Media Device Path is valid
289 
290   The Framework FwVol Device Path changed to conform to the UEFI 2.0 specification.
291   This library function abstracts validating a device path node.
292   Check the MEDIA_FW_VOL_FILEPATH_DEVICE_PATH data structure to see if it's valid.
293   If it is valid, then return the GUID file name from the device path node.  Otherwise,
294   return NULL.  This device path changed in the DXE CIS version 0.92 in a non back ward
295   compatible way to not conflict with the UEFI 2.0 specification.  This function abstracts
296   the differences from the caller.
297   If FvDevicePathNode is NULL, then ASSERT().
298 
299   @param  FvDevicePathNode  The pointer to FV device path to check.
300 
301   @retval NULL              FvDevicePathNode is not valid.
302   @retval Other             FvDevicePathNode is valid and pointer to NameGuid was returned.
303 
304 **/
305 EFI_GUID *
306 EFIAPI
EfiGetNameGuidFromFwVolDevicePathNode(IN CONST MEDIA_FW_VOL_FILEPATH_DEVICE_PATH * FvDevicePathNode)307 EfiGetNameGuidFromFwVolDevicePathNode (
308   IN CONST MEDIA_FW_VOL_FILEPATH_DEVICE_PATH  *FvDevicePathNode
309   )
310 {
311   ASSERT (FvDevicePathNode != NULL);
312 
313   if (DevicePathType (&FvDevicePathNode->Header) == MEDIA_DEVICE_PATH &&
314       DevicePathSubType (&FvDevicePathNode->Header) == MEDIA_PIWG_FW_FILE_DP) {
315     return (EFI_GUID *) &FvDevicePathNode->FvFileName;
316   }
317 
318   return NULL;
319 }
320 
321 
322 /**
323   Initialize a Firmware Volume (FV) Media Device Path node.
324 
325   The Framework FwVol Device Path changed to conform to the UEFI 2.0 specification.
326   This library function abstracts initializing a device path node.
327   Initialize the MEDIA_FW_VOL_FILEPATH_DEVICE_PATH data structure.  This device
328   path changed in the DXE CIS version 0.92 in a non back ward compatible way to
329   not conflict with the UEFI 2.0 specification.  This function abstracts the
330   differences from the caller.
331   If FvDevicePathNode is NULL, then ASSERT().
332   If NameGuid is NULL, then ASSERT().
333 
334   @param  FvDevicePathNode  The pointer to a FV device path node to initialize
335   @param  NameGuid          FV file name to use in FvDevicePathNode
336 
337 **/
338 VOID
339 EFIAPI
EfiInitializeFwVolDevicepathNode(IN OUT MEDIA_FW_VOL_FILEPATH_DEVICE_PATH * FvDevicePathNode,IN CONST EFI_GUID * NameGuid)340 EfiInitializeFwVolDevicepathNode (
341   IN OUT MEDIA_FW_VOL_FILEPATH_DEVICE_PATH  *FvDevicePathNode,
342   IN CONST EFI_GUID                         *NameGuid
343   )
344 {
345   ASSERT (FvDevicePathNode != NULL);
346   ASSERT (NameGuid          != NULL);
347 
348   //
349   // Use the new Device path that does not conflict with the UEFI
350   //
351   FvDevicePathNode->Header.Type     = MEDIA_DEVICE_PATH;
352   FvDevicePathNode->Header.SubType  = MEDIA_PIWG_FW_FILE_DP;
353   SetDevicePathNodeLength (&FvDevicePathNode->Header, sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH));
354 
355   CopyGuid (&FvDevicePathNode->FvFileName, NameGuid);
356 }
357 
358