/** @file
  Firmware Block Services to support emulating non-volatile variables
  by pretending that a memory buffer is storage for the NV variables.

  Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
  This program and the accompanying materials
  are licensed and made available under the terms and conditions of the BSD License
  which accompanies this distribution.  The full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "PiDxe.h"
#include <Guid/EventGroup.h>
#include <Guid/SystemNvDataGuid.h>
#include <Guid/VariableFormat.h>

#include <Protocol/FirmwareVolumeBlock.h>
#include <Protocol/DevicePath.h>

#include <Library/UefiLib.h>
#include <Library/UefiDriverEntryPoint.h>
#include <Library/BaseLib.h>
#include <Library/UefiRuntimeLib.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/DevicePathLib.h>
#include <Library/PcdLib.h>
#include <Library/PlatformFvbLib.h>
#include "Fvb.h"

#define EFI_AUTHENTICATED_VARIABLE_GUID \
{ 0xaaf32c78, 0x947b, 0x439a, { 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92 } }

//
// Virtual Address Change Event
//
// This is needed for runtime variable access.
//
EFI_EVENT   mEmuVarsFvbAddrChangeEvent = NULL;

//
// This is the single instance supported by this driver.  It
// supports the FVB and Device Path protocols.
//
EFI_FW_VOL_BLOCK_DEVICE mEmuVarsFvb = {
  FVB_DEVICE_SIGNATURE,
  {     // DevicePath
    {
      {
        HARDWARE_DEVICE_PATH,
        HW_MEMMAP_DP,
        {
          sizeof (MEMMAP_DEVICE_PATH),
          0
        }
      },
      EfiMemoryMappedIO,
      0,
      0,
    },
    {
      END_DEVICE_PATH_TYPE,
      END_ENTIRE_DEVICE_PATH_SUBTYPE,
      {
        sizeof (EFI_DEVICE_PATH_PROTOCOL),
        0
      }
    }
  },
  NULL, // BufferPtr
  FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize), // BlockSize
  2 * FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize), // Size
  {     // FwVolBlockInstance
    FvbProtocolGetAttributes,
    FvbProtocolSetAttributes,
    FvbProtocolGetPhysicalAddress,
    FvbProtocolGetBlockSize,
    FvbProtocolRead,
    FvbProtocolWrite,
    FvbProtocolEraseBlocks,
    NULL
  },
};


/**
  Notification function of EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE.

  This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.
  It converts pointer to new virtual address.

  @param  Event        Event whose notification function is being invoked.
  @param  Context      Pointer to the notification function's context.

**/
VOID
EFIAPI
FvbVirtualAddressChangeEvent (
  IN EFI_EVENT        Event,
  IN VOID             *Context
  )
{
  EfiConvertPointer (0x0, &mEmuVarsFvb.BufferPtr);
}


//
// FVB protocol APIs
//

/**
  The GetPhysicalAddress() function retrieves the base address of
  a memory-mapped firmware volume. This function should be called
  only for memory-mapped firmware volumes.

  @param This     Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
  
  @param Address  Pointer to a caller-allocated
                  EFI_PHYSICAL_ADDRESS that, on successful
                  return from GetPhysicalAddress(), contains the
                  base address of the firmware volume.
  
  @retval EFI_SUCCESS       The firmware volume base address is returned.
  
  @retval EFI_NOT_SUPPORTED The firmware volume is not memory mapped.

**/
EFI_STATUS
EFIAPI
FvbProtocolGetPhysicalAddress (
  IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
  OUT       EFI_PHYSICAL_ADDRESS                *Address
  )
{
  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;

  FvbDevice = FVB_DEVICE_FROM_THIS (This);

  *Address = (EFI_PHYSICAL_ADDRESS)(UINTN) FvbDevice->BufferPtr;

  return EFI_SUCCESS;
}


/**
  The GetBlockSize() function retrieves the size of the requested
  block. It also returns the number of additional blocks with
  the identical size. The GetBlockSize() function is used to
  retrieve the block map (see EFI_FIRMWARE_VOLUME_HEADER).


  @param This           Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.

  @param Lba            Indicates the block for which to return the size.

  @param BlockSize      Pointer to a caller-allocated UINTN in which
                        the size of the block is returned.

  @param NumberOfBlocks Pointer to a caller-allocated UINTN in
                        which the number of consecutive blocks,
                        starting with Lba, is returned. All
                        blocks in this range have a size of
                        BlockSize.

  
  @retval EFI_SUCCESS             The firmware volume base address is returned.
  
  @retval EFI_INVALID_PARAMETER   The requested LBA is out of range.

**/
EFI_STATUS
EFIAPI
FvbProtocolGetBlockSize (
  IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
  IN        EFI_LBA                             Lba,
  OUT       UINTN                               *BlockSize,
  OUT       UINTN                               *NumberOfBlocks
  )
{
  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;

  if (Lba > 1) {
    return EFI_INVALID_PARAMETER;
  }

  FvbDevice = FVB_DEVICE_FROM_THIS (This);

  *BlockSize = FvbDevice->BlockSize;
  *NumberOfBlocks = (UINTN) (2 - (UINTN) Lba);

  return EFI_SUCCESS;
}


/**
  The GetAttributes() function retrieves the attributes and
  current settings of the block. Status Codes Returned

  @param This       Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.

  @param Attributes Pointer to EFI_FVB_ATTRIBUTES_2 in which the
                    attributes and current settings are
                    returned. Type EFI_FVB_ATTRIBUTES_2 is defined
                    in EFI_FIRMWARE_VOLUME_HEADER.

  @retval EFI_SUCCESS The firmware volume attributes were
                      returned.

**/
EFI_STATUS
EFIAPI
FvbProtocolGetAttributes (
  IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
  OUT       EFI_FVB_ATTRIBUTES_2                *Attributes
  )
{
  *Attributes =
    (EFI_FVB_ATTRIBUTES_2) (
      EFI_FVB2_READ_ENABLED_CAP |
      EFI_FVB2_READ_STATUS |
      EFI_FVB2_WRITE_ENABLED_CAP |
      EFI_FVB2_WRITE_STATUS |
      EFI_FVB2_ERASE_POLARITY
      );

  return EFI_SUCCESS;
}


/**
  The SetAttributes() function sets configurable firmware volume
  attributes and returns the new settings of the firmware volume.

  @param This         Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.

  @param Attributes   On input, Attributes is a pointer to
                      EFI_FVB_ATTRIBUTES_2 that contains the
                      desired firmware volume settings. On
                      successful return, it contains the new
                      settings of the firmware volume. Type
                      EFI_FVB_ATTRIBUTES_2 is defined in
                      EFI_FIRMWARE_VOLUME_HEADER.
  
  @retval EFI_SUCCESS           The firmware volume attributes were returned.

  @retval EFI_INVALID_PARAMETER The attributes requested are in
                                conflict with the capabilities
                                as declared in the firmware
                                volume header.

**/
EFI_STATUS
EFIAPI
FvbProtocolSetAttributes (
  IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
  IN OUT    EFI_FVB_ATTRIBUTES_2                *Attributes
  )
{
  return EFI_ACCESS_DENIED;
}


