CreateHobList.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. /** @file
  2. Creates HOB during Standalone MM Foundation entry point
  3. on ARM platforms.
  4. Copyright (c) 2017 - 2021, Arm Ltd. All rights reserved.<BR>
  5. SPDX-License-Identifier: BSD-2-Clause-Patent
  6. **/
  7. #include <PiMm.h>
  8. #include <PiPei.h>
  9. #include <Guid/MmramMemoryReserve.h>
  10. #include <Guid/MpInformation.h>
  11. #include <Library/Arm/StandaloneMmCoreEntryPoint.h>
  12. #include <Library/ArmMmuLib.h>
  13. #include <Library/ArmSvcLib.h>
  14. #include <Library/DebugLib.h>
  15. #include <Library/HobLib.h>
  16. #include <Library/BaseLib.h>
  17. #include <Library/BaseMemoryLib.h>
  18. #include <Library/SerialPortLib.h>
  19. #include <IndustryStandard/ArmStdSmc.h>
  20. extern EFI_HOB_HANDOFF_INFO_TABLE*
  21. HobConstructor (
  22. IN VOID *EfiMemoryBegin,
  23. IN UINTN EfiMemoryLength,
  24. IN VOID *EfiFreeMemoryBottom,
  25. IN VOID *EfiFreeMemoryTop
  26. );
  27. // GUID to identify HOB with whereabouts of communication buffer with Normal
  28. // World
  29. extern EFI_GUID gEfiStandaloneMmNonSecureBufferGuid;
  30. // GUID to identify HOB where the entry point of the CPU driver will be
  31. // populated to allow this entry point driver to invoke it upon receipt of an
  32. // event
  33. extern EFI_GUID gEfiArmTfCpuDriverEpDescriptorGuid;
  34. /**
  35. Use the boot information passed by privileged firmware to populate a HOB list
  36. suitable for consumption by the MM Core and drivers.
  37. @param [in, out] CpuDriverEntryPoint Address of MM CPU driver entrypoint
  38. @param [in] PayloadBootInfo Boot information passed by privileged
  39. firmware
  40. **/
  41. VOID *
  42. CreateHobListFromBootInfo (
  43. IN OUT PI_MM_ARM_TF_CPU_DRIVER_ENTRYPOINT *CpuDriverEntryPoint,
  44. IN EFI_SECURE_PARTITION_BOOT_INFO *PayloadBootInfo
  45. )
  46. {
  47. EFI_HOB_HANDOFF_INFO_TABLE *HobStart;
  48. EFI_RESOURCE_ATTRIBUTE_TYPE Attributes;
  49. UINT32 Index;
  50. UINT32 BufferSize;
  51. UINT32 Flags;
  52. EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *MmramRangesHob;
  53. EFI_MMRAM_DESCRIPTOR *MmramRanges;
  54. EFI_MMRAM_DESCRIPTOR *NsCommBufMmramRange;
  55. MP_INFORMATION_HOB_DATA *MpInformationHobData;
  56. EFI_PROCESSOR_INFORMATION *ProcInfoBuffer;
  57. EFI_SECURE_PARTITION_CPU_INFO *CpuInfo;
  58. ARM_TF_CPU_DRIVER_EP_DESCRIPTOR *CpuDriverEntryPointDesc;
  59. // Create a hoblist with a PHIT and EOH
  60. HobStart = HobConstructor (
  61. (VOID *) (UINTN) PayloadBootInfo->SpMemBase,
  62. (UINTN) PayloadBootInfo->SpMemLimit - PayloadBootInfo->SpMemBase,
  63. (VOID *) (UINTN) PayloadBootInfo->SpHeapBase,
  64. (VOID *) (UINTN) (PayloadBootInfo->SpHeapBase + PayloadBootInfo->SpHeapSize)
  65. );
  66. // Check that the Hoblist starts at the bottom of the Heap
  67. ASSERT (HobStart == (VOID *) (UINTN) PayloadBootInfo->SpHeapBase);
  68. // Build a Boot Firmware Volume HOB
  69. BuildFvHob (PayloadBootInfo->SpImageBase, PayloadBootInfo->SpImageSize);
  70. // Build a resource descriptor Hob that describes the available physical
  71. // memory range
  72. Attributes = (
  73. EFI_RESOURCE_ATTRIBUTE_PRESENT |
  74. EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
  75. EFI_RESOURCE_ATTRIBUTE_TESTED |
  76. EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
  77. EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
  78. EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
  79. EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
  80. );
  81. BuildResourceDescriptorHob (
  82. EFI_RESOURCE_SYSTEM_MEMORY,
  83. Attributes,
  84. (UINTN) PayloadBootInfo->SpMemBase,
  85. PayloadBootInfo->SpMemLimit - PayloadBootInfo->SpMemBase
  86. );
  87. // Find the size of the GUIDed HOB with MP information
  88. BufferSize = sizeof (MP_INFORMATION_HOB_DATA);
  89. BufferSize += sizeof (EFI_PROCESSOR_INFORMATION) * PayloadBootInfo->NumCpus;
  90. // Create a Guided MP information HOB to enable the ARM TF CPU driver to
  91. // perform per-cpu allocations.
  92. MpInformationHobData = BuildGuidHob (&gMpInformationHobGuid, BufferSize);
  93. // Populate the MP information HOB with the topology information passed by
  94. // privileged firmware
  95. MpInformationHobData->NumberOfProcessors = PayloadBootInfo->NumCpus;
  96. MpInformationHobData->NumberOfEnabledProcessors = PayloadBootInfo->NumCpus;
  97. ProcInfoBuffer = MpInformationHobData->ProcessorInfoBuffer;
  98. CpuInfo = PayloadBootInfo->CpuInfo;
  99. for (Index = 0; Index < PayloadBootInfo->NumCpus; Index++) {
  100. ProcInfoBuffer[Index].ProcessorId = CpuInfo[Index].Mpidr;
  101. ProcInfoBuffer[Index].Location.Package = GET_CLUSTER_ID(CpuInfo[Index].Mpidr);
  102. ProcInfoBuffer[Index].Location.Core = GET_CORE_ID(CpuInfo[Index].Mpidr);
  103. ProcInfoBuffer[Index].Location.Thread = GET_CORE_ID(CpuInfo[Index].Mpidr);
  104. Flags = PROCESSOR_ENABLED_BIT | PROCESSOR_HEALTH_STATUS_BIT;
  105. if (CpuInfo[Index].Flags & CPU_INFO_FLAG_PRIMARY_CPU) {
  106. Flags |= PROCESSOR_AS_BSP_BIT;
  107. }
  108. ProcInfoBuffer[Index].StatusFlag = Flags;
  109. }
  110. // Create a Guided HOB to tell the ARM TF CPU driver the location and length
  111. // of the communication buffer shared with the Normal world.
  112. NsCommBufMmramRange = (EFI_MMRAM_DESCRIPTOR *) BuildGuidHob (
  113. &gEfiStandaloneMmNonSecureBufferGuid,
  114. sizeof (EFI_MMRAM_DESCRIPTOR)
  115. );
  116. NsCommBufMmramRange->PhysicalStart = PayloadBootInfo->SpNsCommBufBase;
  117. NsCommBufMmramRange->CpuStart = PayloadBootInfo->SpNsCommBufBase;
  118. NsCommBufMmramRange->PhysicalSize = PayloadBootInfo->SpNsCommBufSize;
  119. NsCommBufMmramRange->RegionState = EFI_CACHEABLE | EFI_ALLOCATED;
  120. // Create a Guided HOB to enable the ARM TF CPU driver to share its entry
  121. // point and populate it with the address of the shared buffer
  122. CpuDriverEntryPointDesc = (ARM_TF_CPU_DRIVER_EP_DESCRIPTOR *) BuildGuidHob (
  123. &gEfiArmTfCpuDriverEpDescriptorGuid,
  124. sizeof (ARM_TF_CPU_DRIVER_EP_DESCRIPTOR)
  125. );
  126. *CpuDriverEntryPoint = NULL;
  127. CpuDriverEntryPointDesc->ArmTfCpuDriverEpPtr = CpuDriverEntryPoint;
  128. // Find the size of the GUIDed HOB with SRAM ranges
  129. BufferSize = sizeof (EFI_MMRAM_HOB_DESCRIPTOR_BLOCK);
  130. BufferSize += PayloadBootInfo->NumSpMemRegions * sizeof (EFI_MMRAM_DESCRIPTOR);
  131. // Create a GUIDed HOB with SRAM ranges
  132. MmramRangesHob = BuildGuidHob (&gEfiMmPeiMmramMemoryReserveGuid, BufferSize);
  133. // Fill up the number of MMRAM memory regions
  134. MmramRangesHob->NumberOfMmReservedRegions = PayloadBootInfo->NumSpMemRegions;
  135. // Fill up the MMRAM ranges
  136. MmramRanges = &MmramRangesHob->Descriptor[0];
  137. // Base and size of memory occupied by the Standalone MM image
  138. MmramRanges[0].PhysicalStart = PayloadBootInfo->SpImageBase;
  139. MmramRanges[0].CpuStart = PayloadBootInfo->SpImageBase;
  140. MmramRanges[0].PhysicalSize = PayloadBootInfo->SpImageSize;
  141. MmramRanges[0].RegionState = EFI_CACHEABLE | EFI_ALLOCATED;
  142. // Base and size of buffer shared with privileged Secure world software
  143. MmramRanges[1].PhysicalStart = PayloadBootInfo->SpSharedBufBase;
  144. MmramRanges[1].CpuStart = PayloadBootInfo->SpSharedBufBase;
  145. MmramRanges[1].PhysicalSize = PayloadBootInfo->SpPcpuSharedBufSize * PayloadBootInfo->NumCpus;
  146. MmramRanges[1].RegionState = EFI_CACHEABLE | EFI_ALLOCATED;
  147. // Base and size of buffer used for synchronous communication with Normal
  148. // world software
  149. MmramRanges[2].PhysicalStart = PayloadBootInfo->SpNsCommBufBase;
  150. MmramRanges[2].CpuStart = PayloadBootInfo->SpNsCommBufBase;
  151. MmramRanges[2].PhysicalSize = PayloadBootInfo->SpNsCommBufSize;
  152. MmramRanges[2].RegionState = EFI_CACHEABLE | EFI_ALLOCATED;
  153. // Base and size of memory allocated for stacks for all cpus
  154. MmramRanges[3].PhysicalStart = PayloadBootInfo->SpStackBase;
  155. MmramRanges[3].CpuStart = PayloadBootInfo->SpStackBase;
  156. MmramRanges[3].PhysicalSize = PayloadBootInfo->SpPcpuStackSize * PayloadBootInfo->NumCpus;
  157. MmramRanges[3].RegionState = EFI_CACHEABLE | EFI_ALLOCATED;
  158. // Base and size of heap memory shared by all cpus
  159. MmramRanges[4].PhysicalStart = (EFI_PHYSICAL_ADDRESS) (UINTN) HobStart;
  160. MmramRanges[4].CpuStart = (EFI_PHYSICAL_ADDRESS) (UINTN) HobStart;
  161. MmramRanges[4].PhysicalSize = HobStart->EfiFreeMemoryBottom - (EFI_PHYSICAL_ADDRESS) (UINTN) HobStart;
  162. MmramRanges[4].RegionState = EFI_CACHEABLE | EFI_ALLOCATED;
  163. // Base and size of heap memory shared by all cpus
  164. MmramRanges[5].PhysicalStart = HobStart->EfiFreeMemoryBottom;
  165. MmramRanges[5].CpuStart = HobStart->EfiFreeMemoryBottom;
  166. MmramRanges[5].PhysicalSize = HobStart->EfiFreeMemoryTop - HobStart->EfiFreeMemoryBottom;
  167. MmramRanges[5].RegionState = EFI_CACHEABLE;
  168. return HobStart;
  169. }