git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@6797 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			366 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			366 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|   Library functions that abstract areas of conflict between framework and UEFI 2.0.
 | |
| 
 | |
|   Help Port Framework code that has conflicts with UEFI 2.0 by hiding the
 | |
|   old conflicts with library functions and supporting implementations of the old
 | |
|   (EDK/EFI 1.10) and new (EDK II/UEFI 2.0) way. This module is a DXE driver as
 | |
|   it contains DXE enum extensions for EFI event services.
 | |
| 
 | |
| Copyright (c) 2006 - 2007, Intel Corporation<BR>
 | |
| All rights reserved. This program and the accompanying materials
 | |
| are licensed and made available under the terms and conditions of the BSD License
 | |
| which accompanies this distribution.  The full text of the license may be found at
 | |
| http://opensource.org/licenses/bsd-license.php
 | |
| 
 | |
| THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 | |
| WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | |
| 
 | |
| **/
 | |
| 
 | |
| 
 | |
| 
 | |
| #include "UefiLibInternal.h"
 | |
| 
 | |
| /**
 | |
|   An empty function to pass error checking of CreateEventEx ().
 | |
| 
 | |
|   This empty function ensures that EVT_NOTIFY_SIGNAL_ALL is error
 | |
|   checked correctly since it is now mapped into CreateEventEx() in UEFI 2.0.
 | |
|  
 | |
|   @param  Event                 Event whose notification function is being invoked.
 | |
|   @param  Context               Pointer to the notification function's context,
 | |
|                                 which is implementation-dependent.
 | |
| 
 | |
| **/
 | |
| VOID
 | |
| EFIAPI
 | |
| InternalEmptyFuntion (
 | |
|   IN EFI_EVENT                Event,
 | |
|   IN VOID                     *Context
 | |
|   )
 | |
