event.c

来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 823 行 · 第 1/2 页

C
823
字号
/*++

Copyright (c) 2004 - 2006, Intel Corporation                                                         
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.             

Module Name:

  event.c

Abstract:

  EFI Event support.
 
--*/

#include "exec.h"
#include "..\hand\hand.h"

//
// Enumerate the valid types
//
UINT32 mEventTable[] = {
  //
  // 0x80000200       Timer event with a notification function that is
  // queue when the event is signaled with SignalEvent()
  //
  EFI_EVENT_TIMER | EFI_EVENT_NOTIFY_SIGNAL,
  //
  // 0x80000000       Timer event without a notification function. It can be
  // signaled with SignalEvent() and checked with CheckEvent() or WaitForEvent().
  //
  EFI_EVENT_TIMER,
  //
  // 0x00000100       Generic event with a notification function that 
  // can be waited on with CheckEvent() or WaitForEvent()
  //
  EFI_EVENT_NOTIFY_WAIT,
  //
  // 0x00000200       Generic event with a notification function that 
  // is queue when the event is signaled with SignalEvent()
  //
  EFI_EVENT_NOTIFY_SIGNAL,
  //
  // 0x00000201       ExitBootServicesEvent.  
  //
  EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES,
  //
  // 0x60000202       SetVirtualAddressMapEvent.
  //
  EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,
#if (EFI_SPECIFICATION_VERSION < 0x00020000)
  //
  // 0x00000203       ReadyToBootEvent.
  //
  EFI_EVENT_SIGNAL_READY_TO_BOOT,
  //
  // 0x00000204       LegacyBootEvent.
  //
  EFI_EVENT_SIGNAL_LEGACY_BOOT,
  //
  // 0x00000603       Signal all ReadyToBootEvents.
  //
  EFI_EVENT_NOTIFY_SIGNAL_ALL | EFI_EVENT_SIGNAL_READY_TO_BOOT,
  //
  // 0x00000604       Signal all LegacyBootEvents.
  //
  EFI_EVENT_NOTIFY_SIGNAL_ALL | EFI_EVENT_SIGNAL_LEGACY_BOOT,
  //
  // 0x00000000       Generic event without a notification function. 
  // It can be signaled with SignalEvent() and checked with CheckEvent() 
  // or WaitForEvent().
  //
#endif
  0x00000000,
  //
  // 0x80000100       Timer event with a notification function that can be 
  // waited on with CheckEvent() or WaitForEvent()
  //
  EFI_EVENT_TIMER | EFI_EVENT_NOTIFY_WAIT,
};


VOID
CoreAcquireEventLock (
  VOID
  )
/*++

Routine Description:

  Enter critical section by acquiring the lock on gEventQueueLock.

Arguments:

  None

Returns:

  None

--*/
{
  CoreAcquireLock (&gEventQueueLock);
}


VOID
CoreReleaseEventLock (
  VOID
  )
/*++

Routine Description:

  Exit critical section by releasing the lock on gEventQueueLock.

Arguments:

  None

Returns:

  None

--*/
{
  CoreReleaseLock (&gEventQueueLock);
}


EFI_STATUS
CoreInitializeEventServices (
  VOID
  )
/*++

Routine Description:

  Initializes "event" support and populates parts of the System and Runtime Table.

Arguments:

  None
    
Returns:

  EFI_SUCCESS - Always return success

--*/
{
  UINTN        Index;

  for (Index=0; Index <= EFI_TPL_HIGH_LEVEL; Index ++) {
    InitializeListHead (&gEventQueue[Index]);
  }

  CoreInitializeTimer ();
  
  return EFI_SUCCESS;
}


VOID
CoreDispatchEventNotifies (
  IN EFI_TPL      Priority
  )
/*++

Routine Description:

  Dispatches all pending events. 

Arguments:

  Priority - The task priority level of event notifications to dispatch
    
Returns:

  None

--*/
{
  IEVENT          *Event;
  EFI_LIST_ENTRY  *Head;
  
  CoreAcquireEventLock ();
  ASSERT (gEventQueueLock.OwnerTpl == Priority);
  Head = &gEventQueue[Priority];

  //
  // Dispatch all the pending notifications
  //
  while (!IsListEmpty (Head)) {
      
    Event = CR (Head->ForwardLink, IEVENT, NotifyLink, EVENT_SIGNATURE);
    RemoveEntryList (&Event->NotifyLink);

    Event->NotifyLink.ForwardLink = NULL;

    //
    // Only clear the SIGNAL status if it is a SIGNAL type event.
    // WAIT type events are only cleared in CheckEvent()
    //
    if (Event->Type & EFI_EVENT_NOTIFY_SIGNAL) {
      Event->SignalCount = 0;
    }

    CoreReleaseEventLock ();
      
    //
    // Notify this event
    //
    Event->NotifyFunction (Event, Event->NotifyContext);

    //
    // Check for next pending event
    //
    CoreAcquireEventLock ();
  }

  gEventPending &= ~(1 << Priority);
  CoreReleaseEventLock ();
}


