/** @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 = ARRAY_SIZE (mRegionInfo);

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;
}

