]> git.proxmox.com Git - mirror_edk2.git/blobdiff - StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/CreateHobList.c
StandaloneMmPkg: Add an AArch64 specific entry point library.
[mirror_edk2.git] / StandaloneMmPkg / Library / StandaloneMmCoreEntryPoint / AArch64 / CreateHobList.c
diff --git a/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/CreateHobList.c b/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/CreateHobList.c
new file mode 100644 (file)
index 0000000..b19c862
--- /dev/null
@@ -0,0 +1,209 @@
+/** @file\r
+  Creates HOB during Standalone MM Foundation entry point\r
+  on ARM platforms.\r
+\r
+Copyright (c) 2017 - 2018, ARM Ltd. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php.\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+\r
+#include <PiMm.h>\r
+\r
+#include <PiPei.h>\r
+#include <Guid/MmramMemoryReserve.h>\r
+#include <Guid/MpInformation.h>\r
+\r
+#include <Library/AArch64/StandaloneMmCoreEntryPoint.h>\r
+#include <Library/ArmMmuLib.h>\r
+#include <Library/ArmSvcLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/HobLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/SerialPortLib.h>\r
+\r
+#include <IndustryStandard/ArmStdSmc.h>\r
+\r
+extern EFI_HOB_HANDOFF_INFO_TABLE*\r
+HobConstructor (\r
+  IN VOID   *EfiMemoryBegin,\r
+  IN UINTN  EfiMemoryLength,\r
+  IN VOID   *EfiFreeMemoryBottom,\r
+  IN VOID   *EfiFreeMemoryTop\r
+  );\r
+\r
+// GUID to identify HOB with whereabouts of communication buffer with Normal\r
+// World\r
+extern EFI_GUID gEfiStandaloneMmNonSecureBufferGuid;\r
+\r
+// GUID to identify HOB where the entry point of the CPU driver will be\r
+// populated to allow this entry point driver to invoke it upon receipt of an\r
+// event\r
+extern EFI_GUID gEfiArmTfCpuDriverEpDescriptorGuid;\r
+\r
+/**\r
+  Use the boot information passed by privileged firmware to populate a HOB list\r
+  suitable for consumption by the MM Core and drivers.\r
+\r
+  @param  PayloadBootInfo    Boot information passed by privileged firmware\r
+\r
+**/\r
+VOID *\r
+CreateHobListFromBootInfo (\r
+  IN  OUT  PI_MM_ARM_TF_CPU_DRIVER_ENTRYPOINT *CpuDriverEntryPoint,\r
+  IN       EFI_SECURE_PARTITION_BOOT_INFO     *PayloadBootInfo\r
+)\r
+{\r
+  EFI_HOB_HANDOFF_INFO_TABLE      *HobStart;\r
+  EFI_RESOURCE_ATTRIBUTE_TYPE     Attributes;\r
+  UINT32                          Index;\r
+  UINT32                          BufferSize;\r
+  UINT32                          Flags;\r
+  EFI_MMRAM_HOB_DESCRIPTOR_BLOCK  *MmramRangesHob;\r
+  EFI_MMRAM_DESCRIPTOR            *MmramRanges;\r
+  EFI_MMRAM_DESCRIPTOR            *NsCommBufMmramRange;\r
+  MP_INFORMATION_HOB_DATA         *MpInformationHobData;\r
+  EFI_PROCESSOR_INFORMATION       *ProcInfoBuffer;\r
+  EFI_SECURE_PARTITION_CPU_INFO   *CpuInfo;\r
+  ARM_TF_CPU_DRIVER_EP_DESCRIPTOR *CpuDriverEntryPointDesc;\r
+\r
+  // Create a hoblist with a PHIT and EOH\r
+  HobStart = HobConstructor (\r
+               (VOID *) PayloadBootInfo->SpMemBase,\r
+               (UINTN)  PayloadBootInfo->SpMemLimit - PayloadBootInfo->SpMemBase,\r
+               (VOID *) PayloadBootInfo->SpHeapBase,\r
+               (VOID *) (PayloadBootInfo->SpHeapBase + PayloadBootInfo->SpHeapSize)\r
+               );\r
+\r
+  // Check that the Hoblist starts at the bottom of the Heap\r
+  ASSERT (HobStart == (VOID *) PayloadBootInfo->SpHeapBase);\r
+\r
+  // Build a Boot Firmware Volume HOB\r
+  BuildFvHob (PayloadBootInfo->SpImageBase, PayloadBootInfo->SpImageSize);\r
+\r
+  // Build a resource descriptor Hob that describes the available physical\r
+  // memory range\r
+  Attributes = (\r
+    EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
+    EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
+    EFI_RESOURCE_ATTRIBUTE_TESTED |\r
+    EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |\r
+    EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |\r
+    EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |\r
+    EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE\r
+  );\r
+\r
+  BuildResourceDescriptorHob (\r
+    EFI_RESOURCE_SYSTEM_MEMORY,\r
+    Attributes,\r
+    (UINTN) PayloadBootInfo->SpMemBase,\r
+    PayloadBootInfo->SpMemLimit - PayloadBootInfo->SpMemBase\r
+    );\r
+\r
+  // Find the size of the GUIDed HOB with MP information\r
+  BufferSize = sizeof (MP_INFORMATION_HOB_DATA);\r
+  BufferSize += sizeof (EFI_PROCESSOR_INFORMATION) * PayloadBootInfo->NumCpus;\r
+\r
+  // Create a Guided MP information HOB to enable the ARM TF CPU driver to\r
+  // perform per-cpu allocations.\r
+  MpInformationHobData = BuildGuidHob (&gMpInformationHobGuid, BufferSize);\r
+\r
+  // Populate the MP information HOB with the topology information passed by\r
+  // privileged firmware\r
+  MpInformationHobData->NumberOfProcessors = PayloadBootInfo->NumCpus;\r
+  MpInformationHobData->NumberOfEnabledProcessors = PayloadBootInfo->NumCpus;\r
+  ProcInfoBuffer = MpInformationHobData->ProcessorInfoBuffer;\r
+  CpuInfo = PayloadBootInfo->CpuInfo;\r
+\r
+  for (Index = 0; Index < PayloadBootInfo->NumCpus; Index++) {\r
+    ProcInfoBuffer[Index].ProcessorId      = CpuInfo[Index].Mpidr;\r
+    ProcInfoBuffer[Index].Location.Package = GET_CLUSTER_ID(CpuInfo[Index].Mpidr);\r
+    ProcInfoBuffer[Index].Location.Core    = GET_CORE_ID(CpuInfo[Index].Mpidr);\r
+    ProcInfoBuffer[Index].Location.Thread  = GET_CORE_ID(CpuInfo[Index].Mpidr);\r
+\r
+    Flags = PROCESSOR_ENABLED_BIT | PROCESSOR_HEALTH_STATUS_BIT;\r
+    if (CpuInfo[Index].Flags & CPU_INFO_FLAG_PRIMARY_CPU) {\r
+      Flags |= PROCESSOR_AS_BSP_BIT;\r
+    }\r
+    ProcInfoBuffer[Index].StatusFlag = Flags;\r
+  }\r
+\r
+  // Create a Guided HOB to tell the ARM TF CPU driver the location and length\r
+  // of the communication buffer shared with the Normal world.\r
+  NsCommBufMmramRange = (EFI_MMRAM_DESCRIPTOR *) BuildGuidHob (\r
+                                                   &gEfiStandaloneMmNonSecureBufferGuid,\r
+                                                   sizeof (EFI_MMRAM_DESCRIPTOR)\r
+                                                   );\r
+  NsCommBufMmramRange->PhysicalStart = PayloadBootInfo->SpNsCommBufBase;\r
+  NsCommBufMmramRange->CpuStart      = PayloadBootInfo->SpNsCommBufBase;\r
+  NsCommBufMmramRange->PhysicalSize  = PayloadBootInfo->SpNsCommBufSize;\r
+  NsCommBufMmramRange->RegionState   = EFI_CACHEABLE | EFI_ALLOCATED;\r
+\r
+  // Create a Guided HOB to enable the ARM TF CPU driver to share its entry\r
+  // point and populate it with the address of the shared buffer\r
+  CpuDriverEntryPointDesc = (ARM_TF_CPU_DRIVER_EP_DESCRIPTOR *) BuildGuidHob (\r
+                                                                  &gEfiArmTfCpuDriverEpDescriptorGuid,\r
+                                                                  sizeof (ARM_TF_CPU_DRIVER_EP_DESCRIPTOR)\r
+                                                                  );\r
+\r
+  *CpuDriverEntryPoint = NULL;\r
+  CpuDriverEntryPointDesc->ArmTfCpuDriverEpPtr = CpuDriverEntryPoint;\r
+\r
+  // Find the size of the GUIDed HOB with SRAM ranges\r
+  BufferSize = sizeof (EFI_MMRAM_HOB_DESCRIPTOR_BLOCK);\r
+  BufferSize += PayloadBootInfo->NumSpMemRegions * sizeof (EFI_MMRAM_DESCRIPTOR);\r
+\r
+  // Create a GUIDed HOB with SRAM ranges\r
+  MmramRangesHob = BuildGuidHob (&gEfiMmPeiMmramMemoryReserveGuid, BufferSize);\r
+\r
+  // Fill up the number of MMRAM memory regions\r
+  MmramRangesHob->NumberOfMmReservedRegions = PayloadBootInfo->NumSpMemRegions;\r
+  // Fill up the MMRAM ranges\r
+  MmramRanges = &MmramRangesHob->Descriptor[0];\r
+\r
+  // Base and size of memory occupied by the Standalone MM image\r
+  MmramRanges[0].PhysicalStart = PayloadBootInfo->SpImageBase;\r
+  MmramRanges[0].CpuStart      = PayloadBootInfo->SpImageBase;\r
+  MmramRanges[0].PhysicalSize  = PayloadBootInfo->SpImageSize;\r
+  MmramRanges[0].RegionState   = EFI_CACHEABLE | EFI_ALLOCATED;\r
+\r
+  // Base and size of buffer shared with privileged Secure world software\r
+  MmramRanges[1].PhysicalStart = PayloadBootInfo->SpSharedBufBase;\r
+  MmramRanges[1].CpuStart      = PayloadBootInfo->SpSharedBufBase;\r
+  MmramRanges[1].PhysicalSize  = PayloadBootInfo->SpPcpuSharedBufSize * PayloadBootInfo->NumCpus;\r
+  MmramRanges[1].RegionState   = EFI_CACHEABLE | EFI_ALLOCATED;\r
+\r
+  // Base and size of buffer used for synchronous communication with Normal\r
+  // world software\r
+  MmramRanges[2].PhysicalStart = PayloadBootInfo->SpNsCommBufBase;\r
+  MmramRanges[2].CpuStart      = PayloadBootInfo->SpNsCommBufBase;\r
+  MmramRanges[2].PhysicalSize  = PayloadBootInfo->SpNsCommBufSize;\r
+  MmramRanges[2].RegionState   = EFI_CACHEABLE | EFI_ALLOCATED;\r
+\r
+  // Base and size of memory allocated for stacks for all cpus\r
+  MmramRanges[3].PhysicalStart = PayloadBootInfo->SpStackBase;\r
+  MmramRanges[3].CpuStart      = PayloadBootInfo->SpStackBase;\r
+  MmramRanges[3].PhysicalSize  = PayloadBootInfo->SpPcpuStackSize * PayloadBootInfo->NumCpus;\r
+  MmramRanges[3].RegionState   = EFI_CACHEABLE | EFI_ALLOCATED;\r
+\r
+  // Base and size of heap memory shared by all cpus\r
+  MmramRanges[4].PhysicalStart = (EFI_PHYSICAL_ADDRESS) HobStart;\r
+  MmramRanges[4].CpuStart      = (EFI_PHYSICAL_ADDRESS) HobStart;\r
+  MmramRanges[4].PhysicalSize  = HobStart->EfiFreeMemoryBottom - (EFI_PHYSICAL_ADDRESS) HobStart;\r
+  MmramRanges[4].RegionState   = EFI_CACHEABLE | EFI_ALLOCATED;\r
+\r
+  // Base and size of heap memory shared by all cpus\r
+  MmramRanges[5].PhysicalStart = HobStart->EfiFreeMemoryBottom;\r
+  MmramRanges[5].CpuStart      = HobStart->EfiFreeMemoryBottom;\r
+  MmramRanges[5].PhysicalSize  = HobStart->EfiFreeMemoryTop - HobStart->EfiFreeMemoryBottom;\r
+  MmramRanges[5].RegionState   = EFI_CACHEABLE;\r
+\r
+  return HobStart;\r
+}\r