StandaloneMmCpu.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. /** @file
  2. Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
  3. Copyright (c) 2016 HP Development Company, L.P.
  4. Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.
  5. SPDX-License-Identifier: BSD-2-Clause-Patent
  6. **/
  7. #include <Base.h>
  8. #include <Pi/PiMmCis.h>
  9. #include <Library/Arm/StandaloneMmCoreEntryPoint.h>
  10. #include <Library/DebugLib.h>
  11. #include <Library/ArmSvcLib.h>
  12. #include <Library/ArmLib.h>
  13. #include <Library/BaseMemoryLib.h>
  14. #include <Library/HobLib.h>
  15. #include <Protocol/DebugSupport.h> // for EFI_SYSTEM_CONTEXT
  16. #include <Guid/ZeroGuid.h>
  17. #include <Guid/MmramMemoryReserve.h>
  18. #include "StandaloneMmCpu.h"
  19. // GUID to identify HOB with whereabouts of communication buffer with Normal
  20. // World
  21. extern EFI_GUID gEfiStandaloneMmNonSecureBufferGuid;
  22. // GUID to identify HOB where the entry point of this CPU driver will be
  23. // populated to allow the entry point driver to invoke it upon receipt of an
  24. // event
  25. extern EFI_GUID gEfiArmTfCpuDriverEpDescriptorGuid;
  26. //
  27. // Private copy of the MM system table for future use
  28. //
  29. EFI_MM_SYSTEM_TABLE *mMmst = NULL;
  30. //
  31. // Globals used to initialize the protocol
  32. //
  33. STATIC EFI_HANDLE mMmCpuHandle = NULL;
  34. /** Returns the HOB data for the matching HOB GUID.
  35. @param [in] HobList Pointer to the HOB list.
  36. @param [in] HobGuid The GUID for the HOB.
  37. @param [out] HobData Pointer to the HOB data.
  38. @retval EFI_SUCCESS The function completed successfully.
  39. @retval EFI_INVALID_PARAMETER Invalid parameter.
  40. @retval EFI_NOT_FOUND Could not find HOB with matching GUID.
  41. **/
  42. EFI_STATUS
  43. GetGuidedHobData (
  44. IN VOID *HobList,
  45. IN CONST EFI_GUID *HobGuid,
  46. OUT VOID **HobData
  47. )
  48. {
  49. EFI_HOB_GUID_TYPE *Hob;
  50. if ((HobList == NULL) || (HobGuid == NULL) || (HobData == NULL)) {
  51. return EFI_INVALID_PARAMETER;
  52. }
  53. Hob = GetNextGuidHob (HobGuid, HobList);
  54. if (Hob == NULL) {
  55. return EFI_NOT_FOUND;
  56. }
  57. *HobData = GET_GUID_HOB_DATA (Hob);
  58. if (*HobData == NULL) {
  59. return EFI_NOT_FOUND;
  60. }
  61. return EFI_SUCCESS;
  62. }
  63. /** Entry point for the Standalone MM CPU driver.
  64. @param [in] ImageHandle Unused. Not actual image handle.
  65. @param [in] SystemTable Pointer to MM System table.
  66. @retval EFI_SUCCESS The function completed successfully.
  67. @retval EFI_INVALID_PARAMETER Invalid parameter.
  68. @retval EFI_OUT_OF_RESOURCES Out of resources.
  69. @retval EFI_NOT_FOUND Failed to find the HOB for the CPU
  70. driver endpoint descriptor.
  71. **/
  72. EFI_STATUS
  73. StandaloneMmCpuInitialize (
  74. IN EFI_HANDLE ImageHandle, // not actual imagehandle
  75. IN EFI_MM_SYSTEM_TABLE *SystemTable // not actual systemtable
  76. )
  77. {
  78. ARM_TF_CPU_DRIVER_EP_DESCRIPTOR *CpuDriverEntryPointDesc;
  79. EFI_CONFIGURATION_TABLE *ConfigurationTable;
  80. MP_INFORMATION_HOB_DATA *MpInformationHobData;
  81. EFI_MMRAM_DESCRIPTOR *NsCommBufMmramRange;
  82. EFI_STATUS Status;
  83. EFI_HANDLE DispatchHandle;
  84. UINT32 MpInfoSize;
  85. UINTN Index;
  86. UINTN ArraySize;
  87. VOID *HobStart;
  88. ASSERT (SystemTable != NULL);
  89. mMmst = SystemTable;
  90. // publish the MM config protocol so the MM core can register its entry point
  91. Status = mMmst->MmInstallProtocolInterface (
  92. &mMmCpuHandle,
  93. &gEfiMmConfigurationProtocolGuid,
  94. EFI_NATIVE_INTERFACE,
  95. &mMmConfig
  96. );
  97. if (EFI_ERROR (Status)) {
  98. return Status;
  99. }
  100. // register the root MMI handler
  101. Status = mMmst->MmiHandlerRegister (
  102. PiMmCpuTpFwRootMmiHandler,
  103. NULL,
  104. &DispatchHandle
  105. );
  106. if (EFI_ERROR (Status)) {
  107. return Status;
  108. }
  109. // Retrieve the Hoblist from the MMST to extract the details of the NS
  110. // communication buffer that has been reserved by S-EL1/EL3
  111. ConfigurationTable = mMmst->MmConfigurationTable;
  112. for (Index = 0; Index < mMmst->NumberOfTableEntries; Index++) {
  113. if (CompareGuid (&gEfiHobListGuid, &(ConfigurationTable[Index].VendorGuid))) {
  114. break;
  115. }
  116. }
  117. // Bail out if the Hoblist could not be found
  118. if (Index >= mMmst->NumberOfTableEntries) {
  119. DEBUG ((DEBUG_INFO, "Hoblist not found - 0x%x\n", Index));
  120. return EFI_OUT_OF_RESOURCES;
  121. }
  122. HobStart = ConfigurationTable[Index].VendorTable;
  123. //
  124. // Locate the HOB with the buffer to populate the entry point of this driver
  125. //
  126. Status = GetGuidedHobData (
  127. HobStart,
  128. &gEfiArmTfCpuDriverEpDescriptorGuid,
  129. (VOID **) &CpuDriverEntryPointDesc
  130. );
  131. if (EFI_ERROR (Status)) {
  132. DEBUG ((DEBUG_INFO, "ArmTfCpuDriverEpDesc HOB data extraction failed - 0x%x\n", Status));
  133. return Status;
  134. }
  135. // Share the entry point of the CPU driver
  136. DEBUG ((DEBUG_INFO, "Sharing Cpu Driver EP *0x%lx = 0x%lx\n",
  137. (UINTN) CpuDriverEntryPointDesc->ArmTfCpuDriverEpPtr,
  138. (UINTN) PiMmStandaloneArmTfCpuDriverEntry));
  139. *(CpuDriverEntryPointDesc->ArmTfCpuDriverEpPtr) = PiMmStandaloneArmTfCpuDriverEntry;
  140. // Find the descriptor that contains the whereabouts of the buffer for
  141. // communication with the Normal world.
  142. Status = GetGuidedHobData (
  143. HobStart,
  144. &gEfiStandaloneMmNonSecureBufferGuid,
  145. (VOID **) &NsCommBufMmramRange
  146. );
  147. if (EFI_ERROR (Status)) {
  148. DEBUG ((DEBUG_INFO, "NsCommBufMmramRange HOB data extraction failed - 0x%x\n", Status));
  149. return Status;
  150. }
  151. DEBUG ((DEBUG_INFO, "mNsCommBuffer.PhysicalStart - 0x%lx\n", (UINTN) NsCommBufMmramRange->PhysicalStart));
  152. DEBUG ((DEBUG_INFO, "mNsCommBuffer.PhysicalSize - 0x%lx\n", (UINTN) NsCommBufMmramRange->PhysicalSize));
  153. CopyMem (&mNsCommBuffer, NsCommBufMmramRange, sizeof(EFI_MMRAM_DESCRIPTOR));
  154. DEBUG ((DEBUG_INFO, "mNsCommBuffer: 0x%016lx - 0x%lx\n", mNsCommBuffer.CpuStart, mNsCommBuffer.PhysicalSize));
  155. //
  156. // Extract the MP information from the Hoblist
  157. //
  158. Status = GetGuidedHobData (
  159. HobStart,
  160. &gMpInformationHobGuid,
  161. (VOID **) &MpInformationHobData
  162. );
  163. if (EFI_ERROR (Status)) {
  164. DEBUG ((DEBUG_INFO, "MpInformationHob extraction failed - 0x%x\n", Status));
  165. return Status;
  166. }
  167. //
  168. // Allocate memory for the MP information and copy over the MP information
  169. // passed by Trusted Firmware. Use the number of processors passed in the HOB
  170. // to copy the processor information
  171. //
  172. MpInfoSize = sizeof (MP_INFORMATION_HOB_DATA) +
  173. (sizeof (EFI_PROCESSOR_INFORMATION) *
  174. MpInformationHobData->NumberOfProcessors);
  175. Status = mMmst->MmAllocatePool (
  176. EfiRuntimeServicesData,
  177. MpInfoSize,
  178. (VOID **) &mMpInformationHobData
  179. );
  180. if (EFI_ERROR (Status)) {
  181. DEBUG ((DEBUG_INFO, "mMpInformationHobData mem alloc failed - 0x%x\n", Status));
  182. return Status;
  183. }
  184. CopyMem (mMpInformationHobData, MpInformationHobData, MpInfoSize);
  185. // Print MP information
  186. DEBUG ((DEBUG_INFO, "mMpInformationHobData: 0x%016lx - 0x%lx\n",
  187. mMpInformationHobData->NumberOfProcessors,
  188. mMpInformationHobData->NumberOfEnabledProcessors));
  189. for (Index = 0; Index < mMpInformationHobData->NumberOfProcessors; Index++) {
  190. DEBUG ((DEBUG_INFO, "mMpInformationHobData[0x%lx]: %d, %d, %d\n",
  191. mMpInformationHobData->ProcessorInfoBuffer[Index].ProcessorId,
  192. mMpInformationHobData->ProcessorInfoBuffer[Index].Location.Package,
  193. mMpInformationHobData->ProcessorInfoBuffer[Index].Location.Core,
  194. mMpInformationHobData->ProcessorInfoBuffer[Index].Location.Thread));
  195. }
  196. //
  197. // Allocate memory for a table to hold pointers to a
  198. // EFI_MM_COMMUNICATE_HEADER for each CPU
  199. //
  200. ArraySize = sizeof (EFI_MM_COMMUNICATE_HEADER *) *
  201. mMpInformationHobData->NumberOfEnabledProcessors;
  202. Status = mMmst->MmAllocatePool (
  203. EfiRuntimeServicesData,
  204. ArraySize,
  205. (VOID **) &PerCpuGuidedEventContext
  206. );
  207. if (EFI_ERROR (Status)) {
  208. DEBUG ((DEBUG_INFO, "PerCpuGuidedEventContext mem alloc failed - 0x%x\n", Status));
  209. return Status;
  210. }
  211. return Status;
  212. }