]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/Dxe/DxeMain/DxeProtocolNotify.c
1. Refine debug agent library.
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / DxeMain / DxeProtocolNotify.c
index 96338adec8b87e4deadd92cf3fef8a951c0acf65..a49f63e7c34f0ff3e64b9f63ae2d4267e54aa91a 100644 (file)
@@ -16,7 +16,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 #include "DxeMain.h"\r
 \r
-\r
 //\r
 // DXE Core Global Variables for all of the Architectural Protocols.\r
 // If a protocol is installed mArchProtocols[].Present will be TRUE.\r
@@ -25,30 +24,37 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 // and mArchProtocols[].Registration as it creates events for every array\r
 // entry.\r
 //\r
+EFI_CORE_PROTOCOL_NOTIFY_ENTRY  mArchProtocols[] = {\r
+  { &gEfiSecurityArchProtocolGuid,         (VOID **)&gSecurity,      NULL, NULL, FALSE },\r
+  { &gEfiCpuArchProtocolGuid,              (VOID **)&gCpu,           NULL, NULL, FALSE },\r
+  { &gEfiMetronomeArchProtocolGuid,        (VOID **)&gMetronome,     NULL, NULL, FALSE },\r
+  { &gEfiTimerArchProtocolGuid,            (VOID **)&gTimer,         NULL, NULL, FALSE },\r
+  { &gEfiBdsArchProtocolGuid,              (VOID **)&gBds,           NULL, NULL, FALSE },\r
+  { &gEfiWatchdogTimerArchProtocolGuid,    (VOID **)&gWatchdogTimer, NULL, NULL, FALSE },\r
+  { &gEfiRuntimeArchProtocolGuid,          (VOID **)&gRuntime,       NULL, NULL, FALSE },\r
+  { &gEfiVariableArchProtocolGuid,         (VOID **)NULL,            NULL, NULL, FALSE },\r
+  { &gEfiVariableWriteArchProtocolGuid,    (VOID **)NULL,            NULL, NULL, FALSE },\r
+  { &gEfiCapsuleArchProtocolGuid,          (VOID **)NULL,            NULL, NULL, FALSE },\r
+  { &gEfiMonotonicCounterArchProtocolGuid, (VOID **)NULL,            NULL, NULL, FALSE },\r
+  { &gEfiResetArchProtocolGuid,            (VOID **)NULL,            NULL, NULL, FALSE },\r
+  { &gEfiRealTimeClockArchProtocolGuid,    (VOID **)NULL,            NULL, NULL, FALSE },\r
+  { NULL,                                  (VOID **)NULL,            NULL, NULL, FALSE }\r
+};\r
 \r
