• 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 - 2007, 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   Create a Legacy Boot Event.
26 
27   Tiano extended the CreateEvent Type enum to add a legacy boot event type.
28   This was bad as Tiano did not own the enum. In UEFI 2.0 CreateEventEx was
29   added and now it's possible to not voilate the UEFI specification by
30   declaring a GUID for the legacy boot event class. This library supports
31   the EDK/EFI 1.10 form and EDK II/UEFI 2.0 form and allows common code to
32   work both ways.
33 
34   @param  LegacyBootEvent   Returns the EFI event returned from gBS->CreateEvent(Ex).
35 
36   @retval EFI_SUCCESS       Event was created.
37   @retval Other             Event was not created.
38 
39 **/
40 EFI_STATUS
41 EFIAPI
EfiCreateEventLegacyBoot(OUT EFI_EVENT * LegacyBootEvent)42 EfiCreateEventLegacyBoot (
43   OUT EFI_EVENT  *LegacyBootEvent
44   )
45 {
46   return EfiCreateEventLegacyBootEx (
47            TPL_CALLBACK,
48            InternalEmptyFunction,
49            NULL,
50            LegacyBootEvent
51            );
52 }
53 
54 /**
55   Create an EFI event in the Legacy Boot Event Group and allows
56   the caller to specify a notification function.
57 
58   This function abstracts the creation of the Legacy Boot Event.
59   The Framework moved from a proprietary to UEFI 2.0 based mechanism.
60   This library abstracts the caller from how this event is created to prevent
61   to code form having to change with the version of the specification supported.
62   If LegacyBootEvent is NULL, then ASSERT().
63 
64   @param  NotifyTpl         The task priority level of the event.
65   @param  NotifyFunction    The notification function to call when the event is signaled.
66   @param  NotifyContext     The content to pass to NotifyFunction when the event is signaled.
67   @param  LegacyBootEvent   Returns the EFI event returned from gBS->CreateEvent(Ex).
68 
69   @retval EFI_SUCCESS       Event was created.
70   @retval Other             Event was not created.
71 
72 **/
73 EFI_STATUS
74 EFIAPI
EfiCreateEventLegacyBootEx(IN EFI_TPL NotifyTpl,IN EFI_EVENT_NOTIFY NotifyFunction,OPTIONAL IN VOID * NotifyContext,OPTIONAL OUT EFI_EVENT * LegacyBootEvent)75 EfiCreateEventLegacyBootEx (
76   IN  EFI_TPL           NotifyTpl,
77   IN  EFI_EVENT_NOTIFY  NotifyFunction,  OPTIONAL
78   IN  VOID              *NotifyContext,  OPTIONAL
79   OUT EFI_EVENT         *LegacyBootEvent
80   )
81 {
82   EFI_STATUS    Status;
83 
84   ASSERT (LegacyBootEvent != NULL);
85 
86   if (gST->Hdr.Revision < 0x00020000) {
87     //
88     // prior to UEFI 2.0 use Tiano extension to EFI
89     //
90     Status = gBS->CreateEvent (
91                     EFI_EVENT_SIGNAL_LEGACY_BOOT | EVT_NOTIFY_SIGNAL,
92                     NotifyTpl,
93                     NotifyFunction,
94                     NotifyContext,
95                     LegacyBootEvent
96                     );
97   } else {
98     //
99     // For UEFI 2.0 and the future use an Event Group
100     //
101     Status = gBS->CreateEventEx (
102                     EVT_NOTIFY_SIGNAL,
103                     NotifyTpl,
104                     NotifyFunction,
105                     NotifyContext,
106                     &gEfiEventLegacyBootGuid,
107                     LegacyBootEvent
108                     );
109   }
110 
111   return Status;
112 }
113 
114 /**
115   Create a Read to Boot Event.
116 
117   Tiano extended the CreateEvent Type enum to add a ready to boot event type.
118   This was bad as Tiano did not own the enum. In UEFI 2.0 CreateEventEx was
119   added and now it's possible to not voilate the UEFI specification and use
120   the ready to boot event class defined in UEFI 2.0. This library supports
121   the EDK/EFI 1.10 form and EDK II/UEFI 2.0 form and allows common code to
122   work both ways.
123 
124   @param  ReadyToBootEvent   Returns the EFI event returned from gBS->CreateEvent(Ex).
125 
126   @retval EFI_SUCCESS       Event was created.
127   @retval Other             Event was not created.
128 
129 **/
130 EFI_STATUS
131 EFIAPI
EfiCreateEventReadyToBoot(OUT EFI_EVENT * ReadyToBootEvent)132 EfiCreateEventReadyToBoot (
133   OUT EFI_EVENT  *ReadyToBootEvent
134   )
135 {
136   return EfiCreateEventReadyToBootEx (
137            TPL_CALLBACK,
138            InternalEmptyFunction,
139            NULL,
140            ReadyToBootEvent
141            );
142 }
143 
144 /**
145   Create an EFI event in the Ready To Boot Event Group and allows
146   the caller to specify a notification function.
147 
148   This function abstracts the creation of the Ready to Boot Event.
149   The Framework moved from a proprietary to UEFI 2.0 based mechanism.
150   This library abstracts the caller from how this event is created to prevent
151   to code form having to change with the version of the specification supported.
152   If ReadyToBootEvent is NULL, then ASSERT().
153 
154   @param  NotifyTpl         The task priority level of the event.
155   @param  NotifyFunction    The notification function to call when the event is signaled.
156   @param  NotifyContext     The content to pass to NotifyFunction when the event is signaled.
157   @param  ReadyToBootEvent  Returns the EFI event returned from gBS->CreateEvent(Ex).
158 
159   @retval EFI_SUCCESS       Event was created.
160   @retval Other             Event was not created.
161 
162 **/
163 EFI_STATUS
164 EFIAPI
EfiCreateEventReadyToBootEx(IN EFI_TPL NotifyTpl,IN EFI_EVENT_NOTIFY NotifyFunction,OPTIONAL IN VOID * NotifyContext,OPTIONAL OUT EFI_EVENT * ReadyToBootEvent)165 EfiCreateEventReadyToBootEx (
166   IN  EFI_TPL           NotifyTpl,
167   IN  EFI_EVENT_NOTIFY  NotifyFunction,  OPTIONAL
168   IN  VOID              *NotifyContext,  OPTIONAL
169   OUT EFI_EVENT         *ReadyToBootEvent
170   )
171 {
172   EFI_STATUS    Status;
173 
174   ASSERT (ReadyToBootEvent != NULL);
175 
176   if (gST->Hdr.Revision < 0x00020000) {
177     //
178     // prior to UEFI 2.0 use Tiano extension to EFI
179     //
180     Status = gBS->CreateEvent (
181                     EFI_EVENT_SIGNAL_READY_TO_BOOT | EFI_EVENT_NOTIFY_SIGNAL_ALL,
182                     NotifyTpl,
183                     NotifyFunction,
184                     NotifyContext,
185                     ReadyToBootEvent
186                     );
187   } else {
188     //
189     // For UEFI 2.0 and the future use an Event Group
190     //
191     Status = gBS->CreateEventEx (
192                     EVT_NOTIFY_SIGNAL,
193                     NotifyTpl,
194                     NotifyFunction,
195                     NotifyContext,
196                     &gEfiEventReadyToBootGuid,
197                     ReadyToBootEvent
198                     );
199   }
200 
201   return Status;
202 }
203 
204 
205 /**
206   Signal a Ready to Boot Event.
207 
208   Create a Ready to Boot Event. Signal it and close it. This causes other
209   events of the same event group to be signaled in other modules.
210 
211 **/
212 VOID
213 EFIAPI
EfiSignalEventReadyToBoot(VOID)214 EfiSignalEventReadyToBoot (
215   VOID
216   )
217 {
218   EFI_STATUS    Status;
219   EFI_EVENT     ReadyToBootEvent;
220 
221   Status = EfiCreateEventReadyToBoot (&ReadyToBootEvent);
222   if (!EFI_ERROR (Status)) {
223     gBS->SignalEvent (ReadyToBootEvent);
224     gBS->CloseEvent (ReadyToBootEvent);
225   }
226 }
227 
228 /**
229   Signal a Legacy Boot Event.
230 
231   Create a legacy Boot Event. Signal it and close it. This causes other
232   events of the same event group to be signaled in other modules.
233 
234 **/
235 VOID
236 EFIAPI
EfiSignalEventLegacyBoot(VOID)237 EfiSignalEventLegacyBoot (
238   VOID
239   )
240 {
241   EFI_STATUS    Status;
242   EFI_EVENT     LegacyBootEvent;
243 
244   Status = EfiCreateEventLegacyBoot (&LegacyBootEvent);
245   if (!EFI_ERROR (Status)) {
246     gBS->SignalEvent (LegacyBootEvent);
247     gBS->CloseEvent (LegacyBootEvent);
248   }
249 }
250 
251 
252 /**
253   Check to see if the Firmware Volume (FV) Media Device Path is valid
254 
255   Tiano extended the EFI 1.10 device path nodes. Tiano does not own this enum
256   so as we move to UEFI 2.0 support we must use a mechanism that conforms with
257   the UEFI 2.0 specification to define the FV device path. An UEFI GUIDed
258   device path is defined for Tiano extensions of device path. If the code
259   is compiled to conform with the UEFI 2.0 specification use the new device path
260   else use the old form for backwards compatability. The return value to this
261   function points to a location in FvDevicePathNode and it does not allocate
262   new memory for the GUID pointer that is returned.
263 
264   @param  FvDevicePathNode  Pointer to FV device path to check.
265 
266   @retval NULL              FvDevicePathNode is not valid.
267   @retval Other             FvDevicePathNode is valid and pointer to NameGuid was returned.
268 
269 **/
270 EFI_GUID *
271 EFIAPI
EfiGetNameGuidFromFwVolDevicePathNode(IN CONST MEDIA_FW_VOL_FILEPATH_DEVICE_PATH * FvDevicePathNode)272 EfiGetNameGuidFromFwVolDevicePathNode (
273   IN CONST MEDIA_FW_VOL_FILEPATH_DEVICE_PATH  *FvDevicePathNode
274   )
275 {
276   ASSERT (FvDevicePathNode != NULL);
277 
278   //
279   // EFI Specification extension on Media Device Path. MEDIA_FW_VOL_FILEPATH_DEVICE_PATH is adopted by UEFI later and added in UEFI2.10.
280   // In EdkCompatibility Package, we only support MEDIA_FW_VOL_FILEPATH_DEVICE_PATH that complies with
281   // EFI 1.10 and UEFI 2.10.
282   //
283   if (DevicePathType (&FvDevicePathNode->Header) == MEDIA_DEVICE_PATH &&
284       DevicePathSubType (&FvDevicePathNode->Header) == MEDIA_PIWG_FW_FILE_DP) {
285     return (EFI_GUID *) &FvDevicePathNode->FvFileName;
286   }
287 
288   return NULL;
289 }
290 
291 
292 /**
293   Initialize a Firmware Volume (FV) Media Device Path node.
294 
295   Tiano extended the EFI 1.10 device path nodes. Tiano does not own this enum
296   so as we move to UEFI 2.0 support we must use a mechanism that conforms with
297   the UEFI 2.0 specification to define the FV device path. An UEFI GUIDed
298   device path is defined for Tiano extensions of device path. If the code
299   is compiled to conform with the UEFI 2.0 specification use the new device path
300   else use the old form for backwards compatability.
301 
302   @param  FvDevicePathNode  Pointer to a FV device path node to initialize
303   @param  NameGuid          FV file name to use in FvDevicePathNode
304 
305 **/
306 VOID
307 EFIAPI
EfiInitializeFwVolDevicepathNode(IN OUT MEDIA_FW_VOL_FILEPATH_DEVICE_PATH * FvDevicePathNode,IN CONST EFI_GUID * NameGuid)308 EfiInitializeFwVolDevicepathNode (
309   IN OUT MEDIA_FW_VOL_FILEPATH_DEVICE_PATH  *FvDevicePathNode,
310   IN CONST EFI_GUID                         *NameGuid
311   )
312 {
313   ASSERT (FvDevicePathNode  != NULL);
314   ASSERT (NameGuid          != NULL);
315 
316   //
317   // EFI Specification extension on Media Device Path. MEDIA_FW_VOL_FILEPATH_DEVICE_PATH is adopted by UEFI later and added in UEFI2.10.
318   // In EdkCompatibility Package, we only support MEDIA_FW_VOL_FILEPATH_DEVICE_PATH that complies with
319   // EFI 1.10 and UEFI 2.10.
320   //
321   FvDevicePathNode->Header.Type     = MEDIA_DEVICE_PATH;
322   FvDevicePathNode->Header.SubType  = MEDIA_PIWG_FW_FILE_DP;
323   SetDevicePathNodeLength (&FvDevicePathNode->Header, sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH));
324 
325   CopyGuid (&FvDevicePathNode->FvFileName, NameGuid);
326 }
327 
328