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 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 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 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 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 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