VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/CpuMpPei/CpuBist.c@ 106901

Last change on this file since 106901 was 101291, checked in by vboxsync, 17 months ago

EFI/FirmwareNew: Make edk2-stable202308 build on all supported platforms (using gcc at least, msvc not tested yet), bugref:4643

  • Property svn:eol-style set to native
File size: 10.2 KB
Line 
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
11EFI_SEC_PLATFORM_INFORMATION2_PPI mSecPlatformInformation2Ppi = {
12 SecPlatformInformation2
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
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**/
33EFI_STATUS
34EFIAPI
35SecPlatformInformation2 (
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**/
83EFI_STATUS
84GetBistInfoFromPpi (
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
138 return EFI_SUCCESS;
139 }
140 }
141 }
142 }
143
144 return EFI_DEVICE_ERROR;
145}
146
147/**
148 Collects BIST data from PPI.
149
150 This function collects BIST data from Sec Platform Information2 PPI
151 or SEC Platform Information PPI.
152
153 @param PeiServices Pointer to PEI Services Table
154
155**/
156VOID
157CollectBistDataFromPpi (
158 IN CONST EFI_PEI_SERVICES **PeiServices
159 )
160{
161 EFI_STATUS Status;
162 EFI_PEI_PPI_DESCRIPTOR *SecInformationDescriptor;
163 EFI_SEC_PLATFORM_INFORMATION_RECORD2 *SecPlatformInformation2;
164 EFI_SEC_PLATFORM_INFORMATION_RECORD *SecPlatformInformation;
165 UINTN NumberOfData;
166 EFI_SEC_PLATFORM_INFORMATION_CPU *CpuInstance;
167 EFI_SEC_PLATFORM_INFORMATION_CPU BspCpuInstance;
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
195 SecPlatformInformation2 = NULL;
196 SecPlatformInformation = NULL;
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,
206 (VOID *)&SecPlatformInformation2,
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 //
256 REPORT_STATUS_CODE (
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 //
277 BuildGuidDataHob (
278 &gEfiSecPlatformInformation2PpiGuid,
279 PlatformInformationRecord2,
280 (UINTN)BistInformationSize
281 );
282
283 if (SecPlatformInformation2 != NULL) {
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}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette