]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.c
BaseTools: Library hashing fix and optimization for --hash feature
[mirror_edk2.git] / OvmfPkg / EmuVariableFvbRuntimeDxe / Fvb.c
index 4229110719975ef1a59f7ffc04908439bec36d59..b6c6abef1ef2aed83e993fe35ccb96d7cb9627af 100644 (file)
@@ -2,14 +2,8 @@
   Firmware Block Services to support emulating non-volatile variables\r
   by pretending that a memory buffer is storage for the NV variables.\r
 \r
-  Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
-  This program and the accompanying materials\r
-  are licensed and made available under the terms and conditions of the BSD License\r
-  which accompanies this distribution.  The full text of the license may be found at\r
-  http://opensource.org/licenses/bsd-license.php\r
-\r
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+  Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -34,6 +28,9 @@
 #include <Library/PlatformFvbLib.h>\r
 #include "Fvb.h"\r
 \r
+#define EFI_AUTHENTICATED_VARIABLE_GUID \\r
+{ 0xaaf32c78, 0x947b, 0x439a, { 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92 } }\r
+\r
 //\r
 // Virtual Address Change Event\r
 //\r
@@ -71,8 +68,8 @@ EFI_FW_VOL_BLOCK_DEVICE mEmuVarsFvb = {
     }\r
   },\r
   NULL, // BufferPtr\r
