Home | History | Annotate | Download | only in DxeIpl
      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 boundry.
    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