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