]> xenbits.xensource.com Git - xen.git/commitdiff
amd iommu: Advertise iommu extended feature bits to xen.
authorWei Wang <wei.wang2@amd.com>
Tue, 22 Nov 2011 13:25:42 +0000 (13:25 +0000)
committerWei Wang <wei.wang2@amd.com>
Tue, 22 Nov 2011 13:25:42 +0000 (13:25 +0000)
Signed-off-by: Wei Wang <wei.wang2@amd.com>
Committed-by: Keir Fraser <keir@xen.org>
xen/drivers/passthrough/amd/iommu_detect.c
xen/drivers/passthrough/amd/iommu_init.c
xen/include/asm-x86/amd-iommu.h
xen/include/asm-x86/hvm/svm/amd-iommu-defs.h
xen/include/asm-x86/hvm/svm/amd-iommu-proto.h

index e0bce2d390b9976e2059ce8a161c4a7d62557161..0bf933b1103dc05a48332b5140dec9d34bba53dc 100644 (file)
@@ -62,6 +62,47 @@ static int __init get_iommu_capabilities(
     return 0;
 }
 
+void __init get_iommu_features(struct amd_iommu *iommu)
+{
+    u32 low, high;
+    int i = 0 ;
+    char * feature_str[] = {
+        "- Prefetch Pages Command", 
+        "- Peripheral Page Service Request", 
+        "- X2APIC Supported", 
+        "- NX bit Supported", 
+        "- Guest Translation", 
+        "- Reserved bit [5]",
+        "- Invalidate All Command", 
+        "- Guest APIC supported", 
+        "- Hardware Error Registers", 
+        "- Performance Counters", 
+        NULL
+    };
+
+    ASSERT( iommu->mmio_base );
+
+    if ( !iommu_has_cap(iommu, PCI_CAP_EFRSUP_SHIFT) )
+    {
+        iommu->features = 0;
+        return;
+    }
+
+    low = readl(iommu->mmio_base + IOMMU_EXT_FEATURE_MMIO_OFFSET);
+    high = readl(iommu->mmio_base + IOMMU_EXT_FEATURE_MMIO_OFFSET + 4);
+
+    iommu->features = ((u64)high << 32) | low;
+
+    printk("AMD-Vi: IOMMU Extended Features:\n");
+
+    while ( feature_str[i] )
+    {
+        if ( iommu_has_feature(iommu, i) )
+            printk( " %s\n", feature_str[i]);
+        i++;
+    }
+}
+
 int __init amd_iommu_detect_one_acpi(void *ivhd)
 {
     struct amd_iommu *iommu;
index 9ccd1f497d5d5103189b1d48d743a7f2d9ae4341..854d092e513101b03e8f8113a33d8a659e0daa49 100644 (file)
@@ -684,6 +684,8 @@ static int __init amd_iommu_init_one(struct amd_iommu *iommu)
     iommu->dev_table.entries = device_table.entries;
     iommu->dev_table.buffer = device_table.buffer;
 
+    get_iommu_features(iommu);
+
     enable_iommu(iommu);
     printk("AMD-Vi: IOMMU %d Enabled.\n", nr_amd_iommus );
     nr_amd_iommus++;
index 9346da88b000adb333491e0de9f430302bb61f4b..876d9b998a87d7d57e942bb77aae3775f5c76e6c 100644 (file)
@@ -54,6 +54,7 @@ struct amd_iommu {
     iommu_cap_t cap;
 
     u8 ht_flags;
+    u64 features;
 
     void *mmio_base;
     unsigned long mmio_base_phys;
index b5c35b002793488d23ec8bf2158d10146b8e794b..59d33e98d0d280588a0c4731ef37d77bf96fc041 100644 (file)
@@ -54,6 +54,7 @@
 #define PCI_CAP_HT_TUNNEL_SHIFT        25
 #define PCI_CAP_NP_CACHE_MASK  0x04000000
 #define PCI_CAP_NP_CACHE_SHIFT 26
+#define PCI_CAP_EFRSUP_SHIFT    27
 #define PCI_CAP_RESET_MASK     0x80000000
 #define PCI_CAP_RESET_SHIFT    31
 
 #define IOMMU_EXCLUSION_LIMIT_HIGH_MASK                0xFFFFFFFF
 #define IOMMU_EXCLUSION_LIMIT_HIGH_SHIFT       0
 
+/* Extended Feature Register*/
+#define IOMMU_EXT_FEATURE_MMIO_OFFSET                   0x30
+#define IOMMU_EXT_FEATURE_PREFSUP_SHIFT                 0x0
+#define IOMMU_EXT_FEATURE_PPRSUP_SHIFT                  0x1
+#define IOMMU_EXT_FEATURE_XTSUP_SHIFT                   0x2
+#define IOMMU_EXT_FEATURE_NXSUP_SHIFT                   0x3
+#define IOMMU_EXT_FEATURE_GTSUP_SHIFT                   0x4
+#define IOMMU_EXT_FEATURE_IASUP_SHIFT                   0x6
+#define IOMMU_EXT_FEATURE_GASUP_SHIFT                   0x7
+#define IOMMU_EXT_FEATURE_HESUP_SHIFT                   0x8
+#define IOMMU_EXT_FEATURE_PCSUP_SHIFT                   0x9
+#define IOMMU_EXT_FEATURE_HATS_SHIFT                    0x10
+#define IOMMU_EXT_FEATURE_HATS_MASK                     0x00000C00
+#define IOMMU_EXT_FEATURE_GATS_SHIFT                    0x12
+#define IOMMU_EXT_FEATURE_GATS_MASK                     0x00003000
+#define IOMMU_EXT_FEATURE_GLXSUP                        0x14
+
+#define IOMMU_EXT_FEATURE_PASMAX_SHIFT                  0x0
+#define IOMMU_EXT_FEATURE_PASMAX_MASK                   0x0000001F
+
 /* Status Register*/
 #define IOMMU_STATUS_MMIO_OFFSET               0x2020
 #define IOMMU_STATUS_EVENT_OVERFLOW_MASK       0x00000001
index c67f463f8b90247fe7e68381fd202117913e33c8..c639bf54c7c5bfa0fdcfbc001429daf26fd29790 100644 (file)
@@ -43,6 +43,7 @@
 int amd_iommu_get_ivrs_dev_entries(void);
 int amd_iommu_detect_one_acpi(void *ivhd);
 int amd_iommu_detect_acpi(void);
+void get_iommu_features(struct amd_iommu *iommu);
 
 /* amd-iommu-init functions */
 int amd_iommu_init(void);
@@ -183,8 +184,14 @@ static inline uint32_t iommu_get_bit(uint32_t reg, uint32_t bit)
 
 static inline int iommu_has_cap(struct amd_iommu *iommu, uint32_t bit)
 {
-    u32 mask = 1U << bit;
-    return iommu->cap.header & mask;
+    return !!(iommu->cap.header & (1u << bit));
+}
+
+static inline int iommu_has_feature(struct amd_iommu *iommu, uint32_t bit)
+{
+    if ( !iommu_has_cap(iommu, PCI_CAP_EFRSUP_SHIFT) )
+        return 0;
+    return !!(iommu->features & (1U << bit));
 }
 
 #endif /* _ASM_X86_64_AMD_IOMMU_PROTO_H */