/** @file

Copyright (c) 2007  - 2015, Intel Corporation. All rights reserved.<BR>
                                                                                   
  This program and the accompanying materials are licensed and made available under
  the terms and conditions of the BSD License that 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 "FirmwareUpdate.h"

EFI_HII_HANDLE  HiiHandle;

//
// MinnowMax Flash Layout
//
//Start (hex)	End (hex)	Length (hex)	Area Name
//-----------	---------	------------	---------
//00000000	007FFFFF	00800000	Flash Image
//
//00000000	00000FFF	00001000	Descriptor Region
//00001000	003FFFFF	003FF000	TXE Region
//00500000	007FFFFF	00400000	BIOS Region
//
FV_REGION_INFO mRegionInfo[] = {
  {FixedPcdGet32 (PcdFlashDescriptorBase), FixedPcdGet32 (PcdFlashDescriptorSize), TRUE},
  {FixedPcdGet32 (PcdTxeRomBase), FixedPcdGet32 (PcdTxeRomSize), TRUE},
  {FixedPcdGet32 (PcdBiosRomBase), FixedPcdGet32 (PcdBiosRomSize), TRUE}
};

UINTN mRegionInfoCount = sizeof (mRegionInfo) / sizeof (mRegionInfo[0]);

FV_INPUT_DATA mInputData = {0};

EFI_SPI_PROTOCOL  *mSpiProtocol;

EFI_STATUS
GetRegionIndex (
  IN  EFI_PHYSICAL_ADDRESS  Address,
  OUT UINTN                 *RegionIndex
  )
{
  UINTN Index;

  for (Index = 0; Index < mRegionInfoCount; Index++) {
    if (Address >= mRegionInfo[Index].Base &&
        Address < (mRegionInfo[Index].Base + mRegionInfo[Index].Size)
        ) {
      break;
    }
  }

  *RegionIndex = Index;
  if (Index >= mRegionInfoCount) {
    return EFI_NOT_FOUND;
  }
  return EFI_SUCCESS;
}

BOOLEAN
UpdateBlock (
  IN  EFI_PHYSICAL_ADDRESS  Address
  )
{
  EFI_STATUS  Status;
  UINTN       Index;

  if (mInputData.FullFlashUpdate) {
    return TRUE;
  }

  Status = GetRegionIndex (Address, &Index);
  if ((!EFI_ERROR(Status)) && mRegionInfo[Index].Update) {
    return TRUE;
  }

  return FALSE;
}

EFI_STATUS
MarkRegionState (
  IN  EFI_PHYSICAL_ADDRESS  Address,
  IN  BOOLEAN               Update
  )
{
  EFI_STATUS  Status;
  UINTN       Index;

  Status = GetRegionIndex (Address, &Index);
  if (!EFI_ERROR(Status)) {
    mRegionInfo[Index].Update = Update;
  }

  return Status;
}

UINTN
InternalPrintToken (
  IN  CONST CHAR16                     *Format,
  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *Console,
  IN  VA_LIST                          Marker
  )
{
  EFI_STATUS  Status;
  UINTN       Return;
  CHAR16      *Buffer;
  UINTN       BufferSize;

  ASSERT (Format != NULL);
  ASSERT (((UINTN) Format & BIT0) == 0);
  ASSERT (Console != NULL);

  BufferSize = (PcdGet32 (PcdUefiLibMaxPrintBufferSize) + 1) * sizeof (CHAR16);

  Buffer = (CHAR16 *) AllocatePool(BufferSize);
  ASSERT (Buffer != NULL);

  Return = UnicodeVSPrint (Buffer, BufferSize, Format, Marker);

  if (Console != NULL && Return > 0) {
    //
    // To be extra safe make sure Console has been initialized.
    //
    Status = Console->OutputString (Console, Buffer);
    if (EFI_ERROR (Status)) {
      Return = 0;
    }
  }

  FreePool (Buffer);

  return Return;
}

UINTN
EFIAPI
PrintToken (
  IN UINT16             Token,
  IN EFI_HII_HANDLE     Handle,
  ...
  )
{
  VA_LIST Marker;
  UINTN   Return;
  CHAR16  *Format;

  VA_START (Marker, Handle);

  Format = HiiGetString (Handle, Token, NULL);
  ASSERT (Format != NULL);

  Return = InternalPrintToken (Format, gST->ConOut, Marker);

  FreePool (Format);

  VA_END (Marker);

  return Return;
}

EFI_STATUS
ParseCommandLine (
  IN  UINTN   Argc,
  IN  CHAR16  **Argv
  )
{
  EFI_STATUS  Status;
  UINTN       Index;

  //
  // Check to make sure that the command line has enough arguments for minimal
  // operation.  The minimum is just the file name.
  //
  if (Argc < 2 || Argc > 4) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Loop through command line arguments.
  //
  for (Index = 1; Index < Argc; Index++) {
    //
    // Make sure the string is valid.
    //
    if (StrLen (Argv[Index]) == 0) {;
      PrintToken (STRING_TOKEN (STR_FWUPDATE_ZEROLENGTH_ARG), HiiHandle);
      return EFI_INVALID_PARAMETER;
    }

    //
    // Check to see if this is an option or the file name.
    //
    if ((Argv[Index])[0] == L'-' || (Argv[Index])[0] == L'/') {
      //
      // Parse the arguments.
      //
      if ((StrCmp (Argv[Index], L"-h") == 0) ||
          (StrCmp (Argv[Index], L"--help") == 0) ||
          (StrCmp (Argv[Index], L"/?") == 0) ||
          (StrCmp (Argv[Index], L"/h") == 0)) {
        //
        // Print Help Information.
        //
        return EFI_INVALID_PARAMETER;
      } else if (StrCmp (Argv[Index], L"-m") == 0) {
        //
        // Parse the MAC address here.
        //
        Status = ConvertMac(Argv[Index+1]);
        if (EFI_ERROR(Status)) {
          PrintToken (STRING_TOKEN (STR_FWUPDATE_INVAILD_MAC), HiiHandle);
          return Status;
        }

        //
        // Save the MAC address to mInputData.MacValue.
        //
        mInputData.UpdateMac= TRUE;
        Index++;
        } else {
        //
        // Invalid option was provided.
        //
        return EFI_INVALID_PARAMETER;
      }
    }
    if ((Index == Argc - 1) && (StrCmp (Argv[Index - 1], L"-m") != 0)) {
      //
      // The only parameter that is not an option is the firmware image.  Check
      // to make sure that the file exists.
      //
      Status = ShellIsFile (Argv[Index]);
      if (EFI_ERROR (Status)) {
        PrintToken (STRING_TOKEN (STR_FWUPDATE_FILE_NOT_FOUND_ERROR), HiiHandle, Argv[Index]);
        return EFI_INVALID_PARAMETER;
      }
      if (StrLen (Argv[Index]) > INPUT_STRING_LEN) {
        PrintToken (STRING_TOKEN (STR_FWUPDATE_PATH_ERROR), HiiHandle, Argv[Index]);
        return EFI_INVALID_PARAMETER;
      }
      StrCpy (mInputData.FileName, Argv[Index]);
      mInputData.UpdateFromFile = TRUE;
    }
  }

  return EFI_SUCCESS;
}

INTN
EFIAPI
ShellAppMain (
  IN UINTN Argc,
  IN CHAR16 **Argv
  )
{
  EFI_STATUS            Status;
  UINTN                 Index;
  UINT32                FileSize;
  UINT32                BufferSize;
  UINT8                 *FileBuffer;
  UINT8                 *Buffer;
  EFI_PHYSICAL_ADDRESS  Address;
  UINTN                 CountOfBlocks;
  EFI_TPL               OldTpl;
  BOOLEAN               ResetRequired;
  BOOLEAN               FlashError;

  Index             = 0;
  FileSize          = 0;
  BufferSize        = 0;
  FileBuffer        = NULL;
  Buffer            = NULL;
  Address           = 0;
  CountOfBlocks     = 0;
  ResetRequired     = FALSE;
  FlashError        = FALSE;

  Status = EFI_SUCCESS;

  mInputData.FullFlashUpdate = TRUE;

  //
  // Publish our HII data.
  //
  HiiHandle = HiiAddPackages (
                &gEfiCallerIdGuid,
                NULL,
                FirmwareUpdateStrings,
                NULL
                );
  if (HiiHandle == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Done;
  }

  //
  // Locate the SPI protocol.
  //
  Status = gBS->LocateProtocol (
                  &gEfiSpiProtocolGuid,
                  NULL,
                  (VOID **)&mSpiProtocol
                  );
  if (EFI_ERROR (Status)) {
    PrintToken (STRING_TOKEN (STR_SPI_NOT_FOUND), HiiHandle);
    return EFI_DEVICE_ERROR;
  }

  //
  // Parse the command line.
  //
  Status = ParseCommandLine (Argc, Argv);
  if (EFI_ERROR (Status)) {
    PrintHelpInfo ();
    Status = EFI_SUCCESS;
    goto Done;
  }

  //
  // Display sign-on information.
  //
  PrintToken (STRING_TOKEN (STR_FWUPDATE_FIRMWARE_VOL_UPDATE), HiiHandle);
  PrintToken (STRING_TOKEN (STR_FWUPDATE_VERSION), HiiHandle);
  PrintToken (STRING_TOKEN (STR_FWUPDATE_COPYRIGHT), HiiHandle);

  //
  // Test to see if the firmware needs to be updated.
  //
  if (mInputData.UpdateFromFile) {
    //
    // Get the file to use in the update.
    //
    PrintToken (STRING_TOKEN (STR_FWUPDATE_READ_FILE), HiiHandle, mInputData.FileName);
    Status = ReadFileData (mInputData.FileName, &FileBuffer, &FileSize);
    if (EFI_ERROR (Status)) {
      PrintToken (STRING_TOKEN (STR_FWUPDATE_READ_FILE_ERROR), HiiHandle, mInputData.FileName);
      goto Done;
    }

    //
    // Check that the file and flash sizes match.
    //
    if (FileSize != PcdGet32 (PcdFlashChipSize)) {
      PrintToken (STRING_TOKEN (STR_FWUPDATE_SIZE), HiiHandle);
      Status = EFI_UNSUPPORTED;
      goto Done;
    }

    //
    // Display flash update information.
    //
    PrintToken (STRING_TOKEN (STR_FWUPDATE_UPDATING_FIRMWARE), HiiHandle);

    //
    // Update it.
    //
    Buffer        = FileBuffer;
    BufferSize    = FileSize;
    Address       = PcdGet32 (PcdFlashChipBase);
    CountOfBlocks = (UINTN) (BufferSize / BLOCK_SIZE);

    //
    // Raise TPL to TPL_NOTIFY to block any event handler,
    // while still allowing RaiseTPL(TPL_NOTIFY) within
    // output driver during Print().
    //
    OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
    for (Index = 0; Index < CountOfBlocks; Index++) {
      //
      // Handle block based on address and contents.
      //
      if (!UpdateBlock (Address)) {
        DEBUG((EFI_D_INFO, "Skipping block at 0x%lx\n", Address));
      } else if (!EFI_ERROR (InternalCompareBlock (Address, Buffer))) {
        DEBUG((EFI_D_INFO, "Skipping block at 0x%lx (already programmed)\n", Address));
      } else {
        //
        // Display a dot for each block being updated.
        //
        Print (L".");

        //
        // Flag that the flash image will be changed and the system must be rebooted
        // to use the change.
        //
        ResetRequired = TRUE;

        //
        // Make updating process uninterruptable,
        // so that the flash memory area is not accessed by other entities
        // which may interfere with the updating process.
        //
        Status  = InternalEraseBlock (Address);
        ASSERT_EFI_ERROR(Status);
        if (EFI_ERROR (Status)) {
          gBS->RestoreTPL (OldTpl);
          FlashError = TRUE;
          goto Done;
        }
        Status = InternalWriteBlock (
                  Address,
                  Buffer,
                  (BufferSize > BLOCK_SIZE ? BLOCK_SIZE : BufferSize)
                  );
        if (EFI_ERROR (Status)) {
          gBS->RestoreTPL (OldTpl);
          FlashError = TRUE;
          goto Done;
        }
      }

      //
      // Move to next block to update.
      //
      Address += BLOCK_SIZE;
      Buffer += BLOCK_SIZE;
      if (BufferSize > BLOCK_SIZE) {
        BufferSize -= BLOCK_SIZE;
      } else {
        BufferSize = 0;
      }
    }
    gBS->RestoreTPL (OldTpl);

    //
    // Print result of update.
    //
    if (!FlashError) {
      if (ResetRequired) {
        Print (L"\n");
        PrintToken (STRING_TOKEN (STR_FWUPDATE_UPDATE_SUCCESS), HiiHandle);
      } else {
        PrintToken (STRING_TOKEN (STR_FWUPDATE_NO_RESET), HiiHandle);
      }
    } else {
      goto Done;
    }
  }

  //
  // All flash updates are done so see if the system needs to be reset.
  //
  if (ResetRequired && !FlashError) {
    //
    // Update successful.
    //
    for (Index = 5; Index > 0; Index--) {
      PrintToken (STRING_TOKEN (STR_FWUPDATE_SHUTDOWN), HiiHandle, Index);
      gBS->Stall (1000000);
    }

    gRT->ResetSystem (EfiResetShutdown, EFI_SUCCESS, 0, NULL);
    PrintToken (STRING_TOKEN (STR_FWUPDATE_MANUAL_RESET), HiiHandle);
    CpuDeadLoop ();
  }

Done:
  //
  // Print flash update failure message if error detected.
  //
  if (FlashError) {
    PrintToken (STRING_TOKEN (STR_FWUPDATE_UPDATE_FAILED), HiiHandle, Index);
  }

  //
  // Do cleanup.
  //
  if (HiiHandle != NULL) {
    HiiRemovePackages (HiiHandle);
  }
  if (FileBuffer) {
    gBS->FreePool (FileBuffer);
  }

  return Status;
}

STATIC
EFI_STATUS
InternalEraseBlock (
  IN  EFI_PHYSICAL_ADDRESS BaseAddress
  )
/*++

Routine Description:

  Erase the whole block.

Arguments:

  BaseAddress  - Base address of the block to be erased.

Returns:

  EFI_SUCCESS - The command completed successfully.
  Other       - Device error or wirte-locked, operation failed.

--*/
{
  EFI_STATUS                              Status;
  UINTN                                   NumBytes;

  NumBytes = BLOCK_SIZE;

  Status = SpiFlashBlockErase ((UINTN) BaseAddress, &NumBytes);

  return Status;
}

