/** @file
  Try to load an EFI-stubbed ARM Linux kernel from QEMU's fw_cfg.

  This implementation differs from OvmfPkg/Library/LoadLinuxLib. An EFI
  stub in the subject kernel is a hard requirement here.

  Copyright (C) 2014-2016, Red Hat, Inc.

  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.
**/

#include <Guid/FileInfo.h>
#include <Guid/FileSystemInfo.h>
#include <Guid/FileSystemVolumeLabelInfo.h>
#include <Library/PrintLib.h>
#include <Library/QemuFwCfgLib.h>
#include <Protocol/DevicePath.h>
#include <Protocol/LoadedImage.h>
#include <Protocol/SimpleFileSystem.h>

#include "PlatformBm.h"

//
// Static data that hosts the fw_cfg blobs and serves file requests.
//
typedef enum {
  KernelBlobTypeKernel,
  KernelBlobTypeInitrd,
  KernelBlobTypeCommandLine,
  KernelBlobTypeMax
} KERNEL_BLOB_TYPE;

typedef struct {
  FIRMWARE_CONFIG_ITEM CONST SizeKey;
  FIRMWARE_CONFIG_ITEM CONST DataKey;
  CONST CHAR16 *       CONST Name;
  UINT32                     Size;
  UINT8                      *Data;
} KERNEL_BLOB;

STATIC KERNEL_BLOB mKernelBlob[KernelBlobTypeMax] = {
  { QemuFwCfgItemKernelSize,      QemuFwCfgItemKernelData,      L"kernel"  },
  { QemuFwCfgItemInitrdSize,      QemuFwCfgItemInitrdData,      L"initrd"  },
  { QemuFwCfgItemCommandLineSize, QemuFwCfgItemCommandLineData, L"cmdline" }
};

STATIC UINT64 mTotalBlobBytes;

//
// Device path for the handle that incorporates our "EFI stub filesystem". The
// GUID is arbitrary and need not be standardized or advertized.
//
#pragma pack(1)
typedef struct {
  VENDOR_DEVICE_PATH       VenHwNode;
  EFI_DEVICE_PATH_PROTOCOL EndNode;
} SINGLE_VENHW_NODE_DEVPATH;
#pragma pack()

STATIC CONST SINGLE_VENHW_NODE_DEVPATH mFileSystemDevicePath = {
  {
    { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, { sizeof (VENDOR_DEVICE_PATH) } },
    {
      0xb0fae7e7, 0x6b07, 0x49d0,
      { 0x9e, 0x5b, 0x3b, 0xde, 0xc8, 0x3b, 0x03, 0x9d }
    }
  },

  {
    END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE,
    { sizeof (EFI_DEVICE_PATH_PROTOCOL) }
  }
};

//
// The "file in the EFI stub filesystem" abstraction.
//
STATIC EFI_TIME mInitTime;

#define STUB_FILE_SIG SIGNATURE_64 ('S', 'T', 'U', 'B', 'F', 'I', 'L', 'E')

typedef struct {
  UINT64            Signature; // Carries STUB_FILE_SIG.

  KERNEL_BLOB_TYPE  BlobType;  // Index into mKernelBlob. KernelBlobTypeMax
                               // denotes the root directory of the filesystem.

  UINT64            Position;  // Byte position for regular files;
                               // next directory entry to return for the root
                               // directory.

  EFI_FILE_PROTOCOL File;      // Standard protocol interface.
} STUB_FILE;

#define STUB_FILE_FROM_FILE(FilePointer) \
        CR (FilePointer, STUB_FILE, File, STUB_FILE_SIG)

//
// Tentative definition of the file protocol template. The initializer
// (external definition) will be provided later.
//
STATIC CONST EFI_FILE_PROTOCOL mEfiFileProtocolTemplate;


//
// Protocol member functions for File.
//

