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