/** @file

  Copyright (c) 2014, ARM Ltd. All rights reserved.<BR>
  Copyright (c) 2015-2017, Linaro. All rights reserved.

  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.

**/

/*
  Implementation of the Android Fastboot Platform protocol, to be used by the
  Fastboot UEFI application, for Hisilicon HiKey platform.
*/

#include <Protocol/AndroidFastbootPlatform.h>
#include <Protocol/BlockIo.h>
#include <Protocol/DiskIo.h>
#include <Protocol/EraseBlock.h>
#include <Protocol/SimpleTextOut.h>

#include <Protocol/DevicePathToText.h>

#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/DevicePathLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/UsbSerialNumberLib.h>
#include <Library/PrintLib.h>
#include <Library/TimerLib.h>

#define PARTITION_NAME_MAX_LENGTH        (72/2)

#define SERIAL_NUMBER_LBA                20
#define RANDOM_MAX                       0x7FFFFFFFFFFFFFFF
#define RANDOM_MAGIC                     0x9A4DBEAF

typedef struct _FASTBOOT_PARTITION_LIST {
  LIST_ENTRY  Link;
  CHAR16      PartitionName[PARTITION_NAME_MAX_LENGTH];
  EFI_LBA     StartingLBA;
  EFI_LBA     EndingLBA;
} FASTBOOT_PARTITION_LIST;

STATIC LIST_ENTRY                       mPartitionListHead;
STATIC EFI_HANDLE                       mFlashHandle;
STATIC EFI_BLOCK_IO_PROTOCOL           *mFlashBlockIo;
STATIC EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *mTextOut;

/*
  Helper to free the partition list
*/
STATIC
VOID
FreePartitionList (
  VOID
  )
{
  FASTBOOT_PARTITION_LIST *Entry;
  FASTBOOT_PARTITION_LIST *NextEntry;

  Entry = (FASTBOOT_PARTITION_LIST *) GetFirstNode (&mPartitionListHead);
  while (!IsNull (&mPartitionListHead, &Entry->Link)) {
    NextEntry = (FASTBOOT_PARTITION_LIST *) GetNextNode (&mPartitionListHead, &Entry->Link);

    RemoveEntryList (&Entry->Link);
    FreePool (Entry);

    Entry = NextEntry;
  }
}

