]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Change the file name case to follow coding style: The first character should be capital.
authorqhuang8 <qhuang8@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 21 May 2008 01:05:39 +0000 (01:05 +0000)
committerqhuang8 <qhuang8@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 21 May 2008 01:05:39 +0000 (01:05 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@5253 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Core/Dxe/Event/Event.c [new file with mode: 0644]
MdeModulePkg/Core/Dxe/Event/event.c [deleted file]

diff --git a/MdeModulePkg/Core/Dxe/Event/Event.c b/MdeModulePkg/Core/Dxe/Event/Event.c
new file mode 100644 (file)
index 0000000..834ace5
--- /dev/null
@@ -0,0 +1,688 @@
+/** @file \r
+\r
+  UEFI Event support functions implemented in this file.\r
+\r
+Copyright (c) 2006 - 2008, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+\r
+#include <DxeMain.h>\r
+\r
+//\r
+// Enumerate the valid types\r
+//\r
+UINT32 mEventTable[] = {\r
+  //\r
+  // 0x80000200       Timer event with a notification function that is\r
+  // queue when the event is signaled with SignalEvent()\r
+  //\r
+  EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
+  //\r
+  // 0x80000000       Timer event without a notification function. It can be\r
+  // signaled with SignalEvent() and checked with CheckEvent() or WaitForEvent().\r
+  //\r
+  EVT_TIMER,\r
+  //\r
+  // 0x00000100       Generic event with a notification function that\r
+  // can be waited on with CheckEvent() or WaitForEvent()\r
+  //\r
+  EVT_NOTIFY_WAIT,\r
+  //\r
+  // 0x00000200       Generic event with a notification function that\r
+  // is queue when the event is signaled with SignalEvent()\r
+  //\r
+  EVT_NOTIFY_SIGNAL,\r
+  //\r
+  // 0x00000201       ExitBootServicesEvent.\r
+  //\r
+  EVT_SIGNAL_EXIT_BOOT_SERVICES,\r
+  //\r
+  // 0x60000202       SetVirtualAddressMapEvent.\r
+  //\r
+  EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,\r
+\r
+  //\r
+  // 0x00000000       Generic event without a notification function.\r
+  // It can be signaled with SignalEvent() and checked with CheckEvent()\r
+  // or WaitForEvent().\r
+  //\r
+  0x00000000,\r
+  //\r
+  // 0x80000100       Timer event with a notification function that can be\r
+  // waited on with CheckEvent() or WaitForEvent()\r
+  //\r
+  EVT_TIMER | EVT_NOTIFY_WAIT,\r
+};\r
+\r
+\r
+/**\r
+  Enter critical section by acquiring the lock on gEventQueueLock.\r
+\r
+**/\r
+STATIC\r
+VOID\r
+CoreAcquireEventLock (\r
+  VOID\r
+  )\r
+{\r
+  CoreAcquireLock (&gEventQueueLock);\r
+}\r
+\r
+\r
+/**\r
+  Exit critical section by releasing the lock on gEventQueueLock.\r
+\r
+**/\r
+STATIC\r
+VOID\r
+CoreReleaseEventLock (\r
+  VOID\r
+  )\r
+{\r
+  CoreReleaseLock (&gEventQueueLock);\r
+}\r
+\r
+\r
+\r
+/**\r
+  Initializes "event" support and populates parts of the System and Runtime Table.\r
+\r
+\r
+  @retval EFI_SUCCESS            Always return success\r
+\r
+**/\r
+EFI_STATUS\r
+CoreInitializeEventServices (\r
+  VOID\r
+  )\r
+{\r
+  UINTN        Index;\r
+\r
+  for (Index=0; Index <= TPL_HIGH_LEVEL; Index++) {\r
+    InitializeListHead (&gEventQueue[Index]);\r
+  }\r
+\r
+  CoreInitializeTimer ();\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+\r
+/**\r
+  Dispatches all pending events.\r
+\r
+  @param  Priority               The task priority level of event notifications \r
+                                 to dispatch\r
+\r
+**/\r
+VOID\r
+CoreDispatchEventNotifies (\r
+  IN EFI_TPL      Priority\r
+  )\r
+{\r
+  IEVENT          *Event;\r
+  LIST_ENTRY      *Head;\r
+\r
+  CoreAcquireEventLock ();\r
+  ASSERT (gEventQueueLock.OwnerTpl == Priority);\r
+  Head = &gEventQueue[Priority];\r
+\r
+  //\r
+  // Dispatch all the pending notifications\r
+  //\r
+  while (!IsListEmpty (Head)) {\r
+\r
+    Event = CR (Head->ForwardLink, IEVENT, NotifyLink, EVENT_SIGNATURE);\r
+    RemoveEntryList (&Event->NotifyLink);\r
+\r
+    Event->NotifyLink.ForwardLink = NULL;\r
+\r
+    //\r
+    // Only clear the SIGNAL status if it is a SIGNAL type event.\r
+    // WAIT type events are only cleared in CheckEvent()\r
+    //\r
+    if (Event->Type & EVT_NOTIFY_SIGNAL) {\r
+      Event->SignalCount = 0;\r
+    }\r
+\r
+    CoreReleaseEventLock ();\r
+\r
+    //\r
+    // Notify this event\r
+    //\r
+    ASSERT (Event->NotifyFunction != NULL);\r
+    Event->NotifyFunction (Event, Event->NotifyContext);\r
+\r
+    //\r
+    // Check for next pending event\r
+    //\r
+    CoreAcquireEventLock ();\r
+  }\r
+\r
+  gEventPending &= ~(1 << Priority);\r
+  CoreReleaseEventLock ();\r
+}\r
+\r
+\r
+\r
+/**\r
+  Queues the event's notification function to fire.\r
+\r
+  @param  Event                  The Event to notify\r
+\r
+**/\r
+STATIC\r
+VOID\r
+CoreNotifyEvent (\r
+  IN  IEVENT      *Event\r
+  )\r
+{\r
+\r
+  //\r
+  // Event database must be locked\r
+  //\r
+  ASSERT_LOCKED (&gEventQueueLock);\r
+\r
+  //\r
+  // If the event is queued somewhere, remove it\r
+  //\r
+\r
+  if (Event->NotifyLink.ForwardLink != NULL) {\r
+    RemoveEntryList (&Event->NotifyLink);\r
+    Event->NotifyLink.ForwardLink = NULL;\r
+  }\r
+\r
+  //\r
+  // Queue the event to the pending notification list\r
+  //\r
+\r
+  InsertTailList (&gEventQueue[Event->NotifyTpl], &Event->NotifyLink);\r
+  gEventPending |= (UINTN)(1 << Event->NotifyTpl);\r
+}\r
+\r
+\r
+\r
+\r
+/**\r
+  Signals all events in the EventGroup.\r
+\r
+  @param  EventGroup             The list to signal\r
+\r
+**/\r
+VOID\r
+CoreNotifySignalList (\r
+  IN EFI_GUID     *EventGroup\r
+  )\r
+{\r
+  LIST_ENTRY              *Link;\r
+  LIST_ENTRY              *Head;\r
+  IEVENT                  *Event;\r
+\r
+  CoreAcquireEventLock ();\r
+\r
+  Head = &gEventSignalQueue;\r
+  for (Link = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) {\r
+    Event = CR (Link, IEVENT, SignalLink, EVENT_SIGNATURE);\r
+    if (CompareGuid (&Event->EventGroup, EventGroup)) {\r
+      CoreNotifyEvent (Event);\r
+    }\r
+  }\r
+\r
+  CoreReleaseEventLock ();\r
+}\r
+\r
+\r
+/**\r
+  Creates a general-purpose event structure.\r
+\r
+  @param  Type                   The type of event to create and its mode and \r
+                                 attributes \r
+  @param  NotifyTpl              The task priority level of event notifications \r
+  @param  NotifyFunction         Pointer to the events notification function \r
+  @param  NotifyContext          Pointer to the notification functions context; \r
+                                 corresponds to parameter "Context" in the \r
+                                 notification function \r
+  @param  Event                  Pointer to the newly created event if the call \r
+                                 succeeds; undefined otherwise \r
+\r
+  @retval EFI_SUCCESS            The event structure was created \r
+  @retval EFI_INVALID_PARAMETER  One of the parameters has an invalid value \r
+  @retval EFI_OUT_OF_RESOURCES   The event could not be allocated\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CoreCreateEvent (\r
+  IN UINT32                   Type,\r
+  IN EFI_TPL                  NotifyTpl,\r
+  IN EFI_EVENT_NOTIFY         NotifyFunction, OPTIONAL\r
+  IN VOID                     *NotifyContext, OPTIONAL\r
+  OUT EFI_EVENT               *Event\r
+  )\r
+{\r
+  return CoreCreateEventEx (Type, NotifyTpl, NotifyFunction, NotifyContext, NULL, Event);\r
+}\r
+\r
+\r
+\r
+/**\r
+  Creates a general-purpose event structure\r
+\r
+  @param  Type                   The type of event to create and its mode and \r
+                                 attributes \r
+  @param  NotifyTpl              The task priority level of event notifications \r
+  @param  NotifyFunction         Pointer to the events notification function \r
+  @param  NotifyContext          Pointer to the notification functions context; \r
+                                 corresponds to parameter "Context" in the \r
+                                 notification function \r
+  @param  EventGroup             GUID for EventGroup if NULL act the same as \r
+                                 gBS->CreateEvent(). \r
+  @param  Event                  Pointer to the newly created event if the call \r
+                                 succeeds; undefined otherwise \r
+\r
+  @retval EFI_SUCCESS            The event structure was created \r
+  @retval EFI_INVALID_PARAMETER  One of the parameters has an invalid value \r
+  @retval EFI_OUT_OF_RESOURCES   The event could not be allocated\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CoreCreateEventEx (\r
+  IN UINT32                   Type,\r
+  IN EFI_TPL                  NotifyTpl,\r
+  IN EFI_EVENT_NOTIFY         NotifyFunction, OPTIONAL\r
+  IN CONST VOID               *NotifyContext, OPTIONAL\r
+  IN CONST EFI_GUID           *EventGroup,    OPTIONAL\r
+  OUT EFI_EVENT               *Event\r
+  )\r
+{\r
+  EFI_STATUS      Status;\r
+  IEVENT          *IEvent;\r
+  INTN            Index;\r
+\r
+\r
+  if ((Event == NULL) || (NotifyTpl == TPL_APPLICATION)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Check to make sure no reserved flags are set\r
+  //\r
+  Status = EFI_INVALID_PARAMETER;\r
+  for (Index = 0; Index < (sizeof (mEventTable) / sizeof (UINT32)); Index++) {\r
+     if (Type == mEventTable[Index]) {\r
+       Status = EFI_SUCCESS;\r
+       break;\r
+     }\r
+  }\r
+  if(EFI_ERROR (Status)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Convert Event type for pre-defined Event groups\r
+  //\r
+  if (EventGroup != NULL) {\r
+    //\r
+    // For event group, type EVT_SIGNAL_EXIT_BOOT_SERVICES and EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE\r
+    // are not valid\r
+    //\r
+    if ((Type == EVT_SIGNAL_EXIT_BOOT_SERVICES) || (Type == EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE)) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+    if (CompareGuid (EventGroup, &gEfiEventExitBootServicesGuid)) {\r
+      Type = EVT_SIGNAL_EXIT_BOOT_SERVICES;\r
+    } else if (CompareGuid (EventGroup, &gEfiEventVirtualAddressChangeGuid)) {\r
+      Type = EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE;\r
+    }\r
+  } else {\r
+    //\r
+    // Convert EFI 1.10 Events to their UEFI 2.0 CreateEventEx mapping\r
+    //\r
+    if (Type == EVT_SIGNAL_EXIT_BOOT_SERVICES) {\r
+      EventGroup = &gEfiEventExitBootServicesGuid;\r
+    } else if (Type == EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE) {\r
+      EventGroup = &gEfiEventVirtualAddressChangeGuid;\r
+    }\r
+  }\r
+\r
+  //\r
+  // If it's a notify type of event, check its parameters\r
+  //\r
+  if ((Type & (EVT_NOTIFY_WAIT | EVT_NOTIFY_SIGNAL)) != 0) {\r
+    //\r
+    // Check for an invalid NotifyFunction or NotifyTpl\r
+    //\r
+    if ((NotifyFunction == NULL) ||\r
+        (NotifyTpl < TPL_APPLICATION) ||\r
+       (NotifyTpl >= TPL_HIGH_LEVEL)) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+  } else {\r
+    //\r
+    // No notification needed, zero ignored values\r
+    //\r
+    NotifyTpl = 0;\r
+    NotifyFunction = NULL;\r
+    NotifyContext = NULL;\r
+  }\r
+\r
+  //\r
+  // Allcoate and initialize a new event structure.\r
+  //\r
+  Status = CoreAllocatePool (\r
+             ((Type & EVT_RUNTIME) != 0) ? EfiRuntimeServicesData: EfiBootServicesData,\r
+             sizeof (IEVENT),\r
+             (VOID **)&IEvent\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  SetMem (IEvent, sizeof (IEVENT), 0);\r
+\r
+  IEvent->Signature = EVENT_SIGNATURE;\r
+  IEvent->Type = Type;\r
+\r
+  IEvent->NotifyTpl      = NotifyTpl;\r
+  IEvent->NotifyFunction = NotifyFunction;\r
+  IEvent->NotifyContext  = (VOID *)NotifyContext;\r
+  if (EventGroup != NULL) {\r
+    CopyGuid (&IEvent->EventGroup, EventGroup);\r
+    IEvent->ExFlag = TRUE;\r
+  }\r
+\r
+  *Event = IEvent;\r
+\r
+  if ((Type & EVT_RUNTIME) != 0) {\r
+    //\r
+    // Keep a list of all RT events so we can tell the RT AP.\r
+    //\r
+    IEvent->RuntimeData.Type           = Type;\r
+    IEvent->RuntimeData.NotifyTpl      = NotifyTpl;\r
+    IEvent->RuntimeData.NotifyFunction = NotifyFunction;\r
+    IEvent->RuntimeData.NotifyContext  = (VOID *) NotifyContext;\r
+    IEvent->RuntimeData.Event          = (EFI_EVENT *) IEvent;\r
+    InsertTailList (&gRuntime->EventHead, &IEvent->RuntimeData.Link);\r
+  }\r
+\r
+  CoreAcquireEventLock ();\r
+\r
+  if ((Type & EVT_NOTIFY_SIGNAL) != 0x00000000) {\r
+    //\r
+    // The Event's NotifyFunction must be queued whenever the event is signaled\r
+    //\r
+    InsertHeadList (&gEventSignalQueue, &IEvent->SignalLink);\r
+  }\r
+\r
+  CoreReleaseEventLock ();\r
+\r
+  //\r
+  // Done\r
+  //\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+\r
+\r
+/**\r
+  Signals the event.  Queues the event to be notified if needed\r
+\r
+  @param  UserEvent              The event to signal \r
+\r
+  @retval EFI_INVALID_PARAMETER  Parameters are not valid. \r
+  @retval EFI_SUCCESS            The event was signaled.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CoreSignalEvent (\r
+  IN EFI_EVENT    UserEvent\r
+  )\r
+{\r
+  IEVENT          *Event;\r
+\r
+  Event = UserEvent;\r
+\r
+  if (Event == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (Event->Signature != EVENT_SIGNATURE) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  CoreAcquireEventLock ();\r
+\r
+  //\r
+  // If the event is not already signalled, do so\r
+  //\r
+\r
+  if (Event->SignalCount == 0x00000000) {\r
+    Event->SignalCount++;\r
+\r
+    //\r
+    // If signalling type is a notify function, queue it\r
+    //\r
+    if (Event->Type & EVT_NOTIFY_SIGNAL) {\r
+      if (Event->ExFlag) {\r
+        //\r
+        // The CreateEventEx() style requires all members of the Event Group\r
+        //  to be signaled.\r
+        //\r
+        CoreReleaseEventLock ();\r
+        CoreNotifySignalList (&Event->EventGroup);\r
+        CoreAcquireEventLock ();\r
+       } else {\r
+        CoreNotifyEvent (Event);\r
+      }\r
+    }\r
+  }\r
+\r
+  CoreReleaseEventLock ();\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+\r
+/**\r
+  Check the status of an event.\r
+\r
+  @param  UserEvent              The event to check \r
+\r
+  @retval EFI_SUCCESS            The event is in the signaled state \r
+  @retval EFI_NOT_READY          The event is not in the signaled state \r
+  @retval EFI_INVALID_PARAMETER  Event is of type EVT_NOTIFY_SIGNAL\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CoreCheckEvent (\r
+  IN EFI_EVENT        UserEvent\r
+  )\r
+{\r
+  IEVENT      *Event;\r
+  EFI_STATUS  Status;\r
+\r
+  Event = UserEvent;\r
+\r
+  if (Event == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (Event->Signature != EVENT_SIGNATURE) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (Event->Type & EVT_NOTIFY_SIGNAL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Status = EFI_NOT_READY;\r
+\r
+  if (!Event->SignalCount && (Event->Type & EVT_NOTIFY_WAIT)) {\r
+\r
+    //\r
+    // Queue the wait notify function\r
+    //\r
+\r
+    CoreAcquireEventLock ();\r
+    if (!Event->SignalCount) {\r
+      CoreNotifyEvent (Event);\r
+    }\r
+    CoreReleaseEventLock ();\r
+  }\r
+\r
+  //\r
+  // If the even looks signalled, get the lock and clear it\r
+  //\r
+\r
+  if (Event->SignalCount) {\r
+    CoreAcquireEventLock ();\r
+\r
+    if (Event->SignalCount) {\r
+      Event->SignalCount = 0;\r
+      Status = EFI_SUCCESS;\r
+    }\r
+\r
+    CoreReleaseEventLock ();\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+\r
+\r
+/**\r
+  Stops execution until an event is signaled.\r
+\r
+  @param  NumberOfEvents         The number of events in the UserEvents array \r
+  @param  UserEvents             An array of EFI_EVENT \r
+  @param  UserIndex              Pointer to the index of the event which \r
+                                 satisfied the wait condition \r
+\r
+  @retval EFI_SUCCESS            The event indicated by Index was signaled. \r
+  @retval EFI_INVALID_PARAMETER  The event indicated by Index has a notification \r
+                                 function or Event was not a valid type \r
+  @retval EFI_UNSUPPORTED        The current TPL is not TPL_APPLICATION\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CoreWaitForEvent (\r
+  IN UINTN        NumberOfEvents,\r
+  IN EFI_EVENT    *UserEvents,\r
+  OUT UINTN       *UserIndex\r
+  )\r
+{\r
+  EFI_STATUS      Status;\r
+  UINTN           Index;\r
+\r
+  //\r
+  // Can only WaitForEvent at TPL_APPLICATION\r
+  //\r
+  if (gEfiCurrentTpl != TPL_APPLICATION) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  for(;;) {\r
+\r
+    for(Index = 0; Index < NumberOfEvents; Index++) {\r
+\r
+      Status = CoreCheckEvent (UserEvents[Index]);\r
+\r
+      //\r
+      // provide index of event that caused problem\r
+      //\r
+      if (Status != EFI_NOT_READY) {\r
+        *UserIndex = Index;\r
+        return Status;\r
+      }\r
+    }\r
+\r
+    //\r
+    // This was the location of the Idle loop callback in EFI 1.x reference\r
+    // code. We don't have that concept in this base at this point.\r
+    //\r
+  }\r
+}\r
+\r
+\r
+\r
+/**\r
+  Closes an event and frees the event structure.\r
+\r
+  @param  UserEvent              Event to close \r
+\r
+  @retval EFI_INVALID_PARAMETER  Parameters are not valid. \r
+  @retval EFI_SUCCESS            The event has been closed\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CoreCloseEvent (\r
+  IN EFI_EVENT    UserEvent\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  IEVENT      *Event;\r
+\r
+  Event = UserEvent;\r
+\r
+  if (Event == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (Event->Signature != EVENT_SIGNATURE) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // If it's a timer event, make sure it's not pending\r
+  //\r
+  if (Event->Type & EVT_TIMER) {\r
+    CoreSetTimer (Event, TimerCancel, 0);\r
+  }\r
+\r
+  CoreAcquireEventLock ();\r
+\r
+  //\r
+  // If the event is queued somewhere, remove it\r
+  //\r
+\r
+  if (Event->RuntimeData.Link.ForwardLink != NULL) {\r
+    RemoveEntryList (&Event->RuntimeData.Link);\r
+  }\r
+\r
+  if (Event->NotifyLink.ForwardLink != NULL) {\r
+    RemoveEntryList (&Event->NotifyLink);\r
+  }\r
+\r
+  if (Event->SignalLink.ForwardLink != NULL) {\r
+    RemoveEntryList (&Event->SignalLink);\r
+  }\r
+\r
+  CoreReleaseEventLock ();\r
+\r
+  //\r
+  // If the event is registered on a protocol notify, then remove it from the protocol database\r
+  //\r
+  CoreUnregisterProtocolNotify (Event);\r
+\r
+  Status = CoreFreePool (Event);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  return Status;\r
+}\r
diff --git a/MdeModulePkg/Core/Dxe/Event/event.c b/MdeModulePkg/Core/Dxe/Event/event.c
deleted file mode 100644 (file)
index 834ace5..0000000
+++ /dev/null
@@ -1,688 +0,0 @@
-/** @file \r
-\r
-  UEFI Event support functions implemented in this file.\r
-\r
-Copyright (c) 2006 - 2008, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution.  The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-\r
-#include <DxeMain.h>\r
-\r
-//\r
-// Enumerate the valid types\r
-//\r
-UINT32 mEventTable[] = {\r
-  //\r
-  // 0x80000200       Timer event with a notification function that is\r
-  // queue when the event is signaled with SignalEvent()\r
-  //\r
-  EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
-  //\r
-  // 0x80000000       Timer event without a notification function. It can be\r
-  // signaled with SignalEvent() and checked with CheckEvent() or WaitForEvent().\r
-  //\r
-  EVT_TIMER,\r
-  //\r
-  // 0x00000100       Generic event with a notification function that\r
-  // can be waited on with CheckEvent() or WaitForEvent()\r
-  //\r
-  EVT_NOTIFY_WAIT,\r
-  //\r
-  // 0x00000200       Generic event with a notification function that\r
-  // is queue when the event is signaled with SignalEvent()\r
-  //\r
-  EVT_NOTIFY_SIGNAL,\r
-  //\r
-  // 0x00000201       ExitBootServicesEvent.\r
-  //\r
-  EVT_SIGNAL_EXIT_BOOT_SERVICES,\r
-  //\r
-  // 0x60000202       SetVirtualAddressMapEvent.\r
-  //\r
-  EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,\r
-\r
-  //\r
-  // 0x00000000       Generic event without a notification function.\r
-  // It can be signaled with SignalEvent() and checked with CheckEvent()\r
-  // or WaitForEvent().\r
-  //\r
-  0x00000000,\r
-  //\r
-  // 0x80000100       Timer event with a notification function that can be\r
-  // waited on with CheckEvent() or WaitForEvent()\r
-  //\r
-  EVT_TIMER | EVT_NOTIFY_WAIT,\r
-};\r
-\r
-\r
-/**\r
-  Enter critical section by acquiring the lock on gEventQueueLock.\r
-\r
-**/\r
-STATIC\r
-VOID\r
-CoreAcquireEventLock (\r
-  VOID\r
-  )\r
-{\r
-  CoreAcquireLock (&gEventQueueLock);\r
-}\r
-\r
-\r
-/**\r
-  Exit critical section by releasing the lock on gEventQueueLock.\r
-\r
-**/\r
-STATIC\r
-VOID\r
-CoreReleaseEventLock (\r
-  VOID\r
-  )\r
-{\r
-  CoreReleaseLock (&gEventQueueLock);\r
-}\r
-\r
-\r
-\r
-/**\r
-  Initializes "event" support and populates parts of the System and Runtime Table.\r
-\r
-\r
-  @retval EFI_SUCCESS            Always return success\r
-\r
-**/\r
-EFI_STATUS\r
-CoreInitializeEventServices (\r
-  VOID\r
-  )\r
-{\r
-  UINTN        Index;\r
-\r
-  for (Index=0; Index <= TPL_HIGH_LEVEL; Index++) {\r
-    InitializeListHead (&gEventQueue[Index]);\r
-  }\r
-\r
-  CoreInitializeTimer ();\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
-\r
-/**\r
-  Dispatches all pending events.\r
-\r
-  @param  Priority               The task priority level of event notifications \r
-                                 to dispatch\r
-\r
-**/\r
-VOID\r
-CoreDispatchEventNotifies (\r
-  IN EFI_TPL      Priority\r
-  )\r
-{\r
-  IEVENT          *Event;\r
-  LIST_ENTRY      *Head;\r
-\r
-  CoreAcquireEventLock ();\r
-  ASSERT (gEventQueueLock.OwnerTpl == Priority);\r
-  Head = &gEventQueue[Priority];\r
-\r
-  //\r
-  // Dispatch all the pending notifications\r
-  //\r
-  while (!IsListEmpty (Head)) {\r
-\r
-    Event = CR (Head->ForwardLink, IEVENT, NotifyLink, EVENT_SIGNATURE);\r
-    RemoveEntryList (&Event->NotifyLink);\r
-\r
-    Event->NotifyLink.ForwardLink = NULL;\r
-\r
-    //\r
-    // Only clear the SIGNAL status if it is a SIGNAL type event.\r
-    // WAIT type events are only cleared in CheckEvent()\r
-    //\r
-    if (Event->Type & EVT_NOTIFY_SIGNAL) {\r
-      Event->SignalCount = 0;\r
-    }\r
-\r
-    CoreReleaseEventLock ();\r
-\r
-    //\r
-    // Notify this event\r
-    //\r
-    ASSERT (Event->NotifyFunction != NULL);\r
-    Event->NotifyFunction (Event, Event->NotifyContext);\r
-\r
-    //\r
-    // Check for next pending event\r
-    //\r
-    CoreAcquireEventLock ();\r
-  }\r
-\r
-  gEventPending &= ~(1 << Priority);\r
-  CoreReleaseEventLock ();\r
-}\r
-\r
-\r
-\r
-/**\r
-  Queues the event's notification function to fire.\r
-\r
-  @param  Event                  The Event to notify\r
-\r
-**/\r
-STATIC\r
-VOID\r
-CoreNotifyEvent (\r
-  IN  IEVENT      *Event\r
-  )\r
-{\r
-\r
-  //\r
-  // Event database must be locked\r
-  //\r
-  ASSERT_LOCKED (&gEventQueueLock);\r
-\r
-  //\r
-  // If the event is queued somewhere, remove it\r
-  //\r
-\r
-  if (Event->NotifyLink.ForwardLink != NULL) {\r
-    RemoveEntryList (&Event->NotifyLink);\r
-    Event->NotifyLink.ForwardLink = NULL;\r
-  }\r
-\r
-  //\r
-  // Queue the event to the pending notification list\r
-  //\r
-\r
-  InsertTailList (&gEventQueue[Event->NotifyTpl], &Event->NotifyLink);\r
-  gEventPending |= (UINTN)(1 << Event->NotifyTpl);\r
-}\r
-\r
-\r
-\r
-\r
-/**\r
-  Signals all events in the EventGroup.\r
-\r
-  @param  EventGroup             The list to signal\r
-\r
-**/\r
-VOID\r
-CoreNotifySignalList (\r
-  IN EFI_GUID     *EventGroup\r
-  )\r
-{\r
-  LIST_ENTRY              *Link;\r
-  LIST_ENTRY              *Head;\r
-  IEVENT                  *Event;\r
-\r
-  CoreAcquireEventLock ();\r
-\r
-  Head = &gEventSignalQueue;\r
-  for (Link = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) {\r
-    Event = CR (Link, IEVENT, SignalLink, EVENT_SIGNATURE);\r
-    if (CompareGuid (&Event->EventGroup, EventGroup)) {\r
-      CoreNotifyEvent (Event);\r
-    }\r
-  }\r
-\r
-  CoreReleaseEventLock ();\r
-}\r
-\r
-\r
-/**\r
-  Creates a general-purpose event structure.\r
-\r
-  @param  Type                   The type of event to create and its mode and \r
-                                 attributes \r
-  @param  NotifyTpl              The task priority level of event notifications \r
-  @param  NotifyFunction         Pointer to the events notification function \r
-  @param  NotifyContext          Pointer to the notification functions context; \r
-                                 corresponds to parameter "Context" in the \r
-                                 notification function \r
-  @param  Event                  Pointer to the newly created event if the call \r
-                                 succeeds; undefined otherwise \r
-\r
-  @retval EFI_SUCCESS            The event structure was created \r
-  @retval EFI_INVALID_PARAMETER  One of the parameters has an invalid value \r
-  @retval EFI_OUT_OF_RESOURCES   The event could not be allocated\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-CoreCreateEvent (\r
-  IN UINT32                   Type,\r
-  IN EFI_TPL                  NotifyTpl,\r
-  IN EFI_EVENT_NOTIFY         NotifyFunction, OPTIONAL\r
-  IN VOID                     *NotifyContext, OPTIONAL\r
-  OUT EFI_EVENT               *Event\r
-  )\r
-{\r
-  return CoreCreateEventEx (Type, NotifyTpl, NotifyFunction, NotifyContext, NULL, Event);\r
-}\r
-\r
-\r
-\r
-/**\r
-  Creates a general-purpose event structure\r
-\r
-  @param  Type                   The type of event to create and its mode and \r
-                                 attributes \r
-  @param  NotifyTpl              The task priority level of event notifications \r
-  @param  NotifyFunction         Pointer to the events notification function \r
-  @param  NotifyContext          Pointer to the notification functions context; \r
-                                 corresponds to parameter "Context" in the \r
-                                 notification function \r
-  @param  EventGroup             GUID for EventGroup if NULL act the same as \r
-                                 gBS->CreateEvent(). \r
-  @param  Event                  Pointer to the newly created event if the call \r
-                                 succeeds; undefined otherwise \r
-\r
-  @retval EFI_SUCCESS            The event structure was created \r
-  @retval EFI_INVALID_PARAMETER  One of the parameters has an invalid value \r
-  @retval EFI_OUT_OF_RESOURCES   The event could not be allocated\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-CoreCreateEventEx (\r
-  IN UINT32                   Type,\r
-  IN EFI_TPL                  NotifyTpl,\r
-  IN EFI_EVENT_NOTIFY         NotifyFunction, OPTIONAL\r
-  IN CONST VOID               *NotifyContext, OPTIONAL\r
-  IN CONST EFI_GUID           *EventGroup,    OPTIONAL\r
-  OUT EFI_EVENT               *Event\r
-  )\r
-{\r
-  EFI_STATUS      Status;\r
-  IEVENT          *IEvent;\r
-  INTN            Index;\r
-\r
-\r
-  if ((Event == NULL) || (NotifyTpl == TPL_APPLICATION)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  //\r
-  // Check to make sure no reserved flags are set\r
-  //\r
-  Status = EFI_INVALID_PARAMETER;\r
-  for (Index = 0; Index < (sizeof (mEventTable) / sizeof (UINT32)); Index++) {\r
-     if (Type == mEventTable[Index]) {\r
-       Status = EFI_SUCCESS;\r
-       break;\r
-     }\r
-  }\r
-  if(EFI_ERROR (Status)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  //\r
-  // Convert Event type for pre-defined Event groups\r
-  //\r
-  if (EventGroup != NULL) {\r
-    //\r
-    // For event group, type EVT_SIGNAL_EXIT_BOOT_SERVICES and EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE\r
-    // are not valid\r
-    //\r
-    if ((Type == EVT_SIGNAL_EXIT_BOOT_SERVICES) || (Type == EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE)) {\r
-      return EFI_INVALID_PARAMETER;\r
-    }\r
-    if (CompareGuid (EventGroup, &gEfiEventExitBootServicesGuid)) {\r
-      Type = EVT_SIGNAL_EXIT_BOOT_SERVICES;\r
-    } else if (CompareGuid (EventGroup, &gEfiEventVirtualAddressChangeGuid)) {\r
-      Type = EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE;\r
-    }\r
-  } else {\r
-    //\r
-    // Convert EFI 1.10 Events to their UEFI 2.0 CreateEventEx mapping\r
-    //\r
-    if (Type == EVT_SIGNAL_EXIT_BOOT_SERVICES) {\r
-      EventGroup = &gEfiEventExitBootServicesGuid;\r
-    } else if (Type == EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE) {\r
-      EventGroup = &gEfiEventVirtualAddressChangeGuid;\r
-    }\r
-  }\r
-\r
-  //\r
-  // If it's a notify type of event, check its parameters\r
-  //\r
-  if ((Type & (EVT_NOTIFY_WAIT | EVT_NOTIFY_SIGNAL)) != 0) {\r
-    //\r
-    // Check for an invalid NotifyFunction or NotifyTpl\r
-    //\r
-    if ((NotifyFunction == NULL) ||\r
-        (NotifyTpl < TPL_APPLICATION) ||\r
-       (NotifyTpl >= TPL_HIGH_LEVEL)) {\r
-      return EFI_INVALID_PARAMETER;\r
-    }\r
-\r
-  } else {\r
-    //\r
-    // No notification needed, zero ignored values\r
-    //\r
-    NotifyTpl = 0;\r
-    NotifyFunction = NULL;\r
-    NotifyContext = NULL;\r
-  }\r
-\r
-  //\r
-  // Allcoate and initialize a new event structure.\r
-  //\r
-  Status = CoreAllocatePool (\r
-             ((Type & EVT_RUNTIME) != 0) ? EfiRuntimeServicesData: EfiBootServicesData,\r
-             sizeof (IEVENT),\r
-             (VOID **)&IEvent\r
-             );\r
-  if (EFI_ERROR (Status)) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  SetMem (IEvent, sizeof (IEVENT), 0);\r
-\r
-  IEvent->Signature = EVENT_SIGNATURE;\r
-  IEvent->Type = Type;\r
-\r
-  IEvent->NotifyTpl      = NotifyTpl;\r
-  IEvent->NotifyFunction = NotifyFunction;\r
-  IEvent->NotifyContext  = (VOID *)NotifyContext;\r
-  if (EventGroup != NULL) {\r
-    CopyGuid (&IEvent->EventGroup, EventGroup);\r
-    IEvent->ExFlag = TRUE;\r
-  }\r
-\r
-  *Event = IEvent;\r
-\r
-  if ((Type & EVT_RUNTIME) != 0) {\r
-    //\r
-    // Keep a list of all RT events so we can tell the RT AP.\r
-    //\r
-    IEvent->RuntimeData.Type           = Type;\r
-    IEvent->RuntimeData.NotifyTpl      = NotifyTpl;\r
-    IEvent->RuntimeData.NotifyFunction = NotifyFunction;\r
-    IEvent->RuntimeData.NotifyContext  = (VOID *) NotifyContext;\r
-    IEvent->RuntimeData.Event          = (EFI_EVENT *) IEvent;\r
-    InsertTailList (&gRuntime->EventHead, &IEvent->RuntimeData.Link);\r
-  }\r
-\r
-  CoreAcquireEventLock ();\r
-\r
-  if ((Type & EVT_NOTIFY_SIGNAL) != 0x00000000) {\r
-    //\r
-    // The Event's NotifyFunction must be queued whenever the event is signaled\r
-    //\r
-    InsertHeadList (&gEventSignalQueue, &IEvent->SignalLink);\r
-  }\r
-\r
-  CoreReleaseEventLock ();\r
-\r
-  //\r
-  // Done\r
-  //\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
-\r
-\r
-/**\r
-  Signals the event.  Queues the event to be notified if needed\r
-\r
-  @param  UserEvent              The event to signal \r
-\r
-  @retval EFI_INVALID_PARAMETER  Parameters are not valid. \r
-  @retval EFI_SUCCESS            The event was signaled.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-CoreSignalEvent (\r
-  IN EFI_EVENT    UserEvent\r
-  )\r
-{\r
-  IEVENT          *Event;\r
-\r
-  Event = UserEvent;\r
-\r
-  if (Event == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (Event->Signature != EVENT_SIGNATURE) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  CoreAcquireEventLock ();\r
-\r
-  //\r
-  // If the event is not already signalled, do so\r
-  //\r
-\r
-  if (Event->SignalCount == 0x00000000) {\r
-    Event->SignalCount++;\r
-\r
-    //\r
-    // If signalling type is a notify function, queue it\r
-    //\r
-    if (Event->Type & EVT_NOTIFY_SIGNAL) {\r
-      if (Event->ExFlag) {\r
-        //\r
-        // The CreateEventEx() style requires all members of the Event Group\r
-        //  to be signaled.\r
-        //\r
-        CoreReleaseEventLock ();\r
-        CoreNotifySignalList (&Event->EventGroup);\r
-        CoreAcquireEventLock ();\r
-       } else {\r
-        CoreNotifyEvent (Event);\r
-      }\r
-    }\r
-  }\r
-\r
-  CoreReleaseEventLock ();\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
-\r
-/**\r
-  Check the status of an event.\r
-\r
-  @param  UserEvent              The event to check \r
-\r
-  @retval EFI_SUCCESS            The event is in the signaled state \r
-  @retval EFI_NOT_READY          The event is not in the signaled state \r
-  @retval EFI_INVALID_PARAMETER  Event is of type EVT_NOTIFY_SIGNAL\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-CoreCheckEvent (\r
-  IN EFI_EVENT        UserEvent\r
-  )\r
-{\r
-  IEVENT      *Event;\r
-  EFI_STATUS  Status;\r
-\r
-  Event = UserEvent;\r
-\r
-  if (Event == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (Event->Signature != EVENT_SIGNATURE) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (Event->Type & EVT_NOTIFY_SIGNAL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  Status = EFI_NOT_READY;\r
-\r
-  if (!Event->SignalCount && (Event->Type & EVT_NOTIFY_WAIT)) {\r
-\r
-    //\r
-    // Queue the wait notify function\r
-    //\r
-\r
-    CoreAcquireEventLock ();\r
-    if (!Event->SignalCount) {\r
-      CoreNotifyEvent (Event);\r
-    }\r
-    CoreReleaseEventLock ();\r
-  }\r
-\r
-  //\r
-  // If the even looks signalled, get the lock and clear it\r
-  //\r
-\r
-  if (Event->SignalCount) {\r
-    CoreAcquireEventLock ();\r
-\r
-    if (Event->SignalCount) {\r
-      Event->SignalCount = 0;\r
-      Status = EFI_SUCCESS;\r
-    }\r
-\r
-    CoreReleaseEventLock ();\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-\r
-\r
-\r
-/**\r
-  Stops execution until an event is signaled.\r
-\r
-  @param  NumberOfEvents         The number of events in the UserEvents array \r
-  @param  UserEvents             An array of EFI_EVENT \r
-  @param  UserIndex              Pointer to the index of the event which \r
-                                 satisfied the wait condition \r
-\r
-  @retval EFI_SUCCESS            The event indicated by Index was signaled. \r
-  @retval EFI_INVALID_PARAMETER  The event indicated by Index has a notification \r
-                                 function or Event was not a valid type \r
-  @retval EFI_UNSUPPORTED        The current TPL is not TPL_APPLICATION\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-CoreWaitForEvent (\r
-  IN UINTN        NumberOfEvents,\r
-  IN EFI_EVENT    *UserEvents,\r
-  OUT UINTN       *UserIndex\r
-  )\r
-{\r
-  EFI_STATUS      Status;\r
-  UINTN           Index;\r
-\r
-  //\r
-  // Can only WaitForEvent at TPL_APPLICATION\r
-  //\r
-  if (gEfiCurrentTpl != TPL_APPLICATION) {\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-\r
-  for(;;) {\r
-\r
-    for(Index = 0; Index < NumberOfEvents; Index++) {\r
-\r
-      Status = CoreCheckEvent (UserEvents[Index]);\r
-\r
-      //\r
-      // provide index of event that caused problem\r
-      //\r
-      if (Status != EFI_NOT_READY) {\r
-        *UserIndex = Index;\r
-        return Status;\r
-      }\r
-    }\r
-\r
-    //\r
-    // This was the location of the Idle loop callback in EFI 1.x reference\r
-    // code. We don't have that concept in this base at this point.\r
-    //\r
-  }\r
-}\r
-\r
-\r
-\r
-/**\r
-  Closes an event and frees the event structure.\r
-\r
-  @param  UserEvent              Event to close \r
-\r
-  @retval EFI_INVALID_PARAMETER  Parameters are not valid. \r
-  @retval EFI_SUCCESS            The event has been closed\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-CoreCloseEvent (\r
-  IN EFI_EVENT    UserEvent\r
-  )\r
-{\r
-  EFI_STATUS  Status;\r
-  IEVENT      *Event;\r
-\r
-  Event = UserEvent;\r
-\r
-  if (Event == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (Event->Signature != EVENT_SIGNATURE) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  //\r
-  // If it's a timer event, make sure it's not pending\r
-  //\r
-  if (Event->Type & EVT_TIMER) {\r
-    CoreSetTimer (Event, TimerCancel, 0);\r
-  }\r
-\r
-  CoreAcquireEventLock ();\r
-\r
-  //\r
-  // If the event is queued somewhere, remove it\r
-  //\r
-\r
-  if (Event->RuntimeData.Link.ForwardLink != NULL) {\r
-    RemoveEntryList (&Event->RuntimeData.Link);\r
-  }\r
-\r
-  if (Event->NotifyLink.ForwardLink != NULL) {\r
-    RemoveEntryList (&Event->NotifyLink);\r
-  }\r
-\r
-  if (Event->SignalLink.ForwardLink != NULL) {\r
-    RemoveEntryList (&Event->SignalLink);\r
-  }\r
-\r
-  CoreReleaseEventLock ();\r
-\r
-  //\r
-  // If the event is registered on a protocol notify, then remove it from the protocol database\r
-  //\r
-  CoreUnregisterProtocolNotify (Event);\r
-\r
-  Status = CoreFreePool (Event);\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  return Status;\r
-}\r