/**  @file
  X86 specific implementation of QemuLoadImageLib library class interface
  with support for loading mixed mode images and non-EFI stub images

  Note that this implementation reads the cmdline (and possibly kernel, setup
  data, and initrd in the legacy boot mode) from fw_cfg directly.

  Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
  Copyright (c) 2020, ARM Ltd. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent
**/

#include <Uefi.h>

#include <Guid/QemuKernelLoaderFsMedia.h>
#include <Library/DebugLib.h>
#include <Library/LoadLinuxLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PrintLib.h>
#include <Library/QemuFwCfgLib.h>
#include <Library/QemuLoadImageLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Protocol/DevicePath.h>
#include <Protocol/LoadedImage.h>
#include <Protocol/OvmfLoadedX86LinuxKernel.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;
#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
VOID
FreeLegacyImage (
  IN  OVMF_LOADED_X86_LINUX_KERNEL  *LoadedImage
  )
{
  if (LoadedImage->SetupBuf != NULL) {
    FreePages (
      LoadedImage->SetupBuf,
      EFI_SIZE_TO_PAGES (LoadedImage->SetupSize)
      );
  }

  if (LoadedImage->KernelBuf != NULL) {
    FreePages (
      LoadedImage->KernelBuf,
      EFI_SIZE_TO_PAGES (LoadedImage->KernelInitialSize)
      );
  }

  if (LoadedImage->CommandLine != NULL) {
    FreePages (
      LoadedImage->CommandLine,
      EFI_SIZE_TO_PAGES (LoadedImage->CommandLineSize)
      );
  }

  if (LoadedImage->InitrdData != NULL) {
    FreePages (
      LoadedImage->InitrdData,
      EFI_SIZE_TO_PAGES (LoadedImage->InitrdSize)
      );
  }
}

