2 This file deals with Architecture Protocol (AP) registration in
3 the Dxe Core. The mArchProtocols[] array represents a list of
4 events that represent the Architectural Protocols.
6 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
7 SPDX-License-Identifier: BSD-2-Clause-Patent
14 // DXE Core Global Variables for all of the Architectural Protocols.
15 // If a protocol is installed mArchProtocols[].Present will be TRUE.
17 // CoreNotifyOnArchProtocolInstallation () fills in mArchProtocols[].Event
18 // and mArchProtocols[].Registration as it creates events for every array
21 EFI_CORE_PROTOCOL_NOTIFY_ENTRY mArchProtocols
[] = {
22 { &gEfiSecurityArchProtocolGuid
, (VOID
**)&gSecurity
, NULL
, NULL
, FALSE
},
23 { &gEfiCpuArchProtocolGuid
, (VOID
**)&gCpu
, NULL
, NULL
, FALSE
},
24 { &gEfiMetronomeArchProtocolGuid
, (VOID
**)&gMetronome
, NULL
, NULL
, FALSE
},
25 { &gEfiTimerArchProtocolGuid
, (VOID
**)&gTimer
, NULL
, NULL
, FALSE
},
26 { &gEfiBdsArchProtocolGuid
, (VOID
**)&gBds
, NULL
, NULL
, FALSE
},
27 { &gEfiWatchdogTimerArchProtocolGuid
, (VOID
**)&gWatchdogTimer
, NULL
, NULL
, FALSE
},
28 { &gEfiRuntimeArchProtocolGuid
, (VOID
**)&gRuntime
, NULL
, NULL
, FALSE
},
29 { &gEfiVariableArchProtocolGuid
, (VOID
**)NULL
, NULL
, NULL
, FALSE
},
30 { &gEfiVariableWriteArchProtocolGuid
, (VOID
**)NULL
, NULL
, NULL
, FALSE
},
31 { &gEfiCapsuleArchProtocolGuid
, (VOID
**)NULL
, NULL
, NULL
, FALSE
},
32 { &gEfiMonotonicCounterArchProtocolGuid
, (VOID
**)NULL
, NULL
, NULL
, FALSE
},
33 { &gEfiResetArchProtocolGuid
, (VOID
**)NULL
, NULL
, NULL
, FALSE
},
34 { &gEfiRealTimeClockArchProtocolGuid
, (VOID
**)NULL
, NULL
, NULL
, FALSE
},
35 { NULL
, (VOID
**)NULL
, NULL
, NULL
, FALSE
}
39 // Optional protocols that the DXE Core will use if they are present
41 EFI_CORE_PROTOCOL_NOTIFY_ENTRY mOptionalProtocols
[] = {
42 { &gEfiSecurity2ArchProtocolGuid
, (VOID
**)&gSecurity2
, NULL
, NULL
, FALSE
},
43 { &gEfiSmmBase2ProtocolGuid
, (VOID
**)&gSmmBase2
, NULL
, NULL
, FALSE
},
44 { NULL
, (VOID
**)NULL
, NULL
, NULL
, FALSE
}
48 // Following is needed to display missing architectural protocols in debug builds
51 EFI_GUID
*ProtocolGuid
;
53 } GUID_TO_STRING_PROTOCOL_ENTRY
;
55 GLOBAL_REMOVE_IF_UNREFERENCED CONST GUID_TO_STRING_PROTOCOL_ENTRY mMissingProtocols
[] = {
56 { &gEfiSecurityArchProtocolGuid
, "Security" },
57 { &gEfiCpuArchProtocolGuid
, "CPU" },
58 { &gEfiMetronomeArchProtocolGuid
, "Metronome" },
59 { &gEfiTimerArchProtocolGuid
, "Timer" },
60 { &gEfiBdsArchProtocolGuid
, "Bds" },
61 { &gEfiWatchdogTimerArchProtocolGuid
, "Watchdog Timer" },
62 { &gEfiRuntimeArchProtocolGuid
, "Runtime" },
63 { &gEfiVariableArchProtocolGuid
, "Variable" },
64 { &gEfiVariableWriteArchProtocolGuid
, "Variable Write" },
65 { &gEfiCapsuleArchProtocolGuid
, "Capsule" },
66 { &gEfiMonotonicCounterArchProtocolGuid
, "Monotonic Counter" },
67 { &gEfiResetArchProtocolGuid
, "Reset" },
68 { &gEfiRealTimeClockArchProtocolGuid
, "Real Time Clock" },
73 Return TRUE if all AP services are available.
75 @retval EFI_SUCCESS All AP services are available
76 @retval EFI_NOT_FOUND At least one AP service is not available
80 CoreAllEfiServicesAvailable (
84 EFI_CORE_PROTOCOL_NOTIFY_ENTRY
*Entry
;
86 for (Entry
= mArchProtocols
; Entry
->ProtocolGuid
!= NULL
; Entry
++) {
87 if (!Entry
->Present
) {
96 Notification event handler registered by CoreNotifyOnArchProtocolInstallation ().
97 This notify function is registered for every architectural protocol. This handler
98 updates mArchProtocol[] array entry with protocol instance data and sets it's
99 present flag to TRUE. If any constructor is required it is executed. The EFI
100 System Table headers are updated.
102 @param Event The Event that is being processed, not used.
103 @param Context Event Context, not used.
108 GenericProtocolNotify (
114 EFI_CORE_PROTOCOL_NOTIFY_ENTRY
*Entry
;
117 LIST_ENTRY TempLinkNode
;
122 // Get Entry from Context
124 Entry
= (EFI_CORE_PROTOCOL_NOTIFY_ENTRY
*)Context
;
127 // See if the expected protocol is present in the handle database
129 Status
= CoreLocateProtocol (Entry
->ProtocolGuid
, Entry
->Registration
, &Protocol
);
130 if (EFI_ERROR (Status
)) {
135 // Mark the protocol as present
137 Entry
->Present
= TRUE
;
140 // Update protocol global variable if one exists. Entry->Protocol points to a global variable
141 // if one exists in the DXE core for this Architectural Protocol
143 if (Entry
->Protocol
!= NULL
) {
144 *(Entry
->Protocol
) = Protocol
;
148 // Do special operations for Architectural Protocols
151 if (CompareGuid (Entry
->ProtocolGuid
, &gEfiTimerArchProtocolGuid
)) {
153 // Register the Core timer tick handler with the Timer AP
155 gTimer
->RegisterHandler (gTimer
, CoreTimerTick
);
158 if (CompareGuid (Entry
->ProtocolGuid
, &gEfiRuntimeArchProtocolGuid
)) {
160 // When runtime architectural protocol is available, updates CRC32 in the Debug Table
162 CoreUpdateDebugTableCrc32 ();
165 // Update the Runtime Architectural protocol with the template that the core was
166 // using so there would not need to be a dependency on the Runtime AP
170 // Copy all the registered Image to new gRuntime protocol
172 for (Link
= gRuntimeTemplate
.ImageHead
.ForwardLink
; Link
!= &gRuntimeTemplate
.ImageHead
; Link
= TempLinkNode
.ForwardLink
) {
173 CopyMem (&TempLinkNode
, Link
, sizeof(LIST_ENTRY
));
174 InsertTailList (&gRuntime
->ImageHead
, Link
);
177 // Copy all the registered Event to new gRuntime protocol
179 for (Link
= gRuntimeTemplate
.EventHead
.ForwardLink
; Link
!= &gRuntimeTemplate
.EventHead
; Link
= TempLinkNode
.ForwardLink
) {
180 CopyMem (&TempLinkNode
, Link
, sizeof(LIST_ENTRY
));
181 InsertTailList (&gRuntime
->EventHead
, Link
);
185 // Clean up gRuntimeTemplate
187 gRuntimeTemplate
.ImageHead
.ForwardLink
= &gRuntimeTemplate
.ImageHead
;
188 gRuntimeTemplate
.ImageHead
.BackLink
= &gRuntimeTemplate
.ImageHead
;
189 gRuntimeTemplate
.EventHead
.ForwardLink
= &gRuntimeTemplate
.EventHead
;
190 gRuntimeTemplate
.EventHead
.BackLink
= &gRuntimeTemplate
.EventHead
;
194 // It's over kill to do them all every time, but it saves a lot of code.
196 CalculateEfiHdrCrc (&gDxeCoreRT
->Hdr
);
197 CalculateEfiHdrCrc (&gBS
->Hdr
);
198 CalculateEfiHdrCrc (&gDxeCoreST
->Hdr
);
199 CalculateEfiHdrCrc (&gDxeCoreDS
->Hdr
);
203 Creates an event for each entry in a table that is fired everytime a Protocol
204 of a specific type is installed.
206 @param Entry Pointer to EFI_CORE_PROTOCOL_NOTIFY_ENTRY.
210 CoreNotifyOnProtocolEntryTable (
211 EFI_CORE_PROTOCOL_NOTIFY_ENTRY
*Entry
216 for (; Entry
->ProtocolGuid
!= NULL
; Entry
++) {
220 Status
= CoreCreateEvent (
223 GenericProtocolNotify
,
227 ASSERT_EFI_ERROR(Status
);
230 // Register for protocol notifactions on this event
232 Status
= CoreRegisterProtocolNotify (
237 ASSERT_EFI_ERROR(Status
);
242 Creates an events for the Architectural Protocols and the optional protocols
243 that are fired everytime a Protocol of a specific type is installed.
247 CoreNotifyOnProtocolInstallation (
251 CoreNotifyOnProtocolEntryTable (mArchProtocols
);
252 CoreNotifyOnProtocolEntryTable (mOptionalProtocols
);
257 Displays Architectural protocols that were not loaded and are required for DXE
258 core to function. Only used in Debug Builds.
262 CoreDisplayMissingArchProtocols (
266 EFI_CORE_PROTOCOL_NOTIFY_ENTRY
*Entry
;
267 CONST GUID_TO_STRING_PROTOCOL_ENTRY
*MissingEntry
;
269 for (Entry
= mArchProtocols
; Entry
->ProtocolGuid
!= NULL
; Entry
++) {
270 if (!Entry
->Present
) {
271 for (MissingEntry
= mMissingProtocols
; MissingEntry
->ProtocolGuid
!= NULL
; MissingEntry
++) {
272 if (CompareGuid (Entry
->ProtocolGuid
, MissingEntry
->ProtocolGuid
)) {
273 DEBUG ((DEBUG_ERROR
, "\n%a Arch Protocol not present!!\n", MissingEntry
->GuidString
));