/** @file
  OVMF ACPI support using QEMU's fw-cfg interface

  Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR>
  Copyright (C) 2012-2014, Red Hat, Inc.

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <IndustryStandard/Acpi.h>            // EFI_ACPI_DESCRIPTION_HEADER
#include <IndustryStandard/QemuLoader.h>      // QEMU_LOADER_FNAME_SIZE
#include <IndustryStandard/UefiTcgPlatform.h>
#include <Library/AcpiPlatformLib.h>
#include <Library/BaseLib.h>                  // AsciiStrCmp()
#include <Library/BaseMemoryLib.h>            // CopyMem()
#include <Library/DebugLib.h>                 // DEBUG()
#include <Library/MemoryAllocationLib.h>      // AllocatePool()
#include <Library/OrderedCollectionLib.h>     // OrderedCollectionMin()
#include <Library/QemuFwCfgLib.h>             // QemuFwCfgFindFile()
#include <Library/QemuFwCfgS3Lib.h>           // QemuFwCfgS3Enabled()
#include <Library/UefiBootServicesTableLib.h> // gBS
#include <Library/TpmMeasurementLib.h>

//
// The user structure for the ordered collection that will track the fw_cfg
// blobs under processing.
//
typedef struct {
  UINT8      File[QEMU_LOADER_FNAME_SIZE]; // NUL-terminated name of the fw_cfg
                                           // blob. This is the ordering / search
                                           // key.
  UINTN      Size;                         // The number of bytes in this blob.
  UINT8      *Base;                        // Pointer to the blob data.
  BOOLEAN    HostsOnlyTableData;           // TRUE iff the blob has been found to
                                           // only contain data that is directly
                                           // part of ACPI tables.
} BLOB;

/**
  Compare a standalone key against a user structure containing an embedded key.

  @param[in] StandaloneKey  Pointer to the bare key.

  @param[in] UserStruct     Pointer to the user structure with the embedded
                            key.

  @retval <0  If StandaloneKey compares less than UserStruct's key.

  @retval  0  If StandaloneKey compares equal to UserStruct's key.

  @retval >0  If StandaloneKey compares greater than UserStruct's key.
**/
STATIC
INTN
EFIAPI
BlobKeyCompare (
  IN CONST VOID  *StandaloneKey,
  IN CONST VOID  *UserStruct
  )
{
  CONST BLOB  *Blob;

  Blob = UserStruct;
  return AsciiStrCmp (StandaloneKey, (CONST CHAR8 *)Blob->File);
}

/**
  Comparator function for two user structures.

  @param[in] UserStruct1  Pointer to the first user structure.

  @param[in] UserStruct2  Pointer to the second user structure.

  @retval <0  If UserStruct1 compares less than UserStruct2.

  @retval  0  If UserStruct1 compares equal to UserStruct2.

  @retval >0  If UserStruct1 compares greater than UserStruct2.
**/
STATIC
INTN
EFIAPI
BlobCompare (
  IN CONST VOID  *UserStruct1,
  IN CONST VOID  *UserStruct2
  )
{
  CONST BLOB  *Blob1;

  Blob1 = UserStruct1;
  return BlobKeyCompare (Blob1->File, UserStruct2);
}

/**
  Comparator function for two opaque pointers, ordering on (unsigned) pointer
  value itself.
  Can be used as both Key and UserStruct comparator.

  @param[in] Pointer1  First pointer.

  @param[in] Pointer2  Second pointer.

  @retval <0  If Pointer1 compares less than Pointer2.

  @retval  0  If Pointer1 compares equal to Pointer2.

  @retval >0  If Pointer1 compares greater than Pointer2.
**/
STATIC
INTN
EFIAPI
PointerCompare (
  IN CONST VOID  *Pointer1,
  IN CONST VOID  *Pointer2
  )
{
  if (Pointer1 == Pointer2) {
    return 0;
  }

  if ((UINTN)Pointer1 < (UINTN)Pointer2) {
    return -1;
  }

  return 1;
}

/**
  Comparator function for two ASCII strings. Can be used as both Key and
  UserStruct comparator.

  This function exists solely so we can avoid casting &AsciiStrCmp to
  ORDERED_COLLECTION_USER_COMPARE and ORDERED_COLLECTION_KEY_COMPARE.

  @param[in] AsciiString1  Pointer to the first ASCII string.

  @param[in] AsciiString2  Pointer to the second ASCII string.

  @return  The return value of AsciiStrCmp (AsciiString1, AsciiString2).
**/
STATIC
INTN
EFIAPI
AsciiStringCompare (
  IN CONST VOID  *AsciiString1,
  IN CONST VOID  *AsciiString2
  )
{
  return AsciiStrCmp (AsciiString1, AsciiString2);
}

/**
  Release the ORDERED_COLLECTION structure populated by
  CollectAllocationsRestrictedTo32Bit() (below).

  This function may be called by CollectAllocationsRestrictedTo32Bit() itself,
  on the error path.

  @param[in] AllocationsRestrictedTo32Bit  The ORDERED_COLLECTION structure to
                                           release.
**/
STATIC
VOID
ReleaseAllocationsRestrictedTo32Bit (
  IN ORDERED_COLLECTION  *AllocationsRestrictedTo32Bit
  )
{
  ORDERED_COLLECTION_ENTRY  *Entry, *Entry2;

  for (Entry = OrderedCollectionMin (AllocationsRestrictedTo32Bit);
       Entry != NULL;
       Entry = Entry2)
  {
    Entry2 = OrderedCollectionNext (Entry);
    OrderedCollectionDelete (AllocationsRestrictedTo32Bit, Entry, NULL);
  }

  OrderedCollectionUninit (AllocationsRestrictedTo32Bit);
}