/*
  Read the PartitionName fields from the GPT partition entries, putting them
  into an allocated array that should later be freed.
*/
STATIC
EFI_STATUS
ReadPartitionEntries (
  IN  EFI_BLOCK_IO_PROTOCOL *BlockIo,
  OUT EFI_PARTITION_ENTRY  **PartitionEntries,
  OUT UINTN                 *PartitionNumbers
  )
{
  UINT32                      MediaId;
  EFI_PARTITION_TABLE_HEADER *GptHeader;
  EFI_PARTITION_ENTRY        *Entry;
  EFI_STATUS                  Status;
  VOID                       *Buffer;
  UINTN                       PageCount;
  UINTN                       BlockSize;
  UINTN                       Count, EndLBA;

  if ((PartitionEntries == NULL) || (PartitionNumbers == NULL)) {
    return EFI_INVALID_PARAMETER;
  }
  MediaId = BlockIo->Media->MediaId;
  BlockSize = BlockIo->Media->BlockSize;

  //
  // Read size of Partition entry and number of entries from GPT header
  //

  PageCount = EFI_SIZE_TO_PAGES (6 * BlockSize);
  Buffer = AllocatePages (PageCount);
  if (Buffer == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Status = BlockIo->ReadBlocks (BlockIo, MediaId, 0, PageCount * EFI_PAGE_SIZE, Buffer);
  if (EFI_ERROR (Status)) {
    return Status;
  }
  GptHeader = (EFI_PARTITION_TABLE_HEADER *)(Buffer + BlockSize);

  // Check there is a GPT on the media
  if (GptHeader->Header.Signature != EFI_PTAB_HEADER_ID ||
      GptHeader->MyLBA != 1) {
    DEBUG ((DEBUG_ERROR,
      "Fastboot platform: No GPT on flash. "
      "Fastboot on Versatile Express does not support MBR.\n"
      ));
    return EFI_DEVICE_ERROR;
  }

  Entry = (EFI_PARTITION_ENTRY *)(Buffer + (2 * BlockSize));
  EndLBA = GptHeader->FirstUsableLBA - 1;
  Count = 0;
  while (1) {
    if ((Entry->StartingLBA > EndLBA) && (Entry->EndingLBA <= GptHeader->LastUsableLBA)) {
      Count++;
      EndLBA = Entry->EndingLBA;
      Entry++;
    } else {
      break;
    }
  }
  if (Count == 0) {
    return EFI_INVALID_PARAMETER;
  }
  if (Count > GptHeader->NumberOfPartitionEntries) {
    Count = GptHeader->NumberOfPartitionEntries;
  }

  *PartitionEntries = (EFI_PARTITION_ENTRY *)((UINTN)Buffer + (2 * BlockSize));
  *PartitionNumbers = Count;
  return EFI_SUCCESS;
}

EFI_STATUS
LoadPtable (
  VOID
  )
{
  EFI_STATUS                          Status;
  EFI_DEVICE_PATH_PROTOCOL           *FlashDevicePath;
  EFI_DEVICE_PATH_PROTOCOL           *FlashDevicePathDup;
  UINTN                               PartitionNumbers = 0;
  UINTN                               LoopIndex;
  EFI_PARTITION_ENTRY                *PartitionEntries = NULL;
  FASTBOOT_PARTITION_LIST            *Entry;

  InitializeListHead (&mPartitionListHead);

  Status = gBS->LocateProtocol (&gEfiSimpleTextOutProtocolGuid, NULL, (VOID **) &mTextOut);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR,
      "Fastboot platform: Couldn't open Text Output Protocol: %r\n", Status
      ));
    return Status;
  }

  //
  // Get EFI_HANDLES for all the partitions on the block devices pointed to by
  // PcdFastbootFlashDevicePath, also saving their GPT partition labels.
  // There's no way to find all of a device's children, so we get every handle
  // in the system supporting EFI_BLOCK_IO_PROTOCOL and then filter out ones
  // that don't represent partitions on the flash device.
  //
  FlashDevicePath = ConvertTextToDevicePath ((CHAR16*)FixedPcdGetPtr (PcdAndroidFastbootNvmDevicePath));

  // Create another device path pointer because LocateDevicePath will modify it.
  FlashDevicePathDup = FlashDevicePath;
  Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &FlashDevicePathDup, &mFlashHandle);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Warning: Couldn't locate Android NVM device (status: %r)\n", Status));
    // Failing to locate partitions should not prevent to do other Android FastBoot actions
    return EFI_SUCCESS;
  }


  Status = gBS->OpenProtocol (
                  mFlashHandle,
                  &gEfiBlockIoProtocolGuid,
                  (VOID **) &mFlashBlockIo,
                  gImageHandle,
                  NULL,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Fastboot platform: Couldn't open Android NVM device (status: %r)\n", Status));
    return EFI_DEVICE_ERROR;
  }

  // Read the GPT partition entry array into memory so we can get the partition names
  Status = ReadPartitionEntries (mFlashBlockIo, &PartitionEntries, &PartitionNumbers);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Warning: Failed to read partitions from Android NVM device (status: %r)\n", Status));
    // Failing to locate partitions should not prevent to do other Android FastBoot actions
    return EFI_SUCCESS;
  }
  for (LoopIndex = 0; LoopIndex < PartitionNumbers; LoopIndex++) {
    // Create entry
    Entry = AllocatePool (sizeof (FASTBOOT_PARTITION_LIST));
    if (Entry == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      FreePartitionList ();
      goto Exit;
    }
    StrnCpy (
      Entry->PartitionName,
      PartitionEntries[LoopIndex].PartitionName,
      PARTITION_NAME_MAX_LENGTH
      );
    Entry->StartingLBA = PartitionEntries[LoopIndex].StartingLBA;
    Entry->EndingLBA = PartitionEntries[LoopIndex].EndingLBA;
    InsertTailList (&mPartitionListHead, &Entry->Link);
  }
