/** @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/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>

#include "AcpiPlatform.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", __FUNCTION__));
      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",
          __FUNCTION__,
          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", __FUNCTION__));
    return EFI_PROTOCOL_ERROR;
  }

  if (Allocate->Alignment > EFI_PAGE_SIZE) {
    DEBUG ((
      DEBUG_ERROR,
      "%a: unsupported alignment 0x%x\n",
      __FUNCTION__,
      Allocate->Alignment
      ));
    return EFI_UNSUPPORTED;
  }

  Status = QemuFwCfgFindFile ((CHAR8 *)Allocate->File, &FwCfgItem, &FwCfgSize);
  if (EFI_ERROR (Status)) {
    DEBUG ((
      DEBUG_ERROR,
      "%a: QemuFwCfgFindFile(\"%a\"): %r\n",
      __FUNCTION__,
      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",
      __FUNCTION__,
      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",
    __FUNCTION__,
    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", __FUNCTION__));
    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",
      __FUNCTION__,
      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",
      __FUNCTION__,
      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",
      __FUNCTION__,
      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",
      __FUNCTION__,
      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",
    __FUNCTION__,
    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", __FUNCTION__));
    return EFI_PROTOCOL_ERROR;
  }

  TrackerEntry = OrderedCollectionFind (Tracker, AddChecksum->File);
  if (TrackerEntry == NULL) {
    DEBUG ((
      DEBUG_ERROR,
      "%a: invalid blob reference \"%a\"\n",
      __FUNCTION__,
      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",
      __FUNCTION__,
      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",
    __FUNCTION__,
    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", __FUNCTION__));
    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",
      __FUNCTION__,
      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",
      __FUNCTION__,
      WritePointer->PointerFile
      ));
    return EFI_PROTOCOL_ERROR;
  }

  PointeeBlob  = OrderedCollectionUserStruct (PointeeEntry);
  PointerValue = WritePointer->PointeeOffset;
  if (PointerValue >= PointeeBlob->Size) {
    DEBUG ((DEBUG_ERROR, "%a: invalid PointeeOffset\n", __FUNCTION__));
    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",
      __FUNCTION__,
      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",
    __FUNCTION__,
    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",
    __FUNCTION__,
    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",
        __FUNCTION__,
        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): ",
    __FUNCTION__,
    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",
      __FUNCTION__,
      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",
      __FUNCTION__,
      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",
      __FUNCTION__,
      (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",
          __FUNCTION__,
          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", __FUNCTION__, 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",
        __FUNCTION__,
        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;
}
