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