Exit:
  FreePages (
    (VOID *)((UINTN)PartitionEntries - (2 * mFlashBlockIo->Media->BlockSize)),
    EFI_SIZE_TO_PAGES (6 * mFlashBlockIo->Media->BlockSize)
    );
  return Status;
}

/*
  Initialise: Open the Android NVM device and find the partitions on it. Save them in
  a list along with the "PartitionName" fields for their GPT entries.
  We will use these partition names as the key in
  HiKey960FastbootPlatformFlashPartition.
*/
EFI_STATUS
HiKey960FastbootPlatformInit (
  VOID
  )
{
  EFI_STATUS               Status;

  Status = LoadPtable ();
  if (EFI_ERROR (Status)) {
    return Status;
  }
  return Status;
}

VOID
HiKey960FastbootPlatformUnInit (
  VOID
  )
{
  FreePartitionList ();
}

EFI_STATUS
HiKey960FlashPtable (
  IN UINTN   Size,
  IN VOID   *Image
  )
{
  EFI_STATUS               Status;
  Status = mFlashBlockIo->WriteBlocks (
                            mFlashBlockIo,
                            mFlashBlockIo->Media->MediaId,
                            0,
                            Size,
                            Image
                            );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Failed to write (status:%r)\n", Status));
    return Status;
  }
  FreePartitionList ();
  Status = LoadPtable ();
  return Status;
}

EFI_STATUS
HiKey960ErasePtable (
  VOID
  )
{
  EFI_STATUS                  Status;
#if 0
  EFI_ERASE_BLOCK_PROTOCOL   *EraseBlockProtocol;
#endif

#if 0
  Status = gBS->OpenProtocol (
                  mFlashHandle,
                  &gEfiEraseBlockProtocolGuid,
                  (VOID **) &EraseBlockProtocol,
                  gImageHandle,
                  NULL,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Fastboot platform: could not open Erase Block IO: %r\n", Status));
    return EFI_DEVICE_ERROR;
  }
  Status = EraseBlockProtocol->EraseBlocks (
                                 EraseBlockProtocol,
                                 mFlashBlockIo->Media->MediaId,
                                 0,
                                 NULL,
                                 6 * mFlashBlockIo->Media->BlockSize
                                 );
#else
  {
    VOID         *DataPtr;
    UINTN         Lba;

    DataPtr = AllocatePages (1);
    ZeroMem (DataPtr, EFI_PAGE_SIZE);
    for (Lba = 0; Lba < 6; Lba++) {
      Status = mFlashBlockIo->WriteBlocks (
                          mFlashBlockIo,
                          mFlashBlockIo->Media->MediaId,
                          Lba,
                          EFI_PAGE_SIZE,
                          DataPtr
                          );
      if (EFI_ERROR (Status)) {
        goto Exit;
      }
    }
Exit:
    FreePages (DataPtr, 1);
  }
#endif
  FreePartitionList ();
  return Status;
}

EFI_STATUS
HiKey960FlashXloader (
  IN UINTN   Size,
  IN VOID   *Image
  )
{
  EFI_STATUS                        Status;
  EFI_DEVICE_PATH_PROTOCOL         *DevicePath;
  EFI_HANDLE                        Handle;
  EFI_BLOCK_IO_PROTOCOL            *BlockIo;
  EFI_DISK_IO_PROTOCOL             *DiskIo;

  DevicePath = ConvertTextToDevicePath ((CHAR16*)FixedPcdGetPtr (PcdXloaderDevicePath));

  Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &DevicePath, &Handle);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Warning: Couldn't locate xloader device (status: %r)\n", Status));
    return Status;
  }

  Status = gBS->OpenProtocol (
                  Handle,
                  &gEfiBlockIoProtocolGuid,
                  (VOID **) &BlockIo,
                  gImageHandle,
                  NULL,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Fastboot platform: Couldn't open xloader device (status: %r)\n", Status));
    return EFI_DEVICE_ERROR;
  }
  Status = gBS->OpenProtocol (
                  Handle,
                  &gEfiDiskIoProtocolGuid,
                  (VOID **) &DiskIo,
                  gImageHandle,
                  NULL,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = DiskIo->WriteDisk (
                     DiskIo,
                     BlockIo->Media->MediaId,
                     0,
                     Size,
                     Image
                     );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Failed to write (status:%r)\n", Status));
    return Status;
  }
  return Status;
}

