]> git.proxmox.com Git - mirror_edk2.git/blame - StandaloneMmPkg/Drivers/StandaloneMmCpu/AArch64/StandaloneMmCpu.c
StandaloneMmPkg: Fix ECC error 3002 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
47EFI_STATUS\r
48GetGuidedHobData (\r
49 IN VOID *HobList,\r
50 IN CONST EFI_GUID *HobGuid,\r
51 OUT VOID **HobData\r
52 )\r
53{\r
54 EFI_HOB_GUID_TYPE *Hob;\r
55\r
a9da96ac 56 if ((HobList == NULL) || (HobGuid == NULL) || (HobData == NULL)) {\r
275d4bd4 57 return EFI_INVALID_PARAMETER;\r
a9da96ac 58 }\r
275d4bd4
SV
59\r
60 Hob = GetNextGuidHob (HobGuid, HobList);\r
a9da96ac 61 if (Hob == NULL) {\r
275d4bd4 62 return EFI_NOT_FOUND;\r
a9da96ac 63 }\r
275d4bd4
SV
64\r
65 *HobData = GET_GUID_HOB_DATA (Hob);\r
a9da96ac 66 if (*HobData == NULL) {\r
275d4bd4 67 return EFI_NOT_FOUND;\r
a9da96ac 68 }\r
275d4bd4
SV
69\r
70 return EFI_SUCCESS;\r
71}\r
72\r
73EFI_STATUS\r
c8102727 74StandaloneMmCpuInitialize (\r
275d4bd4
SV
75 IN EFI_HANDLE ImageHandle, // not actual imagehandle\r
76 IN EFI_MM_SYSTEM_TABLE *SystemTable // not actual systemtable\r
77 )\r
78{\r
79 ARM_TF_CPU_DRIVER_EP_DESCRIPTOR *CpuDriverEntryPointDesc;\r
80 EFI_CONFIGURATION_TABLE *ConfigurationTable;\r
81 MP_INFORMATION_HOB_DATA *MpInformationHobData;\r
82 EFI_MMRAM_DESCRIPTOR *NsCommBufMmramRange;\r
83 EFI_STATUS Status;\r
84 EFI_HANDLE DispatchHandle;\r
85 UINT32 MpInfoSize;\r
86 UINTN Index;\r
87 UINTN ArraySize;\r
88 VOID *HobStart;\r
89\r
90 ASSERT (SystemTable != NULL);\r
91 mMmst = SystemTable;\r
92\r
93 // publish the MM config protocol so the MM core can register its entry point\r
94 Status = mMmst->MmInstallProtocolInterface (\r
95 &mMmCpuHandle,\r
96 &gEfiMmConfigurationProtocolGuid,\r
97 EFI_NATIVE_INTERFACE,\r
98 &mMmConfig\r
99 );\r
100 if (EFI_ERROR (Status)) {\r
101 return Status;\r
102 }\r
103\r
104 // register the root MMI handler\r
105 Status = mMmst->MmiHandlerRegister (\r
106 PiMmCpuTpFwRootMmiHandler,\r
107 NULL,\r
108 &DispatchHandle\r
109 );\r
110 if (EFI_ERROR (Status)) {\r
111 return Status;\r
112 }\r
113\r
114 // Retrieve the Hoblist from the MMST to extract the details of the NS\r
115 // communication buffer that has been reserved by S-EL1/EL3\r
116 ConfigurationTable = mMmst->MmConfigurationTable;\r
117 for (Index = 0; Index < mMmst->NumberOfTableEntries; Index++) {\r
118 if (CompareGuid (&gEfiHobListGuid, &(ConfigurationTable[Index].VendorGuid))) {\r
119 break;\r
120 }\r
121 }\r
122\r
123 // Bail out if the Hoblist could not be found\r
124 if (Index >= mMmst->NumberOfTableEntries) {\r
125 DEBUG ((DEBUG_INFO, "Hoblist not found - 0x%x\n", Index));\r
126 return EFI_OUT_OF_RESOURCES;\r
127 }\r
128\r
129 HobStart = ConfigurationTable[Index].VendorTable;\r
130\r
131 //\r
132 // Locate the HOB with the buffer to populate the entry point of this driver\r
133 //\r
134 Status = GetGuidedHobData (\r
135 HobStart,\r
136 &gEfiArmTfCpuDriverEpDescriptorGuid,\r
137 (VOID **) &CpuDriverEntryPointDesc\r
138 );\r
139 if (EFI_ERROR (Status)) {\r
140 DEBUG ((DEBUG_INFO, "ArmTfCpuDriverEpDesc HOB data extraction failed - 0x%x\n", Status));\r
141 return Status;\r
142 }\r
143\r
144 // Share the entry point of the CPU driver\r
145 DEBUG ((DEBUG_INFO, "Sharing Cpu Driver EP *0x%lx = 0x%lx\n",\r
146 (UINT64) CpuDriverEntryPointDesc->ArmTfCpuDriverEpPtr,\r
c8102727
AB
147 (UINT64) PiMmStandaloneArmTfCpuDriverEntry));\r
148 *(CpuDriverEntryPointDesc->ArmTfCpuDriverEpPtr) = PiMmStandaloneArmTfCpuDriverEntry;\r
275d4bd4
SV
149\r
150 // Find the descriptor that contains the whereabouts of the buffer for\r
151 // communication with the Normal world.\r
152 Status = GetGuidedHobData (\r
153 HobStart,\r
154 &gEfiStandaloneMmNonSecureBufferGuid,\r
155 (VOID **) &NsCommBufMmramRange\r
156 );\r
157 if (EFI_ERROR (Status)) {\r
158 DEBUG ((DEBUG_INFO, "NsCommBufMmramRange HOB data extraction failed - 0x%x\n", Status));\r
159 return Status;\r
160 }\r
161\r
162 DEBUG ((DEBUG_INFO, "mNsCommBuffer.PhysicalStart - 0x%lx\n", (UINT64) NsCommBufMmramRange->PhysicalStart));\r
163 DEBUG ((DEBUG_INFO, "mNsCommBuffer.PhysicalSize - 0x%lx\n", (UINT64) NsCommBufMmramRange->PhysicalSize));\r
164\r
165 CopyMem (&mNsCommBuffer, NsCommBufMmramRange, sizeof(EFI_MMRAM_DESCRIPTOR));\r
166 DEBUG ((DEBUG_INFO, "mNsCommBuffer: 0x%016lx - 0x%lx\n", mNsCommBuffer.CpuStart, mNsCommBuffer.PhysicalSize));\r
167\r
168 //\r
169 // Extract the MP information from the Hoblist\r
170 //\r
171 Status = GetGuidedHobData (\r
172 HobStart,\r
173 &gMpInformationHobGuid,\r
174 (VOID **) &MpInformationHobData\r
175 );\r
176 if (EFI_ERROR (Status)) {\r
177 DEBUG ((DEBUG_INFO, "MpInformationHob extraction failed - 0x%x\n", Status));\r
178 return Status;\r
179 }\r
180\r
181 //\r
182 // Allocate memory for the MP information and copy over the MP information\r
183 // passed by Trusted Firmware. Use the number of processors passed in the HOB\r
184 // to copy the processor information\r
185 //\r
186 MpInfoSize = sizeof (MP_INFORMATION_HOB_DATA) +\r
187 (sizeof (EFI_PROCESSOR_INFORMATION) *\r
188 MpInformationHobData->NumberOfProcessors);\r
189 Status = mMmst->MmAllocatePool (\r
190 EfiRuntimeServicesData,\r
191 MpInfoSize,\r
192 (VOID **) &mMpInformationHobData\r
193 );\r
194 if (EFI_ERROR (Status)) {\r
195 DEBUG ((DEBUG_INFO, "mMpInformationHobData mem alloc failed - 0x%x\n", Status));\r
196 return Status;\r
197 }\r
198\r
199 CopyMem (mMpInformationHobData, MpInformationHobData, MpInfoSize);\r
200\r
201 // Print MP information\r
202 DEBUG ((DEBUG_INFO, "mMpInformationHobData: 0x%016lx - 0x%lx\n",\r
203 mMpInformationHobData->NumberOfProcessors,\r
204 mMpInformationHobData->NumberOfEnabledProcessors));\r
205 for (Index = 0; Index < mMpInformationHobData->NumberOfProcessors; Index++) {\r
206 DEBUG ((DEBUG_INFO, "mMpInformationHobData[0x%lx]: %d, %d, %d\n",\r
207 mMpInformationHobData->ProcessorInfoBuffer[Index].ProcessorId,\r
208 mMpInformationHobData->ProcessorInfoBuffer[Index].Location.Package,\r
209 mMpInformationHobData->ProcessorInfoBuffer[Index].Location.Core,\r
210 mMpInformationHobData->ProcessorInfoBuffer[Index].Location.Thread));\r
211 }\r
212\r
213 //\r
214 // Allocate memory for a table to hold pointers to a\r
215 // EFI_MM_COMMUNICATE_HEADER for each CPU\r
216 //\r
217 ArraySize = sizeof (EFI_MM_COMMUNICATE_HEADER *) *\r
218 mMpInformationHobData->NumberOfEnabledProcessors;\r
219 Status = mMmst->MmAllocatePool (\r
220 EfiRuntimeServicesData,\r
221 ArraySize,\r
222 (VOID **) &PerCpuGuidedEventContext\r
223 );\r
224 if (EFI_ERROR (Status)) {\r
225 DEBUG ((DEBUG_INFO, "PerCpuGuidedEventContext mem alloc failed - 0x%x\n", Status));\r
226 return Status;\r
227 }\r
228 return Status;\r
229}\r