mirror of
				https://git.proxmox.com/git/mirror_edk2
				synced 2025-11-04 02:40:26 +00:00 
			
		
		
		
	Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Mars Lin <Mars_Lin@phoenix.com> Reviewed-by: Liming Gao <liming.gao@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14631 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			358 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			358 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 - 2008, Intel Corporation. All rights reserved.<BR>
 | 
						|
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               The pointer to the notification function's context,
 | 
						|
                                which is implementation-dependent.
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
EFIAPI
 | 
						|
InternalEmptyFunction (
 | 
						|
  IN EFI_EVENT                Event,
 | 
						|
  IN VOID                     *Context
 | 
						|
  )
 | 
						|
{
 | 
						|
  return;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Creates an EFI event in the Legacy Boot Event Group.
 | 
						|
 | 
						|
  Prior to UEFI 2.0 this was done via a non blessed UEFI extensions and this library
 | 
						|
  abstracts the implementation mechanism of this event from the caller. 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  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,
 | 
						|
           InternalEmptyFunction,
 | 
						|
           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;
 | 
						|
  EFI_EVENT_NOTIFY  WorkerNotifyFunction;
 | 
						|
 | 
						|
  ASSERT (LegacyBootEvent != NULL);
 | 
						|
 | 
						|
  if (gST->Hdr.Revision < EFI_2_00_SYSTEM_TABLE_REVISION) {
 | 
						|
    DEBUG ((EFI_D_ERROR, "EFI1.1 can't support LegacyBootEvent!"));
 | 
						|
    ASSERT (FALSE);
 | 
						|
 | 
						|
    return EFI_UNSUPPORTED;
 | 
						|
  } else {
 | 
						|
    //
 | 
						|
    // For UEFI 2.0 and the future use an Event Group
 | 
						|
    //
 | 
						|
    if (NotifyFunction == NULL) {
 | 
						|
      //
 | 
						|
      // CreateEventEx will check NotifyFunction is NULL or not and return error.
 | 
						|
      // Use dummy routine for the case NotifyFunction is NULL.
 | 
						|
      //
 | 
						|
      WorkerNotifyFunction = InternalEmptyFunction;
 | 
						|
    } else {
 | 
						|
      WorkerNotifyFunction = NotifyFunction;
 | 
						|
    }
 | 
						|
    Status = gBS->CreateEventEx (
 | 
						|
                    EVT_NOTIFY_SIGNAL,
 | 
						|
                    NotifyTpl,
 | 
						|
                    WorkerNotifyFunction,
 | 
						|
                    NotifyContext,
 | 
						|
                    &gEfiEventLegacyBootGuid,
 | 
						|
                    LegacyBootEvent
 | 
						|
                    );
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Create an EFI event in the Ready To Boot Event Group.
 | 
						|
 | 
						|
  Prior to UEFI 2.0 this was done via a non-standard UEFI extension, and this library
 | 
						|
  abstracts the implementation mechanism of this event from the caller.   
 | 
						|
  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 the code form having to 
 | 
						|
  change with the version of the specification supported.
 | 
						|
  If ReadyToBootEvent is NULL, then ASSERT().
 | 
						|
 | 
						|
  @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,
 | 
						|
           InternalEmptyFunction,
 | 
						|
           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;
 | 
						|
  EFI_EVENT_NOTIFY  WorkerNotifyFunction;
 | 
						|
 | 
						|
  ASSERT (ReadyToBootEvent != NULL);
 | 
						|
 | 
						|
  if (gST->Hdr.Revision < EFI_2_00_SYSTEM_TABLE_REVISION) {
 | 
						|
    DEBUG ((EFI_D_ERROR, "EFI1.1 can't support ReadyToBootEvent!"));
 | 
						|
    ASSERT (FALSE);
 | 
						|
 | 
						|
    return EFI_UNSUPPORTED;
 | 
						|
  } else {
 | 
						|
    //
 | 
						|
    // For UEFI 2.0 and the future use an Event Group
 | 
						|
    //
 | 
						|
    if (NotifyFunction == NULL) {
 | 
						|
      //
 | 
						|
      // CreateEventEx will check NotifyFunction is NULL or not and return error.
 | 
						|
      // Use dummy routine for the case NotifyFunction is NULL.
 | 
						|
      //
 | 
						|
      WorkerNotifyFunction = InternalEmptyFunction;
 | 
						|
    } else {
 | 
						|
      WorkerNotifyFunction = NotifyFunction;
 | 
						|
    }
 | 
						|
    Status = gBS->CreateEventEx (
 | 
						|
                    EVT_NOTIFY_SIGNAL,
 | 
						|
                    NotifyTpl,
 | 
						|
                    WorkerNotifyFunction,
 | 
						|
                    NotifyContext,
 | 
						|
                    &gEfiEventReadyToBootGuid,
 | 
						|
                    ReadyToBootEvent
 | 
						|
                    );
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Create, Signal, and Close the Ready to Boot event using EfiSignalEventReadyToBoot().
 | 
						|
  
 | 
						|
  This function abstracts the signaling 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.
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
EFIAPI
 | 
						|
EfiSignalEventReadyToBoot (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS    Status;
 | 
						|
  EFI_EVENT     ReadyToBootEvent;
 | 
						|
 | 
						|
  Status = EfiCreateEventReadyToBoot (&ReadyToBootEvent);
 | 
						|
  if (!EFI_ERROR (Status)) {
 | 
						|
    gBS->SignalEvent (ReadyToBootEvent);
 | 
						|
    gBS->CloseEvent (ReadyToBootEvent);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Create, Signal, and Close the Ready to Boot event using EfiSignalEventLegacyBoot().
 | 
						|
 | 
						|
  This function abstracts the signaling 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.
 | 
						|
 | 
						|
**/
 | 
						|
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 
 | 
						|
  
 | 
						|
  The Framework FwVol Device Path changed to conform to the UEFI 2.0 specification.  
 | 
						|
  This library function abstracts validating a device path node.
 | 
						|
  Check the MEDIA_FW_VOL_FILEPATH_DEVICE_PATH data structure to see if it's valid.  
 | 
						|
  If it is valid, then return the GUID file name from the device path node.  Otherwise, 
 | 
						|
  return NULL.  This device path changed in the DXE CIS version 0.92 in a non back ward 
 | 
						|
  compatible way to not conflict with the UEFI 2.0 specification.  This function abstracts 
 | 
						|
  the differences from the caller.
 | 
						|
  If FvDevicePathNode is NULL, then ASSERT().
 | 
						|
 | 
						|
  @param  FvDevicePathNode  The 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
 | 
						|
  )
 | 
						|
{
 | 
						|
  ASSERT (FvDevicePathNode != NULL);
 | 
						|
 | 
						|
  if (DevicePathType (&FvDevicePathNode->Header) == MEDIA_DEVICE_PATH &&
 | 
						|
      DevicePathSubType (&FvDevicePathNode->Header) == MEDIA_PIWG_FW_FILE_DP) {
 | 
						|
    return (EFI_GUID *) &FvDevicePathNode->FvFileName;
 | 
						|
  }
 | 
						|
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Initialize a Firmware Volume (FV) Media Device Path node.
 | 
						|
  
 | 
						|
  The Framework FwVol Device Path changed to conform to the UEFI 2.0 specification.  
 | 
						|
  This library function abstracts initializing a device path node.  
 | 
						|
  Initialize the MEDIA_FW_VOL_FILEPATH_DEVICE_PATH data structure.  This device 
 | 
						|
  path changed in the DXE CIS version 0.92 in a non back ward compatible way to 
 | 
						|
  not conflict with the UEFI 2.0 specification.  This function abstracts the 
 | 
						|
  differences from the caller.
 | 
						|
  If FvDevicePathNode is NULL, then ASSERT().
 | 
						|
  If NameGuid is NULL, then ASSERT().
 | 
						|
  
 | 
						|
  @param  FvDevicePathNode  The 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
 | 
						|
  )
 | 
						|
{
 | 
						|
  ASSERT (FvDevicePathNode != NULL);
 | 
						|
  ASSERT (NameGuid          != NULL);
 | 
						|
 | 
						|
  //
 | 
						|
  // Use the new Device path that does not conflict with the UEFI
 | 
						|
  //
 | 
						|
  FvDevicePathNode->Header.Type     = MEDIA_DEVICE_PATH;
 | 
						|
  FvDevicePathNode->Header.SubType  = MEDIA_PIWG_FW_FILE_DP;
 | 
						|
  SetDevicePathNodeLength (&FvDevicePathNode->Header, sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH));
 | 
						|
 | 
						|
  CopyGuid (&FvDevicePathNode->FvFileName, NameGuid);
 | 
						|
}
 | 
						|
 |