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