TianoCore EDK2 master
Loading...
Searching...
No Matches
CpuBist.c
Go to the documentation of this file.
1
9#include "CpuMpPei.h"
10
11EFI_SEC_PLATFORM_INFORMATION2_PPI mSecPlatformInformation2Ppi = {
13};
14
15EFI_PEI_PPI_DESCRIPTOR mPeiSecPlatformInformation2Ppi = {
16 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
17 &gEfiSecPlatformInformation2PpiGuid,
18 &mSecPlatformInformation2Ppi
19};
20
34EFIAPI
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
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;
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;
113 Status = SecPlatformInformation2Ppi->PlatformInformation2 (
114 PeiServices,
115 &InformationSize,
117 );
118 if (Status == EFI_BUFFER_TOO_SMALL) {
119 Status = PeiServicesAllocatePool (
120 (UINTN)InformationSize,
122 );
123 if (Status == EFI_SUCCESS) {
124 //
125 // Retrieve BIST data
126 //
127 Status = SecPlatformInformation2Ppi->PlatformInformation2 (
128 PeiServices,
129 &InformationSize,
131 );
132 if (Status == EFI_SUCCESS) {
133 *BistInformationData = SecPlatformInformation2;
134 if (BistInformationSize != NULL) {
135 *BistInformationSize = InformationSize;
136 }
137
138 return EFI_SUCCESS;
139 }
140 }
141 }
142 }
143
144 return EFI_DEVICE_ERROR;
145}
146
156VOID
158 IN CONST EFI_PEI_SERVICES **PeiServices
159 )
160{
161 EFI_STATUS Status;
162 EFI_PEI_PPI_DESCRIPTOR *SecInformationDescriptor;
165 UINTN NumberOfData;
168 UINTN ProcessorNumber;
169 UINTN CpuIndex;
170 EFI_PROCESSOR_INFORMATION ProcessorInfo;
171 EFI_HEALTH_FLAGS BistData;
172 UINTN NumberOfProcessors;
173 UINTN NumberOfEnabledProcessors;
174 UINTN BistInformationSize;
175 EFI_SEC_PLATFORM_INFORMATION_RECORD2 *PlatformInformationRecord2;
176 EFI_SEC_PLATFORM_INFORMATION_CPU *CpuInstanceInHob;
177
178 Status = MpInitLibGetNumberOfProcessors (&NumberOfProcessors, &NumberOfEnabledProcessors);
179 ASSERT_EFI_ERROR (Status);
180
181 if (EFI_ERROR (Status)) {
182 NumberOfProcessors = 1;
183 NumberOfEnabledProcessors = 1;
184 }
185
186 BistInformationSize = sizeof (EFI_SEC_PLATFORM_INFORMATION_RECORD2) +
187 sizeof (EFI_SEC_PLATFORM_INFORMATION_CPU) * NumberOfProcessors;
188 Status = PeiServicesAllocatePool (
189 (UINTN)BistInformationSize,
190 (VOID **)&PlatformInformationRecord2
191 );
192 ASSERT_EFI_ERROR (Status);
193 PlatformInformationRecord2->NumberOfCpus = (UINT32)NumberOfProcessors;
194
197 NumberOfData = 0;
198 CpuInstance = NULL;
199 //
200 // Get BIST information from Sec Platform Information2 Ppi firstly
201 //
202 Status = GetBistInfoFromPpi (
203 PeiServices,
204 &gEfiSecPlatformInformation2PpiGuid,
205 &SecInformationDescriptor,
207 NULL
208 );
209 if (Status == EFI_SUCCESS) {
210 //
211 // Sec Platform Information2 PPI includes BSP/APs' BIST information
212 //
213 NumberOfData = SecPlatformInformation2->NumberOfCpus;
214 CpuInstance = SecPlatformInformation2->CpuInstance;
215 } else {
216 //
217 // Otherwise, get BIST information from Sec Platform Information Ppi
218 //
219 Status = GetBistInfoFromPpi (
220 PeiServices,
221 &gEfiSecPlatformInformationPpiGuid,
222 &SecInformationDescriptor,
223 (VOID *)&SecPlatformInformation,
224 NULL
225 );
226 if (Status == EFI_SUCCESS) {
227 NumberOfData = 1;
228 //
229 // SEC Platform Information only includes BSP's BIST information
230 // and does not have BSP's APIC ID
231 //
232 BspCpuInstance.CpuLocation = GetInitialApicId ();
233 BspCpuInstance.InfoRecord.IA32HealthFlags.Uint32 = SecPlatformInformation->IA32HealthFlags.Uint32;
234 CpuInstance = &BspCpuInstance;
235 } else {
236 DEBUG ((DEBUG_INFO, "Does not find any stored CPU BIST information from PPI!\n"));
237 }
238 }
239
240 for (ProcessorNumber = 0; ProcessorNumber < NumberOfProcessors; ProcessorNumber++) {
241 MpInitLibGetProcessorInfo (ProcessorNumber, &ProcessorInfo, &BistData);
242 for (CpuIndex = 0; CpuIndex < NumberOfData; CpuIndex++) {
243 ASSERT (CpuInstance != NULL);
244 if (ProcessorInfo.ProcessorId == CpuInstance[CpuIndex].CpuLocation) {
245 //
246 // Update processor's BIST data if it is already stored before
247 //
248 BistData = CpuInstance[CpuIndex].InfoRecord.IA32HealthFlags;
249 }
250 }
251
252 if (BistData.Uint32 != 0) {
253 //
254 // Report Status Code that self test is failed
255 //
257 EFI_ERROR_CODE | EFI_ERROR_MAJOR,
258 (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_SELF_TEST)
259 );
260 }
261
262 DEBUG ((
263 DEBUG_INFO,
264 " APICID - 0x%08x, BIST - 0x%08x\n",
265 (UINT32)ProcessorInfo.ProcessorId,
266 BistData
267 ));
268 CpuInstanceInHob = PlatformInformationRecord2->CpuInstance;
269 CpuInstanceInHob[ProcessorNumber].CpuLocation = (UINT32)ProcessorInfo.ProcessorId;
270 CpuInstanceInHob[ProcessorNumber].InfoRecord.IA32HealthFlags = BistData;
271 }
272
273 //
274 // Build SecPlatformInformation2 PPI GUIDed HOB that also could be consumed
275 // by CPU MP driver to get CPU BIST data
276 //
278 &gEfiSecPlatformInformation2PpiGuid,
279 PlatformInformationRecord2,
280 (UINTN)BistInformationSize
281 );
282
284 if (NumberOfData < NumberOfProcessors) {
285 //
286 // Reinstall SecPlatformInformation2 PPI to include new BIST information
287 //
288 Status = PeiServicesReInstallPpi (
289 SecInformationDescriptor,
290 &mPeiSecPlatformInformation2Ppi
291 );
292 ASSERT_EFI_ERROR (Status);
293 }
294 } else {
295 //
296 // Install SecPlatformInformation2 PPI
297 //
298 Status = PeiServicesInstallPpi (&mPeiSecPlatformInformation2Ppi);
299 ASSERT_EFI_ERROR (Status);
300 }
301}
UINT64 UINTN
VOID *EFIAPI GetFirstGuidHob(IN CONST EFI_GUID *Guid)
Definition: HobLib.c:215
VOID *EFIAPI BuildGuidDataHob(IN CONST EFI_GUID *Guid, IN VOID *Data, IN UINTN DataLength)
Definition: HobLib.c:375
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
EFI_STATUS EFIAPI SecPlatformInformation2(IN CONST EFI_PEI_SERVICES **PeiServices, IN OUT UINT64 *StructureSize, OUT EFI_SEC_PLATFORM_INFORMATION_RECORD2 *PlatformInformationRecord2)
Definition: CpuBist.c:35
VOID CollectBistDataFromPpi(IN CONST EFI_PEI_SERVICES **PeiServices)
Definition: CpuBist.c:157
EFI_STATUS GetBistInfoFromPpi(IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_GUID *Guid, OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor, OUT VOID **BistInformationData, OUT UINT64 *BistInformationSize OPTIONAL)
Definition: CpuBist.c:84
EFI_STATUS EFIAPI PeiServicesAllocatePool(IN UINTN Size, OUT VOID **Buffer)
EFI_STATUS EFIAPI PeiServicesLocatePpi(IN CONST EFI_GUID *Guid, IN UINTN Instance, IN OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor, IN OUT VOID **Ppi)
EFI_STATUS EFIAPI PeiServicesInstallPpi(IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList)
EFI_STATUS EFIAPI PeiServicesReInstallPpi(IN CONST EFI_PEI_PPI_DESCRIPTOR *OldPpi, IN CONST EFI_PEI_PPI_DESCRIPTOR *NewPpi)
EFI_STATUS EFIAPI SecPlatformInformation(IN CONST EFI_PEI_SERVICES **PeiServices, IN OUT UINT64 *StructureSize, OUT EFI_SEC_PLATFORM_INFORMATION_RECORD *PlatformInformationRecord)
UINT32 EFIAPI GetInitialApicId(VOID)
Definition: BaseXApicLib.c:298
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define REPORT_STATUS_CODE(Type, Value)
EFI_STATUS EFIAPI MpInitLibGetNumberOfProcessors(OUT UINTN *NumberOfProcessors OPTIONAL, OUT UINTN *NumberOfEnabledProcessors OPTIONAL)
Definition: MpLib.c:1559
EFI_STATUS EFIAPI MpInitLibGetProcessorInfo(IN UINTN ProcessorNumber, OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer, OUT EFI_HEALTH_FLAGS *HealthData OPTIONAL)
Definition: MpLib.c:1452
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
Definition: Base.h:213