X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=StandaloneMmPkg%2FLibrary%2FStandaloneMmCoreEntryPoint%2FAArch64%2FCreateHobList.c;fp=StandaloneMmPkg%2FLibrary%2FStandaloneMmCoreEntryPoint%2FAArch64%2FCreateHobList.c;h=b19c86268a9e201f211718c216f09b89701fa972;hp=0000000000000000000000000000000000000000;hb=184558d072dc8a76cb224205840605b512321e28;hpb=6b46d77243e02d23ce922803998e01277fe9f399 diff --git a/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/CreateHobList.c b/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/CreateHobList.c new file mode 100644 index 0000000000..b19c86268a --- /dev/null +++ b/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/CreateHobList.c @@ -0,0 +1,209 @@ +/** @file + Creates HOB during Standalone MM Foundation entry point + on ARM platforms. + +Copyright (c) 2017 - 2018, ARM Ltd. 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. + +**/ + + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +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; +}