/** @file

  Copyright (c) 2013-2014, ARM Ltd. All rights reserved.<BR>
  Copyright (c) 2017, Linaro. All rights reserved.

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <Library/AndroidBootImgLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/DevicePathLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>

#include <Protocol/BlockIo.h>
#include <Protocol/DevicePathFromText.h>

/* Validate the node is media hard drive type */
EFI_STATUS
ValidateAndroidMediaDevicePath (
  IN EFI_DEVICE_PATH                  *DevicePath
  )
{
  EFI_DEVICE_PATH_PROTOCOL            *Node, *NextNode;

  NextNode = DevicePath;
  while (NextNode != NULL) {
    Node = NextNode;
    if (Node->Type == MEDIA_DEVICE_PATH &&
        Node->SubType == MEDIA_HARDDRIVE_DP) {
      return EFI_SUCCESS;
    }
    NextNode = NextDevicePathNode (Node);
  }
  return EFI_INVALID_PARAMETER;
}

EFI_STATUS
EFIAPI
AndroidBootAppEntryPoint (
  IN EFI_HANDLE                            ImageHandle,
  IN EFI_SYSTEM_TABLE                      *SystemTable
  )
{
  EFI_STATUS                          Status;
  CHAR16                              *BootPathStr;
  EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL  *EfiDevicePathFromTextProtocol;
  EFI_DEVICE_PATH                     *DevicePath;
  EFI_BLOCK_IO_PROTOCOL               *BlockIo;
  UINT32                              MediaId, BlockSize;
  VOID                                *Buffer;
  EFI_HANDLE                          Handle;
  UINTN                               BootImgSize;

  BootPathStr = (CHAR16 *)PcdGetPtr (PcdAndroidBootDevicePath);
  ASSERT (BootPathStr != NULL);
  Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL,
                                (VOID **)&EfiDevicePathFromTextProtocol);
  ASSERT_EFI_ERROR(Status);
  DevicePath = (EFI_DEVICE_PATH *)EfiDevicePathFromTextProtocol->ConvertTextToDevicePath (BootPathStr);
  ASSERT (DevicePath != NULL);

  Status = ValidateAndroidMediaDevicePath (DevicePath);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid,
                                  &DevicePath, &Handle);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = gBS->OpenProtocol (
                  Handle,
                  &gEfiBlockIoProtocolGuid,
                  (VOID **) &BlockIo,
                  gImageHandle,
                  NULL,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Failed to get BlockIo: %r\n", Status));
    return Status;
  }

  MediaId = BlockIo->Media->MediaId;
  BlockSize = BlockIo->Media->BlockSize;
  Buffer = AllocatePages (EFI_SIZE_TO_PAGES (sizeof(ANDROID_BOOTIMG_HEADER)));
  if (Buffer == NULL) {
    return EFI_BUFFER_TOO_SMALL;
  }
  /* Load header of boot.img */
  Status = BlockIo->ReadBlocks (
                      BlockIo,
                      MediaId,
                      0,
                      BlockSize,
                      Buffer
                      );
  Status = AndroidBootImgGetImgSize (Buffer, &BootImgSize);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Failed to get AndroidBootImg Size: %r\n", Status));
    return Status;
  }
  BootImgSize = ALIGN_VALUE (BootImgSize, BlockSize);
  FreePages (Buffer, EFI_SIZE_TO_PAGES (sizeof(ANDROID_BOOTIMG_HEADER)));

  /* Both PartitionStart and PartitionSize are counted as block size. */
  Buffer = AllocatePages (EFI_SIZE_TO_PAGES (BootImgSize));
  if (Buffer == NULL) {
    return EFI_BUFFER_TOO_SMALL;
  }

  /* Load header of boot.img */
  Status = BlockIo->ReadBlocks (
                      BlockIo,
                      MediaId,
                      0,
                      BootImgSize,
                      Buffer
                      );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Failed to read blocks: %r\n", Status));
    goto EXIT;
  }

  Status = AndroidBootImgBoot (Buffer, BootImgSize);

EXIT:
  return Status;
}
