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 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 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