]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Core/Pei/Ppi/Ppi.c
Patch from open source community for CryptoPkg to allow it to build for ARM using...
[mirror_edk2.git] / MdeModulePkg / Core / Pei / Ppi / Ppi.c
CommitLineData
615c6dd0 1/** @file\r
b1f6a7c6 2 EFI PEI Core PPI services\r
3 \r
cd5ebaa0
HT
4Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
5This program and the accompanying materials\r
58dcdada 6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
192f6d4c 12\r
b1f6a7c6 13**/\r
192f6d4c 14\r
0d516397 15#include "PeiMain.h"\r
192f6d4c 16\r
b1f6a7c6 17/**\r
192f6d4c 18\r
b1f6a7c6 19 Initialize PPI services.\r
192f6d4c 20\r
b1f6a7c6 21 @param PrivateData Pointer to the PEI Core data.\r
22 @param OldCoreData Pointer to old PEI Core data. \r
23 NULL if being run in non-permament memory mode.\r
192f6d4c 24\r
b1f6a7c6 25**/\r
192f6d4c 26VOID\r
27InitializePpiServices (\r
b0d803fe 28 IN PEI_CORE_INSTANCE *PrivateData,\r
192f6d4c 29 IN PEI_CORE_INSTANCE *OldCoreData\r
30 )\r
192f6d4c 31{\r
192f6d4c 32 if (OldCoreData == NULL) {\r
4140a663 33 PrivateData->PpiData.NotifyListEnd = FixedPcdGet32 (PcdPeiCoreMaxPpiSupported)-1;\r
34 PrivateData->PpiData.DispatchListEnd = FixedPcdGet32 (PcdPeiCoreMaxPpiSupported)-1;\r
35 PrivateData->PpiData.LastDispatchedNotify = FixedPcdGet32 (PcdPeiCoreMaxPpiSupported)-1;\r
192f6d4c 36 }\r
192f6d4c 37}\r
38\r
b1f6a7c6 39/**\r
40\r
3d4d0c34 41 Migrate the Hob list from the temporary memory stack to PEI installed memory.\r
b1f6a7c6 42\r
0f65cdaa 43 @param PrivateData Pointer to PeiCore's private data structure.\r
731bd38e 44 @param OldCheckingBottom Bottom of temporary memory range. All Ppi in this range\r
45 will be fixup for PpiData and PpiDescriptor pointer.\r
46 @param OldCheckingTop Top of temporary memory range. All Ppi in this range\r
47 will be fixup for PpiData and PpiDescriptor.\r
5c5a0601 48 @param Fixup The address difference between\r
49 the new Hob list and old Hob list.\r
ef05e063 50 @param FixupPositive TRUE if new Hob list is above the old Hob list. \r
51 Otherwise FALSE.\r
b1f6a7c6 52\r
53**/\r
192f6d4c 54VOID\r
55ConvertPpiPointers (\r
40f26b8f 56 IN PEI_CORE_INSTANCE *PrivateData,\r
57 IN UINTN OldCheckingBottom,\r
58 IN UINTN OldCheckingTop,\r
ef05e063 59 IN UINTN Fixup,\r
60 IN BOOLEAN FixupPositive\r
192f6d4c 61 )\r
192f6d4c 62{\r
192f6d4c 63 UINT8 Index;\r
64 PEI_PPI_LIST_POINTERS *PpiPointer;\r
192f6d4c 65\r
4140a663 66 for (Index = 0; Index < FixedPcdGet32 (PcdPeiCoreMaxPpiSupported); Index++) {\r
192f6d4c 67 if (Index < PrivateData->PpiData.PpiListEnd ||\r
68 Index > PrivateData->PpiData.NotifyListEnd) {\r
69 PpiPointer = &PrivateData->PpiData.PpiListPtrs[Index];\r
58dcdada 70\r
71 if (((UINTN)PpiPointer->Raw < OldCheckingTop) &&\r
72 ((UINTN)PpiPointer->Raw >= OldCheckingBottom)) {\r
192f6d4c 73 //\r
74 // Convert the pointer to the PEIM descriptor from the old HOB heap\r
75 // to the relocated HOB heap.\r
76 //\r
ef05e063 77 if (FixupPositive) {\r
78 PpiPointer->Raw = (VOID *) ((UINTN)PpiPointer->Raw + Fixup);\r
79 } else {\r
80 PpiPointer->Raw = (VOID *) ((UINTN)PpiPointer->Raw - Fixup);\r
81 }\r
192f6d4c 82\r
83 //\r
84 // Only when the PEIM descriptor is in the old HOB should it be necessary\r
85 // to try to convert the pointers in the PEIM descriptor\r
86 //\r
58dcdada 87\r
88 if (((UINTN)PpiPointer->Ppi->Guid < OldCheckingTop) &&\r
89 ((UINTN)PpiPointer->Ppi->Guid >= OldCheckingBottom)) {\r
192f6d4c 90 //\r
91 // Convert the pointer to the GUID in the PPI or NOTIFY descriptor\r
92 // from the old HOB heap to the relocated HOB heap.\r
93 //\r
ef05e063 94 if (FixupPositive) {\r
95 PpiPointer->Ppi->Guid = (VOID *) ((UINTN)PpiPointer->Ppi->Guid + Fixup);\r
96 } else {\r
97 PpiPointer->Ppi->Guid = (VOID *) ((UINTN)PpiPointer->Ppi->Guid - Fixup);\r
98 }\r
192f6d4c 99 }\r
100\r
101 //\r
102 // Assume that no code is located in the temporary memory, so the pointer to\r
103 // the notification function in the NOTIFY descriptor needs not be converted.\r
104 //\r
105 if (Index < PrivateData->PpiData.PpiListEnd &&\r
58dcdada 106 (UINTN)PpiPointer->Ppi->Ppi < OldCheckingTop &&\r
107 (UINTN)PpiPointer->Ppi->Ppi >= OldCheckingBottom) {\r
192f6d4c 108 //\r
109 // Convert the pointer to the PPI interface structure in the PPI descriptor\r
110 // from the old HOB heap to the relocated HOB heap.\r
111 //\r
ef05e063 112 if (FixupPositive) {\r
113 PpiPointer->Ppi->Ppi = (VOID *) ((UINTN)PpiPointer->Ppi->Ppi + Fixup);\r
114 } else {\r
115 PpiPointer->Ppi->Ppi = (VOID *) ((UINTN)PpiPointer->Ppi->Ppi - Fixup);\r
116 }\r
192f6d4c 117 }\r
118 }\r
119 }\r
120 }\r
121}\r
122\r
b1f6a7c6 123/**\r
192f6d4c 124\r
0f65cdaa 125 This function installs an interface in the PEI PPI database by GUID. \r
126 The purpose of the service is to publish an interface that other parties\r
127 can use to call additional PEIMs.\r
192f6d4c 128\r
0f65cdaa 129 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r
130 @param PpiList Pointer to a list of PEI PPI Descriptors.\r
b1f6a7c6 131\r
0f65cdaa 132 @retval EFI_SUCCESS if all PPIs in PpiList are successfully installed.\r
133 @retval EFI_INVALID_PARAMETER if PpiList is NULL pointer\r
731bd38e 134 if any PPI in PpiList is not valid\r
0f65cdaa 135 @retval EFI_OUT_OF_RESOURCES if there is no more memory resource to install PPI\r
b1f6a7c6 136\r
137**/\r
192f6d4c 138EFI_STATUS\r
139EFIAPI\r
140PeiInstallPpi (\r
0c2b5da8 141 IN CONST EFI_PEI_SERVICES **PeiServices,\r
142 IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList\r
192f6d4c 143 )\r
192f6d4c 144{\r
145 PEI_CORE_INSTANCE *PrivateData;\r
146 INTN Index;\r
147 INTN LastCallbackInstall;\r
148\r
149\r
150 if (PpiList == NULL) {\r
151 return EFI_INVALID_PARAMETER;\r
152 }\r
153\r
154 PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);\r
155\r
156 Index = PrivateData->PpiData.PpiListEnd;\r
157 LastCallbackInstall = Index;\r
158\r
159 //\r
160 // This is loop installs all PPI descriptors in the PpiList. It is terminated\r
161 // by the EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST being set in the last\r
162 // EFI_PEI_PPI_DESCRIPTOR in the list.\r
163 //\r
58dcdada 164\r
192f6d4c 165 for (;;) {\r
166 //\r
731bd38e 167 // Since PpiData is used for NotifyList and PpiList, max resource\r
192f6d4c 168 // is reached if the Install reaches the NotifyList\r
97b2c9b5 169 // PcdPeiCoreMaxPpiSupported can be set to a larger value in DSC to satisfy more PPI requirement.\r
192f6d4c 170 //\r
171 if (Index == PrivateData->PpiData.NotifyListEnd + 1) {\r
172 return EFI_OUT_OF_RESOURCES;\r
173 }\r
174 //\r
58dcdada 175 // Check if it is a valid PPI.\r
192f6d4c 176 // If not, rollback list to exclude all in this list.\r
177 // Try to indicate which item failed.\r
178 //\r
179 if ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_PPI) == 0) {\r
180 PrivateData->PpiData.PpiListEnd = LastCallbackInstall;\r
0e549d5b 181 DEBUG((EFI_D_ERROR, "ERROR -> InstallPpi: %g %p\n", PpiList->Guid, PpiList->Ppi));\r
192f6d4c 182 return EFI_INVALID_PARAMETER;\r
183 }\r
184\r
58dcdada 185 DEBUG((EFI_D_INFO, "Install PPI: %g\n", PpiList->Guid));\r
186 PrivateData->PpiData.PpiListPtrs[Index].Ppi = (EFI_PEI_PPI_DESCRIPTOR*) PpiList;\r
192f6d4c 187 PrivateData->PpiData.PpiListEnd++;\r
58dcdada 188\r
192f6d4c 189 //\r
190 // Continue until the end of the PPI List.\r
191 //\r
58dcdada 192 if ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) ==\r
192f6d4c 193 EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) {\r
194 break;\r
195 }\r
196 PpiList++;\r
197 Index++;\r
198 }\r
199\r
200 //\r
201 // Dispatch any callback level notifies for newly installed PPIs.\r
202 //\r
203 DispatchNotify (\r
b0d803fe 204 PrivateData,\r
192f6d4c 205 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,\r
206 LastCallbackInstall,\r
207 PrivateData->PpiData.PpiListEnd,\r
58dcdada 208 PrivateData->PpiData.DispatchListEnd,\r
192f6d4c 209 PrivateData->PpiData.NotifyListEnd\r
210 );\r
211\r
212\r
213 return EFI_SUCCESS;\r
214}\r
215\r
b1f6a7c6 216/**\r
217\r
0f65cdaa 218 This function reinstalls an interface in the PEI PPI database by GUID. \r
219 The purpose of the service is to publish an interface that other parties can \r
220 use to replace an interface of the same name in the protocol database with a \r
221 different interface.\r
b1f6a7c6 222\r
0f65cdaa 223 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r
224 @param OldPpi Pointer to the old PEI PPI Descriptors.\r
225 @param NewPpi Pointer to the new PEI PPI Descriptors.\r
192f6d4c 226\r
0f65cdaa 227 @retval EFI_SUCCESS if the operation was successful\r
228 @retval EFI_INVALID_PARAMETER if OldPpi or NewPpi is NULL\r
229 @retval EFI_INVALID_PARAMETER if NewPpi is not valid\r
230 @retval EFI_NOT_FOUND if the PPI was not in the database\r
b1f6a7c6 231\r
232**/\r
192f6d4c 233EFI_STATUS\r
234EFIAPI\r
235PeiReInstallPpi (\r
0c2b5da8 236 IN CONST EFI_PEI_SERVICES **PeiServices,\r
237 IN CONST EFI_PEI_PPI_DESCRIPTOR *OldPpi,\r
238 IN CONST EFI_PEI_PPI_DESCRIPTOR *NewPpi\r
192f6d4c 239 )\r
192f6d4c 240{\r
241 PEI_CORE_INSTANCE *PrivateData;\r
242 INTN Index;\r
243\r
244\r
245 if ((OldPpi == NULL) || (NewPpi == NULL)) {\r
246 return EFI_INVALID_PARAMETER;\r
247 }\r
248\r
249 if ((NewPpi->Flags & EFI_PEI_PPI_DESCRIPTOR_PPI) == 0) {\r
250 return EFI_INVALID_PARAMETER;\r
251 }\r
252\r
253 PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);\r
254\r
255 //\r
256 // Find the old PPI instance in the database. If we can not find it,\r
257 // return the EFI_NOT_FOUND error.\r
258 //\r
259 for (Index = 0; Index < PrivateData->PpiData.PpiListEnd; Index++) {\r
260 if (OldPpi == PrivateData->PpiData.PpiListPtrs[Index].Ppi) {\r
261 break;\r
262 }\r
263 }\r
264 if (Index == PrivateData->PpiData.PpiListEnd) {\r
265 return EFI_NOT_FOUND;\r
266 }\r
267\r
268 //\r
269 // Remove the old PPI from the database, add the new one.\r
58dcdada 270 //\r
192f6d4c 271 DEBUG((EFI_D_INFO, "Reinstall PPI: %g\n", NewPpi->Guid));\r
4140a663 272 ASSERT (Index < (INTN)(FixedPcdGet32 (PcdPeiCoreMaxPpiSupported)));\r
0c2b5da8 273 PrivateData->PpiData.PpiListPtrs[Index].Ppi = (EFI_PEI_PPI_DESCRIPTOR *) NewPpi;\r
192f6d4c 274\r
275 //\r
276 // Dispatch any callback level notifies for the newly installed PPI.\r
277 //\r
278 DispatchNotify (\r
b0d803fe 279 PrivateData,\r
192f6d4c 280 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,\r
281 Index,\r
282 Index+1,\r
58dcdada 283 PrivateData->PpiData.DispatchListEnd,\r
192f6d4c 284 PrivateData->PpiData.NotifyListEnd\r
285 );\r
286\r
287\r
288 return EFI_SUCCESS;\r
289}\r
290\r
b1f6a7c6 291/**\r
292\r
293 Locate a given named PPI.\r
294\r
192f6d4c 295\r
0f65cdaa 296 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r
297 @param Guid Pointer to GUID of the PPI.\r
298 @param Instance Instance Number to discover.\r
299 @param PpiDescriptor Pointer to reference the found descriptor. If not NULL,\r
300 returns a pointer to the descriptor (includes flags, etc)\r
301 @param Ppi Pointer to reference the found PPI\r
b1f6a7c6 302\r
303 @retval EFI_SUCCESS if the PPI is in the database\r
304 @retval EFI_NOT_FOUND if the PPI is not in the database\r
305\r
306**/\r
192f6d4c 307EFI_STATUS\r
308EFIAPI\r
309PeiLocatePpi (\r
0c2b5da8 310 IN CONST EFI_PEI_SERVICES **PeiServices,\r
311 IN CONST EFI_GUID *Guid,\r
0f65cdaa 312 IN UINTN Instance,\r
313 IN OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor,\r
314 IN OUT VOID **Ppi\r
192f6d4c 315 )\r
192f6d4c 316{\r
317 PEI_CORE_INSTANCE *PrivateData;\r
318 INTN Index;\r
319 EFI_GUID *CheckGuid;\r
320 EFI_PEI_PPI_DESCRIPTOR *TempPtr;\r
321\r
58dcdada 322\r
192f6d4c 323 PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);\r
324\r
325 //\r
326 // Search the data base for the matching instance of the GUIDed PPI.\r
327 //\r
328 for (Index = 0; Index < PrivateData->PpiData.PpiListEnd; Index++) {\r
329 TempPtr = PrivateData->PpiData.PpiListPtrs[Index].Ppi;\r
330 CheckGuid = TempPtr->Guid;\r
331\r
332 //\r
333 // Don't use CompareGuid function here for performance reasons.\r
334 // Instead we compare the GUID as INT32 at a time and branch\r
335 // on the first failed comparison.\r
336 //\r
337 if ((((INT32 *)Guid)[0] == ((INT32 *)CheckGuid)[0]) &&\r
338 (((INT32 *)Guid)[1] == ((INT32 *)CheckGuid)[1]) &&\r
339 (((INT32 *)Guid)[2] == ((INT32 *)CheckGuid)[2]) &&\r
340 (((INT32 *)Guid)[3] == ((INT32 *)CheckGuid)[3])) {\r
341 if (Instance == 0) {\r
342\r
343 if (PpiDescriptor != NULL) {\r
344 *PpiDescriptor = TempPtr;\r
345 }\r
346\r
347 if (Ppi != NULL) {\r
348 *Ppi = TempPtr->Ppi;\r
349 }\r
350\r
351\r
352 return EFI_SUCCESS;\r
353 }\r
354 Instance--;\r
355 }\r
356 }\r
357\r
358 return EFI_NOT_FOUND;\r
359}\r
360\r
b1f6a7c6 361/**\r
192f6d4c 362\r
0f65cdaa 363 This function installs a notification service to be called back when a given \r
364 interface is installed or reinstalled. The purpose of the service is to publish \r
365 an interface that other parties can use to call additional PPIs that may materialize later.\r
b1f6a7c6 366\r
0f65cdaa 367 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r
368 @param NotifyList Pointer to list of Descriptors to notify upon.\r
b1f6a7c6 369\r
370 @retval EFI_SUCCESS if successful\r
371 @retval EFI_OUT_OF_RESOURCES if no space in the database\r
372 @retval EFI_INVALID_PARAMETER if not a good decriptor\r
373\r
374**/\r
192f6d4c 375EFI_STATUS\r
376EFIAPI\r
377PeiNotifyPpi (\r
0c2b5da8 378 IN CONST EFI_PEI_SERVICES **PeiServices,\r
379 IN CONST EFI_PEI_NOTIFY_DESCRIPTOR *NotifyList\r
192f6d4c 380 )\r
192f6d4c 381{\r
382 PEI_CORE_INSTANCE *PrivateData;\r
383 INTN Index;\r
384 INTN NotifyIndex;\r
385 INTN LastCallbackNotify;\r
386 EFI_PEI_NOTIFY_DESCRIPTOR *NotifyPtr;\r
387 UINTN NotifyDispatchCount;\r
388\r
389\r
390 NotifyDispatchCount = 0;\r
391\r
392 if (NotifyList == NULL) {\r
393 return EFI_INVALID_PARAMETER;\r
394 }\r
395\r
396 PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);\r
397\r
398 Index = PrivateData->PpiData.NotifyListEnd;\r
399 LastCallbackNotify = Index;\r
400\r
401 //\r
402 // This is loop installs all Notify descriptors in the NotifyList. It is\r
403 // terminated by the EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST being set in the last\r
404 // EFI_PEI_NOTIFY_DESCRIPTOR in the list.\r
405 //\r
406\r
407 for (;;) {\r
408 //\r
409 // Since PpiData is used for NotifyList and InstallList, max resource\r
410 // is reached if the Install reaches the PpiList\r
97b2c9b5 411 // PcdPeiCoreMaxPpiSupported can be set to a larger value in DSC to satisfy more Notify PPIs requirement.\r
192f6d4c 412 //\r
413 if (Index == PrivateData->PpiData.PpiListEnd - 1) {\r
414 return EFI_OUT_OF_RESOURCES;\r
415 }\r
58dcdada 416\r
192f6d4c 417 //\r
418 // If some of the PPI data is invalid restore original Notify PPI database value\r
419 //\r
420 if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_TYPES) == 0) {\r
421 PrivateData->PpiData.NotifyListEnd = LastCallbackNotify;\r
0e549d5b 422 DEBUG((EFI_D_ERROR, "ERROR -> InstallNotify: %g %p\n", NotifyList->Guid, NotifyList->Notify));\r
192f6d4c 423 return EFI_INVALID_PARAMETER;\r
424 }\r
58dcdada 425\r
192f6d4c 426 if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH) != 0) {\r
58dcdada 427 NotifyDispatchCount ++;\r
428 }\r
429\r
430 PrivateData->PpiData.PpiListPtrs[Index].Notify = (EFI_PEI_NOTIFY_DESCRIPTOR *) NotifyList;\r
431\r
192f6d4c 432 PrivateData->PpiData.NotifyListEnd--;\r
433 DEBUG((EFI_D_INFO, "Register PPI Notify: %g\n", NotifyList->Guid));\r
434 if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) ==\r
435 EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) {\r
436 break;\r
437 }\r
438 //\r
439 // Go the next descriptor. Remember the NotifyList moves down.\r
440 //\r
441 NotifyList++;\r
442 Index--;\r
443 }\r
58dcdada 444\r
192f6d4c 445 //\r
58dcdada 446 // If there is Dispatch Notify PPI installed put them on the bottom\r
192f6d4c 447 //\r
448 if (NotifyDispatchCount > 0) {\r
58dcdada 449 for (NotifyIndex = LastCallbackNotify; NotifyIndex > PrivateData->PpiData.NotifyListEnd; NotifyIndex--) {\r
192f6d4c 450 if ((PrivateData->PpiData.PpiListPtrs[NotifyIndex].Notify->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH) != 0) {\r
451 NotifyPtr = PrivateData->PpiData.PpiListPtrs[NotifyIndex].Notify;\r
58dcdada 452\r
192f6d4c 453 for (Index = NotifyIndex; Index < PrivateData->PpiData.DispatchListEnd; Index++){\r
454 PrivateData->PpiData.PpiListPtrs[Index].Notify = PrivateData->PpiData.PpiListPtrs[Index + 1].Notify;\r
455 }\r
456 PrivateData->PpiData.PpiListPtrs[Index].Notify = NotifyPtr;\r
58dcdada 457 PrivateData->PpiData.DispatchListEnd--;\r
192f6d4c 458 }\r
459 }\r
58dcdada 460\r
461 LastCallbackNotify -= NotifyDispatchCount;\r
192f6d4c 462 }\r
58dcdada 463\r
192f6d4c 464 //\r
465 // Dispatch any callback level notifies for all previously installed PPIs.\r
466 //\r
467 DispatchNotify (\r
b0d803fe 468 PrivateData,\r
192f6d4c 469 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,\r
470 0,\r
471 PrivateData->PpiData.PpiListEnd,\r
472 LastCallbackNotify,\r
473 PrivateData->PpiData.NotifyListEnd\r
474 );\r
58dcdada 475\r
192f6d4c 476 return EFI_SUCCESS;\r
477}\r
478\r
479\r
b1f6a7c6 480/**\r
192f6d4c 481\r
482 Process the Notify List at dispatch level.\r
483\r
b1f6a7c6 484 @param PrivateData PeiCore's private data structure.\r
192f6d4c 485\r
b1f6a7c6 486**/\r
487VOID\r
488ProcessNotifyList (\r
489 IN PEI_CORE_INSTANCE *PrivateData\r
490 )\r
192f6d4c 491{\r
192f6d4c 492 INTN TempValue;\r
58dcdada 493\r
192f6d4c 494 while (TRUE) {\r
495 //\r
496 // Check if the PEIM that was just dispatched resulted in any\r
497 // Notifies getting installed. If so, go process any dispatch\r
498 // level Notifies that match the previouly installed PPIs.\r
58dcdada 499 // Use "while" instead of "if" since DispatchNotify can modify\r
192f6d4c 500 // DispatchListEnd (with NotifyPpi) so we have to iterate until the same.\r
501 //\r
502 while (PrivateData->PpiData.LastDispatchedNotify != PrivateData->PpiData.DispatchListEnd) {\r
503 TempValue = PrivateData->PpiData.DispatchListEnd;\r
504 DispatchNotify (\r
b0d803fe 505 PrivateData,\r
192f6d4c 506 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH,\r
507 0,\r
508 PrivateData->PpiData.LastDispatchedInstall,\r
509 PrivateData->PpiData.LastDispatchedNotify,\r
510 PrivateData->PpiData.DispatchListEnd\r
511 );\r
512 PrivateData->PpiData.LastDispatchedNotify = TempValue;\r
513 }\r
58dcdada 514\r
515\r
192f6d4c 516 //\r
517 // Check if the PEIM that was just dispatched resulted in any\r
518 // PPIs getting installed. If so, go process any dispatch\r
519 // level Notifies that match the installed PPIs.\r
58dcdada 520 // Use "while" instead of "if" since DispatchNotify can modify\r
192f6d4c 521 // PpiListEnd (with InstallPpi) so we have to iterate until the same.\r
522 //\r
523 while (PrivateData->PpiData.LastDispatchedInstall != PrivateData->PpiData.PpiListEnd) {\r
524 TempValue = PrivateData->PpiData.PpiListEnd;\r
525 DispatchNotify (\r
b0d803fe 526 PrivateData,\r
192f6d4c 527 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH,\r
528 PrivateData->PpiData.LastDispatchedInstall,\r
529 PrivateData->PpiData.PpiListEnd,\r
4140a663 530 FixedPcdGet32 (PcdPeiCoreMaxPpiSupported)-1,\r
192f6d4c 531 PrivateData->PpiData.DispatchListEnd\r
532 );\r
533 PrivateData->PpiData.LastDispatchedInstall = TempValue;\r
534 }\r
58dcdada 535\r
192f6d4c 536 if (PrivateData->PpiData.LastDispatchedNotify == PrivateData->PpiData.DispatchListEnd) {\r
537 break;\r
538 }\r
58dcdada 539 }\r
192f6d4c 540 return;\r
541}\r
542\r
b1f6a7c6 543/**\r
544\r
545 Dispatch notifications.\r
546\r
547 @param PrivateData PeiCore's private data structure\r
548 @param NotifyType Type of notify to fire.\r
549 @param InstallStartIndex Install Beginning index.\r
550 @param InstallStopIndex Install Ending index.\r
551 @param NotifyStartIndex Notify Beginning index.\r
552 @param NotifyStopIndex Notify Ending index.\r
553\r
554**/\r
192f6d4c 555VOID\r
556DispatchNotify (\r
b0d803fe 557 IN PEI_CORE_INSTANCE *PrivateData,\r
192f6d4c 558 IN UINTN NotifyType,\r
559 IN INTN InstallStartIndex,\r
560 IN INTN InstallStopIndex,\r
561 IN INTN NotifyStartIndex,\r
562 IN INTN NotifyStopIndex\r
563 )\r
192f6d4c 564{\r
192f6d4c 565 INTN Index1;\r
566 INTN Index2;\r
567 EFI_GUID *SearchGuid;\r
568 EFI_GUID *CheckGuid;\r
569 EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor;\r
570\r
192f6d4c 571 //\r
572 // Remember that Installs moves up and Notifies moves down.\r
573 //\r
574 for (Index1 = NotifyStartIndex; Index1 > NotifyStopIndex; Index1--) {\r
575 NotifyDescriptor = PrivateData->PpiData.PpiListPtrs[Index1].Notify;\r
576\r
577 CheckGuid = NotifyDescriptor->Guid;\r
578\r
579 for (Index2 = InstallStartIndex; Index2 < InstallStopIndex; Index2++) {\r
580 SearchGuid = PrivateData->PpiData.PpiListPtrs[Index2].Ppi->Guid;\r
581 //\r
582 // Don't use CompareGuid function here for performance reasons.\r
583 // Instead we compare the GUID as INT32 at a time and branch\r
584 // on the first failed comparison.\r
585 //\r
586 if ((((INT32 *)SearchGuid)[0] == ((INT32 *)CheckGuid)[0]) &&\r
587 (((INT32 *)SearchGuid)[1] == ((INT32 *)CheckGuid)[1]) &&\r
588 (((INT32 *)SearchGuid)[2] == ((INT32 *)CheckGuid)[2]) &&\r
589 (((INT32 *)SearchGuid)[3] == ((INT32 *)CheckGuid)[3])) {\r
0e549d5b 590 DEBUG ((EFI_D_INFO, "Notify: PPI Guid: %g, Peim notify entry point: %p\n",\r
58dcdada 591 SearchGuid,\r
192f6d4c 592 NotifyDescriptor->Notify\r
593 ));\r
594 NotifyDescriptor->Notify (\r
284c8400 595 (EFI_PEI_SERVICES **) GetPeiServicesTablePointer (),\r
192f6d4c 596 NotifyDescriptor,\r
597 (PrivateData->PpiData.PpiListPtrs[Index2].Ppi)->Ppi\r
598 );\r
599 }\r
600 }\r
601 }\r
192f6d4c 602}\r
603\r