hobgeneration.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 526 行 · 第 1/2 页
C
526 行
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,
}
},
{ // 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
)
{
UINTN Index;
EFI_PHYSICAL_ADDRESS PhysicalEnd;
//
// 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;
PhysicalEnd = 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 (PhysicalEnd == EfiMemoryDescriptor[Index].PhysicalStart) {
gHob->MemoryAbove1MB.ResourceLength += LShiftU64 (EfiMemoryDescriptor[Index].NumberOfPages, EFI_PAGE_SHIFT);
}
PhysicalEnd = EfiMemoryDescriptor[Index].PhysicalStart + \
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 >= 0x100000000) {
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));
EfiCommonLibCopyMem (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)DxeCoreEntryPoint;
gHob->DxeCore.MemoryAllocationHeader.MemoryLength = DxeCoreLength;
gHob->DxeCore.EntryPoint = (EFI_PHYSICAL_ADDRESS)(UINTN)DxeCoreEntryPoint;
}
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);
EfiCommonLibCopyMem ((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
CompleteHobGeneration (
VOID
)
{
gHob->MemoryAllocation.AllocDescriptor.MemoryBaseAddress = gHob->Phit.EfiFreeMemoryTop;
gHob->MemoryAllocation.AllocDescriptor.MemoryLength = gHob->Phit.EfiMemoryTop - 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;
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?