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