Vishal Bhoj | 82c8071 | 2015-12-15 21:13:33 +0530 | [diff] [blame^] | 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
|
| 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
|
| 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
|
| 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
|
| 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
|
| 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
|
| 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
|
| 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
|
| 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
|
| 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 |
|