#if 0
STATIC
EFI_STATUS
InternalReadBlock (
  IN  EFI_PHYSICAL_ADDRESS  BaseAddress,
  OUT VOID                  *ReadBuffer
  )
{
  EFI_STATUS    Status;
  UINT32        BlockSize;

  BlockSize = BLOCK_SIZE;

  Status = SpiFlashRead ((UINTN) BaseAddress, &BlockSize, ReadBuffer);

  return Status;
}
#endif

STATIC
EFI_STATUS
InternalCompareBlock (
  IN  EFI_PHYSICAL_ADDRESS        BaseAddress,
  IN  UINT8                       *Buffer
  )
{
  EFI_STATUS                              Status;
  VOID                                    *CompareBuffer;
  UINT32                                  NumBytes;
  INTN                                    CompareResult;

  NumBytes = BLOCK_SIZE;
  CompareBuffer = AllocatePool (NumBytes);
  if (CompareBuffer == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Done;
  }

  Status = SpiFlashRead ((UINTN) BaseAddress, &NumBytes, CompareBuffer);
  if (EFI_ERROR (Status)) {
    goto Done;
  }
  CompareResult = CompareMem (CompareBuffer, Buffer, BLOCK_SIZE);
  if (CompareResult != 0) {
    Status = EFI_VOLUME_CORRUPTED;
  }

Done:
  if (CompareBuffer != NULL) {
    FreePool (CompareBuffer);
  }

  return Status;
}

