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
);
178 // Copy all the registered Event to new gRuntime protocol
180 for (Link
= gRuntimeTemplate
.EventHead
.ForwardLink
; Link
!= &gRuntimeTemplate
.EventHead
; Link
= TempLinkNode
.ForwardLink
) {
181 CopyMem (&TempLinkNode
, Link
, sizeof (LIST_ENTRY
));
182 InsertTailList (&gRuntime
->EventHead
, Link
);
186 // Clean up gRuntimeTemplate
188 gRuntimeTemplate
.ImageHead
.ForwardLink
= &gRuntimeTemplate
.ImageHead
;
189 gRuntimeTemplate
.ImageHead
.BackLink
= &gRuntimeTemplate
.ImageHead
;
190 gRuntimeTemplate
.EventHead
.ForwardLink
= &gRuntimeTemplate
.EventHead
;
191 gRuntimeTemplate
.EventHead
.BackLink
= &gRuntimeTemplate
.EventHead
;
195 // It's over kill to do them all every time, but it saves a lot of code.
197 CalculateEfiHdrCrc (&gDxeCoreRT
->Hdr
);
198 CalculateEfiHdrCrc (&gBS
->Hdr
);
199 CalculateEfiHdrCrc (&gDxeCoreST
->Hdr
);
200 CalculateEfiHdrCrc (&gDxeCoreDS
->Hdr
);
204 Creates an event for each entry in a table that is fired everytime a Protocol
205 of a specific type is installed.
207 @param Entry Pointer to EFI_CORE_PROTOCOL_NOTIFY_ENTRY.
211 CoreNotifyOnProtocolEntryTable (
212 EFI_CORE_PROTOCOL_NOTIFY_ENTRY
*Entry
217 for ( ; Entry
->ProtocolGuid
!= NULL
; Entry
++) {
221 Status
= CoreCreateEvent (
224 GenericProtocolNotify
,
228 ASSERT_EFI_ERROR (Status
);
231 // Register for protocol notifactions on this event
233 Status
= CoreRegisterProtocolNotify (
238 ASSERT_EFI_ERROR (Status
);
243 Creates an events for the Architectural Protocols and the optional protocols
244 that are fired everytime a Protocol of a specific type is installed.
248 CoreNotifyOnProtocolInstallation (
252 CoreNotifyOnProtocolEntryTable (mArchProtocols
);
253 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
));