/** @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/FdtLib.h>
#include <Library/PrintLib.h>
#include <Library/DevicePathLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>

#include <Protocol/AndroidBootImg.h>
#include <Protocol/LoadFile2.h>
#include <Protocol/LoadedImage.h>

#include <Guid/LinuxEfiInitrdMedia.h>

#define FDT_ADDITIONAL_ENTRIES_SIZE  0x400

typedef struct {
  MEMMAP_DEVICE_PATH          Node1;
  EFI_DEVICE_PATH_PROTOCOL    End;
} MEMORY_DEVICE_PATH;

typedef struct {
  VENDOR_DEVICE_PATH          VendorMediaNode;
  EFI_DEVICE_PATH_PROTOCOL    EndNode;
} RAMDISK_DEVICE_PATH;

STATIC ANDROID_BOOTIMG_PROTOCOL  *mAndroidBootImg;
STATIC VOID                      *mRamdiskData          = NULL;
STATIC UINTN                     mRamdiskSize           = 0;
STATIC EFI_HANDLE                mRamDiskLoadFileHandle = NULL;

STATIC CONST MEMORY_DEVICE_PATH  mMemoryDevicePathTemplate =
{
  {
    {
      HARDWARE_DEVICE_PATH,
      HW_MEMMAP_DP,
      {
        (UINT8)(sizeof (MEMMAP_DEVICE_PATH)),
        (UINT8)((sizeof (MEMMAP_DEVICE_PATH)) >> 8),
      },
    }, // Header
    0, // StartingAddress (set at runtime)
    0  // EndingAddress   (set at runtime)
  }, // Node1
  {
    END_DEVICE_PATH_TYPE,
    END_ENTIRE_DEVICE_PATH_SUBTYPE,
    { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 }
  } // End
};

STATIC CONST RAMDISK_DEVICE_PATH  mRamdiskDevicePath =
{
  {
    {
      MEDIA_DEVICE_PATH,
      MEDIA_VENDOR_DP,
      { sizeof (VENDOR_DEVICE_PATH),       0 }
    },
    LINUX_EFI_INITRD_MEDIA_GUID
  },
  {
    END_DEVICE_PATH_TYPE,
    END_ENTIRE_DEVICE_PATH_SUBTYPE,
    { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 }
  }
};

/**
  Causes the driver to load a specified file.

  @param  This       Protocol instance pointer.
  @param  FilePath   The device specific path of the file to load.
  @param  BootPolicy Should always be FALSE.
  @param  BufferSize On input the size of Buffer in bytes. On output with a return
                     code of EFI_SUCCESS, the amount of data transferred to
                     Buffer. On output with a return code of EFI_BUFFER_TOO_SMALL,
                     the size of Buffer required to retrieve the requested file.
  @param  Buffer     The memory buffer to transfer the file to. IF Buffer is NULL,
                     then no the size of the requested file is returned in
                     BufferSize.

  @retval EFI_SUCCESS           The file was loaded.
  @retval EFI_UNSUPPORTED       BootPolicy is TRUE.
  @retval EFI_INVALID_PARAMETER FilePath is not a valid device path, or
                                BufferSize is NULL.
  @retval EFI_NO_MEDIA          No medium was present to load the file.
  @retval EFI_DEVICE_ERROR      The file was not loaded due to a device error.
  @retval EFI_NO_RESPONSE       The remote system did not respond.
  @retval EFI_NOT_FOUND         The file was not found
  @retval EFI_ABORTED           The file load process was manually canceled.
  @retval EFI_BUFFER_TOO_SMALL  The BufferSize is too small to read the current
                                directory entry. BufferSize has been updated with
                                the size needed to complete the request.


**/
EFI_STATUS
EFIAPI
AndroidBootImgLoadFile2 (
  IN EFI_LOAD_FILE2_PROTOCOL   *This,
  IN EFI_DEVICE_PATH_PROTOCOL  *FilePath,
  IN BOOLEAN                   BootPolicy,
  IN OUT UINTN                 *BufferSize,
  IN VOID                      *Buffer OPTIONAL
  )