-ARCHITECTURAL_PROTOCOL_ENTRY  mArchProtocols[] = {\r
-  { &gEfiSecurityArchProtocolGuid,         (VOID **)&gSecurity,      NULL, NULL, FALSE, TRUE  },\r
-  { &gEfiCpuArchProtocolGuid,              (VOID **)&gCpu,           NULL, NULL, FALSE, TRUE  },\r
-  { &gEfiMetronomeArchProtocolGuid,        (VOID **)&gMetronome,     NULL, NULL, FALSE, TRUE  },\r
-  { &gEfiTimerArchProtocolGuid,            (VOID **)&gTimer,         NULL, NULL, FALSE, TRUE  },\r
-  { &gEfiBdsArchProtocolGuid,              (VOID **)&gBds,           NULL, NULL, FALSE, TRUE  },\r
-  { &gEfiWatchdogTimerArchProtocolGuid,    (VOID **)&gWatchdogTimer, NULL, NULL, FALSE, TRUE  },\r
-  { &gEfiRuntimeArchProtocolGuid,          (VOID **)&gRuntime,       NULL, NULL, FALSE, TRUE  },\r
-  { &gEfiVariableArchProtocolGuid,         (VOID **)NULL,            NULL, NULL, FALSE, TRUE  },\r
-  { &gEfiVariableWriteArchProtocolGuid,    (VOID **)NULL,            NULL, NULL, FALSE, TRUE  },\r
-  { &gEfiCapsuleArchProtocolGuid,          (VOID **)NULL,            NULL, NULL, FALSE, TRUE  },\r
-  { &gEfiMonotonicCounterArchProtocolGuid, (VOID **)NULL,            NULL, NULL, FALSE, TRUE  },\r
-  { &gEfiResetArchProtocolGuid,            (VOID **)NULL,            NULL, NULL, FALSE, TRUE  },\r
-  { &gEfiRealTimeClockArchProtocolGuid,    (VOID **)NULL,            NULL, NULL, FALSE, TRUE  },\r
-  { &gEfiSmmBase2ProtocolGuid,             (VOID **)&gSmmBase2,      NULL, NULL, FALSE, FALSE }\r
+//\r
+// Optional protocols that the DXE Core will use if they are present\r
+//\r
+EFI_CORE_PROTOCOL_NOTIFY_ENTRY  mOptionalProtocols[] = {\r
+  { &gEfiSmmBase2ProtocolGuid,             (VOID **)&gSmmBase2,      NULL, NULL, FALSE },\r
+  { NULL,                                  (VOID **)NULL,            NULL, NULL, FALSE }\r
 };\r
 \r
 //\r
 // Following is needed to display missing architectural protocols in debug builds\r
 //\r
 typedef struct {\r
-  EFI_GUID                     *ProtocolGuid;\r
-  CHAR8                        *GuidString;\r
+  EFI_GUID  *ProtocolGuid;\r
+  CHAR8     *GuidString;\r
 } GUID_TO_STRING_PROTOCOL_ENTRY;\r
 \r
 GLOBAL_REMOVE_IF_UNREFERENCED CONST GUID_TO_STRING_PROTOCOL_ENTRY mMissingProtocols[] = {\r
@@ -64,7 +70,8 @@ GLOBAL_REMOVE_IF_UNREFERENCED CONST GUID_TO_STRING_PROTOCOL_ENTRY mMissingProtoc
   { &gEfiCapsuleArchProtocolGuid,          "Capsule"            },\r
   { &gEfiMonotonicCounterArchProtocolGuid, "Monotonic Counter"  },\r
   { &gEfiResetArchProtocolGuid,            "Reset"              },\r
-  { &gEfiRealTimeClockArchProtocolGuid,    "Real Time Clock"    }\r
+  { &gEfiRealTimeClockArchProtocolGuid,    "Real Time Clock"    },\r
+  { NULL,                                  ""                   }\r
 };\r
 \r
 /**\r
@@ -79,14 +86,13 @@ CoreAllEfiServicesAvailable (
   VOID\r
   )\r
 {\r
-  UINTN        Index;\r
+  EFI_CORE_PROTOCOL_NOTIFY_ENTRY  *Entry;\r
 \r
-  for (Index = 0; Index < sizeof (mArchProtocols) / sizeof (mArchProtocols[0]); Index++) {\r
-    if (mArchProtocols[Index].ArchitecturalProtocol && !mArchProtocols[Index].Present) {\r
+  for (Entry = mArchProtocols; Entry->ProtocolGuid != NULL; Entry++) {\r
+    if (!Entry->Present) {\r
       return EFI_NOT_FOUND;\r
     }\r
   }\r
-\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -104,119 +110,121 @@ CoreAllEfiServicesAvailable (
 **/\r
 VOID\r
 EFIAPI\r
-GenericArchProtocolNotify (\r
-  IN  EFI_EVENT       Event,\r
-  IN  VOID            *Context\r
+GenericProtocolNotify (\r
+  IN  EFI_EVENT  Event,\r
+  IN  VOID       *Context\r
   )\r
 {\r
   EFI_STATUS                      Status;\r
-  ARCHITECTURAL_PROTOCOL_ENTRY    *Entry;\r
+  EFI_CORE_PROTOCOL_NOTIFY_ENTRY  *Entry;\r
   VOID                            *Protocol;\r
-  BOOLEAN                         Found;\r
   LIST_ENTRY                      *Link;\r
   LIST_ENTRY                      TempLinkNode;\r
-  UINTN                           Index;\r
 \r
-  Found = FALSE;\r
-  for (Index = 0; Index < sizeof (mArchProtocols) / sizeof (mArchProtocols[0]); Index++) {\r
-    Entry = &mArchProtocols[Index];\r
+  //\r
+  // Get Entry from Context\r
+  //\r
+  Entry = (EFI_CORE_PROTOCOL_NOTIFY_ENTRY *)Context;\r
 \r
-    Status = CoreLocateProtocol (Entry->ProtocolGuid, Entry->Registration, &Protocol);\r
-    if (EFI_ERROR (Status)) {\r
-      continue;\r
-    }\r
+  //\r
+  // See if the expected protocol is present in the handle database\r
+  //\r
+  Status = CoreLocateProtocol (Entry->ProtocolGuid, Entry->Registration, &Protocol);\r
+  if (EFI_ERROR (Status)) {\r
+    return;\r
+  }\r
 \r
-    Found = TRUE;\r
-    Entry->Present = TRUE;\r
+  //\r
+  // Mark the protocol as present\r
+  //\r
+  Entry->Present = TRUE;\r
 \r
+  //\r
+  // Update protocol global variable if one exists. Entry->Protocol points to a global variable\r
+  // if one exists in the DXE core for this Architectural Protocol\r
+  //\r
+  if (Entry->Protocol != NULL) {\r
+    *(Entry->Protocol) = Protocol;\r
+  }\r
+\r
+  //\r
+  // Do special operations for Architectural Protocols\r
+  //\r
+\r
+  if (CompareGuid (Entry->ProtocolGuid, &gEfiTimerArchProtocolGuid)) {\r
     //\r
-    // Update protocol global variable if one exists. Entry->Protocol points to a global variable\r
-    // if one exists in the DXE core for this Architectural Protocol\r
+    // Register the Core timer tick handler with the Timer AP\r
     //\r
-    if (Entry->Protocol != NULL) {\r
-      *(Entry->Protocol) = Protocol;\r
-    }\r
+    gTimer->RegisterHandler (gTimer, CoreTimerTick);\r
+  }\r
 \r
-    if (CompareGuid (Entry->ProtocolGuid, &gEfiTimerArchProtocolGuid)) {\r
-      //\r
-      // Register the Core timer tick handler with the Timer AP\r
-      //\r
-      gTimer->RegisterHandler (gTimer, CoreTimerTick);\r
-    }\r
+  if (CompareGuid (Entry->ProtocolGuid, &gEfiRuntimeArchProtocolGuid)) {\r
+    //\r
+    // When runtime architectural protocol is available, updates CRC32 in the Debug Table\r
+    //\r
+    CoreUpdateDebugTableCrc32 ();\r
 \r
-    if (CompareGuid (Entry->ProtocolGuid, &gEfiRuntimeArchProtocolGuid)) {\r
-      //\r
-      // When runtime architectural protocol is available, updates CRC32 in the Debug Table\r
-      //\r
-      CoreUpdateDebugTableCrc32 ();\r
-\r
-      //\r
-      // Update the Runtime Architectural protocol with the template that the core was\r
-      // using so there would not need to be a dependency on the Runtime AP\r
-      //\r
-\r
-      //\r
-      // Copy all the registered Image to new gRuntime protocol\r
-      //\r
-      for (Link = gRuntimeTemplate.ImageHead.ForwardLink; Link != &gRuntimeTemplate.ImageHead; Link = TempLinkNode.ForwardLink) {\r
-        CopyMem (&TempLinkNode, Link, sizeof(LIST_ENTRY));\r
-        InsertTailList (&gRuntime->ImageHead, Link);\r
-      }\r
-      //\r
-      // Copy all the registered Event to new gRuntime protocol\r
-      //\r
-      for (Link = gRuntimeTemplate.EventHead.ForwardLink; Link != &gRuntimeTemplate.EventHead; Link = TempLinkNode.ForwardLink) {\r
-        CopyMem (&TempLinkNode, Link, sizeof(LIST_ENTRY));\r
-        InsertTailList (&gRuntime->EventHead, Link);\r
-      }\r
+    //\r
+    // Update the Runtime Architectural protocol with the template that the core was\r
+    // using so there would not need to be a dependency on the Runtime AP\r
+    //\r
 \r
-      //\r
-      // Clean up gRuntimeTemplate\r
-      //\r
-      gRuntimeTemplate.ImageHead.ForwardLink = &gRuntimeTemplate.ImageHead;\r
-      gRuntimeTemplate.ImageHead.BackLink    = &gRuntimeTemplate.ImageHead;\r
-      gRuntimeTemplate.EventHead.ForwardLink = &gRuntimeTemplate.EventHead;\r
-      gRuntimeTemplate.EventHead.BackLink    = &gRuntimeTemplate.EventHead;\r
+    //\r
+    // Copy all the registered Image to new gRuntime protocol\r
+    //\r
+    for (Link = gRuntimeTemplate.ImageHead.ForwardLink; Link != &gRuntimeTemplate.ImageHead; Link = TempLinkNode.ForwardLink) {\r
+      CopyMem (&TempLinkNode, Link, sizeof(LIST_ENTRY));\r
+      InsertTailList (&gRuntime->ImageHead, Link);\r
+    }\r
+    //\r
+    // Copy all the registered Event to new gRuntime protocol\r
+    //\r
+    for (Link = gRuntimeTemplate.EventHead.ForwardLink; Link != &gRuntimeTemplate.EventHead; Link = TempLinkNode.ForwardLink) {\r
+      CopyMem (&TempLinkNode, Link, sizeof(LIST_ENTRY));\r
+      InsertTailList (&gRuntime->EventHead, Link);\r
     }\r
+\r
+    //\r
+    // Clean up gRuntimeTemplate\r
+    //\r
+    gRuntimeTemplate.ImageHead.ForwardLink = &gRuntimeTemplate.ImageHead;\r
+    gRuntimeTemplate.ImageHead.BackLink    = &gRuntimeTemplate.ImageHead;\r
+    gRuntimeTemplate.EventHead.ForwardLink = &gRuntimeTemplate.EventHead;\r
+    gRuntimeTemplate.EventHead.BackLink    = &gRuntimeTemplate.EventHead;\r
   }\r
 \r
   //\r
   // It's over kill to do them all every time, but it saves a lot of code.\r
   //\r
-  if (Found) {\r
-    CalculateEfiHdrCrc (&gDxeCoreRT->Hdr);\r
-    CalculateEfiHdrCrc (&gBS->Hdr);\r
-    CalculateEfiHdrCrc (&gDxeCoreST->Hdr);\r
-    CalculateEfiHdrCrc (&gDxeCoreDS->Hdr);\r
-  }\r
+  CalculateEfiHdrCrc (&gDxeCoreRT->Hdr);\r
+  CalculateEfiHdrCrc (&gBS->Hdr);\r
+  CalculateEfiHdrCrc (&gDxeCoreST->Hdr);\r
+  CalculateEfiHdrCrc (&gDxeCoreDS->Hdr);\r
 }\r
 \r
-\r
-\r
 /**\r
-  Creates an event that is fired everytime a Protocol of a specific type is installed.\r
+  Creates an event for each entry in a table that is fired everytime a Protocol \r
+  of a specific type is installed.\r
+\r
+  @param Entry  Pointer to EFI_CORE_PROTOCOL_NOTIFY_ENTRY.\r
 \r
 **/\r
 VOID\r
-CoreNotifyOnArchProtocolInstallation (\r
-  VOID\r
+CoreNotifyOnProtocolEntryTable (\r
+  EFI_CORE_PROTOCOL_NOTIFY_ENTRY  *Entry\r
   )\r
 {\r
-  EFI_STATUS                      Status;\r
-  ARCHITECTURAL_PROTOCOL_ENTRY    *Entry;\r
-  UINTN                           Index;\r
-\r
-  for (Index = 0; Index < sizeof (mArchProtocols) / sizeof (mArchProtocols[0]); Index++) {\r
-    Entry = &mArchProtocols[Index];\r
+  EFI_STATUS  Status;\r
 \r
+  for (; Entry->ProtocolGuid != NULL; Entry++) {\r
     //\r
     // Create the event\r
     //\r
     Status = CoreCreateEvent (\r
               EVT_NOTIFY_SIGNAL,\r
               TPL_CALLBACK,\r
-              GenericArchProtocolNotify,\r
-              NULL,\r
+              GenericProtocolNotify,\r
+              Entry,\r
               &Entry->Event\r
               );\r
     ASSERT_EFI_ERROR(Status);\r
@@ -230,10 +238,23 @@ CoreNotifyOnArchProtocolInstallation (
               &Entry->Registration\r
               );\r
     ASSERT_EFI_ERROR(Status);\r
-\r
   }\r
 }\r
 \r
+/**\r
+  Creates an events for the Architectural Protocols and the optional protocols \r
+  that are fired everytime a Protocol of a specific type is installed.\r
+\r
+**/\r
+VOID\r
+CoreNotifyOnProtocolInstallation (\r
+  VOID\r
+  )\r
+{\r
+  CoreNotifyOnProtocolEntryTable (mArchProtocols);\r
+  CoreNotifyOnProtocolEntryTable (mOptionalProtocols);\r
+}\r
+\r
 \r
 /**\r
   Displays Architectural protocols that were not loaded and are required for DXE\r
@@ -245,14 +266,12 @@ CoreDisplayMissingArchProtocols (
   VOID\r
   )\r
 {\r
+  EFI_CORE_PROTOCOL_NOTIFY_ENTRY       *Entry;\r
   CONST GUID_TO_STRING_PROTOCOL_ENTRY  *MissingEntry;\r
-  ARCHITECTURAL_PROTOCOL_ENTRY         *Entry;\r
-  UINTN                                Index;\r
 \r
-  for (Index = 0; Index < sizeof (mArchProtocols) / sizeof (mArchProtocols[0]); Index++) {\r
-    Entry = &mArchProtocols[Index];\r
-    if (!Entry->Present && Entry->ArchitecturalProtocol) {\r
-      for (MissingEntry = mMissingProtocols; MissingEntry < sizeof (mMissingProtocols)/sizeof (mMissingProtocols[0]) ; MissingEntry++) {\r
+  for (Entry = mArchProtocols; Entry->ProtocolGuid != NULL; Entry++) {\r
+    if (!Entry->Present) {\r
+      for (MissingEntry = mMissingProtocols; MissingEntry->ProtocolGuid != NULL; MissingEntry++) {\r
         if (CompareGuid (Entry->ProtocolGuid, MissingEntry->ProtocolGuid)) {\r
           DEBUG ((DEBUG_ERROR, "\n%a Arch Protocol not present!!\n", MissingEntry->GuidString));\r
           break;\r