summaryrefslogtreecommitdiffstats
path: root/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/CreateHobList.c
diff options
context:
space:
mode:
authorSupreeth Venkatesh <supreeth.venkatesh@arm.com>2018-07-13 23:05:28 +0800
committerJiewen Yao <jiewen.yao@intel.com>2018-07-20 10:59:40 +0800
commit184558d072dc8a76cb224205840605b512321e28 (patch)
tree090b7c3bc9004847610734348db25fb97dbffb73 /StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/CreateHobList.c
parent6b46d77243e02d23ce922803998e01277fe9f399 (diff)
downloadedk2-184558d072dc8a76cb224205840605b512321e28.tar.gz
edk2-184558d072dc8a76cb224205840605b512321e28.tar.bz2
edk2-184558d072dc8a76cb224205840605b512321e28.zip
StandaloneMmPkg: Add an AArch64 specific entry point library.
The Standalone MM environment runs in S-EL0 in AArch64 on ARM Standard Platforms and is initialised during the SEC phase. ARM Trusted firmware in EL3 is responsible for initialising the architectural context for S-EL0 and loading the Standalone MM image. The memory allocated to this image is marked as RO+X. Heap memory is marked as RW+XN. Certain actions have to be completed prior to executing the generic code in the Standalone MM Core module. These are: 1. Memory permission attributes for each section of the Standalone MM Core module need to be changed prior to accessing any RW data. 2. A Hob list has to be created with information that allows the MM environment to initialise and dispatch drivers. Furthermore, this module is responsible for handing over runtime MM events to the Standalone MM CPU driver and returning control to ARM Trusted Firmware upon event completion. Hence it needs to know the CPU driver entry point. This patch implements an entry point module that ARM Trusted Firmware jumps to in S-EL0. It then performs the above actions before calling the Standalone MM Foundation entry point and handling subsequent MM events. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Sughosh Ganu <sughosh.ganu@arm.com> Signed-off-by: Achin Gupta <achin.gupta@arm.com> Signed-off-by: Supreeth Venkatesh <supreeth.venkatesh@arm.com> Reviewed-by: Achin Gupta <achin.gupta@arm.com>
Diffstat (limited to 'StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/CreateHobList.c')
-rw-r--r--StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/CreateHobList.c209
1 files changed, 209 insertions, 0 deletions
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.<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;
+}