/**
  Erases and initializes a firmware volume block.

  The EraseBlocks() function erases one or more blocks as denoted
  by the variable argument list. The entire parameter list of
  blocks must be verified before erasing any blocks. If a block is
  requested that does not exist within the associated firmware
  volume (it has a larger index than the last block of the
  firmware volume), the EraseBlocks() function must return the
  status code EFI_INVALID_PARAMETER without modifying the contents
  of the firmware volume. Implementations should be mindful that
  the firmware volume might be in the WriteDisabled state. If it
  is in this state, the EraseBlocks() function must return the
  status code EFI_ACCESS_DENIED without modifying the contents of
  the firmware volume. All calls to EraseBlocks() must be fully
  flushed to the hardware before the EraseBlocks() service
  returns.

  @param This   Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL
                instance.

  @param ...    The variable argument list is a list of tuples.
                Each tuple describes a range of LBAs to erase
                and consists of the following:
                - An EFI_LBA that indicates the starting LBA
                - A UINTN that indicates the number of blocks to
                  erase

                The list is terminated with an
                EFI_LBA_LIST_TERMINATOR. For example, the
                following indicates that two ranges of blocks
                (5-7 and 10-11) are to be erased: EraseBlocks
                (This, 5, 3, 10, 2, EFI_LBA_LIST_TERMINATOR);

  @retval EFI_SUCCESS The erase request was successfully
                      completed.
  
  @retval EFI_ACCESS_DENIED   The firmware volume is in the
                              WriteDisabled state.
  @retval EFI_DEVICE_ERROR  The block device is not functioning
                            correctly and could not be written.
                            The firmware device may have been
                            partially erased.
  @retval EFI_INVALID_PARAMETER One or more of the LBAs listed
                                in the variable argument list do
                                not exist in the firmware volume.  

**/
EFI_STATUS
EFIAPI
FvbProtocolEraseBlocks (
  IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
  ...
  )
{
  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
  VA_LIST                 args;
  EFI_LBA                 StartingLba;
  UINTN                   NumOfLba;
  UINT8                   Erase;
  VOID                    *ErasePtr;
  UINTN                   EraseSize;

  FvbDevice = FVB_DEVICE_FROM_THIS (This);
  Erase = 0;

  VA_START (args, This);

  do {
    StartingLba = VA_ARG (args, EFI_LBA);
    if (StartingLba == EFI_LBA_LIST_TERMINATOR) {
      break;
    }

    NumOfLba = VA_ARG (args, UINT32);

    //
    // Check input parameters
    //
    if ((NumOfLba == 0) || (StartingLba > 1) || ((StartingLba + NumOfLba) > 2)) {
      VA_END (args);
      return EFI_INVALID_PARAMETER;
    }

    if (StartingLba == 0) {
      Erase = (UINT8) (Erase | BIT0);
    }
    if ((StartingLba + NumOfLba) == 2) {
      Erase = (UINT8) (Erase | BIT1);
    }

  } while (1);

  VA_END (args);

  ErasePtr = (UINT8*) FvbDevice->BufferPtr;
  EraseSize = 0;

  if ((Erase & BIT0) != 0) {
    EraseSize = EraseSize + FvbDevice->BlockSize;
  } else {
    ErasePtr = (VOID*) ((UINT8*)ErasePtr + FvbDevice->BlockSize);
  }

  if ((Erase & BIT1) != 0) {
    EraseSize = EraseSize + FvbDevice->BlockSize;
  }

  if (EraseSize != 0) {
    SetMem (
      (VOID*) ErasePtr,
      EraseSize,
      ERASED_UINT8
      );
    VA_START (args, This);
    PlatformFvbBlocksErased (This, args);
    VA_END (args);
  }

  return EFI_SUCCESS;
}


