]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - UefiCpuPkg/CpuMpPei/CpuBist.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / UefiCpuPkg / CpuMpPei / CpuBist.c
... / ...
CommitLineData
1/** @file\r
2 Update and publish processors' BIST information.\r
3\r
4 Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>\r
5 SPDX-License-Identifier: BSD-2-Clause-Patent\r
6\r
7**/\r
8\r
9#include "CpuMpPei.h"\r
10\r
11EFI_SEC_PLATFORM_INFORMATION2_PPI mSecPlatformInformation2Ppi = {\r
12 SecPlatformInformation2\r
13};\r
14\r
15EFI_PEI_PPI_DESCRIPTOR mPeiSecPlatformInformation2Ppi = {\r
16 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
17 &gEfiSecPlatformInformation2PpiGuid,\r
18 &mSecPlatformInformation2Ppi\r
19};\r
20\r
21/**\r
22 Implementation of the PlatformInformation2 service in EFI_SEC_PLATFORM_INFORMATION2_PPI.\r
23\r
24 @param PeiServices The pointer to the PEI Services Table.\r
25 @param StructureSize The pointer to the variable describing size of the input buffer.\r
26 @param PlatformInformationRecord2 The pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD2.\r
27\r
28 @retval EFI_SUCCESS The data was successfully returned.\r
29 @retval EFI_BUFFER_TOO_SMALL The buffer was too small. The current buffer size needed to\r
30 hold the record is returned in StructureSize.\r
31\r
32**/\r
33EFI_STATUS\r
34EFIAPI\r
35SecPlatformInformation2 (\r
36 IN CONST EFI_PEI_SERVICES **PeiServices,\r
37 IN OUT UINT64 *StructureSize,\r
38 OUT EFI_SEC_PLATFORM_INFORMATION_RECORD2 *PlatformInformationRecord2\r
39 )\r
40{\r
41 EFI_HOB_GUID_TYPE *GuidHob;\r
42 VOID *DataInHob;\r
43 UINTN DataSize;\r
44\r
45 GuidHob = GetFirstGuidHob (&gEfiSecPlatformInformation2PpiGuid);\r
46 if (GuidHob == NULL) {\r
47 *StructureSize = 0;\r
48 return EFI_SUCCESS;\r
49 }\r
50\r
51 DataInHob = GET_GUID_HOB_DATA (GuidHob);\r
52 DataSize = GET_GUID_HOB_DATA_SIZE (GuidHob);\r
53\r
54 //\r
55 // return the information from BistHob\r
56 //\r
57 if ((*StructureSize) < (UINT64)DataSize) {\r
58 *StructureSize = (UINT64)DataSize;\r
59 return EFI_BUFFER_TOO_SMALL;\r
60 }\r
61\r
62 *StructureSize = (UINT64)DataSize;\r
63 CopyMem (PlatformInformationRecord2, DataInHob, DataSize);\r
64 return EFI_SUCCESS;\r
65}\r
66\r
67/**\r
68 Worker function to get CPUs' BIST by calling SecPlatformInformationPpi\r
69 or SecPlatformInformation2Ppi.\r
70\r
71 @param PeiServices Pointer to PEI Services Table\r
72 @param Guid PPI Guid\r
73 @param PpiDescriptor Return a pointer to instance of the\r
74 EFI_PEI_PPI_DESCRIPTOR\r
75 @param BistInformationData Pointer to BIST information data\r
76 @param BistInformationSize Return the size in bytes of BIST information\r
77\r
78 @retval EFI_SUCCESS Retrieve of the BIST data successfully\r
79 @retval EFI_NOT_FOUND No sec platform information(2) ppi export\r
80 @retval EFI_DEVICE_ERROR Failed to get CPU Information\r
81\r
82**/\r
83EFI_STATUS\r
84GetBistInfoFromPpi (\r
85 IN CONST EFI_PEI_SERVICES **PeiServices,\r
86 IN CONST EFI_GUID *Guid,\r
87 OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor,\r
88 OUT VOID **BistInformationData,\r
89 OUT UINT64 *BistInformationSize OPTIONAL\r
90 )\r
91{\r
92 EFI_STATUS Status;\r
93 EFI_SEC_PLATFORM_INFORMATION2_PPI *SecPlatformInformation2Ppi;\r
94 EFI_SEC_PLATFORM_INFORMATION_RECORD2 *SecPlatformInformation2;\r
95 UINT64 InformationSize;\r
96\r
97 Status = PeiServicesLocatePpi (\r
98 Guid, // GUID\r
99 0, // INSTANCE\r
100 PpiDescriptor, // EFI_PEI_PPI_DESCRIPTOR\r
101 (VOID **)&SecPlatformInformation2Ppi // PPI\r
102 );\r
103 if (Status == EFI_NOT_FOUND) {\r
104 return EFI_NOT_FOUND;\r
105 }\r
106\r
107 if (Status == EFI_SUCCESS) {\r
108 //\r
109 // Get the size of the sec platform information2(BSP/APs' BIST data)\r
110 //\r
111 InformationSize = 0;\r
112 SecPlatformInformation2 = NULL;\r
113 Status = SecPlatformInformation2Ppi->PlatformInformation2 (\r
114 PeiServices,\r
115 &InformationSize,\r
116 SecPlatformInformation2\r
117 );\r
118 if (Status == EFI_BUFFER_TOO_SMALL) {\r
119 Status = PeiServicesAllocatePool (\r
120 (UINTN)InformationSize,\r
121 (VOID **)&SecPlatformInformation2\r
122 );\r
123 if (Status == EFI_SUCCESS) {\r
124 //\r
125 // Retrieve BIST data\r
126 //\r
127 Status = SecPlatformInformation2Ppi->PlatformInformation2 (\r
128 PeiServices,\r
129 &InformationSize,\r
130 SecPlatformInformation2\r
131 );\r
132 if (Status == EFI_SUCCESS) {\r
133 *BistInformationData = SecPlatformInformation2;\r
134 if (BistInformationSize != NULL) {\r
135 *BistInformationSize = InformationSize;\r
136 }\r
137\r
138 return EFI_SUCCESS;\r
139 }\r
140 }\r
141 }\r
142 }\r
143\r
144 return EFI_DEVICE_ERROR;\r
145}\r
146\r
147/**\r
148 Collects BIST data from PPI.\r
149\r
150 This function collects BIST data from Sec Platform Information2 PPI\r
151 or SEC Platform Information PPI.\r
152\r
153 @param PeiServices Pointer to PEI Services Table\r
154\r
155**/\r
156VOID\r
157CollectBistDataFromPpi (\r
158 IN CONST EFI_PEI_SERVICES **PeiServices\r
159 )\r
160{\r
161 EFI_STATUS Status;\r
162 EFI_PEI_PPI_DESCRIPTOR *SecInformationDescriptor;\r
163 EFI_SEC_PLATFORM_INFORMATION_RECORD2 *SecPlatformInformation2;\r
164 EFI_SEC_PLATFORM_INFORMATION_RECORD *SecPlatformInformation;\r
165 UINTN NumberOfData;\r
166 EFI_SEC_PLATFORM_INFORMATION_CPU *CpuInstance;\r
167 EFI_SEC_PLATFORM_INFORMATION_CPU BspCpuInstance;\r
168 UINTN ProcessorNumber;\r
169 UINTN CpuIndex;\r
170 EFI_PROCESSOR_INFORMATION ProcessorInfo;\r
171 EFI_HEALTH_FLAGS BistData;\r
172 UINTN NumberOfProcessors;\r
173 UINTN NumberOfEnabledProcessors;\r
174 UINTN BistInformationSize;\r
175 EFI_SEC_PLATFORM_INFORMATION_RECORD2 *PlatformInformationRecord2;\r
176 EFI_SEC_PLATFORM_INFORMATION_CPU *CpuInstanceInHob;\r
177\r
178 MpInitLibGetNumberOfProcessors (&NumberOfProcessors, &NumberOfEnabledProcessors);\r
179\r
180 BistInformationSize = sizeof (EFI_SEC_PLATFORM_INFORMATION_RECORD2) +\r
181 sizeof (EFI_SEC_PLATFORM_INFORMATION_CPU) * NumberOfProcessors;\r
182 Status = PeiServicesAllocatePool (\r
183 (UINTN)BistInformationSize,\r
184 (VOID **)&PlatformInformationRecord2\r
185 );\r
186 ASSERT_EFI_ERROR (Status);\r
187 PlatformInformationRecord2->NumberOfCpus = (UINT32)NumberOfProcessors;\r
188\r
189 SecPlatformInformation2 = NULL;\r
190 SecPlatformInformation = NULL;\r
191 NumberOfData = 0;\r
192 CpuInstance = NULL;\r
193 //\r
194 // Get BIST information from Sec Platform Information2 Ppi firstly\r
195 //\r
196 Status = GetBistInfoFromPpi (\r
197 PeiServices,\r
198 &gEfiSecPlatformInformation2PpiGuid,\r
199 &SecInformationDescriptor,\r
200 (VOID *)&SecPlatformInformation2,\r
201 NULL\r
202 );\r
203 if (Status == EFI_SUCCESS) {\r
204 //\r
205 // Sec Platform Information2 PPI includes BSP/APs' BIST information\r
206 //\r
207 NumberOfData = SecPlatformInformation2->NumberOfCpus;\r
208 CpuInstance = SecPlatformInformation2->CpuInstance;\r
209 } else {\r
210 //\r
211 // Otherwise, get BIST information from Sec Platform Information Ppi\r
212 //\r
213 Status = GetBistInfoFromPpi (\r
214 PeiServices,\r
215 &gEfiSecPlatformInformationPpiGuid,\r
216 &SecInformationDescriptor,\r
217 (VOID *)&SecPlatformInformation,\r
218 NULL\r
219 );\r
220 if (Status == EFI_SUCCESS) {\r
221 NumberOfData = 1;\r
222 //\r
223 // SEC Platform Information only includes BSP's BIST information\r
224 // and does not have BSP's APIC ID\r
225 //\r
226 BspCpuInstance.CpuLocation = GetInitialApicId ();\r
227 BspCpuInstance.InfoRecord.IA32HealthFlags.Uint32 = SecPlatformInformation->IA32HealthFlags.Uint32;\r
228 CpuInstance = &BspCpuInstance;\r
229 } else {\r
230 DEBUG ((DEBUG_INFO, "Does not find any stored CPU BIST information from PPI!\n"));\r
231 }\r
232 }\r
233\r
234 for (ProcessorNumber = 0; ProcessorNumber < NumberOfProcessors; ProcessorNumber++) {\r
235 MpInitLibGetProcessorInfo (ProcessorNumber, &ProcessorInfo, &BistData);\r
236 for (CpuIndex = 0; CpuIndex < NumberOfData; CpuIndex++) {\r
237 ASSERT (CpuInstance != NULL);\r
238 if (ProcessorInfo.ProcessorId == CpuInstance[CpuIndex].CpuLocation) {\r
239 //\r
240 // Update processor's BIST data if it is already stored before\r
241 //\r
242 BistData = CpuInstance[CpuIndex].InfoRecord.IA32HealthFlags;\r
243 }\r
244 }\r
245\r
246 if (BistData.Uint32 != 0) {\r
247 //\r
248 // Report Status Code that self test is failed\r
249 //\r
250 REPORT_STATUS_CODE (\r
251 EFI_ERROR_CODE | EFI_ERROR_MAJOR,\r
252 (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_SELF_TEST)\r
253 );\r
254 }\r
255\r
256 DEBUG ((\r
257 DEBUG_INFO,\r
258 " APICID - 0x%08x, BIST - 0x%08x\n",\r
259 (UINT32)ProcessorInfo.ProcessorId,\r
260 BistData\r
261 ));\r
262 CpuInstanceInHob = PlatformInformationRecord2->CpuInstance;\r
263 CpuInstanceInHob[ProcessorNumber].CpuLocation = (UINT32)ProcessorInfo.ProcessorId;\r
264 CpuInstanceInHob[ProcessorNumber].InfoRecord.IA32HealthFlags = BistData;\r
265 }\r
266\r
267 //\r
268 // Build SecPlatformInformation2 PPI GUIDed HOB that also could be consumed\r
269 // by CPU MP driver to get CPU BIST data\r
270 //\r
271 BuildGuidDataHob (\r
272 &gEfiSecPlatformInformation2PpiGuid,\r
273 PlatformInformationRecord2,\r
274 (UINTN)BistInformationSize\r
275 );\r
276\r
277 if (SecPlatformInformation2 != NULL) {\r
278 if (NumberOfData < NumberOfProcessors) {\r
279 //\r
280 // Reinstall SecPlatformInformation2 PPI to include new BIST information\r
281 //\r
282 Status = PeiServicesReInstallPpi (\r
283 SecInformationDescriptor,\r
284 &mPeiSecPlatformInformation2Ppi\r
285 );\r
286 ASSERT_EFI_ERROR (Status);\r
287 }\r
288 } else {\r
289 //\r
290 // Install SecPlatformInformation2 PPI\r
291 //\r
292 Status = PeiServicesInstallPpi (&mPeiSecPlatformInformation2Ppi);\r
293 ASSERT_EFI_ERROR (Status);\r
294 }\r
295}\r