]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Core/Dxe/DxeMain/DxeProtocolNotify.c
Clean up PERF macro usage. The macros were being used with 0 as the first parameter...
[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
23c98c94 6Copyright (c) 2006 - 2008, Intel Corporation. <BR>\r
28a00297 7All rights reserved. This program and the accompanying materials\r
8are licensed and made available under the terms and conditions of the BSD License\r
9which accompanies this distribution. The full text of the license may be found at\r
10http://opensource.org/licenses/bsd-license.php\r
11\r
12THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
14\r
504214c4 15**/\r
28a00297 16\r
9c4ac31c 17#include "DxeMain.h"\r
28a00297 18\r
19\r
20//\r
21// DXE Core Global Variables for all of the Architectural Protocols.\r
22// If a protocol is installed mArchProtocols[].Present will be TRUE.\r
23//\r
24// CoreNotifyOnArchProtocolInstallation () fills in mArchProtocols[].Event\r
25// and mArchProtocols[].Registration as it creates events for every array\r
26// entry.\r
27//\r
28\r
29ARCHITECTURAL_PROTOCOL_ENTRY mArchProtocols[] = {\r
30 { &gEfiSecurityArchProtocolGuid, (VOID **)&gSecurity, NULL, NULL, FALSE },\r
31 { &gEfiCpuArchProtocolGuid, (VOID **)&gCpu, NULL, NULL, FALSE },\r
32 { &gEfiMetronomeArchProtocolGuid, (VOID **)&gMetronome, NULL, NULL, FALSE },\r
33 { &gEfiTimerArchProtocolGuid, (VOID **)&gTimer, NULL, NULL, FALSE },\r
34 { &gEfiBdsArchProtocolGuid, (VOID **)&gBds, NULL, NULL, FALSE },\r
35 { &gEfiWatchdogTimerArchProtocolGuid, (VOID **)&gWatchdogTimer, NULL, NULL, FALSE },\r
36 { &gEfiRuntimeArchProtocolGuid, (VOID **)&gRuntime, NULL, NULL, FALSE },\r
37 { &gEfiVariableArchProtocolGuid, (VOID **)NULL, NULL, NULL, FALSE },\r
38 { &gEfiVariableWriteArchProtocolGuid, (VOID **)NULL, NULL, NULL, FALSE },\r
e94a9ff7 39 { &gEfiCapsuleArchProtocolGuid, (VOID **)NULL, NULL, NULL, FALSE },\r
28a00297 40 { &gEfiMonotonicCounterArchProtocolGuid, (VOID **)NULL, NULL, NULL, FALSE },\r
41 { &gEfiResetArchProtocolGuid, (VOID **)NULL, NULL, NULL, FALSE },\r
3f143578 42 { &gEfiRealTimeClockArchProtocolGuid, (VOID **)NULL, NULL, NULL, FALSE }\r
28a00297 43};\r
44\r
44cfd8a8 45//\r
46// Following is needed to display missing architectural protocols in debug builds\r
47//\r
48typedef struct {\r
49 EFI_GUID *ProtocolGuid;\r
50 CHAR8 *GuidString;\r
51} GUID_TO_STRING_PROTOCOL_ENTRY;\r
28a00297 52\r
44cfd8a8 53GLOBAL_REMOVE_IF_UNREFERENCED CONST GUID_TO_STRING_PROTOCOL_ENTRY MissingProtocols[] = {\r
54 { &gEfiSecurityArchProtocolGuid, "Security" },\r
55 { &gEfiCpuArchProtocolGuid, "CPU" },\r
56 { &gEfiMetronomeArchProtocolGuid, "Metronome" },\r
57 { &gEfiTimerArchProtocolGuid, "Timer" },\r
58 { &gEfiBdsArchProtocolGuid, "Bds" },\r
59 { &gEfiWatchdogTimerArchProtocolGuid, "Watchdog Timer" },\r
60 { &gEfiRuntimeArchProtocolGuid, "Runtime" },\r
61 { &gEfiVariableArchProtocolGuid, "Variable" },\r
62 { &gEfiVariableWriteArchProtocolGuid, "Variable Write" },\r
63 { &gEfiCapsuleArchProtocolGuid, "Capsule" },\r
64 { &gEfiMonotonicCounterArchProtocolGuid, "Monotonic Counter" },\r
65 { &gEfiResetArchProtocolGuid, "Reset" },\r
66 { &gEfiRealTimeClockArchProtocolGuid, "Real Time Clock" }\r
67};\r
28a00297 68\r
162ed594 69/**\r
28a00297 70 Return TRUE if all AP services are availible.\r
71\r
022c6d45 72 @retval EFI_SUCCESS All AP services are available\r
162ed594 73 @retval EFI_NOT_FOUND At least one AP service is not available\r
28a00297 74\r
162ed594 75**/\r
76EFI_STATUS\r
77CoreAllEfiServicesAvailable (\r
78 VOID\r
79 )\r
28a00297 80{\r
3f143578 81 UINTN Index;\r
28a00297 82\r
3f143578 83 for (Index = 0; Index < sizeof (mArchProtocols) / sizeof (mArchProtocols[0]); Index++) {\r
84 if (!mArchProtocols[Index].Present) {\r
28a00297 85 return EFI_NOT_FOUND;\r
86 }\r
87 }\r
88\r
89 return EFI_SUCCESS;\r
90}\r
91\r
28a00297 92\r
162ed594 93/**\r
28a00297 94 Notification event handler registered by CoreNotifyOnArchProtocolInstallation ().\r
95 This notify function is registered for every architectural protocol. This handler\r
96 updates mArchProtocol[] array entry with protocol instance data and sets it's\r
97 present flag to TRUE. If any constructor is required it is executed. The EFI\r
98 System Table headers are updated.\r
99\r
022c6d45 100 @param Event The Event that is being processed, not used.\r
162ed594 101 @param Context Event Context, not used.\r
28a00297 102\r
162ed594 103**/\r
162ed594 104VOID\r
105EFIAPI\r
106GenericArchProtocolNotify (\r
107 IN EFI_EVENT Event,\r
108 IN VOID *Context\r
109 )\r
28a00297 110{\r
111 EFI_STATUS Status;\r
112 ARCHITECTURAL_PROTOCOL_ENTRY *Entry;\r
113 VOID *Protocol;\r
114 BOOLEAN Found;\r
115 LIST_ENTRY *Link;\r
116 LIST_ENTRY TempLinkNode;\r
3f143578 117 UINTN Index;\r
28a00297 118\r
119 Found = FALSE;\r
3f143578 120 for (Index = 0; Index < sizeof (mArchProtocols) / sizeof (mArchProtocols[0]); Index++) {\r
121 Entry = &mArchProtocols[Index];\r
28a00297 122\r
123 Status = CoreLocateProtocol (Entry->ProtocolGuid, Entry->Registration, &Protocol);\r
124 if (EFI_ERROR (Status)) {\r
125 continue;\r
126 }\r
127\r
128 Found = TRUE;\r
129 Entry->Present = TRUE;\r
130\r
131 //\r
132 // Update protocol global variable if one exists. Entry->Protocol points to a global variable\r
133 // if one exists in the DXE core for this Architectural Protocol\r
134 //\r
135 if (Entry->Protocol != NULL) {\r
136 *(Entry->Protocol) = Protocol;\r
137 }\r
138\r
139 if (CompareGuid (Entry->ProtocolGuid, &gEfiTimerArchProtocolGuid)) {\r
140 //\r
141 // Register the Core timer tick handler with the Timer AP\r
142 //\r
143 gTimer->RegisterHandler (gTimer, CoreTimerTick);\r
144 }\r
145\r
146 if (CompareGuid (Entry->ProtocolGuid, &gEfiRuntimeArchProtocolGuid)) {\r
147 //\r
148 // When runtime architectural protocol is available, updates CRC32 in the Debug Table\r
149 //\r
150 CoreUpdateDebugTableCrc32 ();\r
151\r
152 //\r
153 // Update the Runtime Architectural protocol with the template that the core was\r
154 // using so there would not need to be a dependency on the Runtime AP\r
155 //\r
156\r
157 //\r
158 // Copy all the registered Image to new gRuntime protocol\r
159 //\r
160 for (Link = gRuntimeTemplate.ImageHead.ForwardLink; Link != &gRuntimeTemplate.ImageHead; Link = TempLinkNode.ForwardLink) {\r
161 CopyMem (&TempLinkNode, Link, sizeof(LIST_ENTRY));\r
162 InsertTailList (&gRuntime->ImageHead, Link);\r
163 }\r
164 //\r
165 // Copy all the registered Event to new gRuntime protocol\r
166 //\r
167 for (Link = gRuntimeTemplate.EventHead.ForwardLink; Link != &gRuntimeTemplate.EventHead; Link = TempLinkNode.ForwardLink) {\r
168 CopyMem (&TempLinkNode, Link, sizeof(LIST_ENTRY));\r
169 InsertTailList (&gRuntime->EventHead, Link);\r
170 }\r
171\r
172 //\r
173 // Clean up gRuntimeTemplate\r
174 //\r
175 gRuntimeTemplate.ImageHead.ForwardLink = &gRuntimeTemplate.ImageHead;\r
176 gRuntimeTemplate.ImageHead.BackLink = &gRuntimeTemplate.ImageHead;\r
177 gRuntimeTemplate.EventHead.ForwardLink = &gRuntimeTemplate.EventHead;\r
178 gRuntimeTemplate.EventHead.BackLink = &gRuntimeTemplate.EventHead;\r
179 }\r
180 }\r
181\r
182 //\r
183 // It's over kill to do them all every time, but it saves a lot of code.\r
184 //\r
185 if (Found) {\r
186 CalculateEfiHdrCrc (&gDxeCoreRT->Hdr);\r
0e9b156d 187 CalculateEfiHdrCrc (&gBS->Hdr);\r
28a00297 188 CalculateEfiHdrCrc (&gDxeCoreST->Hdr);\r
189 CalculateEfiHdrCrc (&gDxeCoreDS->Hdr);\r
190 }\r
191}\r
192\r
193\r
194\r
162ed594 195/**\r
196 Creates an event that is fired everytime a Protocol of a specific type is installed.\r
197\r
198**/\r
28a00297 199VOID\r
200CoreNotifyOnArchProtocolInstallation (\r
201 VOID\r
202 )\r
28a00297 203{\r
204 EFI_STATUS Status;\r
205 ARCHITECTURAL_PROTOCOL_ENTRY *Entry;\r
3f143578 206 UINTN Index;\r
28a00297 207\r
3f143578 208 for (Index = 0; Index < sizeof (mArchProtocols) / sizeof (mArchProtocols[0]); Index++) {\r
209 Entry = &mArchProtocols[Index];\r
28a00297 210\r
211 //\r
212 // Create the event\r
213 //\r
214 Status = CoreCreateEvent (\r
215 EVT_NOTIFY_SIGNAL,\r
216 TPL_CALLBACK,\r
217 GenericArchProtocolNotify,\r
218 NULL,\r
219 &Entry->Event\r
220 );\r
221 ASSERT_EFI_ERROR(Status);\r
222\r
223 //\r
224 // Register for protocol notifactions on this event\r
225 //\r
226 Status = CoreRegisterProtocolNotify (\r
227 Entry->ProtocolGuid,\r
228 Entry->Event,\r
229 &Entry->Registration\r
230 );\r
231 ASSERT_EFI_ERROR(Status);\r
232\r
233 }\r
234}\r
235\r
162ed594 236\r
237/**\r
238 Displays Architectural protocols that were not loaded and are required for DXE\r
239 core to function. Only used in Debug Builds.\r
240\r
241**/\r
28a00297 242VOID\r
243CoreDisplayMissingArchProtocols (\r
244 VOID\r
245 )\r
28a00297 246{\r
e94a9ff7 247 CONST GUID_TO_STRING_PROTOCOL_ENTRY *MissingEntry;\r
28a00297 248 ARCHITECTURAL_PROTOCOL_ENTRY *Entry;\r
3f143578 249 UINTN Index;\r
28a00297 250\r
3f143578 251 for (Index = 0; Index < sizeof (mArchProtocols) / sizeof (mArchProtocols[0]); Index++) {\r
252 Entry = &mArchProtocols[Index];\r
28a00297 253 if (!Entry->Present) {\r
28a00297 254 for (MissingEntry = MissingProtocols; TRUE ; MissingEntry++) {\r
255 if (CompareGuid (Entry->ProtocolGuid, MissingEntry->ProtocolGuid)) {\r
4fdc9129 256 DEBUG ((DEBUG_ERROR, "\n%a Arch Protocol not present!!\n", MissingEntry->GuidString));\r
28a00297 257 break;\r
258 }\r
259 }\r
260 }\r
261 }\r
262}\r