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