STATIC
EFI_STATUS
InternalWriteBlock (
  IN  EFI_PHYSICAL_ADDRESS        BaseAddress,
  IN  UINT8                       *Buffer,
  IN  UINT32                      BufferSize
  )
/*++

Routine Description:

  Write a block of data.

Arguments:

  BaseAddress  - Base address of the block.
  Buffer       - Data buffer.
  BufferSize   - Size of the buffer.

Returns:

  EFI_SUCCESS           - The command completed successfully.
  EFI_INVALID_PARAMETER - Invalid parameter, can not proceed.
  Other                 - Device error or wirte-locked, operation failed.

--*/
{
  EFI_STATUS                              Status;

  Status = SpiFlashWrite ((UINTN) BaseAddress, &BufferSize, Buffer);
  ASSERT_EFI_ERROR(Status);
  if (EFI_ERROR (Status)) {
    DEBUG((EFI_D_ERROR, "\nFlash write error."));
    return Status;
  }

  WriteBackInvalidateDataCacheRange ((VOID *) (UINTN) BaseAddress, BLOCK_SIZE);

  Status = InternalCompareBlock (BaseAddress, Buffer);
  if (EFI_ERROR (Status)) {
    DEBUG((EFI_D_ERROR, "\nError when writing to BaseAddress %lx with different at offset %x.", BaseAddress, Status));
  } else {
    DEBUG((EFI_D_INFO, "\nVerified data written to Block at %lx is correct.", BaseAddress));
  }

  return Status;

}

