[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-3.2-testing] vt-d: Clean up and bug fixes to ioapic handling.



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1200664342 0
# Node ID f732c684c3d7394ecfc20568edd3a70d032f63c2
# Parent  eb437e9fc19b2f7c73981be9254eb965d2e9e8f7
vt-d: Clean up and bug fixes to ioapic handling.
Signed-off-by: Allen Kay <allen.m.kay@xxxxxxxxx>
xen-unstable changeset:   16753:2633dc4f55d4010d7d64e9c6a1cf0b28707c7950
xen-unstable date:        Fri Jan 18 13:41:33 2008 +0000
---
 xen/arch/x86/hvm/vmx/vtd/dmar.c           |  223 +++++++++++++++++++-----------
 xen/arch/x86/hvm/vmx/vtd/dmar.h           |   31 ++--
 xen/arch/x86/hvm/vmx/vtd/utils.c          |    9 -
 xen/include/asm-x86/hvm/vmx/intel-iommu.h |   93 +++++++++---
 4 files changed, 234 insertions(+), 122 deletions(-)

diff -r eb437e9fc19b -r f732c684c3d7 xen/arch/x86/hvm/vmx/vtd/dmar.c
--- a/xen/arch/x86/hvm/vmx/vtd/dmar.c   Fri Jan 18 13:51:53 2008 +0000
+++ b/xen/arch/x86/hvm/vmx/vtd/dmar.c   Fri Jan 18 13:52:22 2008 +0000
@@ -43,7 +43,6 @@ LIST_HEAD(acpi_drhd_units);
 LIST_HEAD(acpi_drhd_units);
 LIST_HEAD(acpi_rmrr_units);
 LIST_HEAD(acpi_atsr_units);
-LIST_HEAD(acpi_ioapic_units);
 
 u8 dmar_host_address_width;
 
@@ -66,6 +65,47 @@ static int __init acpi_register_rmrr_uni
     return 0;
 }
 
+static int acpi_ioapic_device_match(
+    struct list_head *ioapic_list, unsigned int apic_id)
+{
+    struct acpi_ioapic_unit *ioapic;
+    list_for_each_entry( ioapic, ioapic_list, list ) {
+        if (ioapic->apic_id == apic_id)
+            return 1;
+    }
+    return 0;
+}
+
+struct acpi_drhd_unit * ioapic_to_drhd(unsigned int apic_id)
+{
+    struct acpi_drhd_unit *drhd;
+    list_for_each_entry( drhd, &acpi_drhd_units, list ) {
+        if ( acpi_ioapic_device_match(&drhd->ioapic_list, apic_id) ) {
+            dprintk(XENLOG_INFO VTDPREFIX,
+                    "ioapic_to_drhd: drhd->address = %lx\n",
+                    drhd->address);
+            return drhd;
+        }
+    }
+    return NULL;
+}
+
+struct iommu * ioapic_to_iommu(unsigned int apic_id)
+{
+    struct acpi_drhd_unit *drhd;
+
+    list_for_each_entry( drhd, &acpi_drhd_units, list ) {
+        if ( acpi_ioapic_device_match(&drhd->ioapic_list, apic_id) ) {
+            dprintk(XENLOG_INFO VTDPREFIX,
+                    "ioapic_to_iommu: drhd->address = %lx\n",
+                    drhd->address);
+            return drhd->iommu;
+        }
+    }
+    dprintk(XENLOG_WARNING VTDPREFIX, "returning NULL\n");
+    return NULL;
+}
+
 static int acpi_pci_device_match(struct pci_dev *devices, int cnt,
                                  struct pci_dev *dev)
 {
@@ -111,18 +151,18 @@ struct acpi_drhd_unit * acpi_find_matche
         if ( acpi_pci_device_match(drhd->devices,
                                    drhd->devices_cnt, dev) )
         {
-            gdprintk(XENLOG_INFO VTDPREFIX, 
-                     "acpi_find_matched_drhd_unit: drhd->address = %lx\n",
-                     drhd->address);
+            dprintk(XENLOG_INFO VTDPREFIX, 
+                    "acpi_find_matched_drhd_unit: drhd->address = %lx\n",
+                    drhd->address);
             return drhd;
         }
     }
 
     if ( include_all_drhd )
     {
-        gdprintk(XENLOG_INFO VTDPREFIX, 
-                 "acpi_find_matched_drhd_unit:include_all_drhd->addr = %lx\n",
-                 include_all_drhd->address);
+        dprintk(XENLOG_INFO VTDPREFIX, 
+                "acpi_find_matched_drhd_unit:include_all_drhd->addr = %lx\n",
+                include_all_drhd->address);
         return include_all_drhd;
     }
 
