1 /** @file 2 3 Copyright (c) 2006 - 2014, 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 HobGeneration.c 14 15 Abstract: 16 17 Revision History: 18 19 **/ 20 #include "DxeIpl.h" 21 #include "HobGeneration.h" 22 #include "PpisNeededByDxeCore.h" 23 #include "FlashLayout.h" 24 #include "Debug.h" 25 26 #define EFI_CPUID_EXTENDED_FUNCTION 0x80000000 27 #define CPUID_EXTENDED_ADD_SIZE 0x80000008 28 #define EBDA_VALUE_ADDRESS 0x40E 29 30 HOB_TEMPLATE gHobTemplate = { 31 { // Phit 32 { // Header 33 EFI_HOB_TYPE_HANDOFF, // HobType 34 sizeof (EFI_HOB_HANDOFF_INFO_TABLE), // HobLength 35 0 // Reserved 36 }, 37 EFI_HOB_HANDOFF_TABLE_VERSION, // Version 38 BOOT_WITH_FULL_CONFIGURATION, // BootMode 39 0, // EfiMemoryTop 40 0, // EfiMemoryBottom 41 0, // EfiFreeMemoryTop 42 0, // EfiFreeMemoryBottom 43 0 // EfiEndOfHobList 44 }, 45 { // Bfv 46 { 47 EFI_HOB_TYPE_FV, // HobType 48 sizeof (EFI_HOB_FIRMWARE_VOLUME), // HobLength 49 0 // Reserved 50 }, 51 0, // BaseAddress 52 0 // Length 53 }, 54 { // BfvResource 55 { 56 EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, // HobType 57 sizeof (EFI_HOB_RESOURCE_DESCRIPTOR), // HobLength 58 0 // Reserved 59 }, 60 { 61 0 // Owner Guid 62 }, 63 EFI_RESOURCE_FIRMWARE_DEVICE, // ResourceType 64 (EFI_RESOURCE_ATTRIBUTE_PRESENT | 65 EFI_RESOURCE_ATTRIBUTE_INITIALIZED | 66 EFI_RESOURCE_ATTRIBUTE_TESTED | 67 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE), // ResourceAttribute 68 0, // PhysicalStart 69 0 // ResourceLength 70 }, 71 { // Cpu 72 { // Header 73 EFI_HOB_TYPE_CPU, // HobType 74 sizeof (EFI_HOB_CPU), // HobLength 75 0 // Reserved 76 }, 77 52, // SizeOfMemorySpace - Architecture Max 78 16, // SizeOfIoSpace, 79 { 80 0, 0, 0, 0, 0, 0 // Reserved[6] 81 } 82 }, 83 { // Stack HOB 84 { // header 85 EFI_HOB_TYPE_MEMORY_ALLOCATION, // Hob type 86 sizeof (EFI_HOB_MEMORY_ALLOCATION_STACK), // Hob size 87 0 // reserved 88 }, 89 { 90 EFI_HOB_MEMORY_ALLOC_STACK_GUID, 91 0x0, // EFI_PHYSICAL_ADDRESS MemoryBaseAddress; 92 0x0, // UINT64 MemoryLength; 93 EfiBootServicesData, // EFI_MEMORY_TYPE MemoryType; 94 {0, 0, 0, 0} // Reserved Reserved[4]; 95 } 96 }, 97 { // MemoryAllocation for HOB's & Images 98 { 99 EFI_HOB_TYPE_MEMORY_ALLOCATION, // HobType 100 sizeof (EFI_HOB_MEMORY_ALLOCATION), // HobLength 101 0 // Reserved 102 }, 103 { 104 { 105 0, //EFI_HOB_MEMORY_ALLOC_MODULE_GUID // Name 106 }, 107 0x0, // EFI_PHYSICAL_ADDRESS MemoryBaseAddress; 108 0x0, // UINT64 MemoryLength; 109 EfiBootServicesData, // EFI_MEMORY_TYPE MemoryType; 110 { 111 0, 0, 0, 0 // Reserved Reserved[4]; 112 } 113 } 114 }, 115 { // MemoryFreeUnder1MB for unused memory that DXE core will claim 116 { 117 EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, // HobType 118 sizeof (EFI_HOB_RESOURCE_DESCRIPTOR), // HobLength 119 0 // Reserved 120 }, 121 { 122 0 // Owner Guid 123 }, 124 EFI_RESOURCE_SYSTEM_MEMORY, // ResourceType 125 (EFI_RESOURCE_ATTRIBUTE_PRESENT | 126 EFI_RESOURCE_ATTRIBUTE_TESTED | 127 EFI_RESOURCE_ATTRIBUTE_INITIALIZED | 128 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | 129 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | 130 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | 131 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE), 132 0x0, // PhysicalStart 133 0 // ResourceLength 134 }, 135 { // MemoryFreeAbove1MB for unused memory that DXE core will claim 136 { 137 EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, // HobType 138 sizeof (EFI_HOB_RESOURCE_DESCRIPTOR), // HobLength 139 0 // Reserved 140 }, 141 { 142 0 // Owner Guid 143 }, 144 EFI_RESOURCE_SYSTEM_MEMORY, // ResourceType 145 (EFI_RESOURCE_ATTRIBUTE_PRESENT | 146 EFI_RESOURCE_ATTRIBUTE_TESTED | 147 EFI_RESOURCE_ATTRIBUTE_INITIALIZED | 148 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | 149 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | 150 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | 151 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE), 152 0x0, // PhysicalStart 153 0 // ResourceLength 154 }, 155 { // MemoryFreeAbove4GB for unused memory that DXE core will claim 156 { 157 EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, // HobType 158 sizeof (EFI_HOB_RESOURCE_DESCRIPTOR), // HobLength 159 0 // Reserved 160 }, 161 { 162 0 // Owner Guid 163 }, 164 EFI_RESOURCE_SYSTEM_MEMORY, // ResourceType 165 (EFI_RESOURCE_ATTRIBUTE_PRESENT | 166 EFI_RESOURCE_ATTRIBUTE_INITIALIZED | 167 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | 168 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | 169 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | 170 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE), 171 0x0, // PhysicalStart 172 0 // ResourceLength 173 }, 174 { // Memory Allocation Module for DxeCore 175 { // header 176 EFI_HOB_TYPE_MEMORY_ALLOCATION, // Hob type 177 sizeof (EFI_HOB_MEMORY_ALLOCATION_MODULE), // Hob size 178 0 // reserved 179 }, 180 { 181 EFI_HOB_MEMORY_ALLOC_MODULE_GUID, 182 0x0, // EFI_PHYSICAL_ADDRESS MemoryBaseAddress; 183 0x0, // UINT64 MemoryLength; 184 EfiBootServicesCode, // EFI_MEMORY_TYPE MemoryType; 185 { 186 0, 0, 0, 0 // UINT8 Reserved[4]; 187 }, 188 }, 189 DXE_CORE_FILE_NAME_GUID, 190 0x0 // EFI_PHYSICAL_ADDRESS of EntryPoint; 191 }, 192 { // MemoryDxeCore 193 { 194 EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, // HobType 195 sizeof (EFI_HOB_RESOURCE_DESCRIPTOR), // HobLength 196 0 // Reserved 197 }, 198 { 199 0 // Owner Guid 200 }, 201 EFI_RESOURCE_SYSTEM_MEMORY, // ResourceType 202 (EFI_RESOURCE_ATTRIBUTE_PRESENT | 203 // EFI_RESOURCE_ATTRIBUTE_TESTED | // Do not mark as TESTED, or DxeCore will find it and use it before check Allocation 204 EFI_RESOURCE_ATTRIBUTE_INITIALIZED | 205 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | 206 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | 207 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | 208 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE), 209 0x0, // PhysicalStart 210 0 // ResourceLength 211 }, 212 { // Memory Map Hints to reduce fragmentation in the memory map 213 { 214 { 215 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type 216 sizeof (MEMORY_TYPE_INFORMATION_HOB), // Hob size 217 0, // reserved 218 }, 219 EFI_MEMORY_TYPE_INFORMATION_GUID 220 }, 221 { 222 { 223 EfiACPIReclaimMemory, 224 0x80 225 }, // 0x80 pages = 512k for ASL 226 { 227 EfiACPIMemoryNVS, 228 0x100 229 }, // 0x100 pages = 1024k for S3, SMM, etc 230 { 231 EfiReservedMemoryType, 232 0x04 233 }, // 16k for BIOS Reserved 234 { 235 EfiRuntimeServicesData, 236 0x100 237 }, 238 { 239 EfiRuntimeServicesCode, 240 0x100 241 }, 242 { 243 EfiBootServicesCode, 244 0x200 245 }, 246 { 247 EfiBootServicesData, 248 0x200 249 }, 250 { 251 EfiLoaderCode, 252 0x100 253 }, 254 { 255 EfiLoaderData, 256 0x100 257 }, 258 { 259 EfiMaxMemoryType, 260 0 261 } 262 } 263 }, 264 { // Pointer to ACPI Table 265 { 266 { 267 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type 268 sizeof (TABLE_HOB), // Hob size 269 0 // reserved 270 }, 271 EFI_ACPI_TABLE_GUID 272 }, 273 0 274 }, 275 { // Pointer to ACPI20 Table 276 { 277 { 278 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type 279 sizeof (TABLE_HOB), // Hob size 280 0 // reserved 281 }, 282 EFI_ACPI_20_TABLE_GUID 283 }, 284 0 285 }, 286 { // Pointer to SMBIOS Table 287 { 288 { 289 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type 290 sizeof (TABLE_HOB), // Hob size 291 0 // reserved 292 }, 293 SMBIOS_TABLE_GUID 294 }, 295 0 296 }, 297 { // Pointer to MPS Table 298 { 299 { 300 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type 301 sizeof (TABLE_HOB), // Hob size 302 0, // reserved 303 }, 304 EFI_MPS_TABLE_GUID 305 }, 306 0 307 }, 308 /** 309 { // Pointer to FlushInstructionCache 310 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type 311 sizeof (PROTOCOL_HOB), // Hob size 312 0, // reserved 313 EFI_PEI_FLUSH_INSTRUCTION_CACHE_GUID, 314 NULL 315 }, 316 { // Pointer to TransferControl 317 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type 318 sizeof (PROTOCOL_HOB), // Hob size 319 0, // reserved 320 EFI_PEI_TRANSFER_CONTROL_GUID, 321 NULL 322 }, 323 { // Pointer to PeCoffLoader 324 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type 325 sizeof (PROTOCOL_HOB), // Hob size 326 0, // reserved 327 EFI_PEI_PE_COFF_LOADER_GUID, 328 NULL 329 }, 330 { // Pointer to EfiDecompress 331 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type 332 sizeof (PROTOCOL_HOB), // Hob size 333 0, // reserved 334 EFI_DECOMPRESS_PROTOCOL_GUID, 335 NULL 336 }, 337 { // Pointer to TianoDecompress 338 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type 339 sizeof (PROTOCOL_HOB), // Hob size 340 0, // reserved 341 EFI_TIANO_DECOMPRESS_PROTOCOL_GUID, 342 NULL 343 }, 344 **/ 345 { // Pointer to ReportStatusCode 346 { 347 { 348 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type 349 sizeof (PROTOCOL_HOB), // Hob size 350 0 // reserved 351 }, 352 EFI_STATUS_CODE_RUNTIME_PROTOCOL_GUID 353 }, 354 0 355 }, 356 { // EFILDR Memory Descriptor 357 { 358 { 359 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type 360 sizeof (MEMORY_DESC_HOB), // Hob size 361 0 // reserved 362 }, 363 LDR_MEMORY_DESCRIPTOR_GUID 364 }, 365 0, 366 NULL 367 }, 368 { // Pci Express Base Address Hob 369 { 370 { 371 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type 372 sizeof (PCI_EXPRESS_BASE_HOB), // Hob size 373 0 // reserved 374 }, 375 EFI_PCI_EXPRESS_BASE_ADDRESS_GUID 376 }, 377 { 378 0, 379 0, 380 0, 381 } 382 }, 383 { // Acpi Description Hob 384 { 385 { 386 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type 387 sizeof (ACPI_DESCRIPTION_HOB), // Hob size 388 0 // reserved 389 }, 390 EFI_ACPI_DESCRIPTION_GUID 391 }, 392 { 393 { 394 0, 395 }, 396 } 397 }, 398 { // NV Storage FV Resource 399 { 400 EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, // HobType 401 sizeof (EFI_HOB_RESOURCE_DESCRIPTOR), // HobLength 402 0 // Reserved 403 }, 404 { 405 0 // Owner Guid 406 }, 407 EFI_RESOURCE_FIRMWARE_DEVICE, // ResourceType 408 (EFI_RESOURCE_ATTRIBUTE_PRESENT | 409 EFI_RESOURCE_ATTRIBUTE_INITIALIZED | 410 EFI_RESOURCE_ATTRIBUTE_TESTED | 411 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE), // ResourceAttribute 412 0, // PhysicalStart (Fixed later) 413 NV_STORAGE_FVB_SIZE // ResourceLength 414 }, 415 { // FVB holding NV Storage 416 { 417 { 418 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type 419 sizeof (FVB_HOB), 420 0 421 }, 422 EFI_FLASH_MAP_HOB_GUID 423 }, 424 { 425 {0, 0, 0}, // Reserved[3] 426 EFI_FLASH_AREA_GUID_DEFINED, // AreaType 427 EFI_SYSTEM_NV_DATA_FV_GUID , // AreaTypeGuid 428 1, 429 { 430 { 431 EFI_FLASH_AREA_FV | EFI_FLASH_AREA_MEMMAPPED_FV, // SubAreaData.Attributes 432 0, // SubAreaData.Reserved 433 0, // SubAreaData.Base (Fixed later) 434 NV_STORAGE_FVB_SIZE, // SubAreaData.Length 435 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID // SubAreaData.FileSystem 436 } 437 }, 438 0, // VolumeSignature (Fixed later) 439 NV_STORAGE_FILE_PATH, // Mapped file without padding 440 // TotalFVBSize = FileSize + PaddingSize = multiple of BLOCK_SIZE 441 NV_STORAGE_SIZE + EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH, 442 // ActuralSize 443 EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH 444 } 445 }, 446 { // NV Storage Hob 447 { 448 { 449 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type 450 sizeof (FVB_HOB), // Hob size 451 0 // reserved 452 }, 453 EFI_FLASH_MAP_HOB_GUID 454 }, 455 { 456 {0, 0, 0}, // Reserved[3] 457 EFI_FLASH_AREA_EFI_VARIABLES, // AreaType 458 { 0 }, // AreaTypeGuid 459 1, 460 { 461 { 462 EFI_FLASH_AREA_SUBFV | EFI_FLASH_AREA_MEMMAPPED_FV, // SubAreaData.Attributes 463 0, // SubAreaData.Reserved 464 0, // SubAreaData.Base (Fixed later) 465 NV_STORAGE_SIZE, // SubAreaData.Length 466 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID // SubAreaData.FileSystem 467 } 468 }, 469 0, 470 NV_STORAGE_FILE_PATH, 471 NV_STORAGE_SIZE, 472 0 473 } 474 }, 475 { // NV Ftw FV Resource 476 { 477 EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, // HobType 478 sizeof (EFI_HOB_RESOURCE_DESCRIPTOR), // HobLength 479 0 // Reserved 480 }, 481 { 482 0 // Owner Guid 483 }, 484 EFI_RESOURCE_FIRMWARE_DEVICE, // ResourceType 485 (EFI_RESOURCE_ATTRIBUTE_PRESENT | 486 EFI_RESOURCE_ATTRIBUTE_INITIALIZED | 487 EFI_RESOURCE_ATTRIBUTE_TESTED | 488 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE), // ResourceAttribute 489 0, // PhysicalStart (Fixed later) 490 NV_FTW_FVB_SIZE // ResourceLength 491 }, 492 { // FVB holding FTW spaces including Working & Spare space 493 { 494 { 495 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type 496 sizeof (FVB_HOB), 497 0 498 }, 499 EFI_FLASH_MAP_HOB_GUID 500 }, 501 { 502 {0, 0, 0}, // Reserved[3] 503 EFI_FLASH_AREA_GUID_DEFINED, // AreaType 504 EFI_SYSTEM_NV_DATA_FV_GUID, // AreaTypeGuid 505 1, 506 { 507 { 508 EFI_FLASH_AREA_FV | EFI_FLASH_AREA_MEMMAPPED_FV, // SubAreaData.Attributes 509 0, // SubAreaData.Reserved 510 0, // SubAreaData.Base (Fixed later) 511 NV_FTW_FVB_SIZE, // SubAreaData.Length 512 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID // SubAreaData.FileSystem 513 } 514 }, 515 0, 516 L"", // Empty String indicates using memory 517 0, 518 0 519 } 520 }, 521 { // NV Ftw working Hob 522 { 523 { 524 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type 525 sizeof (FVB_HOB), // Hob size 526 0 // reserved 527 }, 528 EFI_FLASH_MAP_HOB_GUID 529 }, 530 { 531 {0, 0, 0}, // Reserved[3] 532 EFI_FLASH_AREA_FTW_STATE, // AreaType 533 { 0 }, // AreaTypeGuid 534 1, 535 { 536 { 537 EFI_FLASH_AREA_SUBFV | EFI_FLASH_AREA_MEMMAPPED_FV, // SubAreaData.Attributes 538 0, // SubAreaData.Reserved 539 0, // SubAreaData.Base (Fixed later) 540 NV_FTW_WORKING_SIZE, // SubAreaData.Length 541 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID // SubAreaData.FileSystem 542 } 543 }, 544 0, // VolumeSignature 545 L"", 546 0, 547 0 548 } 549 }, 550 { // NV Ftw spare Hob 551 { 552 { 553 EFI_HOB_TYPE_GUID_EXTENSION, // Hob type 554 sizeof (FVB_HOB), // Hob size 555 0 // reserved 556 }, 557 EFI_FLASH_MAP_HOB_GUID 558 }, 559 { 560 {0, 0, 0}, // Reserved[3] 561 EFI_FLASH_AREA_FTW_BACKUP, // AreaType 562 { 0 }, // AreaTypeGuid 563 1, 564 { 565 { 566 EFI_FLASH_AREA_SUBFV | EFI_FLASH_AREA_MEMMAPPED_FV, // SubAreaData.Attributes 567 0, // SubAreaData.Reserved 568 0, // SubAreaData.Base (Fixed later) 569 NV_FTW_SPARE_SIZE, // SubAreaData.Length 570 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID // SubAreaData.FileSystem 571 } 572 }, 573 0, 574 L"", 575 0, 576 0 577 } 578 }, 579 { // EndOfHobList 580 EFI_HOB_TYPE_END_OF_HOB_LIST, // HobType 581 sizeof (EFI_HOB_GENERIC_HEADER), // HobLength 582 0 // Reserved 583 } 584 }; 585 586 HOB_TEMPLATE *gHob = &gHobTemplate; 587 588 VOID * 589 PrepareHobMemory ( 590 IN UINTN NumberOfMemoryMapEntries, 591 IN EFI_MEMORY_DESCRIPTOR *EfiMemoryDescriptor 592 ) 593 /*++ 594 Description: 595 Update the Hob filling MemoryFreeUnder1MB, MemoryAbove1MB, MemoryAbove4GB 596 597 Arguments: 598 NumberOfMemoryMapEntries - Count of Memory Descriptors 599 EfiMemoryDescriptor - Point to the buffer containing NumberOfMemoryMapEntries Memory Descriptors 600 601 Return: 602 VOID * : The end address of MemoryAbove1MB (or the top free memory under 4GB) 603 --*/ 604 { 605 UINTN Index; 606 UINT64 EbdaAddress; 607 608 // 609 // Prepare Low Memory 610 // 0x18 pages is 72 KB. 611 // 612 EbdaAddress = ((UINT64)(*(UINT16 *)(UINTN)(EBDA_VALUE_ADDRESS))) << 4; 613 if (EbdaAddress < 0x9A000 || EbdaAddress > EFI_MEMORY_BELOW_1MB_END) { 614 // 615 // EBDA should not go below 0x9A000 in any implementation, 616 // so add check here to make sure EBDA_VALUE_ADDRESS has a valid value. 617 // 618 EbdaAddress = EFI_MEMORY_BELOW_1MB_END; 619 } 620 gHob->MemoryFreeUnder1MB.ResourceLength = EbdaAddress - EFI_MEMORY_BELOW_1MB_START; 621 gHob->MemoryFreeUnder1MB.PhysicalStart = EFI_MEMORY_BELOW_1MB_START; 622 623 // 624 // Prepare High Memory 625 // Assume Memory Map is ordered from low to high 626 // 627 gHob->MemoryAbove1MB.PhysicalStart = 0; 628 gHob->MemoryAbove1MB.ResourceLength = 0; 629 gHob->MemoryAbove4GB.PhysicalStart = 0; 630 gHob->MemoryAbove4GB.ResourceLength = 0; 631 632 for (Index = 0; Index < NumberOfMemoryMapEntries; Index++) { 633 // 634 // Skip regions below 1MB 635 // 636 if (EfiMemoryDescriptor[Index].PhysicalStart < 0x100000) { 637 continue; 638 } 639 // 640 // Process regions above 1MB 641 // 642 if (EfiMemoryDescriptor[Index].PhysicalStart >= 0x100000) { 643 if (EfiMemoryDescriptor[Index].Type == EfiConventionalMemory) { 644 if (gHob->MemoryAbove1MB.PhysicalStart == 0) { 645 gHob->MemoryAbove1MB.PhysicalStart = EfiMemoryDescriptor[Index].PhysicalStart; 646 gHob->MemoryAbove1MB.ResourceLength = LShiftU64 (EfiMemoryDescriptor[Index].NumberOfPages, EFI_PAGE_SHIFT); 647 } else if (gHob->MemoryAbove1MB.PhysicalStart + gHob->MemoryAbove1MB.ResourceLength == EfiMemoryDescriptor[Index].PhysicalStart) { 648 gHob->MemoryAbove1MB.ResourceLength += LShiftU64 (EfiMemoryDescriptor[Index].NumberOfPages, EFI_PAGE_SHIFT); 649 } 650 } 651 if ((EfiMemoryDescriptor[Index].Type == EfiReservedMemoryType) || 652 (EfiMemoryDescriptor[Index].Type >= EfiACPIReclaimMemory) ) { 653 continue; 654 } 655 if ((EfiMemoryDescriptor[Index].Type == EfiRuntimeServicesCode) || 656 (EfiMemoryDescriptor[Index].Type == EfiRuntimeServicesData)) { 657 break; 658 } 659 } 660 // 661 // Process region above 4GB 662 // 663 if (EfiMemoryDescriptor[Index].PhysicalStart >= 0x100000000LL) { 664 if (EfiMemoryDescriptor[Index].Type == EfiConventionalMemory) { 665 if (gHob->MemoryAbove4GB.PhysicalStart == 0) { 666 gHob->MemoryAbove4GB.PhysicalStart = EfiMemoryDescriptor[Index].PhysicalStart; 667 gHob->MemoryAbove4GB.ResourceLength = LShiftU64 (EfiMemoryDescriptor[Index].NumberOfPages, EFI_PAGE_SHIFT); 668 } 669 if (gHob->MemoryAbove4GB.PhysicalStart + gHob->MemoryAbove4GB.ResourceLength == 670 EfiMemoryDescriptor[Index].PhysicalStart) { 671 gHob->MemoryAbove4GB.ResourceLength += LShiftU64 (EfiMemoryDescriptor[Index].NumberOfPages, EFI_PAGE_SHIFT); 672 } 673 } 674 } 675 } 676 677 if (gHob->MemoryAbove4GB.ResourceLength == 0) { 678 // 679 // If there is no memory above 4GB then change the resource descriptor HOB 680 // into another type. I'm doing this as it's unclear if a resource 681 // descriptor HOB of length zero is valid. Spec does not say it's illegal, 682 // but code in EDK does not seem to handle this case. 683 // 684 gHob->MemoryAbove4GB.Header.HobType = EFI_HOB_TYPE_UNUSED; 685 } 686 687 return (VOID *)(UINTN)(gHob->MemoryAbove1MB.PhysicalStart + gHob->MemoryAbove1MB.ResourceLength); 688 } 689 690 VOID * 691 PrepareHobStack ( 692 IN VOID *StackTop 693 ) 694 { 695 gHob->Stack.AllocDescriptor.MemoryLength = EFI_MEMORY_STACK_PAGE_NUM * EFI_PAGE_SIZE; 696 gHob->Stack.AllocDescriptor.MemoryBaseAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)StackTop - gHob->Stack.AllocDescriptor.MemoryLength; 697 698 return (VOID *)(UINTN)gHob->Stack.AllocDescriptor.MemoryBaseAddress; 699 } 700 701 VOID * 702 PrepareHobMemoryDescriptor ( 703 VOID *MemoryDescriptorTop, 704 UINTN MemDescCount, 705 EFI_MEMORY_DESCRIPTOR *MemDesc 706 ) 707 { 708 gHob->MemoryDescriptor.MemDescCount = MemDescCount; 709 gHob->MemoryDescriptor.MemDesc = (EFI_MEMORY_DESCRIPTOR *)((UINTN)MemoryDescriptorTop - MemDescCount * sizeof(EFI_MEMORY_DESCRIPTOR)); 710 // 711 // Make MemoryDescriptor.MemDesc page aligned 712 // 713 gHob->MemoryDescriptor.MemDesc = (EFI_MEMORY_DESCRIPTOR *)((UINTN) gHob->MemoryDescriptor.MemDesc & ~EFI_PAGE_MASK); 714 715 CopyMem (gHob->MemoryDescriptor.MemDesc, MemDesc, MemDescCount * sizeof(EFI_MEMORY_DESCRIPTOR)); 716 717 return gHob->MemoryDescriptor.MemDesc; 718 } 719 720 VOID 721 PrepareHobBfv ( 722 VOID *Bfv, 723 UINTN BfvLength 724 ) 725 { 726 //UINTN BfvLengthPageSize; 727 728 // 729 // Calculate BFV location at top of the memory region. 730 // This is like a RAM Disk. Align to page boundary. 731 // 732 //BfvLengthPageSize = EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (BfvLength)); 733 734 gHob->Bfv.BaseAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Bfv; 735 gHob->Bfv.Length = BfvLength; 736 737 // 738 // Resource descriptor for the FV 739 // 740 gHob->BfvResource.PhysicalStart = gHob->Bfv.BaseAddress; 741 gHob->BfvResource.ResourceLength = gHob->Bfv.Length; 742 } 743 744 VOID 745 PrepareHobDxeCore ( 746 VOID *DxeCoreEntryPoint, 747 EFI_PHYSICAL_ADDRESS DxeCoreImageBase, 748 UINT64 DxeCoreLength 749 ) 750 { 751 gHob->DxeCore.MemoryAllocationHeader.MemoryBaseAddress = DxeCoreImageBase; 752 gHob->DxeCore.MemoryAllocationHeader.MemoryLength = DxeCoreLength; 753 gHob->DxeCore.EntryPoint = (EFI_PHYSICAL_ADDRESS)(UINTN)DxeCoreEntryPoint; 754 755 756 gHob->MemoryDxeCore.PhysicalStart = DxeCoreImageBase; 757 gHob->MemoryDxeCore.ResourceLength = DxeCoreLength; 758 } 759 760 VOID * 761 PrepareHobNvStorage ( 762 VOID *NvStorageTop 763 ) 764 /* 765 Initialize Block-Aligned Firmware Block. 766 767 Variable: 768 +-------------------+ 769 | FV_Header | 770 +-------------------+ 771 | | 772 |VAR_STORAGE(0x4000)| 773 | | 774 +-------------------+ 775 FTW: 776 +-------------------+ 777 | FV_Header | 778 +-------------------+ 779 | | 780 | Working(0x2000) | 781 | | 782 +-------------------+ 783 | | 784 | Spare(0x10000) | 785 | | 786 +-------------------+ 787 */ 788 { 789 STATIC VARIABLE_STORE_HEADER VarStoreHeader = { 790 VARIABLE_STORE_SIGNATURE, 791 0xffffffff, // will be fixed in Variable driver 792 VARIABLE_STORE_FORMATTED, 793 VARIABLE_STORE_HEALTHY, 794 0, 795 0 796 }; 797 798 STATIC EFI_FIRMWARE_VOLUME_HEADER NvStorageFvbHeader = { 799 { 800 0, 801 }, // ZeroVector[16] 802 EFI_SYSTEM_NV_DATA_FV_GUID, 803 NV_STORAGE_FVB_SIZE, 804 EFI_FVH_SIGNATURE, 805 EFI_FVB_READ_ENABLED_CAP | 806 EFI_FVB_READ_STATUS | 807 EFI_FVB_WRITE_ENABLED_CAP | 808 EFI_FVB_WRITE_STATUS | 809 EFI_FVB_ERASE_POLARITY, 810 EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH, 811 0, // CheckSum 812 0, // ExtHeaderOffset 813 { 814 0, 815 }, // Reserved[1] 816 1, // Revision 817 { 818 { 819 NV_STORAGE_FVB_BLOCK_NUM, 820 FV_BLOCK_SIZE, 821 } 822 } 823 }; 824 825 STATIC EFI_FV_BLOCK_MAP_ENTRY BlockMapEntryEnd = {0, 0}; 826 827 EFI_PHYSICAL_ADDRESS StorageFvbBase; 828 EFI_PHYSICAL_ADDRESS FtwFvbBase; 829 830 UINT16 *Ptr; 831 UINT16 Checksum; 832 833 834 // 835 // Use first 16-byte Reset Vector of FVB to store extra information 836 // UINT32 Offset 0 stores the volume signature 837 // UINT8 Offset 4 : should init the Variable Store Header if non-zero 838 // 839 gHob->NvStorageFvb.FvbInfo.VolumeId = *(UINT32 *) (UINTN) (NV_STORAGE_STATE); 840 gHob->NvStorage. FvbInfo.VolumeId = *(UINT32 *) (UINTN) (NV_STORAGE_STATE); 841 842 // 843 // *(NV_STORAGE_STATE + 4): 844 // 2 - Size error 845 // 1 - File not exist 846 // 0 - File exist with correct size 847 // 848 if (*(UINT8 *) (UINTN) (NV_STORAGE_STATE + 4) == 2) { 849 ClearScreen (); 850 PrintString ("Error: Size of Efivar.bin should be 16k!\n"); 851 CpuDeadLoop(); 852 } 853 854 if (*(UINT8 *) (UINTN) (NV_STORAGE_STATE + 4) != 0) { 855 // 856 // Efivar.bin doesn't exist 857 // 1. Init variable storage header to valid header 858 // 859 CopyMem ( 860 (VOID *) (UINTN) NV_STORAGE_START, 861 &VarStoreHeader, 862 sizeof (VARIABLE_STORE_HEADER) 863 ); 864 // 865 // 2. set all bits in variable storage body to 1 866 // 867 SetMem ( 868 (VOID *) (UINTN) (NV_STORAGE_START + sizeof (VARIABLE_STORE_HEADER)), 869 NV_STORAGE_SIZE - sizeof (VARIABLE_STORE_HEADER), 870 0xff 871 ); 872 } 873 874 // 875 // Relocate variable storage 876 // 877 // 1. Init FVB Header to valid header: First 0x48 bytes 878 // In real platform, these fields are fixed by tools 879 // 880 // 881 Checksum = 0; 882 for ( 883 Ptr = (UINT16 *) &NvStorageFvbHeader; 884 Ptr < (UINT16 *) ((UINTN) (UINT8 *) &NvStorageFvbHeader + sizeof (EFI_FIRMWARE_VOLUME_HEADER)); 885 ++Ptr 886 ) { 887 Checksum = (UINT16) (Checksum + (*Ptr)); 888 } 889 NvStorageFvbHeader.Checksum = (UINT16) (0x10000 - Checksum); 890 StorageFvbBase = (EFI_PHYSICAL_ADDRESS)(((UINTN)NvStorageTop - NV_STORAGE_FVB_SIZE - NV_FTW_FVB_SIZE) & ~EFI_PAGE_MASK); 891 CopyMem ((VOID *) (UINTN) StorageFvbBase, &NvStorageFvbHeader, sizeof (EFI_FIRMWARE_VOLUME_HEADER)); 892 CopyMem ( 893 (VOID *) (UINTN) (StorageFvbBase + sizeof (EFI_FIRMWARE_VOLUME_HEADER)), 894 &BlockMapEntryEnd, 895 sizeof (EFI_FV_BLOCK_MAP_ENTRY) 896 ); 897 898 // 899 // 2. Relocate variable data 900 // 901 CopyMem ( 902 (VOID *) (UINTN) (StorageFvbBase + EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH), 903 (VOID *) (UINTN) NV_STORAGE_START, 904 NV_STORAGE_SIZE 905 ); 906 907 // 908 // 3. Set the remaining memory to 0xff 909 // 910 SetMem ( 911 (VOID *) (UINTN) (StorageFvbBase + EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH + NV_STORAGE_SIZE), 912 NV_STORAGE_FVB_SIZE - NV_STORAGE_SIZE - EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH, 913 0xff 914 ); 915 916 // 917 // Create the FVB holding NV Storage in memory 918 // 919 gHob->NvStorageFvResource.PhysicalStart = 920 gHob->NvStorageFvb.FvbInfo.Entries[0].Base = StorageFvbBase; 921 // 922 // Create the NV Storage Hob 923 // 924 gHob->NvStorage.FvbInfo.Entries[0].Base = StorageFvbBase + EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH; 925 926 // 927 // Create the FVB holding FTW spaces 928 // 929 FtwFvbBase = (EFI_PHYSICAL_ADDRESS)((UINTN) StorageFvbBase + NV_STORAGE_FVB_SIZE); 930 gHob->NvFtwFvResource.PhysicalStart = 931 gHob->NvFtwFvb.FvbInfo.Entries[0].Base = FtwFvbBase; 932 // 933 // Put FTW Working in front 934 // 935 gHob->NvFtwWorking.FvbInfo.Entries[0].Base = FtwFvbBase + EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH; 936 937 // 938 // Put FTW Spare area after FTW Working area 939 // 940 gHob->NvFtwSpare.FvbInfo.Entries[0].Base = 941 (EFI_PHYSICAL_ADDRESS)((UINTN) FtwFvbBase + EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH + NV_FTW_WORKING_SIZE); 942 943 return (VOID *)(UINTN)StorageFvbBase; 944 } 945 946 VOID 947 PrepareHobPhit ( 948 VOID *MemoryTop, 949 VOID *FreeMemoryTop 950 ) 951 { 952 gHob->Phit.EfiMemoryTop = (EFI_PHYSICAL_ADDRESS)(UINTN)MemoryTop; 953 gHob->Phit.EfiMemoryBottom = gHob->Phit.EfiMemoryTop - CONSUMED_MEMORY; 954 gHob->Phit.EfiFreeMemoryTop = (EFI_PHYSICAL_ADDRESS)(UINTN)FreeMemoryTop; 955 gHob->Phit.EfiFreeMemoryBottom = gHob->Phit.EfiMemoryBottom + sizeof(HOB_TEMPLATE); 956 957 CopyMem ((VOID *)(UINTN)gHob->Phit.EfiMemoryBottom, gHob, sizeof(HOB_TEMPLATE)); 958 gHob = (HOB_TEMPLATE *)(UINTN)gHob->Phit.EfiMemoryBottom; 959 960 gHob->Phit.EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS)(UINTN)&gHob->EndOfHobList; 961 } 962 963 VOID 964 PrepareHobCpu ( 965 VOID 966 ) 967 { 968 UINT32 CpuidEax; 969 970 // 971 // Create a CPU hand-off information 972 // 973 gHob->Cpu.SizeOfMemorySpace = 36; 974 975 AsmCpuid (EFI_CPUID_EXTENDED_FUNCTION, &CpuidEax, NULL, NULL, NULL); 976 if (CpuidEax >= CPUID_EXTENDED_ADD_SIZE) { 977 AsmCpuid (CPUID_EXTENDED_ADD_SIZE, &CpuidEax, NULL, NULL, NULL); 978 gHob->Cpu.SizeOfMemorySpace = (UINT8)(CpuidEax & 0xFF); 979 } 980 } 981 982 VOID 983 CompleteHobGeneration ( 984 VOID 985 ) 986 { 987 gHob->MemoryAllocation.AllocDescriptor.MemoryBaseAddress = gHob->Phit.EfiFreeMemoryTop; 988 // 989 // Reserve all the memory under Stack above FreeMemoryTop as allocated 990 // 991 gHob->MemoryAllocation.AllocDescriptor.MemoryLength = gHob->Stack.AllocDescriptor.MemoryBaseAddress - gHob->Phit.EfiFreeMemoryTop; 992 993 // 994 // adjust Above1MB ResourceLength 995 // 996 if (gHob->MemoryAbove1MB.PhysicalStart + gHob->MemoryAbove1MB.ResourceLength > gHob->Phit.EfiMemoryTop) { 997 gHob->MemoryAbove1MB.ResourceLength = gHob->Phit.EfiMemoryTop - gHob->MemoryAbove1MB.PhysicalStart; 998 } 999 } 1000 1001