Currently IVRS feature report values are hardcoded, this is difficult to
maintain as any updates to extended feature must be synced. Along with
it current feature report does not have GATS and HATS set. Hence use
the extended feature registers to build the IVRS feature report.

Signed-off-by: Sairaj Kodilkar <[email protected]>
---
 hw/i386/acpi-build.c | 38 +++++++++++++++++++++++++++++++-------
 hw/i386/acpi-build.h |  1 -
 2 files changed, 31 insertions(+), 8 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 718e3f546b18..82208e06e155 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1747,6 +1747,36 @@ ivrs_host_bridges(Object *obj, void *opaque)
     return 0;
 }
 
+/*
+ * IVHD type 0x10 reports features using Feature Reporting field, which has
+ * different format than extended feature register (EFR) in the IOMMU MMIO
+ * space.
+ *
+ * Convert the EFR format to feature reporting format.
+ */
+static uint32_t
+get_amd_ivhd_feature_report(AMDVIState *s)
+{
+    uint64_t feature = amdvi_extended_feature_register(s);
+    uint32_t is_gt = !!(feature & AMDVI_FEATURE_GT);
+    uint32_t is_ga = !!(feature & AMDVI_FEATURE_GA);
+    uint64_t glx_sup = (feature & AMDVI_GLX_SUP_MASK) >> AMDVI_GLX_SUP_SHIFT;
+    uint64_t hats_mode = (feature & AMDVI_HATS_MODE_MASK) >>
+                         AMDVI_HATS_MODE_SHIFT;
+    uint64_t gats_mode = (feature & AMDVI_GATS_MODE_MASK) >>
+                         AMDVI_GATS_MODE_SHIFT;
+    uint32_t feature_report;
+
+    feature_report = s->xtsup << AMD_IVHD_FEATURE_REPORT_XT_SUP_SHIFT |
+                     is_gt << AMD_IVHD_FEATURE_REPORT_GT_SUP_SHIFT |
+                     glx_sup << AMD_IVHD_FEATURE_REPORT_GLX_SUP_SHIFT |
+                     is_ga << AMD_IVHD_FEATURE_REPORT_GA_SUP_SHIFT |
+                     hats_mode << AMD_IVHD_FEATURE_REPORT_HATS_SHIFT |
+                     gats_mode << AMD_IVHD_FEATURE_REPORT_GATS_SHIFT;
+
+    return feature_report;
+}
+
 static void
 build_amd_iommu(GArray *table_data, BIOSLinker *linker, const char *oem_id,
                 const char *oem_table_id)
@@ -1829,13 +1859,7 @@ build_amd_iommu(GArray *table_data, BIOSLinker *linker, 
const char *oem_id,
     /* IOMMU info */
     build_append_int_noprefix(table_data, 0, 2);
     /* IOMMU Feature Reporting */
-    feature_report = (48UL << 30) | /* HATS   */
-                     (48UL << 28) | /* GATS   */
-                     (1UL << 2)   | /* GTSup  */
-                     (1UL << 6);    /* GASup  */
-    if (s->xtsup) {
-        feature_report |= (1UL << 0); /* XTSup */
-    }
+    feature_report = get_amd_ivhd_feature_report(s);
     build_append_int_noprefix(table_data, feature_report, 4);
 
     /* IVHD entries as found above */
diff --git a/hw/i386/acpi-build.h b/hw/i386/acpi-build.h
index 9fd60a186db1..d81b7890e6e2 100644
--- a/hw/i386/acpi-build.h
+++ b/hw/i386/acpi-build.h
@@ -1,4 +1,3 @@
-
 #ifndef HW_I386_ACPI_BUILD_H
 #define HW_I386_ACPI_BUILD_H
 #include "hw/acpi/acpi-defs.h"
-- 
2.34.1


Reply via email to