/**
  Opens a new file relative to the source file's location.

  @param[in]  This        A pointer to the EFI_FILE_PROTOCOL instance that is
                          the file handle to the source location. This would
                          typically be an open handle to a directory.

  @param[out] NewHandle   A pointer to the location to return the opened handle
                          for the new file.

  @param[in]  FileName    The Null-terminated string of the name of the file to
                          be opened. The file name may contain the following
                          path modifiers: "\", ".", and "..".

  @param[in]  OpenMode    The mode to open the file. The only valid
                          combinations that the file may be opened with are:
                          Read, Read/Write, or Create/Read/Write.

  @param[in]  Attributes  Only valid for EFI_FILE_MODE_CREATE, in which case
                          these are the attribute bits for the newly created
                          file.

  @retval EFI_SUCCESS           The file was opened.
  @retval EFI_NOT_FOUND         The specified file could not be found on the
                                device.
  @retval EFI_NO_MEDIA          The device has no medium.
  @retval EFI_MEDIA_CHANGED     The device has a different medium in it or the
                                medium is no longer supported.
  @retval EFI_DEVICE_ERROR      The device reported an error.
  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.
  @retval EFI_WRITE_PROTECTED   An attempt was made to create a file, or open a
                                file for write when the media is
                                write-protected.
  @retval EFI_ACCESS_DENIED     The service denied access to the file.
  @retval EFI_OUT_OF_RESOURCES  Not enough resources were available to open the
                                file.
  @retval EFI_VOLUME_FULL       The volume is full.
**/
STATIC
EFI_STATUS
EFIAPI
StubFileOpen (
  IN EFI_FILE_PROTOCOL  *This,
  OUT EFI_FILE_PROTOCOL **NewHandle,
  IN CHAR16             *FileName,
  IN UINT64             OpenMode,
  IN UINT64             Attributes
  )
{
  CONST STUB_FILE *StubFile;
  UINTN           BlobType;
  STUB_FILE       *NewStubFile;

  //
  // We're read-only.
  //
  switch (OpenMode) {
    case EFI_FILE_MODE_READ:
      break;

    case EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE:
    case EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE:
      return EFI_WRITE_PROTECTED;

    default:
      return EFI_INVALID_PARAMETER;
  }

  //
  // Only the root directory supports opening files in it.
  //
  StubFile = STUB_FILE_FROM_FILE (This);
  if (StubFile->BlobType != KernelBlobTypeMax) {
    return EFI_UNSUPPORTED;
  }

  //
  // Locate the file.
  //
  for (BlobType = 0; BlobType < KernelBlobTypeMax; ++BlobType) {
    if (StrCmp (FileName, mKernelBlob[BlobType].Name) == 0) {
      break;
    }
  }
  if (BlobType == KernelBlobTypeMax) {
    return EFI_NOT_FOUND;
  }

  //
  // Found it.
  //
  NewStubFile = AllocatePool (sizeof *NewStubFile);
  if (NewStubFile == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  NewStubFile->Signature = STUB_FILE_SIG;
  NewStubFile->BlobType  = (KERNEL_BLOB_TYPE)BlobType;
  NewStubFile->Position  = 0;
  CopyMem (&NewStubFile->File, &mEfiFileProtocolTemplate,
    sizeof mEfiFileProtocolTemplate);
  *NewHandle = &NewStubFile->File;

  return EFI_SUCCESS;
}


/**
  Closes a specified file handle.

  @param[in] This  A pointer to the EFI_FILE_PROTOCOL instance that is the file
                   handle to close.

  @retval EFI_SUCCESS  The file was closed.
**/
STATIC
EFI_STATUS
EFIAPI
StubFileClose (
  IN EFI_FILE_PROTOCOL *This
  )
{
  FreePool (STUB_FILE_FROM_FILE (This));
  return EFI_SUCCESS;
}


/**
  Close and delete the file handle.

  @param[in] This  A pointer to the EFI_FILE_PROTOCOL instance that is the
                   handle to the file to delete.

  @retval EFI_SUCCESS              The file was closed and deleted, and the
                                   handle was closed.
  @retval EFI_WARN_DELETE_FAILURE  The handle was closed, but the file was not
                                   deleted.

**/
STATIC
EFI_STATUS
EFIAPI
StubFileDelete (
  IN EFI_FILE_PROTOCOL *This
  )
{
  FreePool (STUB_FILE_FROM_FILE (This));
  return EFI_WARN_DELETE_FAILURE;
}


/**
  Helper function that formats an EFI_FILE_INFO structure into the
  user-allocated buffer, for any valid KERNEL_BLOB_TYPE value (including
  KernelBlobTypeMax, which stands for the root directory).

  The interface follows the EFI_FILE_GET_INFO -- and for directories, the
  EFI_FILE_READ -- interfaces.

  @param[in]     BlobType     The KERNEL_BLOB_TYPE value identifying the fw_cfg
                              blob backing the STUB_FILE that information is
                              being requested about. If BlobType equals
                              KernelBlobTypeMax, then information will be
                              provided about the root directory of the
                              filesystem.

  @param[in,out] BufferSize  On input, the size of Buffer. On output, the
                             amount of data returned in Buffer. In both cases,
                             the size is measured in bytes.

  @param[out]    Buffer      A pointer to the data buffer to return. The
                             buffer's type is EFI_FILE_INFO.

  @retval EFI_SUCCESS           The information was returned.
  @retval EFI_BUFFER_TOO_SMALL  BufferSize is too small to store the
                                EFI_FILE_INFO structure. BufferSize has been
                                updated with the size needed to complete the
                                request.
**/
STATIC
EFI_STATUS
ConvertKernelBlobTypeToFileInfo (
  IN KERNEL_BLOB_TYPE BlobType,
  IN OUT UINTN        *BufferSize,
  OUT VOID            *Buffer
  )
{
  CONST CHAR16  *Name;
  UINT64        FileSize;
  UINT64        Attribute;

  UINTN         NameSize;
  UINTN         FileInfoSize;
  EFI_FILE_INFO *FileInfo;
  UINTN         OriginalBufferSize;

  if (BlobType == KernelBlobTypeMax) {
    //
    // getting file info about the root directory
    //
    Name      = L"\\";
    FileSize  = KernelBlobTypeMax;
    Attribute = EFI_FILE_READ_ONLY | EFI_FILE_DIRECTORY;
  } else {
    CONST KERNEL_BLOB *Blob;

    Blob      = &mKernelBlob[BlobType];
    Name      = Blob->Name;
    FileSize  = Blob->Size;
    Attribute = EFI_FILE_READ_ONLY;
  }

  NameSize     = (StrLen(Name) + 1) * 2;
  FileInfoSize = OFFSET_OF (EFI_FILE_INFO, FileName) + NameSize;
  ASSERT (FileInfoSize >= sizeof *FileInfo);

  OriginalBufferSize = *BufferSize;
  *BufferSize        = FileInfoSize;
  if (OriginalBufferSize < *BufferSize) {
    return EFI_BUFFER_TOO_SMALL;
  }

  FileInfo               = (EFI_FILE_INFO *)Buffer;
  FileInfo->Size         = FileInfoSize;
  FileInfo->FileSize     = FileSize;
  FileInfo->PhysicalSize = FileSize;
  FileInfo->Attribute    = Attribute;

  CopyMem (&FileInfo->CreateTime,       &mInitTime, sizeof mInitTime);
  CopyMem (&FileInfo->LastAccessTime,   &mInitTime, sizeof mInitTime);
  CopyMem (&FileInfo->ModificationTime, &mInitTime, sizeof mInitTime);
  CopyMem (FileInfo->FileName,          Name,       NameSize);

  return EFI_SUCCESS;
}


/**
  Reads data from a file, or continues scanning a directory.

  @param[in]     This        A pointer to the EFI_FILE_PROTOCOL instance that
                             is the file handle to read data from.

  @param[in,out] BufferSize  On input, the size of the Buffer. On output, the
                             amount of data returned in Buffer. In both cases,
                             the size is measured in bytes. If the read goes
                             beyond the end of the file, the read length is
                             truncated to the end of the file.

                             If This is a directory, the function reads the
                             directory entry at the current position and
                             returns the entry (as EFI_FILE_INFO) in Buffer. If
                             there are no more directory entries, the
                             BufferSize is set to zero on output.

  @param[out]    Buffer      The buffer into which the data is read.

  @retval EFI_SUCCESS           Data was read.
  @retval EFI_NO_MEDIA          The device has no medium.
  @retval EFI_DEVICE_ERROR      The device reported an error.
  @retval EFI_DEVICE_ERROR      An attempt was made to read from a deleted
                                file.
  @retval EFI_DEVICE_ERROR      On entry, the current file position is beyond
                                the end of the file.
  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.
  @retval EFI_BUFFER_TOO_SMALL  The BufferSize is too small to store the
                                current directory entry as a EFI_FILE_INFO
                                structure. BufferSize has been updated with the
                                size needed to complete the request, and the
                                directory position has not been advanced.
**/
STATIC
EFI_STATUS
EFIAPI
StubFileRead (
  IN EFI_FILE_PROTOCOL *This,
  IN OUT UINTN         *BufferSize,
  OUT VOID             *Buffer
  )
{
  STUB_FILE         *StubFile;
  CONST KERNEL_BLOB *Blob;
  UINT64            Left;

  StubFile = STUB_FILE_FROM_FILE (This);

  //
  // Scanning the root directory?
  //
  if (StubFile->BlobType == KernelBlobTypeMax) {
    EFI_STATUS Status;

    if (StubFile->Position == KernelBlobTypeMax) {
      //
      // Scanning complete.
      //
      *BufferSize = 0;
      return EFI_SUCCESS;
    }

    Status = ConvertKernelBlobTypeToFileInfo (
               (KERNEL_BLOB_TYPE)StubFile->Position,
               BufferSize,
               Buffer);
    if (EFI_ERROR (Status)) {
      return Status;
    }

    ++StubFile->Position;
    return EFI_SUCCESS;
  }

  //
  // Reading a file.
  //
  Blob = &mKernelBlob[StubFile->BlobType];
  if (StubFile->Position > Blob->Size) {
    return EFI_DEVICE_ERROR;
  }

  Left = Blob->Size - StubFile->Position;
  if (*BufferSize > Left) {
    *BufferSize = (UINTN)Left;
  }
  if (Blob->Data != NULL) {
    CopyMem (Buffer, Blob->Data + StubFile->Position, *BufferSize);
  }
  StubFile->Position += *BufferSize;
  return EFI_SUCCESS;
}


/**
  Writes data to a file.

  @param[in]     This        A pointer to the EFI_FILE_PROTOCOL instance that
                             is the file handle to write data to.

  @param[in,out] BufferSize  On input, the size of the Buffer. On output, the
                             amount of data actually written. In both cases,
                             the size is measured in bytes.

  @param[in]     Buffer      The buffer of data to write.

  @retval EFI_SUCCESS           Data was written.
  @retval EFI_UNSUPPORTED       Writes to open directory files are not
                                supported.
  @retval EFI_NO_MEDIA          The device has no medium.
  @retval EFI_DEVICE_ERROR      The device reported an error.
  @retval EFI_DEVICE_ERROR      An attempt was made to write to a deleted file.
  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.
  @retval EFI_WRITE_PROTECTED   The file or medium is write-protected.
  @retval EFI_ACCESS_DENIED     The file was opened read only.
  @retval EFI_VOLUME_FULL       The volume is full.
**/
STATIC
EFI_STATUS
EFIAPI
StubFileWrite (
  IN EFI_FILE_PROTOCOL *This,
  IN OUT UINTN         *BufferSize,
  IN VOID              *Buffer
  )
{
  STUB_FILE *StubFile;

  StubFile = STUB_FILE_FROM_FILE (This);
  return (StubFile->BlobType == KernelBlobTypeMax) ?
         EFI_UNSUPPORTED :
         EFI_WRITE_PROTECTED;
}


/**
  Returns a file's current position.

  @param[in]  This      A pointer to the EFI_FILE_PROTOCOL instance that is the
                        file handle to get the current position on.

  @param[out] Position  The address to return the file's current position
                        value.

  @retval EFI_SUCCESS      The position was returned.
  @retval EFI_UNSUPPORTED  The request is not valid on open directories.
  @retval EFI_DEVICE_ERROR An attempt was made to get the position from a
                           deleted file.
**/
STATIC
EFI_STATUS
EFIAPI
StubFileGetPosition (
  IN EFI_FILE_PROTOCOL *This,
  OUT UINT64           *Position
  )
{
  STUB_FILE *StubFile;

  StubFile = STUB_FILE_FROM_FILE (This);
  if (StubFile->BlobType == KernelBlobTypeMax) {
    return EFI_UNSUPPORTED;
  }

  *Position = StubFile->Position;
  return EFI_SUCCESS;
}


/**
  Sets a file's current position.

  @param[in] This      A pointer to the EFI_FILE_PROTOCOL instance that is the
                       file handle to set the requested position on.

  @param[in] Position  The byte position from the start of the file to set. For
                       regular files, MAX_UINT64 means "seek to end". For
                       directories, zero means "rewind directory scan".

  @retval EFI_SUCCESS       The position was set.
  @retval EFI_UNSUPPORTED   The seek request for nonzero is not valid on open
                            directories.
  @retval EFI_DEVICE_ERROR  An attempt was made to set the position of a
                            deleted file.
**/
STATIC
EFI_STATUS
EFIAPI
StubFileSetPosition (
  IN EFI_FILE_PROTOCOL *This,
  IN UINT64            Position
  )
{
  STUB_FILE   *StubFile;
  KERNEL_BLOB *Blob;

  StubFile = STUB_FILE_FROM_FILE (This);

  if (StubFile->BlobType == KernelBlobTypeMax) {
    if (Position == 0) {
      //
      // rewinding a directory scan is allowed
      //
      StubFile->Position = 0;
      return EFI_SUCCESS;
    }
    return EFI_UNSUPPORTED;
  }

  //
  // regular file seek
  //
  Blob = &mKernelBlob[StubFile->BlobType];
  if (Position == MAX_UINT64) {
    //
    // seek to end
    //
    StubFile->Position = Blob->Size;
  } else {
    //
    // absolute seek from beginning -- seeking past the end is allowed
    //
    StubFile->Position = Position;
  }
  return EFI_SUCCESS;
}


/**
  Returns information about a file.

  @param[in]     This             A pointer to the EFI_FILE_PROTOCOL instance
                                  that is the file handle the requested
                                  information is for.

  @param[in]     InformationType  The type identifier GUID for the information
                                  being requested. The following information
                                  types are supported, storing the
                                  corresponding structures in Buffer:

                                  - gEfiFileInfoGuid: EFI_FILE_INFO

                                  - gEfiFileSystemInfoGuid:
                                    EFI_FILE_SYSTEM_INFO

                                  - gEfiFileSystemVolumeLabelInfoIdGuid:
                                    EFI_FILE_SYSTEM_VOLUME_LABEL

  @param[in,out] BufferSize       On input, the size of Buffer. On output, the
                                  amount of data returned in Buffer. In both
                                  cases, the size is measured in bytes.

  @param[out]    Buffer           A pointer to the data buffer to return. The
                                  buffer's type is indicated by
                                  InformationType.

  @retval EFI_SUCCESS           The information was returned.
  @retval EFI_UNSUPPORTED       The InformationType is not known.
  @retval EFI_NO_MEDIA          The device has no medium.
  @retval EFI_DEVICE_ERROR      The device reported an error.
  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.
  @retval EFI_BUFFER_TOO_SMALL  The BufferSize is too small to store the
                                information structure requested by
                                InformationType. BufferSize has been updated
                                with the size needed to complete the request.
**/
STATIC
EFI_STATUS
EFIAPI
StubFileGetInfo (
  IN EFI_FILE_PROTOCOL *This,
  IN EFI_GUID          *InformationType,
  IN OUT UINTN         *BufferSize,
  OUT VOID             *Buffer
  )
{
  CONST STUB_FILE *StubFile;
  UINTN           OriginalBufferSize;

  StubFile = STUB_FILE_FROM_FILE (This);

  if (CompareGuid (InformationType, &gEfiFileInfoGuid)) {
    return ConvertKernelBlobTypeToFileInfo (StubFile->BlobType, BufferSize,
             Buffer);
  }

  OriginalBufferSize = *BufferSize;

  if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {
    EFI_FILE_SYSTEM_INFO *FileSystemInfo;

    *BufferSize = sizeof *FileSystemInfo;
    if (OriginalBufferSize < *BufferSize) {
      return EFI_BUFFER_TOO_SMALL;
    }

    FileSystemInfo                 = (EFI_FILE_SYSTEM_INFO *)Buffer;
    FileSystemInfo->Size           = sizeof *FileSystemInfo;
    FileSystemInfo->ReadOnly       = TRUE;
    FileSystemInfo->VolumeSize     = mTotalBlobBytes;
    FileSystemInfo->FreeSpace      = 0;
    FileSystemInfo->BlockSize      = 1;
    FileSystemInfo->VolumeLabel[0] = L'\0';

    return EFI_SUCCESS;
  }

  if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) {
    EFI_FILE_SYSTEM_VOLUME_LABEL *FileSystemVolumeLabel;

    *BufferSize = sizeof *FileSystemVolumeLabel;
    if (OriginalBufferSize < *BufferSize) {
      return EFI_BUFFER_TOO_SMALL;
    }

    FileSystemVolumeLabel = (EFI_FILE_SYSTEM_VOLUME_LABEL *)Buffer;
    FileSystemVolumeLabel->VolumeLabel[0] = L'\0';

    return EFI_SUCCESS;
  }

  return EFI_UNSUPPORTED;
}