STATIC
EFI_STATUS
ReadFileData (
  IN  CHAR16   *FileName,
  OUT UINT8    **Buffer,
  OUT UINT32   *BufferSize
  )
{
  EFI_STATUS             Status;
  SHELL_FILE_HANDLE      FileHandle;
  UINT64                 Size;
  VOID                   *NewBuffer;
  UINTN                  ReadSize;

  FileHandle = NULL;
  NewBuffer = NULL;
  Size = 0;

  Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ, 0);
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  Status = FileHandleIsDirectory (FileHandle);
  if (!EFI_ERROR (Status)) {
    Status = EFI_NOT_FOUND;
    goto Done;
  }

  Status = FileHandleGetSize (FileHandle, &Size);
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  NewBuffer = AllocatePool ((UINTN) Size);

  ReadSize = (UINTN) Size;
  Status = FileHandleRead (FileHandle, &ReadSize, NewBuffer);
  if (EFI_ERROR (Status)) {
    goto Done;
  } else if (ReadSize != (UINTN) Size) {
    Status = EFI_INVALID_PARAMETER;
    goto Done;
  }

Done:
  if (FileHandle != NULL) {
    ShellCloseFile (&FileHandle);
  }

  if (EFI_ERROR (Status)) {
    if (NewBuffer != NULL) {
      FreePool (NewBuffer);
    }
  } else {
    *Buffer = NewBuffer;
    *BufferSize = (UINT32) Size;
  }

  return Status;
}

