]> git.proxmox.com Git - mirror_edk2.git/blame - EdkModulePkg/Core/Dxe/DxeMain/DxeProtocolNotify.c
Initial import.
[mirror_edk2.git] / EdkModulePkg / Core / Dxe / DxeMain / DxeProtocolNotify.c
CommitLineData
878ddf1f 1/*++\r
2\r
3Copyright (c) 2006, Intel Corporation \r
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
11\r
12Module Name:\r
13\r
14 DxeProtocolNotify.c\r
15\r
16Abstract:\r
17\r
18 This file deals with Architecture Protocol (AP) registration in \r
19 the Dxe Core. The mArchProtocols[] array represents a list of \r
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
46 { &gEfiMonotonicCounterArchProtocolGuid, (VOID **)NULL, NULL, NULL, FALSE },\r
47 { &gEfiResetArchProtocolGuid, (VOID **)NULL, NULL, NULL, FALSE },\r
48// { &gEfiStatusCodeRuntimeProtocolGuid, (VOID **)&gStatusCode, NULL, NULL, FALSE },\r
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
68 EFI_NOT_FOUND - At least one AP service is not available \r
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
83\r
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
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
97 System Table headers are updated.\r
98\r
99Arguments:\r
100\r
101 Event - The Event that is being processed, not used.\r
102 \r
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
115 \r
116 Found = FALSE;\r
117 for (Entry = mArchProtocols; Entry->ProtocolGuid != NULL; Entry++) {\r
118 \r
119 Status = CoreLocateProtocol (Entry->ProtocolGuid, Entry->Registration, &Protocol);\r
120 if (EFI_ERROR (Status)) {\r
121 continue;\r
122 } \r
123 \r
124 Found = TRUE;\r
125 Entry->Present = TRUE;\r
126 \r
127 //\r
128 // Update protocol global variable if one exists. Entry->Protocol points to a global variable\r
129 // if one exists in the DXE core for this Architectural Protocol \r
130 //\r
131 if (Entry->Protocol != NULL) {\r
132 *(Entry->Protocol) = Protocol;\r
133 }\r
134\r
135 if (CompareGuid (Entry->ProtocolGuid, &gEfiTimerArchProtocolGuid)) {\r
136 //\r
137 // Register the Core timer tick handler with the Timer AP\r
138 //\r
139 gTimer->RegisterHandler (gTimer, CoreTimerTick);\r
140 }\r
141\r
142 if (CompareGuid (Entry->ProtocolGuid, &gEfiRuntimeArchProtocolGuid)) {\r
143 //\r
144 // When runtime architectural protocol is available, updates CRC32 in the Debug Table\r
145 //\r
146 CoreUpdateDebugTableCrc32 ();\r
147 }\r
148 }\r
149\r
150 //\r
151 // It's over kill to do them all every time, but it saves a lot of code.\r
152 //\r
153 if (Found) {\r
154 CalculateEfiHdrCrc (&gRT->Hdr);\r
155 CalculateEfiHdrCrc (&gBS->Hdr);\r
156 CalculateEfiHdrCrc (&gST->Hdr);\r
157 CalculateEfiHdrCrc (&gDS->Hdr);\r
158 }\r
159}\r
160\r
161\r
162\r
163VOID\r
164CoreNotifyOnArchProtocolInstallation (\r
165 VOID\r
166 )\r
167/*++\r
168\r
169Routine Description:\r
170 Creates an event that is fired everytime a Protocol of a specific type is installed\r
171\r
172Arguments:\r
173 NONE\r
174\r
175Returns:\r
176 NONE\r
177\r
178--*/\r
179{\r
180 EFI_STATUS Status;\r
181 ARCHITECTURAL_PROTOCOL_ENTRY *Entry;\r
182\r
183 for (Entry = mArchProtocols; Entry->ProtocolGuid != NULL; Entry++) {\r
184 \r
185 //\r
186 // Create the event\r
187 //\r
188 Status = CoreCreateEvent (\r
189 EFI_EVENT_NOTIFY_SIGNAL,\r
190 EFI_TPL_CALLBACK,\r
191 GenericArchProtocolNotify,\r
192 NULL,\r
193 &Entry->Event\r
194 );\r
195 ASSERT_EFI_ERROR(Status);\r
196\r
197 //\r
198 // Register for protocol notifactions on this event\r
199 //\r
200 Status = CoreRegisterProtocolNotify (\r
201 Entry->ProtocolGuid, \r
202 Entry->Event, \r
203 &Entry->Registration\r
204 );\r
205 ASSERT_EFI_ERROR(Status);\r
206\r
207 }\r
208}\r
209\r
210//\r
211// Following is needed to display missing architectural protocols in debug builds\r
212//\r
213typedef struct {\r
214 EFI_GUID *ProtocolGuid;\r
215 CHAR16 *GuidString;\r
216} GUID_TO_STRING_PROTOCOL_ENTRY;\r
217\r
218static const GUID_TO_STRING_PROTOCOL_ENTRY MissingProtocols[] = {\r
219 { &gEfiSecurityArchProtocolGuid, (CHAR16 *)L"Security" },\r
220 { &gEfiCpuArchProtocolGuid, (CHAR16 *)L"CPU" },\r
221 { &gEfiMetronomeArchProtocolGuid, (CHAR16 *)L"Metronome" },\r
222 { &gEfiTimerArchProtocolGuid, (CHAR16 *)L"Timer" },\r
223 { &gEfiBdsArchProtocolGuid, (CHAR16 *)L"Bds" },\r
224 { &gEfiWatchdogTimerArchProtocolGuid, (CHAR16 *)L"Watchdog Timer" },\r
225 { &gEfiRuntimeArchProtocolGuid, (CHAR16 *)L"Runtime" },\r
226 { &gEfiVariableArchProtocolGuid, (CHAR16 *)L"Variable" },\r
227 { &gEfiVariableWriteArchProtocolGuid, (CHAR16 *)L"Variable Write" },\r
228 { &gEfiMonotonicCounterArchProtocolGuid, (CHAR16 *)L"Monotonic Counter" },\r
229 { &gEfiResetArchProtocolGuid, (CHAR16 *)L"Reset" },\r
230// { &gEfiStatusCodeRuntimeProtocolGuid, (CHAR16 *)L"Status Code" },\r
231 { &gEfiRealTimeClockArchProtocolGuid, (CHAR16 *)L"Real Time Clock" }\r
232};\r
233\r
234VOID\r
235CoreDisplayMissingArchProtocols (\r
236 VOID\r
237 )\r
238/*++\r
239\r
240Routine Description:\r
241 Displays Architectural protocols that were not loaded and are required for DXE core to function\r
242 Only used in Debug Builds\r
243\r
244Arguments:\r
245 NONE\r
246\r
247Returns:\r
248 NONE\r
249\r
250--*/\r
251{\r
252 const GUID_TO_STRING_PROTOCOL_ENTRY *MissingEntry;\r
253 ARCHITECTURAL_PROTOCOL_ENTRY *Entry;\r
254\r
255 for (Entry = mArchProtocols; Entry->ProtocolGuid != NULL; Entry++) {\r
256 if (!Entry->Present) {\r
257 MissingEntry = MissingProtocols;\r
258 for (MissingEntry = MissingProtocols; TRUE ; MissingEntry++) {\r
259 if (CompareGuid (Entry->ProtocolGuid, MissingEntry->ProtocolGuid)) {\r
260 DEBUG ((EFI_D_ERROR, "\n%s Arch Protocol not present!!\n", MissingEntry->GuidString));\r
261 break;\r
262 }\r
263 }\r
264 }\r
265 } \r
266}\r