Home | History | Annotate | Download | only in FrameworkUefiLib
      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
     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
     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
    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
    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
    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
    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
    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
    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