From 4b38f8f132b10c038de87b52ee6d97c84656293c Mon Sep 17 00:00:00 2001
From: Colin Xu <colin.xu@intel.com>
Date: Thu, 27 May 2021 16:36:37 +0800
Subject: [PATCH] OvmfPkg/PlatformPei: Reserve IGD Stolen in E820.

Read DSM info from QemuFwCfg and reserve in E820.

Signed-off-by: Colin Xu <colin.xu@intel.com>
---
 OvmfPkg/PlatformPei/Platform.c | 46 ++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c
index 96468701e3b8..4a883e965b17 100644
--- a/OvmfPkg/PlatformPei/Platform.c
+++ b/OvmfPkg/PlatformPei/Platform.c
@@ -457,6 +457,50 @@ ReserveEmuVariableNvStore (
   ASSERT_RETURN_ERROR (PcdStatus);
 }
 
+#define INTEL_PCI_VENDOR_ID 0x8086
+#define PCI_BUS_NUM_IGD     0
+#define PCI_DEV_NUM_IGD     2
+#define PCI_FUNC_NUM_IGD    0
+
+VOID
+ReserveIgdStolen (
+  )
+{
+  UINT16 VendorId = PciRead16 (PCI_LIB_ADDRESS (PCI_BUS_NUM_IGD, PCI_DEV_NUM_IGD, PCI_FUNC_NUM_IGD, PCI_VENDOR_ID_OFFSET));
+  UINT8 Class = PciRead8 (PCI_LIB_ADDRESS (PCI_BUS_NUM_IGD, PCI_DEV_NUM_IGD, PCI_FUNC_NUM_IGD, PCI_CLASSCODE_OFFSET + 2));
+
+  if (VendorId == INTEL_PCI_VENDOR_ID && Class == PCI_CLASS_DISPLAY) {
+    EFI_STATUS FwCfgStatus = 0;
+    FIRMWARE_CONFIG_ITEM FwCfgItem;
+    UINTN                FwCfgItemSize;
+    UINT64 StolenBase = 0;
+    UINT64 StolenSize = 0;
+
+    FwCfgStatus = QemuFwCfgFindFile ("etc/igd-dsm-base", &FwCfgItem, &FwCfgItemSize);
+    if (EFI_ERROR (FwCfgStatus) || FwCfgItemSize != sizeof(StolenBase)) {
+        return;
+    }
+    QemuFwCfgSelectItem (FwCfgItem);
+    QemuFwCfgReadBytes (FwCfgItemSize, &StolenBase);
+
+    FwCfgStatus = QemuFwCfgFindFile ("etc/igd-dsm-size", &FwCfgItem, &FwCfgItemSize);
+    if (EFI_ERROR (FwCfgStatus) || FwCfgItemSize != sizeof(StolenSize)) {
+        return;
+    }
+    QemuFwCfgSelectItem (FwCfgItem);
+    QemuFwCfgReadBytes (FwCfgItemSize, &StolenSize);
+
+    if (StolenBase && StolenSize) {
+      BuildMemoryAllocationHob (
+        StolenBase,
+        StolenSize,
+        EfiReservedMemoryType
+        );
+
+      DEBUG ((DEBUG_INFO, "IGD stolen memory at %llx, size %x\n", StolenBase, StolenSize));
+    }
+  }
+}
 
 VOID
 DebugDumpCmos (
@@ -705,6 +749,8 @@ InitializePlatform (
 
   XenDetect ();
 
+  ReserveIgdStolen ();
+
   if (QemuFwCfgS3Enabled ()) {
     DEBUG ((DEBUG_INFO, "S3 support was detected on QEMU\n"));
     mS3Supported = TRUE;
-- 
2.31.1

