WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] AMD IOMMU: Remove pci scanning, parse acp

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] AMD IOMMU: Remove pci scanning, parse acpi structures to detect iommu hardware.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 01 Aug 2008 02:20:26 -0700
Delivery-date: Fri, 01 Aug 2008 02:21:26 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1217507774 -3600
# Node ID a352c29d5471a1a6fb3fc5b21a8d7d3f6e6e9431
# Parent  1d00eeddcd83aaacf0bf3a62b4a878efcc80f494
AMD IOMMU: Remove pci scanning, parse acpi structures to detect iommu hardware.

Signed-off-by: Wei Wang <wei.wang2@xxxxxxx>
---
 xen/drivers/passthrough/amd/iommu_detect.c |  227 ++++++++---------------------
 1 files changed, 66 insertions(+), 161 deletions(-)

diff -r 1d00eeddcd83 -r a352c29d5471 xen/drivers/passthrough/amd/iommu_detect.c
--- a/xen/drivers/passthrough/amd/iommu_detect.c        Thu Jul 31 13:35:41 
2008 +0100
+++ b/xen/drivers/passthrough/amd/iommu_detect.c        Thu Jul 31 13:36:14 
2008 +0100
@@ -25,65 +25,10 @@
 #include <xen/pci_regs.h>
 #include <asm/amd-iommu.h>
 #include <asm/hvm/svm/amd-iommu-proto.h>
+#include <asm/hvm/svm/amd-iommu-acpi.h>
 
-static int __init valid_bridge_bus_config(
-    int bus, int dev, int func, int *sec_bus, int *sub_bus)
-{
-    int pri_bus;
-
-    pri_bus = pci_conf_read8(bus, dev, func, PCI_PRIMARY_BUS);
-    *sec_bus = pci_conf_read8(bus, dev, func, PCI_SECONDARY_BUS);
-    *sub_bus = pci_conf_read8(bus, dev, func, PCI_SUBORDINATE_BUS);
-
-    return ((pri_bus == bus) && (*sec_bus > bus) && (*sub_bus >= *sec_bus));
-}
-
-int __init get_iommu_last_downstream_bus(struct amd_iommu *iommu)
-{
-    int bus, dev, func;
-    int devfn, hdr_type;
-    int sec_bus, sub_bus;
-    int multi_func;
-
-    bus = iommu->last_downstream_bus = iommu->root_bus;
-    iommu->downstream_bus_present[bus] = 1;
-    dev = PCI_SLOT(iommu->first_devfn);
-    multi_func = PCI_FUNC(iommu->first_devfn) > 0;
-    for ( devfn = iommu->first_devfn; devfn <= iommu->last_devfn; devfn++ )
-    {
-        /* skipping to next device#? */
-        if ( dev != PCI_SLOT(devfn) )
-        {
-            dev = PCI_SLOT(devfn);
-            multi_func = 0;
-        }
-        func = PCI_FUNC(devfn);
- 
-        if ( !VALID_PCI_VENDOR_ID(pci_conf_read16(bus, dev, func,
-                                                  PCI_VENDOR_ID)) )
-            continue;
-
-        hdr_type = pci_conf_read8(bus, dev, func, PCI_HEADER_TYPE);
-        if ( func == 0 )
-            multi_func = IS_PCI_MULTI_FUNCTION(hdr_type);
-
-        if ( (func == 0 || multi_func) &&
-             IS_PCI_TYPE1_HEADER(hdr_type) )
-        {
-            if ( !valid_bridge_bus_config(bus, dev, func,
-                                          &sec_bus, &sub_bus) )
-                return -ENODEV;
-
-            if ( sub_bus > iommu->last_downstream_bus )
-                iommu->last_downstream_bus = sub_bus;
-            do {
-                iommu->downstream_bus_present[sec_bus] = 1;
-            } while ( sec_bus++ < sub_bus );
-        }
-    }
-
-    return 0;
-}
+extern struct list_head amd_iommu_head;
+unsigned short last_bdf = 0;
 
 static int __init get_iommu_msi_capabilities(u8 bus, u8 dev, u8 func,
             struct amd_iommu *iommu)