{
  // Verify if the valid parameters
  if ((This == NULL) ||
      (BufferSize == NULL) ||
      (FilePath == NULL) ||
      !IsDevicePathValid (FilePath, 0))
  {
    return EFI_INVALID_PARAMETER;
  }

  if (BootPolicy) {
    return EFI_UNSUPPORTED;
  }

  // Check if the given buffer size is big enough
  // EFI_BUFFER_TOO_SMALL to allow caller to allocate a bigger buffer
  if (mRamdiskSize == 0) {
    return EFI_NOT_FOUND;
  }

  if ((Buffer == NULL) || (*BufferSize < mRamdiskSize)) {
    *BufferSize = mRamdiskSize;
    return EFI_BUFFER_TOO_SMALL;
  }

  // Copy InitRd
  CopyMem (Buffer, mRamdiskData, mRamdiskSize);
  *BufferSize = mRamdiskSize;

  return EFI_SUCCESS;
}

///
/// Load File Protocol instance
///
STATIC EFI_LOAD_FILE2_PROTOCOL  mAndroidBootImgLoadFile2 = {
  AndroidBootImgLoadFile2
};

EFI_STATUS
AndroidBootImgGetImgSize (
  IN  VOID   *BootImg,
  OUT UINTN  *ImgSize
  )
{
  ANDROID_BOOTIMG_HEADER  *Header;

  Header = (ANDROID_BOOTIMG_HEADER *)BootImg;

  if (AsciiStrnCmp (
        (CONST CHAR8 *)Header->BootMagic,
        ANDROID_BOOT_MAGIC,
        ANDROID_BOOT_MAGIC_LENGTH
        ) != 0)
  {
    return EFI_INVALID_PARAMETER;
  }

  /* The page size is not specified, but it should be power of 2 at least */
  ASSERT (IS_VALID_ANDROID_PAGE_SIZE (Header->PageSize));

  /* Get real size of abootimg */
  *ImgSize = ALIGN_VALUE (Header->KernelSize, Header->PageSize) +
             ALIGN_VALUE (Header->RamdiskSize, Header->PageSize) +
             ALIGN_VALUE (Header->SecondStageBootloaderSize, Header->PageSize) +
             Header->PageSize;
  return EFI_SUCCESS;
}

EFI_STATUS
AndroidBootImgGetKernelInfo (
  IN  VOID   *BootImg,
  OUT VOID   **Kernel,
  OUT UINTN  *KernelSize
  )
{
  ANDROID_BOOTIMG_HEADER  *Header;

  Header = (ANDROID_BOOTIMG_HEADER *)BootImg;

  if (AsciiStrnCmp (
        (CONST CHAR8 *)Header->BootMagic,
        ANDROID_BOOT_MAGIC,
        ANDROID_BOOT_MAGIC_LENGTH
        ) != 0)
  {
    return EFI_INVALID_PARAMETER;
  }

  if (Header->KernelSize == 0) {
    return EFI_NOT_FOUND;
  }

  ASSERT (IS_VALID_ANDROID_PAGE_SIZE (Header->PageSize));

  *KernelSize = Header->KernelSize;
  *Kernel     = (VOID *)((UINTN)BootImg + Header->PageSize);
  return EFI_SUCCESS;
}

EFI_STATUS
AndroidBootImgGetRamdiskInfo (
  IN  VOID   *BootImg,
  OUT VOID   **Ramdisk,
  OUT UINTN  *RamdiskSize
  )
{
  ANDROID_BOOTIMG_HEADER  *Header;

  Header = (ANDROID_BOOTIMG_HEADER *)BootImg;

  if (AsciiStrnCmp (
        (CONST CHAR8 *)Header->BootMagic,
        ANDROID_BOOT_MAGIC,
        ANDROID_BOOT_MAGIC_LENGTH
        ) != 0)
  {
    return EFI_INVALID_PARAMETER;
  }

  ASSERT (IS_VALID_ANDROID_PAGE_SIZE (Header->PageSize));

  *RamdiskSize = Header->RamdiskSize;

  if (Header->RamdiskSize != 0) {
    *Ramdisk = (VOID *)((INTN)BootImg
                        + Header->PageSize
                        + ALIGN_VALUE (Header->KernelSize, Header->PageSize));
  }

  return EFI_SUCCESS;
}

