/**  @file
  Generic implementation of QemuLoadImageLib library class interface.

  Copyright (c) 2020, ARM Ltd. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent
**/

#include <Uefi.h>

#include <Base.h>
#include <Guid/QemuKernelLoaderFsMedia.h>
#include <Library/DebugLib.h>
#include <Library/FileHandleLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PrintLib.h>
#include <Library/QemuLoadImageLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Protocol/DevicePath.h>
#include <Protocol/LoadedImage.h>
#include <Protocol/SimpleFileSystem.h>

#pragma pack (1)
typedef struct {
  EFI_DEVICE_PATH_PROTOCOL    FilePathHeader;
  CHAR16                      FilePath[ARRAY_SIZE (L"kernel")];
} KERNEL_FILE_DEVPATH;

typedef struct {
  VENDOR_DEVICE_PATH          VenMediaNode;
  KERNEL_FILE_DEVPATH         FileNode;
  EFI_DEVICE_PATH_PROTOCOL    EndNode;
} KERNEL_VENMEDIA_FILE_DEVPATH;

typedef struct {
  VENDOR_DEVICE_PATH          VenMediaNode;
  EFI_DEVICE_PATH_PROTOCOL    EndNode;
} SINGLE_VENMEDIA_NODE_DEVPATH;
#pragma pack ()

STATIC CONST KERNEL_VENMEDIA_FILE_DEVPATH  mKernelDevicePath = {
  {
    {
      MEDIA_DEVICE_PATH, MEDIA_VENDOR_DP,
      { sizeof (VENDOR_DEVICE_PATH)       }
    },
    QEMU_KERNEL_LOADER_FS_MEDIA_GUID
  },  {
    {
      MEDIA_DEVICE_PATH, MEDIA_FILEPATH_DP,
      { sizeof (KERNEL_FILE_DEVPATH)      }
    },
    L"kernel",
  },  {
    END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE,
    { sizeof (EFI_DEVICE_PATH_PROTOCOL) }
  }
};

STATIC CONST SINGLE_VENMEDIA_NODE_DEVPATH  mQemuKernelLoaderFsDevicePath = {
  {
    {
      MEDIA_DEVICE_PATH, MEDIA_VENDOR_DP,
      { sizeof (VENDOR_DEVICE_PATH)       }
    },
    QEMU_KERNEL_LOADER_FS_MEDIA_GUID
  },  {
    END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE,
    { sizeof (EFI_DEVICE_PATH_PROTOCOL) }
  }
};

STATIC
EFI_STATUS
GetQemuKernelLoaderBlobSize (
  IN  EFI_FILE_HANDLE  Root,
  IN  CHAR16           *FileName,
  OUT UINTN            *Size
  )
{
  EFI_STATUS       Status;
  EFI_FILE_HANDLE  FileHandle;
  UINT64           FileSize;

  Status = Root->Open (Root, &FileHandle, FileName, EFI_FILE_MODE_READ, 0);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = FileHandleGetSize (FileHandle, &FileSize);
  if (EFI_ERROR (Status)) {
    goto CloseFile;
  }

  if (FileSize > MAX_UINTN) {
    Status = EFI_UNSUPPORTED;
    goto CloseFile;
  }

  *Size  = (UINTN)FileSize;
  Status = EFI_SUCCESS;
CloseFile:
  FileHandle->Close (FileHandle);
  return Status;
}

STATIC
EFI_STATUS
ReadWholeQemuKernelLoaderBlob (
  IN  EFI_FILE_HANDLE  Root,
  IN  CHAR16           *FileName,
  IN  UINTN            Size,
  OUT VOID             *Buffer
  )
{
  EFI_STATUS       Status;
  EFI_FILE_HANDLE  FileHandle;
  UINTN            ReadSize;

  Status = Root->Open (Root, &FileHandle, FileName, EFI_FILE_MODE_READ, 0);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  ReadSize = Size;
  Status   = FileHandle->Read (FileHandle, &ReadSize, Buffer);
  if (EFI_ERROR (Status)) {
    goto CloseFile;
  }

  if (ReadSize != Size) {
    Status = EFI_PROTOCOL_ERROR;
    goto CloseFile;
  }

  Status = EFI_SUCCESS;
CloseFile:
  FileHandle->Close (FileHandle);
  return Status;
}

