]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Core/Dxe/DxeMain/DxeProtocolNotify.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / DxeMain / DxeProtocolNotify.c
CommitLineData
23c98c94 1/** @file\r
504214c4
LG
2 This file deals with Architecture Protocol (AP) registration in\r
3 the Dxe Core. The mArchProtocols[] array represents a list of\r
4 events that represent the Architectural Protocols.\r
5\r
d1102dba 6Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
9d510e61 7SPDX-License-Identifier: BSD-2-Clause-Patent\r
28a00297 8\r
504214c4 9**/\r
28a00297 10\r
9c4ac31c 11#include "DxeMain.h"\r
28a00297 12\r
28a00297 13//\r
14// DXE Core Global Variables for all of the Architectural Protocols.\r
15// If a protocol is installed mArchProtocols[].Present will be TRUE.\r
16//\r
17// CoreNotifyOnArchProtocolInstallation () fills in mArchProtocols[].Event\r
18// and mArchProtocols[].Registration as it creates events for every array\r
19// entry.\r
20//\r
74e44290 21EFI_CORE_PROTOCOL_NOTIFY_ENTRY mArchProtocols[] = {\r
22 { &gEfiSecurityArchProtocolGuid, (VOID **)&gSecurity, NULL, NULL, FALSE },\r
23 { &gEfiCpuArchProtocolGuid, (VOID **)&gCpu, NULL, NULL, FALSE },\r
24 { &gEfiMetronomeArchProtocolGuid, (VOID **)&gMetronome, NULL, NULL, FALSE },\r
25 { &gEfiTimerArchProtocolGuid, (VOID **)&gTimer, NULL, NULL, FALSE },\r
26 { &gEfiBdsArchProtocolGuid, (VOID **)&gBds, NULL, NULL, FALSE },\r
27 { &gEfiWatchdogTimerArchProtocolGuid, (VOID **)&gWatchdogTimer, NULL, NULL, FALSE },\r
28 { &gEfiRuntimeArchProtocolGuid, (VOID **)&gRuntime, NULL, NULL, FALSE },\r
29 { &gEfiVariableArchProtocolGuid, (VOID **)NULL, NULL, NULL, FALSE },\r
30 { &gEfiVariableWriteArchProtocolGuid, (VOID **)NULL, NULL, NULL, FALSE },\r
31 { &gEfiCapsuleArchProtocolGuid, (VOID **)NULL, NULL, NULL, FALSE },\r
32 { &gEfiMonotonicCounterArchProtocolGuid, (VOID **)NULL, NULL, NULL, FALSE },\r
33 { &gEfiResetArchProtocolGuid, (VOID **)NULL, NULL, NULL, FALSE },\r
34 { &gEfiRealTimeClockArchProtocolGuid, (VOID **)NULL, NULL, NULL, FALSE },\r
35 { NULL, (VOID **)NULL, NULL, NULL, FALSE }\r
36};\r
28a00297 37\r
74e44290 38//\r
39// Optional protocols that the DXE Core will use if they are present\r
40//\r
41EFI_CORE_PROTOCOL_NOTIFY_ENTRY mOptionalProtocols[] = {\r
1436aea4
MK
42 { &gEfiSecurity2ArchProtocolGuid, (VOID **)&gSecurity2, NULL, NULL, FALSE },\r
43 { &gEfiSmmBase2ProtocolGuid, (VOID **)&gSmmBase2, NULL, NULL, FALSE },\r
44 { NULL, (VOID **)NULL, NULL, NULL, FALSE }\r
28a00297 45};\r
46\r
44cfd8a8 47//\r
48// Following is needed to display missing architectural protocols in debug builds\r
49//\r
50typedef struct {\r
1436aea4
MK
51 EFI_GUID *ProtocolGuid;\r
52 CHAR8 *GuidString;\r
44cfd8a8 53} GUID_TO_STRING_PROTOCOL_ENTRY;\r
28a00297 54\r
1436aea4
MK
55GLOBAL_REMOVE_IF_UNREFERENCED CONST GUID_TO_STRING_PROTOCOL_ENTRY mMissingProtocols[] = {\r
56 { &gEfiSecurityArchProtocolGuid, "Security" },\r
57 { &gEfiCpuArchProtocolGuid, "CPU" },\r
58 { &gEfiMetronomeArchProtocolGuid, "Metronome" },\r
59 { &gEfiTimerArchProtocolGuid, "Timer" },\r
60 { &gEfiBdsArchProtocolGuid, "Bds" },\r
61 { &gEfiWatchdogTimerArchProtocolGuid, "Watchdog Timer" },\r
62 { &gEfiRuntimeArchProtocolGuid, "Runtime" },\r
63 { &gEfiVariableArchProtocolGuid, "Variable" },\r
64 { &gEfiVariableWriteArchProtocolGuid, "Variable Write" },\r
65 { &gEfiCapsuleArchProtocolGuid, "Capsule" },\r
66 { &gEfiMonotonicCounterArchProtocolGuid, "Monotonic Counter" },\r
67 { &gEfiResetArchProtocolGuid, "Reset" },\r
68 { &gEfiRealTimeClockArchProtocolGuid, "Real Time Clock" },\r
69 { NULL, "" }\r
44cfd8a8 70};\r
28a00297 71\r
162ed594 72/**\r
6393d9c8 73 Return TRUE if all AP services are available.\r
28a00297 74\r
022c6d45 75 @retval EFI_SUCCESS All AP services are available\r
162ed594 76 @retval EFI_NOT_FOUND At least one AP service is not available\r
28a00297 77\r
162ed594 78**/\r
79EFI_STATUS\r
80CoreAllEfiServicesAvailable (\r
81 VOID\r
82 )\r
28a00297 83{\r
74e44290 84 EFI_CORE_PROTOCOL_NOTIFY_ENTRY *Entry;\r
28a00297 85\r
74e44290 86 for (Entry = mArchProtocols; Entry->ProtocolGuid != NULL; Entry++) {\r
87 if (!Entry->Present) {\r
28a00297 88 return EFI_NOT_FOUND;\r
89 }\r
90 }\r
1436aea4 91\r
28a00297 92 return EFI_SUCCESS;\r
93}\r
94\r
162ed594 95/**\r
28a00297 96 Notification event handler registered by CoreNotifyOnArchProtocolInstallation ().\r
97 This notify function is registered for every architectural protocol. This handler\r
98 updates mArchProtocol[] array entry with protocol instance data and sets it's\r
99 present flag to TRUE. If any constructor is required it is executed. The EFI\r
100 System Table headers are updated.\r
101\r
022c6d45 102 @param Event The Event that is being processed, not used.\r
162ed594 103 @param Context Event Context, not used.\r
28a00297 104\r
162ed594 105**/\r
162ed594 106VOID\r
107EFIAPI\r
74e44290 108GenericProtocolNotify (\r
109 IN EFI_EVENT Event,\r
110 IN VOID *Context\r
162ed594 111 )\r
28a00297 112{\r
113 EFI_STATUS Status;\r
74e44290 114 EFI_CORE_PROTOCOL_NOTIFY_ENTRY *Entry;\r
28a00297 115 VOID *Protocol;\r
28a00297 116 LIST_ENTRY *Link;\r
117 LIST_ENTRY TempLinkNode;\r
118\r
4e1005ec
ED
119 Protocol = NULL;\r
120\r
74e44290 121 //\r
122 // Get Entry from Context\r
123 //\r
124 Entry = (EFI_CORE_PROTOCOL_NOTIFY_ENTRY *)Context;\r
28a00297 125\r
74e44290 126 //\r
127 // See if the expected protocol is present in the handle database\r
128 //\r
129 Status = CoreLocateProtocol (Entry->ProtocolGuid, Entry->Registration, &Protocol);\r
130 if (EFI_ERROR (Status)) {\r
131 return;\r
132 }\r
28a00297 133\r
74e44290 134 //\r
135 // Mark the protocol as present\r
136 //\r
137 Entry->Present = TRUE;\r
28a00297 138\r
74e44290 139 //\r
140 // Update protocol global variable if one exists. Entry->Protocol points to a global variable\r
141 // if one exists in the DXE core for this Architectural Protocol\r
142 //\r
143 if (Entry->Protocol != NULL) {\r
144 *(Entry->Protocol) = Protocol;\r
145 }\r
146\r
147 //\r
148 // Do special operations for Architectural Protocols\r
149 //\r
150\r
151 if (CompareGuid (Entry->ProtocolGuid, &gEfiTimerArchProtocolGuid)) {\r
28a00297 152 //\r
74e44290 153 // Register the Core timer tick handler with the Timer AP\r
28a00297 154 //\r
74e44290 155 gTimer->RegisterHandler (gTimer, CoreTimerTick);\r
156 }\r
28a00297 157\r
74e44290 158 if (CompareGuid (Entry->ProtocolGuid, &gEfiRuntimeArchProtocolGuid)) {\r
159 //\r
160 // When runtime architectural protocol is available, updates CRC32 in the Debug Table\r
161 //\r
162 CoreUpdateDebugTableCrc32 ();\r
28a00297 163\r
74e44290 164 //\r
165 // Update the Runtime Architectural protocol with the template that the core was\r
166 // using so there would not need to be a dependency on the Runtime AP\r
167 //\r
28a00297 168\r
74e44290 169 //\r
170 // Copy all the registered Image to new gRuntime protocol\r
171 //\r
172 for (Link = gRuntimeTemplate.ImageHead.ForwardLink; Link != &gRuntimeTemplate.ImageHead; Link = TempLinkNode.ForwardLink) {\r
1436aea4 173 CopyMem (&TempLinkNode, Link, sizeof (LIST_ENTRY));\r
74e44290 174 InsertTailList (&gRuntime->ImageHead, Link);\r
175 }\r
1436aea4 176\r
74e44290 177 //\r
178 // Copy all the registered Event to new gRuntime protocol\r
179 //\r
180 for (Link = gRuntimeTemplate.EventHead.ForwardLink; Link != &gRuntimeTemplate.EventHead; Link = TempLinkNode.ForwardLink) {\r
1436aea4 181 CopyMem (&TempLinkNode, Link, sizeof (LIST_ENTRY));\r
74e44290 182 InsertTailList (&gRuntime->EventHead, Link);\r
28a00297 183 }\r
74e44290 184\r
185 //\r
186 // Clean up gRuntimeTemplate\r
187 //\r
188 gRuntimeTemplate.ImageHead.ForwardLink = &gRuntimeTemplate.ImageHead;\r
189 gRuntimeTemplate.ImageHead.BackLink = &gRuntimeTemplate.ImageHead;\r
190 gRuntimeTemplate.EventHead.ForwardLink = &gRuntimeTemplate.EventHead;\r
191 gRuntimeTemplate.EventHead.BackLink = &gRuntimeTemplate.EventHead;\r
28a00297 192 }\r
193\r
194 //\r
195 // It's over kill to do them all every time, but it saves a lot of code.\r
196 //\r
74e44290 197 CalculateEfiHdrCrc (&gDxeCoreRT->Hdr);\r
198 CalculateEfiHdrCrc (&gBS->Hdr);\r
199 CalculateEfiHdrCrc (&gDxeCoreST->Hdr);\r
200 CalculateEfiHdrCrc (&gDxeCoreDS->Hdr);\r
28a00297 201}\r
202\r
162ed594 203/**\r
d1102dba 204 Creates an event for each entry in a table that is fired everytime a Protocol\r
74e44290 205 of a specific type is installed.\r
162ed594 206\r
12fbc893 207 @param Entry Pointer to EFI_CORE_PROTOCOL_NOTIFY_ENTRY.\r
208\r
162ed594 209**/\r
28a00297 210VOID\r
74e44290 211CoreNotifyOnProtocolEntryTable (\r
212 EFI_CORE_PROTOCOL_NOTIFY_ENTRY *Entry\r
28a00297 213 )\r
28a00297 214{\r
74e44290 215 EFI_STATUS Status;\r
28a00297 216\r
1436aea4 217 for ( ; Entry->ProtocolGuid != NULL; Entry++) {\r
28a00297 218 //\r
219 // Create the event\r
220 //\r
221 Status = CoreCreateEvent (\r
1436aea4
MK
222 EVT_NOTIFY_SIGNAL,\r
223 TPL_CALLBACK,\r
224 GenericProtocolNotify,\r
225 Entry,\r
226 &Entry->Event\r
227 );\r
228 ASSERT_EFI_ERROR (Status);\r
28a00297 229\r
230 //\r
231 // Register for protocol notifactions on this event\r
232 //\r
233 Status = CoreRegisterProtocolNotify (\r
1436aea4
MK
234 Entry->ProtocolGuid,\r
235 Entry->Event,\r
236 &Entry->Registration\r
237 );\r
238 ASSERT_EFI_ERROR (Status);\r
28a00297 239 }\r
240}\r
241\r
74e44290 242/**\r
d1102dba 243 Creates an events for the Architectural Protocols and the optional protocols\r
74e44290 244 that are fired everytime a Protocol of a specific type is installed.\r
245\r
246**/\r
247VOID\r
248CoreNotifyOnProtocolInstallation (\r
249 VOID\r
250 )\r
251{\r
252 CoreNotifyOnProtocolEntryTable (mArchProtocols);\r
253 CoreNotifyOnProtocolEntryTable (mOptionalProtocols);\r
254}\r
255\r
162ed594 256/**\r
257 Displays Architectural protocols that were not loaded and are required for DXE\r
258 core to function. Only used in Debug Builds.\r
259\r
260**/\r
28a00297 261VOID\r
262CoreDisplayMissingArchProtocols (\r
263 VOID\r
264 )\r
28a00297 265{\r
74e44290 266 EFI_CORE_PROTOCOL_NOTIFY_ENTRY *Entry;\r
e94a9ff7 267 CONST GUID_TO_STRING_PROTOCOL_ENTRY *MissingEntry;\r
28a00297 268\r
74e44290 269 for (Entry = mArchProtocols; Entry->ProtocolGuid != NULL; Entry++) {\r
270 if (!Entry->Present) {\r
271 for (MissingEntry = mMissingProtocols; MissingEntry->ProtocolGuid != NULL; MissingEntry++) {\r
28a00297 272 if (CompareGuid (Entry->ProtocolGuid, MissingEntry->ProtocolGuid)) {\r
4fdc9129 273 DEBUG ((DEBUG_ERROR, "\n%a Arch Protocol not present!!\n", MissingEntry->GuidString));\r
28a00297 274 break;\r
275 }\r
276 }\r
277 }\r
278 }\r
279}\r