EFI_STATUS
AndroidBootImgGetSecondBootLoaderInfo (
  IN  VOID   *BootImg,
  OUT VOID   **Second,
  OUT UINTN  *SecondSize
  )
{
  ANDROID_BOOTIMG_HEADER  *Header;

  Header = (ANDROID_BOOTIMG_HEADER *)BootImg;

  if (AsciiStrnCmp (
        (CONST CHAR8 *)Header->BootMagic,
        ANDROID_BOOT_MAGIC,
        ANDROID_BOOT_MAGIC_LENGTH
        ) != 0)
  {
    return EFI_INVALID_PARAMETER;
  }

  ASSERT (IS_VALID_ANDROID_PAGE_SIZE (Header->PageSize));

  *SecondSize = Header->SecondStageBootloaderSize;

  if (Header->SecondStageBootloaderSize != 0) {
    *Second = (VOID *)((UINTN)BootImg
                       + Header->PageSize
                       + ALIGN_VALUE (Header->KernelSize, Header->PageSize)
                       + ALIGN_VALUE (Header->RamdiskSize, Header->PageSize));
  }

  return EFI_SUCCESS;
}

EFI_STATUS
AndroidBootImgGetKernelArgs (
  IN  VOID   *BootImg,
  OUT CHAR8  *KernelArgs
  )
{
  ANDROID_BOOTIMG_HEADER  *Header;

  Header = (ANDROID_BOOTIMG_HEADER *)BootImg;
  AsciiStrnCpyS (
    KernelArgs,
    ANDROID_BOOTIMG_KERNEL_ARGS_SIZE,
    Header->KernelArgs,
    ANDROID_BOOTIMG_KERNEL_ARGS_SIZE
    );

  return EFI_SUCCESS;
}

EFI_STATUS
AndroidBootImgGetFdt (
  IN  VOID  *BootImg,
  IN  VOID  **FdtBase
  )
{
  UINTN       SecondLoaderSize;
  EFI_STATUS  Status;

  /* Check whether FDT is located in second boot region as some vendor do so,
   * because second loader is never used as far as I know. */
  Status = AndroidBootImgGetSecondBootLoaderInfo (
             BootImg,
             FdtBase,
             &SecondLoaderSize
             );
  return Status;
}

EFI_STATUS
AndroidBootImgUpdateArgs (
  IN  VOID  *BootImg,
  OUT VOID  **KernelArgs
  )
{
  CHAR8       ImageKernelArgs[ANDROID_BOOTIMG_KERNEL_ARGS_SIZE];
  EFI_STATUS  Status;
  UINT32      NewKernelArgSize;

  // Get kernel arguments from Android boot image
  Status = AndroidBootImgGetKernelArgs (BootImg, ImageKernelArgs);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  NewKernelArgSize = ANDROID_BOOTIMG_KERNEL_ARGS_SIZE + PcdGet32 (PcdAndroidKernelCommandLineOverflow);
  *KernelArgs      = AllocateZeroPool (sizeof (CHAR16) * NewKernelArgSize);
  if (*KernelArgs == NULL) {
    DEBUG ((DEBUG_ERROR, "Fail to allocate memory\n"));
    return EFI_OUT_OF_RESOURCES;
  }

  AsciiStrToUnicodeStrS (
    ImageKernelArgs,
    *KernelArgs,
    NewKernelArgSize
    );
  // Append platform kernel arguments
  if (mAndroidBootImg->AppendArgs) {
    Status = mAndroidBootImg->AppendArgs (
                                *KernelArgs,
                                NewKernelArgSize
                                );
  }

  return Status;
}

