SecBist.c 9.0 KB

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