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