EFI_STATUS
AndroidBootImgInstallLoadFile2 (
  IN  VOID   *RamdiskData,
  IN  UINTN  RamdiskSize
  )
{
  mRamDiskLoadFileHandle = NULL;
  mRamdiskData           = RamdiskData;
  mRamdiskSize           = RamdiskSize;
  return gBS->InstallMultipleProtocolInterfaces (
                &mRamDiskLoadFileHandle,
                &gEfiLoadFile2ProtocolGuid,
                &mAndroidBootImgLoadFile2,
                &gEfiDevicePathProtocolGuid,
                &mRamdiskDevicePath,
                NULL
                );
}

EFI_STATUS
AndroidBootImgUninstallLoadFile2 (
  VOID
  )
{
  EFI_STATUS  Status;

  Status       = EFI_SUCCESS;
  mRamdiskData = NULL;
  mRamdiskSize = 0;
  if (mRamDiskLoadFileHandle != NULL) {
    Status = gBS->UninstallMultipleProtocolInterfaces (
                    mRamDiskLoadFileHandle,
                    &gEfiLoadFile2ProtocolGuid,
                    &mAndroidBootImgLoadFile2,
                    &gEfiDevicePathProtocolGuid,
                    &mRamdiskDevicePath,
                    NULL
                    );
    mRamDiskLoadFileHandle = NULL;
  }

  return Status;
}

BOOLEAN
AndroidBootImgAcpiSupported (
  VOID
  )
{
  EFI_STATUS  Status;
  VOID        *AcpiTable;

  Status = EfiGetSystemConfigurationTable (&gEfiAcpiTableGuid, &AcpiTable);
  return !EFI_ERROR (Status);
}

EFI_STATUS
AndroidBootImgLocateFdt (
  IN  VOID  *BootImg,
  IN  VOID  **FdtBase
  )
{
  INTN        Err;
  EFI_STATUS  Status;

  Status = EfiGetSystemConfigurationTable (&gFdtTableGuid, FdtBase);
  if (!EFI_ERROR (Status)) {
    return EFI_SUCCESS;
  }

  Status = AndroidBootImgGetFdt (BootImg, FdtBase);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Err = FdtCheckHeader (*FdtBase);
  if (Err != 0) {
    DEBUG ((
      DEBUG_ERROR,
      "ERROR: Device Tree header not valid (Err:%d)\n",
      Err
      ));
    return EFI_INVALID_PARAMETER;
  }

  return EFI_SUCCESS;
}

INTN
AndroidBootImgGetChosenNode (
  IN  INTN  UpdatedFdtBase
  )
{
  INTN  ChosenNode;

  ChosenNode = FdtSubnodeOffset ((CONST VOID *)UpdatedFdtBase, 0, "chosen");
  if (ChosenNode < 0) {
    ChosenNode = FdtAddSubnode ((VOID *)UpdatedFdtBase, 0, "chosen");
    if (ChosenNode < 0) {
      DEBUG ((DEBUG_ERROR, "Fail to find fdt node chosen!\n"));
      return 0;
    }
  }

  return ChosenNode;
}

EFI_STATUS
AndroidBootImgSetProperty64 (
  IN  INTN    UpdatedFdtBase,
  IN  INTN    ChosenNode,
  IN  CHAR8   *PropertyName,
  IN  UINT64  Val
  )
{
  INTN                Err;
  CONST FDT_PROPERTY  *Property;
  int                 Len;

  Property = FdtGetPropertyW (
               (VOID *)UpdatedFdtBase,
               ChosenNode,
               PropertyName,
               &Len
               );
  if ((NULL == Property) && (Len == -FDT_ERR_NOTFOUND)) {
    Val = CpuToFdt64 (Val);
    Err = FdtAppendProp (
            (VOID *)UpdatedFdtBase,
            ChosenNode,
            PropertyName,
            &Val,
            sizeof (UINT64)
            );
    if (Err) {
      DEBUG ((DEBUG_ERROR, "FdtAppendProp() fail: %a\n", FdtStrerror (Err)));
      return EFI_INVALID_PARAMETER;
    }
  } else if (Property != NULL) {
    Err = FdtSetPropU64 (
            (VOID *)UpdatedFdtBase,
            ChosenNode,
            PropertyName,
            Val
            );
    if (Err) {
      DEBUG ((DEBUG_ERROR, "FdtSetpropU64() fail: %a\n", FdtStrerror (Err)));
      return EFI_INVALID_PARAMETER;
    }
  } else {
    DEBUG ((DEBUG_ERROR, "Failed to set fdt Property %a\n", PropertyName));
    return EFI_INVALID_PARAMETER;
  }

  return EFI_SUCCESS;
}