EFI_STATUS
HiKey960FastbootPlatformFlashPartition (
  IN CHAR8  *PartitionName,
  IN UINTN   Size,
  IN VOID   *Image
  )
{
  EFI_STATUS               Status;
  UINTN                    PartitionSize;
  FASTBOOT_PARTITION_LIST *Entry;
  CHAR16                   PartitionNameUnicode[60];
  BOOLEAN                  PartitionFound;
  EFI_DISK_IO_PROTOCOL    *DiskIo;
  UINTN                    BlockSize;

  // Support the pseudo partition name, such as "ptable".
  if (AsciiStrCmp (PartitionName, "ptable") == 0) {
    return HiKey960FlashPtable (Size, Image);
  } else if (AsciiStrCmp (PartitionName, "xloader") == 0) {
    return HiKey960FlashXloader (Size, Image);
  }

  AsciiStrToUnicodeStr (PartitionName, PartitionNameUnicode);
  PartitionFound = FALSE;
  Entry = (FASTBOOT_PARTITION_LIST *) GetFirstNode (&(mPartitionListHead));
  while (!IsNull (&mPartitionListHead, &Entry->Link)) {
    // Search the partition list for the partition named by PartitionName
    if (StrCmp (Entry->PartitionName, PartitionNameUnicode) == 0) {
      PartitionFound = TRUE;
      break;
    }

   Entry = (FASTBOOT_PARTITION_LIST *) GetNextNode (&mPartitionListHead, &(Entry)->Link);
  }
  if (!PartitionFound) {
    return EFI_NOT_FOUND;
  }

  // Check image will fit on device
  BlockSize = mFlashBlockIo->Media->BlockSize;
  PartitionSize = (Entry->EndingLBA - Entry->StartingLBA + 1) * BlockSize;
  if (PartitionSize < Size) {
    DEBUG ((DEBUG_ERROR, "Partition not big enough.\n"));
    DEBUG ((DEBUG_ERROR, "Partition Size:\t%ld\nImage Size:\t%ld\n", PartitionSize, Size));

    return EFI_VOLUME_FULL;
  }

  Status = gBS->OpenProtocol (
                  mFlashHandle,
                  &gEfiDiskIoProtocolGuid,
                  (VOID **) &DiskIo,
                  gImageHandle,
                  NULL,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  ASSERT_EFI_ERROR (Status);

  Status = DiskIo->WriteDisk (
                     DiskIo,
                     mFlashBlockIo->Media->MediaId,
                     Entry->StartingLBA * BlockSize,
                     Size,
                     Image
                     );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Failed to write %d bytes into 0x%x, Status:%r\n", Size, Entry->StartingLBA * BlockSize, Status));
    return Status;
  }

  mFlashBlockIo->FlushBlocks(mFlashBlockIo);
  MicroSecondDelay (50000);

  return Status;
}

EFI_STATUS
HiKey960FastbootPlatformErasePartition (
  IN CHAR8 *PartitionName
  )
{
  EFI_STATUS                  Status;
  EFI_ERASE_BLOCK_PROTOCOL   *EraseBlockProtocol;
  UINTN                       Size;
  BOOLEAN                     PartitionFound;
  CHAR16                      PartitionNameUnicode[60];
  FASTBOOT_PARTITION_LIST    *Entry;

  AsciiStrToUnicodeStr (PartitionName, PartitionNameUnicode);

  // Support the pseudo partition name, such as "ptable".
  if (AsciiStrCmp (PartitionName, "ptable") == 0) {
    return HiKey960ErasePtable ();
  }

  PartitionFound = FALSE;
  Entry = (FASTBOOT_PARTITION_LIST *) GetFirstNode (&mPartitionListHead);
  while (!IsNull (&mPartitionListHead, &Entry->Link)) {
    // Search the partition list for the partition named by PartitionName
    if (StrCmp (Entry->PartitionName, PartitionNameUnicode) == 0) {
      PartitionFound = TRUE;
      break;
    }
    Entry = (FASTBOOT_PARTITION_LIST *) GetNextNode (&mPartitionListHead, &Entry->Link);
  }
  if (!PartitionFound) {
    return EFI_NOT_FOUND;
  }

  Status = gBS->OpenProtocol (
                  mFlashHandle,
                  &gEfiEraseBlockProtocolGuid,
                  (VOID **) &EraseBlockProtocol,
                  gImageHandle,
                  NULL,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }
  Size = (Entry->EndingLBA - Entry->StartingLBA + 1) * mFlashBlockIo->Media->BlockSize;
  Status = EraseBlockProtocol->EraseBlocks (
                                 EraseBlockProtocol,
                                 mFlashBlockIo->Media->MediaId,
                                 Entry->StartingLBA,
                                 NULL,
                                 Size
                                 );
  return Status;
}

