Signed-off-by: niruiyu Reviewed-by: lgao4 git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12552 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			352 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			352 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*++
 | 
						|
 | 
						|
Copyright (c) 2004 - 2011, 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.
 | 
						|
 | 
						|
Module Name:
 | 
						|
 | 
						|
  Event.c
 | 
						|
 | 
						|
Abstract:
 | 
						|
 | 
						|
  Support for Event lib fucntions.
 | 
						|
 | 
						|
--*/
 | 
						|
 | 
						|
#include "Tiano.h"
 | 
						|
#include "EfiRuntimeLib.h"
 | 
						|
 | 
						|
EFI_EVENT
 | 
						|
RtEfiLibCreateProtocolNotifyEvent (
 | 
						|
  IN EFI_GUID             *ProtocolGuid,
 | 
						|
  IN EFI_TPL              NotifyTpl,
 | 
						|
  IN EFI_EVENT_NOTIFY     NotifyFunction,
 | 
						|
  IN VOID                 *NotifyContext,
 | 
						|
  OUT VOID                **Registration
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  Create a protocol notification event and return it.
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  ProtocolGuid    - Protocol to register notification event on.
 | 
						|
 | 
						|
  NotifyTpl       - Maximum TPL to single the NotifyFunction.
 | 
						|
 | 
						|
  NotifyFunction  - EFI notification routine.
 | 
						|
 | 
						|
  NotifyContext   - Context passed into Event when it is created.
 | 
						|
 | 
						|
  Registration    - Registration key returned from RegisterProtocolNotify().
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  The EFI_EVENT that has been registered to be signaled when a ProtocolGuid
 | 
						|
  is added to the system.
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  EFI_STATUS  Status;
 | 
						|
  EFI_EVENT   Event;
 | 
						|
 | 
						|
  //
 | 
						|
  // Create the event
 | 
						|
  //
 | 
						|
  Status = gBS->CreateEvent (
 | 
						|
                  EFI_EVENT_NOTIFY_SIGNAL,
 | 
						|
                  NotifyTpl,
 | 
						|
                  NotifyFunction,
 | 
						|
                  NotifyContext,
 | 
						|
                  &Event
 | 
						|
                  );
 | 
						|
  ASSERT (!EFI_ERROR (Status));
 | 
						|
 | 
						|
  //
 | 
						|
  // Register for protocol notifactions on this event
 | 
						|
  //
 | 
						|
  Status = gBS->RegisterProtocolNotify (
 | 
						|
                  ProtocolGuid,
 | 
						|
                  Event,
 | 
						|
                  Registration
 | 
						|
                  );
 | 
						|
 | 
						|
  ASSERT (!EFI_ERROR (Status));
 | 
						|
 | 
						|
  //
 | 
						|
  // Kick the event so we will perform an initial pass of
 | 
						|
  // current installed drivers
 | 
						|
  //
 | 
						|
  gBS->SignalEvent (Event);
 | 
						|
  return Event;
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
EfiLibGetSystemConfigurationTable (
 | 
						|
  IN EFI_GUID *TableGuid,
 | 
						|
  IN OUT VOID **Table
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  Return the EFI 1.0 System Tabl entry with TableGuid
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  TableGuid - Name of entry to return in the system table
 | 
						|
  Table     - Pointer in EFI system table associated with TableGuid
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  EFI_SUCCESS - Table returned;
 | 
						|
  EFI_NOT_FOUND - TableGuid not in EFI system table
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  UINTN Index;
 | 
						|
 | 
						|
  for (Index = 0; Index < gST->NumberOfTableEntries; Index++) {
 | 
						|
    if (EfiCompareGuid (TableGuid, &(gST->ConfigurationTable[Index].VendorGuid))) {
 | 
						|
      *Table = gST->ConfigurationTable[Index].VendorTable;
 | 
						|
      return EFI_SUCCESS;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_NOT_FOUND;
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
EfiConvertList (
 | 
						|
  IN UINTN                DebugDisposition,
 | 
						|
  IN OUT EFI_LIST_ENTRY   *ListHead
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  Conver the standard Lib double linked list to a virtual mapping.
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  DebugDisposition - Argument to EfiConvertPointer (EFI 1.0 API)
 | 
						|
 | 
						|
  ListHead         - Head of linked list to convert
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  EFI_SUCCESS
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  EFI_LIST_ENTRY  *Link;
 | 
						|
  EFI_LIST_ENTRY  *NextLink;
 | 
						|
 | 
						|
  //
 | 
						|
  // Convert all the ForwardLink & BackLink pointers in the list
 | 
						|
  //
 | 
						|
  Link = ListHead;
 | 
						|
  do {
 | 
						|
    NextLink = Link->ForwardLink;
 | 
						|
 | 
						|
    EfiConvertPointer (
 | 
						|
      Link->ForwardLink == ListHead ? DebugDisposition : 0,
 | 
						|
      (VOID **) &Link->ForwardLink
 | 
						|
      );
 | 
						|
 | 
						|
    EfiConvertPointer (
 | 
						|
      Link->BackLink == ListHead ? DebugDisposition : 0,
 | 
						|
      (VOID **) &Link->BackLink
 | 
						|
      );
 | 
						|
 | 
						|
    Link = NextLink;
 | 
						|
  } while (Link != ListHead);
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
#if (EFI_SPECIFICATION_VERSION >= 0x00020000)
 | 
						|
 | 
						|
STATIC
 | 
						|
VOID
 | 
						|
EFIAPI
 | 
						|
EventNotifySignalAllNullEvent (
 | 
						|
  IN EFI_EVENT                Event,
 | 
						|
  IN VOID                     *Context
 | 
						|
  )
 | 
						|
{
 | 
						|
  //
 | 
						|
  // This null event is a size efficent way to enusre that 
 | 
						|
  // EFI_EVENT_NOTIFY_SIGNAL_ALL is error checked correctly.
 | 
						|
  // EFI_EVENT_NOTIFY_SIGNAL_ALL is now mapped into 
 | 
						|
  // CreateEventEx() and this function is used to make the
 | 
						|
  // old error checking in CreateEvent() for Tiano extensions
 | 
						|
  // function.
 | 
						|
  //
 | 
						|
  return;
 | 
						|
}
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
RtEfiCreateEventLegacyBoot (
 | 
						|
  IN EFI_TPL                      NotifyTpl,
 | 
						|
  IN EFI_EVENT_NOTIFY             NotifyFunction,
 | 
						|
  IN VOID                         *NotifyContext,
 | 
						|
  OUT EFI_EVENT                   *LegacyBootEvent
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
  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 EFI 1.10 form and UEFI 2.0 form and allows common code to work both ways.
 | 
						|
 | 
						|
Arguments:
 | 
						|
  LegacyBootEvent  Returns the EFI event returned from gBS->CreateEvent(Ex)
 | 
						|
 | 
						|
Returns:
 | 
						|
  EFI_SUCCESS   Event was created.
 | 
						|
  Other         Event was not created.
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  EFI_STATUS        Status;
 | 
						|
  UINT32            EventType;
 | 
						|
  EFI_EVENT_NOTIFY  WorkerNotifyFunction;
 | 
						|
 | 
						|
#if (EFI_SPECIFICATION_VERSION < 0x00020000)
 | 
						|
 | 
						|
  if (NotifyFunction == NULL) {
 | 
						|
    EventType = EFI_EVENT_SIGNAL_LEGACY_BOOT | EFI_EVENT_NOTIFY_SIGNAL_ALL;
 | 
						|
  } else {
 | 
						|
    EventType = EFI_EVENT_SIGNAL_LEGACY_BOOT;
 | 
						|
  }
 | 
						|
  WorkerNotifyFunction = NotifyFunction;
 | 
						|
 | 
						|
  //
 | 
						|
  // prior to UEFI 2.0 use Tiano extension to EFI
 | 
						|
  //
 | 
						|
  Status = gBS->CreateEvent (
 | 
						|
                  EventType,
 | 
						|
                  NotifyTpl,
 | 
						|
                  WorkerNotifyFunction,
 | 
						|
                  NotifyContext,
 | 
						|
                  LegacyBootEvent
 | 
						|
                  );
 | 
						|
#else
 | 
						|
 | 
						|
  EventType = EFI_EVENT_NOTIFY_SIGNAL;
 | 
						|
  if (NotifyFunction == NULL) {
 | 
						|
    //
 | 
						|
    // CreatEventEx will check NotifyFunction is NULL or not
 | 
						|
    //
 | 
						|
    WorkerNotifyFunction = EventNotifySignalAllNullEvent;
 | 
						|
  } else {
 | 
						|
    WorkerNotifyFunction = NotifyFunction;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // For UEFI 2.0 and the future use an Event Group
 | 
						|
  //
 | 
						|
  Status = gBS->CreateEventEx (
 | 
						|
                  EventType,
 | 
						|
                  NotifyTpl,
 | 
						|
                  WorkerNotifyFunction,
 | 
						|
                  NotifyContext,
 | 
						|
                  &gEfiEventLegacyBootGuid,
 | 
						|
                  LegacyBootEvent
 | 
						|
                  );
 | 
						|
#endif
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
RtEfiCreateEventReadyToBoot (
 | 
						|
  IN EFI_TPL                      NotifyTpl,
 | 
						|
  IN EFI_EVENT_NOTIFY             NotifyFunction,
 | 
						|
  IN VOID                         *NotifyContext,
 | 
						|
  OUT EFI_EVENT                   *ReadyToBootEvent
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
  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 EFI 1.10 form and UEFI 2.0 form and allows common code to work both ways.
 | 
						|
 | 
						|
Arguments:
 | 
						|
  ReadyToBootEvent  Returns the EFI event returned from gBS->CreateEvent(Ex)
 | 
						|
 | 
						|
Return:
 | 
						|
  EFI_SUCCESS   - Event was created.
 | 
						|
  Other         - Event was not created.
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  EFI_STATUS        Status;
 | 
						|
  UINT32            EventType;
 | 
						|
  EFI_EVENT_NOTIFY  WorkerNotifyFunction;
 | 
						|
 | 
						|
#if (EFI_SPECIFICATION_VERSION < 0x00020000)
 | 
						|
 | 
						|
  if (NotifyFunction == NULL) {
 | 
						|
    EventType = EFI_EVENT_SIGNAL_READY_TO_BOOT | EFI_EVENT_NOTIFY_SIGNAL_ALL;
 | 
						|
  } else {
 | 
						|
    EventType = EFI_EVENT_SIGNAL_READY_TO_BOOT;
 | 
						|
  }
 | 
						|
  WorkerNotifyFunction = NotifyFunction;
 | 
						|
 | 
						|
  //
 | 
						|
  // prior to UEFI 2.0 use Tiano extension to EFI
 | 
						|
  //
 | 
						|
  Status = gBS->CreateEvent (
 | 
						|
                  EventType,
 | 
						|
                  NotifyTpl,
 | 
						|
                  WorkerNotifyFunction,
 | 
						|
                  NotifyContext,
 | 
						|
                  ReadyToBootEvent
 | 
						|
                  );
 | 
						|
#else
 | 
						|
 | 
						|
  EventType = EFI_EVENT_NOTIFY_SIGNAL;
 | 
						|
  if (NotifyFunction == NULL) {
 | 
						|
    //
 | 
						|
    // CreatEventEx will check NotifyFunction is NULL or not
 | 
						|
    //
 | 
						|
    WorkerNotifyFunction = EventNotifySignalAllNullEvent;
 | 
						|
  } else {
 | 
						|
    WorkerNotifyFunction = NotifyFunction;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // For UEFI 2.0 and the future use an Event Group
 | 
						|
  //
 | 
						|
  Status = gBS->CreateEventEx (
 | 
						|
                  EventType,
 | 
						|
                  NotifyTpl,
 | 
						|
                  WorkerNotifyFunction,
 | 
						|
                  NotifyContext,
 | 
						|
                  &gEfiEventReadyToBootGuid,
 | 
						|
                  ReadyToBootEvent
 | 
						|
                  );
 | 
						|
#endif
 | 
						|
  return Status;
 | 
						|
}
 |