| {
 | |
|   return;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Create a Legacy Boot Event.
 | |
| 
 | |
|   Tiano extended the CreateEvent Type enum to add a legacy boot event type.
 | |
|   This was bad as Tiano did not own the enum. In UEFI 2.0 CreateEventEx was
 | |
|   added and now it's possible to not voilate the UEFI specification by
 | |
|   declaring a GUID for the legacy boot event class. This library supports
 | |
|   the EDK/EFI 1.10 form and EDK II/UEFI 2.0 form and allows common code to
 | |
|   work both ways.
 | |
| 
 | |
|   @param  LegacyBootEvent   Returns the EFI event returned from gBS->CreateEvent(Ex).
 | |
| 
 | |
|   @retval EFI_SUCCESS       Event was created.
 | |
|   @retval Other             Event was not created.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| EfiCreateEventLegacyBoot (
 | |
|   OUT EFI_EVENT  *LegacyBootEvent
 | |
|   )
 | |
| {
 | |
|   return EfiCreateEventLegacyBootEx (
 | |
|            TPL_CALLBACK,
 | |
|            InternalEmptyFuntion,
 | |
|            NULL,
 | |
|            LegacyBootEvent
 | |
|            );
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Create an EFI event in the Legacy Boot Event Group and allows
 | |
|   the caller to specify a notification function.
 | |
| 
 | |
|   This function abstracts the creation of the Legacy Boot Event.
 | |
|   The Framework moved from a proprietary to UEFI 2.0 based mechanism.
 | |
|   This library abstracts the caller from how this event is created to prevent
 | |
|   to code form having to change with the version of the specification supported.
 | |
|   If LegacyBootEvent is NULL, then ASSERT().
 | |
| 
 | |
|   @param  NotifyTpl         The task priority level of the event.
 | |
|   @param  NotifyFunction    The notification function to call when the event is signaled.
 | |
|   @param  NotifyContext     The content to pass to NotifyFunction when the event is signaled.
 | |
|   @param  LegacyBootEvent   Returns the EFI event returned from gBS->CreateEvent(Ex).
 | |
| 
 | |
|   @retval EFI_SUCCESS       Event was created.
 | |
|   @retval Other             Event was not created.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| EfiCreateEventLegacyBootEx (
 | |
|   IN  EFI_TPL           NotifyTpl,
 | |
|   IN  EFI_EVENT_NOTIFY  NotifyFunction,  OPTIONAL
 | |
|   IN  VOID              *NotifyContext,  OPTIONAL
 | |
|   OUT EFI_EVENT         *LegacyBootEvent
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS    Status;
 | |
| 
 | |
|   ASSERT (LegacyBootEvent != NULL);
 | |
| 
 | |
|   if (gST->Hdr.Revision < 0x00020000) {
 | |
|     //
 | |
|     // prior to UEFI 2.0 use Tiano extension to EFI
 | |
|     //
 | |
|     Status = gBS->CreateEvent (
 | |
|                     EFI_EVENT_SIGNAL_LEGACY_BOOT | EVT_NOTIFY_SIGNAL,
 | |
|                     NotifyTpl,
 | |
|                     NotifyFunction,
 | |
|                     NotifyContext,
 | |
|                     LegacyBootEvent
 | |
|                     );
 | |
|   } else {
 | |
|     //
 | |
|     // For UEFI 2.0 and the future use an Event Group
 | |
|     //
 | |
|     Status = gBS->CreateEventEx (
 | |
|                     EVT_NOTIFY_SIGNAL,
 | |
|                     NotifyTpl,
 | |
|                     NotifyFunction,
 | |
|                     NotifyContext,
 | |
|                     &gEfiEventLegacyBootGuid,
 | |
|                     LegacyBootEvent
 | |
|                     );
 | |
|   }
 | |
| 
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Create a Read to Boot Event.
 | |
| 
 | |
|   Tiano extended the CreateEvent Type enum to add a ready to boot event type.
 | |
|   This was bad as Tiano did not own the enum. In UEFI 2.0 CreateEventEx was
 | |
|   added and now it's possible to not voilate the UEFI specification and use
 | |
|   the ready to boot event class defined in UEFI 2.0. This library supports
 | |
|   the EDK/EFI 1.10 form and EDK II/UEFI 2.0 form and allows common code to
 | |
|   work both ways.
 | |
| 
 | |
|   @param  ReadyToBootEvent   Returns the EFI event returned from gBS->CreateEvent(Ex).
 | |
| 
 | |
|   @retval EFI_SUCCESS       Event was created.
 | |
|   @retval Other             Event was not created.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| EfiCreateEventReadyToBoot (
 | |
|   OUT EFI_EVENT  *ReadyToBootEvent
 | |
|   )
 | |
| {
 | |
|   return EfiCreateEventReadyToBootEx (
 | |
|            TPL_CALLBACK,
 | |
|            InternalEmptyFuntion,
 | |
|            NULL,
 | |
|            ReadyToBootEvent
 | |
|            );
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Create an EFI event in the Ready To Boot Event Group and allows
 | |
|   the caller to specify a notification function.
 | |
| 
 | |
|   This function abstracts the creation of the Ready to Boot Event.
 | |
|   The Framework moved from a proprietary to UEFI 2.0 based mechanism.
 | |
|   This library abstracts the caller from how this event is created to prevent
 | |
|   to code form having to change with the version of the specification supported.
 | |
|   If ReadyToBootEvent is NULL, then ASSERT().
 | |
| 
 | |
|   @param  NotifyTpl         The task priority level of the event.
 | |
|   @param  NotifyFunction    The notification function to call when the event is signaled.
 | |
|   @param  NotifyContext     The content to pass to NotifyFunction when the event is signaled.
 | |
|   @param  ReadyToBootEvent  Returns the EFI event returned from gBS->CreateEvent(Ex).
 | |
| 
 | |
|   @retval EFI_SUCCESS       Event was created.
 | |
|   @retval Other             Event was not created.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| EfiCreateEventReadyToBootEx (
 | |
|   IN  EFI_TPL           NotifyTpl,
 | |
|   IN  EFI_EVENT_NOTIFY  NotifyFunction,  OPTIONAL
 | |
|   IN  VOID              *NotifyContext,  OPTIONAL
 | |
|   OUT EFI_EVENT         *ReadyToBootEvent
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS    Status;
 | |
| 
 | |
|   ASSERT (ReadyToBootEvent != NULL);
 | |
| 
 | |
|   if (gST->Hdr.Revision < 0x00020000) {
 | |
|     //
 | |
|     // prior to UEFI 2.0 use Tiano extension to EFI
 | |
|     //
 | |
|     Status = gBS->CreateEvent (
 | |
|                     EFI_EVENT_SIGNAL_READY_TO_BOOT | EFI_EVENT_NOTIFY_SIGNAL_ALL,
 | |
|                     NotifyTpl,
 | |
|                     NotifyFunction,
 | |
|                     NotifyContext,
 | |
|                     ReadyToBootEvent
 | |
|                     );
 | |
|   } else {
 | |
|     //
 | |
|     // For UEFI 2.0 and the future use an Event Group
 | |
|     //
 | |
|     Status = gBS->CreateEventEx (
 | |
|                     EVT_NOTIFY_SIGNAL,
 | |
|                     NotifyTpl,
 | |
|                     NotifyFunction,
 | |
|                     NotifyContext,
 | |
|                     &gEfiEventReadyToBootGuid,
 | |
|                     ReadyToBootEvent
 | |
|                     );
 | |
|   }
 | |
| 
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| 
 | |
| /**
 | |
|   Signal a Ready to Boot Event.
 | |
| 
 | |
|   Create a Ready to Boot Event. Signal it and close it. This causes other
 | |
|   events of the same event group to be signaled in other modules.
 | |
| 
 | |
| **/
 | |
| VOID
 | |
| EFIAPI
 | |
| EfiSignalEventReadyToBoot (
 | |
|   VOID
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS    Status;
 | |
|   EFI_EVENT     ReadyToBootEvent;
 | |
| 
 | |
|   Status = EfiCreateEventReadyToBoot (&ReadyToBootEvent);
 | |
|   if (!EFI_ERROR (Status)) {
 | |
|     gBS->SignalEvent (ReadyToBootEvent);
 | |
|     gBS->CloseEvent (ReadyToBootEvent);
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Signal a Legacy Boot Event.
 | |
| 
 | |
|   Create a legacy Boot Event. Signal it and close it. This causes other
 | |
|   events of the same event group to be signaled in other modules.
 | |
| 
 | |
| **/
 | |
| VOID
 | |
| EFIAPI
 | |
| EfiSignalEventLegacyBoot (
 | |
|   VOID
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS    Status;
 | |
|   EFI_EVENT     LegacyBootEvent;
 | |
| 
 | |
|   Status = EfiCreateEventLegacyBoot (&LegacyBootEvent);
 | |
|   if (!EFI_ERROR (Status)) {
 | |
|     gBS->SignalEvent (LegacyBootEvent);
 | |
|     gBS->CloseEvent (LegacyBootEvent);
 | |
|   }
 | |
| }
 | |
| 
 | |
| 
 | |
| /**
 | |
|   Check to see if the Firmware Volume (FV) Media Device Path is valid
 | |
| 
 | |
|   Tiano extended the EFI 1.10 device path nodes. Tiano does not own this enum
 | |
|   so as we move to UEFI 2.0 support we must use a mechanism that conforms with
 | |
|   the UEFI 2.0 specification to define the FV device path. An UEFI GUIDed
 | |
|   device path is defined for Tiano extensions of device path. If the code
 | |
|   is compiled to conform with the UEFI 2.0 specification use the new device path
 | |
|   else use the old form for backwards compatability. The return value to this
 | |
|   function points to a location in FvDevicePathNode and it does not allocate
 | |
|   new memory for the GUID pointer that is returned.
 | |
| 
 | |
|   @param  FvDevicePathNode  Pointer to FV device path to check.
 | |
| 
 | |
|   @retval NULL              FvDevicePathNode is not valid.
 | |
|   @retval Other             FvDevicePathNode is valid and pointer to NameGuid was returned.
 | |
| 
 | |
| **/
 | |
| EFI_GUID *
 | |
| EFIAPI
 | |
| EfiGetNameGuidFromFwVolDevicePathNode (
 | |
|   IN CONST MEDIA_FW_VOL_FILEPATH_DEVICE_PATH  *FvDevicePathNode
 | |
|   )
 | |
| {
 | |
|   FRAMEWORK_MEDIA_FW_VOL_FILEPATH_DEVICE_PATH  *FrameworkFvDevicePathNode;
 | |
| 
 | |
|   ASSERT (FvDevicePathNode != NULL);
 | |
| 
 | |
|   FrameworkFvDevicePathNode = (FRAMEWORK_MEDIA_FW_VOL_FILEPATH_DEVICE_PATH  *) FvDevicePathNode;
 | |
|   //
 | |
|   // Use the new Device path that does not conflict with the UEFI
 | |
|   //
 | |
|   if (DevicePathType (&FrameworkFvDevicePathNode->Tiano.Header) == MEDIA_DEVICE_PATH &&
 | |
|       DevicePathSubType (&FrameworkFvDevicePathNode->Tiano.Header) == MEDIA_VENDOR_DP) {
 | |
|     if (CompareGuid (&gEfiFrameworkDevicePathGuid, &FrameworkFvDevicePathNode->Tiano.TianoSpecificDevicePath)) {
 | |
|       if (FrameworkFvDevicePathNode->Tiano.Type == TIANO_MEDIA_FW_VOL_FILEPATH_DEVICE_PATH_TYPE) {
 | |
|         return (EFI_GUID *) &FrameworkFvDevicePathNode->NameGuid;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return NULL;
 | |
| }
 | |
| 
 | |
| 
 | |
| /**
 | |
|   Initialize a Firmware Volume (FV) Media Device Path node.
 | |
| 
 | |
|   Tiano extended the EFI 1.10 device path nodes. Tiano does not own this enum
 | |
|   so as we move to UEFI 2.0 support we must use a mechanism that conforms with
 | |
|   the UEFI 2.0 specification to define the FV device path. An UEFI GUIDed
 | |
|   device path is defined for Tiano extensions of device path. If the code
 | |
|   is compiled to conform with the UEFI 2.0 specification use the new device path
 | |
|   else use the old form for backwards compatability.
 | |
| 
 | |
|   @param  FvDevicePathNode  Pointer to a FV device path node to initialize
 | |
|   @param  NameGuid          FV file name to use in FvDevicePathNode
 | |
| 
 | |
| **/
 | |
| VOID
 | |
| EFIAPI
 | |
| EfiInitializeFwVolDevicepathNode (
 | |
|   IN OUT MEDIA_FW_VOL_FILEPATH_DEVICE_PATH  *FvDevicePathNode,
 | |
|   IN CONST EFI_GUID                         *NameGuid
 | |
|   )
 | |
| {
 | |
|   FRAMEWORK_MEDIA_FW_VOL_FILEPATH_DEVICE_PATH  *FrameworkFvDevicePathNode;
 | |
| 
 | |
|   ASSERT (FvDevicePathNode  != NULL);
 | |
|   ASSERT (NameGuid          != NULL);
 | |
| 
 | |
|   FrameworkFvDevicePathNode = (FRAMEWORK_MEDIA_FW_VOL_FILEPATH_DEVICE_PATH  *) FvDevicePathNode;
 | |
| 
 | |
|   //
 | |
|   // Use the new Device path that does not conflict with the UEFI
 | |
|   //
 | |
|   FrameworkFvDevicePathNode->Tiano.Header.Type     = MEDIA_DEVICE_PATH;
 | |
|   FrameworkFvDevicePathNode->Tiano.Header.SubType  = MEDIA_VENDOR_DP;
 | |
|   SetDevicePathNodeLength (&FrameworkFvDevicePathNode->Tiano.Header, sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH));
 | |
| 
 | |
|   //
 | |
|   // Add the GUID for generic Tiano device paths
 | |
|   //
 | |
|   CopyGuid (&FrameworkFvDevicePathNode->Tiano.TianoSpecificDevicePath, &gEfiFrameworkDevicePathGuid);
 | |
| 
 | |
|   //
 | |
|   // Add in the FW Vol File Path Tiano defined information
 | |
|   //
 | |
|   FrameworkFvDevicePathNode->Tiano.Type = TIANO_MEDIA_FW_VOL_FILEPATH_DEVICE_PATH_TYPE;
 | |
| 
 | |
|   CopyGuid (&FrameworkFvDevicePathNode->NameGuid, NameGuid);
 | |
| }
 | |
| 
 |