EFI_STATUS
HiKey960FastbootPlatformGetVar (
  IN  CHAR8   *Name,
  OUT CHAR8   *Value
  )
{
  EFI_STATUS               Status = EFI_SUCCESS;
  UINT64                   PartitionSize;
  FASTBOOT_PARTITION_LIST *Entry;
  CHAR16                   PartitionNameUnicode[60];
  BOOLEAN                  PartitionFound;
  CHAR16                   UnicodeSN[SERIAL_NUMBER_SIZE];

  if (!AsciiStrCmp (Name, "max-download-size")) {
    AsciiStrCpy (Value, FixedPcdGetPtr (PcdArmFastbootFlashLimit));
  } else if (!AsciiStrCmp (Name, "product")) {
    AsciiStrCpy (Value, FixedPcdGetPtr (PcdFirmwareVendor));
  } else if (!AsciiStrCmp (Name, "serialno")) {
    Status = LoadSNFromBlock (mFlashHandle, SERIAL_NUMBER_LBA, UnicodeSN);
    UnicodeStrToAsciiStr (UnicodeSN, Value);
  } else if ( !AsciiStrnCmp (Name, "partition-size", 14)) {
    AsciiStrToUnicodeStr ((Name + 15), PartitionNameUnicode);
    PartitionFound = FALSE;
    Entry = (FASTBOOT_PARTITION_LIST *) GetFirstNode (&(mPartitionListHead));
    while (!IsNull (&mPartitionListHead, &Entry->Link)) {
      // Search the partition list for the partition named by PartitionName
      if (StrCmp (Entry->PartitionName, PartitionNameUnicode) == 0) {
        PartitionFound = TRUE;
        break;
      }

     Entry = (FASTBOOT_PARTITION_LIST *) GetNextNode (&mPartitionListHead, &(Entry)->Link);
    }
    if (!PartitionFound) {
      *Value = '\0';
      return EFI_NOT_FOUND;
    }

    PartitionSize = (Entry->EndingLBA - Entry->StartingLBA + 1) * mFlashBlockIo->Media->BlockSize;
    DEBUG ((DEBUG_ERROR, "Fastboot platform: check for partition-size:%a 0X%llx\n", Name, PartitionSize ));
    AsciiSPrint (Value, 12, "0x%llx", PartitionSize);
  } else if ( !AsciiStrnCmp (Name, "partition-type", 14)) {
      DEBUG ((DEBUG_ERROR, "Fastboot platform: check for partition-type:%a\n", (Name + 15) ));
    if ( !AsciiStrnCmp  ( (Name + 15) , "system", 6) || !AsciiStrnCmp  ( (Name + 15) , "userdata", 8)
            || !AsciiStrnCmp  ( (Name + 15) , "cache", 5)) {
      AsciiStrCpy (Value, "ext4");
    } else {
      AsciiStrCpy (Value, "raw");
    }
  } else {
    *Value = '\0';
  }
  return Status;
}