STATIC
EFI_STATUS
QemuLoadLegacyImage (
  OUT EFI_HANDLE  *ImageHandle
  )
{
  EFI_STATUS                    Status;
  UINTN                         KernelSize;
  UINTN                         SetupSize;
  OVMF_LOADED_X86_LINUX_KERNEL  *LoadedImage;

  QemuFwCfgSelectItem (QemuFwCfgItemKernelSize);
  KernelSize = (UINTN)QemuFwCfgRead32 ();

  QemuFwCfgSelectItem (QemuFwCfgItemKernelSetupSize);
  SetupSize = (UINTN)QemuFwCfgRead32 ();

  if ((KernelSize == 0) || (SetupSize == 0)) {
    DEBUG ((DEBUG_INFO, "qemu -kernel was not used.\n"));
    return EFI_NOT_FOUND;
  }

  LoadedImage = AllocateZeroPool (sizeof (*LoadedImage));
  if (LoadedImage == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  LoadedImage->SetupSize = SetupSize;
  LoadedImage->SetupBuf  = LoadLinuxAllocateKernelSetupPages (
                             EFI_SIZE_TO_PAGES (LoadedImage->SetupSize)
                             );
  if (LoadedImage->SetupBuf == NULL) {
    DEBUG ((DEBUG_ERROR, "Unable to allocate memory for kernel setup!\n"));
    Status = EFI_OUT_OF_RESOURCES;
    goto FreeImageDesc;
  }

  DEBUG ((DEBUG_INFO, "Setup size: 0x%x\n", (UINT32)LoadedImage->SetupSize));
  DEBUG ((DEBUG_INFO, "Reading kernel setup image ..."));
  QemuFwCfgSelectItem (QemuFwCfgItemKernelSetupData);
  QemuFwCfgReadBytes (LoadedImage->SetupSize, LoadedImage->SetupBuf);
  DEBUG ((DEBUG_INFO, " [done]\n"));

  Status = LoadLinuxCheckKernelSetup (
             LoadedImage->SetupBuf,
             LoadedImage->SetupSize
             );
  if (EFI_ERROR (Status)) {
    goto FreeImage;
  }

  Status = LoadLinuxInitializeKernelSetup (LoadedImage->SetupBuf);
  if (EFI_ERROR (Status)) {
    goto FreeImage;
  }

  LoadedImage->KernelInitialSize = LoadLinuxGetKernelSize (
                                     LoadedImage->SetupBuf,
                                     KernelSize
                                     );
  if (LoadedImage->KernelInitialSize == 0) {
    Status = EFI_UNSUPPORTED;
    goto FreeImage;
  }

  LoadedImage->KernelBuf = LoadLinuxAllocateKernelPages (
                             LoadedImage->SetupBuf,
                             EFI_SIZE_TO_PAGES (LoadedImage->KernelInitialSize)
                             );
  if (LoadedImage->KernelBuf == NULL) {
    DEBUG ((DEBUG_ERROR, "Unable to allocate memory for kernel!\n"));
    Status = EFI_OUT_OF_RESOURCES;
    goto FreeImage;
  }

  DEBUG ((DEBUG_INFO, "Kernel size: 0x%x\n", (UINT32)KernelSize));
  DEBUG ((DEBUG_INFO, "Reading kernel image ..."));
  QemuFwCfgSelectItem (QemuFwCfgItemKernelData);
  QemuFwCfgReadBytes (KernelSize, LoadedImage->KernelBuf);
  DEBUG ((DEBUG_INFO, " [done]\n"));

  QemuFwCfgSelectItem (QemuFwCfgItemCommandLineSize);
  LoadedImage->CommandLineSize = (UINTN)QemuFwCfgRead32 ();

  if (LoadedImage->CommandLineSize > 0) {
    LoadedImage->CommandLine = LoadLinuxAllocateCommandLinePages (
                                 EFI_SIZE_TO_PAGES (
                                   LoadedImage->CommandLineSize
                                   )
                                 );
    if (LoadedImage->CommandLine == NULL) {
      DEBUG ((DEBUG_ERROR, "Unable to allocate memory for kernel command line!\n"));
      Status = EFI_OUT_OF_RESOURCES;
      goto FreeImage;
    }

    QemuFwCfgSelectItem (QemuFwCfgItemCommandLineData);
    QemuFwCfgReadBytes (LoadedImage->CommandLineSize, LoadedImage->CommandLine);
  }

  Status = LoadLinuxSetCommandLine (
             LoadedImage->SetupBuf,
             LoadedImage->CommandLine
             );
  if (EFI_ERROR (Status)) {
    goto FreeImage;
  }

  QemuFwCfgSelectItem (QemuFwCfgItemInitrdSize);
  LoadedImage->InitrdSize = (UINTN)QemuFwCfgRead32 ();

  if (LoadedImage->InitrdSize > 0) {
    LoadedImage->InitrdData = LoadLinuxAllocateInitrdPages (
                                LoadedImage->SetupBuf,
                                EFI_SIZE_TO_PAGES (LoadedImage->InitrdSize)
                                );
    if (LoadedImage->InitrdData == NULL) {
      DEBUG ((DEBUG_ERROR, "Unable to allocate memory for initrd!\n"));
      Status = EFI_OUT_OF_RESOURCES;
      goto FreeImage;
    }

    DEBUG ((
      DEBUG_INFO,
      "Initrd size: 0x%x\n",
      (UINT32)LoadedImage->InitrdSize
      ));
    DEBUG ((DEBUG_INFO, "Reading initrd image ..."));
    QemuFwCfgSelectItem (QemuFwCfgItemInitrdData);
    QemuFwCfgReadBytes (LoadedImage->InitrdSize, LoadedImage->InitrdData);
    DEBUG ((DEBUG_INFO, " [done]\n"));
  }

  Status = LoadLinuxSetInitrd (
             LoadedImage->SetupBuf,
             LoadedImage->InitrdData,
             LoadedImage->InitrdSize
             );
  if (EFI_ERROR (Status)) {
    goto FreeImage;
  }

  *ImageHandle = NULL;
  Status       = gBS->InstallProtocolInterface (
                        ImageHandle,
                        &gOvmfLoadedX86LinuxKernelProtocolGuid,
                        EFI_NATIVE_INTERFACE,
                        LoadedImage
                        );
  if (EFI_ERROR (Status)) {
    goto FreeImage;
  }

  return EFI_SUCCESS;

FreeImage:
  FreeLegacyImage (LoadedImage);
FreeImageDesc:
  FreePool (LoadedImage);
  return Status;
}

STATIC
EFI_STATUS
QemuStartLegacyImage (
  IN  EFI_HANDLE  ImageHandle
  )
{
  EFI_STATUS                    Status;
  OVMF_LOADED_X86_LINUX_KERNEL  *LoadedImage;

  Status = gBS->OpenProtocol (
                  ImageHandle,
                  &gOvmfLoadedX86LinuxKernelProtocolGuid,
                  (VOID **)&LoadedImage,
                  gImageHandle,                  // AgentHandle
                  NULL,                          // ControllerHandle
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    return EFI_INVALID_PARAMETER;
  }

  return LoadLinux (LoadedImage->KernelBuf, LoadedImage->SetupBuf);
}

STATIC
EFI_STATUS
QemuUnloadLegacyImage (
  IN  EFI_HANDLE  ImageHandle
  )
{
  EFI_STATUS                    Status;
  OVMF_LOADED_X86_LINUX_KERNEL  *LoadedImage;

  Status = gBS->OpenProtocol (
                  ImageHandle,
                  &gOvmfLoadedX86LinuxKernelProtocolGuid,
                  (VOID **)&LoadedImage,
                  gImageHandle,                  // AgentHandle
                  NULL,                          // ControllerHandle
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    return EFI_INVALID_PARAMETER;
  }

  Status = gBS->UninstallProtocolInterface (
                  ImageHandle,
                  &gOvmfLoadedX86LinuxKernelProtocolGuid,
                  LoadedImage
                  );
  ASSERT_EFI_ERROR (Status);

  FreeLegacyImage (LoadedImage);
  FreePool (LoadedImage);
  return EFI_SUCCESS;
}

/**
  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.

  @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;
  UINTN                      CommandLineSize;
  CHAR8                      *CommandLine;
  UINTN                      InitrdSize;

  //
  // Redundant assignment to work around GCC48/GCC49 limitations.
  //
  CommandLine = NULL;

  //
  // 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_NOT_FOUND:
      //
      // The image does not exist - no -kernel image was supplied via the
      // command line so no point in invoking the legacy fallback
      //
      return EFI_NOT_FOUND;

    case EFI_SECURITY_VIOLATION:
      //
      // Since the image has been loaded, we need to unload it before proceeding
      // to the EFI_ACCESS_DENIED case below.
      //
      gBS->UnloadImage (KernelImageHandle);
    //
    // Fall through
    //
    case EFI_ACCESS_DENIED:
    //
    // We are running with UEFI secure boot enabled, and the image failed to
    // authenticate. For compatibility reasons, we fall back to the legacy
    // loader in this case.
    //
    // Fall through
    //
    case EFI_UNSUPPORTED:
      //
      // The image is not natively supported or cross-type supported. Let's try
      // loading it using the loader that parses the bzImage metadata directly.
      //
      Status = QemuLoadLegacyImage (&KernelImageHandle);
      if (EFI_ERROR (Status)) {
        DEBUG ((
          DEBUG_ERROR,
          "%a: QemuLoadLegacyImage(): %r\n",
          __func__,
          Status
          ));
        return Status;
      }

      *ImageHandle = KernelImageHandle;
      return EFI_SUCCESS;

    default:
      DEBUG ((DEBUG_ERROR, "%a: LoadImage(): %r\n", __func__, 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);

  QemuFwCfgSelectItem (QemuFwCfgItemCommandLineSize);
  CommandLineSize = (UINTN)QemuFwCfgRead32 ();

  if (CommandLineSize == 0) {
    KernelLoadedImage->LoadOptionsSize = 0;
  } else {
    CommandLine = AllocatePool (CommandLineSize);
    if (CommandLine == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto UnloadImage;
    }

    QemuFwCfgSelectItem (QemuFwCfgItemCommandLineData);
    QemuFwCfgReadBytes (CommandLineSize, CommandLine);

    //
    // Verify NUL-termination of the command line.
    //
    if (CommandLine[CommandLineSize - 1] != '\0') {
      DEBUG ((
        DEBUG_ERROR,
        "%a: kernel command line is not NUL-terminated\n",
        __func__
        ));
      Status = EFI_PROTOCOL_ERROR;
      goto FreeCommandLine;
    }

    //
    // Drop the terminating NUL, convert to UTF-16.
    //
    KernelLoadedImage->LoadOptionsSize = (UINT32)((CommandLineSize - 1) * 2);
  }

  QemuFwCfgSelectItem (QemuFwCfgItemInitrdSize);
  InitrdSize = (UINTN)QemuFwCfgRead32 ();

  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",
      __func__,
      (CHAR16 *)KernelLoadedImage->LoadOptions
      ));
  }

  *ImageHandle = KernelImageHandle;
  Status       = EFI_SUCCESS;

FreeCommandLine:
  if (CommandLineSize > 0) {
    FreePool (CommandLine);
  }

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
  )
{
  EFI_STATUS                    Status;
  OVMF_LOADED_X86_LINUX_KERNEL  *LoadedImage;

  Status = gBS->OpenProtocol (
                  *ImageHandle,
                  &gOvmfLoadedX86LinuxKernelProtocolGuid,
                  (VOID **)&LoadedImage,
                  gImageHandle,                  // AgentHandle
                  NULL,                          // ControllerHandle
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (!EFI_ERROR (Status)) {
    return QemuStartLegacyImage (*ImageHandle);
  }

  Status = gBS->StartImage (
                  *ImageHandle,
                  NULL,              // ExitDataSize
                  NULL               // ExitData
                  );
 #ifdef MDE_CPU_IA32
  if (Status == EFI_UNSUPPORTED) {
    EFI_HANDLE  KernelImageHandle;

    //
    // On IA32, EFI_UNSUPPORTED means that the image's machine type is X64 while
    // we are expecting a IA32 one, and the StartImage () boot service is unable
    // to handle it, either because the image does not have the special .compat
    // PE/COFF section that Linux specifies for mixed mode capable images, or
    // because we are running without the support code for that. So load the
    // image again, using the legacy loader, and unload the normally loaded
    // image before starting the legacy one.
    //
    Status = QemuLoadLegacyImage (&KernelImageHandle);
    if (EFI_ERROR (Status)) {
      //
      // Note: no change to (*ImageHandle), the caller will release it.
      //
      return Status;
    }

    //
    // Swap in the legacy-loaded image.
    //
    QemuUnloadKernelImage (*ImageHandle);
    *ImageHandle = KernelImageHandle;
    return QemuStartLegacyImage (KernelImageHandle);
  }

 #endif
  return Status;
}

/**
  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 (Status == EFI_UNSUPPORTED) {
    //
    // The handle exists but does not have an instance of the standard loaded
    // image protocol installed on it. Attempt to unload it as a legacy image
    // instead.
    //
    return QemuUnloadLegacyImage (ImageHandle);
  }

  if (EFI_ERROR (Status)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // We are unloading a normal, non-legacy loaded image, either on behalf of
  // an external caller, or called from QemuStartKernelImage() on IA32, while
  // switching from the normal to the legacy method to load and start a X64
  // image.
  //
  if (KernelLoadedImage->LoadOptions != NULL) {
    FreePool (KernelLoadedImage->LoadOptions);
    KernelLoadedImage->LoadOptions = NULL;
  }

  KernelLoadedImage->LoadOptionsSize = 0;

  return gBS->UnloadImage (ImageHandle);
}
