1 /** @file 2 3 Copyright (c) 2010, Apple Inc. All rights reserved.<BR> 4 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 <PiPei.h> 16 17 #include <Library/BaseLib.h> 18 #include <Library/BaseMemoryLib.h> 19 #include <Library/DebugLib.h> 20 #include <Library/PeCoffLib.h> 21 #include <Library/HobLib.h> 22 #include <Library/PcdLib.h> 23 #include <Library/PrePiHobListPointerLib.h> 24 25 #include <Protocol/PeCoffLoader.h> 26 #include <Guid/ExtractSection.h> 27 #include <Guid/MemoryTypeInformation.h> 28 #include <Guid/MemoryAllocationHob.h> 29 30 VOID 31 BuildMemoryTypeInformationHob ( 32 VOID 33 ); 34 35 /** 36 Returns the pointer to the HOB list. 37 38 This function returns the pointer to first HOB in the list. 39 40 @return The pointer to the HOB list. 41 42 **/ 43 VOID * 44 EFIAPI 45 GetHobList ( 46 VOID 47 ) 48 { 49 return PrePeiGetHobList (); 50 } 51 52 53 54 /** 55 Updates the pointer to the HOB list. 56 57 @param HobList Hob list pointer to store 58 59 **/ 60 EFI_STATUS 61 EFIAPI 62 SetHobList ( 63 IN VOID *HobList 64 ) 65 { 66 return PrePeiSetHobList (HobList); 67 } 68 69 /** 70 71 72 **/ 73 EFI_HOB_HANDOFF_INFO_TABLE* 74 HobConstructor ( 75 IN VOID *EfiMemoryBegin, 76 IN UINTN EfiMemoryLength, 77 IN VOID *EfiFreeMemoryBottom, 78 IN VOID *EfiFreeMemoryTop 79 ) 80 { 81 EFI_HOB_HANDOFF_INFO_TABLE *Hob; 82 EFI_HOB_GENERIC_HEADER *HobEnd; 83 84 Hob = EfiFreeMemoryBottom; 85 HobEnd = (EFI_HOB_GENERIC_HEADER *)(Hob+1); 86 87 Hob->Header.HobType = EFI_HOB_TYPE_HANDOFF; 88 Hob->Header.HobLength = sizeof(EFI_HOB_HANDOFF_INFO_TABLE); 89 Hob->Header.Reserved = 0; 90 91 HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST; 92 HobEnd->HobLength = sizeof(EFI_HOB_GENERIC_HEADER); 93 HobEnd->Reserved = 0; 94 95 Hob->Version = EFI_HOB_HANDOFF_TABLE_VERSION; 96 Hob->BootMode = BOOT_WITH_FULL_CONFIGURATION; 97 98 Hob->EfiMemoryTop = (UINTN)EfiMemoryBegin + EfiMemoryLength; 99 Hob->EfiMemoryBottom = (UINTN)EfiMemoryBegin; 100 Hob->EfiFreeMemoryTop = (UINTN)EfiFreeMemoryTop; 101 Hob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS)(UINTN)(HobEnd+1); 102 Hob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS)(UINTN)HobEnd; 103 104 return Hob; 105 } 106 107 VOID * 108 CreateHob ( 109 IN UINT16 HobType, 110 IN UINT16 HobLength 111 ) 112 { 113 EFI_HOB_HANDOFF_INFO_TABLE *HandOffHob; 114 EFI_HOB_GENERIC_HEADER *HobEnd; 115 EFI_PHYSICAL_ADDRESS FreeMemory; 116 VOID *Hob; 117 118 HandOffHob = GetHobList (); 119 120 HobLength = (UINT16)((HobLength + 0x7) & (~0x7)); 121 122 FreeMemory = HandOffHob->EfiFreeMemoryTop - HandOffHob->EfiFreeMemoryBottom; 123 124 if (FreeMemory < HobLength) { 125 return NULL; 126 } 127 128 Hob = (VOID*) (UINTN) HandOffHob->EfiEndOfHobList; 129 ((EFI_HOB_GENERIC_HEADER*) Hob)->HobType = HobType; 130 ((EFI_HOB_GENERIC_HEADER*) Hob)->HobLength = HobLength; 131 ((EFI_HOB_GENERIC_HEADER*) Hob)->Reserved = 0; 132 133 HobEnd = (EFI_HOB_GENERIC_HEADER*) ((UINTN)Hob + HobLength); 134 HandOffHob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd; 135 136 HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST; 137 HobEnd->HobLength = sizeof(EFI_HOB_GENERIC_HEADER); 138 HobEnd->Reserved = 0; 139 HobEnd++; 140 HandOffHob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd; 141 142 return Hob; 143 } 144 145 /** 146 Builds a HOB that describes a chunk of system memory. 147 148 This function builds a HOB that describes a chunk of system memory. 149 If there is no additional space for HOB creation, then ASSERT(). 150 151 @param ResourceType The type of resource described by this HOB. 152 @param ResourceAttribute The resource attributes of the memory described by this HOB. 153 @param PhysicalStart The 64 bit physical address of memory described by this HOB. 154 @param NumberOfBytes The length of the memory described by this HOB in bytes. 155 156 **/ 157 VOID 158 EFIAPI 159 BuildResourceDescriptorHob ( 160 IN EFI_RESOURCE_TYPE ResourceType, 161 IN EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute, 162 IN EFI_PHYSICAL_ADDRESS PhysicalStart, 163 IN UINT64 NumberOfBytes 164 ) 165 { 166 EFI_HOB_RESOURCE_DESCRIPTOR *Hob; 167 168 Hob = CreateHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, sizeof (EFI_HOB_RESOURCE_DESCRIPTOR)); 169 ASSERT(Hob != NULL); 170 171 Hob->ResourceType = ResourceType; 172 Hob->ResourceAttribute = ResourceAttribute; 173 Hob->PhysicalStart = PhysicalStart; 174 Hob->ResourceLength = NumberOfBytes; 175 } 176 177 /** 178 179 180 **/ 181 VOID 182 CreateHobList ( 183 IN VOID *MemoryBegin, 184 IN UINTN MemoryLength, 185 IN VOID *HobBase, 186 IN VOID *StackBase 187 ) 188 { 189 EFI_HOB_HANDOFF_INFO_TABLE *Hob; 190 EFI_RESOURCE_ATTRIBUTE_TYPE Attributes; 191 192 Hob = HobConstructor (MemoryBegin,MemoryLength,HobBase,StackBase); 193 SetHobList (Hob); 194 195 BuildCpuHob (PcdGet8 (PcdPrePiCpuMemorySize), PcdGet8 (PcdPrePiCpuIoSize)); 196 197 Attributes =( 198 EFI_RESOURCE_ATTRIBUTE_PRESENT | 199 EFI_RESOURCE_ATTRIBUTE_INITIALIZED | 200 EFI_RESOURCE_ATTRIBUTE_TESTED | 201 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | 202 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | 203 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | 204 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE 205 ); 206 207 BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY, Attributes, (UINTN)MemoryBegin, MemoryLength); 208 209 BuildStackHob ((EFI_PHYSICAL_ADDRESS)(UINTN)StackBase, ((UINTN)MemoryBegin + MemoryLength) - (UINTN)StackBase); 210 211 if (FeaturePcdGet (PcdPrePiProduceMemoryTypeInformationHob)) { 212 // Optional feature that helps prevent EFI memory map fragmentation. 213 BuildMemoryTypeInformationHob (); 214 } 215 } 216 217 218 VOID 219 EFIAPI 220 BuildFvHobs ( 221 IN EFI_PHYSICAL_ADDRESS PhysicalStart, 222 IN UINT64 NumberOfBytes, 223 IN EFI_RESOURCE_ATTRIBUTE_TYPE *ResourceAttribute 224 ) 225 { 226 227 EFI_RESOURCE_ATTRIBUTE_TYPE Resource; 228 229 BuildFvHob (PhysicalStart, NumberOfBytes); 230 231 if (ResourceAttribute == NULL) { 232 Resource = (EFI_RESOURCE_ATTRIBUTE_PRESENT | 233 EFI_RESOURCE_ATTRIBUTE_INITIALIZED | 234 EFI_RESOURCE_ATTRIBUTE_TESTED | 235 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE); 236 } else { 237 Resource = *ResourceAttribute; 238 } 239 240 BuildResourceDescriptorHob (EFI_RESOURCE_FIRMWARE_DEVICE, Resource, PhysicalStart, NumberOfBytes); 241 } 242 243 /** 244 Returns the next instance of a HOB type from the starting HOB. 245 246 This function searches the first instance of a HOB type from the starting HOB pointer. 247 If there does not exist such HOB type from the starting HOB pointer, it will return NULL. 248 In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer 249 unconditionally: it returns HobStart back if HobStart itself meets the requirement; 250 caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart. 251 If HobStart is NULL, then ASSERT(). 252 253 @param Type The HOB type to return. 254 @param HobStart The starting HOB pointer to search from. 255 256 @return The next instance of a HOB type from the starting HOB. 257 258 **/ 259 VOID * 260 EFIAPI 261 GetNextHob ( 262 IN UINT16 Type, 263 IN CONST VOID *HobStart 264 ) 265 { 266 EFI_PEI_HOB_POINTERS Hob; 267 268 ASSERT (HobStart != NULL); 269 270 Hob.Raw = (UINT8 *) HobStart; 271 // 272 // Parse the HOB list until end of list or matching type is found. 273 // 274 while (!END_OF_HOB_LIST (Hob)) { 275 if (Hob.Header->HobType == Type) { 276 return Hob.Raw; 277 } 278 Hob.Raw = GET_NEXT_HOB (Hob); 279 } 280 return NULL; 281 } 282 283 284 285 /** 286 Returns the first instance of a HOB type among the whole HOB list. 287 288 This function searches the first instance of a HOB type among the whole HOB list. 289 If there does not exist such HOB type in the HOB list, it will return NULL. 290 291 @param Type The HOB type to return. 292 293 @return The next instance of a HOB type from the starting HOB. 294 295 **/ 296 VOID * 297 EFIAPI 298 GetFirstHob ( 299 IN UINT16 Type 300 ) 301 { 302 VOID *HobList; 303 304 HobList = GetHobList (); 305 return GetNextHob (Type, HobList); 306 } 307 308 309 /** 310 This function searches the first instance of a HOB from the starting HOB pointer. 311 Such HOB should satisfy two conditions: 312 its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid. 313 If there does not exist such HOB from the starting HOB pointer, it will return NULL. 314 Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE () 315 to extract the data section and its size info respectively. 316 In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer 317 unconditionally: it returns HobStart back if HobStart itself meets the requirement; 318 caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart. 319 If Guid is NULL, then ASSERT(). 320 If HobStart is NULL, then ASSERT(). 321 322 @param Guid The GUID to match with in the HOB list. 323 @param HobStart A pointer to a Guid. 324 325 @return The next instance of the matched GUID HOB from the starting HOB. 326 327 **/ 328 VOID * 329 EFIAPI 330 GetNextGuidHob ( 331 IN CONST EFI_GUID *Guid, 332 IN CONST VOID *HobStart 333 ){ 334 EFI_PEI_HOB_POINTERS GuidHob; 335 336 GuidHob.Raw = (UINT8 *) HobStart; 337 while ((GuidHob.Raw = GetNextHob (EFI_HOB_TYPE_GUID_EXTENSION, GuidHob.Raw)) != NULL) { 338 if (CompareGuid (Guid, &GuidHob.Guid->Name)) { 339 break; 340 } 341 GuidHob.Raw = GET_NEXT_HOB (GuidHob); 342 } 343 return GuidHob.Raw; 344 } 345 346 347 /** 348 This function searches the first instance of a HOB among the whole HOB list. 349 Such HOB should satisfy two conditions: 350 its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid. 351 If there does not exist such HOB from the starting HOB pointer, it will return NULL. 352 Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE () 353 to extract the data section and its size info respectively. 354 If Guid is NULL, then ASSERT(). 355 356 @param Guid The GUID to match with in the HOB list. 357 358 @return The first instance of the matched GUID HOB among the whole HOB list. 359 360 **/ 361 VOID * 362 EFIAPI 363 GetFirstGuidHob ( 364 IN CONST EFI_GUID *Guid 365 ) 366 { 367 VOID *HobList; 368 369 HobList = GetHobList (); 370 return GetNextGuidHob (Guid, HobList); 371 } 372 373 374 /** 375 Get the Boot Mode from the HOB list. 376 377 This function returns the system boot mode information from the 378 PHIT HOB in HOB list. 379 380 @param VOID 381 382 @return The Boot Mode. 383 384 **/ 385 EFI_BOOT_MODE 386 EFIAPI 387 GetBootMode ( 388 VOID 389 ) 390 { 391 EFI_PEI_HOB_POINTERS Hob; 392 393 Hob.Raw = GetHobList (); 394 return Hob.HandoffInformationTable->BootMode; 395 } 396 397 398 /** 399 Get the Boot Mode from the HOB list. 400 401 This function returns the system boot mode information from the 402 PHIT HOB in HOB list. 403 404 @param VOID 405 406 @return The Boot Mode. 407 408 **/ 409 EFI_STATUS 410 EFIAPI 411 SetBootMode ( 412 IN EFI_BOOT_MODE BootMode 413 ) 414 { 415 EFI_PEI_HOB_POINTERS Hob; 416 417 Hob.Raw = GetHobList (); 418 Hob.HandoffInformationTable->BootMode = BootMode; 419 return BootMode; 420 } 421 422 /** 423 Builds a HOB for a loaded PE32 module. 424 425 This function builds a HOB for a loaded PE32 module. 426 It can only be invoked during PEI phase; 427 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase. 428 If ModuleName is NULL, then ASSERT(). 429 If there is no additional space for HOB creation, then ASSERT(). 430 431 @param ModuleName The GUID File Name of the module. 432 @param MemoryAllocationModule The 64 bit physical address of the module. 433 @param ModuleLength The length of the module in bytes. 434 @param EntryPoint The 64 bit physical address of the module entry point. 435 436 **/ 437 VOID 438 EFIAPI 439 BuildModuleHob ( 440 IN CONST EFI_GUID *ModuleName, 441 IN EFI_PHYSICAL_ADDRESS MemoryAllocationModule, 442 IN UINT64 ModuleLength, 443 IN EFI_PHYSICAL_ADDRESS EntryPoint 444 ) 445 { 446 EFI_HOB_MEMORY_ALLOCATION_MODULE *Hob; 447 448 ASSERT (((MemoryAllocationModule & (EFI_PAGE_SIZE - 1)) == 0) && 449 ((ModuleLength & (EFI_PAGE_SIZE - 1)) == 0)); 450 451 Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_MODULE)); 452 453 CopyGuid (&(Hob->MemoryAllocationHeader.Name), &gEfiHobMemoryAllocModuleGuid); 454 Hob->MemoryAllocationHeader.MemoryBaseAddress = MemoryAllocationModule; 455 Hob->MemoryAllocationHeader.MemoryLength = ModuleLength; 456 Hob->MemoryAllocationHeader.MemoryType = EfiBootServicesCode; 457 458 // 459 // Zero the reserved space to match HOB spec 460 // 461 ZeroMem (Hob->MemoryAllocationHeader.Reserved, sizeof (Hob->MemoryAllocationHeader.Reserved)); 462 463 CopyGuid (&Hob->ModuleName, ModuleName); 464 Hob->EntryPoint = EntryPoint; 465 } 466 467 /** 468 Builds a GUID HOB with a certain data length. 469 470 This function builds a customized HOB tagged with a GUID for identification 471 and returns the start address of GUID HOB data so that caller can fill the customized data. 472 The HOB Header and Name field is already stripped. 473 It can only be invoked during PEI phase; 474 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase. 475 If Guid is NULL, then ASSERT(). 476 If there is no additional space for HOB creation, then ASSERT(). 477 If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT(). 478 479 @param Guid The GUID to tag the customized HOB. 480 @param DataLength The size of the data payload for the GUID HOB. 481 482 @return The start address of GUID HOB data. 483 484 **/ 485 VOID * 486 EFIAPI 487 BuildGuidHob ( 488 IN CONST EFI_GUID *Guid, 489 IN UINTN DataLength 490 ) 491 { 492 EFI_HOB_GUID_TYPE *Hob; 493 494 // 495 // Make sure that data length is not too long. 496 // 497 ASSERT (DataLength <= (0xffff - sizeof (EFI_HOB_GUID_TYPE))); 498 499 Hob = CreateHob (EFI_HOB_TYPE_GUID_EXTENSION, (UINT16) (sizeof (EFI_HOB_GUID_TYPE) + DataLength)); 500 CopyGuid (&Hob->Name, Guid); 501 return Hob + 1; 502 } 503 504 505 /** 506 Copies a data buffer to a newly-built HOB. 507 508 This function builds a customized HOB tagged with a GUID for identification, 509 copies the input data to the HOB data field and returns the start address of the GUID HOB data. 510 The HOB Header and Name field is already stripped. 511 It can only be invoked during PEI phase; 512 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase. 513 If Guid is NULL, then ASSERT(). 514 If Data is NULL and DataLength > 0, then ASSERT(). 515 If there is no additional space for HOB creation, then ASSERT(). 516 If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT(). 517 518 @param Guid The GUID to tag the customized HOB. 519 @param Data The data to be copied into the data field of the GUID HOB. 520 @param DataLength The size of the data payload for the GUID HOB. 521 522 @return The start address of GUID HOB data. 523 524 **/ 525 VOID * 526 EFIAPI 527 BuildGuidDataHob ( 528 IN CONST EFI_GUID *Guid, 529 IN VOID *Data, 530 IN UINTN DataLength 531 ) 532 { 533 VOID *HobData; 534 535 ASSERT (Data != NULL || DataLength == 0); 536 537 HobData = BuildGuidHob (Guid, DataLength); 538 539 return CopyMem (HobData, Data, DataLength); 540 } 541 542 543 /** 544 Builds a Firmware Volume HOB. 545 546 This function builds a Firmware Volume HOB. 547 It can only be invoked during PEI phase; 548 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase. 549 If there is no additional space for HOB creation, then ASSERT(). 550 551 @param BaseAddress The base address of the Firmware Volume. 552 @param Length The size of the Firmware Volume in bytes. 553 554 **/ 555 VOID 556 EFIAPI 557 BuildFvHob ( 558 IN EFI_PHYSICAL_ADDRESS BaseAddress, 559 IN UINT64 Length 560 ) 561 { 562 EFI_HOB_FIRMWARE_VOLUME *Hob; 563 564 Hob = CreateHob (EFI_HOB_TYPE_FV, sizeof (EFI_HOB_FIRMWARE_VOLUME)); 565 566 Hob->BaseAddress = BaseAddress; 567 Hob->Length = Length; 568 } 569 570 571 /** 572 Builds a EFI_HOB_TYPE_FV2 HOB. 573 574 This function builds a EFI_HOB_TYPE_FV2 HOB. 575 It can only be invoked during PEI phase; 576 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase. 577 If there is no additional space for HOB creation, then ASSERT(). 578 579 @param BaseAddress The base address of the Firmware Volume. 580 @param Length The size of the Firmware Volume in bytes. 581 @param FvName The name of the Firmware Volume. 582 @param FileName The name of the file. 583 584 **/ 585 VOID 586 EFIAPI 587 BuildFv2Hob ( 588 IN EFI_PHYSICAL_ADDRESS BaseAddress, 589 IN UINT64 Length, 590 IN CONST EFI_GUID *FvName, 591 IN CONST EFI_GUID *FileName 592 ) 593 { 594 EFI_HOB_FIRMWARE_VOLUME2 *Hob; 595 596 Hob = CreateHob (EFI_HOB_TYPE_FV2, sizeof (EFI_HOB_FIRMWARE_VOLUME2)); 597 598 Hob->BaseAddress = BaseAddress; 599 Hob->Length = Length; 600 CopyGuid (&Hob->FvName, FvName); 601 CopyGuid (&Hob->FileName, FileName); 602 } 603 604 605 606 /** 607 Builds a Capsule Volume HOB. 608 609 This function builds a Capsule Volume HOB. 610 It can only be invoked during PEI phase; 611 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase. 612 If there is no additional space for HOB creation, then ASSERT(). 613 614 @param BaseAddress The base address of the Capsule Volume. 615 @param Length The size of the Capsule Volume in bytes. 616 617 **/ 618 VOID 619 EFIAPI 620 BuildCvHob ( 621 IN EFI_PHYSICAL_ADDRESS BaseAddress, 622 IN UINT64 Length 623 ) 624 { 625 ASSERT (FALSE); 626 } 627 628 629 /** 630 Builds a HOB for the CPU. 631 632 This function builds a HOB for the CPU. 633 It can only be invoked during PEI phase; 634 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase. 635 If there is no additional space for HOB creation, then ASSERT(). 636 637 @param SizeOfMemorySpace The maximum physical memory addressability of the processor. 638 @param SizeOfIoSpace The maximum physical I/O addressability of the processor. 639 640 **/ 641 VOID 642 EFIAPI 643 BuildCpuHob ( 644 IN UINT8 SizeOfMemorySpace, 645 IN UINT8 SizeOfIoSpace 646 ) 647 { 648 EFI_HOB_CPU *Hob; 649 650 Hob = CreateHob (EFI_HOB_TYPE_CPU, sizeof (EFI_HOB_CPU)); 651 652 Hob->SizeOfMemorySpace = SizeOfMemorySpace; 653 Hob->SizeOfIoSpace = SizeOfIoSpace; 654 655 // 656 // Zero the reserved space to match HOB spec 657 // 658 ZeroMem (Hob->Reserved, sizeof (Hob->Reserved)); 659 } 660 661 662 /** 663 Builds a HOB for the Stack. 664 665 This function builds a HOB for the stack. 666 It can only be invoked during PEI phase; 667 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase. 668 If there is no additional space for HOB creation, then ASSERT(). 669 670 @param BaseAddress The 64 bit physical address of the Stack. 671 @param Length The length of the stack in bytes. 672 673 **/ 674 VOID 675 EFIAPI 676 BuildStackHob ( 677 IN EFI_PHYSICAL_ADDRESS BaseAddress, 678 IN UINT64 Length 679 ) 680 { 681 EFI_HOB_MEMORY_ALLOCATION_STACK *Hob; 682 683 ASSERT (((BaseAddress & (EFI_PAGE_SIZE - 1)) == 0) && 684 ((Length & (EFI_PAGE_SIZE - 1)) == 0)); 685 686 Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_STACK)); 687 688 CopyGuid (&(Hob->AllocDescriptor.Name), &gEfiHobMemoryAllocStackGuid); 689 Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress; 690 Hob->AllocDescriptor.MemoryLength = Length; 691 Hob->AllocDescriptor.MemoryType = EfiBootServicesData; 692 693 // 694 // Zero the reserved space to match HOB spec 695 // 696 ZeroMem (Hob->AllocDescriptor.Reserved, sizeof (Hob->AllocDescriptor.Reserved)); 697 } 698 699 700 /** 701 Update the Stack Hob if the stack has been moved 702 703 @param BaseAddress The 64 bit physical address of the Stack. 704 @param Length The length of the stack in bytes. 705 706 **/ 707 VOID 708 UpdateStackHob ( 709 IN EFI_PHYSICAL_ADDRESS BaseAddress, 710 IN UINT64 Length 711 ) 712 { 713 EFI_PEI_HOB_POINTERS Hob; 714 715 Hob.Raw = GetHobList (); 716 while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw)) != NULL) { 717 if (CompareGuid (&gEfiHobMemoryAllocStackGuid, &(Hob.MemoryAllocationStack->AllocDescriptor.Name))) { 718 // 719 // Build a new memory allocation HOB with old stack info with EfiConventionalMemory type 720 // to be reclaimed by DXE core. 721 // 722 BuildMemoryAllocationHob ( 723 Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress, 724 Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength, 725 EfiConventionalMemory 726 ); 727 // 728 // Update the BSP Stack Hob to reflect the new stack info. 729 // 730 Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress = BaseAddress; 731 Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength = Length; 732 break; 733 } 734 Hob.Raw = GET_NEXT_HOB (Hob); 735 } 736 } 737 738 739 740 /** 741 Builds a HOB for the memory allocation. 742 743 This function builds a HOB for the memory allocation. 744 It can only be invoked during PEI phase; 745 for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase. 746 If there is no additional space for HOB creation, then ASSERT(). 747 748 @param BaseAddress The 64 bit physical address of the memory. 749 @param Length The length of the memory allocation in bytes. 750 @param MemoryType Type of memory allocated by this HOB. 751 752 **/ 753 VOID 754 EFIAPI 755 BuildMemoryAllocationHob ( 756 IN EFI_PHYSICAL_ADDRESS BaseAddress, 757 IN UINT64 Length, 758 IN EFI_MEMORY_TYPE MemoryType 759 ) 760 { 761 EFI_HOB_MEMORY_ALLOCATION *Hob; 762 763 ASSERT (((BaseAddress & (EFI_PAGE_SIZE - 1)) == 0) && 764 ((Length & (EFI_PAGE_SIZE - 1)) == 0)); 765 766 Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION)); 767 768 ZeroMem (&(Hob->AllocDescriptor.Name), sizeof (EFI_GUID)); 769 Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress; 770 Hob->AllocDescriptor.MemoryLength = Length; 771 Hob->AllocDescriptor.MemoryType = MemoryType; 772 // 773 // Zero the reserved space to match HOB spec 774 // 775 ZeroMem (Hob->AllocDescriptor.Reserved, sizeof (Hob->AllocDescriptor.Reserved)); 776 } 777 778 779 780 VOID 781 EFIAPI 782 BuildExtractSectionHob ( 783 IN EFI_GUID *Guid, 784 IN EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER SectionGetInfo, 785 IN EXTRACT_GUIDED_SECTION_DECODE_HANDLER SectionExtraction 786 ) 787 { 788 EXTRACT_SECTION_DATA Data; 789 790 Data.SectionGetInfo = SectionGetInfo; 791 Data.SectionExtraction = SectionExtraction; 792 BuildGuidDataHob (Guid, &Data, sizeof (Data)); 793 } 794 795 PE_COFF_LOADER_PROTOCOL gPeCoffProtocol = { 796 PeCoffLoaderGetImageInfo, 797 PeCoffLoaderLoadImage, 798 PeCoffLoaderRelocateImage, 799 PeCoffLoaderImageReadFromMemory, 800 PeCoffLoaderRelocateImageForRuntime, 801 PeCoffLoaderUnloadImage 802 }; 803 804 805 806 VOID 807 EFIAPI 808 BuildPeCoffLoaderHob ( 809 VOID 810 ) 811 { 812 VOID *Ptr; 813 814 Ptr = &gPeCoffProtocol; 815 BuildGuidDataHob (&gPeCoffLoaderProtocolGuid, &Ptr, sizeof (VOID *)); 816 } 817 818 // May want to put this into a library so you only need the PCD setings if you are using the feature? 819 VOID 820 BuildMemoryTypeInformationHob ( 821 VOID 822 ) 823 { 824 EFI_MEMORY_TYPE_INFORMATION Info[10]; 825 826 Info[0].Type = EfiACPIReclaimMemory; 827 Info[0].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiACPIReclaimMemory); 828 Info[1].Type = EfiACPIMemoryNVS; 829 Info[1].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiACPIMemoryNVS); 830 Info[2].Type = EfiReservedMemoryType; 831 Info[2].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiReservedMemoryType); 832 Info[3].Type = EfiRuntimeServicesData; 833 Info[3].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiRuntimeServicesData); 834 Info[4].Type = EfiRuntimeServicesCode; 835 Info[4].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiRuntimeServicesCode); 836 Info[5].Type = EfiBootServicesCode; 837 Info[5].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiBootServicesCode); 838 Info[6].Type = EfiBootServicesData; 839 Info[6].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiBootServicesData); 840 Info[7].Type = EfiLoaderCode; 841 Info[7].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiLoaderCode); 842 Info[8].Type = EfiLoaderData; 843 Info[8].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiLoaderData); 844 845 // Terminator for the list 846 Info[9].Type = EfiMaxMemoryType; 847 Info[9].NumberOfPages = 0; 848 849 850 BuildGuidDataHob (&gEfiMemoryTypeInformationGuid, &Info, sizeof (Info)); 851 } 852 853