• 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   Creates an EFI event in the Legacy Boot Event Group.
26 
27   Prior to UEFI 2.0 this was done via a non blessed UEFI extensions and this library
28   abstracts the implementation mechanism of this event from the caller. This function
29   abstracts the creation of the Legacy Boot Event. The Framework moved from a proprietary
30   to UEFI 2.0 based mechanism.  This library abstracts the caller from how this event
31   is created to prevent to code form having to change with the version of the
32   specification supported.
33   If LegacyBootEvent is NULL, then ASSERT().
34 
35   @param  LegacyBootEvent   Returns the EFI event returned from gBS->CreateEvent(Ex).
36 
37   @retval EFI_SUCCESS       Event was created.
38   @retval Other             Event was not created.
39 
40 **/
41 EFI_STATUS
42 EFIAPI
EfiCreateEventLegacyBoot(OUT EFI_EVENT * LegacyBootEvent)43 EfiCreateEventLegacyBoot (
44   OUT EFI_EVENT  *LegacyBootEvent
45   )
46 {
47   return EfiCreateEventLegacyBootEx (
48            TPL_CALLBACK,
49            InternalEmptyFunction,
50            NULL,
51            LegacyBootEvent
52            );
53 }
54 
55 /**
56   Create an EFI event in the Legacy Boot Event Group and allows
57   the caller to specify a notification function.
58 
59   This function abstracts the creation of the Legacy Boot Event.
60   The Framework moved from a proprietary to UEFI 2.0 based mechanism.
61   This library abstracts the caller from how this event is created to prevent
62   to code form having to change with the version of the specification supported.
63   If LegacyBootEvent is NULL, then ASSERT().
64 
65   @param  NotifyTpl         The task priority level of the event.
66   @param  NotifyFunction    The notification function to call when the event is signaled.
67   @param  NotifyContext     The content to pass to NotifyFunction when the event is signaled.
68   @param  LegacyBootEvent   Returns the EFI event returned from gBS->CreateEvent(Ex).
69 
70   @retval EFI_SUCCESS       Event was created.
71   @retval Other             Event was not created.
72 
73 **/
74 EFI_STATUS
75 EFIAPI
EfiCreateEventLegacyBootEx(IN EFI_TPL NotifyTpl,IN EFI_EVENT_NOTIFY NotifyFunction,OPTIONAL IN VOID * NotifyContext,OPTIONAL OUT EFI_EVENT * LegacyBootEvent)76 EfiCreateEventLegacyBootEx (
77   IN  EFI_TPL           NotifyTpl,
78   IN  EFI_EVENT_NOTIFY  NotifyFunction,  OPTIONAL
79   IN  VOID              *NotifyContext,  OPTIONAL
80   OUT EFI_EVENT         *LegacyBootEvent
81   )
82 {
83   EFI_STATUS        Status;
84   EFI_EVENT_NOTIFY  WorkerNotifyFunction;
85 
86   ASSERT (LegacyBootEvent != NULL);
87 
88   if (gST->Hdr.Revision < EFI_2_00_SYSTEM_TABLE_REVISION) {
89     DEBUG ((EFI_D_ERROR, "EFI1.1 can't support LegacyBootEvent!"));
90     ASSERT (FALSE);
91 
92     return EFI_UNSUPPORTED;
93   } else {
94     //
95     // For UEFI 2.0 and the future use an Event Group
96     //
97     if (NotifyFunction == NULL) {
98       //
99       // CreateEventEx will check NotifyFunction is NULL or not and return error.
100       // Use dummy routine for the case NotifyFunction is NULL.
101       //
102       WorkerNotifyFunction = InternalEmptyFunction;
103     } else {
104       WorkerNotifyFunction = NotifyFunction;
105     }
106     Status = gBS->CreateEventEx (
107                     EVT_NOTIFY_SIGNAL,
108                     NotifyTpl,
109                     WorkerNotifyFunction,
110                     NotifyContext,
111                     &gEfiEventLegacyBootGuid,
112                     LegacyBootEvent
113                     );
114   }
115 
116   return Status;
117 }
118 
119 /**
120   Create an EFI event in the Ready To Boot Event Group.
121 
122   Prior to UEFI 2.0 this was done via a non-standard UEFI extension, and this library
123   abstracts the implementation mechanism of this event from the caller.
124   This function abstracts the creation of the Ready to Boot Event.  The Framework
125   moved from a proprietary to UEFI 2.0-based mechanism.  This library abstracts
126   the caller from how this event is created to prevent the code form having to
127   change with the version of the specification supported.
128   If ReadyToBootEvent is NULL, then ASSERT().
129 
130   @param  ReadyToBootEvent  Returns the EFI event returned from gBS->CreateEvent(Ex).
131 
132   @retval EFI_SUCCESS       Event was created.
133   @retval Other             Event was not created.
134 
135 **/
136 EFI_STATUS
137 EFIAPI
EfiCreateEventReadyToBoot(OUT EFI_EVENT * ReadyToBootEvent)138 EfiCreateEventReadyToBoot (
139   OUT EFI_EVENT  *ReadyToBootEvent
140   )
141 {
142   return EfiCreateEventReadyToBootEx (
143            TPL_CALLBACK,
144            InternalEmptyFunction,
145            NULL,
146            ReadyToBootEvent
147            );
148 }
149 
150 /**
151   Create an EFI event in the Ready To Boot Event Group and allows
152   the caller to specify a notification function.
153 
154   This function abstracts the creation of the Ready to Boot Event.
155   The Framework moved from a proprietary to UEFI 2.0 based mechanism.
156   This library abstracts the caller from how this event is created to prevent
157   to code form having to change with the version of the specification supported.
158   If ReadyToBootEvent is NULL, then ASSERT().
159 
160   @param  NotifyTpl         The task priority level of the event.
161   @param  NotifyFunction    The notification function to call when the event is signaled.
162   @param  NotifyContext     The content to pass to NotifyFunction when the event is signaled.
163   @param  ReadyToBootEvent  Returns the EFI event returned from gBS->CreateEvent(Ex).
164 
165   @retval EFI_SUCCESS       Event was created.
166   @retval Other             Event was not created.
167 
168 **/
169 EFI_STATUS
170 EFIAPI
EfiCreateEventReadyToBootEx(IN EFI_TPL NotifyTpl,IN EFI_EVENT_NOTIFY NotifyFunction,OPTIONAL IN VOID * NotifyContext,OPTIONAL OUT EFI_EVENT * ReadyToBootEvent)171 EfiCreateEventReadyToBootEx (
172   IN  EFI_TPL           NotifyTpl,
173   IN  EFI_EVENT_NOTIFY  NotifyFunction,  OPTIONAL
174   IN  VOID              *NotifyContext,  OPTIONAL
175   OUT EFI_EVENT         *ReadyToBootEvent
176   )
177 {
178   EFI_STATUS        Status;
179   EFI_EVENT_NOTIFY  WorkerNotifyFunction;
180 
181   ASSERT (ReadyToBootEvent != NULL);
182 
183   if (gST->Hdr.Revision < EFI_2_00_SYSTEM_TABLE_REVISION) {
184     DEBUG ((EFI_D_ERROR, "EFI1.1 can't support ReadyToBootEvent!"));
185     ASSERT (FALSE);
186 
187     return EFI_UNSUPPORTED;
188   } else {
189     //
190     // For UEFI 2.0 and the future use an Event Group
191     //
192     if (NotifyFunction == NULL) {
193       //
194       // CreateEventEx will check NotifyFunction is NULL or not and return error.
195       // Use dummy routine for the case NotifyFunction is NULL.
196       //
197       WorkerNotifyFunction = InternalEmptyFunction;
198     } else {
199       WorkerNotifyFunction = NotifyFunction;
200     }
201     Status = gBS->CreateEventEx (
202                     EVT_NOTIFY_SIGNAL,
203                     NotifyTpl,
204                     WorkerNotifyFunction,
205                     NotifyContext,
206                     &gEfiEventReadyToBootGuid,
207                     ReadyToBootEvent
208                     );
209   }
210 
211   return Status;
212 }
213 
214 
215 /**
216   Create, Signal, and Close the Ready to Boot event using EfiSignalEventReadyToBoot().
217 
218   This function abstracts the signaling of the Ready to Boot Event. The Framework moved
219   from a proprietary to UEFI 2.0 based mechanism. This library abstracts the caller
220   from how this event is created to prevent to code form having to change with the
221   version of the specification supported.
222 
223 **/
224 VOID
225 EFIAPI
EfiSignalEventReadyToBoot(VOID)226 EfiSignalEventReadyToBoot (
227   VOID
228   )
229 {
230   EFI_STATUS    Status;
231   EFI_EVENT     ReadyToBootEvent;
232 
233   Status = EfiCreateEventReadyToBoot (&ReadyToBootEvent);
234   if (!EFI_ERROR (Status)) {
235     gBS->SignalEvent (ReadyToBootEvent);
236     gBS->CloseEvent (ReadyToBootEvent);
237   }
238 }
239 
240 /**
241   Create, Signal, and Close the Ready to Boot event using EfiSignalEventLegacyBoot().
242 
243   This function abstracts the signaling of the Legacy Boot Event. The Framework moved from
244   a proprietary to UEFI 2.0 based mechanism.  This library abstracts the caller from how
245   this event is created to prevent to code form having to change with the version of the
246   specification supported.
247 
248 **/
249 VOID
250 EFIAPI
EfiSignalEventLegacyBoot(VOID)251 EfiSignalEventLegacyBoot (
252   VOID
253   )
254 {
255   EFI_STATUS    Status;
256   EFI_EVENT     LegacyBootEvent;
257 
258   Status = EfiCreateEventLegacyBoot (&LegacyBootEvent);
259   if (!EFI_ERROR (Status)) {
260     gBS->SignalEvent (LegacyBootEvent);
261     gBS->CloseEvent (LegacyBootEvent);
262   }
263 }
264 
265 
266 /**
267   Check to see if the Firmware Volume (FV) Media Device Path is valid
268 
269   The Framework FwVol Device Path changed to conform to the UEFI 2.0 specification.
270   This library function abstracts validating a device path node.
271   Check the MEDIA_FW_VOL_FILEPATH_DEVICE_PATH data structure to see if it's valid.
272   If it is valid, then return the GUID file name from the device path node.  Otherwise,
273   return NULL.  This device path changed in the DXE CIS version 0.92 in a non back ward
274   compatible way to not conflict with the UEFI 2.0 specification.  This function abstracts
275   the differences from the caller.
276   If FvDevicePathNode is NULL, then ASSERT().
277 
278   @param  FvDevicePathNode  The pointer to FV device path to check.
279 
280   @retval NULL              FvDevicePathNode is not valid.
281   @retval Other             FvDevicePathNode is valid and pointer to NameGuid was returned.
282 
283 **/
284 EFI_GUID *
285 EFIAPI
EfiGetNameGuidFromFwVolDevicePathNode(IN CONST MEDIA_FW_VOL_FILEPATH_DEVICE_PATH * FvDevicePathNode)286 EfiGetNameGuidFromFwVolDevicePathNode (
287   IN CONST MEDIA_FW_VOL_FILEPATH_DEVICE_PATH  *FvDevicePathNode
288   )
289 {
290   ASSERT (FvDevicePathNode != NULL);
291 
292   if (DevicePathType (&FvDevicePathNode->Header) == MEDIA_DEVICE_PATH &&
293       DevicePathSubType (&FvDevicePathNode->Header) == MEDIA_PIWG_FW_FILE_DP) {
294     return (EFI_GUID *) &FvDevicePathNode->FvFileName;
295   }
296 
297   return NULL;
298 }
299 
300 
301 /**
302   Initialize a Firmware Volume (FV) Media Device Path node.
303 
304   The Framework FwVol Device Path changed to conform to the UEFI 2.0 specification.
305   This library function abstracts initializing a device path node.
306   Initialize the MEDIA_FW_VOL_FILEPATH_DEVICE_PATH data structure.  This device
307   path changed in the DXE CIS version 0.92 in a non back ward compatible way to
308   not conflict with the UEFI 2.0 specification.  This function abstracts the
309   differences from the caller.
310   If FvDevicePathNode is NULL, then ASSERT().
311   If NameGuid is NULL, then ASSERT().
312 
313   @param  FvDevicePathNode  The pointer to a FV device path node to initialize
314   @param  NameGuid          FV file name to use in FvDevicePathNode
315 
316 **/
317 VOID
318 EFIAPI
EfiInitializeFwVolDevicepathNode(IN OUT MEDIA_FW_VOL_FILEPATH_DEVICE_PATH * FvDevicePathNode,IN CONST EFI_GUID * NameGuid)319 EfiInitializeFwVolDevicepathNode (
320   IN OUT MEDIA_FW_VOL_FILEPATH_DEVICE_PATH  *FvDevicePathNode,
321   IN CONST EFI_GUID                         *NameGuid
322   )
323 {
324   ASSERT (FvDevicePathNode != NULL);
325   ASSERT (NameGuid          != NULL);
326 
327   //
328   // Use the new Device path that does not conflict with the UEFI
329   //
330   FvDevicePathNode->Header.Type     = MEDIA_DEVICE_PATH;
331   FvDevicePathNode->Header.SubType  = MEDIA_PIWG_FW_FILE_DP;
332   SetDevicePathNodeLength (&FvDevicePathNode->Header, sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH));
333 
334   CopyGuid (&FvDevicePathNode->FvFileName, NameGuid);
335 }
336 
337