diff --git a/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf b/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
index 90178e0..3229d71 100644
--- a/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
+++ b/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
@@ -51,6 +51,7 @@
   MemoryAllocationLib
   BaseLib
   DxeServicesTableLib
+  OrderedCollectionLib
 
 [Protocols]
   gEfiAcpiTableProtocolGuid                     # PROTOCOL ALWAYS_CONSUMED
diff --git a/OvmfPkg/AcpiPlatformDxe/Qemu.c b/OvmfPkg/AcpiPlatformDxe/Qemu.c
index ef2ba11..0e01c37 100644
--- a/OvmfPkg/AcpiPlatformDxe/Qemu.c
+++ b/OvmfPkg/AcpiPlatformDxe/Qemu.c
@@ -22,6 +22,7 @@
 #include <Library/QemuFwCfgLib.h>
 #include <Library/DxeServicesTableLib.h>
 #include <Library/PcdLib.h>
+#include <Library/OrderedCollectionLib.h>
 #include <IndustryStandard/Acpi.h>
 
 BOOLEAN
@@ -517,12 +518,530 @@ QemuInstallAcpiTable (
 }
 
 
+//
+// 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;
+
+
 /**
-  Download all ACPI table data files from QEMU and interpret them.
+  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);
+}
+
+
+/**
+  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.
+
+  @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
+  )
+{
+  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 ((EFI_D_ERROR, "%a: malformed file name\n", __FUNCTION__));
+    return EFI_PROTOCOL_ERROR;
+  }
+
+  if (Allocate->Alignment > EFI_PAGE_SIZE) {
+    DEBUG ((EFI_D_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 ((EFI_D_ERROR, "%a: QemuFwCfgFindFile(\"%a\"): %r\n", __FUNCTION__,
+      Allocate->File, Status));
+    return Status;
+  }
+
+  NumPages = EFI_SIZE_TO_PAGES (FwCfgSize);
+  Address = 0xFFFFFFFF;
+  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 ((EFI_D_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 ((EFI_D_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));
+  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 ((EFI_D_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 ((EFI_D_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 ((EFI_D_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 ((EFI_D_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 (RShiftU64 (
+        RShiftU64 (PointerValue, AddPointer->PointerSize * 8 - 1), 1) != 0) {
+    DEBUG ((EFI_D_ERROR, "%a: relocated pointer value unrepresentable in "
+      "\"%a\"\n", __FUNCTION__, AddPointer->PointerFile));
+    return EFI_PROTOCOL_ERROR;
+  }
+
+  CopyMem (PointerField, &PointerValue, AddPointer->PointerSize);
+
+  DEBUG ((EFI_D_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 ((EFI_D_ERROR, "%a: malformed file name\n", __FUNCTION__));
+    return EFI_PROTOCOL_ERROR;
+  }
+
+  TrackerEntry = OrderedCollectionFind (Tracker, AddChecksum->File);
+  if (TrackerEntry == NULL) {
+    DEBUG ((EFI_D_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 ((EFI_D_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 ((EFI_D_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;
+}
+
+
+//
+// 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 successfuly 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.
+
+  @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 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
+  )
+{
+  CONST ORDERED_COLLECTION_ENTRY                     *TrackerEntry;
+  CONST ORDERED_COLLECTION_ENTRY                     *TrackerEntry2;
+  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);
+
+  Blob2Remaining -= PointerValue;
+  DEBUG ((EFI_D_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 ((EFI_D_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 &&
+        (
+         (AsciiStrnCmp ((CONST CHAR8 *)Header->OemId, "BOCHS ",
+            sizeof Header->OemId) == 0 &&
+          AsciiStrnCmp ((CONST CHAR8 *)&Header->OemTableId, "BXPC", 4) == 0
+          ) ||
+         (CompareMem (Header->OemId, "BXPC\0", sizeof Header->OemId) == 0 &&
+          CompareMem (&Header->OemTableId, "BXDSDT\0",
+            sizeof Header->OemTableId) == 0
+          )
+         )
+        ) {
+      //
+      // This looks very much like an ACPI table from QEMU:
+      // - Length field consistent with both ACPI and containing blob size
+      // - checksum is correct
+      // - 10-byte signature checks out
+      //
+      DEBUG ((EFI_D_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 ((EFI_D_VERBOSE, "not found; marking fw_cfg blob as opaque\n"));
+    Blob2->HostsOnlyTableData = FALSE;
+    return EFI_SUCCESS;
+  }
+
+  if (*NumInstalled == INSTALLED_TABLES_MAX) {
+    DEBUG ((EFI_D_ERROR, "%a: can't install more than %d tables\n",
+      __FUNCTION__, INSTALLED_TABLES_MAX));
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Status = AcpiProtocol->InstallAcpiTable (AcpiProtocol,
+                           (VOID *)(UINTN)PointerValue, TableSize,
+                           &InstalledKey[*NumInstalled]);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "%a: InstallAcpiTable(): %r\n", __FUNCTION__,
+      Status));
+    return Status;
+  }
+  ++*NumInstalled;
+  return EFI_SUCCESS;
+}
+
+
+/**
+  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.
+  @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.
@@ -536,12 +1055,136 @@ QemuInstallAcpiTable (
                                  AcpiProtocol->InstallAcpiTable().
 
 **/
