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