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