/**
  Sets information about a file.

  @param[in] File             A pointer to the EFI_FILE_PROTOCOL instance that
                              is the file handle the information is for.

  @param[in] InformationType  The type identifier for the information being
                              set.

  @param[in] BufferSize       The size, in bytes, of Buffer.

  @param[in] Buffer           A pointer to the data buffer to write. The
                              buffer's type is indicated by InformationType.

  @retval EFI_SUCCESS           The information was set.
  @retval EFI_UNSUPPORTED       The InformationType is not known.
  @retval EFI_NO_MEDIA          The device has no medium.
  @retval EFI_DEVICE_ERROR      The device reported an error.
  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.
  @retval EFI_WRITE_PROTECTED   InformationType is EFI_FILE_INFO_ID and the
                                media is read-only.
  @retval EFI_WRITE_PROTECTED   InformationType is
                                EFI_FILE_PROTOCOL_SYSTEM_INFO_ID and the media
                                is read only.
  @retval EFI_WRITE_PROTECTED   InformationType is
                                EFI_FILE_SYSTEM_VOLUME_LABEL_ID and the media
                                is read-only.
  @retval EFI_ACCESS_DENIED     An attempt is made to change the name of a file
                                to a file that is already present.
  @retval EFI_ACCESS_DENIED     An attempt is being made to change the
                                EFI_FILE_DIRECTORY Attribute.
  @retval EFI_ACCESS_DENIED     An attempt is being made to change the size of
                                a directory.
  @retval EFI_ACCESS_DENIED     InformationType is EFI_FILE_INFO_ID and the
                                file was opened read-only and an attempt is
                                being made to modify a field other than
                                Attribute.
  @retval EFI_VOLUME_FULL       The volume is full.
  @retval EFI_BAD_BUFFER_SIZE   BufferSize is smaller than the size of the type
                                indicated by InformationType.
**/
STATIC
EFI_STATUS
EFIAPI
StubFileSetInfo (
  IN EFI_FILE_PROTOCOL *This,
  IN EFI_GUID          *InformationType,
  IN UINTN             BufferSize,
  IN VOID              *Buffer
  )
{
  return EFI_WRITE_PROTECTED;
}