STATIC
VOID
PrintHelpInfo (
  VOID
  )
/*++

Routine Description:

  Print out help information.

Arguments:

  None.

Returns:

  None.

--*/
{
  PrintToken (STRING_TOKEN (STR_FWUPDATE_FIRMWARE_VOL_UPDATE), HiiHandle);
  PrintToken (STRING_TOKEN (STR_FWUPDATE_VERSION), HiiHandle);
  PrintToken (STRING_TOKEN (STR_FWUPDATE_COPYRIGHT), HiiHandle);

  Print (L"\n");
  PrintToken (STRING_TOKEN (STR_FWUPDATE_USAGE), HiiHandle);
  PrintToken (STRING_TOKEN (STR_FWUPDATE_USAGE_1), HiiHandle);
  PrintToken (STRING_TOKEN (STR_FWUPDATE_USAGE_2), HiiHandle);
  PrintToken (STRING_TOKEN (STR_FWUPDATE_USAGE_3), HiiHandle);
  PrintToken (STRING_TOKEN (STR_FWUPDATE_USAGE_4), HiiHandle);

  Print (L"\n");
}

/**
  Read NumBytes bytes of data from the address specified by
  PAddress into Buffer.

  @param[in]      Address       The starting physical address of the read.
  @param[in,out]  NumBytes      On input, the number of bytes to read. On output, the number
                                of bytes actually read.
  @param[out]     Buffer        The destination data buffer for the read.

  @retval         EFI_SUCCESS       Opertion is successful.
  @retval         EFI_DEVICE_ERROR  If there is any device errors.

**/
EFI_STATUS
EFIAPI
SpiFlashRead (
  IN     UINTN     Address,
  IN OUT UINT32    *NumBytes,
     OUT UINT8     *Buffer
  )
{
  EFI_STATUS    Status = EFI_SUCCESS;
  UINTN         Offset = 0;

  ASSERT ((NumBytes != NULL) && (Buffer != NULL));

    Offset = Address - (UINTN)PcdGet32 (PcdFlashChipBase);

    Status = mSpiProtocol->Execute (
                             mSpiProtocol,
                             1, //SPI_READ,
                             0, //SPI_WREN,
                             TRUE,
                             TRUE,
                             FALSE,
                             Offset,
                             BLOCK_SIZE,
                             Buffer,
                             EnumSpiRegionAll
                             );
    return Status;

}

