2. move VariableFormat.h into GUID directory and change the “Signature” field of the VARIABLE_STORE_HEADER to gEfiVariableGuid value. 3. merging VARIABLE_INFO_ENTRY structure into the new Include/Guid/VariableFormat.h 4. change gEfiVariableInfoGuid into gEfiVariableGuid. 5. modify FDF files to use new guid value instead of the original signature. 6. all code related to signature is changed to use guid value. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@7728 6f19259b-4bc3-4df7-8a09-765794883524
954 lines
31 KiB
C
954 lines
31 KiB
C
/** @file
|
|
|
|
Copyright (c) 2006 - 2007, Intel Corporation
|
|
All rights reserved. This program and the accompanying materials
|
|
are licensed and made available under the terms and conditions of the BSD License
|
|
which accompanies this distribution. The full text of the license may be found at
|
|
http://opensource.org/licenses/bsd-license.php
|
|
|
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
|
|
Module Name:
|
|
HobGeneration.c
|
|
|
|
Abstract:
|
|
|
|
Revision History:
|
|
|
|
**/
|
|
#include "DxeIpl.h"
|
|
#include "HobGeneration.h"
|
|
#include "PpisNeededByDxeCore.h"
|
|
#include "FlashLayout.h"
|
|
#include "Debug.h"
|
|
|
|
#define EFI_DXE_FILE_GUID \
|
|
{ 0xb1644c1a, 0xc16a, 0x4c5b, {0x88, 0xde, 0xea, 0xfb, 0xa9, 0x7e, 0x74, 0xd8 }}
|
|
|
|
#define CPUID_EXTENDED_ADD_SIZE 0x80000008
|
|
|
|
HOB_TEMPLATE gHobTemplate = {
|
|
{ // Phit
|
|
{ // Header
|
|
EFI_HOB_TYPE_HANDOFF, // HobType
|
|
sizeof (EFI_HOB_HANDOFF_INFO_TABLE), // HobLength
|
|
0 // Reserved
|
|
},
|
|
EFI_HOB_HANDOFF_TABLE_VERSION, // Version
|
|
BOOT_WITH_FULL_CONFIGURATION, // BootMode
|
|
0, // EfiMemoryTop
|
|
0, // EfiMemoryBottom
|
|
0, // EfiFreeMemoryTop
|
|
0, // EfiFreeMemoryBottom
|
|
0 // EfiEndOfHobList
|
|
},
|
|
{ // Bfv
|
|
{
|
|
EFI_HOB_TYPE_FV, // HobType
|
|
sizeof (EFI_HOB_FIRMWARE_VOLUME), // HobLength
|
|
0 // Reserved
|
|
},
|
|
0, // BaseAddress
|
|
0 // Length
|
|
},
|
|
{ // BfvResource
|
|
{
|
|
EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, // HobType
|
|
sizeof (EFI_HOB_RESOURCE_DESCRIPTOR), // HobLength
|
|
0 // Reserved
|
|
},
|
|
{
|
|
0 // Owner Guid
|
|
},
|
|
EFI_RESOURCE_FIRMWARE_DEVICE, // ResourceType
|
|
(EFI_RESOURCE_ATTRIBUTE_PRESENT |
|
|
EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
|
|
EFI_RESOURCE_ATTRIBUTE_TESTED |
|
|
EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE), // ResourceAttribute
|
|
0, // PhysicalStart
|
|
0 // ResourceLength
|
|
},
|
|
{ // Cpu
|
|
{ // Header
|
|
EFI_HOB_TYPE_CPU, // HobType
|
|
sizeof (EFI_HOB_CPU), // HobLength
|
|
0 // Reserved
|
|
},
|
|
52, // SizeOfMemorySpace - Architecture Max
|
|
16, // SizeOfIoSpace,
|
|
{
|
|
0, 0, 0, 0, 0, 0 // Reserved[6]
|
|
}
|
|
},
|
|
{ // Stack HOB
|
|
{ // header
|
|
EFI_HOB_TYPE_MEMORY_ALLOCATION, // Hob type
|
|
sizeof (EFI_HOB_MEMORY_ALLOCATION_STACK), // Hob size
|
|
0 // reserved
|
|
},
|
|
{
|
|
EFI_HOB_MEMORY_ALLOC_STACK_GUID,
|
|
0x0, // EFI_PHYSICAL_ADDRESS MemoryBaseAddress;
|
|
0x0, // UINT64 MemoryLength;
|
|
EfiBootServicesData, // EFI_MEMORY_TYPE MemoryType;
|
|
{0, 0, 0, 0} // Reserved Reserved[4];
|
|
}
|
|
},
|
|
{ // MemoryAllocation for HOB's & Images
|
|
{
|
|
EFI_HOB_TYPE_MEMORY_ALLOCATION, // HobType
|
|
sizeof (EFI_HOB_MEMORY_ALLOCATION), // HobLength
|
|
0 // Reserved
|
|
},
|
|
{
|
|
{
|
|
0, //EFI_HOB_MEMORY_ALLOC_MODULE_GUID // Name
|
|
},
|
|
0x0, // EFI_PHYSICAL_ADDRESS MemoryBaseAddress;
|
|
0x0, // UINT64 MemoryLength;
|
|
EfiBootServicesData, // EFI_MEMORY_TYPE MemoryType;
|
|
{
|
|
0, 0, 0, 0 // Reserved Reserved[4];
|
|
}
|
|
}
|
|
},
|
|
{ // MemoryFreeUnder1MB for unused memory that DXE core will claim
|
|
{
|
|
EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, // HobType
|
|
sizeof (EFI_HOB_RESOURCE_DESCRIPTOR), // HobLength
|
|
0 // Reserved
|
|
},
|
|
{
|
|
0 // Owner Guid
|
|
},
|
|
EFI_RESOURCE_SYSTEM_MEMORY, // ResourceType
|
|
(EFI_RESOURCE_ATTRIBUTE_PRESENT |
|
|
EFI_RESOURCE_ATTRIBUTE_TESTED |
|
|
EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
|
|
EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
|
|
EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
|
|
EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
|
|
EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE),
|
|
0x0, // PhysicalStart
|
|
0 // ResourceLength
|
|
},
|
|
{ // MemoryFreeAbove1MB for unused memory that DXE core will claim
|
|
{
|
|
EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, // HobType
|
|
sizeof (EFI_HOB_RESOURCE_DESCRIPTOR), // HobLength
|
|
0 // Reserved
|
|
},
|
|
{
|
|
0 // Owner Guid
|
|
},
|
|
EFI_RESOURCE_SYSTEM_MEMORY, // ResourceType
|
|
(EFI_RESOURCE_ATTRIBUTE_PRESENT |
|
|
EFI_RESOURCE_ATTRIBUTE_TESTED |
|
|
EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
|
|
EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
|
|
EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
|
|
EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
|
|
EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE),
|
|
0x0, // PhysicalStart
|
|
0 // ResourceLength
|
|
},
|
|
{ // MemoryFreeAbove4GB for unused memory that DXE core will claim
|
|
{
|
|
EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, // HobType
|
|
sizeof (EFI_HOB_RESOURCE_DESCRIPTOR), // HobLength
|
|
0 // Reserved
|
|
},
|
|
{
|
|
0 // Owner Guid
|
|
},
|
|
EFI_RESOURCE_SYSTEM_MEMORY, // ResourceType
|
|
(EFI_RESOURCE_ATTRIBUTE_PRESENT |
|
|
EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
|
|
EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
|
|
EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
|
|
EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
|
|
EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE),
|
|
0x0, // PhysicalStart
|
|
0 // ResourceLength
|
|
},
|
|
{ // Memory Allocation Module for DxeCore
|
|
{ // header
|
|
EFI_HOB_TYPE_MEMORY_ALLOCATION, // Hob type
|
|
sizeof (EFI_HOB_MEMORY_ALLOCATION_MODULE), // Hob size
|
|
0 // reserved
|
|
},
|
|
{
|
|
EFI_HOB_MEMORY_ALLOC_MODULE_GUID,
|
|
0x0, // EFI_PHYSICAL_ADDRESS MemoryBaseAddress;
|
|
0x0, // UINT64 MemoryLength;
|
|
EfiBootServicesCode, // EFI_MEMORY_TYPE MemoryType;
|
|
{
|
|
0, 0, 0, 0 // UINT8 Reserved[4];
|
|
},
|
|
},
|
|
EFI_DXE_FILE_GUID,
|
|
0x0 // EFI_PHYSICAL_ADDRESS of EntryPoint;
|
|
},
|
|
{ // Memory Map Hints to reduce fragmentation in the memory map
|
|
{
|
|
{
|
|
EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
|
|
sizeof (MEMORY_TYPE_INFORMATION_HOB), // Hob size
|
|
0, // reserved
|
|
},
|
|
EFI_MEMORY_TYPE_INFORMATION_GUID
|
|
},
|
|
{
|
|
{
|
|
EfiACPIReclaimMemory,
|
|
0x80
|
|
}, // 0x80 pages = 512k for ASL
|
|
{
|
|
EfiACPIMemoryNVS,
|
|
0x100
|
|
}, // 0x100 pages = 1024k for S3, SMM, etc
|
|
{
|
|
EfiReservedMemoryType,
|
|
0x04
|
|
}, // 16k for BIOS Reserved
|
|
{
|
|
EfiRuntimeServicesData,
|
|
0x100
|
|
},
|
|
{
|
|
EfiRuntimeServicesCode,
|
|
0x100
|
|
},
|
|
{
|
|
EfiBootServicesCode,
|
|
0x200
|
|
},
|
|
{
|
|
EfiBootServicesData,
|
|
0x200
|
|
},
|
|
{
|
|
EfiLoaderCode,
|
|
0x100
|
|
},
|
|
{
|
|
EfiLoaderData,
|
|
0x100
|
|
},
|
|
{
|
|
EfiMaxMemoryType,
|
|
0
|
|
}
|
|
}
|
|
},
|
|
{ // Pointer to ACPI Table
|
|
{
|
|
{
|
|
EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
|
|
sizeof (TABLE_HOB), // Hob size
|
|
0 // reserved
|
|
},
|
|
EFI_ACPI_TABLE_GUID
|
|
},
|
|
0
|
|
},
|
|
{ // Pointer to ACPI20 Table
|
|
{
|
|
{
|
|
EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
|
|
sizeof (TABLE_HOB), // Hob size
|
|
0 // reserved
|
|
},
|
|
EFI_ACPI_20_TABLE_GUID
|
|
},
|
|
0
|
|
},
|
|
{ // Pointer to SMBIOS Table
|
|
{
|
|
{
|
|
EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
|
|
sizeof (TABLE_HOB), // Hob size
|
|
0 // reserved
|
|
},
|
|
EFI_SMBIOS_TABLE_GUID
|
|
},
|
|
0
|
|
},
|
|
{ // Pointer to MPS Table
|
|
{
|
|
{
|
|
EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
|
|
sizeof (TABLE_HOB), // Hob size
|
|
0, // reserved
|
|
},
|
|
EFI_MPS_TABLE_GUID
|
|
},
|
|
0
|
|
},
|
|
/**
|
|
{ // Pointer to FlushInstructionCache
|
|
EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
|
|
sizeof (PROTOCOL_HOB), // Hob size
|
|
0, // reserved
|
|
EFI_PEI_FLUSH_INSTRUCTION_CACHE_GUID,
|
|
NULL
|
|
},
|
|
{ // Pointer to TransferControl
|
|
EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
|
|
sizeof (PROTOCOL_HOB), // Hob size
|
|
0, // reserved
|
|
EFI_PEI_TRANSFER_CONTROL_GUID,
|
|
NULL
|
|
},
|
|
{ // Pointer to PeCoffLoader
|
|
EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
|
|
sizeof (PROTOCOL_HOB), // Hob size
|
|
0, // reserved
|
|
EFI_PEI_PE_COFF_LOADER_GUID,
|
|
NULL
|
|
},
|
|
{ // Pointer to EfiDecompress
|
|
EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
|
|
sizeof (PROTOCOL_HOB), // Hob size
|
|
0, // reserved
|
|
EFI_DECOMPRESS_PROTOCOL_GUID,
|
|
NULL
|
|
},
|
|
{ // Pointer to TianoDecompress
|
|
EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
|
|
sizeof (PROTOCOL_HOB), // Hob size
|
|
0, // reserved
|
|
EFI_TIANO_DECOMPRESS_PROTOCOL_GUID,
|
|
NULL
|
|
},
|
|
**/
|
|
{ // Pointer to ReportStatusCode
|
|
{
|
|
{
|
|
EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
|
|
sizeof (PROTOCOL_HOB), // Hob size
|
|
0 // reserved
|
|
},
|
|
EFI_STATUS_CODE_RUNTIME_PROTOCOL_GUID
|
|
},
|
|
NULL
|
|
},
|
|
{ // EFILDR Memory Descriptor
|
|
{
|
|
{
|
|
EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
|
|
sizeof (MEMORY_DESC_HOB), // Hob size
|
|
0 // reserved
|
|
},
|
|
EFI_LDR_MEMORY_DESCRIPTOR_GUID
|
|
},
|
|
0,
|
|
NULL
|
|
},
|
|
{ // Pci Express Base Address Hob
|
|
{
|
|
{
|
|
EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
|
|
sizeof (PCI_EXPRESS_BASE_HOB), // Hob size
|
|
0 // reserved
|
|
},
|
|
EFI_PCI_EXPRESS_BASE_ADDRESS_GUID
|
|
},
|
|
{
|
|
0,
|
|
0,
|
|
0,
|
|
}
|
|
},
|
|
{ // Acpi Description Hob
|
|
{
|
|
{
|
|
EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
|
|
sizeof (ACPI_DESCRIPTION_HOB), // Hob size
|
|
0 // reserved
|
|
},
|
|
EFI_ACPI_DESCRIPTION_GUID
|
|
},
|
|
{
|
|
{
|
|
0,
|
|
},
|
|
}
|
|
},
|
|
{ // NV Storage FV Resource
|
|
{
|
|
EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, // HobType
|
|
sizeof (EFI_HOB_RESOURCE_DESCRIPTOR), // HobLength
|
|
0 // Reserved
|
|
},
|
|
{
|
|
0 // Owner Guid
|
|
},
|
|
EFI_RESOURCE_FIRMWARE_DEVICE, // ResourceType
|
|
(EFI_RESOURCE_ATTRIBUTE_PRESENT |
|
|
EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
|
|
EFI_RESOURCE_ATTRIBUTE_TESTED |
|
|
EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE), // ResourceAttribute
|
|
0, // PhysicalStart (Fixed later)
|
|
NV_STORAGE_FVB_SIZE // ResourceLength
|
|
},
|
|
{ // FVB holding NV Storage
|
|
{
|
|
{
|
|
EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
|
|
sizeof (FVB_HOB),
|
|
0
|
|
},
|
|
EFI_FLASH_MAP_HOB_GUID
|
|
},
|
|
{
|
|
{0, 0, 0}, // Reserved[3]
|
|
EFI_FLASH_AREA_GUID_DEFINED, // AreaType
|
|
EFI_SYSTEM_NV_DATA_FV_GUID , // AreaTypeGuid
|
|
1,
|
|
{
|
|
{
|
|
EFI_FLASH_AREA_FV | EFI_FLASH_AREA_MEMMAPPED_FV, // SubAreaData.Attributes
|
|
0, // SubAreaData.Reserved
|
|
0, // SubAreaData.Base (Fixed later)
|
|
NV_STORAGE_FVB_SIZE, // SubAreaData.Length
|
|
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID // SubAreaData.FileSystem
|
|
}
|
|
},
|
|
0, // VolumeSignature (Fixed later)
|
|
NV_STORAGE_FILE_PATH, // Mapped file without padding
|
|
// TotalFVBSize = FileSize + PaddingSize = multiple of BLOCK_SIZE
|
|
NV_STORAGE_SIZE + EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH,
|
|
// ActuralSize
|
|
EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH
|
|
}
|
|
},
|
|
{ // NV Storage Hob
|
|
{
|
|
{
|
|
EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
|
|
sizeof (FVB_HOB), // Hob size
|
|
0 // reserved
|
|
},
|
|
EFI_FLASH_MAP_HOB_GUID
|
|
},
|
|
{
|
|
{0, 0, 0}, // Reserved[3]
|
|
EFI_FLASH_AREA_EFI_VARIABLES, // AreaType
|
|
{ 0 }, // AreaTypeGuid
|
|
1,
|
|
{
|
|
{
|
|
EFI_FLASH_AREA_SUBFV | EFI_FLASH_AREA_MEMMAPPED_FV, // SubAreaData.Attributes
|
|
0, // SubAreaData.Reserved
|
|
0, // SubAreaData.Base (Fixed later)
|
|
NV_STORAGE_SIZE, // SubAreaData.Length
|
|
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID // SubAreaData.FileSystem
|
|
}
|
|
},
|
|
0,
|
|
NV_STORAGE_FILE_PATH,
|
|
NV_STORAGE_SIZE,
|
|
0
|
|
}
|
|
},
|
|
{ // FVB holding FTW spaces including Working & Spare space
|
|
{
|
|
{
|
|
EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
|
|
sizeof (FVB_HOB),
|
|
0
|
|
},
|
|
EFI_FLASH_MAP_HOB_GUID
|
|
},
|
|
{
|
|
{0, 0, 0}, // Reserved[3]
|
|
EFI_FLASH_AREA_GUID_DEFINED, // AreaType
|
|
EFI_SYSTEM_NV_DATA_FV_GUID, // AreaTypeGuid
|
|
1,
|
|
{
|
|
{
|
|
EFI_FLASH_AREA_FV | EFI_FLASH_AREA_MEMMAPPED_FV, // SubAreaData.Attributes
|
|
0, // SubAreaData.Reserved
|
|
0, // SubAreaData.Base (Fixed later)
|
|
NV_FTW_FVB_SIZE, // SubAreaData.Length
|
|
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID // SubAreaData.FileSystem
|
|
}
|
|
},
|
|
0,
|
|
L"", // Empty String indicates using memory
|
|
0,
|
|
0
|
|
}
|
|
},
|
|
{ // NV Ftw working Hob
|
|
{
|
|
{
|
|
EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
|
|
sizeof (FVB_HOB), // Hob size
|
|
0 // reserved
|
|
},
|
|
EFI_FLASH_MAP_HOB_GUID
|
|
},
|
|
{
|
|
{0, 0, 0}, // Reserved[3]
|
|
EFI_FLASH_AREA_FTW_STATE, // AreaType
|
|
{ 0 }, // AreaTypeGuid
|
|
1,
|
|
{
|
|
{
|
|
EFI_FLASH_AREA_SUBFV | EFI_FLASH_AREA_MEMMAPPED_FV, // SubAreaData.Attributes
|
|
0, // SubAreaData.Reserved
|
|
0, // SubAreaData.Base (Fixed later)
|
|
NV_FTW_WORKING_SIZE, // SubAreaData.Length
|
|
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID // SubAreaData.FileSystem
|
|
}
|
|
},
|
|
0, // VolumeSignature
|
|
L"",
|
|
0,
|
|
0
|
|
}
|
|
},
|
|
{ // NV Ftw spare Hob
|
|
{
|
|
{
|
|
EFI_HOB_TYPE_GUID_EXTENSION, // Hob type
|
|
sizeof (FVB_HOB), // Hob size
|
|
0 // reserved
|
|
},
|
|
EFI_FLASH_MAP_HOB_GUID
|
|
},
|
|
{
|
|
{0, 0, 0}, // Reserved[3]
|
|
EFI_FLASH_AREA_FTW_BACKUP, // AreaType
|
|
{ 0 }, // AreaTypeGuid
|
|
1,
|
|
{
|
|
{
|
|
EFI_FLASH_AREA_SUBFV | EFI_FLASH_AREA_MEMMAPPED_FV, // SubAreaData.Attributes
|
|
0, // SubAreaData.Reserved
|
|
0, // SubAreaData.Base (Fixed later)
|
|
NV_FTW_SPARE_SIZE, // SubAreaData.Length
|
|
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID // SubAreaData.FileSystem
|
|
}
|
|
},
|
|
0,
|
|
L"",
|
|
0,
|
|
0
|
|
}
|
|
},
|
|
{ // EndOfHobList
|
|
EFI_HOB_TYPE_END_OF_HOB_LIST, // HobType
|
|
sizeof (EFI_HOB_GENERIC_HEADER), // HobLength
|
|
0 // Reserved
|
|
}
|
|
};
|
|
|
|
HOB_TEMPLATE *gHob = &gHobTemplate;
|
|
|
|
VOID *
|
|
PrepareHobMemory (
|
|
IN UINTN NumberOfMemoryMapEntries,
|
|
IN EFI_MEMORY_DESCRIPTOR *EfiMemoryDescriptor
|
|
)
|
|
/*++
|
|
Description:
|
|
Update the Hob filling MemoryFreeUnder1MB, MemoryAbove1MB, MemoryAbove4GB
|
|
|
|
Arguments:
|
|
NumberOfMemoryMapEntries - Count of Memory Descriptors
|
|
EfiMemoryDescriptor - Point to the buffer containing NumberOfMemoryMapEntries Memory Descriptors
|
|
|
|
Return:
|
|
VOID * : The end address of MemoryAbove1MB (or the top free memory under 4GB)
|
|
--*/
|
|
{
|
|
UINTN Index;
|
|
|
|
//
|
|
// Prepare Low Memory
|
|
// 0x18 pages is 72 KB.
|
|
//
|
|
gHob->MemoryFreeUnder1MB.ResourceLength = EFI_MEMORY_BELOW_1MB_END - EFI_MEMORY_BELOW_1MB_START;
|
|
gHob->MemoryFreeUnder1MB.PhysicalStart = EFI_MEMORY_BELOW_1MB_START;
|
|
|
|
//
|
|
// Prepare High Memory
|
|
// Assume Memory Map is ordered from low to high
|
|
//
|
|
gHob->MemoryAbove1MB.PhysicalStart = 0;
|
|
gHob->MemoryAbove1MB.ResourceLength = 0;
|
|
gHob->MemoryAbove4GB.PhysicalStart = 0;
|
|
gHob->MemoryAbove4GB.ResourceLength = 0;
|
|
|
|
for (Index = 0; Index < NumberOfMemoryMapEntries; Index++) {
|
|
//
|
|
// Skip regions below 1MB
|
|
//
|
|
if (EfiMemoryDescriptor[Index].PhysicalStart < 0x100000) {
|
|
continue;
|
|
}
|
|
//
|
|
// Process regions above 1MB
|
|
//
|
|
if (EfiMemoryDescriptor[Index].PhysicalStart >= 0x100000) {
|
|
if (EfiMemoryDescriptor[Index].Type == EfiConventionalMemory) {
|
|
if (gHob->MemoryAbove1MB.PhysicalStart == 0) {
|
|
gHob->MemoryAbove1MB.PhysicalStart = EfiMemoryDescriptor[Index].PhysicalStart;
|
|
gHob->MemoryAbove1MB.ResourceLength = LShiftU64 (EfiMemoryDescriptor[Index].NumberOfPages, EFI_PAGE_SHIFT);
|
|
} else if (gHob->MemoryAbove1MB.PhysicalStart + gHob->MemoryAbove1MB.ResourceLength == EfiMemoryDescriptor[Index].PhysicalStart) {
|
|
gHob->MemoryAbove1MB.ResourceLength += LShiftU64 (EfiMemoryDescriptor[Index].NumberOfPages, EFI_PAGE_SHIFT);
|
|
}
|
|
}
|
|
if ((EfiMemoryDescriptor[Index].Type == EfiReservedMemoryType) ||
|
|
(EfiMemoryDescriptor[Index].Type >= EfiACPIReclaimMemory) ) {
|
|
continue;
|
|
}
|
|
if ((EfiMemoryDescriptor[Index].Type == EfiRuntimeServicesCode) ||
|
|
(EfiMemoryDescriptor[Index].Type == EfiRuntimeServicesData)) {
|
|
break;
|
|
}
|
|
}
|
|
//
|
|
// Process region above 4GB
|
|
//
|
|
if (EfiMemoryDescriptor[Index].PhysicalStart >= 0x100000000LL) {
|
|
if (EfiMemoryDescriptor[Index].Type == EfiConventionalMemory) {
|
|
if (gHob->MemoryAbove4GB.PhysicalStart == 0) {
|
|
gHob->MemoryAbove4GB.PhysicalStart = EfiMemoryDescriptor[Index].PhysicalStart;
|
|
gHob->MemoryAbove4GB.ResourceLength = LShiftU64 (EfiMemoryDescriptor[Index].NumberOfPages, EFI_PAGE_SHIFT);
|
|
}
|
|
if (gHob->MemoryAbove4GB.PhysicalStart + gHob->MemoryAbove4GB.ResourceLength ==
|
|
EfiMemoryDescriptor[Index].PhysicalStart) {
|
|
gHob->MemoryAbove4GB.ResourceLength += LShiftU64 (EfiMemoryDescriptor[Index].NumberOfPages, EFI_PAGE_SHIFT);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (gHob->MemoryAbove4GB.ResourceLength == 0) {
|
|
//
|
|
// If there is no memory above 4GB then change the resource descriptor HOB
|
|
// into another type. I'm doing this as it's unclear if a resource
|
|
// descriptor HOB of length zero is valid. Spec does not say it's illegal,
|
|
// but code in EDK does not seem to handle this case.
|
|
//
|
|
gHob->MemoryAbove4GB.Header.HobType = EFI_HOB_TYPE_UNUSED;
|
|
}
|
|
|
|
return (VOID *)(UINTN)(gHob->MemoryAbove1MB.PhysicalStart + gHob->MemoryAbove1MB.ResourceLength);
|
|
}
|
|
|
|
VOID *
|
|
PrepareHobStack (
|
|
IN VOID *StackTop
|
|
)
|
|
{
|
|
gHob->Stack.AllocDescriptor.MemoryLength = EFI_MEMORY_STACK_PAGE_NUM * EFI_PAGE_SIZE;
|
|
gHob->Stack.AllocDescriptor.MemoryBaseAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)StackTop - gHob->Stack.AllocDescriptor.MemoryLength;
|
|
|
|
return (VOID *)(UINTN)gHob->Stack.AllocDescriptor.MemoryBaseAddress;
|
|
}
|
|
|
|
VOID *
|
|
PrepareHobMemoryDescriptor (
|
|
VOID *MemoryDescriptorTop,
|
|
UINTN MemDescCount,
|
|
EFI_MEMORY_DESCRIPTOR *MemDesc
|
|
)
|
|
{
|
|
gHob->MemoryDescriptor.MemDescCount = MemDescCount;
|
|
gHob->MemoryDescriptor.MemDesc = (EFI_MEMORY_DESCRIPTOR *)((UINTN)MemoryDescriptorTop - MemDescCount * sizeof(EFI_MEMORY_DESCRIPTOR));
|
|
//
|
|
// Make MemoryDescriptor.MemDesc page aligned
|
|
//
|
|
gHob->MemoryDescriptor.MemDesc = (EFI_MEMORY_DESCRIPTOR *)((UINTN) gHob->MemoryDescriptor.MemDesc & ~EFI_PAGE_MASK);
|
|
|
|
CopyMem (gHob->MemoryDescriptor.MemDesc, MemDesc, MemDescCount * sizeof(EFI_MEMORY_DESCRIPTOR));
|
|
|
|
return gHob->MemoryDescriptor.MemDesc;
|
|
}
|
|
|
|
VOID
|
|
PrepareHobBfv (
|
|
VOID *Bfv,
|
|
UINTN BfvLength
|
|
)
|
|
{
|
|
//UINTN BfvLengthPageSize;
|
|
|
|
//
|
|
// Calculate BFV location at top of the memory region.
|
|
// This is like a RAM Disk. Align to page boundry.
|
|
//
|
|
//BfvLengthPageSize = EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (BfvLength));
|
|
|
|
gHob->Bfv.BaseAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Bfv;
|
|
gHob->Bfv.Length = BfvLength;
|
|
|
|
//
|
|
// Resource descriptor for the FV
|
|
//
|
|
gHob->BfvResource.PhysicalStart = gHob->Bfv.BaseAddress;
|
|
gHob->BfvResource.ResourceLength = gHob->Bfv.Length;
|
|
}
|
|
|
|
VOID
|
|
PrepareHobDxeCore (
|
|
VOID *DxeCoreEntryPoint,
|
|
EFI_PHYSICAL_ADDRESS DxeCoreImageBase,
|
|
UINT64 DxeCoreLength
|
|
)
|
|
{
|
|
gHob->DxeCore.MemoryAllocationHeader.MemoryBaseAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)DxeCoreImageBase;
|
|
gHob->DxeCore.MemoryAllocationHeader.MemoryLength = DxeCoreLength;
|
|
gHob->DxeCore.EntryPoint = (EFI_PHYSICAL_ADDRESS)(UINTN)DxeCoreEntryPoint;
|
|
}
|
|
|
|
VOID *
|
|
PrepareHobNvStorage (
|
|
VOID *NvStorageTop
|
|
)
|
|
/*
|
|
Initialize Block-Aligned Firmware Block.
|
|
|
|
Variable:
|
|
+-------------------+
|
|
| FV_Header |
|
|
+-------------------+
|
|
| |
|
|
|VAR_STORAGE(0x4000)|
|
|
| |
|
|
+-------------------+
|
|
FTW:
|
|
+-------------------+
|
|
| FV_Header |
|
|
+-------------------+
|
|
| |
|
|
| Working(0x2000) |
|
|
| |
|
|
+-------------------+
|
|
| |
|
|
| Spare(0x10000) |
|
|
| |
|
|
+-------------------+
|
|
*/
|
|
{
|
|
STATIC VARIABLE_STORE_HEADER VarStoreHeader = {
|
|
gEfiVariableGuid,
|
|
0xffffffff, // will be fixed in Variable driver
|
|
VARIABLE_STORE_FORMATTED,
|
|
VARIABLE_STORE_HEALTHY,
|
|
0,
|
|
0
|
|
};
|
|
|
|
STATIC EFI_FIRMWARE_VOLUME_HEADER NvStorageFvbHeader = {
|
|
{
|
|
0,
|
|
}, // ZeroVector[16]
|
|
EFI_SYSTEM_NV_DATA_FV_GUID,
|
|
NV_STORAGE_FVB_SIZE,
|
|
EFI_FVH_SIGNATURE,
|
|
EFI_FVB_READ_ENABLED_CAP |
|
|
EFI_FVB_READ_STATUS |
|
|
EFI_FVB_WRITE_ENABLED_CAP |
|
|
EFI_FVB_WRITE_STATUS |
|
|
EFI_FVB_ERASE_POLARITY,
|
|
EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH,
|
|
0, // CheckSum
|
|
0, // ExtHeaderOffset
|
|
{
|
|
0,
|
|
}, // Reserved[1]
|
|
1, // Revision
|
|
{
|
|
{
|
|
NV_STORAGE_FVB_BLOCK_NUM,
|
|
FV_BLOCK_SIZE,
|
|
}
|
|
}
|
|
};
|
|
|
|
STATIC EFI_FV_BLOCK_MAP_ENTRY BlockMapEntryEnd = {0, 0};
|
|
|
|
EFI_PHYSICAL_ADDRESS StorageFvbBase;
|
|
EFI_PHYSICAL_ADDRESS FtwFvbBase;
|
|
|
|
UINT16 *Ptr;
|
|
UINT16 Checksum;
|
|
|
|
|
|
//
|
|
// Use first 16-byte Reset Vector of FVB to store extra information
|
|
// UINT32 Offset 0 stores the volume signature
|
|
// UINT8 Offset 4 : should init the Variable Store Header if non-zero
|
|
//
|
|
gHob->NvStorageFvb.FvbInfo.VolumeId = *(UINT32 *) (UINTN) (NV_STORAGE_STATE);
|
|
gHob->NvStorage. FvbInfo.VolumeId = *(UINT32 *) (UINTN) (NV_STORAGE_STATE);
|
|
|
|
//
|
|
// *(NV_STORAGE_STATE + 4):
|
|
// 2 - Size error
|
|
// 1 - File not exist
|
|
// 0 - File exist with correct size
|
|
//
|
|
if (*(UINT8 *) (UINTN) (NV_STORAGE_STATE + 4) == 2) {
|
|
ClearScreen ();
|
|
PrintString ("Error: Size of Efivar.bin should be 16k!\n");
|
|
CpuDeadLoop();
|
|
}
|
|
|
|
if (*(UINT8 *) (UINTN) (NV_STORAGE_STATE + 4) != 0) {
|
|
//
|
|
// Efivar.bin doesn't exist
|
|
// 1. Init variable storage header to valid header
|
|
//
|
|
CopyMem (
|
|
(VOID *) (UINTN) NV_STORAGE_START,
|
|
&VarStoreHeader,
|
|
sizeof (VARIABLE_STORE_HEADER)
|
|
);
|
|
//
|
|
// 2. set all bits in variable storage body to 1
|
|
//
|
|
SetMem (
|
|
(VOID *) (UINTN) (NV_STORAGE_START + sizeof (VARIABLE_STORE_HEADER)),
|
|
NV_STORAGE_SIZE - sizeof (VARIABLE_STORE_HEADER),
|
|
0xff
|
|
);
|
|
}
|
|
|
|
//
|
|
// Relocate variable storage
|
|
//
|
|
// 1. Init FVB Header to valid header: First 0x48 bytes
|
|
// In real platform, these fields are fixed by tools
|
|
//
|
|
//
|
|
Checksum = 0;
|
|
for (
|
|
Ptr = (UINT16 *) &NvStorageFvbHeader;
|
|
Ptr < (UINT16 *) ((UINTN) (UINT8 *) &NvStorageFvbHeader + sizeof (EFI_FIRMWARE_VOLUME_HEADER));
|
|
++Ptr
|
|
) {
|
|
Checksum = (UINT16) (Checksum + (*Ptr));
|
|
}
|
|
NvStorageFvbHeader.Checksum = (UINT16) (0x10000 - Checksum);
|
|
StorageFvbBase = (EFI_PHYSICAL_ADDRESS)(((UINTN)NvStorageTop - NV_STORAGE_FVB_SIZE - NV_FTW_FVB_SIZE) & ~EFI_PAGE_MASK);
|
|
CopyMem ((VOID *) (UINTN) StorageFvbBase, &NvStorageFvbHeader, sizeof (EFI_FIRMWARE_VOLUME_HEADER));
|
|
CopyMem (
|
|
(VOID *) (UINTN) (StorageFvbBase + sizeof (EFI_FIRMWARE_VOLUME_HEADER)),
|
|
&BlockMapEntryEnd,
|
|
sizeof (EFI_FV_BLOCK_MAP_ENTRY)
|
|
);
|
|
|
|
//
|
|
// 2. Relocate variable data
|
|
//
|
|
CopyMem (
|
|
(VOID *) (UINTN) (StorageFvbBase + EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH),
|
|
(VOID *) (UINTN) NV_STORAGE_START,
|
|
NV_STORAGE_SIZE
|
|
);
|
|
|
|
//
|
|
// 3. Set the remaining memory to 0xff
|
|
//
|
|
SetMem (
|
|
(VOID *) (UINTN) (StorageFvbBase + EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH + NV_STORAGE_SIZE),
|
|
NV_STORAGE_FVB_SIZE - NV_STORAGE_SIZE - EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH,
|
|
0xff
|
|
);
|
|
|
|
//
|
|
// Create the FVB holding NV Storage in memory
|
|
//
|
|
gHob->NvStorageFvResource.PhysicalStart =
|
|
gHob->NvStorageFvb.FvbInfo.Entries[0].Base = StorageFvbBase;
|
|
//
|
|
// Create the NV Storage Hob
|
|
//
|
|
gHob->NvStorage.FvbInfo.Entries[0].Base = StorageFvbBase + EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH;
|
|
|
|
//
|
|
// Create the FVB holding FTW spaces
|
|
//
|
|
FtwFvbBase = (EFI_PHYSICAL_ADDRESS)((UINTN) StorageFvbBase + NV_STORAGE_FVB_SIZE);
|
|
gHob->NvFtwFvb.FvbInfo.Entries[0].Base = FtwFvbBase;
|
|
//
|
|
// Put FTW Working in front
|
|
//
|
|
gHob->NvFtwWorking.FvbInfo.Entries[0].Base = FtwFvbBase + EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH;
|
|
|
|
//
|
|
// Put FTW Spare area after FTW Working area
|
|
//
|
|
gHob->NvFtwSpare.FvbInfo.Entries[0].Base =
|
|
(EFI_PHYSICAL_ADDRESS)((UINTN) FtwFvbBase + EFI_RUNTIME_UPDATABLE_FV_HEADER_LENGTH + NV_FTW_WORKING_SIZE);
|
|
|
|
return (VOID *)(UINTN)StorageFvbBase;
|
|
}
|
|
|
|
VOID
|
|
PrepareHobPhit (
|
|
VOID *MemoryTop,
|
|
VOID *FreeMemoryTop
|
|
)
|
|
{
|
|
gHob->Phit.EfiMemoryTop = (EFI_PHYSICAL_ADDRESS)(UINTN)MemoryTop;
|
|
gHob->Phit.EfiMemoryBottom = gHob->Phit.EfiMemoryTop - CONSUMED_MEMORY;
|
|
gHob->Phit.EfiFreeMemoryTop = (EFI_PHYSICAL_ADDRESS)(UINTN)FreeMemoryTop;
|
|
gHob->Phit.EfiFreeMemoryBottom = gHob->Phit.EfiMemoryBottom + sizeof(HOB_TEMPLATE);
|
|
|
|
CopyMem ((VOID *)(UINTN)gHob->Phit.EfiMemoryBottom, gHob, sizeof(HOB_TEMPLATE));
|
|
gHob = (HOB_TEMPLATE *)(UINTN)gHob->Phit.EfiMemoryBottom;
|
|
|
|
gHob->Phit.EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS)(UINTN)&gHob->EndOfHobList;
|
|
}
|
|
|
|
VOID
|
|
PrepareHobCpu (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_CPUID_REGISTER Reg;
|
|
UINT8 CpuMemoryAddrBitNumber;
|
|
|
|
//
|
|
// Create a CPU hand-off information
|
|
//
|
|
CpuMemoryAddrBitNumber = 36;
|
|
AsmCpuid (EFI_CPUID_EXTENDED_FUNCTION, &Reg.RegEax, &Reg.RegEbx, &Reg.RegEcx, &Reg.RegEdx);
|
|
|
|
if (Reg.RegEax >= CPUID_EXTENDED_ADD_SIZE) {
|
|
AsmCpuid (CPUID_EXTENDED_ADD_SIZE, &Reg.RegEax, &Reg.RegEbx, &Reg.RegEcx, &Reg.RegEdx);
|
|
CpuMemoryAddrBitNumber = (UINT8)(UINTN)(Reg.RegEax & 0xFF);
|
|
}
|
|
|
|
gHob->Cpu.SizeOfMemorySpace = CpuMemoryAddrBitNumber;
|
|
}
|
|
|
|
VOID
|
|
CompleteHobGeneration (
|
|
VOID
|
|
)
|
|
{
|
|
gHob->MemoryAllocation.AllocDescriptor.MemoryBaseAddress = gHob->Phit.EfiFreeMemoryTop;
|
|
//
|
|
// Reserve all the memory under Stack above FreeMemoryTop as allocated
|
|
//
|
|
gHob->MemoryAllocation.AllocDescriptor.MemoryLength = gHob->Stack.AllocDescriptor.MemoryBaseAddress - gHob->Phit.EfiFreeMemoryTop;
|
|
|
|
//
|
|
// adjust Above1MB ResourceLength
|
|
//
|
|
if (gHob->MemoryAbove1MB.PhysicalStart + gHob->MemoryAbove1MB.ResourceLength > gHob->Phit.EfiMemoryTop) {
|
|
gHob->MemoryAbove1MB.ResourceLength = gHob->Phit.EfiMemoryTop - gHob->MemoryAbove1MB.PhysicalStart;
|
|
}
|
|
}
|
|
|