/**
  Writes the specified number of bytes from the input buffer to the block.

  The Write() function writes the specified number of bytes from
  the provided buffer to the specified block and offset. If the
  firmware volume is sticky write, the caller must ensure that
  all the bits of the specified range to write are in the
  EFI_FVB_ERASE_POLARITY state before calling the Write()
  function, or else the result will be unpredictable. This
  unpredictability arises because, for a sticky-write firmware
  volume, a write may negate a bit in the EFI_FVB_ERASE_POLARITY
  state but cannot flip it back again. In general, before
  calling the Write() function, the caller should call the
  EraseBlocks() function first to erase the specified block to
  write. A block erase cycle will transition bits from the
  (NOT)EFI_FVB_ERASE_POLARITY state back to the
  EFI_FVB_ERASE_POLARITY state. Implementations should be
  mindful that the firmware volume might be in the WriteDisabled
  state. If it is in this state, the Write() function must
  return the status code EFI_ACCESS_DENIED without modifying the
  contents of the firmware volume. The Write() function must
  also prevent spanning block boundaries. If a write is
  requested that spans a block boundary, the write must store up
  to the boundary but not beyond. The output parameter NumBytes
  must be set to correctly indicate the number of bytes actually
  written. The caller must be aware that a write may be
  partially completed. All writes, partial or otherwise, must be
  fully flushed to the hardware before the Write() service
  returns.

  @param This     Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
  
  @param Lba      The starting logical block index to write to.
  
  @param Offset   Offset into the block at which to begin writing.
  
  @param NumBytes Pointer to a UINTN. At entry, *NumBytes
                  contains the total size of the buffer. At
                  exit, *NumBytes contains the total number of
                  bytes actually written.
  
  @param Buffer   Pointer to a caller-allocated buffer that
                  contains the source for the write.
  
  @retval EFI_SUCCESS         The firmware volume was written successfully.
  
  @retval EFI_BAD_BUFFER_SIZE The write was attempted across an
                              LBA boundary. On output, NumBytes
                              contains the total number of bytes
                              actually written.
  
  @retval EFI_ACCESS_DENIED   The firmware volume is in the
                              WriteDisabled state.
  
  @retval EFI_DEVICE_ERROR    The block device is malfunctioning
                              and could not be written.


**/
EFI_STATUS
EFIAPI
FvbProtocolWrite (
  IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
  IN        EFI_LBA                             Lba,
  IN        UINTN                               Offset,
  IN OUT    UINTN                               *NumBytes,
  IN        UINT8                               *Buffer
  )
{

  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
  UINT8                   *FvbDataPtr;

  FvbDevice = FVB_DEVICE_FROM_THIS (This);

  if ((Lba > 1) || (Offset > FvbDevice->BlockSize)) {
    return EFI_INVALID_PARAMETER;
  }

  if ((Offset + *NumBytes) > FvbDevice->BlockSize) {
    *NumBytes = FvbDevice->BlockSize - Offset;
  }

  FvbDataPtr =
    (UINT8*) FvbDevice->BufferPtr +
    MultU64x32 (Lba, (UINT32) FvbDevice->BlockSize) +
    Offset;

  if (*NumBytes > 0) {
    CopyMem (FvbDataPtr, Buffer, *NumBytes);
    PlatformFvbDataWritten (This, Lba, Offset, *NumBytes, Buffer);
  }

  return EFI_SUCCESS;
}


/**
  Reads the specified number of bytes into a buffer from the specified block.

  The Read() function reads the requested number of bytes from the
  requested block and stores them in the provided buffer.
  Implementations should be mindful that the firmware volume
  might be in the ReadDisabled state. If it is in this state,
  the Read() function must return the status code
  EFI_ACCESS_DENIED without modifying the contents of the
  buffer. The Read() function must also prevent spanning block
  boundaries. If a read is requested that would span a block
  boundary, the read must read up to the boundary but not
  beyond. The output parameter NumBytes must be set to correctly
  indicate the number of bytes actually read. The caller must be
  aware that a read may be partially completed.

  @param This     Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
  
  @param Lba      The starting logical block index
                  from which to read.

  @param Offset   Offset into the block at which to begin reading.

  @param NumBytes Pointer to a UINTN. At entry, *NumBytes
                  contains the total size of the buffer. At
                  exit, *NumBytes contains the total number of
                  bytes read.

  @param Buffer   Pointer to a caller-allocated buffer that will
                  be used to hold the data that is read.

  @retval EFI_SUCCESS         The firmware volume was read successfully
                              and contents are in Buffer.
  
  @retval EFI_BAD_BUFFER_SIZE Read attempted across an LBA
                              boundary. On output, NumBytes
                              contains the total number of bytes
                              returned in Buffer.
  
  @retval EFI_ACCESS_DENIED   The firmware volume is in the
                              ReadDisabled state.
  
  @retval EFI_DEVICE_ERROR    The block device is not
                              functioning correctly and could
                              not be read.

**/
EFI_STATUS
EFIAPI
FvbProtocolRead (
  IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
  IN        EFI_LBA                             Lba,
  IN        UINTN                               Offset,
  IN OUT    UINTN                               *NumBytes,
  IN OUT    UINT8                               *Buffer
  )
{
  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
  UINT8                   *FvbDataPtr;

  FvbDevice = FVB_DEVICE_FROM_THIS (This);

  if ((Lba > 1) || (Offset > FvbDevice->BlockSize)) {
    return EFI_INVALID_PARAMETER;
  }

  if ((Offset + *NumBytes) > FvbDevice->BlockSize) {
    *NumBytes = FvbDevice->BlockSize - Offset;
  }

  FvbDataPtr =
    (UINT8*) FvbDevice->BufferPtr +
    MultU64x32 (Lba, (UINT32) FvbDevice->BlockSize) +
    Offset;

  if (*NumBytes > 0) {
    CopyMem (Buffer, FvbDataPtr, *NumBytes);
    PlatformFvbDataRead (This, Lba, Offset, *NumBytes, Buffer);
  }

  return EFI_SUCCESS;
}


