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