1 /*++ 2 3 Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR> 4 This program and the accompanying materials 5 are licensed and made available under the terms and conditions of the BSD License 6 which accompanies this distribution. The full text of the license may be found at 7 http://opensource.org/licenses/bsd-license.php 8 9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 11 12 Module Name: 13 14 PeiLib.c 15 16 Abstract: 17 18 PEI Library Functions 19 20 --*/ 21 22 #include "TianoCommon.h" 23 #include "PeiHob.h" 24 #include "Pei.h" 25 #include "PeiLib.h" 26 #include "EfiCommonLib.h" 27 28 VOID 29 PeiCopyMem ( 30 IN VOID *Destination, 31 IN VOID *Source, 32 IN UINTN Length 33 ); 34 35 VOID 36 ZeroMem ( 37 IN VOID *Buffer, 38 IN UINTN Size 39 ) 40 /*++ 41 42 Routine Description: 43 44 Set Buffer to zero for Size bytes. 45 46 Arguments: 47 48 Buffer - Memory to set. 49 50 Size - Number of bytes to set 51 52 Returns: 53 54 None 55 56 --*/ 57 { 58 EfiCommonLibZeroMem (Buffer, Size); 59 } 60 61 VOID 62 PeiCopyMem ( 63 IN VOID *Destination, 64 IN VOID *Source, 65 IN UINTN Length 66 ) 67 /*++ 68 69 Routine Description: 70 71 Copy Length bytes from Source to Destination. 72 73 Arguments: 74 75 Destination - Target of copy 76 77 Source - Place to copy from 78 79 Length - Number of bytes to copy 80 81 Returns: 82 83 None 84 85 --*/ 86 { 87 EfiCommonLibCopyMem (Destination, Source, Length); 88 } 89 90 VOID 91 CopyMem ( 92 IN VOID *Destination, 93 IN VOID *Source, 94 IN UINTN Length 95 ) 96 /*++ 97 98 Routine Description: 99 100 Copy Length bytes from Source to Destination. 101 102 Arguments: 103 104 Destination - Target of copy 105 106 Source - Place to copy from 107 108 Length - Number of bytes to copy 109 110 Returns: 111 112 None 113 114 --*/ 115 { 116 EfiCommonLibCopyMem (Destination, Source, Length); 117 } 118 119 120 BOOLEAN 121 CompareGuid ( 122 IN EFI_GUID *Guid1, 123 IN EFI_GUID *Guid2 124 ) 125 /*++ 126 127 Routine Description: 128 129 Compares two GUIDs 130 131 Arguments: 132 133 Guid1 - guid to compare 134 Guid2 - guid to compare 135 136 Returns: 137 = TRUE if Guid1 == Guid2 138 = FALSE if Guid1 != Guid2 139 140 --*/ 141 { 142 if ((((INT32 *) Guid1)[0] - ((INT32 *) Guid2)[0]) == 0) { 143 if ((((INT32 *) Guid1)[1] - ((INT32 *) Guid2)[1]) == 0) { 144 if ((((INT32 *) Guid1)[2] - ((INT32 *) Guid2)[2]) == 0) { 145 if ((((INT32 *) Guid1)[3] - ((INT32 *) Guid2)[3]) == 0) { 146 return TRUE; 147 } 148 } 149 } 150 } 151 152 return FALSE; 153 } 154 155 156 EFI_STATUS 157 EFIAPI 158 PeiLibPciCfgModify ( 159 IN EFI_PEI_SERVICES **PeiServices, 160 IN PEI_PCI_CFG_PPI *PciCfg, 161 IN PEI_PCI_CFG_PPI_WIDTH Width, 162 IN UINT64 Address, 163 IN UINTN SetBits, 164 IN UINTN ClearBits 165 ) 166 /*++ 167 168 Routine Description: 169 170 PCI read-modify-write operations. 171 172 PIWG's PI specification replaces Inte's EFI Specification 1.10. 173 EFI_PEI_PCI_CFG_PPI defined in Inte's EFI Specification 1.10 is replaced by 174 EFI_PEI_PCI_CFG2_PPI in PI 1.0. "Modify" function in these two PPI are not 175 compatibile with each other. 176 177 178 For Framework code that make the following call: 179 180 PciCfg->Modify ( 181 PeiServices, 182 PciCfg, 183 Width, 184 Address, 185 SetBits, 186 ClearBits 187 ); 188 it will be updated to the following code which call this library API: 189 PeiLibPciCfgModify ( 190 PeiServices, 191 PciCfg, 192 Width, 193 Address, 194 SetBits, 195 ClearBits 196 ); 197 198 The 199 200 Arguments: 201 202 PeiServices An indirect pointer to the PEI Services Table 203 published by the PEI Foundation. 204 PciCfg A pointer to the this pointer of EFI_PEI_PCI_CFG_PPI. 205 This parameter is unused as a place holder to make 206 the parameter list identical to PEI_PCI_CFG_PPI_RW. 207 Width The width of the access. Enumerated in bytes. Type 208 EFI_PEI_PCI_CFG_PPI_WIDTH is defined in Read(). 209 210 Address The physical address of the access. 211 212 SetBits Points to value to bitwise-OR with the read configuration value. 213 214 The size of the value is determined by Width. 215 216 ClearBits Points to the value to negate and bitwise-AND with the read configuration value. 217 The size of the value is determined by Width. 218 219 220 Returns: 221 222 EFI_SUCCESS The function completed successfully. 223 224 EFI_DEVICE_ERROR There was a problem with the transaction. 225 226 --*/ 227 { 228 EFI_STATUS Status; 229 EFI_PEI_PCI_CFG2_PPI *PciCfg2; 230 231 Status = (*PeiServices)->LocatePpi ( 232 PeiServices, 233 &gPeiPciCfg2PpiGuid, 234 0, 235 NULL, 236 (VOID **) &PciCfg2 237 ); 238 ASSERT_PEI_ERROR ((CONST EFI_PEI_SERVICES **) PeiServices, Status); 239 240 Status = PciCfg2->Modify ( 241 (CONST EFI_PEI_SERVICES **) PeiServices, 242 PciCfg2, 243 (EFI_PEI_PCI_CFG_PPI_WIDTH) Width, 244 Address, 245 &SetBits, 246 &ClearBits 247 ); 248 249 return Status; 250 } 251 252 253 #if (PI_SPECIFICATION_VERSION >= 0x00010000) 254 255 VOID * 256 EFIAPI 257 ScanGuid ( 258 IN VOID *Buffer, 259 IN UINTN Length, 260 IN EFI_GUID *Guid 261 ) 262 /*++ 263 264 Routine Description: 265 266 Scans a target buffer for a GUID, and returns a pointer to the matching GUID 267 in the target buffer. 268 269 This function searches target the buffer specified by Buffer and Length from 270 the lowest address to the highest address at 128-bit increments for the 128-bit 271 GUID value that matches Guid. If a match is found, then a pointer to the matching 272 GUID in the target buffer is returned. If no match is found, then NULL is returned. 273 If Length is 0, then NULL is returned. 274 If Length > 0 and Buffer is NULL, then ASSERT(). 275 If Buffer is not aligned on a 32-bit boundary, then ASSERT(). 276 If Length is not aligned on a 128-bit boundary, then ASSERT(). 277 If Length is greater than (EFI_MAX_ADDRESS ?Buffer + 1), then ASSERT(). 278 279 Arguments: 280 281 Buffer - Pointer to the target buffer to scan. 282 Length - Number of bytes in Buffer to scan. 283 Guid - Value to search for in the target buffer. 284 285 Returns: 286 A pointer to the matching Guid in the target buffer or NULL otherwise. 287 288 --*/ 289 { 290 EFI_GUID *GuidPtr; 291 EFI_PEI_SERVICES **PeiServices; 292 293 PeiServices = GetPeiServicesTablePointer(); 294 PEI_ASSERT(PeiServices, (((UINTN)Buffer & (sizeof (Guid->Data1) - 1)) == 0)); 295 PEI_ASSERT(PeiServices, (Length <= (EFI_MAX_ADDRESS - (UINTN)Buffer + 1))); 296 PEI_ASSERT(PeiServices, ((Length & (sizeof (*GuidPtr) - 1)) == 0)); 297 298 GuidPtr = (EFI_GUID*)Buffer; 299 Buffer = GuidPtr + Length / sizeof (*GuidPtr); 300 while (GuidPtr < (EFI_GUID*)Buffer) { 301 if (CompareGuid (GuidPtr, Guid)) { 302 return (VOID*)GuidPtr; 303 } 304 GuidPtr++; 305 } 306 return NULL; 307 } 308 309 310 VOID * 311 EFIAPI 312 InvalidateInstructionCacheRange ( 313 IN VOID *Address, 314 IN UINTN Length 315 ) 316 /*++ 317 318 Routine Description: 319 320 Invalidates a range of instruction cache lines in the cache coherency domain 321 of the calling CPU. 322 323 Invalidates the instruction cache lines specified by Address and Length. If 324 Address is not aligned on a cache line boundary, then entire instruction 325 cache line containing Address is invalidated. If Address + Length is not 326 aligned on a cache line boundary, then the entire instruction cache line 327 containing Address + Length -1 is invalidated. This function may choose to 328 invalidate the entire instruction cache if that is more efficient than 329 invalidating the specified range. If Length is 0, the no instruction cache 330 lines are invalidated. Address is returned. 331 332 If Length is greater than (EFI_MAX_ADDRESS - Address + 1), then ASSERT(). 333 334 Arguments: 335 336 Address - The base address of the instruction cache lines to 337 invalidate. If the CPU is in a physical addressing mode, then 338 Address is a physical address. If the CPU is in a virtual 339 addressing mode, then Address is a virtual address. 340 341 Length - The number of bytes to invalidate from the instruction cache. 342 343 Returns: 344 Address 345 346 **/ 347 { 348 PEI_ASSERT(GetPeiServicesTablePointer() , (Length <= EFI_MAX_ADDRESS - (UINTN)Address + 1)); 349 return Address; 350 } 351 352 353 EFI_STATUS 354 EFIAPI 355 PeiLibFfsFindNextVolume ( 356 IN UINTN Instance, 357 IN OUT EFI_PEI_FV_HANDLE *VolumeHandle 358 ) 359 /*++ 360 361 Routine Description: 362 363 The wrapper of Pei Core Service function FfsFindNextVolume. 364 365 Arguments: 366 367 Instance - The Fv Volume Instance. 368 VolumeHandle - Pointer to the current Fv Volume to search. 369 370 Returns: 371 EFI_STATUS 372 373 --*/ 374 375 { 376 EFI_PEI_SERVICES **PeiServices; 377 378 PeiServices = GetPeiServicesTablePointer(); 379 return (*PeiServices)->FfsFindNextVolume (PeiServices, Instance, VolumeHandle); 380 } 381 382 EFI_STATUS 383 EFIAPI 384 PeiLibFfsFindNextFile ( 385 IN EFI_FV_FILETYPE SearchType, 386 IN EFI_PEI_FV_HANDLE FvHandle, 387 IN OUT EFI_PEI_FILE_HANDLE *FileHandle 388 ) 389 /*++ 390 391 Routine Description: 392 393 The wrapper of Pei Core Service function FfsFindNextFile. 394 395 Arguments: 396 397 SearchType - Filter to find only file of this type. 398 FvHandle - Pointer to the current FV to search. 399 FileHandle - Pointer to the file matching SearchType in FwVolHeader. 400 - NULL if file not found 401 402 Returns: 403 EFI_STATUS 404 405 --*/ 406 { 407 EFI_PEI_SERVICES **PeiServices; 408 409 PeiServices = GetPeiServicesTablePointer(); 410 return (*PeiServices)->FfsFindNextFile (PeiServices, SearchType, FvHandle, FileHandle); 411 } 412 413 414 EFI_STATUS 415 EFIAPI 416 PeiLibFfsFindFileByName ( 417 IN EFI_GUID *FileName, 418 IN EFI_PEI_FV_HANDLE VolumeHandle, 419 OUT EFI_PEI_FILE_HANDLE *FileHandle 420 ) 421 /*++ 422 423 Routine Description: 424 425 The wrapper of Pei Core Service function FfsFindFileByName. 426 427 Arguments: 428 429 FileName - File name to search. 430 VolumeHandle - The current FV to search. 431 FileHandle - Pointer to the file matching name in VolumeHandle. 432 - NULL if file not found 433 434 Returns: 435 EFI_STATUS 436 437 --*/ 438 { 439 EFI_PEI_SERVICES **PeiServices; 440 441 PeiServices = GetPeiServicesTablePointer(); 442 return (*PeiServices)->FfsFindFileByName (FileName, VolumeHandle, FileHandle); 443 } 444 445 446 447 EFI_STATUS 448 EFIAPI 449 PeiLibFfsFindSectionData ( 450 IN EFI_SECTION_TYPE SectionType, 451 IN EFI_FFS_FILE_HEADER *FfsFileHeader, 452 IN OUT VOID **SectionData 453 ) 454 /*++ 455 456 Routine Description: 457 458 The wrapper of Pei Core Service function FfsFindSectionData. 459 460 Arguments: 461 462 SearchType - Filter to find only sections of this type. 463 FileHandle - Pointer to the current file to search. 464 SectionData - Pointer to the Section matching SectionType in FfsFileHeader. 465 - NULL if section not found 466 467 Returns: 468 EFI_STATUS 469 --*/ 470 { 471 EFI_PEI_SERVICES **PeiServices; 472 473 PeiServices = GetPeiServicesTablePointer(); 474 return (*PeiServices)->FfsFindSectionData (PeiServices, SectionType, (EFI_PEI_FILE_HANDLE)FfsFileHeader, SectionData); 475 } 476 477 EFI_STATUS 478 EFIAPI 479 PeiLibFfsGetVolumeInfo ( 480 IN EFI_PEI_FV_HANDLE VolumeHandle, 481 OUT EFI_FV_INFO *VolumeInfo 482 ) 483 /*++ 484 485 Routine Description: 486 487 The wrapper of Pei Core Service function FfsGetVolumeInfo. 488 489 Arguments: 490 491 VolumeHandle - The handle to Fv Volume. 492 VolumeInfo - The pointer to volume information. 493 494 Returns: 495 EFI_STATUS 496 --*/ 497 { 498 EFI_PEI_SERVICES **PeiServices; 499 500 PeiServices = GetPeiServicesTablePointer(); 501 return (*PeiServices)->FfsGetVolumeInfo (VolumeHandle, VolumeInfo); 502 } 503 504 505 506 VOID 507 EFIAPI 508 BuildFvHob ( 509 IN EFI_PHYSICAL_ADDRESS BaseAddress, 510 IN UINT64 Length 511 ) 512 /*++ 513 514 Routine Description: 515 516 Build FvHob. 517 518 Arguments: 519 520 BaseAddress - Fv base address. 521 Length - Fv Length. 522 523 Returns: 524 NONE. 525 --*/ 526 { 527 528 EFI_STATUS Status; 529 EFI_HOB_FIRMWARE_VOLUME *Hob; 530 EFI_PEI_SERVICES **PeiServices; 531 532 PeiServices = GetPeiServicesTablePointer(); 533 534 // 535 // Check FV Signature 536 // 537 PEI_ASSERT (PeiServices, ((EFI_FIRMWARE_VOLUME_HEADER*)((UINTN)BaseAddress))->Signature == EFI_FVH_SIGNATURE); 538 539 540 Status = (*PeiServices)->CreateHob ( 541 PeiServices, 542 EFI_HOB_TYPE_FV, 543 sizeof (EFI_HOB_FIRMWARE_VOLUME), 544 &Hob 545 ); 546 Hob->BaseAddress = BaseAddress; 547 Hob->Length = Length; 548 } 549 550 VOID 551 EFIAPI 552 BuildFvHob2 ( 553 IN EFI_PHYSICAL_ADDRESS BaseAddress, 554 IN UINT64 Length, 555 IN EFI_GUID *FvNameGuid, 556 IN EFI_GUID *FileNameGuid 557 ) 558 /*++ 559 560 Routine Description: 561 562 Build FvHob2. 563 564 Arguments: 565 566 BaseAddress - Fv base address. 567 Length - Fv length. 568 FvNameGuid - Fv name. 569 FileNameGuid - File name which contians encapsulated Fv. 570 571 Returns: 572 NONE. 573 --*/ 574 { 575 576 EFI_STATUS Status; 577 EFI_HOB_FIRMWARE_VOLUME2 *Hob; 578 EFI_PEI_SERVICES **PeiServices; 579 580 PeiServices = GetPeiServicesTablePointer(); 581 582 // 583 // Check FV Signature 584 // 585 PEI_ASSERT (PeiServices, ((EFI_FIRMWARE_VOLUME_HEADER*)((UINTN)BaseAddress))->Signature == EFI_FVH_SIGNATURE); 586 587 Status = (*PeiServices)->CreateHob ( 588 PeiServices, 589 EFI_HOB_TYPE_FV2, 590 sizeof (EFI_HOB_FIRMWARE_VOLUME2), 591 &Hob 592 ); 593 Hob->BaseAddress = BaseAddress; 594 Hob->Length = Length; 595 CopyMem ((VOID*)&Hob->FvName, FvNameGuid, sizeof(EFI_GUID)); 596 CopyMem ((VOID*)&Hob->FileName, FileNameGuid, sizeof(EFI_GUID)); 597 } 598 599 EFI_STATUS 600 EFIAPI 601 PeiServicesLocatePpi ( 602 IN EFI_GUID *Guid, 603 IN UINTN Instance, 604 IN OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor, 605 IN OUT VOID **Ppi 606 ) 607 /*++ 608 609 Routine Description: 610 611 The wrapper of Pei Core Service function LocatePpi. 612 613 Arguments: 614 615 Guid - Pointer to GUID of the PPI. 616 Instance - Instance Number to discover. 617 PpiDescriptor - Pointer to reference the found descriptor. If not NULL, 618 returns a pointer to the descriptor (includes flags, etc) 619 Ppi - Pointer to reference the found PPI 620 621 Returns: 622 623 Status - EFI_SUCCESS if the PPI is in the database 624 EFI_NOT_FOUND if the PPI is not in the database 625 --*/ 626 { 627 EFI_PEI_SERVICES **PeiServices; 628 629 PeiServices = GetPeiServicesTablePointer(); 630 return (*PeiServices)->LocatePpi (PeiServices, Guid, Instance, PpiDescriptor, Ppi); 631 } 632 633 634 VOID 635 EFIAPI 636 BuildGuidDataHob ( 637 IN EFI_GUID *Guid, 638 IN VOID *Data, 639 IN UINTN DataLength 640 ) 641 /*++ 642 643 Routine Description: 644 645 Build Guid data Hob. 646 647 Arguments: 648 649 Guid - guid to build data hob. 650 Data - data to build data hob. 651 DataLength - the length of data. 652 653 Returns: 654 NONE 655 --*/ 656 { 657 VOID *HobData; 658 EFI_HOB_GUID_TYPE *Hob; 659 EFI_PEI_SERVICES **PeiServices; 660 661 PeiServices = GetPeiServicesTablePointer(); 662 (*PeiServices)->CreateHob ( 663 PeiServices, 664 EFI_HOB_TYPE_GUID_EXTENSION, 665 (UINT16) (sizeof (EFI_HOB_GUID_TYPE) + DataLength), 666 &Hob 667 ); 668 CopyMem ((VOID*)&Hob->Name, (VOID*)Guid, sizeof(EFI_GUID)); 669 670 HobData = Hob + 1; 671 672 CopyMem (HobData, Data, DataLength); 673 } 674 675 676 VOID * 677 EFIAPI 678 AllocatePages ( 679 IN UINTN Pages 680 ) 681 /*++ 682 683 Routine Description: 684 685 Allocate Memory. 686 687 Arguments: 688 689 Pages - Pages to allocate. 690 691 Returns: 692 = Address if successful to allocate memory. 693 = NULL if fail to allocate memory. 694 695 --*/ 696 { 697 EFI_STATUS Status; 698 EFI_PHYSICAL_ADDRESS Memory; 699 EFI_PEI_SERVICES **PeiServices; 700 701 if (Pages == 0) { 702 return NULL; 703 } 704 705 PeiServices = GetPeiServicesTablePointer(); 706 Status = (*PeiServices)->AllocatePages (PeiServices, EfiBootServicesData, Pages, &Memory); 707 if (EFI_ERROR (Status)) { 708 Memory = 0; 709 } 710 return (VOID *) (UINTN) Memory; 711 712 } 713 714 #endif 715