13cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/**@file
23cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  Defines data structure that is the volume header found.
33cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  These data is intent to decouple FVB driver with FV header.
43cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
5abbe4e57f4bf753613535a85f3bd82067644bdaeStar ZengCopyright (c) 2006  - 2015, Intel Corporation. All rights reserved.<BR>
63cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
73cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
83cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  This program and the accompanying materials are licensed and made available under
93cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
103cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  the terms and conditions of the BSD License that accompanies this distribution.
113cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
123cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  The full text of the license may be found at
133cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
143cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  http://opensource.org/licenses/bsd-license.php.
153cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
163cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
173cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
183cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
193cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
203cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
213cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
223cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
233cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
243cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
253cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei**/
263cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
273cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei#include <PiDxe.h>
283cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei#include <Protocol/FirmwareVolumeBlock.h>
293cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei#include <Library/PcdLib.h>
303cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei#include <Library/DebugLib.h>
313cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei#include <Library/BaseLib.h>
323cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei#include <Guid/FirmwareFileSystem2.h>
333cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei#include <Guid/SystemNvDataGuid.h>
343cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
353cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei#define FIRMWARE_BLOCK_SIZE         0x8000
363cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei#define FVB_MEDIA_BLOCK_SIZE        (FIRMWARE_BLOCK_SIZE * 2)
373cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
383cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei#define FV_RECOVERY_BASE_ADDRESS    FixedPcdGet32(PcdFlashFvRecoveryBase)
393cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei#define RECOVERY_BIOS_BLOCK_NUM     (FixedPcdGet32(PcdFlashFvRecoverySize) / FVB_MEDIA_BLOCK_SIZE)
403cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
413cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei#define FV_MAIN_BASE_ADDRESS        FixedPcdGet32(PcdFlashFvMainBase)
423cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei#define MAIN_BIOS_BLOCK_NUM         (FixedPcdGet32(PcdFlashFvMainSize) / FVB_MEDIA_BLOCK_SIZE)
433cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
443cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei#define NV_STORAGE_BASE_ADDRESS     FixedPcdGet32(PcdFlashNvStorageVariableBase)
453cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei#define SYSTEM_NV_BLOCK_NUM         ((FixedPcdGet32(PcdFlashNvStorageVariableSize)+ FixedPcdGet32(PcdFlashNvStorageFtwWorkingSize) + FixedPcdGet32(PcdFlashNvStorageFtwSpareSize))/ FVB_MEDIA_BLOCK_SIZE)
463cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
473cbfba02fef9dae07a041fdbf2e89611d72d6f90David Weitypedef struct {
483cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  EFI_PHYSICAL_ADDRESS        BaseAddress;
493cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  EFI_FIRMWARE_VOLUME_HEADER  FvbInfo;
503cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  EFI_FV_BLOCK_MAP_ENTRY      End[1];
513cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei} EFI_FVB2_MEDIA_INFO;
523cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
533cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei//
543cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei// This data structure contains a template of all correct FV headers, which is used to restore
553cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei// Fv header if it's corrupted.
563cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei//
573cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFI_FVB2_MEDIA_INFO mPlatformFvbMediaInfo[] = {
583cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  //
593cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  // Main BIOS FVB
603cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  //
613cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  {
623cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei    FV_MAIN_BASE_ADDRESS,
633cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei    {
643cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      {0,}, //ZeroVector[16]
653cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      EFI_FIRMWARE_FILE_SYSTEM2_GUID,
663cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      FVB_MEDIA_BLOCK_SIZE * MAIN_BIOS_BLOCK_NUM,
673cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      EFI_FVH_SIGNATURE,
683cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      0x0004feff, // check MdePkg/Include/Pi/PiFirmwareVolume.h for details on EFI_FVB_ATTRIBUTES_2
693cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY),
703cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      0,    //CheckSum which will be calucated dynamically.
713cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      0,    //ExtHeaderOffset
723cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      {0,}, //Reserved[1]
733cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      2,    //Revision
743cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      {
753cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei        {
763cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei          MAIN_BIOS_BLOCK_NUM,
773cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei          FVB_MEDIA_BLOCK_SIZE,
783cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei        }
793cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      }
803cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei    },
813cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei    {
823cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      {
833cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei        0,
843cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei        0
853cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      }
863cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei    }
873cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  },
883cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
893cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  //
903cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  // Systen NvStorage FVB
913cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  //
923cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  {
933cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei    NV_STORAGE_BASE_ADDRESS,
943cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei    {
953cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      {0,}, //ZeroVector[16]
963cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      EFI_SYSTEM_NV_DATA_FV_GUID,
973cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      FVB_MEDIA_BLOCK_SIZE * SYSTEM_NV_BLOCK_NUM,
983cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      EFI_FVH_SIGNATURE,
993cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      0x0004feff, // check MdePkg/Include/Pi/PiFirmwareVolume.h for details on EFI_FVB_ATTRIBUTES_2
1003cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY),
1013cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      0,    //CheckSum which will be calucated dynamically.
1023cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      0,    //ExtHeaderOffset
1033cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      {0,}, //Reserved[1]
1043cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      2,    //Revision
1053cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      {
1063cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei        {
1073cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei          SYSTEM_NV_BLOCK_NUM,
1083cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei          FVB_MEDIA_BLOCK_SIZE,
1093cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei        }
1103cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      }
1113cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei    },
1123cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei    {
1133cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      {
1143cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei        0,
1153cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei        0
1163cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      }
1173cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei    }
1183cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  },
1193cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
1203cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  //
1213cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  // Recovery BIOS FVB
1223cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  //
1233cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  {
1243cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei    FV_RECOVERY_BASE_ADDRESS,
1253cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei    {
1263cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      {0,}, //ZeroVector[16]
1273cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      EFI_FIRMWARE_FILE_SYSTEM2_GUID,
1283cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      FVB_MEDIA_BLOCK_SIZE * RECOVERY_BIOS_BLOCK_NUM,
1293cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      EFI_FVH_SIGNATURE,
1303cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      0x0004feff, // check MdePkg/Include/Pi/PiFirmwareVolume.h for details on EFI_FVB_ATTRIBUTES_2
1313cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY),
1323cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      0,    //CheckSum which will be calucated dynamically.
1333cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      0,    //ExtHeaderOffset
1343cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      {0,}, //Reserved[1]
1353cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      2,    //Revision
1363cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      {
1373cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei        {
1383cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei          RECOVERY_BIOS_BLOCK_NUM,
1393cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei          FVB_MEDIA_BLOCK_SIZE,
1403cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei        }
1413cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      }
1423cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei    },
1433cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei    {
1443cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      {
1453cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei        0,
1463cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei        0
1473cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      }
1483cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei    }
1493cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  }
1503cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei};
1513cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
1523cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFI_STATUS
1533cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiGetFvbInfo (
1543cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  IN  EFI_PHYSICAL_ADDRESS         FvBaseAddress,
1553cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  OUT EFI_FIRMWARE_VOLUME_HEADER   **FvbInfo
1563cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  )
1573cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei{
1583cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  UINTN                       Index;
159abbe4e57f4bf753613535a85f3bd82067644bdaeStar Zeng  EFI_FIRMWARE_VOLUME_HEADER  *FvHeader;
1603cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
1613cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei  for (Index = 0; Index < sizeof (mPlatformFvbMediaInfo) / sizeof (EFI_FVB2_MEDIA_INFO); Index += 1) {
1623cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei    if (mPlatformFvbMediaInfo[Index].BaseAddress == FvBaseAddress) {
1633cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      FvHeader =  &mPlatformFvbMediaInfo[Index].FvbInfo;
1643cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
1653cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      //
1663cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      // Update the checksum value of FV header.
1673cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      //
1683cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      FvHeader->Checksum = CalculateCheckSum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength);
1693cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
1703cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      *FvbInfo = FvHeader;
1713cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei
1723cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      DEBUG ((EFI_D_INFO, "\nBaseAddr: 0x%lx \n", FvBaseAddress));
1733cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      DEBUG ((EFI_D_INFO, "FvLength: 0x%lx \n", (*FvbInfo)->FvLength));
1743cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      DEBUG ((EFI_D_INFO, "HeaderLength: 0x%x \n", (*FvbInfo)->HeaderLength));
1753cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei      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