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