diff --git a/Silicon/Socionext/SynQuacer/Drivers/Fip006Dxe/Fip006Dxe.inf b/Silicon/Socionext/SynQuacer/Drivers/Fip006Dxe/Fip006Dxe.inf
index b939aa689eef..603641e0a68f 100644
--- a/Silicon/Socionext/SynQuacer/Drivers/Fip006Dxe/Fip006Dxe.inf
+++ b/Silicon/Socionext/SynQuacer/Drivers/Fip006Dxe/Fip006Dxe.inf
@@ -2,7 +2,7 @@
 #  Socionext FIP006 High-Speed SPI Controller with NOR Flash Driver
 #
 #  Copyright (c) 2017, Socionext Inc. All rights reserved.<BR>
-#  Copyright (c) 2017, Linaro, Ltd. All rights reserved.<BR>
+#  Copyright (c) 2017-2018, Linaro, Ltd. All rights reserved.<BR>
 #
 #  This program and the accompanying materials
 #  are licensed and made available under the terms and conditions of the BSD License
@@ -25,7 +25,9 @@ [Defines]
 
 [Sources]
   NorFlashDxe.c
-  NorFlashFvbDxe.c
+  NorFlash.c
+  NorFlash.h
+  NorFlashFvb.c
 
 [Packages]
   ArmPlatformPkg/ArmPlatformPkg.dec