/**
  Flushes all modified data associated with a file to a device.

  @param [in] This  A pointer to the EFI_FILE_PROTOCOL instance that is the
                    file handle to flush.

  @retval EFI_SUCCESS           The data was flushed.
  @retval EFI_NO_MEDIA          The device has no medium.
  @retval EFI_DEVICE_ERROR      The device reported an error.
  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.
  @retval EFI_WRITE_PROTECTED   The file or medium is write-protected.
  @retval EFI_ACCESS_DENIED     The file was opened read-only.
  @retval EFI_VOLUME_FULL       The volume is full.
**/
STATIC
EFI_STATUS
EFIAPI
StubFileFlush (
  IN EFI_FILE_PROTOCOL *This
  )
{
  return EFI_WRITE_PROTECTED;
}

//
// External definition of the file protocol template.
//
STATIC CONST EFI_FILE_PROTOCOL mEfiFileProtocolTemplate = {
  EFI_FILE_PROTOCOL_REVISION, // revision 1
  StubFileOpen,
  StubFileClose,
  StubFileDelete,
  StubFileRead,
  StubFileWrite,
  StubFileGetPosition,
  StubFileSetPosition,
  StubFileGetInfo,
  StubFileSetInfo,
  StubFileFlush,
  NULL,                       // OpenEx, revision 2
  NULL,                       // ReadEx, revision 2
  NULL,                       // WriteEx, revision 2
  NULL                        // FlushEx, revision 2
};


