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