@@ -160,8 +200,8 @@ struct acpi_atsr_unit * acpi_find_matche
 
     if ( all_ports_atsru )
     {
-        gdprintk(XENLOG_INFO VTDPREFIX,
-                 "acpi_find_matched_atsr_unit: all_ports_atsru\n");
+        dprintk(XENLOG_INFO VTDPREFIX,
+                "acpi_find_matched_atsr_unit: all_ports_atsru\n");
         return all_ports_atsru;;
     }
 
@@ -180,9 +220,10 @@ static int scope_device_count(void *star
     while ( start < end )
     {
         scope = start;
-        if ( scope->length < MIN_SCOPE_LEN )
-        {
-            printk(KERN_WARNING PREFIX "Invalid device scope\n");
+        if ( (scope->length < MIN_SCOPE_LEN) ||
+             (scope->dev_type >= ACPI_DEV_ENTRY_COUNT) )
+        {
+            dprintk(XENLOG_WARNING VTDPREFIX, "Invalid device scope\n");
             return -EINVAL;
         }
 
@@ -199,16 +240,16 @@ static int scope_device_count(void *star
 
         if ( scope->dev_type == ACPI_DEV_ENDPOINT )
         {
-            printk(KERN_INFO PREFIX
-                   "found endpoint: bdf = %x:%x:%x\n",
-                   bus, path->dev, path->fn);
+            dprintk(XENLOG_INFO VTDPREFIX,
+                    "found endpoint: bdf = %x:%x:%x\n",
+                    bus, path->dev, path->fn);
             count++;
         }
         else if ( scope->dev_type == ACPI_DEV_P2PBRIDGE )
         {
-            printk(KERN_INFO PREFIX
-                   "found bridge: bdf = %x:%x:%x\n",
-                   bus, path->dev, path->fn);
+            dprintk(XENLOG_INFO VTDPREFIX,
+                    "found bridge: bdf = %x:%x:%x\n",
+                    bus, path->dev, path->fn);
             sec_bus = read_pci_config_byte(
                 bus, path->dev, path->fn, PCI_SECONDARY_BUS);
             sub_bus = read_pci_config_byte(
@@ -237,16 +278,16 @@ static int scope_device_count(void *star
         }
         else if ( scope->dev_type == ACPI_DEV_IOAPIC )
         {
-            printk(KERN_INFO PREFIX
-                   "found IOAPIC: bdf = %x:%x:%x\n",
-                   bus, path->dev, path->fn);
+            dprintk(XENLOG_INFO VTDPREFIX,
+                    "found IOAPIC: bdf = %x:%x:%x\n",
+                    bus, path->dev, path->fn);
             count++;
         }
         else
         {
-            printk(KERN_INFO PREFIX
-                   "found MSI HPET: bdf = %x:%x:%x\n",
-                   bus, path->dev, path->fn);
+            dprintk(XENLOG_INFO VTDPREFIX,
+                    "found MSI HPET: bdf = %x:%x:%x\n",
+                    bus, path->dev, path->fn);
             count++;
         }
 
@@ -256,8 +297,8 @@ static int scope_device_count(void *star
     return count;
 }
 
-static int __init acpi_parse_dev_scope(void *start, void *end, int *cnt,
-                                       struct pci_dev **devices)
+static int __init acpi_parse_dev_scope(
+    void *start, void *end, void *acpi_entry, int type)
 {
     struct acpi_dev_scope *scope;
     u8 bus, sub_bus, sec_bus;
@@ -268,10 +309,33 @@ static int __init acpi_parse_dev_scope(v
     u8 dev, func;
     u32 l;
 
+    int *cnt = NULL;
+    struct pci_dev **devices = NULL;
+    struct acpi_drhd_unit *dmaru = (struct acpi_drhd_unit *) acpi_entry;
+    struct acpi_rmrr_unit *rmrru = (struct acpi_rmrr_unit *) acpi_entry;
+    struct acpi_atsr_unit *atsru = (struct acpi_atsr_unit *) acpi_entry;
+
+    switch (type) {
+        case DMAR_TYPE:
+            cnt = &(dmaru->devices_cnt);
+            devices = &(dmaru->devices);
+            break;
+        case RMRR_TYPE:
+            cnt = &(rmrru->devices_cnt);
+            devices = &(rmrru->devices);
+            break;
+        case ATSR_TYPE:
+            cnt = &(atsru->devices_cnt);
+            devices = &(atsru->devices);
+            break;
+        default:
+            dprintk(XENLOG_ERR VTDPREFIX, "invalid vt-d acpi entry type\n");
+    }
+
     *cnt = scope_device_count(start, end);
     if ( *cnt == 0 )
     {
-        printk(KERN_INFO PREFIX "acpi_parse_dev_scope: no device\n");
+        dprintk(XENLOG_INFO VTDPREFIX, "acpi_parse_dev_scope: no device\n");
         return 0;
     }
 
@@ -298,18 +362,18 @@ static int __init acpi_parse_dev_scope(v
 
         if ( scope->dev_type == ACPI_DEV_ENDPOINT )
         {
-            printk(KERN_INFO PREFIX
-                   "found endpoint: bdf = %x:%x:%x\n",
-                   bus, path->dev, path->fn);
+            dprintk(XENLOG_INFO VTDPREFIX,
+                    "found endpoint: bdf = %x:%x:%x\n",
+                    bus, path->dev, path->fn);
             pdev->bus = bus;
             pdev->devfn = PCI_DEVFN(path->dev, path->fn);
             pdev++;
         }
         else if ( scope->dev_type == ACPI_DEV_P2PBRIDGE )
         {
-            printk(KERN_INFO PREFIX
-                   "found bridge: bus = %x dev = %x func = %x\n",
-                   bus, path->dev, path->fn);
+            dprintk(XENLOG_INFO VTDPREFIX,
+                    "found bridge: bus = %x dev = %x func = %x\n",
+                    bus, path->dev, path->fn);
             sec_bus = read_pci_config_byte(
                 bus, path->dev, path->fn, PCI_SECONDARY_BUS);
             sub_bus = read_pci_config_byte(
@@ -348,16 +412,15 @@ static int __init acpi_parse_dev_scope(v
             acpi_ioapic_unit->ioapic.bdf.bus = bus;
             acpi_ioapic_unit->ioapic.bdf.dev = path->dev;
             acpi_ioapic_unit->ioapic.bdf.func = path->fn;
-            list_add(&acpi_ioapic_unit->list, &acpi_ioapic_units);
-            printk(KERN_INFO PREFIX
-                   "found IOAPIC: bus = %x dev = %x func = %x\n",
-                   bus, path->dev, path->fn);
+            list_add(&acpi_ioapic_unit->list, &dmaru->ioapic_list);
+            dprintk(XENLOG_INFO VTDPREFIX,
+                    "found IOAPIC: bus = %x dev = %x func = %x\n",
+                    bus, path->dev, path->fn);
         }
         else
-            printk(KERN_INFO PREFIX
-                   "found MSI HPET: bus = %x dev = %x func = %x\n",
-                   bus, path->dev, path->fn);
-        
+            dprintk(XENLOG_INFO VTDPREFIX,
+                    "found MSI HPET: bus = %x dev = %x func = %x\n",
+                    bus, path->dev, path->fn);
         start += scope->length;
     }
 
@@ -371,6 +434,7 @@ acpi_parse_one_drhd(struct acpi_dmar_ent
     struct acpi_drhd_unit *dmaru;
     int ret = 0;
     static int include_all;
+    void *dev_scope_start, *dev_scope_end;
 
     dmaru = xmalloc(struct acpi_drhd_unit);
     if ( !dmaru )
@@ -379,21 +443,22 @@ acpi_parse_one_drhd(struct acpi_dmar_ent
 
     dmaru->address = drhd->address;
     dmaru->include_all = drhd->flags & 1; /* BIT0: INCLUDE_ALL */
-    printk(KERN_INFO PREFIX "dmaru->address = %lx\n", dmaru->address);
-
-    if ( !dmaru->include_all )
-        ret = acpi_parse_dev_scope(
-            (void *)(drhd + 1),
-            ((void *)drhd) + header->length,
-            &dmaru->devices_cnt, &dmaru->devices);
-    else
-    {
-        printk(KERN_INFO PREFIX "found INCLUDE_ALL\n");
+    INIT_LIST_HEAD(&dmaru->ioapic_list);
+    dprintk(XENLOG_INFO VTDPREFIX, "dmaru->address = %lx\n", dmaru->address);
+
+    dev_scope_start = (void *)(drhd + 1);
+    dev_scope_end   = ((void *)drhd) + header->length;
+    ret = acpi_parse_dev_scope(dev_scope_start, dev_scope_end,
+                               dmaru, DMAR_TYPE);
+
+    if ( dmaru->include_all )
+    {
+        dprintk(XENLOG_INFO VTDPREFIX, "found INCLUDE_ALL\n");
         /* Only allow one INCLUDE_ALL */
         if ( include_all )
         {
-            printk(KERN_WARNING PREFIX "Only one INCLUDE_ALL "
-                   "device scope is allowed\n");
+            dprintk(XENLOG_WARNING VTDPREFIX,
+                    "Only one INCLUDE_ALL device scope is allowed\n");
             ret = -EINVAL;
         }
         include_all = 1;
@@ -411,6 +476,7 @@ acpi_parse_one_rmrr(struct acpi_dmar_ent
 {
     struct acpi_table_rmrr *rmrr = (struct acpi_table_rmrr *)header;
     struct acpi_rmrr_unit *rmrru;
+    void *dev_scope_start, *dev_scope_end;
     int ret = 0;
 
     rmrru = xmalloc(struct acpi_rmrr_unit);
@@ -420,15 +486,10 @@ acpi_parse_one_rmrr(struct acpi_dmar_ent
 
     rmrru->base_address = rmrr->base_address;
     rmrru->end_address = rmrr->end_address;
-    printk(KERN_INFO PREFIX
-           "acpi_parse_one_rmrr: base=%"PRIx64" end=%"PRIx64"\n",
-           rmrr->base_address, rmrr->end_address);
-
-    ret = acpi_parse_dev_scope(
-        (void *)(rmrr + 1),
-        ((void*)rmrr) + header->length,
-        &rmrru->devices_cnt, &rmrru->devices);
-
+    dev_scope_start = (void *)(rmrr + 1);
+    dev_scope_end   = ((void *)rmrr) + header->length;
+    ret = acpi_parse_dev_scope(dev_scope_start, dev_scope_end,
+                               rmrru, RMRR_TYPE);
     if ( ret || (rmrru->devices_cnt == 0) )
         xfree(rmrru);
     else
@@ -443,6 +504,7 @@ acpi_parse_one_atsr(struct acpi_dmar_ent
     struct acpi_atsr_unit *atsru;
     int ret = 0;
     static int all_ports;
+    void *dev_scope_start, *dev_scope_end;
 
     atsru = xmalloc(struct acpi_atsr_unit);
     if ( !atsru )
@@ -451,18 +513,19 @@ acpi_parse_one_atsr(struct acpi_dmar_ent
 
     atsru->all_ports = atsr->flags & 1; /* BIT0: ALL_PORTS */
     if ( !atsru->all_ports )
-        ret = acpi_parse_dev_scope(
-            (void *)(atsr + 1),
-            ((void *)atsr) + header->length,
-            &atsru->devices_cnt, &atsru->devices);
-    else
-    {
-        printk(KERN_INFO PREFIX "found ALL_PORTS\n");
+    {
+        dev_scope_start = (void *)(atsr + 1);
+        dev_scope_end   = ((void *)atsr) + header->length;
+        ret = acpi_parse_dev_scope(dev_scope_start, dev_scope_end,
+                                   atsru, ATSR_TYPE);
+    }
+    else {
+        dprintk(XENLOG_INFO VTDPREFIX, "found ALL_PORTS\n");
         /* Only allow one ALL_PORTS */
         if ( all_ports )
         {
-            printk(KERN_WARNING PREFIX "Only one ALL_PORTS "
-                   "device scope is allowed\n");
+            dprintk(XENLOG_WARNING VTDPREFIX,
+                    "Only one ALL_PORTS device scope is allowed\n");
             ret = -EINVAL;
         }
         all_ports = 1;
@@ -488,19 +551,19 @@ static int __init acpi_parse_dmar(unsign
     dmar = (struct acpi_table_dmar *)__acpi_map_table(phys_addr, size);
     if ( !dmar )
     {
-        printk(KERN_WARNING PREFIX "Unable to map DMAR\n");
+        dprintk(XENLOG_WARNING VTDPREFIX, "Unable to map DMAR\n");
         return -ENODEV;
     }
 
     if ( !dmar->haw )
     {
-        printk(KERN_WARNING PREFIX "Zero: Invalid DMAR haw\n");
+        dprintk(XENLOG_WARNING VTDPREFIX, "Zero: Invalid DMAR haw\n");
         return -EINVAL;
     }
 
     dmar_host_address_width = dmar->haw;
-    printk(KERN_INFO PREFIX "Host address width %d\n",
-           dmar_host_address_width);
+    dprintk(XENLOG_INFO VTDPREFIX, "Host address width %d\n",
+            dmar_host_address_width);
 
     entry_header = (struct acpi_dmar_entry_header *)(dmar + 1);
     while ( ((unsigned long)entry_header) <
@@ -509,19 +572,19 @@ static int __init acpi_parse_dmar(unsign
         switch ( entry_header->type )
         {
         case ACPI_DMAR_DRHD:
-            printk(KERN_INFO PREFIX "found ACPI_DMAR_DRHD\n");
+            dprintk(XENLOG_INFO VTDPREFIX, "found ACPI_DMAR_DRHD\n");
             ret = acpi_parse_one_drhd(entry_header);
             break;
         case ACPI_DMAR_RMRR:
-            printk(KERN_INFO PREFIX "found ACPI_DMAR_RMRR\n");
+            dprintk(XENLOG_INFO VTDPREFIX, "found ACPI_DMAR_RMRR\n");
             ret = acpi_parse_one_rmrr(entry_header);
             break;
         case ACPI_DMAR_ATSR:
-            printk(KERN_INFO PREFIX "found ACPI_DMAR_ATSR\n");
+            dprintk(XENLOG_INFO VTDPREFIX, "found ACPI_DMAR_ATSR\n");
             ret = acpi_parse_one_atsr(entry_header);
             break;
         default:
-            printk(KERN_WARNING PREFIX "Unknown DMAR structure type\n");
+            dprintk(XENLOG_WARNING VTDPREFIX, "Unknown DMAR structure type\n");
             ret = -EINVAL;
             break;
         }
@@ -551,7 +614,7 @@ int acpi_dmar_init(void)
 
     if ( list_empty(&acpi_drhd_units) )
     {
-        printk(KERN_ERR PREFIX "No DMAR devices found\n");
+        dprintk(XENLOG_ERR VTDPREFIX, "No DMAR devices found\n");
         vtd_enabled = 0;
         return -ENODEV;
     }
diff -r eb437e9fc19b -r f732c684c3d7 xen/arch/x86/hvm/vmx/vtd/dmar.h
--- a/xen/arch/x86/hvm/vmx/vtd/dmar.h   Fri Jan 18 13:51:53 2008 +0000
+++ b/xen/arch/x86/hvm/vmx/vtd/dmar.h   Fri Jan 18 13:52:22 2008 +0000
@@ -26,6 +26,20 @@
 
 extern u8 dmar_host_address_width;
 
+/* This one is for interrupt remapping */
+struct acpi_ioapic_unit {
+    struct list_head list;
+    int apic_id;
+    union {
+        u16 info;
+        struct {
+            u16 func: 3,
+                dev:  5,
+                bus:  8;
+        }bdf;
+    }ioapic;
+};
+
 struct acpi_drhd_unit {
     struct list_head list;
     unsigned long    address; /* register base address of the unit */
@@ -33,6 +47,7 @@ struct acpi_drhd_unit {
     int    devices_cnt;
     u8    include_all:1;
     struct iommu *iommu;
+    struct list_head ioapic_list;
 };
 
 struct acpi_rmrr_unit {
@@ -73,19 +88,9 @@ struct acpi_drhd_unit * acpi_find_matche
 struct acpi_drhd_unit * acpi_find_matched_drhd_unit(struct pci_dev *dev);
 struct acpi_rmrr_unit * acpi_find_matched_rmrr_unit(struct pci_dev *dev);
 
-/* This one is for interrupt remapping */
-struct acpi_ioapic_unit {
-    struct list_head list;
-    int apic_id;
-    union {
-        u16 info;
-        struct {
-            u16 bus: 8,
-                dev: 5,
-                func: 3;
-        }bdf;
-    }ioapic;
-};
+#define DMAR_TYPE 1
+#define RMRR_TYPE 2
+#define ATSR_TYPE 3
 
 #define DMAR_OPERATION_TIMEOUT (HZ*60) /* 1m */
 #define time_after(a,b)         \
diff -r eb437e9fc19b -r f732c684c3d7 xen/arch/x86/hvm/vmx/vtd/utils.c
--- a/xen/arch/x86/hvm/vmx/vtd/utils.c  Fri Jan 18 13:51:53 2008 +0000
+++ b/xen/arch/x86/hvm/vmx/vtd/utils.c  Fri Jan 18 13:52:22 2008 +0000
@@ -146,12 +146,14 @@ u32 get_level_index(unsigned long gmfn, 
     return gmfn & LEVEL_MASK;
 }
 
-void print_vtd_entries(struct domain *d, int bus, int devfn,
-                       unsigned long gmfn)
+void print_vtd_entries(
+    struct domain *d, 
+    struct iommu *iommu,
+    int bus, int devfn,
+    unsigned long gmfn)
 {
     struct hvm_iommu *hd = domain_hvm_iommu(d);
     struct acpi_drhd_unit *drhd;
-    struct iommu *iommu;
     struct context_entry *ctxt_entry;
     struct root_entry *root_entry;
     struct dma_pte pte;
@@ -175,7 +177,6 @@ void print_vtd_entries(struct domain *d,
     {
         printk("---- print_vtd_entries %d ----\n", i++);
 
-        iommu = drhd->iommu;
         root_entry = iommu->root_entry;
         if ( root_entry == NULL )
         {
diff -r eb437e9fc19b -r f732c684c3d7 xen/include/asm-x86/hvm/vmx/intel-iommu.h
--- a/xen/include/asm-x86/hvm/vmx/intel-iommu.h Fri Jan 18 13:51:53 2008 +0000
+++ b/xen/include/asm-x86/hvm/vmx/intel-iommu.h Fri Jan 18 13:52:22 2008 +0000
@@ -127,32 +127,34 @@
 #define DMA_TLB_IVA_HINT(x) ((((u64)x) & 1) << 6)
 
 /* GCMD_REG */
-#define DMA_GCMD_TE (((u64)1) << 31)
-#define DMA_GCMD_SRTP (((u64)1) << 30)
-#define DMA_GCMD_SFL (((u64)1) << 29)
-#define DMA_GCMD_EAFL (((u64)1) << 28)
-#define DMA_GCMD_WBF (((u64)1) << 27)
-#define DMA_GCMD_QIE (((u64)1) << 26)
-#define DMA_GCMD_IRE (((u64)1) << 25)
-#define DMA_GCMD_SIRTP (((u64)1) << 24)
+#define DMA_GCMD_TE     (((u64)1) << 31)
+#define DMA_GCMD_SRTP   (((u64)1) << 30)
+#define DMA_GCMD_SFL    (((u64)1) << 29)
+#define DMA_GCMD_EAFL   (((u64)1) << 28)
+#define DMA_GCMD_WBF    (((u64)1) << 27)
+#define DMA_GCMD_QIE    (((u64)1) << 26)
+#define DMA_GCMD_IRE    (((u64)1) << 25)
+#define DMA_GCMD_SIRTP  (((u64)1) << 24)
+#define DMA_GCMD_CFI    (((u64)1) << 23)
 
 /* GSTS_REG */
-#define DMA_GSTS_TES (((u64)1) << 31)
-#define DMA_GSTS_RTPS (((u64)1) << 30)
-#define DMA_GSTS_FLS (((u64)1) << 29)
-#define DMA_GSTS_AFLS (((u64)1) << 28)
-#define DMA_GSTS_WBFS (((u64)1) << 27)
-#define DMA_GSTS_IRTPS (((u64)1) << 24)
+#define DMA_GSTS_TES    (((u64)1) << 31)
+#define DMA_GSTS_RTPS   (((u64)1) << 30)
+#define DMA_GSTS_FLS    (((u64)1) << 29)
+#define DMA_GSTS_AFLS   (((u64)1) << 28)
+#define DMA_GSTS_WBFS   (((u64)1) << 27)
 #define DMA_GSTS_QIES   (((u64)1) <<26)
 #define DMA_GSTS_IRES   (((u64)1) <<25)
+#define DMA_GSTS_SIRTPS (((u64)1) << 24)
+#define DMA_GSTS_CFIS   (((u64)1) <<23)
 
 /* PMEN_REG */
-#define DMA_PMEN_EPM   (((u32)1) << 31)
-#define DMA_PMEN_PRS   (((u32)1) << 0)
+#define DMA_PMEN_EPM    (((u32)1) << 31)
+#define DMA_PMEN_PRS    (((u32)1) << 0)
 
 /* CCMD_REG */
 #define DMA_CCMD_INVL_GRANU_OFFSET  61
-#define DMA_CCMD_ICC (((u64)1) << 63)
+#define DMA_CCMD_ICC   (((u64)1) << 63)
 #define DMA_CCMD_GLOBAL_INVL (((u64)1) << 61)
 #define DMA_CCMD_DOMAIN_INVL (((u64)2) << 61)
 #define DMA_CCMD_DEVICE_INVL (((u64)3) << 61)
@@ -171,8 +173,14 @@
 #define DMA_FECTL_IM (((u64)1) << 31)
 
 /* FSTS_REG */
-#define DMA_FSTS_PPF ((u64)2)
-#define DMA_FSTS_PFO ((u64)1)
+#define DMA_FSTS_PFO ((u64)1 << 0)
+#define DMA_FSTS_PPF ((u64)1 << 1)
+#define DMA_FSTS_AFO ((u64)1 << 2)
+#define DMA_FSTS_APF ((u64)1 << 3)
+#define DMA_FSTS_IQE ((u64)1 << 4)
+#define DMA_FSTS_ICE ((u64)1 << 5)
+#define DMA_FSTS_ITE ((u64)1 << 6)
+#define DMA_FSTS_FAULTS    DMA_FSTS_PFO | DMA_FSTS_PPF | DMA_FSTS_AFO | 
DMA_FSTS_APF | DMA_FSTS_IQE | DMA_FSTS_ICE | DMA_FSTS_ITE
 #define dma_fsts_fault_record_index(s) (((s) >> 8) & 0xff)
 
 /* FRCD_REG, 32 bits access */
@@ -266,8 +274,10 @@ struct dma_pte {
 
 /* interrupt remap entry */
 struct iremap_entry {
+  union {
+    u64 lo_val;
     struct {
-        u64 present : 1,
+        u64 p       : 1,
             fpd     : 1,
             dm      : 1,
             rh      : 1,
@@ -279,12 +289,16 @@ struct iremap_entry {
             res_2   : 8,
             dst     : 32;
     }lo;
+  };
+  union {
+    u64 hi_val;
     struct {
         u64 sid     : 16,
             sq      : 2,
             svt     : 2,
             res_1   : 44;
     }hi;
+  };
 };
 #define IREMAP_ENTRY_NR (PAGE_SIZE_4K/sizeof(struct iremap_entry))
 #define iremap_present(v) ((v).lo & 1)
@@ -386,11 +400,11 @@ struct poll_info {
 
 #define RESERVED_VAL        0
 
-#define TYPE_INVAL_CONTEXT  1
-#define TYPE_INVAL_IOTLB    2
-#define TYPE_INVAL_DEVICE_IOTLB 3
-#define TYPE_INVAL_IEC          4
-#define TYPE_INVAL_WAIT         5
+#define TYPE_INVAL_CONTEXT      0x1
+#define TYPE_INVAL_IOTLB        0x2
+#define TYPE_INVAL_DEVICE_IOTLB 0x3
+#define TYPE_INVAL_IEC          0x4
+#define TYPE_INVAL_WAIT         0x5
 
 #define NOTIFY_TYPE_POLL        1
 #define NOTIFY_TYPE_INTR        1
@@ -400,6 +414,10 @@ struct poll_info {
 
 #define IEC_GLOBAL_INVL         0
 #define IEC_INDEX_INVL          1
+#define IRTA_REG_EIME_SHIFT     11
+#define IRTA_REG_TABLE_SIZE     7    // 4k page = 256 * 16 byte entries
+                                     // 2^^(IRTA_REG_TABLE_SIZE + 1) = 256
+                                     // IRTA_REG_TABLE_SIZE = 7
 
 #define VTD_PAGE_TABLE_LEVEL_3  3
 #define VTD_PAGE_TABLE_LEVEL_4  4
@@ -414,4 +432,29 @@ extern struct list_head acpi_rmrr_units;
 extern struct list_head acpi_rmrr_units;
 extern struct list_head acpi_ioapic_units;
 
+struct qi_ctrl {
+    struct qinval_entry *qinval;         /* queue invalidation page */
+    int qinval_index;                    /* queue invalidation index */
+    spinlock_t qinval_lock;      /* lock for queue invalidation page */
+    spinlock_t qinval_poll_lock; /* lock for queue invalidation poll addr */
+    volatile u32 qinval_poll_status;     /* used by poll methord to sync */
+};
+
+struct ir_ctrl {
+    struct iremap_entry *iremap;         /* interrupt remap table */
+    int iremap_index;                    /* interrupt remap index */
+    spinlock_t iremap_lock;      /* lock for irq remappping table */
+};
+
+struct iommu_flush {
+    int (*context)(void *iommu, u16 did, u16 source_id, u8 function_mask, u64 
type, int non_present_entry_flush);
+    int (*iotlb)(void *iommu, u16 did, u64 addr, unsigned int size_order, u64 
type, int non_present_entry_flush);
+};
+
+struct intel_iommu {
+    struct qi_ctrl qi_ctrl;
+    struct ir_ctrl ir_ctrl;
+    struct iommu_flush flush; 
+};
+
 #endif

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.