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