FvbInfo.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. /** @file
  2. Copyright (c) 2014 - 2021, Intel Corporation. All rights reserved.<BR>
  3. SPDX-License-Identifier: BSD-2-Clause-Patent
  4. **/
  5. #include <PiDxe.h>
  6. #include <Protocol/FirmwareVolumeBlock.h>
  7. #include <Library/PcdLib.h>
  8. #include <Library/DebugLib.h>
  9. #include <Library/BaseLib.h>
  10. #include <Guid/FirmwareFileSystem2.h>
  11. #include <Guid/SystemNvDataGuid.h>
  12. #include <Guid/NvVariableInfoGuid.h>
  13. #include <Library/HobLib.h>
  14. #define FVB_MEDIA_BLOCK_SIZE 0x1000
  15. typedef struct {
  16. EFI_FIRMWARE_VOLUME_HEADER FvInfo;
  17. EFI_FV_BLOCK_MAP_ENTRY End[1];
  18. } EFI_FVB2_MEDIA_INFO;
  19. //
  20. // This data structure contains a template of FV header which is used to restore
  21. // Fv header if it's corrupted.
  22. //
  23. EFI_FVB2_MEDIA_INFO mFvbMediaInfo = {
  24. {
  25. { 0, }, // ZeroVector[16]
  26. EFI_SYSTEM_NV_DATA_FV_GUID,
  27. 0,
  28. EFI_FVH_SIGNATURE,
  29. 0x0004feff, // check PiFirmwareVolume.h for details on EFI_FVB_ATTRIBUTES_2
  30. sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY),
  31. 0, // CheckSum which will be calucated dynamically.
  32. 0, // ExtHeaderOffset
  33. { 0, },
  34. EFI_FVH_REVISION,
  35. {
  36. {
  37. 0,
  38. FVB_MEDIA_BLOCK_SIZE,
  39. }
  40. }
  41. },
  42. {
  43. {
  44. 0,
  45. 0
  46. }
  47. }
  48. };
  49. /**
  50. Initialize the variable store
  51. @retval EFI_SUCCESS if initialize the store success.
  52. **/
  53. EFI_STATUS
  54. InitVariableStore (
  55. VOID
  56. )
  57. {
  58. EFI_STATUS Status;
  59. UINT32 NvStorageBase;
  60. UINT32 NvStorageSize;
  61. UINT32 NvVariableSize;
  62. UINT32 FtwWorkingSize;
  63. UINT32 FtwSpareSize;
  64. EFI_HOB_GUID_TYPE *GuidHob;
  65. NV_VARIABLE_INFO *NvVariableInfo;
  66. //
  67. // Find SPI flash variable hob
  68. //
  69. GuidHob = GetFirstGuidHob (&gNvVariableInfoGuid);
  70. if (GuidHob == NULL) {
  71. ASSERT (FALSE);
  72. return EFI_NOT_FOUND;
  73. }
  74. NvVariableInfo = (NV_VARIABLE_INFO *)GET_GUID_HOB_DATA (GuidHob);
  75. //
  76. // Get variable region base and size.
  77. //
  78. NvStorageSize = NvVariableInfo->VariableStoreSize;
  79. NvStorageBase = NvVariableInfo->VariableStoreBase;
  80. //
  81. // NvStorageBase needs to be 4KB aligned, NvStorageSize needs to be 8KB * n
  82. //
  83. if (((NvStorageBase & (SIZE_4KB - 1)) != 0) || ((NvStorageSize & (SIZE_8KB - 1)) != 0)) {
  84. return EFI_INVALID_PARAMETER;
  85. }
  86. FtwSpareSize = NvStorageSize / 2;
  87. FtwWorkingSize = 0x2000;
  88. NvVariableSize = NvStorageSize / 2 - FtwWorkingSize;
  89. DEBUG ((DEBUG_INFO, "NvStorageBase:0x%x, NvStorageSize:0x%x\n", NvStorageBase, NvStorageSize));
  90. if (NvVariableSize >= 0x80000000) {
  91. return EFI_INVALID_PARAMETER;
  92. }
  93. Status = PcdSet32S (PcdFlashNvStorageVariableSize, NvVariableSize);
  94. ASSERT_EFI_ERROR (Status);
  95. Status = PcdSet32S (PcdFlashNvStorageVariableBase, NvStorageBase);
  96. ASSERT_EFI_ERROR (Status);
  97. Status = PcdSet64S (PcdFlashNvStorageVariableBase64, NvStorageBase);
  98. ASSERT_EFI_ERROR (Status);
  99. Status = PcdSet32S (PcdFlashNvStorageFtwWorkingSize, FtwWorkingSize);
  100. ASSERT_EFI_ERROR (Status);
  101. Status = PcdSet32S (PcdFlashNvStorageFtwWorkingBase, NvStorageBase + NvVariableSize);
  102. ASSERT_EFI_ERROR (Status);
  103. Status = PcdSet32S (PcdFlashNvStorageFtwSpareSize, FtwSpareSize);
  104. ASSERT_EFI_ERROR (Status);
  105. Status = PcdSet32S (PcdFlashNvStorageFtwSpareBase, NvStorageBase + FtwSpareSize);
  106. ASSERT_EFI_ERROR (Status);
  107. return EFI_SUCCESS;
  108. }
  109. /**
  110. Get a heathy FV header used for variable store recovery
  111. @retval The FV header.
  112. **/
  113. EFI_FIRMWARE_VOLUME_HEADER *
  114. GetFvHeaderTemplate (
  115. VOID
  116. )
  117. {
  118. EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
  119. UINTN FvSize;
  120. FvSize = PcdGet32 (PcdFlashNvStorageFtwSpareSize) * 2;
  121. FvHeader = &mFvbMediaInfo.FvInfo;
  122. FvHeader->FvLength = FvSize;
  123. FvHeader->BlockMap[0].NumBlocks = (UINT32)(FvSize / FvHeader->BlockMap[0].Length);
  124. FvHeader->Checksum = 0;
  125. FvHeader->Checksum = CalculateCheckSum16 ((UINT16 *)FvHeader, FvHeader->HeaderLength);
  126. return FvHeader;
  127. }