/**
  Write NumBytes bytes of data from Buffer to the address specified by
  PAddresss.

  @param[in]      Address         The starting physical address of the write.
  @param[in,out]  NumBytes        On input, the number of bytes to write. On output,
                                  the actual number of bytes written.
  @param[in]      Buffer          The source data buffer for the write.

  @retval         EFI_SUCCESS       Opertion is successful.
  @retval         EFI_DEVICE_ERROR  If there is any device errors.

**/
EFI_STATUS
EFIAPI
SpiFlashWrite (
  IN     UINTN     Address,
  IN OUT UINT32    *NumBytes,
  IN     UINT8     *Buffer
  )
{
  EFI_STATUS                Status;
  UINTN                     Offset;
  UINT32                    Length;
  UINT32                    RemainingBytes;

  ASSERT ((NumBytes != NULL) && (Buffer != NULL));
  ASSERT (Address >= (UINTN)PcdGet32 (PcdFlashChipBase));

  Offset    = Address - (UINTN)PcdGet32 (PcdFlashChipBase);

  ASSERT ((*NumBytes + Offset) <= (UINTN)PcdGet32 (PcdFlashChipSize));

  Status = EFI_SUCCESS;
  RemainingBytes = *NumBytes;

  while (RemainingBytes > 0) {
    if (RemainingBytes > SIZE_4KB) {
      Length = SIZE_4KB;
    } else {
      Length = RemainingBytes;
    }
    Status = mSpiProtocol->Execute (
                             mSpiProtocol,
                             SPI_PROG,
                             SPI_WREN,
                             TRUE,
                             TRUE,
                             TRUE,
                             (UINT32) Offset,
                             Length,
                             Buffer,
                             EnumSpiRegionAll
                             );
    if (EFI_ERROR (Status)) {
      break;
    }
    RemainingBytes -= Length;
    Offset += Length;
    Buffer += Length;
  }

  //
  // Actual number of bytes written.
  //
  *NumBytes -= RemainingBytes;

  return Status;
}

/**
  Erase the block starting at Address.

  @param[in]  Address         The starting physical address of the block to be erased.
                              This library assume that caller garantee that the PAddress
                              is at the starting address of this block.
  @param[in]  NumBytes        On input, the number of bytes of the logical block to be erased.
                              On output, the actual number of bytes erased.

  @retval     EFI_SUCCESS.      Opertion is successful.
  @retval     EFI_DEVICE_ERROR  If there is any device errors.

**/
EFI_STATUS
EFIAPI
SpiFlashBlockErase (
  IN UINTN    Address,
  IN UINTN    *NumBytes
  )
{
  EFI_STATUS          Status;
  UINTN               Offset;
  UINTN               RemainingBytes;

  ASSERT (NumBytes != NULL);
  ASSERT (Address >= (UINTN)PcdGet32 (PcdFlashChipBase));

  Offset    = Address - (UINTN)PcdGet32 (PcdFlashChipBase);

  ASSERT ((*NumBytes % SIZE_4KB) == 0);
  ASSERT ((*NumBytes + Offset) <= (UINTN)PcdGet32 (PcdFlashChipSize));

  Status = EFI_SUCCESS;
  RemainingBytes = *NumBytes;

    while (RemainingBytes > 0) {
      Status = mSpiProtocol->Execute (
                               mSpiProtocol,
                               SPI_SERASE,
                               SPI_WREN,
                               FALSE,
                               TRUE,
                               FALSE,
                               (UINT32) Offset,
                               0,
                               NULL,
                               EnumSpiRegionAll
                               );
      if (EFI_ERROR (Status)) {
        break;
      }
      RemainingBytes -= SIZE_4KB;
      Offset         += SIZE_4KB;
    }

  //
  // Actual number of bytes erased.
  //
  *NumBytes -= RemainingBytes;

  return Status;
}

EFI_STATUS
EFIAPI
ConvertMac (
  CHAR16 *Str
  )
{
  UINTN Index;
  UINT8 Temp[MAC_ADD_STR_LEN];

  if (Str == NULL)
    return EFI_INVALID_PARAMETER;

  if (StrLen(Str) != MAC_ADD_STR_LEN)
    return EFI_INVALID_PARAMETER;

  for (Index = 0; Index < MAC_ADD_STR_LEN; Index++) {
    if (Str[Index] >= 0x30 && Str[Index] <= 0x39) {
      Temp[Index] = (UINT8)Str[Index] - 0x30;
    } else if (Str[Index] >= 0x41 && Str[Index] <= 0x46) {
      Temp[Index] = (UINT8)Str[Index] - 0x37;
    } else if (Str[Index] >= 0x61 && Str[Index] <= 0x66) {
      Temp[Index] = (UINT8)Str[Index] - 0x57;
    } else {
      return EFI_INVALID_PARAMETER;
    }
  }

  for (Index = 0; Index < MAC_ADD_BYTE_COUNT; Index++) {
    mInputData.MacValue[Index] = (Temp[2 * Index] << 4) + Temp[2 * Index + 1];
  }

  return EFI_SUCCESS;
}