/**
  Check the integrity of firmware volume header.

  @param[in] FwVolHeader - A pointer to a firmware volume header

  @retval  EFI_SUCCESS   - The firmware volume is consistent
  @retval  EFI_NOT_FOUND - The firmware volume has been corrupted.

**/
EFI_STATUS
ValidateFvHeader (
  IN EFI_FIRMWARE_VOLUME_HEADER   *FwVolHeader
  )
{
  UINT16  Checksum;

  //
  // Verify the header revision, header signature, length
  // Length of FvBlock cannot be 2**64-1
  // HeaderLength cannot be an odd number
  //
  if ((FwVolHeader->Revision != EFI_FVH_REVISION) ||
      (FwVolHeader->Signature != EFI_FVH_SIGNATURE) ||
      (FwVolHeader->FvLength != EMU_FVB_SIZE) ||
      (FwVolHeader->HeaderLength != EMU_FV_HEADER_LENGTH)
      ) {
    DEBUG ((EFI_D_INFO, "EMU Variable FVB: Basic FV headers were invalid\n"));
    return EFI_NOT_FOUND;
  }
  //
  // Verify the header checksum
  //
  Checksum = CalculateSum16((VOID*) FwVolHeader, FwVolHeader->HeaderLength);

  if (Checksum != 0) {
    DEBUG ((EFI_D_INFO, "EMU Variable FVB: FV checksum was invalid\n"));
    return EFI_NOT_FOUND;
  }

  return EFI_SUCCESS;
}


