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