diff --git a/Silicon/Socionext/SynQuacer/Drivers/Fip006Dxe/NorFlash.c b/Silicon/Socionext/SynQuacer/Drivers/Fip006Dxe/NorFlash.c
new file mode 100644
index 000000000000..2134739bfba9
--- /dev/null
+++ b/Silicon/Socionext/SynQuacer/Drivers/Fip006Dxe/NorFlash.c
@@ -0,0 +1,1006 @@
+/** @file  NorFlashDxe.c
+
+  Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>
+  Copyright (c) 2017, Socionext Inc. All rights reserved.<BR>
+  Copyright (c) 2017, Linaro, Ltd. 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 <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/NorFlashInfoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+
+#include "NorFlash.h"
+
+STATIC CONST UINT16 mFip006NullCmdSeq[] = {
+  CSDC (CSDC_END, CSDC_CONT_NON_CONTINUOUS, CSDC_TRP_MBM, CSDC_DEC_DECODE),
+  CSDC (CSDC_END, CSDC_CONT_NON_CONTINUOUS, CSDC_TRP_MBM, CSDC_DEC_DECODE),
+  CSDC (CSDC_END, CSDC_CONT_NON_CONTINUOUS, CSDC_TRP_MBM, CSDC_DEC_DECODE),
+  CSDC (CSDC_END, CSDC_CONT_NON_CONTINUOUS, CSDC_TRP_MBM, CSDC_DEC_DECODE),
+  CSDC (CSDC_END, CSDC_CONT_NON_CONTINUOUS, CSDC_TRP_MBM, CSDC_DEC_DECODE),
+  CSDC (CSDC_END, CSDC_CONT_NON_CONTINUOUS, CSDC_TRP_MBM, CSDC_DEC_DECODE),
+  CSDC (CSDC_END, CSDC_CONT_NON_CONTINUOUS, CSDC_TRP_MBM, CSDC_DEC_DECODE),
+  CSDC (CSDC_END, CSDC_CONT_NON_CONTINUOUS, CSDC_TRP_MBM, CSDC_DEC_DECODE),
+};
+
+STATIC CONST CSDC_DEFINITION mN25qCSDCDefTable[] = {
+  // Identification Operations
+  { SPINOR_OP_RDID,     FALSE, FALSE, FALSE, FALSE, CS_CFG_MBM_SINGLE,
+                        CSDC_TRP_SINGLE },
+  // Register Operations
+  { SPINOR_OP_RDSR,     FALSE, FALSE, FALSE, FALSE, CS_CFG_MBM_SINGLE,
+                        CSDC_TRP_SINGLE },
+  { SPINOR_OP_WRSR,     FALSE, FALSE, FALSE, TRUE,  CS_CFG_MBM_SINGLE,
+                        CSDC_TRP_SINGLE },
+  { SPINOR_OP_RD_ARRAY, TRUE,  FALSE, FALSE, FALSE, CS_CFG_MBM_SINGLE,
+                        CSDC_TRP_SINGLE },
+  { SPINOR_OP_RDFSR,    FALSE, FALSE, FALSE, FALSE, CS_CFG_MBM_SINGLE,
+                        CSDC_TRP_SINGLE },
+  { SPINOR_OP_RD_NVCFG, FALSE, FALSE, FALSE, FALSE, CS_CFG_MBM_SINGLE,
+                        CSDC_TRP_SINGLE },
+  { SPINOR_OP_RD_VCR,   FALSE, FALSE, FALSE, FALSE, CS_CFG_MBM_SINGLE,
+                        CSDC_TRP_SINGLE },
+  { SPINOR_OP_RD_EVCR,  FALSE, FALSE, FALSE, FALSE, CS_CFG_MBM_SINGLE,
+                        CSDC_TRP_SINGLE },
+  // Read Operations
+  { SPINOR_OP_READ_4B,  TRUE,  TRUE,  FALSE, FALSE, CS_CFG_MBM_SINGLE,
+                        CSDC_TRP_SINGLE },
+  // Write Operations
+  { SPINOR_OP_PP,       TRUE,  FALSE, FALSE, TRUE,  CS_CFG_MBM_SINGLE,
+                        CSDC_TRP_SINGLE },
+  { SPINOR_OP_PP_1_1_4, TRUE,  FALSE, FALSE, TRUE,  CS_CFG_MBM_QUAD,
+                        CSDC_TRP_SINGLE },
+  // Erase Operations
+  { SPINOR_OP_SE,       FALSE, FALSE, FALSE, TRUE,  CS_CFG_MBM_SINGLE,
+                        CSDC_TRP_SINGLE },
+};
+
+STATIC CONST NOR_FLASH_INSTANCE mNorFlashInstanceTemplate = {
+  NOR_FLASH_SIGNATURE, // Signature
+  NULL, // Handle ... NEED TO BE FILLED
+
+  FALSE, // Initialized
+  NULL, // Initialize
+
+  0, // HostRegisterBaseAddress ... NEED TO BE FILLED
+  0, // DeviceBaseAddress ... NEED TO BE FILLED
+  0, // RegionBaseAddress ... NEED TO BE FILLED
+  0, // Size ... NEED TO BE FILLED
+  0, // BlockSize
+  0, // LastBlock
+  0, // StartLba
+  0, // OffsetLba
+
+  {
+    FvbGetAttributes, // GetAttributes
+    FvbSetAttributes, // SetAttributes
+    FvbGetPhysicalAddress,  // GetPhysicalAddress
+    FvbGetBlockSize,  // GetBlockSize
+    FvbRead,  // Read
+    FvbWrite, // Write
+    FvbEraseBlocks, // EraseBlocks
+    NULL, //ParentHandle
+  }, //  FvbProtoccol;
+
+  NULL, // ShadowBuffer
+  {
+    {
+      {
+        HARDWARE_DEVICE_PATH,
+        HW_VENDOR_DP,
+        {
+          (UINT8)(OFFSET_OF (NOR_FLASH_DEVICE_PATH, End)),
+          (UINT8)(OFFSET_OF (NOR_FLASH_DEVICE_PATH, End) >> 8)
+        }
+      },
+      { 0x0, 0x0, 0x0, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } },
+    },
+    0,  // Index
+    {
+      END_DEVICE_PATH_TYPE,
+      END_ENTIRE_DEVICE_PATH_SUBTYPE,
+      { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 }
+    }
+  }, // DevicePath
+  0 // Flags
+};
+
+EFI_STATUS
+NorFlashCreateInstance (
+  IN UINTN                  HostRegisterBase,
+  IN UINTN                  NorFlashDeviceBase,
+  IN UINTN                  NorFlashRegionBase,
+  IN UINTN                  NorFlashSize,
+  IN UINT32                 Index,
+  IN UINT32                 BlockSize,
+  IN BOOLEAN                HasVarStore,
+  OUT NOR_FLASH_INSTANCE**  NorFlashInstance
+  )
+{
+  EFI_STATUS Status;
+  NOR_FLASH_INSTANCE* Instance;
+  NOR_FLASH_INFO *FlashInfo;
+  UINT8 JedecId[3];
+
+  ASSERT(NorFlashInstance != NULL);
+
+  Instance = AllocateRuntimeCopyPool (sizeof mNorFlashInstanceTemplate,
+                                      &mNorFlashInstanceTemplate);
+  if (Instance == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Instance->HostRegisterBaseAddress = HostRegisterBase;
+  Instance->DeviceBaseAddress       = NorFlashDeviceBase;
+  Instance->RegionBaseAddress       = NorFlashRegionBase;
+  Instance->Size                    = NorFlashSize;
+  Instance->BlockSize               = BlockSize;
+  Instance->LastBlock               = (NorFlashSize / BlockSize) - 1;
+
+  Instance->OffsetLba = (NorFlashRegionBase - NorFlashDeviceBase) / BlockSize;
+
+  CopyGuid (&Instance->DevicePath.Vendor.Guid, &gEfiCallerIdGuid);
+  Instance->DevicePath.Index = (UINT8)Index;
+
+  NorFlashReset (Instance);
+
+  NorFlashReadID (Instance, JedecId);
+  Status = NorFlashGetInfo (JedecId, &FlashInfo, FALSE);
+  if (EFI_ERROR (Status)) {
+    goto FreeInstance;
+  }
+
+  NorFlashPrintInfo (FlashInfo);
+
+  Instance->Flags = 0;
+  if (FlashInfo->Flags & NOR_FLASH_WRITE_FSR) {
+    Instance->Flags = NOR_FLASH_POLL_FSR;
+  }
+
+  Instance->ShadowBuffer = AllocateRuntimePool (BlockSize);
+  if (Instance->ShadowBuffer == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto FreeInstance;
+  }
+
+  if (HasVarStore) {
+    Instance->Initialize = NorFlashFvbInitialize;
+  }
+
+  *NorFlashInstance = Instance;
+  FreePool (FlashInfo);
+  return EFI_SUCCESS;
+
+FreeInstance:
+  FreePool (Instance);
+  return Status;
+}
+
+STATIC
+EFI_STATUS
+NorFlashSetHostCSDC (
+  IN  NOR_FLASH_INSTANCE    *Instance,
+  IN  BOOLEAN               ReadWrite,
+  IN  CONST UINT16          CSDC[ARRAY_SIZE (mFip006NullCmdSeq)]
+  )
+{
+  EFI_PHYSICAL_ADDRESS      Dst;
+  UINTN                     Index;
+
+  Dst = Instance->HostRegisterBaseAddress
+        + (ReadWrite ? FIP006_REG_CS_WR : FIP006_REG_CS_RD);
+  for (Index = 0; Index < ARRAY_SIZE (mFip006NullCmdSeq); Index++) {
+    MmioWrite16 (Dst + (Index << 1), CSDC[Index]);
+  }
+  return EFI_SUCCESS;
+}
+
+STATIC
+CONST CSDC_DEFINITION *
+NorFlashGetCmdDef (
+  IN  NOR_FLASH_INSTANCE    *Instance,
+  IN  UINT8                 Code
+  )
+{
+  CONST CSDC_DEFINITION *Cmd;
+  UINTN                 Index;
+
+  Cmd = NULL;
+  for (Index = 0; Index <  ARRAY_SIZE (mN25qCSDCDefTable); Index++) {
+    if (Code == mN25qCSDCDefTable[Index].Code) {
+      Cmd = &mN25qCSDCDefTable[Index];
+      break;
+    }
+  }
+  return Cmd;
+}
+
+STATIC
+EFI_STATUS
+GenCSDC (
+  IN  UINT8     Cmd,
+  IN  BOOLEAN   AddrAccess,
+  IN  BOOLEAN   AddrMode4Byte,
+  IN  BOOLEAN   HighZ,
+  IN  UINT8     TransferMode,
+  OUT UINT16    *CmdSeq
+  )
+{
+  UINTN         Index;
+
+  if (!CmdSeq) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Index = 0;
+  CopyMem (CmdSeq, mFip006NullCmdSeq, sizeof (mFip006NullCmdSeq));
+
+  CmdSeq[Index++] = CSDC (Cmd, CSDC_CONT_NON_CONTINUOUS, TransferMode,
+                          CSDC_DEC_LEAVE_ASIS);
+  if (AddrAccess) {
+    if (AddrMode4Byte) {
+      CmdSeq[Index++] = CSDC (CSDC_ADDRESS_31_24, CSDC_CONT_NON_CONTINUOUS,
+                              TransferMode, CSDC_DEC_DECODE);
+    }
+    CmdSeq[Index++] = CSDC (CSDC_ADDRESS_23_16, CSDC_CONT_NON_CONTINUOUS,
+                            TransferMode, CSDC_DEC_DECODE);
+    CmdSeq[Index++] = CSDC (CSDC_ADDRESS_15_8, CSDC_CONT_NON_CONTINUOUS,
+                            TransferMode, CSDC_DEC_DECODE);
+    CmdSeq[Index++] = CSDC (CSDC_ADDRESS_7_0, CSDC_CONT_NON_CONTINUOUS,
+                            TransferMode, CSDC_DEC_DECODE);
+  }
+  if (HighZ) {
+    CmdSeq[Index++] = CSDC (CSDC_HIGH_Z, CSDC_CONT_NON_CONTINUOUS,
+                            TransferMode, CSDC_DEC_DECODE);
+  }
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+NorFlashSetHostCommand (
+  IN  NOR_FLASH_INSTANCE    *Instance,
+  IN  UINT8                 Code
+  )
+{
+  CONST CSDC_DEFINITION     *Cmd;
+  UINT16                    CSDC[ARRAY_SIZE (mFip006NullCmdSeq)];
+
+  Cmd = NorFlashGetCmdDef (Instance, Code);
+  if (Cmd == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  GenCSDC (
+      Cmd->Code,
+      Cmd->AddrAccess,
+      Cmd->AddrMode4Byte,
+      Cmd->HighZ,
+      Cmd->CsdcTrp,
+      CSDC
+      );
+  NorFlashSetHostCSDC (Instance, Cmd->ReadWrite, CSDC);
+  return EFI_SUCCESS;
+}
+
+STATIC
+UINT8
+NorFlashReadStatusRegister (
+  IN NOR_FLASH_INSTANCE     *Instance
+  )
+{
+  UINT8       StatusRegister;
+
+  NorFlashSetHostCommand (Instance, SPINOR_OP_RDSR);
+  StatusRegister = MmioRead8 (Instance->RegionBaseAddress);
+  NorFlashSetHostCommand (Instance, SPINOR_OP_READ_4B);
+  return StatusRegister;
+}
+
+STATIC
+EFI_STATUS
+NorFlashWaitProgramErase (
+  IN NOR_FLASH_INSTANCE     *Instance
+  )
+{
+  BOOLEAN     SRegDone;
+  BOOLEAN     FSRegDone;
+
+  DEBUG ((DEBUG_BLKIO, "NorFlashWaitProgramErase()\n"));
+
+  do {
+    SRegDone = (NorFlashReadStatusRegister (Instance) & SPINOR_SR_WIP) == 0;
+    FSRegDone = TRUE;
+    if (Instance->Flags & NOR_FLASH_POLL_FSR) {
+      NorFlashSetHostCommand (Instance, SPINOR_OP_RDFSR);
+      FSRegDone = (MmioRead8 (Instance->RegionBaseAddress) &
+                   SPINOR_FSR_READY) != 0;
+    }
+  } while (!SRegDone || !FSRegDone);
+  NorFlashSetHostCommand (Instance, SPINOR_OP_READ_4B);
+  return EFI_SUCCESS;
+}
+
+// TODO: implement lock checking
+STATIC
+BOOLEAN
+NorFlashBlockIsLocked (
+  IN NOR_FLASH_INSTANCE     *Instance,
+  IN UINTN                  BlockAddress
+  )
+{
+  return FALSE;
+}
+
+// TODO: implement sector unlocking
+STATIC
+EFI_STATUS
+NorFlashUnlockSingleBlock (
+  IN NOR_FLASH_INSTANCE     *Instance,
+  IN UINTN                  BlockAddress
+  )
+{
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+NorFlashUnlockSingleBlockIfNecessary (
+  IN NOR_FLASH_INSTANCE     *Instance,
+  IN UINTN                  BlockAddress
+  )
+{
+  EFI_STATUS Status;
+
+  Status = EFI_SUCCESS;
+
+  if (NorFlashBlockIsLocked (Instance, BlockAddress) == TRUE) {
+    Status = NorFlashUnlockSingleBlock (Instance, BlockAddress);
+  }
+
+  return Status;
+}
+
+STATIC
+EFI_STATUS
+NorFlashEnableWrite (
+  IN  NOR_FLASH_INSTANCE    *Instance
+  )
+{
+  EFI_STATUS      Status;
+  UINT8           StatusRegister;
+  UINTN           Retry;
+
+  DEBUG ((DEBUG_BLKIO, "NorFlashEnableWrite()\n"));
+
+  Status = EFI_DEVICE_ERROR;
+  Retry = NOR_FLASH_ERASE_RETRY;
+
+  NorFlashSetHostCSDC (Instance, TRUE, mFip006NullCmdSeq);
+  while (Retry > 0 && EFI_ERROR (Status)) {
+    MmioWrite8 (Instance->RegionBaseAddress, SPINOR_OP_WREN);
+    MemoryFence ();
+    StatusRegister = NorFlashReadStatusRegister (Instance);
+    Status = (StatusRegister & BIT1) ? EFI_SUCCESS : EFI_DEVICE_ERROR;
+    Retry--;
+  }
+  return Status;
+}
+
+STATIC
+EFI_STATUS
+NorFlashDisableWrite (
+  IN  NOR_FLASH_INSTANCE    *Instance
+  )
+{
+  EFI_STATUS      Status;
+  UINT8           StatusRegister;
+  UINTN           Retry;
+
+  DEBUG ((DEBUG_BLKIO, "NorFlashDisableWrite()\n"));
+
+  Status = EFI_DEVICE_ERROR;
+  Retry = NOR_FLASH_ERASE_RETRY;
+
+  NorFlashSetHostCSDC (Instance, TRUE, mFip006NullCmdSeq);
+  while (Retry > 0 && EFI_ERROR (Status)) {
+    MmioWrite8 (Instance->RegionBaseAddress, SPINOR_OP_WRDIS);
+    MemoryFence ();
+    StatusRegister = NorFlashReadStatusRegister (Instance);
+    Status = (StatusRegister & BIT1) ? EFI_DEVICE_ERROR : EFI_SUCCESS;
+    Retry--;
+  }
+  return Status;
+}
+
+/**
+ * The following function presumes that the block has already been unlocked.
+ **/
+STATIC
+EFI_STATUS
+NorFlashEraseSingleBlock (
+  IN NOR_FLASH_INSTANCE     *Instance,
+  IN UINTN                  BlockAddress
+  )
+{
+
+  DEBUG ((DEBUG_BLKIO, "NorFlashEraseSingleBlock(BlockAddress=0x%08x)\n",
+    BlockAddress));
+
+  if (EFI_ERROR (NorFlashEnableWrite (Instance))) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  //
+  // The virtual address chosen by the OS may have a different offset modulo
+  // 16 MB than the physical address, so we need to subtract the region base
+  // address before we can mask off a block index. Note that the relative
+  // offset between device base address and region base address may have changed
+  // as well, so we cannot use the device base address directly.
+  //
+  BlockAddress -= Instance->RegionBaseAddress;
+  BlockAddress += Instance->OffsetLba * Instance->BlockSize;
+
+  NorFlashSetHostCSDC (Instance, TRUE, mFip006NullCmdSeq);
+  MmioWrite32 (Instance->DeviceBaseAddress,
+               SwapBytes32 (BlockAddress & 0x00FFFFFF) | SPINOR_OP_SE);
+  NorFlashWaitProgramErase (Instance);
+  NorFlashSetHostCSDC (Instance, TRUE, mFip006NullCmdSeq);
+
+  if (EFI_ERROR (NorFlashDisableWrite (Instance))) {
+    return EFI_DEVICE_ERROR;
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+ * This function unlock and erase an entire NOR Flash block.
+ **/
+EFI_STATUS
+NorFlashUnlockAndEraseSingleBlock (
+  IN NOR_FLASH_INSTANCE     *Instance,
+  IN UINTN                  BlockAddress
+  )
+{
+  EFI_STATUS              Status;
+  UINTN                   Index;
+  NOR_FLASH_LOCK_CONTEXT  Lock;
+
+  NorFlashLock (&Lock);
+
+  Index = 0;
+  // The block erase might fail a first time (SW bug ?). Retry it ...
+  do {
+    // Unlock the block if we have to
+    Status = NorFlashUnlockSingleBlockIfNecessary (Instance, BlockAddress);
+    if (EFI_ERROR (Status)) {
+      break;
+    }
+    Status = NorFlashEraseSingleBlock (Instance, BlockAddress);
+    Index++;
+  } while ((Index < NOR_FLASH_ERASE_RETRY) && (Status == EFI_WRITE_PROTECTED));
+
+  if (Index == NOR_FLASH_ERASE_RETRY) {
+    DEBUG ((DEBUG_ERROR,
+      "EraseSingleBlock(BlockAddress=0x%08x: Block Locked Error (try to erase %d times)\n",
+      BlockAddress,Index));
+  }
+
+  NorFlashUnlock (&Lock);
+
+  return Status;
+}
+
+STATIC
+EFI_STATUS
+NorFlashWriteSingleWord (
+  IN NOR_FLASH_INSTANCE     *Instance,
+  IN UINTN                  WordAddress,
+  IN UINT32                 WriteData
+  )
+{
+  EFI_STATUS            Status;
+
+  DEBUG ((DEBUG_BLKIO,
+    "NorFlashWriteSingleWord(WordAddress=0x%08x, WriteData=0x%08x)\n",
+    WordAddress, WriteData));
+
+  Status = EFI_SUCCESS;
+
+  if (EFI_ERROR (NorFlashEnableWrite (Instance))) {
+    return EFI_DEVICE_ERROR;
+  }
+  NorFlashSetHostCommand (Instance, SPINOR_OP_PP);
+  MmioWrite32 (WordAddress, WriteData);
+  NorFlashWaitProgramErase (Instance);
+
+  NorFlashDisableWrite (Instance);
+  NorFlashSetHostCSDC (Instance, TRUE, mFip006NullCmdSeq);
+  return Status;
+}
+
+STATIC
+EFI_STATUS
+NorFlashWriteFullBlock (
+  IN NOR_FLASH_INSTANCE     *Instance,
+  IN EFI_LBA                Lba,
+  IN UINT32                 *DataBuffer,
+  IN UINT32                 BlockSizeInWords
+  )
+{
+  EFI_STATUS              Status;
+  UINTN                   WordAddress;
+  UINT32                  WordIndex;
+  UINTN                   BlockAddress;
+  NOR_FLASH_LOCK_CONTEXT  Lock;
+
+  Status = EFI_SUCCESS;
+
+  // Get the physical address of the block
+  BlockAddress = GET_NOR_BLOCK_ADDRESS (Instance->RegionBaseAddress, Lba,
+                   BlockSizeInWords * 4);
+
+  // Start writing from the first address at the start of the block
+  WordAddress = BlockAddress;
+
+  NorFlashLock (&Lock);
+
+  Status = NorFlashUnlockAndEraseSingleBlock (Instance, BlockAddress);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR,
+      "WriteSingleBlock: ERROR - Failed to Unlock and Erase the single block at 0x%X\n",
+      BlockAddress));
+    goto EXIT;
+  }
+
+  for (WordIndex=0;
+       WordIndex < BlockSizeInWords;
+       WordIndex++, DataBuffer++, WordAddress += 4) {
+    Status = NorFlashWriteSingleWord (Instance, WordAddress, *DataBuffer);
+    if (EFI_ERROR (Status)) {
+      goto EXIT;
+    }
+  }
+
+EXIT:
+  NorFlashUnlock (&Lock);
+
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR,
+      "NOR FLASH Programming [WriteSingleBlock] failed at address 0x%08x. Exit Status = \"%r\".\n",
+      WordAddress, Status));
+  }
+  return Status;
+}
+
+EFI_STATUS
+NorFlashWriteBlocks (
+  IN NOR_FLASH_INSTANCE     *Instance,
+  IN EFI_LBA                Lba,
+  IN UINTN                  BufferSizeInBytes,
+  IN VOID                   *Buffer
+  )
+{
+  UINT32          *pWriteBuffer;
+  EFI_STATUS      Status = EFI_SUCCESS;
+  EFI_LBA         CurrentBlock;
+  UINT32          BlockSizeInWords;
+  UINT32          NumBlocks;
+  UINT32          BlockCount;
+
+  // The buffer must be valid
+  if (Buffer == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // We must have some bytes to read
+  DEBUG ((DEBUG_BLKIO, "NorFlashWriteBlocks: BufferSizeInBytes=0x%x\n",
+    BufferSizeInBytes));
+  if (BufferSizeInBytes == 0) {
+    return EFI_BAD_BUFFER_SIZE;
+  }
+
+  // The size of the buffer must be a multiple of the block size
+  DEBUG ((DEBUG_BLKIO, "NorFlashWriteBlocks: BlockSize in bytes =0x%x\n",
+    Instance->BlockSize));
+  if ((BufferSizeInBytes % Instance->BlockSize) != 0) {
+    return EFI_BAD_BUFFER_SIZE;
+  }
+
+  // All blocks must be within the device
+  NumBlocks = ((UINT32)BufferSizeInBytes) / Instance->BlockSize ;
+
+  DEBUG ((DEBUG_BLKIO,
+    "NorFlashWriteBlocks: NumBlocks=%d, LastBlock=%ld, Lba=%ld.\n", NumBlocks,
+    Instance->LastBlock, Lba));
+
+  if ((Lba + NumBlocks) > (Instance->LastBlock + 1)) {
+    DEBUG ((DEBUG_ERROR,
+      "NorFlashWriteBlocks: ERROR - Write will exceed last block.\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  ASSERT (((UINTN)Buffer % sizeof (UINT32)) == 0);
+
+  BlockSizeInWords = Instance->BlockSize / 4;
+
+  // Because the target *Buffer is a pointer to VOID, we must put
+  // all the data into a pointer to a proper data type, so use *ReadBuffer
+  pWriteBuffer = (UINT32 *)Buffer;
+
+  CurrentBlock = Lba;
+  for (BlockCount = 0;
+       BlockCount < NumBlocks;
+       BlockCount++, CurrentBlock++, pWriteBuffer += BlockSizeInWords) {
+
+    DEBUG ((DEBUG_BLKIO, "NorFlashWriteBlocks: Writing block #%d\n",
+      (UINTN)CurrentBlock));
+
+    Status = NorFlashWriteFullBlock (Instance, CurrentBlock, pWriteBuffer,
+               BlockSizeInWords);
+
+    if (EFI_ERROR (Status)) {
+      break;
+    }
+  }
+
+  DEBUG ((DEBUG_BLKIO, "NorFlashWriteBlocks: Exit Status = \"%r\".\n", Status));
+  return Status;
+}
+
+EFI_STATUS
+NorFlashReadBlocks (
+  IN NOR_FLASH_INSTANCE   *Instance,
+  IN EFI_LBA              Lba,
+  IN UINTN                BufferSizeInBytes,
+  OUT VOID                *Buffer
+  )
+{
+  UINT32              NumBlocks;
+  UINTN               StartAddress;
+
+  DEBUG ((DEBUG_BLKIO,
+    "NorFlashReadBlocks: BufferSize=0x%xB BlockSize=0x%xB LastBlock=%ld, Lba=%ld.\n",
+    BufferSizeInBytes, Instance->BlockSize, Instance->LastBlock,
+    Lba));
+
+  // The buffer must be valid
+  if (Buffer == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // Return if we have not any byte to read
+  if (BufferSizeInBytes == 0) {
+    return EFI_SUCCESS;
+  }
+
+  // The size of the buffer must be a multiple of the block size
+  if ((BufferSizeInBytes % Instance->BlockSize) != 0) {
+    return EFI_BAD_BUFFER_SIZE;
+  }
+
+  // All blocks must be within the device
+  NumBlocks = ((UINT32)BufferSizeInBytes) / Instance->BlockSize ;
+
+  if ((Lba + NumBlocks) > (Instance->LastBlock + 1)) {
+    DEBUG ((DEBUG_ERROR,
+      "NorFlashReadBlocks: ERROR - Read will exceed last block\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // Get the address to start reading from
+  StartAddress = GET_NOR_BLOCK_ADDRESS (Instance->RegionBaseAddress, Lba,
+                                        Instance->BlockSize);
+
+  // Put the device into Read Array mode
+  NorFlashSetHostCommand (Instance, SPINOR_OP_READ_4B);
+  NorFlashSetHostCSDC (Instance, TRUE, mFip006NullCmdSeq);
+
+  // Readout the data
+  CopyMem(Buffer, (UINTN *)StartAddress, BufferSizeInBytes);
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+NorFlashRead (
+  IN NOR_FLASH_INSTANCE   *Instance,
+  IN EFI_LBA              Lba,
+  IN UINTN                Offset,
+  IN UINTN                BufferSizeInBytes,
+  OUT VOID                *Buffer
+  )
+{
+  UINTN  StartAddress;
+
+  // The buffer must be valid
+  if (Buffer == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // Return if we have not any byte to read
+  if (BufferSizeInBytes == 0) {
+    return EFI_SUCCESS;
+  }
+
+  if (((Lba * Instance->BlockSize) + Offset + BufferSizeInBytes) >
+      Instance->Size) {
+    DEBUG ((DEBUG_ERROR,
+      "NorFlashRead: ERROR - Read will exceed device size.\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // Get the address to start reading from
+  StartAddress = GET_NOR_BLOCK_ADDRESS (Instance->RegionBaseAddress, Lba,
+                                        Instance->BlockSize);
+
+  // Put the device into Read Array mode
+  NorFlashSetHostCommand (Instance, SPINOR_OP_READ_4B);
+  NorFlashSetHostCSDC (Instance, TRUE, mFip006NullCmdSeq);
+
+  // Readout the data
+  CopyMem (Buffer, (UINTN *)(StartAddress + Offset), BufferSizeInBytes);
+
+  return EFI_SUCCESS;
+}
+
+/*
+  Write a full or portion of a block. It must not span block boundaries;
+  that is, Offset + *NumBytes <= Instance->BlockSize.
+*/
+EFI_STATUS
+NorFlashWriteSingleBlock (
+  IN        NOR_FLASH_INSTANCE   *Instance,
+  IN        EFI_LBA               Lba,
+  IN        UINTN                 Offset,
+  IN OUT    UINTN                *NumBytes,
+  IN        UINT8                *Buffer
+  )
+{
+  EFI_STATUS  TempStatus;
+  UINT32      Tmp;
+  UINT32      TmpBuf;
+  UINT32      WordToWrite;
+  UINT32      Mask;
+  BOOLEAN     DoErase;
+  UINTN       BytesToWrite;
+  UINTN       CurOffset;
+  UINTN       WordAddr;
+  UINTN       BlockSize;
+  UINTN       BlockAddress;
+  UINTN       PrevBlockAddress;
+
+  PrevBlockAddress = 0;
+
+  if (!Instance->Initialized && Instance->Initialize) {
+    Instance->Initialize(Instance);
+  }
+
+  DEBUG ((DEBUG_BLKIO,
+    "NorFlashWriteSingleBlock(Parameters: Lba=%ld, Offset=0x%x, *NumBytes=0x%x, Buffer @ 0x%08x)\n",
+    Lba, Offset, *NumBytes, Buffer));
+
+  // Cache the block size to avoid de-referencing pointers all the time
+  BlockSize = Instance->BlockSize;
+
+  // The write must not span block boundaries.
+  // We need to check each variable individually because adding two large
+  // values together overflows.
+  if (Offset               >= BlockSize ||
+      *NumBytes            >  BlockSize ||
+      (Offset + *NumBytes) >  BlockSize) {
+    DEBUG ((DEBUG_ERROR,
+      "NorFlashWriteSingleBlock: ERROR - EFI_BAD_BUFFER_SIZE: (Offset=0x%x + NumBytes=0x%x) > BlockSize=0x%x\n",
+      Offset, *NumBytes, BlockSize ));
+    return EFI_BAD_BUFFER_SIZE;
+  }
+
+  // We must have some bytes to write
+  if (*NumBytes == 0) {
+    DEBUG ((DEBUG_ERROR,
+      "NorFlashWriteSingleBlock: ERROR - EFI_BAD_BUFFER_SIZE: (Offset=0x%x + NumBytes=0x%x) > BlockSize=0x%x\n",
+      Offset, *NumBytes, BlockSize ));
+    return EFI_BAD_BUFFER_SIZE;
+  }
+
+  // Pick 128bytes as a good start for word operations as opposed to erasing the
+  // block and writing the data regardless if an erase is really needed.
+  // It looks like most individual NV variable writes are smaller than 128bytes.
+  if (*NumBytes <= 128) {
+    // Check to see if we need to erase before programming the data into NOR.
+    // If the destination bits are only changing from 1s to 0s we can just write.
+    // After a block is erased all bits in the block is set to 1.
+    // If any byte requires us to erase we just give up and rewrite all of it.
+    DoErase      = FALSE;
+    BytesToWrite = *NumBytes;
+    CurOffset    = Offset;
+
+    while (BytesToWrite > 0) {
+      // Read full word from NOR, splice as required. A word is the smallest
+      // unit we can write.
+      TempStatus = NorFlashRead (Instance, Lba, CurOffset & ~(0x3), sizeof(Tmp),
+                     &Tmp);
+      if (EFI_ERROR (TempStatus)) {
+        return EFI_DEVICE_ERROR;
+      }
+
+      // Physical address of word in NOR to write.
+      WordAddr = (CurOffset & ~(0x3)) +
+                 GET_NOR_BLOCK_ADDRESS (Instance->RegionBaseAddress, Lba,
+                   BlockSize);
+
+      // The word of data that is to be written.
+      TmpBuf = *((UINT32*)(Buffer + (*NumBytes - BytesToWrite)));
+
+      // First do word aligned chunks.
+      if ((CurOffset & 0x3) == 0) {
+        if (BytesToWrite >= 4) {
+          // Is the destination still in 'erased' state?
+          if (~Tmp != 0) {
+            // Check to see if we are only changing bits to zero.
+            if ((Tmp ^ TmpBuf) & TmpBuf) {
+              DoErase = TRUE;
+              break;
+            }
+          }
+          // Write this word to NOR
+          WordToWrite = TmpBuf;
+          CurOffset += sizeof(TmpBuf);
+          BytesToWrite -= sizeof(TmpBuf);
+        } else {
+          // BytesToWrite < 4. Do small writes and left-overs
+          Mask = ~((~0) << (BytesToWrite * 8));
+          // Mask out the bytes we want.
+          TmpBuf &= Mask;
+          // Is the destination still in 'erased' state?
+          if ((Tmp & Mask) != Mask) {
+            // Check to see if we are only changing bits to zero.
+            if ((Tmp ^ TmpBuf) & TmpBuf) {
+              DoErase = TRUE;
+              break;
+            }
+          }
+          // Merge old and new data. Write merged word to NOR
+          WordToWrite = (Tmp & ~Mask) | TmpBuf;
+          CurOffset += BytesToWrite;
+          BytesToWrite = 0;
+        }
+      } else {
+        // Do multiple words, but starting unaligned.
+        if (BytesToWrite > (4 - (CurOffset & 0x3))) {
+          Mask = ((~0) << ((CurOffset & 0x3) * 8));
+          // Mask out the bytes we want.
+          TmpBuf &= Mask;
+          // Is the destination still in 'erased' state?
+          if ((Tmp & Mask) != Mask) {
+            // Check to see if we are only changing bits to zero.
+            if ((Tmp ^ TmpBuf) & TmpBuf) {
+              DoErase = TRUE;
+              break;
+            }
+          }
+          // Merge old and new data. Write merged word to NOR
+          WordToWrite = (Tmp & ~Mask) | TmpBuf;
+          BytesToWrite -= (4 - (CurOffset & 0x3));
+          CurOffset += (4 - (CurOffset & 0x3));
+        } else {
+          // Unaligned and fits in one word.
+          Mask = (~((~0) << (BytesToWrite * 8))) << ((CurOffset & 0x3) * 8);
+          // Mask out the bytes we want.
+          TmpBuf = (TmpBuf << ((CurOffset & 0x3) * 8)) & Mask;
+          // Is the destination still in 'erased' state?
+          if ((Tmp & Mask) != Mask) {
+            // Check to see if we are only changing bits to zero.
+            if ((Tmp ^ TmpBuf) & TmpBuf) {
+              DoErase = TRUE;
+              break;
+            }
+          }
+          // Merge old and new data. Write merged word to NOR
+          WordToWrite = (Tmp & ~Mask) | TmpBuf;
+          CurOffset += BytesToWrite;
+          BytesToWrite = 0;
+        }
+      }
+
+      //
+      // Write the word to NOR.
+      //
+
+      BlockAddress = GET_NOR_BLOCK_ADDRESS (Instance->RegionBaseAddress, Lba,
+        BlockSize);
+      if (BlockAddress != PrevBlockAddress) {
+        TempStatus = NorFlashUnlockSingleBlockIfNecessary (Instance,
+                       BlockAddress);
+        if (EFI_ERROR (TempStatus)) {
+          return EFI_DEVICE_ERROR;
+        }
+        PrevBlockAddress = BlockAddress;
+      }
+      TempStatus = NorFlashWriteSingleWord (Instance, WordAddr, WordToWrite);
+      if (EFI_ERROR (TempStatus)) {
+        return EFI_DEVICE_ERROR;
+      }
+    }
+    // Exit if we got here and could write all the data. Otherwise do the
+    // Erase-Write cycle.
+    if (!DoErase) {
+      return EFI_SUCCESS;
+    }
+  }
+
+  // Check we did get some memory. Buffer is BlockSize.
+  if (Instance->ShadowBuffer == NULL) {
+    DEBUG ((DEBUG_ERROR, "FvbWrite: ERROR - Buffer not ready\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  // Read NOR Flash data into shadow buffer
+  TempStatus = NorFlashReadBlocks (Instance, Lba, BlockSize,
+                 Instance->ShadowBuffer);
+  if (EFI_ERROR (TempStatus)) {
+    // Return one of the pre-approved error statuses
+    return EFI_DEVICE_ERROR;
+  }
+
+  // Put the data at the appropriate location inside the buffer area
+  CopyMem ((VOID*)((UINTN)Instance->ShadowBuffer + Offset), Buffer, *NumBytes);
+
+  // Write the modified buffer back to the NorFlash
+  TempStatus = NorFlashWriteBlocks (Instance, Lba, BlockSize,
+                 Instance->ShadowBuffer);
+  if (EFI_ERROR (TempStatus)) {
+    // Return one of the pre-approved error statuses
+    return EFI_DEVICE_ERROR;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+NorFlashReset (
+  IN  NOR_FLASH_INSTANCE *Instance
+  )
+{
+  FIP006_CS_CFG         CsCfg;
+
+  DEBUG ((DEBUG_BLKIO, "NorFlashReset()\n"));
+  CsCfg.Raw = MmioRead32 (Instance->HostRegisterBaseAddress +
+                          FIP006_REG_CS_CFG);
+  CsCfg.Reg.MBM = CS_CFG_MBM_SINGLE;
+  CsCfg.Reg.SRAM = CS_CFG_SRAM_RW;
+  MmioWrite32 (Instance->HostRegisterBaseAddress + FIP006_REG_CS_CFG,
+               CsCfg.Raw);
+  NorFlashSetHostCommand (Instance, SPINOR_OP_READ_4B);
+  NorFlashSetHostCSDC (Instance, TRUE, mFip006NullCmdSeq);
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+NorFlashReadID (
+  IN  NOR_FLASH_INSTANCE  *Instance,
+  OUT UINT8               JedecId[3]
+  )
+{
+  if (Instance == NULL || JedecId == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  NorFlashSetHostCommand (Instance, SPINOR_OP_RDID);
+  JedecId[0] = MmioRead8 (Instance->DeviceBaseAddress);
+  JedecId[1] = MmioRead8 (Instance->DeviceBaseAddress + 1);
+  JedecId[2] = MmioRead8 (Instance->DeviceBaseAddress + 2);
+  NorFlashSetHostCommand (Instance, SPINOR_OP_READ_4B);
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Socionext/SynQuacer/Drivers/Fip006Dxe/NorFlashDxe.h b/Silicon/Socionext/SynQuacer/Drivers/Fip006Dxe/NorFlash.h
similarity index 88%
rename from Silicon/Socionext/SynQuacer/Drivers/Fip006Dxe/NorFlashDxe.h
rename to Silicon/Socionext/SynQuacer/Drivers/Fip006Dxe/NorFlash.h
index 20e74b0320ce..61b8e6a08fa0 100644
--- a/Silicon/Socionext/SynQuacer/Drivers/Fip006Dxe/NorFlashDxe.h
+++ b/Silicon/Socionext/SynQuacer/Drivers/Fip006Dxe/NorFlash.h
@@ -27,11 +27,9 @@
 #include <Protocol/FirmwareVolumeBlock.h>
 
 #include <Library/DebugLib.h>
-#include <Library/DxeServicesTableLib.h>
 #include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
 #include <Library/NorFlashPlatformLib.h>
-#include <Library/UefiLib.h>
-#include <Library/UefiRuntimeLib.h>
 
 #include "Fip006Reg.h"
 
@@ -112,13 +110,27 @@ struct _NOR_FLASH_INSTANCE {
 
   NOR_FLASH_DEVICE_PATH               DevicePath;
 
-  CONST CSDC_DEFINITION               *CmdTable;
-  UINTN                               CmdTableSize;
-
   UINT32                              Flags;
 #define NOR_FLASH_POLL_FSR      BIT0
 };
 
+typedef struct {
+  EFI_TPL         OriginalTPL;
+  BOOLEAN         InterruptsEnabled;
+} NOR_FLASH_LOCK_CONTEXT;
+
+VOID
+EFIAPI
+NorFlashLock (
+  NOR_FLASH_LOCK_CONTEXT    *Context
+  );
+
+VOID
+EFIAPI
+NorFlashUnlock (
+  NOR_FLASH_LOCK_CONTEXT    *Context
+  );
+
 EFI_STATUS
 NorFlashReadCfiData (
   IN  UINTN                   DeviceBaseAddress,
@@ -135,14 +147,34 @@ NorFlashWriteBuffer (
   IN UINT32                 *Buffer
   );
 
-//
-// NorFlashFvbDxe.c
-//
+extern UINTN     mFlashNvStorageVariableBase;
+
+EFI_STATUS
+NorFlashCreateInstance (
+  IN UINTN                  HostRegisterBase,
+  IN UINTN                  NorFlashDeviceBase,
+  IN UINTN                  NorFlashRegionBase,
+  IN UINTN                  NorFlashSize,
+  IN UINT32                 Index,
+  IN UINT32                 BlockSize,
+  IN BOOLEAN                HasVarStore,
+  OUT NOR_FLASH_INSTANCE**  NorFlashInstance
+  );
 
 EFI_STATUS
 EFIAPI
 NorFlashFvbInitialize (
-  IN NOR_FLASH_INSTANCE*                            Instance
+  IN NOR_FLASH_INSTANCE* Instance
+  );
+
+EFI_STATUS
+ValidateFvHeader (
+  IN  NOR_FLASH_INSTANCE *Instance
+  );
+
+EFI_STATUS
+InitializeFvAndVariableStoreHeaders (
+  IN NOR_FLASH_INSTANCE *Instance
   );
 
 EFI_STATUS
diff --git a/Silicon/Socionext/SynQuacer/Drivers/Fip006Dxe/NorFlashDxe.c b/Silicon/Socionext/SynQuacer/Drivers/Fip006Dxe/NorFlashDxe.c
index e52ab52d8cf7..6c07799b22d8 100644
--- a/Silicon/Socionext/SynQuacer/Drivers/Fip006Dxe/NorFlashDxe.c
+++ b/Silicon/Socionext/SynQuacer/Drivers/Fip006Dxe/NorFlashDxe.c
@@ -15,15 +15,16 @@
 **/
 
 #include <Library/BaseMemoryLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/HobLib.h>
 #include <Library/MemoryAllocationLib.h>
 #include <Library/NorFlashInfoLib.h>
 #include <Library/PcdLib.h>
 #include <Library/UefiBootServicesTableLib.h>
 #include <Library/UefiLib.h>
+#include <Library/UefiRuntimeLib.h>
 
-#include "NorFlashDxe.h"
-
-STATIC EFI_EVENT mNorFlashVirtualAddrChangeEvent;
+#include "NorFlash.h"
 
 //
 // Global variable declarations
@@ -31,1035 +32,129 @@ STATIC EFI_EVENT mNorFlashVirtualAddrChangeEvent;
 STATIC NOR_FLASH_INSTANCE   **mNorFlashInstances;
 STATIC UINT32               mNorFlashDeviceCount;
 
-STATIC CONST UINT16 mFip006NullCmdSeq[] = {
-  CSDC (CSDC_END, CSDC_CONT_NON_CONTINUOUS, CSDC_TRP_MBM, CSDC_DEC_DECODE),
-  CSDC (CSDC_END, CSDC_CONT_NON_CONTINUOUS, CSDC_TRP_MBM, CSDC_DEC_DECODE),
-  CSDC (CSDC_END, CSDC_CONT_NON_CONTINUOUS, CSDC_TRP_MBM, CSDC_DEC_DECODE),
-  CSDC (CSDC_END, CSDC_CONT_NON_CONTINUOUS, CSDC_TRP_MBM, CSDC_DEC_DECODE),
-  CSDC (CSDC_END, CSDC_CONT_NON_CONTINUOUS, CSDC_TRP_MBM, CSDC_DEC_DECODE),
-  CSDC (CSDC_END, CSDC_CONT_NON_CONTINUOUS, CSDC_TRP_MBM, CSDC_DEC_DECODE),
-  CSDC (CSDC_END, CSDC_CONT_NON_CONTINUOUS, CSDC_TRP_MBM, CSDC_DEC_DECODE),
-  CSDC (CSDC_END, CSDC_CONT_NON_CONTINUOUS, CSDC_TRP_MBM, CSDC_DEC_DECODE),
-};
-
-STATIC CONST CSDC_DEFINITION mN25qCSDCDefTable[] = {
-  // Identification Operations
-  { SPINOR_OP_RDID,     FALSE, FALSE, FALSE, FALSE, CS_CFG_MBM_SINGLE,
-                        CSDC_TRP_SINGLE },
-  // Register Operations
-  { SPINOR_OP_RDSR,     FALSE, FALSE, FALSE, FALSE, CS_CFG_MBM_SINGLE,
-                        CSDC_TRP_SINGLE },
-  { SPINOR_OP_WRSR,     FALSE, FALSE, FALSE, TRUE,  CS_CFG_MBM_SINGLE,
-                        CSDC_TRP_SINGLE },
-  { SPINOR_OP_RD_ARRAY, TRUE,  FALSE, FALSE, FALSE, CS_CFG_MBM_SINGLE,
-                        CSDC_TRP_SINGLE },
-  { SPINOR_OP_RDFSR,    FALSE, FALSE, FALSE, FALSE, CS_CFG_MBM_SINGLE,
-                        CSDC_TRP_SINGLE },
-  { SPINOR_OP_RD_NVCFG, FALSE, FALSE, FALSE, FALSE, CS_CFG_MBM_SINGLE,
-                        CSDC_TRP_SINGLE },
-  { SPINOR_OP_RD_VCR,   FALSE, FALSE, FALSE, FALSE, CS_CFG_MBM_SINGLE,
-                        CSDC_TRP_SINGLE },
-  { SPINOR_OP_RD_EVCR,  FALSE, FALSE, FALSE, FALSE, CS_CFG_MBM_SINGLE,
-                        CSDC_TRP_SINGLE },
-  // Read Operations
-  { SPINOR_OP_READ_4B,  TRUE,  TRUE,  FALSE, FALSE, CS_CFG_MBM_SINGLE,
-                        CSDC_TRP_SINGLE },
-  // Write Operations
-  { SPINOR_OP_PP,       TRUE,  FALSE, FALSE, TRUE,  CS_CFG_MBM_SINGLE,
-                        CSDC_TRP_SINGLE },
-  { SPINOR_OP_PP_1_1_4, TRUE,  FALSE, FALSE, TRUE,  CS_CFG_MBM_QUAD,
-                        CSDC_TRP_SINGLE },
-  // Erase Operations
-  { SPINOR_OP_SE,       FALSE, FALSE, FALSE, TRUE,  CS_CFG_MBM_SINGLE,
-                        CSDC_TRP_SINGLE },
-};
-
-STATIC
-EFI_STATUS
-NorFlashSetHostCSDC (
-  IN  NOR_FLASH_INSTANCE    *Instance,
-  IN  BOOLEAN               ReadWrite,
-  IN  CONST UINT16          CSDC[ARRAY_SIZE (mFip006NullCmdSeq)]
-  )
-{
-  EFI_PHYSICAL_ADDRESS      Dst;
-  UINTN                     Index;
-
-  Dst = Instance->HostRegisterBaseAddress
-        + (ReadWrite ? FIP006_REG_CS_WR : FIP006_REG_CS_RD);
-  for (Index = 0; Index < ARRAY_SIZE (mFip006NullCmdSeq); Index++) {
-    MmioWrite16 (Dst + (Index << 1), CSDC[Index]);
-  }
-  return EFI_SUCCESS;
-}
-
-STATIC
-CONST CSDC_DEFINITION *
-NorFlashGetCmdDef (
-  IN  NOR_FLASH_INSTANCE    *Instance,
-  IN  UINT8                 Code
-  )
-{
-  CONST CSDC_DEFINITION *Cmd;
-  UINTN                 Index;
-
-  Cmd = NULL;
-  for (Index = 0; Index <  Instance->CmdTableSize; Index++) {
-    if (Code == Instance->CmdTable[Index].Code) {
-      Cmd = &Instance->CmdTable[Index];
-      break;
-    }
-  }
-  return Cmd;
-}
-
-STATIC
-EFI_STATUS
-GenCSDC (
-  IN  UINT8     Cmd,
-  IN  BOOLEAN   AddrAccess,
-  IN  BOOLEAN   AddrMode4Byte,
-  IN  BOOLEAN   HighZ,
-  IN  UINT8     TransferMode,
-  OUT UINT16    *CmdSeq
-  )
-{
-  UINTN         Index;
-
-  if (!CmdSeq) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  Index = 0;
-  CopyMem (CmdSeq, mFip006NullCmdSeq, sizeof (mFip006NullCmdSeq));
-
-  CmdSeq[Index++] = CSDC (Cmd, CSDC_CONT_NON_CONTINUOUS, TransferMode,
-                          CSDC_DEC_LEAVE_ASIS);
-  if (AddrAccess) {
-    if (AddrMode4Byte) {
-      CmdSeq[Index++] = CSDC (CSDC_ADDRESS_31_24, CSDC_CONT_NON_CONTINUOUS,
-                              TransferMode, CSDC_DEC_DECODE);
-    }
-    CmdSeq[Index++] = CSDC (CSDC_ADDRESS_23_16, CSDC_CONT_NON_CONTINUOUS,
-                            TransferMode, CSDC_DEC_DECODE);
-    CmdSeq[Index++] = CSDC (CSDC_ADDRESS_15_8, CSDC_CONT_NON_CONTINUOUS,
-                            TransferMode, CSDC_DEC_DECODE);
-    CmdSeq[Index++] = CSDC (CSDC_ADDRESS_7_0, CSDC_CONT_NON_CONTINUOUS,
-                            TransferMode, CSDC_DEC_DECODE);
-  }
-  if (HighZ) {
-    CmdSeq[Index++] = CSDC (CSDC_HIGH_Z, CSDC_CONT_NON_CONTINUOUS,
-                            TransferMode, CSDC_DEC_DECODE);
-  }
-
-  return EFI_SUCCESS;
-}
-
-STATIC
-EFI_STATUS
-NorFlashSetHostCommand (
-  IN  NOR_FLASH_INSTANCE    *Instance,
-  IN  UINT8                 Code
-  )
-{
-  CONST CSDC_DEFINITION     *Cmd;
-  UINT16                    CSDC[ARRAY_SIZE (mFip006NullCmdSeq)];
-
-  Cmd = NorFlashGetCmdDef (Instance, Code);
-  if (Cmd == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-  GenCSDC (
-      Cmd->Code,
-      Cmd->AddrAccess,
-      Cmd->AddrMode4Byte,
-      Cmd->HighZ,
-      Cmd->CsdcTrp,
-      CSDC
-      );
-  NorFlashSetHostCSDC (Instance, Cmd->ReadWrite, CSDC);
-  return EFI_SUCCESS;
-}
-
-STATIC
-UINT8
-NorFlashReadStatusRegister (
-  IN NOR_FLASH_INSTANCE     *Instance
-  )
-{
-  UINT8       StatusRegister;
-
-  NorFlashSetHostCommand (Instance, SPINOR_OP_RDSR);
-  StatusRegister = MmioRead8 (Instance->RegionBaseAddress);
-  NorFlashSetHostCommand (Instance, SPINOR_OP_READ_4B);
-  return StatusRegister;
-}
-
-STATIC
-EFI_STATUS
-NorFlashWaitProgramErase (
-  IN NOR_FLASH_INSTANCE     *Instance
-  )
-{
-  BOOLEAN     SRegDone;
-  BOOLEAN     FSRegDone;
-
-  DEBUG ((DEBUG_BLKIO, "NorFlashWaitProgramErase()\n"));
-
-  do {
-    SRegDone = (NorFlashReadStatusRegister (Instance) & SPINOR_SR_WIP) == 0;
-    FSRegDone = TRUE;
-    if (Instance->Flags & NOR_FLASH_POLL_FSR) {
-      NorFlashSetHostCommand (Instance, SPINOR_OP_RDFSR);
-      FSRegDone = (MmioRead8 (Instance->RegionBaseAddress) &
-                   SPINOR_FSR_READY) != 0;
-    }
-  } while (!SRegDone || !FSRegDone);
-  NorFlashSetHostCommand (Instance, SPINOR_OP_READ_4B);
-  return EFI_SUCCESS;
-}
-
-// TODO: implement lock checking
-STATIC
-BOOLEAN
-NorFlashBlockIsLocked (
-  IN NOR_FLASH_INSTANCE     *Instance,
-  IN UINTN                  BlockAddress
-  )
-{
-  return FALSE;
-}
-
-// TODO: implement sector unlocking
-STATIC
-EFI_STATUS
-NorFlashUnlockSingleBlock (
-  IN NOR_FLASH_INSTANCE     *Instance,
-  IN UINTN                  BlockAddress
-  )
-{
-  return EFI_SUCCESS;
-}
-
-STATIC
-EFI_STATUS
-NorFlashUnlockSingleBlockIfNecessary (
-  IN NOR_FLASH_INSTANCE     *Instance,
-  IN UINTN                  BlockAddress
-  )
-{
-  EFI_STATUS Status;
-
-  Status = EFI_SUCCESS;
-
-  if (NorFlashBlockIsLocked (Instance, BlockAddress) == TRUE) {
-    Status = NorFlashUnlockSingleBlock (Instance, BlockAddress);
-  }
-
-  return Status;
-}
-
-STATIC
-EFI_STATUS
-NorFlashEnableWrite (
-  IN  NOR_FLASH_INSTANCE    *Instance
-  )
-{
-  EFI_STATUS      Status;
-  UINT8           StatusRegister;
-  UINTN           Retry;
-
-  DEBUG ((DEBUG_BLKIO, "NorFlashEnableWrite()\n"));
-
-  Status = EFI_DEVICE_ERROR;
-  Retry = NOR_FLASH_ERASE_RETRY;
-
-  NorFlashSetHostCSDC (Instance, TRUE, mFip006NullCmdSeq);
-  while (Retry > 0 && EFI_ERROR (Status)) {
-    MmioWrite8 (Instance->RegionBaseAddress, SPINOR_OP_WREN);
-    MemoryFence ();
-    StatusRegister = NorFlashReadStatusRegister (Instance);
-    Status = (StatusRegister & BIT1) ? EFI_SUCCESS : EFI_DEVICE_ERROR;
-    Retry--;
-  }
-  return Status;
-}
+STATIC EFI_EVENT mNorFlashVirtualAddrChangeEvent;
 
-STATIC
 EFI_STATUS
-NorFlashDisableWrite (
-  IN  NOR_FLASH_INSTANCE    *Instance
+EFIAPI
+NorFlashFvbInitialize (
+  IN NOR_FLASH_INSTANCE* Instance
   )
 {
   EFI_STATUS      Status;
-  UINT8           StatusRegister;
-  UINTN           Retry;
-
-  DEBUG ((DEBUG_BLKIO, "NorFlashDisableWrite()\n"));
-
-  Status = EFI_DEVICE_ERROR;
-  Retry = NOR_FLASH_ERASE_RETRY;
-
-  NorFlashSetHostCSDC (Instance, TRUE, mFip006NullCmdSeq);
-  while (Retry > 0 && EFI_ERROR (Status)) {
-    MmioWrite8 (Instance->RegionBaseAddress, SPINOR_OP_WRDIS);
-    MemoryFence ();
-    StatusRegister = NorFlashReadStatusRegister (Instance);
-    Status = (StatusRegister & BIT1) ? EFI_DEVICE_ERROR : EFI_SUCCESS;
-    Retry--;
-  }
-  return Status;
-}
-
-/**
- * The following function presumes that the block has already been unlocked.
- **/
-STATIC
-EFI_STATUS
-NorFlashEraseSingleBlock (
-  IN NOR_FLASH_INSTANCE     *Instance,
-  IN UINTN                  BlockAddress
-  )
-{
-
-  DEBUG ((DEBUG_BLKIO, "NorFlashEraseSingleBlock(BlockAddress=0x%08x)\n",
-    BlockAddress));
-
-  if (EFI_ERROR (NorFlashEnableWrite (Instance))) {
-    return EFI_DEVICE_ERROR;
-  }
+  UINT32          FvbNumLba;
+  EFI_BOOT_MODE   BootMode;
+  UINTN           RuntimeMmioRegionSize;
+  UINTN           BlockSize;
 
-  //
-  // The virtual address chosen by the OS may have a different offset modulo
-  // 16 MB than the physical address, so we need to subtract the region base
-  // address before we can mask off a block index. Note that the relative
-  // offset between device base address and region base address may have changed
-  // as well, so we cannot use the device base address directly.
-  //
-  if (EfiAtRuntime()) {
-    BlockAddress -= Instance->RegionBaseAddress;
-    BlockAddress += Instance->OffsetLba * Instance->BlockSize;
-  }
-
-  NorFlashSetHostCSDC (Instance, TRUE, mFip006NullCmdSeq);
-  MmioWrite32 (Instance->DeviceBaseAddress,
-               SwapBytes32 (BlockAddress & 0x00FFFFFF) | SPINOR_OP_SE);
-  NorFlashWaitProgramErase (Instance);
-  NorFlashSetHostCSDC (Instance, TRUE, mFip006NullCmdSeq);
-
-  if (EFI_ERROR (NorFlashDisableWrite (Instance))) {
-    return EFI_DEVICE_ERROR;
-  }
-  return EFI_SUCCESS;
-}
-
-/**
- * This function unlock and erase an entire NOR Flash block.
- **/
-EFI_STATUS
-NorFlashUnlockAndEraseSingleBlock (
-  IN NOR_FLASH_INSTANCE     *Instance,
-  IN UINTN                  BlockAddress
-  )
-{
-  EFI_STATUS      Status;
-  UINTN           Index;
-  EFI_TPL         OriginalTPL;
-  BOOLEAN         InterruptsEnabled;
+  DEBUG ((DEBUG_BLKIO,"NorFlashFvbInitialize\n"));
 
-  OriginalTPL = 0;
-  InterruptsEnabled = FALSE;
+  BlockSize = Instance->BlockSize;
 
-  if (!EfiAtRuntime ()) {
-    // Raise TPL to TPL_HIGH to stop anyone from interrupting us.
-    OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
+  // FirmwareVolumeHeader->FvLength is declared to have the Variable area
+  // AND the FTW working area AND the FTW Spare contiguous.
+  ASSERT(PcdGet32(PcdFlashNvStorageVariableBase) +
+         PcdGet32(PcdFlashNvStorageVariableSize) ==
+         PcdGet32(PcdFlashNvStorageFtwWorkingBase));
+  ASSERT(PcdGet32(PcdFlashNvStorageFtwWorkingBase) +
+         PcdGet32(PcdFlashNvStorageFtwWorkingSize) ==
+         PcdGet32(PcdFlashNvStorageFtwSpareBase));
+
+  // Check if the size of the area is at least one block size
+  ASSERT((PcdGet32(PcdFlashNvStorageVariableSize) > 0) &&
+         (PcdGet32(PcdFlashNvStorageVariableSize) / BlockSize > 0));
+  ASSERT((PcdGet32(PcdFlashNvStorageFtwWorkingSize) > 0) &&
+         (PcdGet32(PcdFlashNvStorageFtwWorkingSize) / BlockSize > 0));
+  ASSERT((PcdGet32(PcdFlashNvStorageFtwSpareSize) > 0) &&
+         (PcdGet32(PcdFlashNvStorageFtwSpareSize) / BlockSize > 0));
+
+  // Ensure the Variable areas are aligned on block size boundaries
+  ASSERT((PcdGet32(PcdFlashNvStorageVariableBase) % BlockSize) == 0);
+  ASSERT((PcdGet32(PcdFlashNvStorageFtwWorkingBase) % BlockSize) == 0);
+  ASSERT((PcdGet32(PcdFlashNvStorageFtwSpareBase) % BlockSize) == 0);
+
+
+  Instance->Initialized = TRUE;
+  mFlashNvStorageVariableBase = FixedPcdGet32 (PcdFlashNvStorageVariableBase);
+
+  // Set the index of the first LBA for the FVB
+  Instance->StartLba = (PcdGet32 (PcdFlashNvStorageVariableBase) -
+                        Instance->RegionBaseAddress) / BlockSize;
+
+  BootMode = GetBootModeHob ();
+  if (BootMode == BOOT_WITH_DEFAULT_SETTINGS) {
+    Status = EFI_INVALID_PARAMETER;
   } else {
-    InterruptsEnabled = SaveAndDisableInterrupts ();
-  }
-
-  Index = 0;
-  // The block erase might fail a first time (SW bug ?). Retry it ...
-  do {
-    // Unlock the block if we have to
-    Status = NorFlashUnlockSingleBlockIfNecessary (Instance, BlockAddress);
-    if (EFI_ERROR (Status)) {
-      break;
+    // Determine if there is a valid header at the beginning of the NorFlash
+    Status = ValidateFvHeader (Instance);
+  }
+
+  // Install the Default FVB header if required
+  if (EFI_ERROR(Status)) {
+    // There is no valid header, so time to install one.
+    DEBUG ((DEBUG_INFO, "%a: The FVB Header is not valid.\n", __FUNCTION__));
+    DEBUG ((DEBUG_INFO, "%a: Installing a correct one for this volume.\n",
+      __FUNCTION__));
+
+    // Erase all the NorFlash that is reserved for variable storage
+    FvbNumLba = (PcdGet32(PcdFlashNvStorageVariableSize) +
+                 PcdGet32(PcdFlashNvStorageFtwWorkingSize) +
+                 PcdGet32(PcdFlashNvStorageFtwSpareSize)) /
+                Instance->BlockSize;
+
+    Status = FvbEraseBlocks (&Instance->FvbProtocol, (EFI_LBA)0, FvbNumLba,
+               EFI_LBA_LIST_TERMINATOR);
+    if (EFI_ERROR(Status)) {
+      return Status;
     }
-    Status = NorFlashEraseSingleBlock (Instance, BlockAddress);
-    Index++;
-  } while ((Index < NOR_FLASH_ERASE_RETRY) && (Status == EFI_WRITE_PROTECTED));
-
-  if (Index == NOR_FLASH_ERASE_RETRY) {
-    DEBUG ((DEBUG_ERROR,
-      "EraseSingleBlock(BlockAddress=0x%08x: Block Locked Error (try to erase %d times)\n",
-      BlockAddress,Index));
-  }
 
-  if (!EfiAtRuntime ()) {
-    // Interruptions can resume.
-    gBS->RestoreTPL (OriginalTPL);
-  } else if (InterruptsEnabled) {
-    SetInterruptState (TRUE);
-  }
-
-  return Status;
-}
-
-STATIC
-EFI_STATUS
-NorFlashWriteSingleWord (
-  IN NOR_FLASH_INSTANCE     *Instance,
-  IN UINTN                  WordAddress,
-  IN UINT32                 WriteData
-  )
-{
-  EFI_STATUS            Status;
-
-  DEBUG ((DEBUG_BLKIO,
-    "NorFlashWriteSingleWord(WordAddress=0x%08x, WriteData=0x%08x)\n",
-    WordAddress, WriteData));
-
-  Status = EFI_SUCCESS;
-
-  if (EFI_ERROR (NorFlashEnableWrite (Instance))) {
-    return EFI_DEVICE_ERROR;
-  }
-  NorFlashSetHostCommand (Instance, SPINOR_OP_PP);
-  MmioWrite32 (WordAddress, WriteData);
-  NorFlashWaitProgramErase (Instance);
-
-  NorFlashDisableWrite (Instance);
-  NorFlashSetHostCSDC (Instance, TRUE, mFip006NullCmdSeq);
-  return Status;
-}
-
-STATIC
-EFI_STATUS
-NorFlashWriteFullBlock (
-  IN NOR_FLASH_INSTANCE     *Instance,
-  IN EFI_LBA                Lba,
-  IN UINT32                 *DataBuffer,
-  IN UINT32                 BlockSizeInWords
-  )
-{
-  EFI_STATUS    Status;
-  UINTN         WordAddress;
-  UINT32        WordIndex;
-  UINTN         BlockAddress;
-  EFI_TPL       OriginalTPL;
-  BOOLEAN       InterruptsEnabled;
-
-  Status = EFI_SUCCESS;
-  OriginalTPL = 0;
-  InterruptsEnabled = FALSE;
-
-  // Get the physical address of the block
-  BlockAddress = GET_NOR_BLOCK_ADDRESS (Instance->RegionBaseAddress, Lba,
-                   BlockSizeInWords * 4);
-
-  // Start writing from the first address at the start of the block
-  WordAddress = BlockAddress;
-
-  if (!EfiAtRuntime ()) {
-    // Raise TPL to TPL_HIGH to stop anyone from interrupting us.
-    OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
-  } else {
-    InterruptsEnabled = SaveAndDisableInterrupts ();
-  }
-
-  Status = NorFlashUnlockAndEraseSingleBlock (Instance, BlockAddress);
-  if (EFI_ERROR (Status)) {
-    DEBUG ((DEBUG_ERROR,
-      "WriteSingleBlock: ERROR - Failed to Unlock and Erase the single block at 0x%X\n",
-      BlockAddress));
-    goto EXIT;
-  }
-
-  for (WordIndex=0;
-       WordIndex < BlockSizeInWords;
-       WordIndex++, DataBuffer++, WordAddress += 4) {
-    Status = NorFlashWriteSingleWord (Instance, WordAddress, *DataBuffer);
-    if (EFI_ERROR (Status)) {
-      goto EXIT;
+    // Install all appropriate headers
+    Status = InitializeFvAndVariableStoreHeaders (Instance);
+    if (EFI_ERROR(Status)) {
+      return Status;
     }
   }
 
-EXIT:
-  if (!EfiAtRuntime ()) {
-    // Interruptions can resume.
-    gBS->RestoreTPL (OriginalTPL);
-  } else if (InterruptsEnabled) {
-    SetInterruptState (TRUE);
-  }
-
+  //
+  // The driver implementing the variable read service can now be dispatched;
+  // the varstore headers are in place.
+  //
+  Status = gBS->InstallProtocolInterface (&gImageHandle,
+                  &gEdkiiNvVarStoreFormattedGuid,
+                  EFI_NATIVE_INTERFACE,
+                  NULL);
   if (EFI_ERROR (Status)) {
     DEBUG ((DEBUG_ERROR,
-      "NOR FLASH Programming [WriteSingleBlock] failed at address 0x%08x. Exit Status = \"%r\".\n",
-      WordAddress, Status));
-  }
-  return Status;
-}
-
-EFI_STATUS
-NorFlashWriteBlocks (
-  IN NOR_FLASH_INSTANCE     *Instance,
-  IN EFI_LBA                Lba,
-  IN UINTN                  BufferSizeInBytes,
-  IN VOID                   *Buffer
-  )
-{
-  UINT32          *pWriteBuffer;
-  EFI_STATUS      Status = EFI_SUCCESS;
-  EFI_LBA         CurrentBlock;
-  UINT32          BlockSizeInWords;
-  UINT32          NumBlocks;
-  UINT32          BlockCount;
-
-  // The buffer must be valid
-  if (Buffer == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  // We must have some bytes to read
-  DEBUG ((DEBUG_BLKIO, "NorFlashWriteBlocks: BufferSizeInBytes=0x%x\n",
-    BufferSizeInBytes));
-  if (BufferSizeInBytes == 0) {
-    return EFI_BAD_BUFFER_SIZE;
-  }
-
-  // The size of the buffer must be a multiple of the block size
-  DEBUG ((DEBUG_BLKIO, "NorFlashWriteBlocks: BlockSize in bytes =0x%x\n",
-    Instance->BlockSize));
-  if ((BufferSizeInBytes % Instance->BlockSize) != 0) {
-    return EFI_BAD_BUFFER_SIZE;
-  }
-
-  // All blocks must be within the device
-  NumBlocks = ((UINT32)BufferSizeInBytes) / Instance->BlockSize ;
-
-  DEBUG ((DEBUG_BLKIO,
-    "NorFlashWriteBlocks: NumBlocks=%d, LastBlock=%ld, Lba=%ld.\n", NumBlocks,
-    Instance->LastBlock, Lba));
-
-  if ((Lba + NumBlocks) > (Instance->LastBlock + 1)) {
-    DEBUG ((DEBUG_ERROR,
-      "NorFlashWriteBlocks: ERROR - Write will exceed last block.\n"));
-    return EFI_INVALID_PARAMETER;
-  }
-
-  ASSERT (((UINTN)Buffer % sizeof (UINT32)) == 0);
-
-  BlockSizeInWords = Instance->BlockSize / 4;
-
-  // Because the target *Buffer is a pointer to VOID, we must put
-  // all the data into a pointer to a proper data type, so use *ReadBuffer
-  pWriteBuffer = (UINT32 *)Buffer;
-
-  CurrentBlock = Lba;
-  for (BlockCount = 0;
-       BlockCount < NumBlocks;
-       BlockCount++, CurrentBlock++, pWriteBuffer += BlockSizeInWords) {
-
-    DEBUG ((DEBUG_BLKIO, "NorFlashWriteBlocks: Writing block #%d\n",
-      (UINTN)CurrentBlock));
-
-    Status = NorFlashWriteFullBlock (Instance, CurrentBlock, pWriteBuffer,
-               BlockSizeInWords);
-
-    if (EFI_ERROR (Status)) {
-      break;
-    }
-  }
-
-  DEBUG ((DEBUG_BLKIO, "NorFlashWriteBlocks: Exit Status = \"%r\".\n", Status));
-  return Status;
-}
-
-EFI_STATUS
-NorFlashReadBlocks (
-  IN NOR_FLASH_INSTANCE   *Instance,
-  IN EFI_LBA              Lba,
-  IN UINTN                BufferSizeInBytes,
-  OUT VOID                *Buffer
-  )
-{
-  UINT32              NumBlocks;
-  UINTN               StartAddress;
-
-  DEBUG ((DEBUG_BLKIO,
-    "NorFlashReadBlocks: BufferSize=0x%xB BlockSize=0x%xB LastBlock=%ld, Lba=%ld.\n",
-    BufferSizeInBytes, Instance->BlockSize, Instance->LastBlock,
-    Lba));
-
-  // The buffer must be valid
-  if (Buffer == NULL) {
-    return EFI_INVALID_PARAMETER;
+      "%a: Failed to install gEdkiiNvVarStoreFormattedGuid\n",
+      __FUNCTION__));
+      return Status;
   }
 
-  // Return if we have not any byte to read
-  if (BufferSizeInBytes == 0) {
-    return EFI_SUCCESS;
-  }
-
-  // The size of the buffer must be a multiple of the block size
-  if ((BufferSizeInBytes % Instance->BlockSize) != 0) {
-    return EFI_BAD_BUFFER_SIZE;
-  }
-
-  // All blocks must be within the device
-  NumBlocks = ((UINT32)BufferSizeInBytes) / Instance->BlockSize ;
-
-  if ((Lba + NumBlocks) > (Instance->LastBlock + 1)) {
-    DEBUG ((DEBUG_ERROR,
-      "NorFlashReadBlocks: ERROR - Read will exceed last block\n"));
-    return EFI_INVALID_PARAMETER;
-  }
-
-  // Get the address to start reading from
-  StartAddress = GET_NOR_BLOCK_ADDRESS (Instance->RegionBaseAddress, Lba,
-                                        Instance->BlockSize);
-
-  // Put the device into Read Array mode
-  NorFlashSetHostCommand (Instance, SPINOR_OP_READ_4B);
-  NorFlashSetHostCSDC (Instance, TRUE, mFip006NullCmdSeq);
-
-  // Readout the data
-  CopyMem(Buffer, (UINTN *)StartAddress, BufferSizeInBytes);
-
-  return EFI_SUCCESS;
-}
-
-EFI_STATUS
-NorFlashRead (
-  IN NOR_FLASH_INSTANCE   *Instance,
-  IN EFI_LBA              Lba,
-  IN UINTN                Offset,
-  IN UINTN                BufferSizeInBytes,
-  OUT VOID                *Buffer
-  )
-{
-  UINTN  StartAddress;
-
-  // The buffer must be valid
-  if (Buffer == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  // Return if we have not any byte to read
-  if (BufferSizeInBytes == 0) {
-    return EFI_SUCCESS;
-  }
-
-  if (((Lba * Instance->BlockSize) + Offset + BufferSizeInBytes) >
-      Instance->Size) {
-    DEBUG ((DEBUG_ERROR,
-      "NorFlashRead: ERROR - Read will exceed device size.\n"));
-    return EFI_INVALID_PARAMETER;
-  }
-
-  // Get the address to start reading from
-  StartAddress = GET_NOR_BLOCK_ADDRESS (Instance->RegionBaseAddress, Lba,
-                                        Instance->BlockSize);
-
-  // Put the device into Read Array mode
-  NorFlashSetHostCommand (Instance, SPINOR_OP_READ_4B);
-  NorFlashSetHostCSDC (Instance, TRUE, mFip006NullCmdSeq);
-
-  // Readout the data
-  CopyMem (Buffer, (UINTN *)(StartAddress + Offset), BufferSizeInBytes);
-
-  return EFI_SUCCESS;
-}
-
-/*
-  Write a full or portion of a block. It must not span block boundaries;
-  that is, Offset + *NumBytes <= Instance->BlockSize.
-*/
-EFI_STATUS
-NorFlashWriteSingleBlock (
-  IN        NOR_FLASH_INSTANCE   *Instance,
-  IN        EFI_LBA               Lba,
-  IN        UINTN                 Offset,
-  IN OUT    UINTN                *NumBytes,
-  IN        UINT8                *Buffer
-  )
-{
-  EFI_STATUS  TempStatus;
-  UINT32      Tmp;
-  UINT32      TmpBuf;
-  UINT32      WordToWrite;
-  UINT32      Mask;
-  BOOLEAN     DoErase;
-  UINTN       BytesToWrite;
-  UINTN       CurOffset;
-  UINTN       WordAddr;
-  UINTN       BlockSize;
-  UINTN       BlockAddress;
-  UINTN       PrevBlockAddress;
-
-  PrevBlockAddress = 0;
-
-  if (!Instance->Initialized && Instance->Initialize) {
-    Instance->Initialize(Instance);
-  }
-
-  DEBUG ((DEBUG_BLKIO,
-    "NorFlashWriteSingleBlock(Parameters: Lba=%ld, Offset=0x%x, *NumBytes=0x%x, Buffer @ 0x%08x)\n",
-    Lba, Offset, *NumBytes, Buffer));
-
-  // Cache the block size to avoid de-referencing pointers all the time
-  BlockSize = Instance->BlockSize;
-
-  // The write must not span block boundaries.
-  // We need to check each variable individually because adding two large
-  // values together overflows.
-  if (Offset               >= BlockSize ||
-      *NumBytes            >  BlockSize ||
-      (Offset + *NumBytes) >  BlockSize) {
-    DEBUG ((DEBUG_ERROR,
-      "NorFlashWriteSingleBlock: ERROR - EFI_BAD_BUFFER_SIZE: (Offset=0x%x + NumBytes=0x%x) > BlockSize=0x%x\n",
-      Offset, *NumBytes, BlockSize ));
-    return EFI_BAD_BUFFER_SIZE;
-  }
-
-  // We must have some bytes to write
-  if (*NumBytes == 0) {
-    DEBUG ((DEBUG_ERROR,
-      "NorFlashWriteSingleBlock: ERROR - EFI_BAD_BUFFER_SIZE: (Offset=0x%x + NumBytes=0x%x) > BlockSize=0x%x\n",
-      Offset, *NumBytes, BlockSize ));
-    return EFI_BAD_BUFFER_SIZE;
-  }
-
-  // Pick 128bytes as a good start for word operations as opposed to erasing the
-  // block and writing the data regardless if an erase is really needed.
-  // It looks like most individual NV variable writes are smaller than 128bytes.
-  if (*NumBytes <= 128) {
-    // Check to see if we need to erase before programming the data into NOR.
-    // If the destination bits are only changing from 1s to 0s we can just write.
-    // After a block is erased all bits in the block is set to 1.
-    // If any byte requires us to erase we just give up and rewrite all of it.
-    DoErase      = FALSE;
-    BytesToWrite = *NumBytes;
-    CurOffset    = Offset;
-
-    while (BytesToWrite > 0) {
-      // Read full word from NOR, splice as required. A word is the smallest
-      // unit we can write.
-      TempStatus = NorFlashRead (Instance, Lba, CurOffset & ~(0x3), sizeof(Tmp),
-                     &Tmp);
-      if (EFI_ERROR (TempStatus)) {
-        return EFI_DEVICE_ERROR;
-      }
-
-      // Physical address of word in NOR to write.
-      WordAddr = (CurOffset & ~(0x3)) +
-                 GET_NOR_BLOCK_ADDRESS (Instance->RegionBaseAddress, Lba,
-                   BlockSize);
-
-      // The word of data that is to be written.
-      TmpBuf = *((UINT32*)(Buffer + (*NumBytes - BytesToWrite)));
-
-      // First do word aligned chunks.
-      if ((CurOffset & 0x3) == 0) {
-        if (BytesToWrite >= 4) {
-          // Is the destination still in 'erased' state?
-          if (~Tmp != 0) {
-            // Check to see if we are only changing bits to zero.
-            if ((Tmp ^ TmpBuf) & TmpBuf) {
-              DoErase = TRUE;
-              break;
-            }
-          }
-          // Write this word to NOR
-          WordToWrite = TmpBuf;
-          CurOffset += sizeof(TmpBuf);
-          BytesToWrite -= sizeof(TmpBuf);
-        } else {
-          // BytesToWrite < 4. Do small writes and left-overs
-          Mask = ~((~0) << (BytesToWrite * 8));
-          // Mask out the bytes we want.
-          TmpBuf &= Mask;
-          // Is the destination still in 'erased' state?
-          if ((Tmp & Mask) != Mask) {
-            // Check to see if we are only changing bits to zero.
-            if ((Tmp ^ TmpBuf) & TmpBuf) {
-              DoErase = TRUE;
-              break;
-            }
-          }
-          // Merge old and new data. Write merged word to NOR
-          WordToWrite = (Tmp & ~Mask) | TmpBuf;
-          CurOffset += BytesToWrite;
-          BytesToWrite = 0;
-        }
-      } else {
-        // Do multiple words, but starting unaligned.
-        if (BytesToWrite > (4 - (CurOffset & 0x3))) {
-          Mask = ((~0) << ((CurOffset & 0x3) * 8));
-          // Mask out the bytes we want.
-          TmpBuf &= Mask;
-          // Is the destination still in 'erased' state?
-          if ((Tmp & Mask) != Mask) {
-            // Check to see if we are only changing bits to zero.
-            if ((Tmp ^ TmpBuf) & TmpBuf) {
-              DoErase = TRUE;
-              break;
-            }
-          }
-          // Merge old and new data. Write merged word to NOR
-          WordToWrite = (Tmp & ~Mask) | TmpBuf;
-          BytesToWrite -= (4 - (CurOffset & 0x3));
-          CurOffset += (4 - (CurOffset & 0x3));
-        } else {
-          // Unaligned and fits in one word.
-          Mask = (~((~0) << (BytesToWrite * 8))) << ((CurOffset & 0x3) * 8);
-          // Mask out the bytes we want.
-          TmpBuf = (TmpBuf << ((CurOffset & 0x3) * 8)) & Mask;
-          // Is the destination still in 'erased' state?
-          if ((Tmp & Mask) != Mask) {
-            // Check to see if we are only changing bits to zero.
-            if ((Tmp ^ TmpBuf) & TmpBuf) {
-              DoErase = TRUE;
-              break;
-            }
-          }
-          // Merge old and new data. Write merged word to NOR
-          WordToWrite = (Tmp & ~Mask) | TmpBuf;
-          CurOffset += BytesToWrite;
-          BytesToWrite = 0;
-        }
-      }
-
-      //
-      // Write the word to NOR.
-      //
-
-      BlockAddress = GET_NOR_BLOCK_ADDRESS (Instance->RegionBaseAddress, Lba,
-        BlockSize);
-      if (BlockAddress != PrevBlockAddress) {
-        TempStatus = NorFlashUnlockSingleBlockIfNecessary (Instance,
-                       BlockAddress);
-        if (EFI_ERROR (TempStatus)) {
-          return EFI_DEVICE_ERROR;
-        }
-        PrevBlockAddress = BlockAddress;
-      }
-      TempStatus = NorFlashWriteSingleWord (Instance, WordAddr, WordToWrite);
-      if (EFI_ERROR (TempStatus)) {
-        return EFI_DEVICE_ERROR;
-      }
-    }
-    // Exit if we got here and could write all the data. Otherwise do the
-    // Erase-Write cycle.
-    if (!DoErase) {
-      return EFI_SUCCESS;
-    }
-  }
-
-  // Check we did get some memory. Buffer is BlockSize.
-  if (Instance->ShadowBuffer == NULL) {
-    DEBUG ((DEBUG_ERROR, "FvbWrite: ERROR - Buffer not ready\n"));
-    return EFI_DEVICE_ERROR;
-  }
-
-  // Read NOR Flash data into shadow buffer
-  TempStatus = NorFlashReadBlocks (Instance, Lba, BlockSize,
-                 Instance->ShadowBuffer);
-  if (EFI_ERROR (TempStatus)) {
-    // Return one of the pre-approved error statuses
-    return EFI_DEVICE_ERROR;
-  }
-
-  // Put the data at the appropriate location inside the buffer area
-  CopyMem ((VOID*)((UINTN)Instance->ShadowBuffer + Offset), Buffer, *NumBytes);
-
-  // Write the modified buffer back to the NorFlash
-  TempStatus = NorFlashWriteBlocks (Instance, Lba, BlockSize,
-                 Instance->ShadowBuffer);
-  if (EFI_ERROR (TempStatus)) {
-    // Return one of the pre-approved error statuses
-    return EFI_DEVICE_ERROR;
-  }
-
-  return EFI_SUCCESS;
-}
-
-STATIC CONST NOR_FLASH_INSTANCE mNorFlashInstanceTemplate = {
-  NOR_FLASH_SIGNATURE, // Signature
-  NULL, // Handle ... NEED TO BE FILLED
-
-  FALSE, // Initialized
-  NULL, // Initialize
-
-  0, // HostRegisterBaseAddress ... NEED TO BE FILLED
-  0, // DeviceBaseAddress ... NEED TO BE FILLED
-  0, // RegionBaseAddress ... NEED TO BE FILLED
-  0, // Size ... NEED TO BE FILLED
-  0, // BlockSize
-  0, // LastBlock
-  0, // StartLba
-  0, // OffsetLba
-
-  {
-    FvbGetAttributes, // GetAttributes
-    FvbSetAttributes, // SetAttributes
-    FvbGetPhysicalAddress,  // GetPhysicalAddress
-    FvbGetBlockSize,  // GetBlockSize
-    FvbRead,  // Read
-    FvbWrite, // Write
-    FvbEraseBlocks, // EraseBlocks
-    NULL, //ParentHandle
-  }, //  FvbProtoccol;
-
-  NULL, // ShadowBuffer
-  {
-    {
-      {
-        HARDWARE_DEVICE_PATH,
-        HW_VENDOR_DP,
-        {
-          (UINT8)(OFFSET_OF (NOR_FLASH_DEVICE_PATH, End)),
-          (UINT8)(OFFSET_OF (NOR_FLASH_DEVICE_PATH, End) >> 8)
-        }
-      },
-      { 0x0, 0x0, 0x0, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } },
-    },
-    0,  // Index
-    {
-      END_DEVICE_PATH_TYPE,
-      END_ENTIRE_DEVICE_PATH_SUBTYPE,
-      { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 }
-    }
-  }, // DevicePath
-
-  NULL, // CmdTable
-  0, // CmdTableSize
-  0 // Flags
-};
-
-STATIC
-EFI_STATUS
-NorFlashCreateInstance (
-  IN UINTN                  HostRegisterBase,
-  IN UINTN                  NorFlashDeviceBase,
-  IN UINTN                  NorFlashRegionBase,
-  IN UINTN                  NorFlashSize,
-  IN UINT32                 Index,
-  IN UINT32                 BlockSize,
-  IN BOOLEAN                HasVarStore,
-  IN CONST CSDC_DEFINITION  *CommandTable,
-  IN UINTN                  CommandTableSize,
-  OUT NOR_FLASH_INSTANCE**  NorFlashInstance
-  )
-{
-  EFI_STATUS Status;
-  NOR_FLASH_INSTANCE* Instance;
-  NOR_FLASH_INFO *FlashInfo;
-  UINT8 JedecId[3];
-
-  ASSERT(NorFlashInstance != NULL);
-
-  Instance = AllocateRuntimeCopyPool (sizeof mNorFlashInstanceTemplate,
-                                      &mNorFlashInstanceTemplate);
-  if (Instance == NULL) {
-    return EFI_OUT_OF_RESOURCES;
-  }
-
-  Instance->HostRegisterBaseAddress = HostRegisterBase;
-  Instance->DeviceBaseAddress       = NorFlashDeviceBase;
-  Instance->RegionBaseAddress       = NorFlashRegionBase;
-  Instance->Size                    = NorFlashSize;
-  Instance->BlockSize               = BlockSize;
-  Instance->LastBlock               = (NorFlashSize / BlockSize) - 1;
-
-  Instance->OffsetLba = (NorFlashRegionBase - NorFlashDeviceBase) / BlockSize;
-
-  CopyGuid (&Instance->DevicePath.Vendor.Guid, &gEfiCallerIdGuid);
-  Instance->DevicePath.Index = (UINT8)Index;
-
-  Instance->CmdTable = CommandTable;
-  Instance->CmdTableSize = CommandTableSize;
-  NorFlashReset (Instance);
-
-  NorFlashReadID (Instance, JedecId);
-  Status = NorFlashGetInfo (JedecId, &FlashInfo, FALSE);
-  if (EFI_ERROR (Status)) {
-    goto FreeInstance;
-  }
-
-  NorFlashPrintInfo (FlashInfo);
-
-  Instance->Flags = 0;
-  if (FlashInfo->Flags & NOR_FLASH_WRITE_FSR) {
-    Instance->Flags = NOR_FLASH_POLL_FSR;
-  }
+  //
+  // Declare the Non-Volatile storage as EFI_MEMORY_RUNTIME
+  //
+  RuntimeMmioRegionSize = Instance->Size;
 
-  Instance->ShadowBuffer = AllocateRuntimePool (BlockSize);;
-  if (Instance->ShadowBuffer == NULL) {
-    Status = EFI_OUT_OF_RESOURCES;
-    goto FreeInstance;
-  }
+  Status = gDS->AddMemorySpace (EfiGcdMemoryTypeMemoryMappedIo,
+                  Instance->RegionBaseAddress, RuntimeMmioRegionSize,
+                  EFI_MEMORY_UC | EFI_MEMORY_RUNTIME);
+  ASSERT_EFI_ERROR (Status);
 
-  if (HasVarStore) {
-    Instance->Initialize = NorFlashFvbInitialize;
-  }
+  Status = gDS->AddMemorySpace (EfiGcdMemoryTypeMemoryMappedIo,
+                  Instance->DeviceBaseAddress, SIZE_4KB,
+                  EFI_MEMORY_UC | EFI_MEMORY_RUNTIME);
+  ASSERT_EFI_ERROR (Status);
 
-  Status = gBS->InstallMultipleProtocolInterfaces (
-                &Instance->Handle,
-                &gEfiDevicePathProtocolGuid, &Instance->DevicePath,
-                &gEfiFirmwareVolumeBlockProtocolGuid, &Instance->FvbProtocol,
-                NULL
-                );
-  if (EFI_ERROR (Status)) {
-    goto FreeInstance;
-  }
+  Status = gDS->SetMemorySpaceAttributes (Instance->RegionBaseAddress,
+                  RuntimeMmioRegionSize, EFI_MEMORY_UC | EFI_MEMORY_RUNTIME);
+  ASSERT_EFI_ERROR (Status);
 
-  *NorFlashInstance = Instance;
-  FreePool (FlashInfo);
-  return EFI_SUCCESS;
+  Status = gDS->SetMemorySpaceAttributes (Instance->DeviceBaseAddress,
+                  SIZE_4KB, EFI_MEMORY_UC | EFI_MEMORY_RUNTIME);
+  ASSERT_EFI_ERROR (Status);
 
-FreeInstance:
-  FreePool (Instance);
   return Status;
 }
 
-EFI_STATUS
-NorFlashReset (
-  IN  NOR_FLASH_INSTANCE *Instance
-  )
-{
-  FIP006_CS_CFG         CsCfg;
-
-  DEBUG ((DEBUG_BLKIO, "NorFlashReset()\n"));
-  CsCfg.Raw = MmioRead32 (Instance->HostRegisterBaseAddress +
-                          FIP006_REG_CS_CFG); 
-  CsCfg.Reg.MBM = CS_CFG_MBM_SINGLE;
-  CsCfg.Reg.SRAM = CS_CFG_SRAM_RW;
-  MmioWrite32 (Instance->HostRegisterBaseAddress + FIP006_REG_CS_CFG,
-               CsCfg.Raw);
-  NorFlashSetHostCommand (Instance, SPINOR_OP_READ_4B);
-  NorFlashSetHostCSDC (Instance, TRUE, mFip006NullCmdSeq);
-  return EFI_SUCCESS;
-}
-
-EFI_STATUS
-NorFlashReadID (
-  IN  NOR_FLASH_INSTANCE  *Instance,
-  OUT UINT8               JedecId[3]
-  )
-{
-  if (Instance == NULL || JedecId == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  NorFlashSetHostCommand (Instance, SPINOR_OP_RDID);
-  JedecId[0] = MmioRead8 (Instance->DeviceBaseAddress);
-  JedecId[1] = MmioRead8 (Instance->DeviceBaseAddress + 1);
-  JedecId[2] = MmioRead8 (Instance->DeviceBaseAddress + 2);
-  NorFlashSetHostCommand (Instance, SPINOR_OP_READ_4B);
-  return EFI_SUCCESS;
-}
-
 /**
   Fixup internal data so that EFI can be call in virtual mode.
   Call the passed in Child Notify event and convert any pointers in
@@ -1078,6 +173,8 @@ NorFlashVirtualNotifyEvent (
 {
   UINTN Index;
 
+  EfiConvertPointer (0x0, (VOID**)&mFlashNvStorageVariableBase);
+
   for (Index = 0; Index < mNorFlashDeviceCount; Index++) {
     EfiConvertPointer (0x0,
       (VOID**)&mNorFlashInstances[Index]->HostRegisterBaseAddress);
@@ -1105,8 +202,6 @@ NorFlashVirtualNotifyEvent (
     if (mNorFlashInstances[Index]->ShadowBuffer != NULL) {
       EfiConvertPointer (0x0, (VOID**)&mNorFlashInstances[Index]->ShadowBuffer);
     }
-
-    EfiConvertPointer (0x0, (VOID**)&mNorFlashInstances[Index]->CmdTable);
   }
 
   return;
@@ -1174,17 +269,24 @@ NorFlashInitialise (
       Index,
       NorFlashDevices[Index].BlockSize,
       ContainVariableStorage,
-      mN25qCSDCDefTable,
-      ARRAY_SIZE (mN25qCSDCDefTable),
       &mNorFlashInstances[Index]
     );
     if (EFI_ERROR (Status)) {
       DEBUG ((DEBUG_ERROR,
         "NorFlashInitialise: Fail to create instance for NorFlash[%d]\n",
         Index));
+      continue;
     }
+    Status = gBS->InstallMultipleProtocolInterfaces (
+                    &mNorFlashInstances[Index]->Handle,
+                    &gEfiDevicePathProtocolGuid, &mNorFlashInstances[Index]->DevicePath,
+                    &gEfiFirmwareVolumeBlockProtocolGuid, &mNorFlashInstances[Index]->FvbProtocol,
+                    NULL
+                    );
+    ASSERT_EFI_ERROR (Status);
   }
 
+
   //
   // Register for the virtual address change event
   //
@@ -1196,3 +298,31 @@ NorFlashInitialise (
 
   return Status;
 }
+
+VOID
+EFIAPI
+NorFlashLock (
+  NOR_FLASH_LOCK_CONTEXT    *Context
+  )
+{
+  if (!EfiAtRuntime ()) {
+    // Raise TPL to TPL_HIGH to stop anyone from interrupting us.
+    Context->OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
+  } else {
+    Context->InterruptsEnabled = SaveAndDisableInterrupts ();
+  }
+}
+
+VOID
+EFIAPI
+NorFlashUnlock (
+  NOR_FLASH_LOCK_CONTEXT    *Context
+  )
+{
+  if (!EfiAtRuntime ()) {
+    // Interruptions can resume.
+    gBS->RestoreTPL (Context->OriginalTPL);
+  } else if (Context->InterruptsEnabled) {
+    SetInterruptState (TRUE);
+  }
+}
diff --git a/Silicon/Socionext/SynQuacer/Drivers/Fip006Dxe/NorFlashFvbDxe.c b/Silicon/Socionext/SynQuacer/Drivers/Fip006Dxe/NorFlashFvb.c
similarity index 80%
rename from Silicon/Socionext/SynQuacer/Drivers/Fip006Dxe/NorFlashFvbDxe.c
rename to Silicon/Socionext/SynQuacer/Drivers/Fip006Dxe/NorFlashFvb.c
index 776ec8a5437c..30b7442d8947 100644
--- a/Silicon/Socionext/SynQuacer/Drivers/Fip006Dxe/NorFlashFvbDxe.c
+++ b/Silicon/Socionext/SynQuacer/Drivers/Fip006Dxe/NorFlashFvb.c
@@ -21,16 +21,14 @@
 
 #include <Library/BaseLib.h>
 #include <Library/BaseMemoryLib.h>
-#include <Library/HobLib.h>
 #include <Library/MemoryAllocationLib.h>
 #include <Library/PcdLib.h>
 #include <Library/UefiBootServicesTableLib.h>
 #include <Library/UefiLib.h>
 
-#include "NorFlashDxe.h"
+#include "NorFlash.h"
 
-STATIC EFI_EVENT mFvbVirtualAddrChangeEvent;
-STATIC UINTN     mFlashNvStorageVariableBase;
+UINTN     mFlashNvStorageVariableBase;
 
 ///
 /// The Firmware Volume Block Protocol is the low-level interface
@@ -49,7 +47,6 @@ STATIC UINTN     mFlashNvStorageVariableBase;
   @param[in]  Ptr - Location to initialise the headers
 
 **/
-STATIC
 EFI_STATUS
 InitializeFvAndVariableStoreHeaders (
   IN NOR_FLASH_INSTANCE *Instance
@@ -700,157 +697,3 @@ FvbEraseBlocks (
 EXIT:
   return Status;
 }
-
-/**
-  Fixup internal data so that EFI can be call in virtual mode.
-  Call the passed in Child Notify event and convert any pointers in
-  lib to virtual mode.
-
-  @param[in]    Event   The Event that is being processed
-  @param[in]    Context Event Context
-**/
-STATIC
-VOID
-EFIAPI
-FvbVirtualNotifyEvent (
-  IN EFI_EVENT        Event,
-  IN VOID             *Context
-  )
-{
-  EfiConvertPointer (0x0, (VOID**)&mFlashNvStorageVariableBase);
-  return;
-}
-
-EFI_STATUS
-EFIAPI
-NorFlashFvbInitialize (
-  IN NOR_FLASH_INSTANCE* Instance
-  )
-{
-  EFI_STATUS      Status;
-  UINT32          FvbNumLba;
-  EFI_BOOT_MODE   BootMode;
-  UINTN           RuntimeMmioRegionSize;
-  UINTN           BlockSize;
-
-  DEBUG ((DEBUG_BLKIO,"NorFlashFvbInitialize\n"));
-
-  BlockSize = Instance->BlockSize;
-
-  // FirmwareVolumeHeader->FvLength is declared to have the Variable area
-  // AND the FTW working area AND the FTW Spare contiguous.
-  ASSERT(PcdGet32(PcdFlashNvStorageVariableBase) +
-         PcdGet32(PcdFlashNvStorageVariableSize) ==
-         PcdGet32(PcdFlashNvStorageFtwWorkingBase));
-  ASSERT(PcdGet32(PcdFlashNvStorageFtwWorkingBase) +
-         PcdGet32(PcdFlashNvStorageFtwWorkingSize) ==
-         PcdGet32(PcdFlashNvStorageFtwSpareBase));
-
-  // Check if the size of the area is at least one block size
-  ASSERT((PcdGet32(PcdFlashNvStorageVariableSize) > 0) &&
-         (PcdGet32(PcdFlashNvStorageVariableSize) / BlockSize > 0));
-  ASSERT((PcdGet32(PcdFlashNvStorageFtwWorkingSize) > 0) &&
-         (PcdGet32(PcdFlashNvStorageFtwWorkingSize) / BlockSize > 0));
-  ASSERT((PcdGet32(PcdFlashNvStorageFtwSpareSize) > 0) &&
-         (PcdGet32(PcdFlashNvStorageFtwSpareSize) / BlockSize > 0));
-
-  // Ensure the Variable areas are aligned on block size boundaries
-  ASSERT((PcdGet32(PcdFlashNvStorageVariableBase) % BlockSize) == 0);
-  ASSERT((PcdGet32(PcdFlashNvStorageFtwWorkingBase) % BlockSize) == 0);
-  ASSERT((PcdGet32(PcdFlashNvStorageFtwSpareBase) % BlockSize) == 0);
-
-
-  Instance->Initialized = TRUE;
-  mFlashNvStorageVariableBase = FixedPcdGet32 (PcdFlashNvStorageVariableBase);
-
-  // Set the index of the first LBA for the FVB
-  Instance->StartLba = (PcdGet32 (PcdFlashNvStorageVariableBase) -
-                        Instance->RegionBaseAddress) / BlockSize;
-
-  BootMode = GetBootModeHob ();
-  if (BootMode == BOOT_WITH_DEFAULT_SETTINGS) {
-    Status = EFI_INVALID_PARAMETER;
-  } else {
-    // Determine if there is a valid header at the beginning of the NorFlash
-    Status = ValidateFvHeader (Instance);
-  }
-
-  // Install the Default FVB header if required
-  if (EFI_ERROR(Status)) {
-    // There is no valid header, so time to install one.
-    DEBUG ((DEBUG_INFO, "%a: The FVB Header is not valid.\n", __FUNCTION__));
-    DEBUG ((DEBUG_INFO, "%a: Installing a correct one for this volume.\n",
-      __FUNCTION__));
-
-    // Erase all the NorFlash that is reserved for variable storage
-    FvbNumLba = (PcdGet32(PcdFlashNvStorageVariableSize) +
-                 PcdGet32(PcdFlashNvStorageFtwWorkingSize) +
-                 PcdGet32(PcdFlashNvStorageFtwSpareSize)) /
-                Instance->BlockSize;
-
-    Status = FvbEraseBlocks (&Instance->FvbProtocol, (EFI_LBA)0, FvbNumLba,
-               EFI_LBA_LIST_TERMINATOR);
-    if (EFI_ERROR(Status)) {
-      return Status;
-    }
-
-    // Install all appropriate headers
-    Status = InitializeFvAndVariableStoreHeaders (Instance);
-    if (EFI_ERROR(Status)) {
-      return Status;
-    }
-  }
-
-  //
-  // The driver implementing the variable read service can now be dispatched;
-  // the varstore headers are in place.
-  //
-  Status = gBS->InstallProtocolInterface (&gImageHandle,
-                  &gEdkiiNvVarStoreFormattedGuid,
-                  EFI_NATIVE_INTERFACE,
-                  NULL);
-  if (EFI_ERROR (Status)) {
-    DEBUG ((DEBUG_ERROR,
-      "%a: Failed to install gEdkiiNvVarStoreFormattedGuid\n",
-      __FUNCTION__));
-      return Status;
-  }
-
-  //
-  // Declare the Non-Volatile storage as EFI_MEMORY_RUNTIME
-  //
-  RuntimeMmioRegionSize = Instance->Size;
-
-  Status = gDS->AddMemorySpace (EfiGcdMemoryTypeMemoryMappedIo,
-                  Instance->RegionBaseAddress, RuntimeMmioRegionSize,
-                  EFI_MEMORY_UC | EFI_MEMORY_RUNTIME);
-  ASSERT_EFI_ERROR (Status);
-
-  Status = gDS->AddMemorySpace (EfiGcdMemoryTypeMemoryMappedIo,
-                  Instance->DeviceBaseAddress, SIZE_4KB,
-                  EFI_MEMORY_UC | EFI_MEMORY_RUNTIME);
-  ASSERT_EFI_ERROR (Status);
-
-  Status = gDS->SetMemorySpaceAttributes (Instance->RegionBaseAddress,
-                  RuntimeMmioRegionSize, EFI_MEMORY_UC | EFI_MEMORY_RUNTIME);
-  ASSERT_EFI_ERROR (Status);
-
-  Status = gDS->SetMemorySpaceAttributes (Instance->DeviceBaseAddress,
-                  SIZE_4KB, EFI_MEMORY_UC | EFI_MEMORY_RUNTIME);
-  ASSERT_EFI_ERROR (Status);
-
-  //
-  // Register for the virtual address change event
-  //
-  Status = gBS->CreateEventEx (
-                  EVT_NOTIFY_SIGNAL,
-                  TPL_NOTIFY,
-                  FvbVirtualNotifyEvent,
-                  NULL,
-                  &gEfiEventVirtualAddressChangeGuid,
-                  &mFvbVirtualAddrChangeEvent
-                  );
-  ASSERT_EFI_ERROR (Status);
-
-  return Status;
-}
