| /** @file |
| HOB Library implementation for Standalone MM Core. |
| |
| Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR> |
| Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.<BR> |
| |
| SPDX-License-Identifier: BSD-2-Clause-Patent |
| |
| **/ |
| |
| #include <Guid/MemoryAllocationHob.h> |
| |
| #include <Library/BaseMemoryLib.h> |
| #include <Library/DebugLib.h> |
| #include <Library/HobLib.h> |
| |
| #include <PiMm.h> |
| |
| // |
| // Cache copy of HobList pointer. |
| // |
| VOID *gHobList = NULL; |
| |
| VOID * |
| CreateHob ( |
| IN UINT16 HobType, |
| IN UINT16 HobLength |
| ) |
| { |
| EFI_HOB_HANDOFF_INFO_TABLE *HandOffHob; |
| EFI_HOB_GENERIC_HEADER *HobEnd; |
| EFI_PHYSICAL_ADDRESS FreeMemory; |
| VOID *Hob; |
| |
| HandOffHob = GetHobList (); |
| |
| // |
| // Check Length to avoid data overflow. |
| // |
| if (HobLength > MAX_UINT16 - 0x7) { |
| return NULL; |
| } |
| |
| HobLength = (UINT16)((HobLength + 0x7) & (~0x7)); |
| |
| FreeMemory = HandOffHob->EfiFreeMemoryTop - HandOffHob->EfiFreeMemoryBottom; |
| |
| if (FreeMemory < HobLength) { |
| return NULL; |
| } |
| |
| Hob = (VOID *)(UINTN)HandOffHob->EfiEndOfHobList; |
| ((EFI_HOB_GENERIC_HEADER *)Hob)->HobType = HobType; |
| ((EFI_HOB_GENERIC_HEADER *)Hob)->HobLength = HobLength; |
| ((EFI_HOB_GENERIC_HEADER *)Hob)->Reserved = 0; |
| |
| HobEnd = (EFI_HOB_GENERIC_HEADER *)((UINTN)Hob + HobLength); |
| HandOffHob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS)(UINTN)HobEnd; |
| |
| HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST; |
| HobEnd->HobLength = sizeof (EFI_HOB_GENERIC_HEADER); |
| HobEnd->Reserved = 0; |
| HobEnd++; |
| HandOffHob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS)(UINTN)HobEnd; |
| |
| return Hob; |
| } |
| |
| /** |
| Builds a HOB for a loaded PE32 module. |
| |
| This function builds a HOB for a loaded PE32 module. |
| If ModuleName is NULL, then ASSERT(). |
| If there is no additional space for HOB creation, then ASSERT(). |
| |
| @param ModuleName The GUID File Name of the module. |
| @param MemoryAllocationModule The 64 bit physical address of the module. |
| @param ModuleLength The length of the module in bytes. |
| @param EntryPoint The 64 bit physical address of the module entry point. |
| |
| **/ |
| VOID |
| EFIAPI |
| BuildModuleHob ( |
| IN CONST EFI_GUID *ModuleName, |
| IN EFI_PHYSICAL_ADDRESS MemoryAllocationModule, |
| IN UINT64 ModuleLength, |
| IN EFI_PHYSICAL_ADDRESS EntryPoint |
| ) |
| { |
| EFI_HOB_MEMORY_ALLOCATION_MODULE *Hob; |
| |
| ASSERT ( |
| ((MemoryAllocationModule & (EFI_PAGE_SIZE - 1)) == 0) && |
| ((ModuleLength & (EFI_PAGE_SIZE - 1)) == 0) |
| ); |
| |
| Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_MODULE)); |
| ASSERT (Hob != NULL); |
| if (Hob == NULL) { |
| return; |
| } |
| |
| CopyGuid (&(Hob->MemoryAllocationHeader.Name), &gEfiHobMemoryAllocModuleGuid); |
| Hob->MemoryAllocationHeader.MemoryBaseAddress = MemoryAllocationModule; |
| Hob->MemoryAllocationHeader.MemoryLength = ModuleLength; |
| Hob->MemoryAllocationHeader.MemoryType = EfiBootServicesCode; |
| |
| // |
| // Zero the reserved space to match HOB spec |
| // |
| ZeroMem (Hob->MemoryAllocationHeader.Reserved, sizeof (Hob->MemoryAllocationHeader.Reserved)); |
| |
| CopyGuid (&Hob->ModuleName, ModuleName); |
| Hob->EntryPoint = EntryPoint; |
| } |
| |
| /** |
| Builds a HOB that describes a chunk of system memory. |
| |
| This function builds a HOB that describes a chunk of system memory. |
| If there is no additional space for HOB creation, then ASSERT(). |
| |
| @param ResourceType The type of resource described by this HOB. |
| @param ResourceAttribute The resource attributes of the memory described by this HOB. |
| @param PhysicalStart The 64 bit physical address of memory described by this HOB. |
| @param NumberOfBytes The length of the memory described by this HOB in bytes. |
| |
| **/ |
| VOID |
| EFIAPI |
| BuildResourceDescriptorHob ( |
| IN EFI_RESOURCE_TYPE ResourceType, |
| IN EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute, |
| IN EFI_PHYSICAL_ADDRESS PhysicalStart, |
| IN UINT64 NumberOfBytes |
| ) |
| { |
| EFI_HOB_RESOURCE_DESCRIPTOR *Hob; |
| |
| Hob = CreateHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, sizeof (EFI_HOB_RESOURCE_DESCRIPTOR)); |
| ASSERT (Hob != NULL); |
| if (Hob == NULL) { |
| return; |
| } |
| |
| Hob->ResourceType = ResourceType; |
| Hob->ResourceAttribute = ResourceAttribute; |
| Hob->PhysicalStart = PhysicalStart; |
| Hob->ResourceLength = NumberOfBytes; |
| } |
| |
| /** |
| Builds a GUID HOB with a certain data length. |
| |
| This function builds a customized HOB tagged with a GUID for identification |
| and returns the start address of GUID HOB data so that caller can fill the customized data. |
| The HOB Header and Name field is already stripped. |
| If Guid is NULL, then ASSERT(). |
| If there is no additional space for HOB creation, then ASSERT(). |
| If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT(). |
| |
| @param Guid The GUID to tag the customized HOB. |
| @param DataLength The size of the data payload for the GUID HOB. |
| |
| @return The start address of GUID HOB data. |
| |
| **/ |
| VOID * |
| EFIAPI |
| BuildGuidHob ( |
| IN CONST EFI_GUID *Guid, |
| IN UINTN DataLength |
| ) |
| { |
| EFI_HOB_GUID_TYPE *Hob; |
| |
| // |
| // Make sure that data length is not too long. |
| // |
| ASSERT (DataLength <= (0xffff - sizeof (EFI_HOB_GUID_TYPE))); |
| |
| Hob = CreateHob (EFI_HOB_TYPE_GUID_EXTENSION, (UINT16)(sizeof (EFI_HOB_GUID_TYPE) + DataLength)); |
| ASSERT (Hob != NULL); |
| if (Hob == NULL) { |
| return NULL; |
| } |
| |
| CopyGuid (&Hob->Name, Guid); |
| return Hob + 1; |
| } |
| |
| /** |
| Copies a data buffer to a newly-built HOB. |
| |
| This function builds a customized HOB tagged with a GUID for identification, |
| copies the input data to the HOB data field and returns the start address of the GUID HOB data. |
| The HOB Header and Name field is already stripped. |
| If Guid is NULL, then ASSERT(). |
| If Data is NULL and DataLength > 0, then ASSERT(). |
| If there is no additional space for HOB creation, then ASSERT(). |
| If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT(). |
| |
| @param Guid The GUID to tag the customized HOB. |
| @param Data The data to be copied into the data field of the GUID HOB. |
| @param DataLength The size of the data payload for the GUID HOB. |
| |
| @return The start address of GUID HOB data. |
| |
| **/ |
| VOID * |
| EFIAPI |
| BuildGuidDataHob ( |
| IN CONST EFI_GUID *Guid, |
| IN VOID *Data, |
| IN UINTN DataLength |
| ) |
| { |
| VOID *HobData; |
| |
| ASSERT (Data != NULL || DataLength == 0); |
| |
| HobData = BuildGuidHob (Guid, DataLength); |
| |
| return CopyMem (HobData, Data, DataLength); |
| } |
| |
| /** |
| Builds a Firmware Volume HOB. |
| |
| This function builds a Firmware Volume HOB. |
| If there is no additional space for HOB creation, then ASSERT(). |
| |
| @param BaseAddress The base address of the Firmware Volume. |
| @param Length The size of the Firmware Volume in bytes. |
| |
| **/ |
| VOID |
| EFIAPI |
| BuildFvHob ( |
| IN EFI_PHYSICAL_ADDRESS BaseAddress, |
| IN UINT64 Length |
| ) |
| { |
| EFI_HOB_FIRMWARE_VOLUME *Hob; |
| |
| Hob = CreateHob (EFI_HOB_TYPE_FV, sizeof (EFI_HOB_FIRMWARE_VOLUME)); |
| ASSERT (Hob != NULL); |
| if (Hob == NULL) { |
| return; |
| } |
| |
| Hob->BaseAddress = BaseAddress; |
| Hob->Length = Length; |
| } |
| |
| /** |
| Builds a EFI_HOB_TYPE_FV2 HOB. |
| |
| This function builds a EFI_HOB_TYPE_FV2 HOB. |
| If there is no additional space for HOB creation, then ASSERT(). |
| |
| @param BaseAddress The base address of the Firmware Volume. |
| @param Length The size of the Firmware Volume in bytes. |
| @param FvName The name of the Firmware Volume. |
| @param FileName The name of the file. |
| |
| **/ |
| VOID |
| EFIAPI |
| BuildFv2Hob ( |
| IN EFI_PHYSICAL_ADDRESS BaseAddress, |
| IN UINT64 Length, |
| IN CONST EFI_GUID *FvName, |
| IN CONST EFI_GUID *FileName |
| ) |
| { |
| EFI_HOB_FIRMWARE_VOLUME2 *Hob; |
| |
| Hob = CreateHob (EFI_HOB_TYPE_FV2, sizeof (EFI_HOB_FIRMWARE_VOLUME2)); |
| ASSERT (Hob != NULL); |
| if (Hob == NULL) { |
| return; |
| } |
| |
| Hob->BaseAddress = BaseAddress; |
| Hob->Length = Length; |
| CopyGuid (&Hob->FvName, FvName); |
| CopyGuid (&Hob->FileName, FileName); |
| } |
| |
| /** |
| Builds a HOB for the CPU. |
| |
| This function builds a HOB for the CPU. |
| If there is no additional space for HOB creation, then ASSERT(). |
| |
| @param SizeOfMemorySpace The maximum physical memory addressability of the processor. |
| @param SizeOfIoSpace The maximum physical I/O addressability of the processor. |
| |
| **/ |
| VOID |
| EFIAPI |
| BuildCpuHob ( |
| IN UINT8 SizeOfMemorySpace, |
| IN UINT8 SizeOfIoSpace |
| ) |
| { |
| EFI_HOB_CPU *Hob; |
| |
| Hob = CreateHob (EFI_HOB_TYPE_CPU, sizeof (EFI_HOB_CPU)); |
| ASSERT (Hob != NULL); |
| if (Hob == NULL) { |
| return; |
| } |
| |
| Hob->SizeOfMemorySpace = SizeOfMemorySpace; |
| Hob->SizeOfIoSpace = SizeOfIoSpace; |
| |
| // |
| // Zero the reserved space to match HOB spec |
| // |
| ZeroMem (Hob->Reserved, sizeof (Hob->Reserved)); |
| } |
| |
| /** |
| Builds a HOB for the memory allocation. |
| |
| This function builds a HOB for the memory allocation. |
| If there is no additional space for HOB creation, then ASSERT(). |
| |
| @param BaseAddress The 64 bit physical address of the memory. |
| @param Length The length of the memory allocation in bytes. |
| @param MemoryType Type of memory allocated by this HOB. |
| |
| **/ |
| VOID |
| EFIAPI |
| BuildMemoryAllocationHob ( |
| IN EFI_PHYSICAL_ADDRESS BaseAddress, |
| IN UINT64 Length, |
| IN EFI_MEMORY_TYPE MemoryType |
| ) |
| { |
| EFI_HOB_MEMORY_ALLOCATION *Hob; |
| |
| ASSERT ( |
| ((BaseAddress & (EFI_PAGE_SIZE - 1)) == 0) && |
| ((Length & (EFI_PAGE_SIZE - 1)) == 0) |
| ); |
| |
| Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION)); |
| ASSERT (Hob != NULL); |
| if (Hob == NULL) { |
| return; |
| } |
| |
| ZeroMem (&(Hob->AllocDescriptor.Name), sizeof (EFI_GUID)); |
| Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress; |
| Hob->AllocDescriptor.MemoryLength = Length; |
| Hob->AllocDescriptor.MemoryType = MemoryType; |
| // |
| // Zero the reserved space to match HOB spec |
| // |
| ZeroMem (Hob->AllocDescriptor.Reserved, sizeof (Hob->AllocDescriptor.Reserved)); |
| } |
| |