• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2 Defines data structure that is the volume header found.These data is intent
3 to decouple FVB driver with FV header.
4 
5 Copyright (c) 2013 Intel Corporation.
6 
7 This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution.  The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
11 
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14 
15 
16 **/
17 
18 #include <PiDxe.h>
19 #include "FwBlockService.h"
20 
21 
22 //#define FVB_MEDIA_BLOCK_SIZE  PcdGet32(PcdFlashMinEraseSize)
23 #define FVB_MEDIA_BLOCK_SIZE  0x1000
24 
25 typedef struct {
26   EFI_PHYSICAL_ADDRESS        BaseAddress;
27   EFI_FIRMWARE_VOLUME_HEADER  FvbInfo;
28   //
29   //EFI_FV_BLOCK_MAP_ENTRY    ExtraBlockMap[n];//n=0
30   //
31   EFI_FV_BLOCK_MAP_ENTRY      End[1];
32 } EFI_FVB2_MEDIA_INFO;
33 
34 //
35 // This data structure contains a template of all correct FV headers, which is used to restore
36 // Fv header if it's corrupted.
37 //
38 EFI_FVB2_MEDIA_INFO mPlatformFvbMediaInfo[] = {
39   //
40   // Main BIOS FVB
41   //
42   {
43     0,
44     {
45       {0,}, //ZeroVector[16]
46       EFI_FIRMWARE_FILE_SYSTEM2_GUID,
47       0,
48       EFI_FVH_SIGNATURE,
49       0x0004feff, // check MdePkg/Include/Pi/PiFirmwareVolume.h for details on EFI_FVB_ATTRIBUTES_2
50       sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY),
51       0,    //CheckSum, check the FD for the value.
52       0,    //ExtHeaderOffset
53       {0,}, //Reserved[1]
54       2,    //Revision
55       {
56         {
57           0,
58           0,
59         }
60       }
61     },
62     {
63       {
64         0,
65         0
66       }
67     }
68   },
69   //
70   // Systen NvStorage FVB
71   //
72   {
73     0,
74     {
75       {0,}, //ZeroVector[16]
76       EFI_SYSTEM_NV_DATA_FV_GUID,
77       0,
78       EFI_FVH_SIGNATURE,
79       0x0004feff, // check MdePkg/Include/Pi/PiFirmwareVolume.h for details on EFI_FVB_ATTRIBUTES_2
80       sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY),
81       0,    //CheckSum which will be calucated dynamically.
82       0,    //ExtHeaderOffset
83       {0,}, //Reserved[1]
84       2,    //Revision
85       {
86         {
87           0,
88           0,
89         }
90       }
91     },
92     {
93       {
94         0,
95         0
96       }
97     }
98   },
99   //
100   // Recovery BIOS FVB
101   //
102   {
103     0,
104     {
105       {0,}, //ZeroVector[16]
106       EFI_FIRMWARE_FILE_SYSTEM2_GUID,
107       0,
108       EFI_FVH_SIGNATURE,
109       0x0004feff, // check MdePkg/Include/Pi/PiFirmwareVolume.h for details on EFI_FVB_ATTRIBUTES_2
110       sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY),
111       0,    //CheckSum which will be calucated dynamically.
112       0,    //ExtHeaderOffset
113       {0,}, //Reserved[1]
114       2,    //Revision
115       {
116         {
117           0,
118           0,
119         }
120       }
121     },
122     {
123       {
124         0,
125         0
126       }
127     }
128   },
129   //
130   // Payload FVB
131   //
132   {
133     0,
134     {
135       {0,}, //ZeroVector[16]
136       EFI_FIRMWARE_FILE_SYSTEM2_GUID,
137       0,
138       EFI_FVH_SIGNATURE,
139       0x0004feff, // check MdePkg/Include/Pi/PiFirmwareVolume.h for details on EFI_FVB_ATTRIBUTES_2
140       sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY),
141       0,    //CheckSum which will be calucated dynamically.
142       0x60,    //ExtHeaderOffset
143       {0,}, //Reserved[1]
144       2,    //Revision
145       {
146         {
147           0,
148           0,
149         }
150       }
151     },
152     {
153       {
154         0,
155         0
156       }
157     }
158   }
159 };
160 
161 
162 //
163 // FTW working space and FTW spare space don't have FV header.
164 // We need create one for them and use it for FVB protocol.
165 //
166 EFI_FVB2_MEDIA_INFO mPlatformFtwFvbInfo[] = {
167   //
168   // System variable FTW working FVB
169   //
170   {
171     0,
172     {
173       {0,}, //ZeroVector[16]
174       EFI_SYSTEM_NV_DATA_FV_GUID,
175       0,
176       EFI_FVH_SIGNATURE,
177       0x0004feff, // check MdePkg/Include/Pi/PiFirmwareVolume.h for details on EFI_FVB_ATTRIBUTES_2
178       sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY),
179       0,    //CheckSum which will be calucated dynamically.
180       0,    //ExtHeaderOffset
181       {0,}, //Reserved[1]
182       2,    //Revision
183       {
184         {
185           0,
186           0,
187         }
188       }
189     },
190     {
191       {
192         0,
193         0
194       }
195     }
196   },
197   //
198   // Systen NV variable FTW spare FVB
199   //
200   {
201     0,
202     {
203       {0,}, //ZeroVector[16]
204       EFI_SYSTEM_NV_DATA_FV_GUID,
205       0,
206       EFI_FVH_SIGNATURE,
207       0x0004feff, // check MdePkg/Include/Pi/PiFirmwareVolume.h for details on EFI_FVB_ATTRIBUTES_2
208       sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY),
209       0,    //CheckSum which will be calucated dynamically.
210       0,    //ExtHeaderOffset
211       {0,}, //Reserved[1]
212       2,    //Revision
213       {
214         {
215           0,
216           0,
217         }
218       }
219     },
220     {
221       {
222         0,
223         0
224       }
225     }
226   }
227 };
228 
229 
230 
231 EFI_STATUS
GetFtwFvbInfo(IN EFI_PHYSICAL_ADDRESS FvBaseAddress,OUT EFI_FIRMWARE_VOLUME_HEADER ** FvbInfo)232 GetFtwFvbInfo (
233   IN  EFI_PHYSICAL_ADDRESS         FvBaseAddress,
234   OUT EFI_FIRMWARE_VOLUME_HEADER   **FvbInfo
235   )
236 {
237   UINTN                       Index;
238   EFI_FIRMWARE_VOLUME_HEADER  *FvHeader;
239 
240   //
241   // Init Fvb data
242   //
243   mPlatformFtwFvbInfo[0].BaseAddress      = PcdGet32 (PcdFlashNvStorageFtwWorkingBase);
244   mPlatformFtwFvbInfo[0].FvbInfo.FvLength = PcdGet32 (PcdFlashNvStorageFtwWorkingSize);
245   mPlatformFtwFvbInfo[0].FvbInfo.BlockMap[0].NumBlocks = PcdGet32 (PcdFlashNvStorageFtwWorkingSize) / FVB_MEDIA_BLOCK_SIZE;
246   mPlatformFtwFvbInfo[0].FvbInfo.BlockMap[0].Length    = FVB_MEDIA_BLOCK_SIZE;
247   ASSERT ((PcdGet32 (PcdFlashNvStorageFtwWorkingSize) % FVB_MEDIA_BLOCK_SIZE) == 0);
248 
249   mPlatformFtwFvbInfo[1].BaseAddress      = PcdGet32 (PcdFlashNvStorageFtwSpareBase);
250   mPlatformFtwFvbInfo[1].FvbInfo.FvLength = PcdGet32 (PcdFlashNvStorageFtwSpareSize);
251   mPlatformFtwFvbInfo[1].FvbInfo.BlockMap[0].NumBlocks = PcdGet32 (PcdFlashNvStorageFtwSpareSize) / FVB_MEDIA_BLOCK_SIZE;
252   mPlatformFtwFvbInfo[1].FvbInfo.BlockMap[0].Length    = FVB_MEDIA_BLOCK_SIZE;
253   ASSERT ((PcdGet32 (PcdFlashNvStorageFtwSpareSize) % FVB_MEDIA_BLOCK_SIZE) == 0);
254 
255   for (Index=0; Index < sizeof (mPlatformFtwFvbInfo)/sizeof (mPlatformFtwFvbInfo[0]); Index += 1) {
256     if (mPlatformFtwFvbInfo[Index].BaseAddress == FvBaseAddress) {
257       FvHeader =  &mPlatformFtwFvbInfo[Index].FvbInfo;
258       //
259       // Update the checksum value of FV header.
260       //
261       FvHeader->Checksum = CalculateCheckSum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16));
262 
263       *FvbInfo = FvHeader;
264 
265       DEBUG ((EFI_D_INFO, "\nFTW BaseAddr: 0x%lx \n", FvBaseAddress));
266       DEBUG ((EFI_D_INFO, "FvLength: 0x%lx \n", (*FvbInfo)->FvLength));
267       DEBUG ((EFI_D_INFO, "HeaderLength: 0x%x \n", (*FvbInfo)->HeaderLength));
268       DEBUG ((EFI_D_INFO, "FvBlockMap[0].NumBlocks: 0x%x \n", (*FvbInfo)->BlockMap[0].NumBlocks));
269       DEBUG ((EFI_D_INFO, "FvBlockMap[0].BlockLength: 0x%x \n", (*FvbInfo)->BlockMap[0].Length));
270       DEBUG ((EFI_D_INFO, "FvBlockMap[1].NumBlocks: 0x%x \n",   (*FvbInfo)->BlockMap[1].NumBlocks));
271       DEBUG ((EFI_D_INFO, "FvBlockMap[1].BlockLength: 0x%x \n\n", (*FvbInfo)->BlockMap[1].Length));
272 
273       return EFI_SUCCESS;
274     }
275   }
276   return EFI_NOT_FOUND;
277 }
278 
279 
280 EFI_STATUS
GetFvbInfo(IN EFI_PHYSICAL_ADDRESS FvBaseAddress,OUT EFI_FIRMWARE_VOLUME_HEADER ** FvbInfo)281 GetFvbInfo (
282   IN  EFI_PHYSICAL_ADDRESS         FvBaseAddress,
283   OUT EFI_FIRMWARE_VOLUME_HEADER   **FvbInfo
284   )
285 {
286   UINTN                       Index;
287   EFI_FIRMWARE_VOLUME_HEADER  *FvHeader;
288 
289   //
290   // Init Fvb data
291   //
292   mPlatformFvbMediaInfo[0].BaseAddress      = PcdGet32 (PcdFlashFvMainBase);
293   mPlatformFvbMediaInfo[0].FvbInfo.FvLength = PcdGet32 (PcdFlashFvMainSize);
294   mPlatformFvbMediaInfo[0].FvbInfo.BlockMap[0].NumBlocks = PcdGet32 (PcdFlashFvMainSize) / FVB_MEDIA_BLOCK_SIZE;
295   mPlatformFvbMediaInfo[0].FvbInfo.BlockMap[0].Length    = FVB_MEDIA_BLOCK_SIZE;
296   ASSERT ((PcdGet32 (PcdFlashFvMainSize) % FVB_MEDIA_BLOCK_SIZE) == 0);
297 
298   mPlatformFvbMediaInfo[1].BaseAddress      = PcdGet32 (PcdFlashNvStorageVariableBase);
299   mPlatformFvbMediaInfo[1].FvbInfo.FvLength = PcdGet32 (PcdFlashNvStorageVariableSize);
300   mPlatformFvbMediaInfo[1].FvbInfo.BlockMap[0].NumBlocks = PcdGet32 (PcdFlashNvStorageVariableSize) / FVB_MEDIA_BLOCK_SIZE;
301   mPlatformFvbMediaInfo[1].FvbInfo.BlockMap[0].Length    = FVB_MEDIA_BLOCK_SIZE;
302   ASSERT ((PcdGet32 (PcdFlashNvStorageVariableSize) % FVB_MEDIA_BLOCK_SIZE) == 0);
303 
304   mPlatformFvbMediaInfo[2].BaseAddress      = PcdGet32 (PcdFlashFvRecoveryBase);
305   mPlatformFvbMediaInfo[2].FvbInfo.FvLength = PcdGet32 (PcdFlashFvRecoverySize);
306   mPlatformFvbMediaInfo[2].FvbInfo.BlockMap[0].NumBlocks = PcdGet32 (PcdFlashFvRecoverySize) / FVB_MEDIA_BLOCK_SIZE;
307   mPlatformFvbMediaInfo[2].FvbInfo.BlockMap[0].Length    = FVB_MEDIA_BLOCK_SIZE;
308   ASSERT ((PcdGet32 (PcdFlashFvRecoverySize) % FVB_MEDIA_BLOCK_SIZE) == 0);
309 
310   mPlatformFvbMediaInfo[3].BaseAddress      = PcdGet32 (PcdFlashFvPayloadBase);
311   mPlatformFvbMediaInfo[3].FvbInfo.FvLength = PcdGet32 (PcdFlashFvPayloadSize);
312   mPlatformFvbMediaInfo[3].FvbInfo.BlockMap[0].NumBlocks = PcdGet32 (PcdFlashFvPayloadSize) / FVB_MEDIA_BLOCK_SIZE;
313   mPlatformFvbMediaInfo[3].FvbInfo.BlockMap[0].Length    = FVB_MEDIA_BLOCK_SIZE;
314   ASSERT ((PcdGet32 (PcdFlashFvPayloadSize) % FVB_MEDIA_BLOCK_SIZE) == 0);
315 
316   for (Index=0; Index < sizeof (mPlatformFvbMediaInfo)/sizeof (mPlatformFvbMediaInfo[0]); Index += 1) {
317     if (mPlatformFvbMediaInfo[Index].BaseAddress == FvBaseAddress) {
318       FvHeader =  &mPlatformFvbMediaInfo[Index].FvbInfo;
319       //
320       // Update the checksum value of FV header.
321       //
322       FvHeader->Checksum = CalculateCheckSum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16));
323 
324       *FvbInfo = FvHeader;
325 
326       DEBUG ((EFI_D_INFO, "\nBaseAddr: 0x%lx \n", FvBaseAddress));
327       DEBUG ((EFI_D_INFO, "FvLength: 0x%lx \n", (*FvbInfo)->FvLength));
328       DEBUG ((EFI_D_INFO, "HeaderLength: 0x%x \n", (*FvbInfo)->HeaderLength));
329       DEBUG ((EFI_D_INFO, "FvBlockMap[0].NumBlocks: 0x%x \n", (*FvbInfo)->BlockMap[0].NumBlocks));
330       DEBUG ((EFI_D_INFO, "FvBlockMap[0].BlockLength: 0x%x \n", (*FvbInfo)->BlockMap[0].Length));
331       DEBUG ((EFI_D_INFO, "FvBlockMap[1].NumBlocks: 0x%x \n",   (*FvbInfo)->BlockMap[1].NumBlocks));
332       DEBUG ((EFI_D_INFO, "FvBlockMap[1].BlockLength: 0x%x \n\n", (*FvbInfo)->BlockMap[1].Length));
333 
334       return EFI_SUCCESS;
335     }
336   }
337   return EFI_NOT_FOUND;
338 }
339