/**
  Initializes the FV Header and Variable Store Header
  to support variable operations.

  @param[in]  Ptr - Location to initialize the headers

**/
VOID
InitializeFvAndVariableStoreHeaders (
  IN  VOID   *Ptr
  )
{
  //
  // Templates for standard (non-authenticated) variable FV header
  //
  STATIC FVB_FV_HDR_AND_VARS_TEMPLATE FvAndVarTemplate = {
    { // EFI_FIRMWARE_VOLUME_HEADER FvHdr;
      // UINT8                     ZeroVector[16];
      { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },

      // EFI_GUID                  FileSystemGuid;
      EFI_SYSTEM_NV_DATA_FV_GUID,

      // UINT64                    FvLength;
      EMU_FVB_SIZE,

      // UINT32                    Signature;
      EFI_FVH_SIGNATURE,

      // EFI_FVB_ATTRIBUTES_2      Attributes;
      0x4feff,

      // UINT16                    HeaderLength;
      EMU_FV_HEADER_LENGTH,

      // UINT16                    Checksum;
      0,

      // UINT16                    ExtHeaderOffset;
      0,

      // UINT8                     Reserved[1];
      {0},

      // UINT8                     Revision;
      EFI_FVH_REVISION,

      // EFI_FV_BLOCK_MAP_ENTRY    BlockMap[1];
      { 
        {
          2, // UINT32 NumBlocks;
          EMU_FVB_BLOCK_SIZE  // UINT32 Length;
        }
      }
    },
    // EFI_FV_BLOCK_MAP_ENTRY     EndBlockMap;
    { 0, 0 }, // End of block map
    { // VARIABLE_STORE_HEADER      VarHdr;
      // EFI_GUID  Signature;
      EFI_VARIABLE_GUID,

      // UINT32  Size;
      (
        FixedPcdGet32 (PcdVariableStoreSize) -
        OFFSET_OF (FVB_FV_HDR_AND_VARS_TEMPLATE, VarHdr)
      ),

      // UINT8   Format;
      VARIABLE_STORE_FORMATTED,

      // UINT8   State;
      VARIABLE_STORE_HEALTHY,

      // UINT16  Reserved;
      0,

      // UINT32  Reserved1;
      0
    }
  };

  //
  // Templates for authenticated variable FV header
  //
  STATIC FVB_FV_HDR_AND_VARS_TEMPLATE FvAndAuthenticatedVarTemplate = {
    { // EFI_FIRMWARE_VOLUME_HEADER FvHdr;
      // UINT8                     ZeroVector[16];
      { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },

      // EFI_GUID                  FileSystemGuid;
      EFI_SYSTEM_NV_DATA_FV_GUID,

      // UINT64                    FvLength;
      EMU_FVB_SIZE,

      // UINT32                    Signature;
      EFI_FVH_SIGNATURE,

      // EFI_FVB_ATTRIBUTES_2      Attributes;
      0x4feff,

      // UINT16                    HeaderLength;
      EMU_FV_HEADER_LENGTH,

      // UINT16                    Checksum;
      0,

      // UINT16                    ExtHeaderOffset;
      0,

      // UINT8                     Reserved[1];
      {0},

      // UINT8                     Revision;
      EFI_FVH_REVISION,

      // EFI_FV_BLOCK_MAP_ENTRY    BlockMap[1];
      {
        {
          2, // UINT32 NumBlocks;
          EMU_FVB_BLOCK_SIZE  // UINT32 Length;
        }
      }
    },
    // EFI_FV_BLOCK_MAP_ENTRY     EndBlockMap;
    { 0, 0 }, // End of block map
    { // VARIABLE_STORE_HEADER      VarHdr;
        // EFI_GUID  Signature;     // need authenticated variables for secure boot
        EFI_AUTHENTICATED_VARIABLE_GUID,

      // UINT32  Size;
      (
        FixedPcdGet32 (PcdVariableStoreSize) -
        OFFSET_OF (FVB_FV_HDR_AND_VARS_TEMPLATE, VarHdr)
      ),

      // UINT8   Format;
      VARIABLE_STORE_FORMATTED,

      // UINT8   State;
      VARIABLE_STORE_HEALTHY,

      // UINT16  Reserved;
      0,

      // UINT32  Reserved1;
      0
    }
  };

  EFI_FIRMWARE_VOLUME_HEADER  *Fv;

  //
  // Copy the template structure into the location
  //
  if (FeaturePcdGet (PcdSecureBootEnable) == FALSE) {
    CopyMem (Ptr, (VOID*)&FvAndVarTemplate, sizeof (FvAndVarTemplate));
  } else {
    CopyMem (Ptr, (VOID*)&FvAndAuthenticatedVarTemplate, sizeof (FvAndAuthenticatedVarTemplate));
  }

  //
  // Update the checksum for the FV header
  //
  Fv = (EFI_FIRMWARE_VOLUME_HEADER*) Ptr;
  Fv->Checksum = CalculateCheckSum16 (Ptr, Fv->HeaderLength);
}

