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