Home | History | Annotate | Download | only in SpiFvbServices
      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