EFI_STATUS
AndroidBootImgUpdateFdt (
  IN  VOID   *BootImg,
  IN  VOID   *FdtBase,
  IN  VOID   *RamdiskData,
  IN  UINTN  RamdiskSize
  )
{
  INTN                  ChosenNode, Err, NewFdtSize;
  EFI_STATUS            Status;
  EFI_PHYSICAL_ADDRESS  UpdatedFdtBase, NewFdtBase;

  NewFdtSize = (UINTN)FdtTotalSize (FdtBase)
               + FDT_ADDITIONAL_ENTRIES_SIZE;
  Status = gBS->AllocatePages (
                  AllocateAnyPages,
                  EfiBootServicesData,
                  EFI_SIZE_TO_PAGES (NewFdtSize),
                  &UpdatedFdtBase
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((
      DEBUG_WARN,
      "Warning: Failed to reallocate FDT, err %d.\n",
      Status
      ));
    return Status;
  }

  // Load the Original FDT tree into the new region
  Err = FdtOpenInto (FdtBase, (VOID *)(INTN)UpdatedFdtBase, NewFdtSize);
  if (Err) {
    DEBUG ((DEBUG_ERROR, "FdtOpenInto(): %a\n", FdtStrerror (Err)));
    Status = EFI_INVALID_PARAMETER;
    goto Fdt_Exit;
  }

  if (FeaturePcdGet (PcdAndroidBootLoadFile2)) {
    Status = AndroidBootImgInstallLoadFile2 (RamdiskData, RamdiskSize);
    if (EFI_ERROR (Status)) {
      goto Fdt_Exit;
    }
  } else {
    ChosenNode = AndroidBootImgGetChosenNode (UpdatedFdtBase);
    if (!ChosenNode) {
      goto Fdt_Exit;
    }

    Status = AndroidBootImgSetProperty64 (
               UpdatedFdtBase,
               ChosenNode,
               "linux,initrd-start",
               (UINTN)RamdiskData
               );
    if (EFI_ERROR (Status)) {
      goto Fdt_Exit;
    }

    Status = AndroidBootImgSetProperty64 (
               UpdatedFdtBase,
               ChosenNode,
               "linux,initrd-end",
               (UINTN)RamdiskData + RamdiskSize
               );
    if (EFI_ERROR (Status)) {
      goto Fdt_Exit;
    }
  }

  if (mAndroidBootImg->UpdateDtb) {
    Status = mAndroidBootImg->UpdateDtb (UpdatedFdtBase, &NewFdtBase);
    if (EFI_ERROR (Status)) {
      goto Fdt_Exit;
    }
  } else {
    NewFdtBase = UpdatedFdtBase;
  }

  Status = gBS->InstallConfigurationTable (
                  &gFdtTableGuid,
                  (VOID *)(UINTN)NewFdtBase
                  );

  if (!EFI_ERROR (Status)) {
    return EFI_SUCCESS;
  }

Fdt_Exit:
  gBS->FreePages (UpdatedFdtBase, EFI_SIZE_TO_PAGES (NewFdtSize));
  return Status;
}

