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