1 /**@file
2   Defines data structure that is the volume header found.
3   These data is intent to decouple FVB driver with FV header.
4 
5 Copyright (c) 2006  - 2015, Intel Corporation. All rights reserved.<BR>
6 
7 
8   This program and the accompanying materials are licensed and made available under
9 
10   the terms and conditions of the BSD License that accompanies this distribution.
11 
12   The full text of the license may be found at
13 
14   http://opensource.org/licenses/bsd-license.php.
15 
16 
17 
18   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
19 
20   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
21 
22 
23 
24 
25 **/
26 
27 #include <PiDxe.h>
28 #include <Protocol/FirmwareVolumeBlock.h>
29 #include <Library/PcdLib.h>
30 #include <Library/DebugLib.h>
31 #include <Library/BaseLib.h>
32 #include <Guid/FirmwareFileSystem2.h>
33 #include <Guid/SystemNvDataGuid.h>
34 
35 #define FIRMWARE_BLOCK_SIZE         0x8000
36 #define FVB_MEDIA_BLOCK_SIZE        (FIRMWARE_BLOCK_SIZE * 2)
37 
38 #define FV_RECOVERY_BASE_ADDRESS    FixedPcdGet32(PcdFlashFvRecoveryBase)
39 #define RECOVERY_BIOS_BLOCK_NUM     (FixedPcdGet32(PcdFlashFvRecoverySize) / FVB_MEDIA_BLOCK_SIZE)
40 
41 #define FV_MAIN_BASE_ADDRESS        FixedPcdGet32(PcdFlashFvMainBase)
42 #define MAIN_BIOS_BLOCK_NUM         (FixedPcdGet32(PcdFlashFvMainSize) / FVB_MEDIA_BLOCK_SIZE)
43 
44 #define NV_STORAGE_BASE_ADDRESS     FixedPcdGet32(PcdFlashNvStorageVariableBase)
45 #define SYSTEM_NV_BLOCK_NUM         ((FixedPcdGet32(PcdFlashNvStorageVariableSize)+ FixedPcdGet32(PcdFlashNvStorageFtwWorkingSize) + FixedPcdGet32(PcdFlashNvStorageFtwSpareSize))/ FVB_MEDIA_BLOCK_SIZE)
46 
47 typedef struct {
48   EFI_PHYSICAL_ADDRESS        BaseAddress;
49   EFI_FIRMWARE_VOLUME_HEADER  FvbInfo;
50   EFI_FV_BLOCK_MAP_ENTRY      End[1];
51 } EFI_FVB2_MEDIA_INFO;
52 
53 //
54 // This data structure contains a template of all correct FV headers, which is used to restore
55 // Fv header if it's corrupted.
56 //
57 EFI_FVB2_MEDIA_INFO mPlatformFvbMediaInfo[] = {
58   //
59   // Main BIOS FVB
60   //
61   {
62     FV_MAIN_BASE_ADDRESS,
63     {
64       {0,}, //ZeroVector[16]
65       EFI_FIRMWARE_FILE_SYSTEM2_GUID,
66       FVB_MEDIA_BLOCK_SIZE * MAIN_BIOS_BLOCK_NUM,
67       EFI_FVH_SIGNATURE,
68       0x0004feff, // check MdePkg/Include/Pi/PiFirmwareVolume.h for details on EFI_FVB_ATTRIBUTES_2
69       sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY),
70       0,    //CheckSum which will be calucated dynamically.
71       0,    //ExtHeaderOffset
72       {0,}, //Reserved[1]
73       2,    //Revision
74       {
75         {
76           MAIN_BIOS_BLOCK_NUM,
77           FVB_MEDIA_BLOCK_SIZE,
78         }
79       }
80     },
81     {
82       {
83         0,
84         0
85       }
86     }
87   },
88 
89   //
90   // Systen NvStorage FVB
91   //
92   {
93     NV_STORAGE_BASE_ADDRESS,
94     {
95       {0,}, //ZeroVector[16]
96       EFI_SYSTEM_NV_DATA_FV_GUID,
97       FVB_MEDIA_BLOCK_SIZE * SYSTEM_NV_BLOCK_NUM,
98       EFI_FVH_SIGNATURE,
99       0x0004feff, // check MdePkg/Include/Pi/PiFirmwareVolume.h for details on EFI_FVB_ATTRIBUTES_2
100       sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY),
101       0,    //CheckSum which will be calucated dynamically.
102       0,    //ExtHeaderOffset
103       {0,}, //Reserved[1]
104       2,    //Revision
105       {
106         {
107           SYSTEM_NV_BLOCK_NUM,
108           FVB_MEDIA_BLOCK_SIZE,
109         }
110       }
111     },
112     {
113       {
114         0,
115         0
116       }
117     }
118   },
119 
120   //
121   // Recovery BIOS FVB
122   //
123   {
124     FV_RECOVERY_BASE_ADDRESS,
125     {
126       {0,}, //ZeroVector[16]
127       EFI_FIRMWARE_FILE_SYSTEM2_GUID,
128       FVB_MEDIA_BLOCK_SIZE * RECOVERY_BIOS_BLOCK_NUM,
129       EFI_FVH_SIGNATURE,
130       0x0004feff, // check MdePkg/Include/Pi/PiFirmwareVolume.h for details on EFI_FVB_ATTRIBUTES_2
131       sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY),
132       0,    //CheckSum which will be calucated dynamically.
133       0,    //ExtHeaderOffset
134       {0,}, //Reserved[1]
135       2,    //Revision
136       {
137         {
138           RECOVERY_BIOS_BLOCK_NUM,
139           FVB_MEDIA_BLOCK_SIZE,
140         }
141       }
142     },
143     {
GetFvbInfo(IN EFI_PHYSICAL_ADDRESS FvBaseAddress,OUT EFI_FIRMWARE_VOLUME_HEADER ** FvbInfo)144       {
145         0,
146         0
147       }
148     }
149   }
150 };
151 
152 EFI_STATUS
153 GetFvbInfo (
154   IN  EFI_PHYSICAL_ADDRESS         FvBaseAddress,
155   OUT EFI_FIRMWARE_VOLUME_HEADER   **FvbInfo
156   )
157 {
158   UINTN                       Index;
159   EFI_FIRMWARE_VOLUME_HEADER  *FvHeader;
160 
161   for (Index = 0; Index < sizeof (mPlatformFvbMediaInfo) / sizeof (EFI_FVB2_MEDIA_INFO); Index += 1) {
162     if (mPlatformFvbMediaInfo[Index].BaseAddress == FvBaseAddress) {
163       FvHeader =  &mPlatformFvbMediaInfo[Index].FvbInfo;
164 
165       //
166       // Update the checksum value of FV header.
167       //
168       FvHeader->Checksum = CalculateCheckSum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength);
169 
170       *FvbInfo = FvHeader;
171 
172       DEBUG ((EFI_D_INFO, "\nBaseAddr: 0x%lx \n", FvBaseAddress));
173       DEBUG ((EFI_D_INFO, "FvLength: 0x%lx \n", (*FvbInfo)->FvLength));
174       DEBUG ((EFI_D_INFO, "HeaderLength: 0x%x \n", (*FvbInfo)->HeaderLength));
175       DEBUG ((EFI_D_INFO, "FvBlockMap[0].NumBlocks: 0x%x \n", (*FvbInfo)->BlockMap[0].NumBlocks));
176       DEBUG ((EFI_D_INFO, "FvBlockMap[0].BlockLength: 0x%x \n", (*FvbInfo)->BlockMap[0].Length));
177       DEBUG ((EFI_D_INFO, "FvBlockMap[1].NumBlocks: 0x%x \n",   (*FvbInfo)->BlockMap[1].NumBlocks));
178       DEBUG ((EFI_D_INFO, "FvBlockMap[1].BlockLength: 0x%x \n\n", (*FvbInfo)->BlockMap[1].Length));
179 
180       return EFI_SUCCESS;
181     }
182   }
183   return EFI_NOT_FOUND;
184 }
185