/** @file | |
Creates HOB during Standalone MM Foundation entry point | |
on ARM platforms. | |
Copyright (c) 2017 - 2018, ARM Ltd. All rights reserved.<BR> | |
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. | |
**/ | |
#include <PiMm.h> | |
#include <PiPei.h> | |
#include <Guid/MmramMemoryReserve.h> | |
#include <Guid/MpInformation.h> | |
#include <Library/AArch64/StandaloneMmCoreEntryPoint.h> | |
#include <Library/ArmMmuLib.h> | |
#include <Library/ArmSvcLib.h> | |
#include <Library/DebugLib.h> | |
#include <Library/HobLib.h> | |
#include <Library/BaseLib.h> | |
#include <Library/BaseMemoryLib.h> | |
#include <Library/SerialPortLib.h> | |
#include <IndustryStandard/ArmStdSmc.h> | |
extern EFI_HOB_HANDOFF_INFO_TABLE* | |
HobConstructor ( | |
IN VOID *EfiMemoryBegin, | |
IN UINTN EfiMemoryLength, | |
IN VOID *EfiFreeMemoryBottom, | |
IN VOID *EfiFreeMemoryTop | |
); | |
// GUID to identify HOB with whereabouts of communication buffer with Normal | |
// World | |
extern EFI_GUID gEfiStandaloneMmNonSecureBufferGuid; | |
// GUID to identify HOB where the entry point of the CPU driver will be | |
// populated to allow this entry point driver to invoke it upon receipt of an | |
// event | |
extern EFI_GUID gEfiArmTfCpuDriverEpDescriptorGuid; | |
/** | |
Use the boot information passed by privileged firmware to populate a HOB list | |
suitable for consumption by the MM Core and drivers. | |
@param PayloadBootInfo Boot information passed by privileged firmware | |
**/ | |
VOID * | |
CreateHobListFromBootInfo ( | |
IN OUT PI_MM_ARM_TF_CPU_DRIVER_ENTRYPOINT *CpuDriverEntryPoint, | |
IN EFI_SECURE_PARTITION_BOOT_INFO *PayloadBootInfo | |
) | |
{ | |
EFI_HOB_HANDOFF_INFO_TABLE *HobStart; | |
EFI_RESOURCE_ATTRIBUTE_TYPE Attributes; | |
UINT32 Index; | |
UINT32 BufferSize; | |
UINT32 Flags; | |
EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *MmramRangesHob; | |
EFI_MMRAM_DESCRIPTOR *MmramRanges; | |
EFI_MMRAM_DESCRIPTOR *NsCommBufMmramRange; | |
MP_INFORMATION_HOB_DATA *MpInformationHobData; | |
EFI_PROCESSOR_INFORMATION *ProcInfoBuffer; | |
EFI_SECURE_PARTITION_CPU_INFO *CpuInfo; | |
ARM_TF_CPU_DRIVER_EP_DESCRIPTOR *CpuDriverEntryPointDesc; | |
// Create a hoblist with a PHIT and EOH | |
HobStart = HobConstructor ( | |
(VOID *) PayloadBootInfo->SpMemBase, | |
(UINTN) PayloadBootInfo->SpMemLimit - PayloadBootInfo->SpMemBase, | |
(VOID *) PayloadBootInfo->SpHeapBase, | |
(VOID *) (PayloadBootInfo->SpHeapBase + PayloadBootInfo->SpHeapSize) | |
); | |
// Check that the Hoblist starts at the bottom of the Heap | |
ASSERT (HobStart == (VOID *) PayloadBootInfo->SpHeapBase); | |
// Build a Boot Firmware Volume HOB | |
BuildFvHob (PayloadBootInfo->SpImageBase, PayloadBootInfo->SpImageSize); | |
// Build a resource descriptor Hob that describes the available physical | |
// memory range | |
Attributes = ( | |
EFI_RESOURCE_ATTRIBUTE_PRESENT | | |
EFI_RESOURCE_ATTRIBUTE_INITIALIZED | | |
EFI_RESOURCE_ATTRIBUTE_TESTED | | |
EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | | |
EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | | |
EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | | |
EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE | |
); | |
BuildResourceDescriptorHob ( | |
EFI_RESOURCE_SYSTEM_MEMORY, | |
Attributes, | |
(UINTN) PayloadBootInfo->SpMemBase, | |
PayloadBootInfo->SpMemLimit - PayloadBootInfo->SpMemBase | |
); | |
// Find the size of the GUIDed HOB with MP information | |
BufferSize = sizeof (MP_INFORMATION_HOB_DATA); | |
BufferSize += sizeof (EFI_PROCESSOR_INFORMATION) * PayloadBootInfo->NumCpus; | |
// Create a Guided MP information HOB to enable the ARM TF CPU driver to | |
// perform per-cpu allocations. | |
MpInformationHobData = BuildGuidHob (&gMpInformationHobGuid, BufferSize); | |
// Populate the MP information HOB with the topology information passed by | |
// privileged firmware | |
MpInformationHobData->NumberOfProcessors = PayloadBootInfo->NumCpus; | |
MpInformationHobData->NumberOfEnabledProcessors = PayloadBootInfo->NumCpus; | |
ProcInfoBuffer = MpInformationHobData->ProcessorInfoBuffer; | |
CpuInfo = PayloadBootInfo->CpuInfo; | |
for (Index = 0; Index < PayloadBootInfo->NumCpus; Index++) { | |
ProcInfoBuffer[Index].ProcessorId = CpuInfo[Index].Mpidr; | |
ProcInfoBuffer[Index].Location.Package = GET_CLUSTER_ID(CpuInfo[Index].Mpidr); | |
ProcInfoBuffer[Index].Location.Core = GET_CORE_ID(CpuInfo[Index].Mpidr); | |
ProcInfoBuffer[Index].Location.Thread = GET_CORE_ID(CpuInfo[Index].Mpidr); | |
Flags = PROCESSOR_ENABLED_BIT | PROCESSOR_HEALTH_STATUS_BIT; | |
if (CpuInfo[Index].Flags & CPU_INFO_FLAG_PRIMARY_CPU) { | |
Flags |= PROCESSOR_AS_BSP_BIT; | |
} | |
ProcInfoBuffer[Index].StatusFlag = Flags; | |
} | |
// Create a Guided HOB to tell the ARM TF CPU driver the location and length | |
// of the communication buffer shared with the Normal world. | |
NsCommBufMmramRange = (EFI_MMRAM_DESCRIPTOR *) BuildGuidHob ( | |
&gEfiStandaloneMmNonSecureBufferGuid, | |
sizeof (EFI_MMRAM_DESCRIPTOR) | |
); | |
NsCommBufMmramRange->PhysicalStart = PayloadBootInfo->SpNsCommBufBase; | |
NsCommBufMmramRange->CpuStart = PayloadBootInfo->SpNsCommBufBase; | |
NsCommBufMmramRange->PhysicalSize = PayloadBootInfo->SpNsCommBufSize; | |
NsCommBufMmramRange->RegionState = EFI_CACHEABLE | EFI_ALLOCATED; | |
// Create a Guided HOB to enable the ARM TF CPU driver to share its entry | |
// point and populate it with the address of the shared buffer | |
CpuDriverEntryPointDesc = (ARM_TF_CPU_DRIVER_EP_DESCRIPTOR *) BuildGuidHob ( | |
&gEfiArmTfCpuDriverEpDescriptorGuid, | |
sizeof (ARM_TF_CPU_DRIVER_EP_DESCRIPTOR) | |
); | |
*CpuDriverEntryPoint = NULL; | |
CpuDriverEntryPointDesc->ArmTfCpuDriverEpPtr = CpuDriverEntryPoint; | |
// Find the size of the GUIDed HOB with SRAM ranges | |
BufferSize = sizeof (EFI_MMRAM_HOB_DESCRIPTOR_BLOCK); | |
BufferSize += PayloadBootInfo->NumSpMemRegions * sizeof (EFI_MMRAM_DESCRIPTOR); | |
// Create a GUIDed HOB with SRAM ranges | |
MmramRangesHob = BuildGuidHob (&gEfiMmPeiMmramMemoryReserveGuid, BufferSize); | |
// Fill up the number of MMRAM memory regions | |
MmramRangesHob->NumberOfMmReservedRegions = PayloadBootInfo->NumSpMemRegions; | |
// Fill up the MMRAM ranges | |
MmramRanges = &MmramRangesHob->Descriptor[0]; | |
// Base and size of memory occupied by the Standalone MM image | |
MmramRanges[0].PhysicalStart = PayloadBootInfo->SpImageBase; | |
MmramRanges[0].CpuStart = PayloadBootInfo->SpImageBase; | |
MmramRanges[0].PhysicalSize = PayloadBootInfo->SpImageSize; | |
MmramRanges[0].RegionState = EFI_CACHEABLE | EFI_ALLOCATED; | |
// Base and size of buffer shared with privileged Secure world software | |
MmramRanges[1].PhysicalStart = PayloadBootInfo->SpSharedBufBase; | |
MmramRanges[1].CpuStart = PayloadBootInfo->SpSharedBufBase; | |
MmramRanges[1].PhysicalSize = PayloadBootInfo->SpPcpuSharedBufSize * PayloadBootInfo->NumCpus; | |
MmramRanges[1].RegionState = EFI_CACHEABLE | EFI_ALLOCATED; | |
// Base and size of buffer used for synchronous communication with Normal | |
// world software | |
MmramRanges[2].PhysicalStart = PayloadBootInfo->SpNsCommBufBase; | |
MmramRanges[2].CpuStart = PayloadBootInfo->SpNsCommBufBase; | |
MmramRanges[2].PhysicalSize = PayloadBootInfo->SpNsCommBufSize; | |
MmramRanges[2].RegionState = EFI_CACHEABLE | EFI_ALLOCATED; | |
// Base and size of memory allocated for stacks for all cpus | |
MmramRanges[3].PhysicalStart = PayloadBootInfo->SpStackBase; | |
MmramRanges[3].CpuStart = PayloadBootInfo->SpStackBase; | |
MmramRanges[3].PhysicalSize = PayloadBootInfo->SpPcpuStackSize * PayloadBootInfo->NumCpus; | |
MmramRanges[3].RegionState = EFI_CACHEABLE | EFI_ALLOCATED; | |
// Base and size of heap memory shared by all cpus | |
MmramRanges[4].PhysicalStart = (EFI_PHYSICAL_ADDRESS) HobStart; | |
MmramRanges[4].CpuStart = (EFI_PHYSICAL_ADDRESS) HobStart; | |
MmramRanges[4].PhysicalSize = HobStart->EfiFreeMemoryBottom - (EFI_PHYSICAL_ADDRESS) HobStart; | |
MmramRanges[4].RegionState = EFI_CACHEABLE | EFI_ALLOCATED; | |
// Base and size of heap memory shared by all cpus | |
MmramRanges[5].PhysicalStart = HobStart->EfiFreeMemoryBottom; | |
MmramRanges[5].CpuStart = HobStart->EfiFreeMemoryBottom; | |
MmramRanges[5].PhysicalSize = HobStart->EfiFreeMemoryTop - HobStart->EfiFreeMemoryBottom; | |
MmramRanges[5].RegionState = EFI_CACHEABLE; | |
return HobStart; | |
} |