//
// Protocol member functions for SimpleFileSystem.
//

/**
  Open the root directory on a volume.

  @param[in]  This  A pointer to the volume to open the root directory on.

  @param[out] Root  A pointer to the location to return the opened file handle
                    for the root directory in.

  @retval EFI_SUCCESS           The device was opened.
  @retval EFI_UNSUPPORTED       This volume does not support the requested file
                                system type.
  @retval EFI_NO_MEDIA          The device has no medium.
  @retval EFI_DEVICE_ERROR      The device reported an error.
  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.
  @retval EFI_ACCESS_DENIED     The service denied access to the file.
  @retval EFI_OUT_OF_RESOURCES  The volume was not opened due to lack of
                                resources.
  @retval EFI_MEDIA_CHANGED     The device has a different medium in it or the
                                medium is no longer supported. Any existing
                                file handles for this volume are no longer
                                valid. To access the files on the new medium,
                                the volume must be reopened with OpenVolume().
**/
STATIC
EFI_STATUS
EFIAPI
StubFileSystemOpenVolume (
  IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,
  OUT EFI_FILE_PROTOCOL              **Root
  )
{
  STUB_FILE *StubFile;

  StubFile = AllocatePool (sizeof *StubFile);
  if (StubFile == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  StubFile->Signature = STUB_FILE_SIG;
  StubFile->BlobType  = KernelBlobTypeMax;
  StubFile->Position  = 0;
  CopyMem (&StubFile->File, &mEfiFileProtocolTemplate,
    sizeof mEfiFileProtocolTemplate);
  *Root = &StubFile->File;

  return EFI_SUCCESS;
}

STATIC CONST EFI_SIMPLE_FILE_SYSTEM_PROTOCOL mFileSystem = {
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION,
  StubFileSystemOpenVolume
};


//
// Utility functions.
//

/**
  Populate a blob in mKernelBlob.

  param[in,out] Blob  Pointer to the KERNEL_BLOB element in mKernelBlob that is
                      to be filled from fw_cfg.

  @retval EFI_SUCCESS           Blob has been populated. If fw_cfg reported a
                                size of zero for the blob, then Blob->Data has
                                been left unchanged.

  @retval EFI_OUT_OF_RESOURCES  Failed to allocate memory for Blob->Data.
**/
STATIC
EFI_STATUS
FetchBlob (
  IN OUT KERNEL_BLOB *Blob
  )
{
  UINT32 Left;

  //
  // Read blob size.
  //
  QemuFwCfgSelectItem (Blob->SizeKey);
  Blob->Size = QemuFwCfgRead32 ();
  if (Blob->Size == 0) {
    return EFI_SUCCESS;
  }

  //
  // Read blob.
  //
  Blob->Data = AllocatePool (Blob->Size);
  if (Blob->Data == NULL) {
    DEBUG ((EFI_D_ERROR, "%a: failed to allocate %Ld bytes for \"%s\"\n",
      __FUNCTION__, (INT64)Blob->Size, Blob->Name));
    return EFI_OUT_OF_RESOURCES;
  }

  DEBUG ((EFI_D_INFO, "%a: loading %Ld bytes for \"%s\"\n", __FUNCTION__,
    (INT64)Blob->Size, Blob->Name));
  QemuFwCfgSelectItem (Blob->DataKey);

  Left = Blob->Size;
  do {
    UINT32 Chunk;

    Chunk = (Left < SIZE_1MB) ? Left : SIZE_1MB;
    QemuFwCfgReadBytes (Chunk, Blob->Data + (Blob->Size - Left));
    Left -= Chunk;
    DEBUG ((EFI_D_VERBOSE, "%a: %Ld bytes remaining for \"%s\"\n",
      __FUNCTION__, (INT64)Left, Blob->Name));
  } while (Left > 0);
  return EFI_SUCCESS;
}


//
// The entry point of the feature.
//

/**
  Download the kernel, the initial ramdisk, and the kernel command line from
  QEMU's fw_cfg. Construct a minimal SimpleFileSystem that contains the two
  image files, and load and start the kernel from it.

  The kernel will be instructed via its command line to load the initrd from
  the same Simple FileSystem.

  @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. On success, the function doesn't
                                return.
**/
EFI_STATUS
EFIAPI
TryRunningQemuKernel (
  VOID
  )
{
  UINTN                     BlobType;
  KERNEL_BLOB               *CurrentBlob;
  KERNEL_BLOB               *KernelBlob, *InitrdBlob, *CommandLineBlob;
  EFI_STATUS                Status;
  EFI_HANDLE                FileSystemHandle;
  EFI_DEVICE_PATH_PROTOCOL  *KernelDevicePath;
  EFI_HANDLE                KernelImageHandle;
  EFI_LOADED_IMAGE_PROTOCOL *KernelLoadedImage;

  Status = gRT->GetTime (&mInitTime, NULL /* Capabilities */);
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "%a: GetTime(): %r\n", __FUNCTION__, Status));
    return Status;
  }

  //
  // Fetch all blobs.
  //
  for (BlobType = 0; BlobType < KernelBlobTypeMax; ++BlobType) {
    CurrentBlob = &mKernelBlob[BlobType];
    Status = FetchBlob (CurrentBlob);
    if (EFI_ERROR (Status)) {
      goto FreeBlobs;
    }
    mTotalBlobBytes += CurrentBlob->Size;
  }
  KernelBlob      = &mKernelBlob[KernelBlobTypeKernel];
  InitrdBlob      = &mKernelBlob[KernelBlobTypeInitrd];
  CommandLineBlob = &mKernelBlob[KernelBlobTypeCommandLine];

  if (KernelBlob->Data == NULL) {
    Status = EFI_NOT_FOUND;
    goto FreeBlobs;
  }

  //
  // Create a new handle with a single VenHw() node device path protocol on it,
  // plus a custom SimpleFileSystem protocol on it.
  //
  FileSystemHandle = NULL;
  Status = gBS->InstallMultipleProtocolInterfaces (&FileSystemHandle,
                  &gEfiDevicePathProtocolGuid,       &mFileSystemDevicePath,
                  &gEfiSimpleFileSystemProtocolGuid, &mFileSystem,
                  NULL);
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "%a: InstallMultipleProtocolInterfaces(): %r\n",
      __FUNCTION__, Status));
    goto FreeBlobs;
  }

  //
  // Create a device path for the kernel image to be loaded from that will call
  // back into our file system.
  //
  KernelDevicePath = FileDevicePath (FileSystemHandle, KernelBlob->Name);
  if (KernelDevicePath == NULL) {
    DEBUG ((EFI_D_ERROR, "%a: failed to allocate kernel device path\n",
      __FUNCTION__));
    Status = EFI_OUT_OF_RESOURCES;
    goto UninstallProtocols;
  }

  //
  // Load the image. This should call back into our file system.
  //
  Status = gBS->LoadImage (
                  FALSE,             // BootPolicy: exact match required
                  gImageHandle,      // ParentImageHandle
                  KernelDevicePath,
                  NULL,              // SourceBuffer
                  0,                 // SourceSize
                  &KernelImageHandle
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "%a: LoadImage(): %r\n", __FUNCTION__, Status));
    goto FreeKernelDevicePath;
  }

  //
  // 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);

  if (CommandLineBlob->Data == NULL) {
    KernelLoadedImage->LoadOptionsSize = 0;
  } else {
    //
    // Verify NUL-termination of the command line.
    //
    if (CommandLineBlob->Data[CommandLineBlob->Size - 1] != '\0') {
      DEBUG ((EFI_D_ERROR, "%a: kernel command line is not NUL-terminated\n",
        __FUNCTION__));
      Status = EFI_PROTOCOL_ERROR;
      goto UnloadKernelImage;
    }

    //
    // Drop the terminating NUL, convert to UTF-16.
    //
    KernelLoadedImage->LoadOptionsSize = (CommandLineBlob->Size - 1) * 2;
  }

  if (InitrdBlob->Data != NULL) {
    //
    // Append ' initrd=<name>' in UTF-16.
    //
    KernelLoadedImage->LoadOptionsSize +=
                                        (8 + StrLen(InitrdBlob->Name)) * 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 UnloadKernelImage;
    }

    UnicodeSPrintAsciiFormat (
      KernelLoadedImage->LoadOptions,
      KernelLoadedImage->LoadOptionsSize,
      "%a%a%s",
      (CommandLineBlob->Data == NULL) ?  "" : (CHAR8 *)CommandLineBlob->Data,
      (InitrdBlob->Data      == NULL) ?  "" : " initrd=",
      (InitrdBlob->Data      == NULL) ? L"" : InitrdBlob->Name
      );
    DEBUG ((EFI_D_INFO, "%a: command line: \"%s\"\n", __FUNCTION__,
      (CHAR16 *)KernelLoadedImage->LoadOptions));
  }

  //
  // Signal the EFI_EVENT_GROUP_READY_TO_BOOT event.
  //
  EfiSignalEventReadyToBoot();

  //
  // Start the image.
  //
  Status = gBS->StartImage (
                KernelImageHandle,
                NULL,              // ExitDataSize
                NULL               // ExitData
                );
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "%a: StartImage(): %r\n", __FUNCTION__, Status));
  }

  if (KernelLoadedImage->LoadOptions != NULL) {
    FreePool (KernelLoadedImage->LoadOptions);
  }
  KernelLoadedImage->LoadOptionsSize = 0;

UnloadKernelImage:
  gBS->UnloadImage (KernelImageHandle);

FreeKernelDevicePath:
  FreePool (KernelDevicePath);

UninstallProtocols:
  gBS->UninstallMultipleProtocolInterfaces (FileSystemHandle,
         &gEfiSimpleFileSystemProtocolGuid, &mFileSystem,
         &gEfiDevicePathProtocolGuid,       &mFileSystemDevicePath,
         NULL);

FreeBlobs:
  while (BlobType > 0) {
    CurrentBlob = &mKernelBlob[--BlobType];
    if (CurrentBlob->Data != NULL) {
      FreePool (CurrentBlob->Data);
      CurrentBlob->Size = 0;
      CurrentBlob->Data = NULL;
    }
  }

  return Status;
}