VOID
STATIC
CoreNotifyEvent (
  IN  IEVENT      *Event
  )
/*++

Routine Description:

  Queues the event's notification function to fire

Arguments:

  Event       - The Event to notify
    
Returns:

  None

--*/
{

  //
  // Event database must be locked
  //
  ASSERT_LOCKED (&gEventQueueLock);

  //
  // If the event is queued somewhere, remove it
  //

  if (Event->NotifyLink.ForwardLink != NULL) {
    RemoveEntryList (&Event->NotifyLink);
    Event->NotifyLink.ForwardLink = NULL;
  }

  // 
  // Queue the event to the pending notification list
  //

  InsertTailList (&gEventQueue[Event->NotifyTpl], &Event->NotifyLink);
  gEventPending |= 1 << Event->NotifyTpl;
}



VOID
CoreNotifySignalList (
  IN EFI_GUID     *EventGroup
  )
/*++

Routine Description:

  Signals all events on the requested list

Arguments:

  SignalType      - The list to signal
    
Returns:

  None

--*/
{
  EFI_LIST_ENTRY          *Link;
  EFI_LIST_ENTRY          *Head;
  IEVENT                  *Event;

  CoreAcquireEventLock ();

  Head = &gEventSignalQueue;
  for (Link = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) {
    Event = CR (Link, IEVENT, SignalLink, EVENT_SIGNATURE);
    if ((Event->ExFlag) && EfiCompareGuid (&Event->EventGroup, EventGroup)) {
      CoreNotifyEvent (Event);
    }
  }

  CoreReleaseEventLock ();
}

#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_BOOTSERVICE
EFI_STATUS
EFIAPI
CoreCreateEvent (
  IN UINT32                   Type,
  IN EFI_TPL                  NotifyTpl,
  IN EFI_EVENT_NOTIFY         NotifyFunction,
  IN VOID                     *NotifyContext,
  OUT EFI_EVENT               *Event
  )
/*++

Routine Description:

  Creates a general-purpose event structure

Arguments:

  Type                - The type of event to create and its mode and attributes
  NotifyTpl           - The task priority level of event notifications
  NotifyFunction      - Pointer to the events notification function
  NotifyContext       - Pointer to the notification functions context; corresponds to
                        parameter "Context" in the notification function
  Event               - Pointer to the newly created event if the call succeeds; undefined otherwise

Returns:

  EFI_SUCCESS           - The event structure was created
  EFI_INVALID_PARAMETER - One of the parameters has an invalid value
  EFI_OUT_OF_RESOURCES  - The event could not be allocated

--*/
{ 
  EFI_GUID            *GuidPtr;
  EFI_EVENT_NOTIFY    Function;
  
  GuidPtr = NULL;
  Function = NotifyFunction;

#if (EFI_SPECIFICATION_VERSION < 0x00020000)
  //
  // Clear EFI_EVENT_NOFITY_SIGNAL_ALL (Tiano extension) as all events in the 
  // EventGroup now have this property. So we need to filter it out.
  //
  if (Type & EFI_EVENT_NOTIFY_SIGNAL_ALL) {
    Type &= ~EFI_EVENT_NOTIFY_SIGNAL_ALL;
    Function = EventNotifySignalAllNullEvent;
  }

  //
  // Map the Tiano extensions Events to CreateEventEx form
  //
  if (Type == EFI_EVENT_SIGNAL_READY_TO_BOOT) {
    GuidPtr = &gEfiEventReadyToBootGuid;
  } else if (Type == EFI_EVENT_SIGNAL_LEGACY_BOOT) {
    GuidPtr = &gEfiEventLegacyBootGuid;
  }
#endif

  //
  // Convert EFI 1.10 Events to thier UEFI 2.0 CreateEventEx mapping
  // 
  if (Type == EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES) {
    GuidPtr = &gEfiEventExitBootServicesGuid;
  } else if (Type == EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE) {
    GuidPtr = &gEfiEventVirtualAddressChangeGuid;
  }
  
  return CoreCreateEventEx (Type, NotifyTpl, Function, NotifyContext, GuidPtr, Event);
}

EFI_BOOTSERVICE
EFI_STATUS
EFIAPI

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?