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