@@ -128,30 +73,10 @@ int __init get_iommu_capabilities(u8 bus
                                   struct amd_iommu *iommu)
 {
     u32 cap_header, cap_range, misc_info;
-    u64 mmio_bar;
-
-    mmio_bar = (u64)pci_conf_read32(
-        bus, dev, func, cap_ptr + PCI_CAP_MMIO_BAR_HIGH_OFFSET) << 32;
-    mmio_bar |= pci_conf_read32(bus, dev, func,
-                                cap_ptr + PCI_CAP_MMIO_BAR_LOW_OFFSET);
-    iommu->mmio_base_phys = mmio_bar & (u64)~0x3FFF;
-
-    if ( ((mmio_bar & 0x1) == 0) || (iommu->mmio_base_phys == 0) )
-    {
-        amd_iov_error("Invalid MMIO_BAR = 0x%"PRIx64"\n", mmio_bar);
-        return -ENODEV;
-    }
-
-    iommu->bdf = (bus << 8) | PCI_DEVFN(dev, func);
-    iommu->cap_offset = cap_ptr;
 
     cap_header = pci_conf_read32(bus, dev, func, cap_ptr);
     iommu->revision = get_field_from_reg_u32(
         cap_header, PCI_CAP_REV_MASK, PCI_CAP_REV_SHIFT);
-    iommu->iotlb_support = get_field_from_reg_u32(
-        cap_header, PCI_CAP_IOTLB_MASK, PCI_CAP_IOTLB_SHIFT);
-    iommu->ht_tunnel_support = get_field_from_reg_u32(
-        cap_header, PCI_CAP_HT_TUNNEL_MASK, PCI_CAP_HT_TUNNEL_SHIFT);
     iommu->pte_not_present_cached = get_field_from_reg_u32(
         cap_header, PCI_CAP_NP_CACHE_MASK, PCI_CAP_NP_CACHE_SHIFT);
 
@@ -159,96 +84,76 @@ int __init get_iommu_capabilities(u8 bus
                                 cap_ptr + PCI_CAP_RANGE_OFFSET);
     iommu->unit_id = get_field_from_reg_u32(
         cap_range, PCI_CAP_UNIT_ID_MASK, PCI_CAP_UNIT_ID_SHIFT);
-    iommu->root_bus = get_field_from_reg_u32(
-        cap_range, PCI_CAP_BUS_NUMBER_MASK, PCI_CAP_BUS_NUMBER_SHIFT);
-    iommu->first_devfn = get_field_from_reg_u32(
-        cap_range, PCI_CAP_FIRST_DEVICE_MASK, PCI_CAP_FIRST_DEVICE_SHIFT);
-    iommu->last_devfn = get_field_from_reg_u32(
-        cap_range, PCI_CAP_LAST_DEVICE_MASK, PCI_CAP_LAST_DEVICE_SHIFT);
 
     misc_info = pci_conf_read32(bus, dev, func,
                                 cap_ptr + PCI_MISC_INFO_OFFSET);
     iommu->msi_number = get_field_from_reg_u32(
         misc_info, PCI_CAP_MSI_NUMBER_MASK, PCI_CAP_MSI_NUMBER_SHIFT);
 
+    return 0;
+}
+
+int __init amd_iommu_detect_one_acpi(void *ivhd)
+{
+    struct amd_iommu *iommu;
+    u8 bus, dev, func;
+    struct acpi_ivhd_block_header *ivhd_block;
+
+    ivhd_block = (struct acpi_ivhd_block_header *)ivhd;
+
+    if ( ivhd_block->header.length < sizeof(struct acpi_ivhd_block_header) )
+    {
+        amd_iov_error("Invalid IVHD Block Length!\n");
+        return -ENODEV;
+    }
+
+    if ( !ivhd_block->header.dev_id ||
+        !ivhd_block->cap_offset || !ivhd_block->mmio_base)
+    {
+        amd_iov_error("Invalid IVHD Block!\n");
+        return -ENODEV;
+    }
+
+    iommu = (struct amd_iommu *) xmalloc(struct amd_iommu);
+    if ( !iommu )
+    {
+        amd_iov_error("Error allocating amd_iommu\n");
+        return -ENOMEM;
+    }
+    memset(iommu, 0, sizeof(struct amd_iommu));
+
+    spin_lock_init(&iommu->lock);
+
+    iommu->bdf = ivhd_block->header.dev_id;
+    iommu->cap_offset = ivhd_block->cap_offset;
+    iommu->mmio_base_phys = ivhd_block->mmio_base;
+
+    /* override IOMMU support flags */
+    iommu->coherent = get_field_from_byte(ivhd_block->header.flags,
+                        AMD_IOMMU_ACPI_COHERENT_MASK,
+                        AMD_IOMMU_ACPI_COHERENT_SHIFT);
+    iommu->iotlb_support = get_field_from_byte(ivhd_block->header.flags,
+                        AMD_IOMMU_ACPI_IOTLB_SUP_MASK,
+                        AMD_IOMMU_ACPI_IOTLB_SUP_SHIFT);
+    iommu->isochronous = get_field_from_byte(ivhd_block->header.flags,
+                        AMD_IOMMU_ACPI_ISOC_MASK,
+                        AMD_IOMMU_ACPI_ISOC_SHIFT);
+    iommu->res_pass_pw = get_field_from_byte(ivhd_block->header.flags,
+                        AMD_IOMMU_ACPI_RES_PASS_PW_MASK,
+                        AMD_IOMMU_ACPI_RES_PASS_PW_SHIFT);
+    iommu->pass_pw = get_field_from_byte(ivhd_block->header.flags,
+                        AMD_IOMMU_ACPI_PASS_PW_MASK,
+                        AMD_IOMMU_ACPI_PASS_PW_SHIFT);
+    iommu->ht_tunnel_enable = get_field_from_byte(ivhd_block->header.flags,
+                        AMD_IOMMU_ACPI_HT_TUN_ENB_MASK,
+                        AMD_IOMMU_ACPI_HT_TUN_ENB_SHIFT);
+    bus = iommu->bdf >> 8;
+    dev = PCI_SLOT(iommu->bdf & 0xFF);
+    func = PCI_FUNC(iommu->bdf & 0xFF);
+    get_iommu_capabilities(bus, dev, func, iommu->cap_offset, iommu);
     get_iommu_msi_capabilities(bus, dev, func, iommu);
+
+    list_add_tail(&iommu->list, &amd_iommu_head);
 
     return 0;
 }