/**
  Download the kernel, the initial ramdisk, and the kernel command line from
  QEMU's fw_cfg. The kernel will be instructed via its command line to load
  the initrd from the same Simple FileSystem where the kernel was loaded from.

  @param[out] ImageHandle       The image handle that was allocated for
                                loading the image

  @retval EFI_SUCCESS           The image was loaded successfully.
  @retval EFI_NOT_FOUND         Kernel image was not found.
  @retval EFI_OUT_OF_RESOURCES  Memory allocation failed.
  @retval EFI_PROTOCOL_ERROR    Unterminated kernel command line.
  @retval EFI_ACCESS_DENIED     The underlying LoadImage boot service call
                                returned EFI_SECURITY_VIOLATION, and the image
                                was unloaded again.

  @return                       Error codes from any of the underlying
                                functions.
**/
EFI_STATUS
EFIAPI
QemuLoadKernelImage (
  OUT EFI_HANDLE  *ImageHandle
  )
{
  EFI_STATUS                       Status;
  EFI_HANDLE                       KernelImageHandle;
  EFI_LOADED_IMAGE_PROTOCOL        *KernelLoadedImage;
  EFI_DEVICE_PATH_PROTOCOL         *DevicePathNode;
  EFI_HANDLE                       FsVolumeHandle;
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL  *FsProtocol;
  EFI_FILE_HANDLE                  Root;
  UINTN                            CommandLineSize;
  CHAR8                            *CommandLine;
  UINTN                            InitrdSize;

  //
  // Load the image. This should call back into the QEMU EFI loader file system.
  //
  Status = gBS->LoadImage (
                  FALSE,                    // BootPolicy: exact match required
                  gImageHandle,             // ParentImageHandle
                  (EFI_DEVICE_PATH_PROTOCOL *)&mKernelDevicePath,
                  NULL,                     // SourceBuffer
                  0,                        // SourceSize
                  &KernelImageHandle
                  );
  switch (Status) {
    case EFI_SUCCESS:
      break;

    case EFI_SECURITY_VIOLATION:
      //
      // In this case, the image was loaded but failed to authenticate.
      //
      Status = EFI_ACCESS_DENIED;
      goto UnloadImage;

    default:
      DEBUG ((
        Status == EFI_NOT_FOUND ? DEBUG_INFO : DEBUG_ERROR,
        "%a: LoadImage(): %r\n",
        __FUNCTION__,
        Status
        ));
      return Status;
  }

  //
  // Construct the kernel command line.
  //
  Status = gBS->OpenProtocol (
                  KernelImageHandle,
                  &gEfiLoadedImageProtocolGuid,
                  (VOID **)&KernelLoadedImage,
                  gImageHandle,                  // AgentHandle
                  NULL,                          // ControllerHandle
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  ASSERT_EFI_ERROR (Status);

  //
  // Open the Qemu Kernel Loader abstract filesystem (volume) which will be
  // used to query the "initrd" and to read the "cmdline" synthetic files.
  //
  DevicePathNode = (EFI_DEVICE_PATH_PROTOCOL *)&mQemuKernelLoaderFsDevicePath;
  Status         = gBS->LocateDevicePath (
                          &gEfiSimpleFileSystemProtocolGuid,
                          &DevicePathNode,
                          &FsVolumeHandle
                          );
  if (EFI_ERROR (Status)) {
    goto UnloadImage;
  }

  Status = gBS->HandleProtocol (
                  FsVolumeHandle,
                  &gEfiSimpleFileSystemProtocolGuid,
                  (VOID **)&FsProtocol
                  );
  if (EFI_ERROR (Status)) {
    goto UnloadImage;
  }

  Status = FsProtocol->OpenVolume (FsVolumeHandle, &Root);
  if (EFI_ERROR (Status)) {
    goto UnloadImage;
  }

  Status = GetQemuKernelLoaderBlobSize (Root, L"cmdline", &CommandLineSize);
  if (EFI_ERROR (Status)) {
    goto CloseRoot;
  }

  if (CommandLineSize == 0) {
    KernelLoadedImage->LoadOptionsSize = 0;
  } else {
    CommandLine = AllocatePool (CommandLineSize);
    if (CommandLine == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto CloseRoot;
    }

    Status = ReadWholeQemuKernelLoaderBlob (
               Root,
               L"cmdline",
               CommandLineSize,
               CommandLine
               );
    if (EFI_ERROR (Status)) {
      goto FreeCommandLine;
    }

    //
    // Verify NUL-termination of the command line.
    //
    if (CommandLine[CommandLineSize - 1] != '\0') {
      DEBUG ((
        DEBUG_ERROR,
        "%a: kernel command line is not NUL-terminated\n",
        __FUNCTION__
        ));
      Status = EFI_PROTOCOL_ERROR;
      goto FreeCommandLine;
    }

    //
    // Drop the terminating NUL, convert to UTF-16.
    //
    KernelLoadedImage->LoadOptionsSize = (UINT32)((CommandLineSize - 1) * 2);
  }

  Status = GetQemuKernelLoaderBlobSize (Root, L"initrd", &InitrdSize);
  if (EFI_ERROR (Status)) {
    goto FreeCommandLine;
  }

  if (InitrdSize > 0) {
    //
    // Append ' initrd=initrd' in UTF-16.
    //
    KernelLoadedImage->LoadOptionsSize += sizeof (L" initrd=initrd") - 2;
  }

  if (KernelLoadedImage->LoadOptionsSize == 0) {
    KernelLoadedImage->LoadOptions = NULL;
  } else {
    //
    // NUL-terminate in UTF-16.
    //
    KernelLoadedImage->LoadOptionsSize += 2;

    KernelLoadedImage->LoadOptions = AllocatePool (
                                       KernelLoadedImage->LoadOptionsSize
                                       );
    if (KernelLoadedImage->LoadOptions == NULL) {
      KernelLoadedImage->LoadOptionsSize = 0;
      Status                             = EFI_OUT_OF_RESOURCES;
      goto FreeCommandLine;
    }

    UnicodeSPrintAsciiFormat (
      KernelLoadedImage->LoadOptions,
      KernelLoadedImage->LoadOptionsSize,
      "%a%a",
      (CommandLineSize == 0) ?  "" : CommandLine,
      (InitrdSize == 0)      ?  "" : " initrd=initrd"
      );
    DEBUG ((
      DEBUG_INFO,
      "%a: command line: \"%s\"\n",
      __FUNCTION__,
      (CHAR16 *)KernelLoadedImage->LoadOptions
      ));
  }

  *ImageHandle = KernelImageHandle;
  Status       = EFI_SUCCESS;

FreeCommandLine:
  if (CommandLineSize > 0) {
    FreePool (CommandLine);
  }

CloseRoot:
  Root->Close (Root);
UnloadImage:
  if (EFI_ERROR (Status)) {
    gBS->UnloadImage (KernelImageHandle);
  }

  return Status;
}

/**
  Transfer control to a kernel image loaded with QemuLoadKernelImage ()

  @param[in,out]  ImageHandle     Handle of image to be started. May assume a
                                  different value on return if the image was
                                  reloaded.

  @retval EFI_INVALID_PARAMETER   ImageHandle is either an invalid image handle
                                  or the image has already been initialized with
                                  StartImage
  @retval EFI_SECURITY_VIOLATION  The current platform policy specifies that the
                                  image should not be started.

  @return                         Error codes returned by the started image
**/
EFI_STATUS
EFIAPI
QemuStartKernelImage (
  IN  OUT EFI_HANDLE  *ImageHandle
  )
{
  return gBS->StartImage (
                *ImageHandle,
                NULL,              // ExitDataSize
                NULL               // ExitData
                );
}

/**
  Unloads an image loaded with QemuLoadKernelImage ().

  @param  ImageHandle             Handle that identifies the image to be
                                  unloaded.

  @retval EFI_SUCCESS             The image has been unloaded.
  @retval EFI_UNSUPPORTED         The image has been started, and does not
                                  support unload.
  @retval EFI_INVALID_PARAMETER   ImageHandle is not a valid image handle.

  @return                         Exit code from the image's unload function.
**/
EFI_STATUS
EFIAPI
QemuUnloadKernelImage (
  IN  EFI_HANDLE  ImageHandle
  )
{
  EFI_LOADED_IMAGE_PROTOCOL  *KernelLoadedImage;
  EFI_STATUS                 Status;

  Status = gBS->OpenProtocol (
                  ImageHandle,
                  &gEfiLoadedImageProtocolGuid,
                  (VOID **)&KernelLoadedImage,
                  gImageHandle,                  // AgentHandle
                  NULL,                          // ControllerHandle
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    return EFI_INVALID_PARAMETER;
  }

  if (KernelLoadedImage->LoadOptions != NULL) {
    FreePool (KernelLoadedImage->LoadOptions);
    KernelLoadedImage->LoadOptions = NULL;
  }

  KernelLoadedImage->LoadOptionsSize = 0;

  return gBS->UnloadImage (ImageHandle);
}
