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