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