-
-static int __init scan_caps_for_iommu(
-    int bus, int dev, int func,
-    iommu_detect_callback_ptr_t iommu_detect_callback)
-{
-    int cap_ptr, cap_id, cap_type;
-    u32 cap_header;
-    int count, error = 0;
-
-    count = 0;
-    cap_ptr = pci_conf_read8(bus, dev, func, PCI_CAPABILITY_LIST);
-    while ( (cap_ptr >= PCI_MIN_CAP_OFFSET) &&
-            (count < PCI_MAX_CAP_BLOCKS) &&
-            !error )
-    {
-        cap_ptr &= PCI_CAP_PTR_MASK;
-        cap_header = pci_conf_read32(bus, dev, func, cap_ptr);
-        cap_id = get_field_from_reg_u32(
-            cap_header, PCI_CAP_ID_MASK, PCI_CAP_ID_SHIFT);
-
-        if ( cap_id == PCI_CAP_ID_SECURE_DEVICE )
-        {
-            cap_type = get_field_from_reg_u32(
-                cap_header, PCI_CAP_TYPE_MASK, PCI_CAP_TYPE_SHIFT);
-            if ( cap_type == PCI_CAP_TYPE_IOMMU )
-                error = iommu_detect_callback(
-                    bus, dev, func, cap_ptr);
-        }
-
-        cap_ptr = get_field_from_reg_u32(
-            cap_header, PCI_CAP_NEXT_PTR_MASK, PCI_CAP_NEXT_PTR_SHIFT);
-        count++;
-    }
-
-    return error;
-}
-
-static int __init scan_functions_for_iommu(
-    int bus, int dev, iommu_detect_callback_ptr_t iommu_detect_callback)
-{
-    int func, hdr_type;
-    int count = 1, error = 0;
-
-    for ( func = 0;
-          (func < count) && !error &&
-              VALID_PCI_VENDOR_ID(pci_conf_read16(bus, dev, func,
-                                                  PCI_VENDOR_ID));
-          func++ )
-
-    {
-        hdr_type = pci_conf_read8(bus, dev, func, PCI_HEADER_TYPE);
-
-        if ( (func == 0) && IS_PCI_MULTI_FUNCTION(hdr_type) )
-            count = PCI_MAX_FUNC_COUNT;
-
-        if ( IS_PCI_TYPE0_HEADER(hdr_type) ||
-             IS_PCI_TYPE1_HEADER(hdr_type) )
-            error = scan_caps_for_iommu(bus, dev, func,
-                                        iommu_detect_callback);
-    }
-
-    return error;
-}
-
-
-int __init scan_for_iommu(iommu_detect_callback_ptr_t iommu_detect_callback)
-{
-    int bus, dev, error = 0;
-
-    for ( bus = 0; bus < PCI_MAX_BUS_COUNT && !error; ++bus )
-        for ( dev = 0; dev < PCI_MAX_DEV_COUNT && !error; ++dev )
-            error = scan_functions_for_iommu(bus, dev,
-                                             iommu_detect_callback);
-
-    return error;
-}
-

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] AMD IOMMU: Remove pci scanning, parse acpi structures to detect iommu hardware., Xen patchbot-unstable <=