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