/**
  Main entry point.

  @param[in] ImageHandle    The firmware allocated handle for the EFI image.  
  @param[in] SystemTable    A pointer to the EFI System Table.
  
  @retval EFI_SUCCESS       Successfully initialized.

**/
EFI_STATUS
EFIAPI
FvbInitialize (
  IN EFI_HANDLE         ImageHandle,
  IN EFI_SYSTEM_TABLE   *SystemTable
  )
{
  EFI_STATUS                          Status;
  VOID                                *Ptr;
  VOID                                *SubPtr;
  BOOLEAN                             Initialize;
  EFI_HANDLE                          Handle;
  EFI_PHYSICAL_ADDRESS                Address;

  DEBUG ((EFI_D_INFO, "EMU Variable FVB Started\n"));

  //
  // Verify that the PCD's are set correctly.
  //
  if (
       (PcdGet32 (PcdVariableStoreSize) +
        PcdGet32 (PcdFlashNvStorageFtwWorkingSize)
       ) >
       EMU_FVB_BLOCK_SIZE
     ) {
    DEBUG ((EFI_D_ERROR, "EMU Variable invalid PCD sizes\n"));
    return EFI_INVALID_PARAMETER;
  }

  if (PcdGet64 (PcdFlashNvStorageVariableBase64) != 0) {
    DEBUG ((EFI_D_INFO, "Disabling EMU Variable FVB since "
                        "flash variables appear to be supported.\n"));
    return EFI_ABORTED;
  }

  //
  // By default we will initialize the FV contents.  But, if
  // PcdEmuVariableNvStoreReserved is non-zero, then we will
  // use this location for our buffer.
  //
  // If this location does not have a proper FV header, then
  // we will initialize it.
  //
  Initialize = TRUE;
  if (PcdGet64 (PcdEmuVariableNvStoreReserved) != 0) {
    Ptr = (VOID*)(UINTN) PcdGet64 (PcdEmuVariableNvStoreReserved);
    DEBUG ((
      EFI_D_INFO,
      "EMU Variable FVB: Using pre-reserved block at %p\n",
      Ptr
      ));
    Status = ValidateFvHeader (Ptr);
    if (!EFI_ERROR (Status)) {
      DEBUG ((EFI_D_INFO, "EMU Variable FVB: Found valid pre-existing FV\n"));
      Initialize = FALSE;
    }
  } else {
    Ptr = AllocateAlignedRuntimePages (
            EFI_SIZE_TO_PAGES (EMU_FVB_SIZE),
            SIZE_64KB
            );
  }

  mEmuVarsFvb.BufferPtr = Ptr;

  //
  // Initialize the main FV header and variable store header
  //
  if (Initialize) {
    SetMem (Ptr, EMU_FVB_SIZE, ERASED_UINT8);
    InitializeFvAndVariableStoreHeaders (Ptr);
  }
  PcdSet64 (PcdFlashNvStorageVariableBase64, (UINT32)(UINTN) Ptr);

  //
  // Initialize the Fault Tolerant Write data area
  //
  SubPtr = (VOID*) ((UINT8*) Ptr + PcdGet32 (PcdVariableStoreSize));
  PcdSet32 (PcdFlashNvStorageFtwWorkingBase, (UINT32)(UINTN) SubPtr);

  //
  // Initialize the Fault Tolerant Write spare block
  //
  SubPtr = (VOID*) ((UINT8*) Ptr + EMU_FVB_BLOCK_SIZE);
  PcdSet32 (PcdFlashNvStorageFtwSpareBase, (UINT32)(UINTN) SubPtr);

  //
  // Setup FVB device path
  //
  Address = (EFI_PHYSICAL_ADDRESS)(UINTN) Ptr;
  mEmuVarsFvb.DevicePath.MemMapDevPath.StartingAddress = Address;
  mEmuVarsFvb.DevicePath.MemMapDevPath.EndingAddress = Address + EMU_FVB_SIZE - 1;

  //
  // Install the protocols
  //
  DEBUG ((EFI_D_INFO, "Installing FVB for EMU Variable support\n"));
  Handle = 0;
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &Handle,
                  &gEfiFirmwareVolumeBlock2ProtocolGuid,
                  &mEmuVarsFvb.FwVolBlockInstance,
                  &gEfiDevicePathProtocolGuid,
                  &mEmuVarsFvb.DevicePath,
                  NULL
                  );
  ASSERT_EFI_ERROR (Status);

  //
  // Register for the virtual address change event
  //
  Status = gBS->CreateEventEx (
                  EVT_NOTIFY_SIGNAL,
                  TPL_NOTIFY,
                  FvbVirtualAddressChangeEvent,
                  NULL,
                  &gEfiEventVirtualAddressChangeGuid,
                  &mEmuVarsFvbAddrChangeEvent
                  );
  ASSERT_EFI_ERROR (Status);

  return EFI_SUCCESS;
}