EFI_STATUS
HiKey960FastbootPlatformOemCommand (
  IN  CHAR8   *Command
  )
{
  EFI_STATUS   Status;
  CHAR16       UnicodeSN[SERIAL_NUMBER_SIZE];

  if (AsciiStrCmp (Command, "Demonstrate") == 0) {
    DEBUG ((DEBUG_ERROR, "ARM OEM Fastboot command 'Demonstrate' received.\n"));
    return EFI_SUCCESS;
  } else if (AsciiStrCmp (Command, "serialno") == 0) {
    Status = GenerateUsbSN (UnicodeSN);
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "Failed to generate USB Serial Number.\n"));
      return Status;
    }
    Status = StoreSNToBlock (mFlashHandle, SERIAL_NUMBER_LBA, UnicodeSN);
    return Status;
  } else {
    DEBUG ((DEBUG_ERROR,
      "HiKey960: Unrecognised Fastboot OEM command: %a\n",
      Command
      ));
    return EFI_NOT_FOUND;
  }
}

EFI_STATUS
HiKey960FastbootPlatformFlashPartitionEx (
  IN CHAR8  *PartitionName,
  IN UINTN   Offset,
  IN UINTN   Size,
  IN VOID   *Image
  )
{
  EFI_STATUS               Status;
  UINTN                    PartitionSize;
  FASTBOOT_PARTITION_LIST *Entry;
  CHAR16                   PartitionNameUnicode[60];
  BOOLEAN                  PartitionFound;
  UINTN                    BlockSize;
  EFI_DISK_IO_PROTOCOL    *DiskIo;

  AsciiStrToUnicodeStr (PartitionName, PartitionNameUnicode);
  PartitionFound = FALSE;
  Entry = (FASTBOOT_PARTITION_LIST *) GetFirstNode (&(mPartitionListHead));
  while (!IsNull (&mPartitionListHead, &Entry->Link)) {
    // Search the partition list for the partition named by PartitionName
    if (StrCmp (Entry->PartitionName, PartitionNameUnicode) == 0) {
      PartitionFound = TRUE;
      break;
    }

   Entry = (FASTBOOT_PARTITION_LIST *) GetNextNode (&mPartitionListHead, &(Entry)->Link);
  }
  if (!PartitionFound) {
    return EFI_NOT_FOUND;
  }

  // Check image will fit on device
  PartitionSize = (Entry->EndingLBA - Entry->StartingLBA + 1) * mFlashBlockIo->Media->BlockSize;
  if (PartitionSize < Size) {
    DEBUG ((DEBUG_ERROR, "Partition not big enough.\n"));
    DEBUG ((DEBUG_ERROR, "Partition Size:\t%ld\nImage Size:\t%ld\n", PartitionSize, Size));

    return EFI_VOLUME_FULL;
  }

  BlockSize = mFlashBlockIo->Media->BlockSize;

  Status = gBS->OpenProtocol (
                  mFlashHandle,
                  &gEfiDiskIoProtocolGuid,
                  (VOID **) &DiskIo,
                  gImageHandle,
                  NULL,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = DiskIo->WriteDisk (
                     DiskIo,
                     mFlashBlockIo->Media->MediaId,
                     Entry->StartingLBA * BlockSize + Offset,
                     Size,
                     Image
                     );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Failed to write %d bytes into 0x%x, Status:%r\n", Size, Entry->StartingLBA * BlockSize + Offset, Status));
    return Status;
  }
  return Status;
}

FASTBOOT_PLATFORM_PROTOCOL mPlatformProtocol = {
  HiKey960FastbootPlatformInit,
  HiKey960FastbootPlatformUnInit,
  HiKey960FastbootPlatformFlashPartition,
  HiKey960FastbootPlatformErasePartition,
  HiKey960FastbootPlatformGetVar,
  HiKey960FastbootPlatformOemCommand,
  HiKey960FastbootPlatformFlashPartitionEx
};

EFI_STATUS
EFIAPI
HiKey960FastbootPlatformEntryPoint (
  IN EFI_HANDLE                            ImageHandle,
  IN EFI_SYSTEM_TABLE                      *SystemTable
  )
{
  return gBS->InstallProtocolInterface (
                &ImageHandle,
                &gAndroidFastbootPlatformProtocolGuid,
                EFI_NATIVE_INTERFACE,
                &mPlatformProtocol
                );
}