-
 EFI_STATUS
 EFIAPI
 InstallAllQemuLinkedTables (
   IN   EFI_ACPI_TABLE_PROTOCOL       *AcpiProtocol
   )
 {
-  return EFI_NOT_FOUND;
+  EFI_STATUS               Status;
+  FIRMWARE_CONFIG_ITEM     FwCfgItem;
+  UINTN                    FwCfgSize;
+  QEMU_LOADER_ENTRY        *LoaderStart;
+  CONST QEMU_LOADER_ENTRY  *LoaderEntry, *LoaderEnd;
+  ORDERED_COLLECTION       *Tracker;
+  UINTN                    *InstalledKey;
+  INT32                    Installed;
+  ORDERED_COLLECTION_ENTRY *TrackerEntry, *TrackerEntry2;
+
+  Status = QemuFwCfgFindFile ("etc/table-loader", &FwCfgItem, &FwCfgSize);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  if (FwCfgSize % sizeof *LoaderEntry != 0) {
+    DEBUG ((EFI_D_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;
+  }
+  QemuFwCfgSelectItem (FwCfgItem);
+  QemuFwCfgReadBytes (FwCfgSize, LoaderStart);
+  LoaderEnd = LoaderStart + FwCfgSize / sizeof *LoaderEntry;
+
+  Tracker = OrderedCollectionInit (BlobCompare, BlobKeyCompare);
+  if (Tracker == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto FreeLoader;
+  }
+
+  //
+  // first pass: process the commands
+  //
+  for (LoaderEntry = LoaderStart; LoaderEntry < LoaderEnd; ++LoaderEntry) {
+    switch (LoaderEntry->Type) {
+    case QemuLoaderCmdAllocate:
+      Status = ProcessCmdAllocate (&LoaderEntry->Command.Allocate, Tracker);
+      break;
+
+    case QemuLoaderCmdAddPointer:
+      Status = ProcessCmdAddPointer (&LoaderEntry->Command.AddPointer,
+                 Tracker);
+      break;
+
+    case QemuLoaderCmdAddChecksum:
+      Status = ProcessCmdAddChecksum (&LoaderEntry->Command.AddChecksum,
+                 Tracker);
+      break;
+
+    default:
+      DEBUG ((EFI_D_VERBOSE, "%a: unknown loader command: 0x%x\n",
+        __FUNCTION__, LoaderEntry->Type));
+      break;
+    }
+
+    if (EFI_ERROR (Status)) {
+      goto FreeTracker;
+    }
+  }
+
+  InstalledKey = AllocatePool (INSTALLED_TABLES_MAX * sizeof *InstalledKey);
+  if (InstalledKey == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto FreeTracker;
+  }
+
+  //
+  // 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);
+      if (EFI_ERROR (Status)) {
+        break;
+      }
+    }
+  }
+
+  if (EFI_ERROR (Status)) {
+    //
+    // roll back partial installation
+    //
+    while (Installed > 0) {
+      --Installed;
+      AcpiProtocol->UninstallAcpiTable (AcpiProtocol, InstalledKey[Installed]);
+    }
+  } else {
+    DEBUG ((EFI_D_INFO, "%a: installed %d tables\n", __FUNCTION__, Installed));
+  }
+
+  FreePool (InstalledKey);
+
+FreeTracker:
+  //
+  // 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 ((EFI_D_VERBOSE, "%a: freeing \"%a\"\n", __FUNCTION__,
+        Blob->File));
+      gBS->FreePages ((UINTN)Blob->Base, EFI_SIZE_TO_PAGES (Blob->Size));
+    }
+    FreePool (Blob);
+  }
+  OrderedCollectionUninit (Tracker);
+
+FreeLoader:
+  FreePool (LoaderStart);
+
+  return Status;
 }
