]> git.proxmox.com Git - mirror_edk2.git/blob - UefiCpuPkg/SecCore/SecBist.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / UefiCpuPkg / SecCore / SecBist.c
1 /** @file
2 Get SEC platform information(2) PPI and reinstall it.
3
4 Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include "SecMain.h"
10
11 EFI_SEC_PLATFORM_INFORMATION_PPI mSecPlatformInformation = {
12 SecPlatformInformationBist
13 };
14
15 EFI_PEI_PPI_DESCRIPTOR mPeiSecPlatformInformation = {
16 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
17 &gEfiSecPlatformInformationPpiGuid,
18 &mSecPlatformInformation
19 };
20
21 EFI_SEC_PLATFORM_INFORMATION2_PPI mSecPlatformInformation2 = {
22 SecPlatformInformation2Bist
23 };
24
25 EFI_PEI_PPI_DESCRIPTOR mPeiSecPlatformInformation2 = {
26 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
27 &gEfiSecPlatformInformation2PpiGuid,
28 &mSecPlatformInformation2
29 };
30
31 /**
32 Worker function to parse CPU BIST information from Guided HOB.
33
34 @param[in, out] StructureSize Pointer to the variable describing size of the input buffer.
35 @param[in, out] StructureBuffer Pointer to the buffer save CPU BIST information.
36
37 @retval EFI_SUCCESS The data was successfully returned.
38 @retval EFI_BUFFER_TOO_SMALL The buffer was too small.
39
40 **/
41 EFI_STATUS
42 GetBistFromHob (
43 IN OUT UINT64 *StructureSize,
44 IN OUT VOID *StructureBuffer
45 )
46 {
47 EFI_HOB_GUID_TYPE *GuidHob;
48 VOID *DataInHob;
49 UINTN DataSize;
50
51 GuidHob = GetFirstGuidHob (&gEfiCallerIdGuid);
52 if (GuidHob == NULL) {
53 *StructureSize = 0;
54 return EFI_SUCCESS;
55 }
56
57 DataInHob = GET_GUID_HOB_DATA (GuidHob);
58 DataSize = GET_GUID_HOB_DATA_SIZE (GuidHob);
59
60 //
61 // return the information from BistHob
62 //
63 if ((*StructureSize) < (UINT64)DataSize) {
64 *StructureSize = (UINT64)DataSize;
65 return EFI_BUFFER_TOO_SMALL;
66 }
67
68 *StructureSize = (UINT64)DataSize;
69 CopyMem (StructureBuffer, DataInHob, DataSize);
70 return EFI_SUCCESS;
71 }
72
73 /**
74 Implementation of the PlatformInformation service in EFI_SEC_PLATFORM_INFORMATION_PPI.
75
76 @param[in] PeiServices Pointer to the PEI Services Table.
77 @param[in, out] StructureSize Pointer to the variable describing size of the input buffer.
78 @param[out] PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD.
79
80 @retval EFI_SUCCESS The data was successfully returned.
81 @retval EFI_BUFFER_TOO_SMALL The buffer was too small.
82
83 **/
84 EFI_STATUS
85 EFIAPI
86 SecPlatformInformationBist (
87 IN CONST EFI_PEI_SERVICES **PeiServices,
88 IN OUT UINT64 *StructureSize,
89 OUT EFI_SEC_PLATFORM_INFORMATION_RECORD *PlatformInformationRecord
90 )
91 {
92 return GetBistFromHob (StructureSize, PlatformInformationRecord);
93 }
94
95 /**
96 Implementation of the PlatformInformation2 service in EFI_SEC_PLATFORM_INFORMATION2_PPI.
97
98 @param[in] PeiServices The pointer to the PEI Services Table.
99 @param[in, out] StructureSize The pointer to the variable describing size of the input buffer.
100 @param[out] PlatformInformationRecord2 The pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD2.
101
102 @retval EFI_SUCCESS The data was successfully returned.
103 @retval EFI_BUFFER_TOO_SMALL The buffer was too small. The current buffer size needed to
104 hold the record is returned in StructureSize.
105
106 **/
107 EFI_STATUS
108 EFIAPI
109 SecPlatformInformation2Bist (
110 IN CONST EFI_PEI_SERVICES **PeiServices,
111 IN OUT UINT64 *StructureSize,
112 OUT EFI_SEC_PLATFORM_INFORMATION_RECORD2 *PlatformInformationRecord2
113 )
114 {
115 return GetBistFromHob (StructureSize, PlatformInformationRecord2);
116 }
117
118 /**
119 Worker function to get CPUs' BIST by calling SecPlatformInformationPpi
120 or SecPlatformInformation2Ppi.
121
122 @param[in] PeiServices Pointer to PEI Services Table
123 @param[in] Guid PPI Guid
124 @param[out] PpiDescriptor Return a pointer to instance of the
125 EFI_PEI_PPI_DESCRIPTOR
126 @param[out] BistInformationData Pointer to BIST information data
127 @param[out] BistInformationSize Return the size in bytes of BIST information
128
129 @retval EFI_SUCCESS Retrieve of the BIST data successfully
130 @retval EFI_NOT_FOUND No sec platform information(2) ppi export
131 @retval EFI_DEVICE_ERROR Failed to get CPU Information
132
133 **/
134 EFI_STATUS
135 GetBistInfoFromPpi (
136 IN CONST EFI_PEI_SERVICES **PeiServices,
137 IN CONST EFI_GUID *Guid,
138 OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor,
139 OUT VOID **BistInformationData,
140 OUT UINT64 *BistInformationSize OPTIONAL
141 )
142 {
143 EFI_STATUS Status;
144 EFI_SEC_PLATFORM_INFORMATION2_PPI *SecPlatformInformation2Ppi;
145 EFI_SEC_PLATFORM_INFORMATION_RECORD2 *SecPlatformInformation2;
146 UINT64 InformationSize;
147
148 Status = PeiServicesLocatePpi (
149 Guid, // GUID
150 0, // INSTANCE
151 PpiDescriptor, // EFI_PEI_PPI_DESCRIPTOR
152 (VOID **)&SecPlatformInformation2Ppi // PPI
153 );
154 if (Status == EFI_NOT_FOUND) {
155 return EFI_NOT_FOUND;
156 }
157
158 if (Status == EFI_SUCCESS) {
159 //
160 // Get the size of the sec platform information2(BSP/APs' BIST data)
161 //
162 InformationSize = 0;
163 SecPlatformInformation2 = NULL;
164 Status = SecPlatformInformation2Ppi->PlatformInformation2 (
165 PeiServices,
166 &InformationSize,
167 SecPlatformInformation2
168 );
169 if (Status == EFI_BUFFER_TOO_SMALL) {
170 Status = PeiServicesAllocatePool (
171 (UINTN)InformationSize,
172 (VOID **)&SecPlatformInformation2
173 );
174 if (Status == EFI_SUCCESS) {
175 //
176 // Retrieve BIST data
177 //
178 Status = SecPlatformInformation2Ppi->PlatformInformation2 (
179 PeiServices,
180 &InformationSize,
181 SecPlatformInformation2
182 );
183 if (Status == EFI_SUCCESS) {
184 *BistInformationData = SecPlatformInformation2;
185 if (BistInformationSize != NULL) {
186 *BistInformationSize = InformationSize;
187 }
188
189 return EFI_SUCCESS;
190 }
191 }
192 }
193 }
194
195 return EFI_DEVICE_ERROR;
196 }
197
198 /**
199 Get CPUs' BIST by calling SecPlatformInformationPpi/SecPlatformInformation2Ppi.
200
201 **/
202 VOID
203 RepublishSecPlatformInformationPpi (
204 VOID
205 )
206 {
207 EFI_STATUS Status;
208 CONST EFI_PEI_SERVICES **PeiServices;
209 UINT64 BistInformationSize;
210 VOID *BistInformationData;
211 EFI_PEI_PPI_DESCRIPTOR *SecInformationDescriptor;
212
213 PeiServices = GetPeiServicesTablePointer ();
214 Status = GetBistInfoFromPpi (
215 PeiServices,
216 &gEfiSecPlatformInformation2PpiGuid,
217 &SecInformationDescriptor,
218 &BistInformationData,
219 &BistInformationSize
220 );
221 if (Status == EFI_SUCCESS) {
222 BuildGuidDataHob (
223 &gEfiCallerIdGuid,
224 BistInformationData,
225 (UINTN)BistInformationSize
226 );
227 //
228 // The old SecPlatformInformation2 data is on temporary memory.
229 // After memory discovered, we should never get it from temporary memory,
230 // or the data will be crashed. So, we reinstall SecPlatformInformation2 PPI here.
231 //
232 Status = PeiServicesReInstallPpi (
233 SecInformationDescriptor,
234 &mPeiSecPlatformInformation2
235 );
236 }
237
238 if (Status == EFI_NOT_FOUND) {
239 Status = GetBistInfoFromPpi (
240 PeiServices,
241 &gEfiSecPlatformInformationPpiGuid,
242 &SecInformationDescriptor,
243 &BistInformationData,
244 &BistInformationSize
245 );
246 if (Status == EFI_SUCCESS) {
247 BuildGuidDataHob (
248 &gEfiCallerIdGuid,
249 BistInformationData,
250 (UINTN)BistInformationSize
251 );
252 //
253 // The old SecPlatformInformation data is on temporary memory.
254 // After memory discovered, we should never get it from temporary memory,
255 // or the data will be crashed. So, we reinstall SecPlatformInformation PPI here.
256 //
257 Status = PeiServicesReInstallPpi (
258 SecInformationDescriptor,
259 &mPeiSecPlatformInformation
260 );
261 } else if (Status == EFI_NOT_FOUND) {
262 return;
263 }
264 }
265
266 ASSERT_EFI_ERROR (Status);
267 }