-  FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize), // BlockSize\r
-  2 * FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize), // Size\r
+  EMU_FVB_BLOCK_SIZE, // BlockSize\r
+  EMU_FVB_SIZE, // Size\r
   {     // FwVolBlockInstance\r
     FvbProtocolGetAttributes,\r
     FvbProtocolSetAttributes,\r
@@ -116,22 +113,22 @@ FvbVirtualAddressChangeEvent (
   a memory-mapped firmware volume. This function should be called\r
   only for memory-mapped firmware volumes.\r
 \r
-  @param This     Indicates the EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL instance.\r
-  \r
+  @param This     Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.\r
+\r
   @param Address  Pointer to a caller-allocated\r
                   EFI_PHYSICAL_ADDRESS that, on successful\r
                   return from GetPhysicalAddress(), contains the\r
                   base address of the firmware volume.\r
-  \r
+\r
   @retval EFI_SUCCESS       The firmware volume base address is returned.\r
-  \r
+\r
   @retval EFI_NOT_SUPPORTED The firmware volume is not memory mapped.\r
 \r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
 FvbProtocolGetPhysicalAddress (\r
-  IN CONST  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *This,\r
+  IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,\r
   OUT       EFI_PHYSICAL_ADDRESS                *Address\r
   )\r
 {\r
@@ -152,7 +149,7 @@ FvbProtocolGetPhysicalAddress (
   retrieve the block map (see EFI_FIRMWARE_VOLUME_HEADER).\r
 \r
 \r
-  @param This           Indicates the EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL instance.\r
+  @param This           Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.\r
 \r
   @param Lba            Indicates the block for which to return the size.\r
 \r
@@ -165,16 +162,16 @@ FvbProtocolGetPhysicalAddress (
                         blocks in this range have a size of\r
                         BlockSize.\r
 \r
-  \r
+\r
   @retval EFI_SUCCESS             The firmware volume base address is returned.\r
-  \r
+\r
   @retval EFI_INVALID_PARAMETER   The requested LBA is out of range.\r
 \r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
 FvbProtocolGetBlockSize (\r
-  IN CONST  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *This,\r
+  IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,\r
   IN        EFI_LBA                             Lba,\r
   OUT       UINTN                               *BlockSize,\r
   OUT       UINTN                               *NumberOfBlocks\r
@@ -182,14 +179,14 @@ FvbProtocolGetBlockSize (
 {\r
   EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;\r
 \r
-  if (Lba > 1) {\r
+  if (Lba >= EMU_FVB_NUM_TOTAL_BLOCKS) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
   FvbDevice = FVB_DEVICE_FROM_THIS (This);\r
 \r
   *BlockSize = FvbDevice->BlockSize;\r
-  *NumberOfBlocks = (UINTN) (2 - (UINTN) Lba);\r
+  *NumberOfBlocks = (UINTN)(EMU_FVB_NUM_TOTAL_BLOCKS - Lba);\r
 \r
   return EFI_SUCCESS;\r
 }\r
@@ -199,7 +196,7 @@ FvbProtocolGetBlockSize (
   The GetAttributes() function retrieves the attributes and\r
   current settings of the block. Status Codes Returned\r
 \r
-  @param This       Indicates the EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL instance.\r
+  @param This       Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.\r
 \r
   @param Attributes Pointer to EFI_FVB_ATTRIBUTES_2 in which the\r
                     attributes and current settings are\r
@@ -213,7 +210,7 @@ FvbProtocolGetBlockSize (
 EFI_STATUS\r
 EFIAPI\r
 FvbProtocolGetAttributes (\r
-  IN CONST  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *This,\r
+  IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,\r
   OUT       EFI_FVB_ATTRIBUTES_2                *Attributes\r
   )\r
 {\r
@@ -234,7 +231,7 @@ FvbProtocolGetAttributes (
   The SetAttributes() function sets configurable firmware volume\r
   attributes and returns the new settings of the firmware volume.\r
 \r
-  @param This         Indicates the EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL instance.\r
+  @param This         Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.\r
 \r
   @param Attributes   On input, Attributes is a pointer to\r
                       EFI_FVB_ATTRIBUTES_2 that contains the\r
@@ -243,7 +240,7 @@ FvbProtocolGetAttributes (
                       settings of the firmware volume. Type\r
                       EFI_FVB_ATTRIBUTES_2 is defined in\r
                       EFI_FIRMWARE_VOLUME_HEADER.\r
-  \r
+\r
   @retval EFI_SUCCESS           The firmware volume attributes were returned.\r
 \r
   @retval EFI_INVALID_PARAMETER The attributes requested are in\r
@@ -255,7 +252,7 @@ FvbProtocolGetAttributes (
 EFI_STATUS\r
 EFIAPI\r
 FvbProtocolSetAttributes (\r
-  IN CONST  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *This,\r
+  IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,\r
   IN OUT    EFI_FVB_ATTRIBUTES_2                *Attributes\r
   )\r
 {\r
@@ -281,7 +278,7 @@ FvbProtocolSetAttributes (
   flushed to the hardware before the EraseBlocks() service\r
   returns.\r
 \r
-  @param This   Indicates the EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL\r
+  @param This   Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL\r
                 instance.\r
 \r
   @param ...    The variable argument list is a list of tuples.\r
@@ -299,7 +296,7 @@ FvbProtocolSetAttributes (
 \r
   @retval EFI_SUCCESS The erase request was successfully\r
                       completed.\r
-  \r
+\r
   @retval EFI_ACCESS_DENIED   The firmware volume is in the\r
                               WriteDisabled state.\r
   @retval EFI_DEVICE_ERROR  The block device is not functioning\r
@@ -308,76 +305,69 @@ FvbProtocolSetAttributes (
                             partially erased.\r
   @retval EFI_INVALID_PARAMETER One or more of the LBAs listed\r
                                 in the variable argument list do\r
-                                not exist in the firmware volume.  \r
+                                not exist in the firmware volume.\r
 \r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
 FvbProtocolEraseBlocks (\r
-  IN CONST  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *This,\r
+  IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,\r
   ...\r
   )\r
 {\r
   EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;\r
-  VA_LIST                 args;\r
+  VA_LIST                 Args;\r
   EFI_LBA                 StartingLba;\r
   UINTN                   NumOfLba;\r
-  UINT8                   Erase;\r
-  VOID                    *ErasePtr;\r
+  UINT8                   *ErasePtr;\r
   UINTN                   EraseSize;\r
 \r
   FvbDevice = FVB_DEVICE_FROM_THIS (This);\r
-  Erase = 0;\r
-\r
-  VA_START (args, This);\r
 \r
+  //\r
+  // Check input parameters\r
+  //\r
+  VA_START (Args, This);\r
   do {\r
-    StartingLba = VA_ARG (args, EFI_LBA);\r
+    StartingLba = VA_ARG (Args, EFI_LBA);\r
     if (StartingLba == EFI_LBA_LIST_TERMINATOR) {\r
       break;\r
     }\r
+    NumOfLba = VA_ARG (Args, UINTN);\r
 \r
-    NumOfLba = VA_ARG (args, UINT32);\r
-\r
-    //\r
-    // Check input parameters\r
-    //\r
-    if ((NumOfLba == 0) || (StartingLba > 1) || ((StartingLba + NumOfLba) > 2)) {\r
-      VA_END (args);\r
+    if (StartingLba > EMU_FVB_NUM_TOTAL_BLOCKS ||\r
+        NumOfLba > EMU_FVB_NUM_TOTAL_BLOCKS - StartingLba) {\r
+      VA_END (Args);\r
       return EFI_INVALID_PARAMETER;\r
     }\r
-\r
-    if (StartingLba == 0) {\r
-      Erase = (UINT8) (Erase | BIT0);\r
-    }\r
-    if ((StartingLba + NumOfLba) == 2) {\r
-      Erase = (UINT8) (Erase | BIT1);\r
-    }\r
-\r
   } while (1);\r
+  VA_END (Args);\r
 \r
-  VA_END (args);\r
-\r
-  ErasePtr = (UINT8*) FvbDevice->BufferPtr;\r
-  EraseSize = 0;\r
+  //\r
+  // Erase blocks\r
+  //\r
+  VA_START (Args, This);\r
+  do {\r
+    StartingLba = VA_ARG (Args, EFI_LBA);\r
+    if (StartingLba == EFI_LBA_LIST_TERMINATOR) {\r
+      break;\r
+    }\r
+    NumOfLba = VA_ARG (Args, UINTN);\r
 \r
-  if ((Erase & BIT0) != 0) {\r
-    EraseSize = EraseSize + FvbDevice->BlockSize;\r
-  } else {\r
-    ErasePtr = (VOID*) ((UINT8*)ErasePtr + FvbDevice->BlockSize);\r
-  }\r
+    ErasePtr = FvbDevice->BufferPtr;\r
+    ErasePtr += (UINTN)StartingLba * FvbDevice->BlockSize;\r
+    EraseSize = NumOfLba * FvbDevice->BlockSize;\r
 \r
-  if ((Erase & BIT1) != 0) {\r
-    EraseSize = EraseSize + FvbDevice->BlockSize;\r
-  }\r
+    SetMem (ErasePtr, EraseSize, ERASED_UINT8);\r
+  } while (1);\r
+  VA_END (Args);\r
 \r
-  if (EraseSize != 0) {\r
-    SetMem (\r
-      (VOID*) ErasePtr,\r
-      EraseSize,\r
-      ERASED_UINT8\r
-      );\r
-  }\r
+  //\r
+  // Call platform hook\r
+  //\r
+  VA_START (Args, This);\r
+  PlatformFvbBlocksErased (This, Args);\r
+  VA_END (Args);\r
 \r
   return EFI_SUCCESS;\r
 }\r
@@ -413,30 +403,30 @@ FvbProtocolEraseBlocks (
   fully flushed to the hardware before the Write() service\r
   returns.\r
 \r
-  @param This     Indicates the EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL instance.\r
-  \r
+  @param This     Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.\r
+\r
   @param Lba      The starting logical block index to write to.\r
-  \r
+\r
   @param Offset   Offset into the block at which to begin writing.\r
-  \r
+\r
   @param NumBytes Pointer to a UINTN. At entry, *NumBytes\r
                   contains the total size of the buffer. At\r
                   exit, *NumBytes contains the total number of\r
                   bytes actually written.\r
-  \r
+\r
   @param Buffer   Pointer to a caller-allocated buffer that\r
                   contains the source for the write.\r
-  \r
+\r
   @retval EFI_SUCCESS         The firmware volume was written successfully.\r
-  \r
+\r
   @retval EFI_BAD_BUFFER_SIZE The write was attempted across an\r
                               LBA boundary. On output, NumBytes\r
                               contains the total number of bytes\r
                               actually written.\r
-  \r
+\r
   @retval EFI_ACCESS_DENIED   The firmware volume is in the\r
                               WriteDisabled state.\r
-  \r
+\r
   @retval EFI_DEVICE_ERROR    The block device is malfunctioning\r
                               and could not be written.\r
 \r
@@ -445,38 +435,37 @@ FvbProtocolEraseBlocks (
 EFI_STATUS\r
 EFIAPI\r
 FvbProtocolWrite (\r
-  IN CONST  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *This,\r
+  IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,\r
   IN        EFI_LBA                             Lba,\r
   IN        UINTN                               Offset,\r
   IN OUT    UINTN                               *NumBytes,\r
   IN        UINT8                               *Buffer\r
   )\r
 {\r
-\r
   EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;\r
   UINT8                   *FvbDataPtr;\r
+  EFI_STATUS              Status;\r
 \r
   FvbDevice = FVB_DEVICE_FROM_THIS (This);\r
 \r
-  if ((Lba > 1) || (Offset > FvbDevice->BlockSize)) {\r
+  if (Lba >= EMU_FVB_NUM_TOTAL_BLOCKS ||\r
+      Offset > FvbDevice->BlockSize) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  if ((Offset + *NumBytes) > FvbDevice->BlockSize) {\r
+  Status = EFI_SUCCESS;\r
+  if (*NumBytes > FvbDevice->BlockSize - Offset) {\r
     *NumBytes = FvbDevice->BlockSize - Offset;\r
+    Status = EFI_BAD_BUFFER_SIZE;\r
   }\r
 \r
-  FvbDataPtr =\r
-    (UINT8*) FvbDevice->BufferPtr +\r
-    MultU64x32 (Lba, (UINT32) FvbDevice->BlockSize) +\r
-    Offset;\r
-\r
-  if (*NumBytes > 0) {\r
-    CopyMem (FvbDataPtr, Buffer, *NumBytes);\r
-    PlatformFvbDataWritten (This, Lba);\r
-  }\r
+  FvbDataPtr = FvbDevice->BufferPtr;\r
+  FvbDataPtr += (UINTN)Lba * FvbDevice->BlockSize;\r
+  FvbDataPtr += Offset;\r
 \r
-  return EFI_SUCCESS;\r
+  CopyMem (FvbDataPtr, Buffer, *NumBytes);\r
+  PlatformFvbDataWritten (This, Lba, Offset, *NumBytes, Buffer);\r
+  return Status;\r
 }\r
 \r
 \r
@@ -496,8 +485,8 @@ FvbProtocolWrite (
   indicate the number of bytes actually read. The caller must be\r
   aware that a read may be partially completed.\r
 \r
-  @param This     Indicates the EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL instance.\r
-  \r
+  @param This     Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.\r
+\r
   @param Lba      The starting logical block index\r
                   from which to read.\r
 \r
@@ -513,15 +502,15 @@ FvbProtocolWrite (
 \r
   @retval EFI_SUCCESS         The firmware volume was read successfully\r
                               and contents are in Buffer.\r
-  \r
+\r
   @retval EFI_BAD_BUFFER_SIZE Read attempted across an LBA\r
                               boundary. On output, NumBytes\r
                               contains the total number of bytes\r
                               returned in Buffer.\r
-  \r
+\r
   @retval EFI_ACCESS_DENIED   The firmware volume is in the\r
                               ReadDisabled state.\r
-  \r
+\r
   @retval EFI_DEVICE_ERROR    The block device is not\r
                               functioning correctly and could\r
                               not be read.\r
@@ -530,7 +519,7 @@ FvbProtocolWrite (
 EFI_STATUS\r
 EFIAPI\r
 FvbProtocolRead (\r
-  IN CONST  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *This,\r
+  IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,\r
   IN        EFI_LBA                             Lba,\r
   IN        UINTN                               Offset,\r
   IN OUT    UINTN                               *NumBytes,\r
@@ -539,27 +528,28 @@ FvbProtocolRead (
 {\r
   EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;\r
   UINT8                   *FvbDataPtr;\r
+  EFI_STATUS              Status;\r
 \r
   FvbDevice = FVB_DEVICE_FROM_THIS (This);\r
 \r
-  if ((Lba > 1) || (Offset > FvbDevice->BlockSize)) {\r
+  if (Lba >= EMU_FVB_NUM_TOTAL_BLOCKS ||\r
+      Offset > FvbDevice->BlockSize) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  if ((Offset + *NumBytes) > FvbDevice->BlockSize) {\r
+  Status = EFI_SUCCESS;\r
+  if (*NumBytes > FvbDevice->BlockSize - Offset) {\r
     *NumBytes = FvbDevice->BlockSize - Offset;\r
+    Status = EFI_BAD_BUFFER_SIZE;\r
   }\r
 \r
-  FvbDataPtr =\r
-    (UINT8*) FvbDevice->BufferPtr +\r
-    MultU64x32 (Lba, (UINT32) FvbDevice->BlockSize) +\r
-    Offset;\r
+  FvbDataPtr = FvbDevice->BufferPtr;\r
+  FvbDataPtr += (UINTN)Lba * FvbDevice->BlockSize;\r
+  FvbDataPtr += Offset;\r
 \r
-  if (*NumBytes > 0) {\r
-    CopyMem (Buffer, FvbDataPtr, *NumBytes);\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
+  CopyMem (Buffer, FvbDataPtr, *NumBytes);\r
+  PlatformFvbDataRead (This, Lba, Offset, *NumBytes, Buffer);\r
+  return Status;\r
 }\r
 \r
 \r
@@ -618,7 +608,10 @@ InitializeFvAndVariableStoreHeaders (
   IN  VOID   *Ptr\r
   )\r
 {\r
-  STATIC FVB_FV_HDR_AND_VARS_TEMPLATE FvAndVarTemplate = {\r
+  //\r
+  // Templates for authenticated variable FV header\r
+  //\r
+  STATIC FVB_FV_HDR_AND_VARS_TEMPLATE FvAndAuthenticatedVarTemplate = {\r
     { // EFI_FIRMWARE_VOLUME_HEADER FvHdr;\r
       // UINT8                     ZeroVector[16];\r
       { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },\r
@@ -645,25 +638,28 @@ InitializeFvAndVariableStoreHeaders (
       0,\r
 \r
       // UINT8                     Reserved[1];\r
-      0,\r
+      {0},\r
 \r
       // UINT8                     Revision;\r
       EFI_FVH_REVISION,\r
 \r
       // EFI_FV_BLOCK_MAP_ENTRY    BlockMap[1];\r
-      { 2, // UINT32 NumBlocks;\r
-        EMU_FVB_BLOCK_SIZE  // UINT32 Length;\r
+      {\r
+        {\r
+          EMU_FVB_NUM_TOTAL_BLOCKS, // UINT32 NumBlocks;\r
+          EMU_FVB_BLOCK_SIZE  // UINT32 Length;\r
+        }\r
       }\r
     },\r
     // EFI_FV_BLOCK_MAP_ENTRY     EndBlockMap;\r
     { 0, 0 }, // End of block map\r
     { // VARIABLE_STORE_HEADER      VarHdr;\r
-      // EFI_GUID  Signature;\r
-      EFI_VARIABLE_GUID,\r
+        // EFI_GUID  Signature;     // need authenticated variables for secure boot\r
+        EFI_AUTHENTICATED_VARIABLE_GUID,\r
 \r
       // UINT32  Size;\r
       (\r
-        FixedPcdGet32 (PcdVariableStoreSize) -\r
+        FixedPcdGet32 (PcdFlashNvStorageVariableSize) -\r
         OFFSET_OF (FVB_FV_HDR_AND_VARS_TEMPLATE, VarHdr)\r
       ),\r
 \r
@@ -680,12 +676,17 @@ InitializeFvAndVariableStoreHeaders (
       0\r
     }\r
   };\r
+\r
   EFI_FIRMWARE_VOLUME_HEADER  *Fv;\r
 \r
   //\r
   // Copy the template structure into the location\r
   //\r
-  CopyMem (Ptr, (VOID*)&FvAndVarTemplate, sizeof (FvAndVarTemplate));\r
+  CopyMem (\r
+    Ptr,\r
+    &FvAndAuthenticatedVarTemplate,\r
+    sizeof FvAndAuthenticatedVarTemplate\r
+    );\r
 \r
   //\r
   // Update the checksum for the FV header\r
@@ -694,58 +695,12 @@ InitializeFvAndVariableStoreHeaders (
   Fv->Checksum = CalculateCheckSum16 (Ptr, Fv->HeaderLength);\r
 }\r
 \r
-\r
-/**\r
-  Initializes the Fault Tolerant Write data structure\r
-\r
-  This data structure is used by the Fault Tolerant Write driver.\r
-\r
-  @param[in]  Buffer - Location for the FTW data structure\r
-\r
-**/\r
-VOID\r
-InitializeFtwState (\r
-  IN  VOID   *Buffer\r
-  )\r
-{\r
-  EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *Hdr;\r
-  UINT32                                  TempCrc;\r
-  STATIC EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER DefaultFtw = {\r
-    EFI_SYSTEM_NV_DATA_FV_GUID, // EFI_GUID  Signature;\r
-    ERASED_UINT32,              // UINT32    Crc;\r
-    ERASED_BIT,                 // UINT8     WorkingBlockValid : 1;\r
-    ERASED_BIT,                 // UINT8     WorkingBlockInvalid : 1;\r
-    0,                          // UINT8     Reserved : 6;\r
-    { 0, 0, 0 },                // UINT8     Reserved3[3];\r
-    FTW_WRITE_QUEUE_SIZE        // UINT64    WriteQueueSize;\r
-  };\r
-\r
-  CopyMem (Buffer, (VOID*) &DefaultFtw, sizeof (DefaultFtw));\r
-\r
-  Hdr = (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER*) Buffer;\r
-\r
-  //\r
-  // Calculate checksum.\r
-  //\r
-  // The Crc, WorkingBlockValid and WorkingBlockInvalid bits should\r
-  // be set to the erased state before computing the checksum.\r
-  //\r
-  gBS->CalculateCrc32 (Buffer, sizeof (DefaultFtw), &TempCrc);\r
-  Hdr->Crc = TempCrc;\r
-\r
-  //\r
-  // Mark as valid.\r
-  //\r
-  Hdr->WorkingBlockValid = NOT_ERASED_BIT;\r
-}\r
-\r
-\r
 /**\r
   Main entry point.\r
 \r
-  @param[in] ImageHandle    The firmware allocated handle for the EFI image.  \r
+  @param[in] ImageHandle    The firmware allocated handle for the EFI image.\r
   @param[in] SystemTable    A pointer to the EFI System Table.\r
-  \r
+\r
   @retval EFI_SUCCESS       Successfully initialized.\r
 \r
 **/\r
@@ -762,22 +717,31 @@ FvbInitialize (
   BOOLEAN                             Initialize;\r
   EFI_HANDLE                          Handle;\r
   EFI_PHYSICAL_ADDRESS                Address;\r
+  RETURN_STATUS                       PcdStatus;\r
 \r
   DEBUG ((EFI_D_INFO, "EMU Variable FVB Started\n"));\r
 \r
   //\r
   // Verify that the PCD's are set correctly.\r
   //\r
+  ASSERT (FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize) %\r
+          EMU_FVB_BLOCK_SIZE == 0);\r
   if (\r
-       (PcdGet32 (PcdVariableStoreSize) +\r
+       (PcdGet32 (PcdFlashNvStorageVariableSize) +\r
         PcdGet32 (PcdFlashNvStorageFtwWorkingSize)\r
        ) >\r
-       EMU_FVB_BLOCK_SIZE\r
+       EMU_FVB_NUM_SPARE_BLOCKS * EMU_FVB_BLOCK_SIZE\r
      ) {\r
     DEBUG ((EFI_D_ERROR, "EMU Variable invalid PCD sizes\n"));\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
+  if (PcdGet64 (PcdFlashNvStorageVariableBase64) != 0) {\r
+    DEBUG ((EFI_D_INFO, "Disabling EMU Variable FVB since "\r
+                        "flash variables appear to be supported.\n"));\r
+    return EFI_ABORTED;\r
+  }\r
+\r
   //\r
   // By default we will initialize the FV contents.  But, if\r
   // PcdEmuVariableNvStoreReserved is non-zero, then we will\r
@@ -800,10 +764,7 @@ FvbInitialize (
       Initialize = FALSE;\r
     }\r
   } else {\r
-    Ptr = AllocateAlignedRuntimePages (\r
-            EFI_SIZE_TO_PAGES (EMU_FVB_SIZE),\r
-            SIZE_64KB\r
-            );\r
+    Ptr = AllocateRuntimePages (EFI_SIZE_TO_PAGES (EMU_FVB_SIZE));\r
   }\r
 \r
   mEmuVarsFvb.BufferPtr = Ptr;\r
@@ -815,22 +776,25 @@ FvbInitialize (
     SetMem (Ptr, EMU_FVB_SIZE, ERASED_UINT8);\r
     InitializeFvAndVariableStoreHeaders (Ptr);\r
   }\r
-  PcdSet32 (PcdFlashNvStorageVariableBase, (UINT32)(UINTN) Ptr);\r
+  PcdStatus = PcdSet64S (PcdFlashNvStorageVariableBase64, (UINT32)(UINTN) Ptr);\r
+  ASSERT_RETURN_ERROR (PcdStatus);\r
 \r
   //\r
   // Initialize the Fault Tolerant Write data area\r
   //\r
-  SubPtr = (VOID*) ((UINT8*) Ptr + PcdGet32 (PcdVariableStoreSize));\r
-  if (Initialize) {\r
-    InitializeFtwState (SubPtr);\r
-  }\r
-  PcdSet32 (PcdFlashNvStorageFtwWorkingBase, (UINT32)(UINTN) SubPtr);\r
+  SubPtr = (VOID*) ((UINT8*) Ptr + PcdGet32 (PcdFlashNvStorageVariableSize));\r
+  PcdStatus = PcdSet32S (PcdFlashNvStorageFtwWorkingBase,\r
+                (UINT32)(UINTN) SubPtr);\r
+  ASSERT_RETURN_ERROR (PcdStatus);\r
 \r
   //\r
   // Initialize the Fault Tolerant Write spare block\r
   //\r
-  SubPtr = (VOID*) ((UINT8*) Ptr + EMU_FVB_BLOCK_SIZE);\r
-  PcdSet32 (PcdFlashNvStorageFtwSpareBase, (UINT32)(UINTN) SubPtr);\r
+  SubPtr = (VOID*) ((UINT8*) Ptr +\r
+                    EMU_FVB_NUM_SPARE_BLOCKS * EMU_FVB_BLOCK_SIZE);\r
+  PcdStatus = PcdSet32S (PcdFlashNvStorageFtwSpareBase,\r
+                (UINT32)(UINTN) SubPtr);\r
+  ASSERT_RETURN_ERROR (PcdStatus);\r
 \r
   //\r
   // Setup FVB device path\r
@@ -846,7 +810,7 @@ FvbInitialize (
   Handle = 0;\r
   Status = gBS->InstallMultipleProtocolInterfaces (\r
                   &Handle,\r
-                  &gEfiFirmwareVolumeBlockProtocolGuid,\r
+                  &gEfiFirmwareVolumeBlock2ProtocolGuid,\r
                   &mEmuVarsFvb.FwVolBlockInstance,\r
                   &gEfiDevicePathProtocolGuid,\r
                   &mEmuVarsFvb.DevicePath,\r