MultiPlatSupportLib.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. /** @file
  2. @copyright
  3. Copyright 2012 - 2021 Intel Corporation. <BR>
  4. SPDX-License-Identifier: BSD-2-Clause-Patent
  5. **/
  6. #include <PiPei.h>
  7. #include <Library/MultiPlatSupportLib.h>
  8. #include <Library/HobLib.h>
  9. #include <MultiPlatSupport.h>
  10. #include <Ppi/MemoryDiscovered.h>
  11. #include <Library/ReadFfsLib.h>
  12. #include <Library/MemoryAllocationLib.h>
  13. #include <Guid/AuthenticatedVariableFormat.h>
  14. #include <Library/PeiServicesLib.h>
  15. //notes
  16. //1: security variable and non-security variable may have different implementation
  17. //2. BP core variable sync may need update this module
  18. //3 different generation need to sync base on RP variable and Generation variable
  19. // this library to use a lightweight get variable service to patch variable hob before PEI variable service is ready
  20. /**
  21. Gets a vairable store header from FFS inserted by FCE
  22. Arguments:
  23. DefaultId - Specifies the type of defaults to retrieve.
  24. BoardId - Specifies the platform board of defaults to retrieve.
  25. @return The start address of VARIABLE_STORE_HEADER *. Null if cannot find it
  26. **/
  27. VOID * FindDefaultHobinFfs (
  28. IN UINT16 DefaultId,
  29. IN UINT16 BoardId
  30. )
  31. {
  32. EFI_PEI_SERVICES **PeiServices;
  33. UINTN FvInstance;
  34. EFI_PEI_FV_HANDLE FvHandle;
  35. EFI_PEI_FILE_HANDLE *FfsHandle;
  36. EFI_FFS_FILE_HEADER *FfsHeader;
  37. UINT32 FileSize;
  38. EFI_COMMON_SECTION_HEADER *Section;
  39. UINT32 SectionLength;
  40. BOOLEAN DefaultFileIsFound;
  41. DEFAULT_DATA *DefaultData;
  42. DEFAULT_INFO *DefaultInfo;
  43. VARIABLE_STORE_HEADER *VarStoreHeader;
  44. UINT32 FFSSize = 0;
  45. //
  46. // Find the FFS file that stores all default data.
  47. //
  48. DefaultFileIsFound = FALSE;
  49. FvInstance = 0;
  50. FfsHandle = NULL;
  51. while ((PeiServicesFfsFindNextVolume (FvInstance, &FvHandle) == EFI_SUCCESS) && (!DefaultFileIsFound)) {
  52. FfsHandle = NULL;
  53. while (PeiServicesFfsFindNextFile (EFI_FV_FILETYPE_FREEFORM, FvHandle, FfsHandle) == EFI_SUCCESS) {
  54. if (CompareGuid ((EFI_GUID *) FfsHandle, &gDefaultDataFileGuid)) {
  55. DefaultFileIsFound = TRUE;
  56. FfsHeader = (EFI_FFS_FILE_HEADER *) FfsHandle;
  57. break;
  58. }
  59. }
  60. FvInstance ++;
  61. }
  62. //
  63. // FFS file is not found.
  64. //
  65. if (!DefaultFileIsFound) {
  66. if (PcdGet32 (PcdFailSafeVarFfsSize) != 0 ){
  67. //
  68. // try to search other FVS
  69. //
  70. FfsHeader = (EFI_FFS_FILE_HEADER *) AllocatePool (PcdGet32 (PcdFailSafeVarFfsSize));
  71. if (FfsHeader == NULL) {
  72. return NULL;
  73. }
  74. if (EFI_SUCCESS != ReadFFSFile ((EFI_FIRMWARE_VOLUME_HEADER *) PcdGet32 (PcdFailSafeVarFvBase), gDefaultDataFileGuid, 0, FfsHeader, &FFSSize, FALSE)) {
  75. return NULL;
  76. }
  77. ASSERT (PcdGet32 (PcdFailSafeVarFfsSize) <FFSSize);
  78. } else {
  79. return NULL;
  80. }
  81. }
  82. //
  83. // Find the matched default data for the input default ID and plat ID.
  84. //
  85. VarStoreHeader = NULL;
  86. Section = (EFI_COMMON_SECTION_HEADER *)(FfsHeader + 1);
  87. FileSize = *(UINT32 *) (FfsHeader->Size) & 0x00FFFFFF;
  88. while (((UINTN) Section < (UINTN) FfsHeader + FileSize) && (VarStoreHeader == NULL)) {
  89. DefaultData = (DEFAULT_DATA *) (Section + 1);
  90. DefaultInfo = &(DefaultData->DefaultInfo[0]);
  91. while ((UINTN) DefaultInfo < (UINTN) DefaultData + DefaultData->HeaderSize) {
  92. if (DefaultInfo->DefaultId == DefaultId && DefaultInfo->BoardId == BoardId) {
  93. VarStoreHeader = (VARIABLE_STORE_HEADER *) ((UINT8 *) DefaultData + DefaultData->HeaderSize);
  94. break;
  95. }
  96. DefaultInfo ++;
  97. }
  98. //
  99. // Size is 24 bits wide so mask upper 8 bits.
  100. // SectionLength is adjusted it is 4 byte aligned.
  101. // Go to the next section
  102. //
  103. SectionLength = *(UINT32 *)Section->Size & 0x00FFFFFF;
  104. SectionLength = (SectionLength + 3) & (~3);
  105. ASSERT (SectionLength != 0);
  106. Section = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + SectionLength);
  107. }
  108. return VarStoreHeader;
  109. }
  110. /**
  111. This function searches the first instance of a HOB from the starting HOB pointer.
  112. Such HOB should satisfy two conditions:
  113. its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.
  114. If there does not exist such HOB from the starting HOB pointer, it will return NULL.
  115. Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()
  116. to extract the data section and its size info respectively.
  117. In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer
  118. unconditionally: it returns HobStart back if HobStart itself meets the requirement;
  119. caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.
  120. If Guid is NULL, then ASSERT().
  121. If HobStart is NULL, then ASSERT().
  122. @param Guid The GUID to match with in the HOB list.
  123. @param HobStart A pointer to a Guid.
  124. @return The next instance of the matched GUID HOB from the starting HOB.
  125. **/
  126. VOID *
  127. InternalGetNextGuidHob (
  128. IN CONST EFI_GUID *Guid,
  129. IN CONST VOID *HobStart
  130. )
  131. {
  132. EFI_PEI_HOB_POINTERS GuidHob;
  133. GuidHob.Raw = (UINT8 *) HobStart;
  134. while (!END_OF_HOB_LIST (GuidHob)) {
  135. if (GuidHob.Header->HobType == EFI_HOB_TYPE_GUID_EXTENSION && CompareGuid (Guid, &GuidHob.Guid->Name)) {
  136. break;
  137. }
  138. GuidHob.Raw = GET_NEXT_HOB (GuidHob);
  139. }
  140. return GuidHob.Raw;
  141. }
  142. EFI_STATUS
  143. CreateDefaultVariableHob (
  144. IN UINT16 DefaultId,
  145. IN UINT16 BoardId
  146. )
  147. /*++
  148. Description:
  149. This function finds the matched default data and create GUID hob for it.
  150. Arguments:
  151. DefaultId - Specifies the type of defaults to retrieve.
  152. BoardId - Specifies the platform board of defaults to retrieve.
  153. Returns:
  154. EFI_SUCCESS - The matched default data is found.
  155. EFI_NOT_FOUND - The matched default data is not found.
  156. EFI_OUT_OF_RESOURCES - No enough resource to create HOB.
  157. --*/
  158. {
  159. VARIABLE_STORE_HEADER *VarStoreHeader;
  160. VARIABLE_STORE_HEADER *VarStoreHeaderHob;
  161. UINT8 *VarHobPtr;
  162. UINT8 *VarPtr;
  163. UINT32 VarDataOffset;
  164. UINT32 VarHobDataOffset;
  165. EFI_PEI_SERVICES **PeiServices;
  166. //
  167. // Get PeiService pointer
  168. //
  169. PeiServices = (EFI_PEI_SERVICES **)GetPeiServicesTablePointer ();
  170. VarStoreHeader = (VARIABLE_STORE_HEADER*)FindDefaultHobinFfs( DefaultId, BoardId);
  171. //
  172. // Matched default data is not found.
  173. //
  174. if (VarStoreHeader == NULL) {
  175. return EFI_NOT_FOUND;
  176. }
  177. //
  178. // Create HOB to store defautl data so that Variable driver can use it.
  179. // Allocate more data for header alignment.
  180. //
  181. VarStoreHeaderHob = (VARIABLE_STORE_HEADER *) BuildGuidHob (&VarStoreHeader->Signature, VarStoreHeader->Size + HEADER_ALIGNMENT - 1);
  182. if (VarStoreHeaderHob == NULL) {
  183. //
  184. // No enough hob resource.
  185. //
  186. return EFI_OUT_OF_RESOURCES;
  187. }
  188. //
  189. // Copy variable storage header.
  190. //
  191. CopyMem (VarStoreHeaderHob, VarStoreHeader, sizeof (VARIABLE_STORE_HEADER));
  192. //
  193. // Copy variable data.
  194. //
  195. VarPtr = (UINT8 *) HEADER_ALIGN ((UINTN) (VarStoreHeader + 1));
  196. VarDataOffset = (UINT32) ((UINTN) VarPtr - (UINTN) VarStoreHeader);
  197. VarHobPtr = (UINT8 *) HEADER_ALIGN ((UINTN) (VarStoreHeaderHob + 1));
  198. VarHobDataOffset = (UINT32) ((UINTN) VarHobPtr - (UINTN) VarStoreHeaderHob);
  199. CopyMem (VarHobPtr, VarPtr, VarStoreHeader->Size - VarDataOffset);
  200. //
  201. // Update variable size.
  202. //
  203. VarStoreHeaderHob->Size = VarStoreHeader->Size - VarDataOffset + VarHobDataOffset;
  204. // SyncSetupVariable(PeiServices,VarStoreHeaderHob,FALSE);
  205. return EFI_SUCCESS;
  206. }