/**
  Iterate over the linker/loader script, and collect the names of the fw_cfg
  blobs that are referenced by QEMU_LOADER_ADD_POINTER.PointeeFile fields, such
  that QEMU_LOADER_ADD_POINTER.PointerSize is less than 8. This means that the
  pointee blob's address will have to be patched into a narrower-than-8 byte
  pointer field, hence the pointee blob must not be allocated from 64-bit
  address space.

  @param[out] AllocationsRestrictedTo32Bit  The ORDERED_COLLECTION structure
                                            linking (not copying / owning) such
                                            QEMU_LOADER_ADD_POINTER.PointeeFile
                                            fields that name the blobs
                                            restricted from 64-bit allocation.

  @param[in] LoaderStart                    Points to the first entry in the
                                            linker/loader script.

  @param[in] LoaderEnd                      Points one past the last entry in
                                            the linker/loader script.

  @retval EFI_SUCCESS           AllocationsRestrictedTo32Bit has been
                                populated.

  @retval EFI_OUT_OF_RESOURCES  Memory allocation failed.

  @retval EFI_PROTOCOL_ERROR    Invalid linker/loader script contents.
**/
STATIC
EFI_STATUS
CollectAllocationsRestrictedTo32Bit (
  OUT ORDERED_COLLECTION      **AllocationsRestrictedTo32Bit,
  IN CONST QEMU_LOADER_ENTRY  *LoaderStart,
  IN CONST QEMU_LOADER_ENTRY  *LoaderEnd
  )
{
  ORDERED_COLLECTION       *Collection;
  CONST QEMU_LOADER_ENTRY  *LoaderEntry;
  EFI_STATUS               Status;

  Collection = OrderedCollectionInit (AsciiStringCompare, AsciiStringCompare);
  if (Collection == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  for (LoaderEntry = LoaderStart; LoaderEntry < LoaderEnd; ++LoaderEntry) {
    CONST QEMU_LOADER_ADD_POINTER  *AddPointer;

    if (LoaderEntry->Type != QemuLoaderCmdAddPointer) {
      continue;
    }

    AddPointer = &LoaderEntry->Command.AddPointer;

    if (AddPointer->PointerSize >= 8) {
      continue;
    }

    if (AddPointer->PointeeFile[QEMU_LOADER_FNAME_SIZE - 1] != '\0') {
      DEBUG ((DEBUG_ERROR, "%a: malformed file name\n", __func__));
      Status = EFI_PROTOCOL_ERROR;
      goto RollBack;
    }

    Status = OrderedCollectionInsert (
               Collection,
               NULL,                           // Entry
               (VOID *)AddPointer->PointeeFile
               );
    switch (Status) {
      case EFI_SUCCESS:
        DEBUG ((
          DEBUG_VERBOSE,
          "%a: restricting blob \"%a\" from 64-bit allocation\n",
          __func__,
          AddPointer->PointeeFile
          ));
        break;
      case EFI_ALREADY_STARTED:
        //
        // The restriction has been recorded already.
        //
        break;
      case EFI_OUT_OF_RESOURCES:
        goto RollBack;
      default:
        ASSERT (FALSE);
    }
  }

  *AllocationsRestrictedTo32Bit = Collection;
  return EFI_SUCCESS;

RollBack:
  ReleaseAllocationsRestrictedTo32Bit (Collection);
  return Status;
}

/**
  Process a QEMU_LOADER_ALLOCATE command.

  @param[in] Allocate                      The QEMU_LOADER_ALLOCATE command to
                                           process.

  @param[in,out] Tracker                   The ORDERED_COLLECTION tracking the
                                           BLOB user structures created thus
                                           far.

  @param[in] AllocationsRestrictedTo32Bit  The ORDERED_COLLECTION populated by
                                           the function
                                           CollectAllocationsRestrictedTo32Bit,
                                           naming the fw_cfg blobs that must
                                           not be allocated from 64-bit address
                                           space.

  @retval EFI_SUCCESS           An area of whole AcpiNVS pages has been
                                allocated for the blob contents, and the
                                contents have been saved. A BLOB object (user
                                structure) has been allocated from pool memory,
                                referencing the blob contents. The BLOB user
                                structure has been linked into Tracker.

  @retval EFI_PROTOCOL_ERROR    Malformed fw_cfg file name has been found in
                                Allocate, or the Allocate command references a
                                file that is already known by Tracker.

  @retval EFI_UNSUPPORTED       Unsupported alignment request has been found in
                                Allocate.

  @retval EFI_OUT_OF_RESOURCES  Pool allocation failed.

  @return                       Error codes from QemuFwCfgFindFile() and
                                gBS->AllocatePages().
**/
STATIC
EFI_STATUS
EFIAPI
ProcessCmdAllocate (
  IN CONST QEMU_LOADER_ALLOCATE  *Allocate,
  IN OUT ORDERED_COLLECTION      *Tracker,
  IN ORDERED_COLLECTION          *AllocationsRestrictedTo32Bit
  )
{
  FIRMWARE_CONFIG_ITEM  FwCfgItem;
  UINTN                 FwCfgSize;
  EFI_STATUS            Status;
  UINTN                 NumPages;
  EFI_PHYSICAL_ADDRESS  Address;
  BLOB                  *Blob;

  if (Allocate->File[QEMU_LOADER_FNAME_SIZE - 1] != '\0') {
    DEBUG ((DEBUG_ERROR, "%a: malformed file name\n", __func__));
    return EFI_PROTOCOL_ERROR;
  }

  if (Allocate->Alignment > EFI_PAGE_SIZE) {
    DEBUG ((
      DEBUG_ERROR,
      "%a: unsupported alignment 0x%x\n",
      __func__,
      Allocate->Alignment
      ));
    return EFI_UNSUPPORTED;
  }

  Status = QemuFwCfgFindFile ((CHAR8 *)Allocate->File, &FwCfgItem, &FwCfgSize);
  if (EFI_ERROR (Status)) {
    DEBUG ((
      DEBUG_ERROR,
      "%a: QemuFwCfgFindFile(\"%a\"): %r\n",
      __func__,
      Allocate->File,
      Status
      ));
    return Status;
  }

  NumPages = EFI_SIZE_TO_PAGES (FwCfgSize);
  Address  = MAX_UINT64;
  if (OrderedCollectionFind (
        AllocationsRestrictedTo32Bit,
        Allocate->File
        ) != NULL)
  {
    Address = MAX_UINT32;
  }

  Status = gBS->AllocatePages (
                  AllocateMaxAddress,
                  EfiACPIMemoryNVS,
                  NumPages,
                  &Address
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Blob = AllocatePool (sizeof *Blob);
  if (Blob == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto FreePages;
  }

  CopyMem (Blob->File, Allocate->File, QEMU_LOADER_FNAME_SIZE);
  Blob->Size               = FwCfgSize;
  Blob->Base               = (VOID *)(UINTN)Address;
  Blob->HostsOnlyTableData = TRUE;

  Status = OrderedCollectionInsert (Tracker, NULL, Blob);
  if (Status == RETURN_ALREADY_STARTED) {
    DEBUG ((
      DEBUG_ERROR,
      "%a: duplicated file \"%a\"\n",
      __func__,
      Allocate->File
      ));
    Status = EFI_PROTOCOL_ERROR;
  }

  if (EFI_ERROR (Status)) {
    goto FreeBlob;
  }

  QemuFwCfgSelectItem (FwCfgItem);
  QemuFwCfgReadBytes (FwCfgSize, Blob->Base);
  ZeroMem (Blob->Base + Blob->Size, EFI_PAGES_TO_SIZE (NumPages) - Blob->Size);

  DEBUG ((
    DEBUG_VERBOSE,
    "%a: File=\"%a\" Alignment=0x%x Zone=%d Size=0x%Lx "
    "Address=0x%Lx\n",
    __func__,
    Allocate->File,
    Allocate->Alignment,
    Allocate->Zone,
    (UINT64)Blob->Size,
    (UINT64)(UINTN)Blob->Base
    ));

  //
  // Measure the data which is downloaded from QEMU.
  // It has to be done before it is consumed. Because the data will
  // be updated in the following operations.
  //
  TpmMeasureAndLogData (
    1,
    EV_PLATFORM_CONFIG_FLAGS,
    EV_POSTCODE_INFO_ACPI_DATA,
    ACPI_DATA_LEN,
    (VOID *)(UINTN)Blob->Base,
    Blob->Size
    );

  return EFI_SUCCESS;

FreeBlob:
  FreePool (Blob);

FreePages:
  gBS->FreePages (Address, NumPages);

  return Status;
}

/**
  Process a QEMU_LOADER_ADD_POINTER command.

  @param[in] AddPointer  The QEMU_LOADER_ADD_POINTER command to process.

  @param[in] Tracker     The ORDERED_COLLECTION tracking the BLOB user
                         structures created thus far.

  @retval EFI_PROTOCOL_ERROR  Malformed fw_cfg file name(s) have been found in
                              AddPointer, or the AddPointer command references
                              a file unknown to Tracker, or the pointer to
                              relocate has invalid location, size, or value, or
                              the relocated pointer value is not representable
                              in the given pointer size.

  @retval EFI_SUCCESS         The pointer field inside the pointer blob has
                              been relocated.
**/
STATIC
EFI_STATUS
EFIAPI
ProcessCmdAddPointer (
  IN CONST QEMU_LOADER_ADD_POINTER  *AddPointer,
  IN CONST ORDERED_COLLECTION       *Tracker
  )
{
  ORDERED_COLLECTION_ENTRY  *TrackerEntry, *TrackerEntry2;
  BLOB                      *Blob, *Blob2;
  UINT8                     *PointerField;
  UINT64                    PointerValue;

  if ((AddPointer->PointerFile[QEMU_LOADER_FNAME_SIZE - 1] != '\0') ||
      (AddPointer->PointeeFile[QEMU_LOADER_FNAME_SIZE - 1] != '\0'))
  {
    DEBUG ((DEBUG_ERROR, "%a: malformed file name\n", __func__));
    return EFI_PROTOCOL_ERROR;
  }

  TrackerEntry  = OrderedCollectionFind (Tracker, AddPointer->PointerFile);
  TrackerEntry2 = OrderedCollectionFind (Tracker, AddPointer->PointeeFile);
  if ((TrackerEntry == NULL) || (TrackerEntry2 == NULL)) {
    DEBUG ((
      DEBUG_ERROR,
      "%a: invalid blob reference(s) \"%a\" / \"%a\"\n",
      __func__,
      AddPointer->PointerFile,
      AddPointer->PointeeFile
      ));
    return EFI_PROTOCOL_ERROR;
  }

  Blob  = OrderedCollectionUserStruct (TrackerEntry);
  Blob2 = OrderedCollectionUserStruct (TrackerEntry2);
  if (((AddPointer->PointerSize != 1) && (AddPointer->PointerSize != 2) &&
       (AddPointer->PointerSize != 4) && (AddPointer->PointerSize != 8)) ||
      (Blob->Size < AddPointer->PointerSize) ||
      (Blob->Size - AddPointer->PointerSize < AddPointer->PointerOffset))
  {
    DEBUG ((
      DEBUG_ERROR,
      "%a: invalid pointer location or size in \"%a\"\n",
      __func__,
      AddPointer->PointerFile
      ));
    return EFI_PROTOCOL_ERROR;
  }

  PointerField = Blob->Base + AddPointer->PointerOffset;
  PointerValue = 0;
  CopyMem (&PointerValue, PointerField, AddPointer->PointerSize);
  if (PointerValue >= Blob2->Size) {
    DEBUG ((
      DEBUG_ERROR,
      "%a: invalid pointer value in \"%a\"\n",
      __func__,
      AddPointer->PointerFile
      ));
    return EFI_PROTOCOL_ERROR;
  }

  //
  // The memory allocation system ensures that the address of the byte past the
  // last byte of any allocated object is expressible (no wraparound).
  //
  ASSERT ((UINTN)Blob2->Base <= MAX_ADDRESS - Blob2->Size);

  PointerValue += (UINT64)(UINTN)Blob2->Base;
  if ((AddPointer->PointerSize < 8) &&
      (RShiftU64 (PointerValue, AddPointer->PointerSize * 8) != 0))
  {
    DEBUG ((
      DEBUG_ERROR,
      "%a: relocated pointer value unrepresentable in "
      "\"%a\"\n",
      __func__,
      AddPointer->PointerFile
      ));
    return EFI_PROTOCOL_ERROR;
  }

  CopyMem (PointerField, &PointerValue, AddPointer->PointerSize);

  DEBUG ((
    DEBUG_VERBOSE,
    "%a: PointerFile=\"%a\" PointeeFile=\"%a\" "
    "PointerOffset=0x%x PointerSize=%d\n",
    __func__,
    AddPointer->PointerFile,
    AddPointer->PointeeFile,
    AddPointer->PointerOffset,
    AddPointer->PointerSize
    ));
  return EFI_SUCCESS;
}

/**
  Process a QEMU_LOADER_ADD_CHECKSUM command.

  @param[in] AddChecksum  The QEMU_LOADER_ADD_CHECKSUM command to process.

  @param[in] Tracker      The ORDERED_COLLECTION tracking the BLOB user
                          structures created thus far.

  @retval EFI_PROTOCOL_ERROR  Malformed fw_cfg file name has been found in
                              AddChecksum, or the AddChecksum command
                              references a file unknown to Tracker, or the
                              range to checksum is invalid.

  @retval EFI_SUCCESS         The requested range has been checksummed.
**/
STATIC
EFI_STATUS
EFIAPI
ProcessCmdAddChecksum (
  IN CONST QEMU_LOADER_ADD_CHECKSUM  *AddChecksum,
  IN CONST ORDERED_COLLECTION        *Tracker
  )
{
  ORDERED_COLLECTION_ENTRY  *TrackerEntry;
  BLOB                      *Blob;

  if (AddChecksum->File[QEMU_LOADER_FNAME_SIZE - 1] != '\0') {
    DEBUG ((DEBUG_ERROR, "%a: malformed file name\n", __func__));
    return EFI_PROTOCOL_ERROR;
  }

  TrackerEntry = OrderedCollectionFind (Tracker, AddChecksum->File);
  if (TrackerEntry == NULL) {
    DEBUG ((
      DEBUG_ERROR,
      "%a: invalid blob reference \"%a\"\n",
      __func__,
      AddChecksum->File
      ));
    return EFI_PROTOCOL_ERROR;
  }

  Blob = OrderedCollectionUserStruct (TrackerEntry);
  if ((Blob->Size <= AddChecksum->ResultOffset) ||
      (Blob->Size < AddChecksum->Length) ||
      (Blob->Size - AddChecksum->Length < AddChecksum->Start))
  {
    DEBUG ((
      DEBUG_ERROR,
      "%a: invalid checksum range in \"%a\"\n",
      __func__,
      AddChecksum->File
      ));
    return EFI_PROTOCOL_ERROR;
  }

  Blob->Base[AddChecksum->ResultOffset] = CalculateCheckSum8 (
                                            Blob->Base + AddChecksum->Start,
                                            AddChecksum->Length
                                            );
  DEBUG ((
    DEBUG_VERBOSE,
    "%a: File=\"%a\" ResultOffset=0x%x Start=0x%x "
    "Length=0x%x\n",
    __func__,
    AddChecksum->File,
    AddChecksum->ResultOffset,
    AddChecksum->Start,
    AddChecksum->Length
    ));
  return EFI_SUCCESS;
}

/**
  Process a QEMU_LOADER_WRITE_POINTER command.

  @param[in] WritePointer   The QEMU_LOADER_WRITE_POINTER command to process.

  @param[in] Tracker        The ORDERED_COLLECTION tracking the BLOB user
                            structures created thus far.

  @param[in,out] S3Context  The S3_CONTEXT object capturing the fw_cfg actions
                            of successfully processed QEMU_LOADER_WRITE_POINTER
                            commands, to be replayed at S3 resume. S3Context
                            may be NULL if S3 is disabled.

  @retval EFI_PROTOCOL_ERROR  Malformed fw_cfg file name(s) have been found in
                              WritePointer. Or, the WritePointer command
                              references a file unknown to Tracker or the
                              fw_cfg directory. Or, the pointer object to
                              rewrite has invalid location, size, or initial
                              relative value. Or, the pointer value to store
                              does not fit in the given pointer size.

  @retval EFI_SUCCESS         The pointer object inside the writeable fw_cfg
                              file has been written. If S3Context is not NULL,
                              then WritePointer has been condensed into
                              S3Context.

  @return                     Error codes propagated from
                              SaveCondensedWritePointerToS3Context(). The
                              pointer object inside the writeable fw_cfg file
                              has not been written.
**/
STATIC
EFI_STATUS
ProcessCmdWritePointer (
  IN     CONST QEMU_LOADER_WRITE_POINTER  *WritePointer,
  IN     CONST ORDERED_COLLECTION         *Tracker,
  IN OUT       S3_CONTEXT                 *S3Context OPTIONAL
  )
{
  RETURN_STATUS             Status;
  FIRMWARE_CONFIG_ITEM      PointerItem;
  UINTN                     PointerItemSize;
  ORDERED_COLLECTION_ENTRY  *PointeeEntry;
  BLOB                      *PointeeBlob;
  UINT64                    PointerValue;

  if ((WritePointer->PointerFile[QEMU_LOADER_FNAME_SIZE - 1] != '\0') ||
      (WritePointer->PointeeFile[QEMU_LOADER_FNAME_SIZE - 1] != '\0'))
  {
    DEBUG ((DEBUG_ERROR, "%a: malformed file name\n", __func__));
    return EFI_PROTOCOL_ERROR;
  }

  Status = QemuFwCfgFindFile (
             (CONST CHAR8 *)WritePointer->PointerFile,
             &PointerItem,
             &PointerItemSize
             );
  PointeeEntry = OrderedCollectionFind (Tracker, WritePointer->PointeeFile);
  if (RETURN_ERROR (Status) || (PointeeEntry == NULL)) {
    DEBUG ((
      DEBUG_ERROR,
      "%a: invalid fw_cfg file or blob reference \"%a\" / \"%a\"\n",
      __func__,
      WritePointer->PointerFile,
      WritePointer->PointeeFile
      ));
    return EFI_PROTOCOL_ERROR;
  }

  if (((WritePointer->PointerSize != 1) && (WritePointer->PointerSize != 2) &&
       (WritePointer->PointerSize != 4) && (WritePointer->PointerSize != 8)) ||
      (PointerItemSize < WritePointer->PointerSize) ||
      (PointerItemSize - WritePointer->PointerSize <
       WritePointer->PointerOffset))
  {
    DEBUG ((
      DEBUG_ERROR,
      "%a: invalid pointer location or size in \"%a\"\n",
      __func__,
      WritePointer->PointerFile
      ));
    return EFI_PROTOCOL_ERROR;
  }

  PointeeBlob  = OrderedCollectionUserStruct (PointeeEntry);
  PointerValue = WritePointer->PointeeOffset;
  if (PointerValue >= PointeeBlob->Size) {
    DEBUG ((DEBUG_ERROR, "%a: invalid PointeeOffset\n", __func__));
    return EFI_PROTOCOL_ERROR;
  }

  //
  // The memory allocation system ensures that the address of the byte past the
  // last byte of any allocated object is expressible (no wraparound).
  //
  ASSERT ((UINTN)PointeeBlob->Base <= MAX_ADDRESS - PointeeBlob->Size);

  PointerValue += (UINT64)(UINTN)PointeeBlob->Base;
  if ((WritePointer->PointerSize < 8) &&
      (RShiftU64 (PointerValue, WritePointer->PointerSize * 8) != 0))
  {
    DEBUG ((
      DEBUG_ERROR,
      "%a: pointer value unrepresentable in \"%a\"\n",
      __func__,
      WritePointer->PointerFile
      ));
    return EFI_PROTOCOL_ERROR;
  }

  //
  // If S3 is enabled, we have to capture the below fw_cfg actions in condensed
  // form, to be replayed during S3 resume.
  //
  if (S3Context != NULL) {
    EFI_STATUS  SaveStatus;

    SaveStatus = SaveCondensedWritePointerToS3Context (
                   S3Context,
                   (UINT16)PointerItem,
                   WritePointer->PointerSize,
                   WritePointer->PointerOffset,
                   PointerValue
                   );
    if (EFI_ERROR (SaveStatus)) {
      return SaveStatus;
    }
  }

  QemuFwCfgSelectItem (PointerItem);
  QemuFwCfgSkipBytes (WritePointer->PointerOffset);
  QemuFwCfgWriteBytes (WritePointer->PointerSize, &PointerValue);

  //
  // Because QEMU has now learned PointeeBlob->Base, we must mark PointeeBlob
  // as unreleasable, for the case when the whole linker/loader script is
  // handled successfully.
  //
  PointeeBlob->HostsOnlyTableData = FALSE;

  DEBUG ((
    DEBUG_VERBOSE,
    "%a: PointerFile=\"%a\" PointeeFile=\"%a\" "
    "PointerOffset=0x%x PointeeOffset=0x%x PointerSize=%d\n",
    __func__,
    WritePointer->PointerFile,
    WritePointer->PointeeFile,
    WritePointer->PointerOffset,
    WritePointer->PointeeOffset,
    WritePointer->PointerSize
    ));
  return EFI_SUCCESS;
}

/**
  Undo a QEMU_LOADER_WRITE_POINTER command.

  This function revokes (zeroes out) a guest memory reference communicated to
  QEMU earlier. The caller is responsible for invoking this function only on
  such QEMU_LOADER_WRITE_POINTER commands that have been successfully processed
  by ProcessCmdWritePointer().

  @param[in] WritePointer  The QEMU_LOADER_WRITE_POINTER command to undo.
**/
STATIC
VOID
UndoCmdWritePointer (
  IN CONST QEMU_LOADER_WRITE_POINTER  *WritePointer
  )
{
  RETURN_STATUS         Status;
  FIRMWARE_CONFIG_ITEM  PointerItem;
  UINTN                 PointerItemSize;
  UINT64                PointerValue;

  Status = QemuFwCfgFindFile (
             (CONST CHAR8 *)WritePointer->PointerFile,
             &PointerItem,
             &PointerItemSize
             );
  ASSERT_RETURN_ERROR (Status);

  PointerValue = 0;
  QemuFwCfgSelectItem (PointerItem);
  QemuFwCfgSkipBytes (WritePointer->PointerOffset);
  QemuFwCfgWriteBytes (WritePointer->PointerSize, &PointerValue);

  DEBUG ((
    DEBUG_VERBOSE,
    "%a: PointerFile=\"%a\" PointerOffset=0x%x PointerSize=%d\n",
    __func__,
    WritePointer->PointerFile,
    WritePointer->PointerOffset,
    WritePointer->PointerSize
    ));
}

//
// We'll be saving the keys of installed tables so that we can roll them back
// in case of failure. 128 tables should be enough for anyone (TM).
//
#define INSTALLED_TABLES_MAX  128

/**
  Process a QEMU_LOADER_ADD_POINTER command in order to see if its target byte
  array is an ACPI table, and if so, install it.

  This function assumes that the entire QEMU linker/loader command file has
  been processed successfully in a prior first pass.

  @param[in] AddPointer        The QEMU_LOADER_ADD_POINTER command to process.

  @param[in] Tracker           The ORDERED_COLLECTION tracking the BLOB user
                               structures.

  @param[in] AcpiProtocol      The ACPI table protocol used to install tables.

  @param[in,out] InstalledKey  On input, an array of INSTALLED_TABLES_MAX UINTN
                               elements, allocated by the caller. On output,
                               the function will have stored (appended) the
                               AcpiProtocol-internal key of the ACPI table that
                               the function has installed, if the AddPointer
                               command identified an ACPI table that is
                               different from RSDT and XSDT.

  @param[in,out] NumInstalled  On input, the number of entries already used in
                               InstalledKey; it must be in [0,
                               INSTALLED_TABLES_MAX] inclusive. On output, the
                               parameter is incremented if the AddPointer
                               command identified an ACPI table that is
                               different from RSDT and XSDT.

  @param[in,out] SeenPointers  The ORDERED_COLLECTION tracking the absolute
                               target addresses that have been pointed-to by
                               QEMU_LOADER_ADD_POINTER commands thus far. If a
                               target address is encountered for the first
                               time, and it identifies an ACPI table that is
                               different from RDST and XSDT, the table is
                               installed. If a target address is seen for the
                               second or later times, it is skipped without
                               taking any action.

  @retval EFI_INVALID_PARAMETER  NumInstalled was outside the allowed range on
                                 input.

  @retval EFI_OUT_OF_RESOURCES   The AddPointer command identified an ACPI
                                 table different from RSDT and XSDT, but there
                                 was no more room in InstalledKey.

  @retval EFI_SUCCESS            AddPointer has been processed. Either its
                                 absolute target address has been encountered
                                 before, or an ACPI table different from RSDT
                                 and XSDT has been installed (reflected by
                                 InstalledKey and NumInstalled), or RSDT or
                                 XSDT has been identified but not installed, or
                                 the fw_cfg blob pointed-into by AddPointer has
                                 been marked as hosting something else than
                                 just direct ACPI table contents.

  @return                        Error codes returned by
                                 AcpiProtocol->InstallAcpiTable().
**/
STATIC
EFI_STATUS
EFIAPI
Process2ndPassCmdAddPointer (
  IN     CONST QEMU_LOADER_ADD_POINTER  *AddPointer,
  IN     CONST ORDERED_COLLECTION       *Tracker,
  IN     EFI_ACPI_TABLE_PROTOCOL        *AcpiProtocol,
  IN OUT UINTN                          InstalledKey[INSTALLED_TABLES_MAX],
  IN OUT INT32                          *NumInstalled,
  IN OUT ORDERED_COLLECTION             *SeenPointers
  )
{
  CONST ORDERED_COLLECTION_ENTRY                      *TrackerEntry;
  CONST ORDERED_COLLECTION_ENTRY                      *TrackerEntry2;
  ORDERED_COLLECTION_ENTRY                            *SeenPointerEntry;
  CONST BLOB                                          *Blob;
  BLOB                                                *Blob2;
  CONST UINT8                                         *PointerField;
  UINT64                                              PointerValue;
  UINTN                                               Blob2Remaining;
  UINTN                                               TableSize;
  CONST EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE  *Facs;
  CONST EFI_ACPI_DESCRIPTION_HEADER                   *Header;
  EFI_STATUS                                          Status;

  if ((*NumInstalled < 0) || (*NumInstalled > INSTALLED_TABLES_MAX)) {
    return EFI_INVALID_PARAMETER;
  }

  TrackerEntry  = OrderedCollectionFind (Tracker, AddPointer->PointerFile);
  TrackerEntry2 = OrderedCollectionFind (Tracker, AddPointer->PointeeFile);
  Blob          = OrderedCollectionUserStruct (TrackerEntry);
  Blob2         = OrderedCollectionUserStruct (TrackerEntry2);
  PointerField  = Blob->Base + AddPointer->PointerOffset;
  PointerValue  = 0;
  CopyMem (&PointerValue, PointerField, AddPointer->PointerSize);

  //
  // We assert that PointerValue falls inside Blob2's contents. This is ensured
  // by the Blob2->Size check and later checks in ProcessCmdAddPointer().
  //
  Blob2Remaining = (UINTN)Blob2->Base;
  ASSERT (PointerValue >= Blob2Remaining);
  Blob2Remaining += Blob2->Size;
  ASSERT (PointerValue < Blob2Remaining);

  Status = OrderedCollectionInsert (
             SeenPointers,
             &SeenPointerEntry, // for reverting insertion in error case
             (VOID *)(UINTN)PointerValue
             );
  if (EFI_ERROR (Status)) {
    if (Status == RETURN_ALREADY_STARTED) {
      //
      // Already seen this pointer, don't try to process it again.
      //
      DEBUG ((
        DEBUG_VERBOSE,
        "%a: PointerValue=0x%Lx already processed, skipping.\n",
        __func__,
        PointerValue
        ));
      Status = EFI_SUCCESS;
    }

    return Status;
  }

  Blob2Remaining -= (UINTN)PointerValue;
  DEBUG ((
    DEBUG_VERBOSE,
    "%a: checking for ACPI header in \"%a\" at 0x%Lx "
    "(remaining: 0x%Lx): ",
    __func__,
    AddPointer->PointeeFile,
    PointerValue,
    (UINT64)Blob2Remaining
    ));

  TableSize = 0;

  //
  // To make our job simple, the FACS has a custom header. Sigh.
  //
  if (sizeof *Facs <= Blob2Remaining) {
    Facs = (EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)(UINTN)PointerValue;

    if ((Facs->Length >= sizeof *Facs) &&
        (Facs->Length <= Blob2Remaining) &&
        (Facs->Signature ==
         EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE))
    {
      DEBUG ((
        DEBUG_VERBOSE,
        "found \"%-4.4a\" size 0x%x\n",
        (CONST CHAR8 *)&Facs->Signature,
        Facs->Length
        ));
      TableSize = Facs->Length;
    }
  }

  //
  // check for the uniform tables
  //
  if ((TableSize == 0) && (sizeof *Header <= Blob2Remaining)) {
    Header = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)PointerValue;

    if ((Header->Length >= sizeof *Header) &&
        (Header->Length <= Blob2Remaining) &&
        (CalculateSum8 ((CONST UINT8 *)Header, Header->Length) == 0))
    {
      //
      // This looks very much like an ACPI table from QEMU:
      // - Length field consistent with both ACPI and containing blob size
      // - checksum is correct
      //
      DEBUG ((
        DEBUG_VERBOSE,
        "found \"%-4.4a\" size 0x%x\n",
        (CONST CHAR8 *)&Header->Signature,
        Header->Length
        ));
      TableSize = Header->Length;

      //
      // Skip RSDT and XSDT because those are handled by
      // EFI_ACPI_TABLE_PROTOCOL automatically.
      if ((Header->Signature ==
           EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) ||
          (Header->Signature ==
           EFI_ACPI_2_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE))
      {
        return EFI_SUCCESS;
      }
    }
  }

  if (TableSize == 0) {
    DEBUG ((DEBUG_VERBOSE, "not found; marking fw_cfg blob as opaque\n"));
    Blob2->HostsOnlyTableData = FALSE;
    return EFI_SUCCESS;
  }

  if (*NumInstalled == INSTALLED_TABLES_MAX) {
    DEBUG ((
      DEBUG_ERROR,
      "%a: can't install more than %d tables\n",
      __func__,
      INSTALLED_TABLES_MAX
      ));
    Status = EFI_OUT_OF_RESOURCES;
    goto RollbackSeenPointer;
  }

  Status = AcpiProtocol->InstallAcpiTable (
                           AcpiProtocol,
                           (VOID *)(UINTN)PointerValue,
                           TableSize,
                           &InstalledKey[*NumInstalled]
                           );
  if (EFI_ERROR (Status)) {
    DEBUG ((
      DEBUG_ERROR,
      "%a: InstallAcpiTable(): %r\n",
      __func__,
      Status
      ));
    goto RollbackSeenPointer;
  }

  ++*NumInstalled;
  return EFI_SUCCESS;

RollbackSeenPointer:
  OrderedCollectionDelete (SeenPointers, SeenPointerEntry, NULL);
  return Status;
}

/**
  Download, process, and install ACPI table data from the QEMU loader
  interface.

  @param[in] AcpiProtocol  The ACPI table protocol used to install tables.

  @retval  EFI_UNSUPPORTED       Firmware configuration is unavailable, or QEMU
                                 loader command with unsupported parameters
                                 has been found.

  @retval  EFI_NOT_FOUND         The host doesn't export the required fw_cfg
                                 files.

  @retval  EFI_OUT_OF_RESOURCES  Memory allocation failed, or more than
                                 INSTALLED_TABLES_MAX tables found.

  @retval  EFI_PROTOCOL_ERROR    Found invalid fw_cfg contents.

  @return                        Status codes returned by
                                 AcpiProtocol->InstallAcpiTable().

**/
EFI_STATUS
EFIAPI
InstallQemuFwCfgTables (
  IN   EFI_ACPI_TABLE_PROTOCOL  *AcpiProtocol
  )
{
  EFI_STATUS                Status;
  FIRMWARE_CONFIG_ITEM      FwCfgItem;
  UINTN                     FwCfgSize;
  QEMU_LOADER_ENTRY         *LoaderStart;
  CONST QEMU_LOADER_ENTRY   *LoaderEntry, *LoaderEnd;
  CONST QEMU_LOADER_ENTRY   *WritePointerSubsetEnd;
  ORIGINAL_ATTRIBUTES       *OriginalPciAttributes;
  UINTN                     OriginalPciAttributesCount;
  ORDERED_COLLECTION        *AllocationsRestrictedTo32Bit;
  S3_CONTEXT                *S3Context;
  ORDERED_COLLECTION        *Tracker;
  UINTN                     *InstalledKey;
  INT32                     Installed;
  ORDERED_COLLECTION_ENTRY  *TrackerEntry, *TrackerEntry2;
  ORDERED_COLLECTION        *SeenPointers;
  ORDERED_COLLECTION_ENTRY  *SeenPointerEntry, *SeenPointerEntry2;
  EFI_HANDLE                QemuAcpiHandle;

  Status = QemuFwCfgFindFile ("etc/table-loader", &FwCfgItem, &FwCfgSize);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (FwCfgSize % sizeof *LoaderEntry != 0) {
    DEBUG ((
      DEBUG_ERROR,
      "%a: \"etc/table-loader\" has invalid size 0x%Lx\n",
      __func__,
      (UINT64)FwCfgSize
      ));
    return EFI_PROTOCOL_ERROR;
  }

  LoaderStart = AllocatePool (FwCfgSize);
  if (LoaderStart == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  EnablePciDecoding (&OriginalPciAttributes, &OriginalPciAttributesCount);
  QemuFwCfgSelectItem (FwCfgItem);
  QemuFwCfgReadBytes (FwCfgSize, LoaderStart);
  RestorePciDecoding (OriginalPciAttributes, OriginalPciAttributesCount);

  //
  // Measure the "etc/table-loader" which is downloaded from QEMU.
  // It has to be done before it is consumed. Because it would be
  // updated in the following operations.
  //
  TpmMeasureAndLogData (
    1,
    EV_PLATFORM_CONFIG_FLAGS,
    EV_POSTCODE_INFO_ACPI_DATA,
    ACPI_DATA_LEN,
    (VOID *)(UINTN)LoaderStart,
    FwCfgSize
    );

  LoaderEnd = LoaderStart + FwCfgSize / sizeof *LoaderEntry;

  AllocationsRestrictedTo32Bit = NULL;
  Status                       = CollectAllocationsRestrictedTo32Bit (
                                   &AllocationsRestrictedTo32Bit,
                                   LoaderStart,
                                   LoaderEnd
                                   );
  if (EFI_ERROR (Status)) {
    goto FreeLoader;
  }

  S3Context = NULL;
  if (QemuFwCfgS3Enabled ()) {
    //
    // Size the allocation pessimistically, assuming that all commands in the
    // script are QEMU_LOADER_WRITE_POINTER commands.
    //
    Status = AllocateS3Context (&S3Context, LoaderEnd - LoaderStart);
    if (EFI_ERROR (Status)) {
      goto FreeAllocationsRestrictedTo32Bit;
    }
  }

  Tracker = OrderedCollectionInit (BlobCompare, BlobKeyCompare);
  if (Tracker == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto FreeS3Context;
  }

  //
  // first pass: process the commands
  //
  // "WritePointerSubsetEnd" points one past the last successful
  // QEMU_LOADER_WRITE_POINTER command. Now when we're about to start the first
  // pass, no such command has been encountered yet.
  //
  WritePointerSubsetEnd = LoaderStart;
  for (LoaderEntry = LoaderStart; LoaderEntry < LoaderEnd; ++LoaderEntry) {
    switch (LoaderEntry->Type) {
      case QemuLoaderCmdAllocate:
        Status = ProcessCmdAllocate (
                   &LoaderEntry->Command.Allocate,
                   Tracker,
                   AllocationsRestrictedTo32Bit
                   );
        break;

      case QemuLoaderCmdAddPointer:
        Status = ProcessCmdAddPointer (
                   &LoaderEntry->Command.AddPointer,
                   Tracker
                   );
        break;

      case QemuLoaderCmdAddChecksum:
        Status = ProcessCmdAddChecksum (
                   &LoaderEntry->Command.AddChecksum,
                   Tracker
                   );
        break;

      case QemuLoaderCmdWritePointer:
        Status = ProcessCmdWritePointer (
                   &LoaderEntry->Command.WritePointer,
                   Tracker,
                   S3Context
                   );
        if (!EFI_ERROR (Status)) {
          WritePointerSubsetEnd = LoaderEntry + 1;
        }

        break;

      default:
        DEBUG ((
          DEBUG_VERBOSE,
          "%a: unknown loader command: 0x%x\n",
          __func__,
          LoaderEntry->Type
          ));
        break;
    }

    if (EFI_ERROR (Status)) {
      goto RollbackWritePointersAndFreeTracker;
    }
  }

  InstalledKey = AllocatePool (INSTALLED_TABLES_MAX * sizeof *InstalledKey);
  if (InstalledKey == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto RollbackWritePointersAndFreeTracker;
  }

  SeenPointers = OrderedCollectionInit (PointerCompare, PointerCompare);
  if (SeenPointers == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto FreeKeys;
  }

  //
  // second pass: identify and install ACPI tables
  //
  Installed = 0;
  for (LoaderEntry = LoaderStart; LoaderEntry < LoaderEnd; ++LoaderEntry) {
    if (LoaderEntry->Type == QemuLoaderCmdAddPointer) {
      Status = Process2ndPassCmdAddPointer (
                 &LoaderEntry->Command.AddPointer,
                 Tracker,
                 AcpiProtocol,
                 InstalledKey,
                 &Installed,
                 SeenPointers
                 );
      if (EFI_ERROR (Status)) {
        goto UninstallAcpiTables;
      }
    }
  }

  //
  // Install a protocol to notify that the ACPI table provided by Qemu is
  // ready.
  //
  QemuAcpiHandle = NULL;
  Status         = gBS->InstallProtocolInterface (
                          &QemuAcpiHandle,
                          &gQemuAcpiTableNotifyProtocolGuid,
                          EFI_NATIVE_INTERFACE,
                          NULL
                          );
  if (EFI_ERROR (Status)) {
    goto UninstallAcpiTables;
  }

  //
  // Translating the condensed QEMU_LOADER_WRITE_POINTER commands to ACPI S3
  // Boot Script opcodes has to be the last operation in this function, because
  // if it succeeds, it cannot be undone.
  //
  if (S3Context != NULL) {
    Status = TransferS3ContextToBootScript (S3Context);
    if (EFI_ERROR (Status)) {
      goto UninstallQemuAcpiTableNotifyProtocol;
    }

    //
    // Ownership of S3Context has been transferred.
    //
    S3Context = NULL;
  }

  DEBUG ((DEBUG_INFO, "%a: installed %d tables\n", __func__, Installed));

UninstallQemuAcpiTableNotifyProtocol:
  if (EFI_ERROR (Status)) {
    gBS->UninstallProtocolInterface (
           QemuAcpiHandle,
           &gQemuAcpiTableNotifyProtocolGuid,
           NULL
           );
  }

UninstallAcpiTables:
  if (EFI_ERROR (Status)) {
    //
    // roll back partial installation
    //
    while (Installed > 0) {
      --Installed;
      AcpiProtocol->UninstallAcpiTable (AcpiProtocol, InstalledKey[Installed]);
    }
  }

  for (SeenPointerEntry = OrderedCollectionMin (SeenPointers);
       SeenPointerEntry != NULL;
       SeenPointerEntry = SeenPointerEntry2)
  {
    SeenPointerEntry2 = OrderedCollectionNext (SeenPointerEntry);
    OrderedCollectionDelete (SeenPointers, SeenPointerEntry, NULL);
  }

  OrderedCollectionUninit (SeenPointers);

FreeKeys:
  FreePool (InstalledKey);

RollbackWritePointersAndFreeTracker:
  //
  // In case of failure, revoke any allocation addresses that were communicated
  // to QEMU previously, before we release all the blobs.
  //
  if (EFI_ERROR (Status)) {
    LoaderEntry = WritePointerSubsetEnd;
    while (LoaderEntry > LoaderStart) {
      --LoaderEntry;
      if (LoaderEntry->Type == QemuLoaderCmdWritePointer) {
        UndoCmdWritePointer (&LoaderEntry->Command.WritePointer);
      }
    }
  }

  //
  // Tear down the tracker infrastructure. Each fw_cfg blob will be left in
  // place only if we're exiting with success and the blob hosts data that is
  // not directly part of some ACPI table.
  //
  for (TrackerEntry = OrderedCollectionMin (Tracker); TrackerEntry != NULL;
       TrackerEntry = TrackerEntry2)
  {
    VOID  *UserStruct;
    BLOB  *Blob;

    TrackerEntry2 = OrderedCollectionNext (TrackerEntry);
    OrderedCollectionDelete (Tracker, TrackerEntry, &UserStruct);
    Blob = UserStruct;

    if (EFI_ERROR (Status) || Blob->HostsOnlyTableData) {
      DEBUG ((
        DEBUG_VERBOSE,
        "%a: freeing \"%a\"\n",
        __func__,
        Blob->File
        ));
      gBS->FreePages ((UINTN)Blob->Base, EFI_SIZE_TO_PAGES (Blob->Size));
    }

    FreePool (Blob);
  }

  OrderedCollectionUninit (Tracker);

FreeS3Context:
  if (S3Context != NULL) {
    ReleaseS3Context (S3Context);
  }

FreeAllocationsRestrictedTo32Bit:
  ReleaseAllocationsRestrictedTo32Bit (AllocationsRestrictedTo32Bit);

FreeLoader:
  FreePool (LoaderStart);

  return Status;
}
