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