\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
// 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
{ &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
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
**/\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
&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
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