EFI_STATUS
AndroidBootImgBoot (
  IN VOID   *Buffer,
  IN UINTN  BufferSize
  )
{
  EFI_STATUS                 Status;
  VOID                       *Kernel;
  UINTN                      KernelSize;
  MEMORY_DEVICE_PATH         KernelDevicePath;
  EFI_HANDLE                 ImageHandle;
  VOID                       *NewKernelArg;
  EFI_LOADED_IMAGE_PROTOCOL  *ImageInfo;
  VOID                       *RamdiskData;
  UINTN                      RamdiskSize;
  IN  VOID                   *FdtBase;

  if ((Buffer == NULL) || (BufferSize == 0)) {
    return EFI_INVALID_PARAMETER;
  }

  NewKernelArg = NULL;
  ImageHandle  = NULL;

  Status = gBS->LocateProtocol (
                  &gAndroidBootImgProtocolGuid,
                  NULL,
                  (VOID **)&mAndroidBootImg
                  );
  if (EFI_ERROR (Status)) {
    goto Exit;
  }

  Status = AndroidBootImgGetKernelInfo (
             Buffer,
             &Kernel,
             &KernelSize
             );
  if (EFI_ERROR (Status)) {
    goto Exit;
  }

  Status = AndroidBootImgUpdateArgs (Buffer, &NewKernelArg);
  if (EFI_ERROR (Status)) {
    goto Exit;
  }

  Status = AndroidBootImgGetRamdiskInfo (
             Buffer,
             &RamdiskData,
             &RamdiskSize
             );
  if (EFI_ERROR (Status)) {
    goto Exit;
  }

  if (AndroidBootImgAcpiSupported ()) {
    Status = AndroidBootImgInstallLoadFile2 (RamdiskData, RamdiskSize);
    if (EFI_ERROR (Status)) {
      goto Exit;
    }
  } else {
    Status = AndroidBootImgLocateFdt (Buffer, &FdtBase);
    if (EFI_ERROR (Status)) {
      goto Exit;
    }

    Status = AndroidBootImgUpdateFdt (Buffer, FdtBase, RamdiskData, RamdiskSize);
    if (EFI_ERROR (Status)) {
      goto Exit;
    }
  }

  KernelDevicePath = mMemoryDevicePathTemplate;

  KernelDevicePath.Node1.StartingAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Kernel;
  KernelDevicePath.Node1.EndingAddress   = (EFI_PHYSICAL_ADDRESS)(UINTN)Kernel
                                           + KernelSize;

  Status = gBS->LoadImage (
                  TRUE,
                  gImageHandle,
                  (EFI_DEVICE_PATH *)&KernelDevicePath,
                  (VOID *)(UINTN)Kernel,
                  KernelSize,
                  &ImageHandle
                  );
  if (EFI_ERROR (Status)) {
    goto Exit;
  }

  // Set kernel arguments
  Status = gBS->HandleProtocol (
                  ImageHandle,
                  &gEfiLoadedImageProtocolGuid,
                  (VOID **)&ImageInfo
                  );
  if (EFI_ERROR (Status)) {
    goto Exit;
  }

  ImageInfo->LoadOptions     = NewKernelArg;
  ImageInfo->LoadOptionsSize = StrLen (NewKernelArg) * sizeof (CHAR16);

  // Before calling the image, enable the Watchdog Timer for  the 5 Minute period
  gBS->SetWatchdogTimer (5 * 60, 0x10000, 0, NULL);
  // Start the image
  Status = gBS->StartImage (ImageHandle, NULL, NULL);
  // Clear the Watchdog Timer if the image returns
  gBS->SetWatchdogTimer (0, 0x10000, 0, NULL);

Exit:
  // Unload image as it will not be used anymore
  if (ImageHandle != NULL) {
    gBS->UnloadImage (ImageHandle);
    ImageHandle = NULL;
  }

  if (EFI_ERROR (Status)) {
    if (NewKernelArg != NULL) {
      FreePool (NewKernelArg);
      NewKernelArg = NULL;
    }
  }

  AndroidBootImgUninstallLoadFile2 ();
  return Status;
}
