]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/Dxe/Event/Event.c
MdeModulePkg DxeCore: Fix issue to print GUID value %g without pointer
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / Event / Event.c
index bc01256960fc5dce0ca98cda9dc860cf7a26dad6..86ca369d56ffad1a9f728138e1b18bc38dfb9c06 100644 (file)
@@ -1,7 +1,8 @@
 /** @file\r
   UEFI Event support functions implemented in this file.\r
 \r
-Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>\r
+(C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>\r
 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
@@ -22,7 +23,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 EFI_TPL  gEfiCurrentTpl = TPL_APPLICATION;\r
 \r
 ///\r
-/// gEventQueueLock - Protects the event queus\r
+/// gEventQueueLock - Protects the event queues\r
 ///\r
 EFI_LOCK gEventQueueLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_HIGH_LEVEL);\r
 \r
@@ -87,6 +88,11 @@ UINT32 mEventTable[] = {
   EVT_TIMER | EVT_NOTIFY_WAIT,\r
 };\r
 \r
+///\r
+/// gIdleLoopEvent - Event which is signalled when the core is idle\r
+///\r
+EFI_EVENT       gIdleLoopEvent = NULL;\r
+\r
 \r
 /**\r
   Enter critical section by acquiring the lock on gEventQueueLock.\r
@@ -134,6 +140,15 @@ CoreInitializeEventServices (
 \r
   CoreInitializeTimer ();\r
 \r
+  CoreCreateEventEx (\r
+    EVT_NOTIFY_SIGNAL,\r
+    TPL_NOTIFY,\r
+    EfiEventEmptyFunction,\r
+    NULL,\r
+    &gIdleLoopEventGuid,\r
+    &gIdleLoopEvent\r
+    );\r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -190,7 +205,7 @@ CoreDispatchEventNotifies (
     CoreAcquireEventLock ();\r
   }\r
 \r
-  gEventPending &= ~(1 << Priority);\r
+  gEventPending &= ~(UINTN)(1 << Priority);\r
   CoreReleaseEventLock ();\r
 }\r
 \r
@@ -263,7 +278,7 @@ CoreNotifySignalList (
 \r
 \r
 /**\r
-  Creates a general-purpose event structure.\r
+  Creates an event.\r
 \r
   @param  Type                   The type of event to create and its mode and\r
                                  attributes\r
@@ -296,7 +311,7 @@ CoreCreateEvent (
 \r
 \r
 /**\r
-  Creates a general-purpose event structure\r
+  Creates an event in a group.\r
 \r
   @param  Type                   The type of event to create and its mode and\r
                                  attributes\r
@@ -325,6 +340,51 @@ CoreCreateEventEx (
   IN CONST EFI_GUID           *EventGroup,    OPTIONAL\r
   OUT EFI_EVENT               *Event\r
   )\r
+{\r
+  //\r
+  // If it's a notify type of event, check for invalid NotifyTpl\r
+  //\r
+  if ((Type & (EVT_NOTIFY_WAIT | EVT_NOTIFY_SIGNAL)) != 0) {\r
+    if (NotifyTpl != TPL_APPLICATION &&\r
+        NotifyTpl != TPL_CALLBACK &&\r
+        NotifyTpl != TPL_NOTIFY) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+  }\r
+\r
+  return CoreCreateEventInternal (Type, NotifyTpl, NotifyFunction, NotifyContext, EventGroup, Event);\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
+CoreCreateEventInternal (\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
@@ -418,7 +478,7 @@ CoreCreateEventEx (
   IEvent->NotifyContext  = (VOID *)NotifyContext;\r
   if (EventGroup != NULL) {\r
     CopyGuid (&IEvent->EventGroup, EventGroup);\r
-    IEvent->ExFlag = TRUE;\r
+    IEvent->ExFlag |= EVT_EXFLAG_EVENT_GROUP;\r
   }\r
 \r
   *Event = IEvent;\r
@@ -495,7 +555,7 @@ CoreSignalEvent (
     // If signalling type is a notify function, queue it\r
     //\r
     if ((Event->Type & EVT_NOTIFY_SIGNAL) != 0) {\r
-      if (Event->ExFlag) {\r
+      if ((Event->ExFlag & EVT_EXFLAG_EVENT_GROUP) != 0) {\r
         //\r
         // The CreateEventEx() style requires all members of the Event Group\r
         //  to be signaled.\r
@@ -614,6 +674,14 @@ CoreWaitForEvent (
     return EFI_UNSUPPORTED;\r
   }\r
 \r
+  if (NumberOfEvents == 0) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (UserEvents == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
   for(;;) {\r
 \r
     for(Index = 0; Index < NumberOfEvents; Index++) {\r
@@ -624,15 +692,17 @@ CoreWaitForEvent (
       // provide index of event that caused problem\r
       //\r
       if (Status != EFI_NOT_READY) {\r
-        *UserIndex = Index;\r
+        if (UserIndex != NULL) {\r
+          *UserIndex = Index;\r
+        }\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
+    // Signal the Idle event\r
     //\r
+    CoreSignalEvent (gIdleLoopEvent);\r
   }\r
 }\r
 \r
@@ -695,10 +765,18 @@ CoreCloseEvent (
   //\r
   // If the event is registered on a protocol notify, then remove it from the protocol database\r
   //\r
-  CoreUnregisterProtocolNotify (Event);\r
+  if ((Event->ExFlag & EVT_EXFLAG_EVENT_PROTOCOL_NOTIFICATION) != 0) {\r
+    CoreUnregisterProtocolNotify (Event);\r
+  }\r
 \r
+  //\r
+  // To avoid the Event to be signalled wrongly after closed,\r
+  // clear the Signature of Event before free pool.\r
+  //\r
+  Event->Signature = 0;\r
   Status = CoreFreePool (Event);\r
   ASSERT_EFI_ERROR (Status);\r
 \r
   return Status;\r
 }\r
+\r