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