[PATCH] x86_64: Calgary IOMMU - IOMMU abstractions
authorJon Mason <jdmason@us.ibm.com>
Mon, 26 Jun 2006 11:58:11 +0000 (13:58 +0200)
committerLinus Torvalds <torvalds@g5.osdl.org>
Mon, 26 Jun 2006 17:48:18 +0000 (10:48 -0700)
This patch creates a new interface for IOMMUs by adding a centralized
location for IOMMU allocation (for translation tables/apertures) and
IOMMU initialization.  In creating these, code was moved around for
abstraction, uniformity, and consiceness.

Take note of the move of the iommu_setup bootarg parsing code to
__setup.  This is enabled by moving back the location of the aperture
allocation/detection to mem init (which while ugly, was already the
location of the swiotlb_init).

While a slight departure from the previous patch, I belive this provides
the true intention of the previous versions of the patch which changed
this code.  It also makes the addition of the upcoming calgary code much
cleaner than previous patches.

[AK: Removed one broken change. iommu_setup still has to be called
early]

Signed-off-by: Muli Ben-Yehuda <muli@il.ibm.com>
Signed-off-by: Jon Mason <jdmason@us.ibm.com>
Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
arch/x86_64/kernel/pci-dma.c
arch/x86_64/kernel/pci-gart.c
arch/x86_64/kernel/setup.c
arch/x86_64/mm/init.c
include/asm-x86_64/pci.h
include/asm-x86_64/proto.h

index 7edd1a40fab38661cdc7aa38c828ff2d8f4014e6..a45844c7e3a32b31cc5d853920a1ce3e00bcf2a4 100644 (file)
@@ -279,3 +279,32 @@ __init int iommu_setup(char *p)
     }
     return 1;
 }
+__setup("iommu=", iommu_setup);
+
+void __init pci_iommu_alloc(void)
+{
+       /*
+        * The order of these functions is important for
+        * fall-back/fail-over reasons
+        */
+#ifdef CONFIG_IOMMU
+       iommu_hole_init();
+#endif
+
+#ifdef CONFIG_SWIOTLB
+       pci_swiotlb_init();
+#endif
+}
+
+static int __init pci_iommu_init(void)
+{
+#ifdef CONFIG_IOMMU
+       gart_iommu_init();
+#endif
+
+       no_iommu_init();
+       return 0;
+}
+
+/* Must execute after PCI subsystem */
+fs_initcall(pci_iommu_init);
index 4f67957d2b422f1794d2b181f6e779e6bcb3918c..9a93954bed37d89d008b5a350582977613734dd8 100644 (file)
@@ -571,7 +571,7 @@ static struct dma_mapping_ops gart_dma_ops = {
        .unmap_sg = gart_unmap_sg,
 };
 
-static int __init pci_iommu_init(void)
+void __init gart_iommu_init(void)
 { 
        struct agp_kern_info info;
        unsigned long aper_size;
@@ -581,7 +581,7 @@ static int __init pci_iommu_init(void)
 
        if (cache_k8_northbridges() < 0 || num_k8_northbridges == 0) {
                printk(KERN_INFO "PCI-GART: No AMD northbridge found.\n");
-               return -ENODEV;
+               return;
        }
 
 #ifndef CONFIG_AGP_AMD64
@@ -595,11 +595,11 @@ static int __init pci_iommu_init(void)
 #endif 
 
        if (swiotlb)
-               return -ENODEV;
+               return;
 
        /* Did we detect a different HW IOMMU? */
        if (iommu_detected && !iommu_aperture)
-               return -1;
+               return;
 
        if (no_iommu ||
            (!force_iommu && end_pfn <= MAX_DMA32_PFN) ||
@@ -611,7 +611,7 @@ static int __init pci_iommu_init(void)
                                        "but IOMMU not available.\n"
                               KERN_ERR "WARNING 32bit PCI may malfunction.\n");
                }
-               return -ENODEV;
+               return;
        }
 
        printk(KERN_INFO "PCI-DMA: using GART IOMMU.\n");
@@ -678,11 +678,10 @@ static int __init pci_iommu_init(void)
 
        flush_gart();
        dma_ops = &gart_dma_ops;
-       return 0;
 } 
 
 /* Must execute after PCI subsystem */
-fs_initcall(pci_iommu_init);
+fs_initcall(gart_iommu_init);
 
 void gart_parse_options(char *p)
 {
index a9de8f02671f4c879573e274ed7f9e5e89f4525d..04b2d7b92d1797149f9993cc02ac6657ed11115d 100644 (file)
@@ -63,7 +63,6 @@
 #include <asm/setup.h>
 #include <asm/mach_apic.h>
 #include <asm/numa.h>
-#include <asm/swiotlb.h>
 #include <asm/sections.h>
 #include <asm/dmi.h>
 
@@ -702,10 +701,6 @@ void __init setup_arch(char **cmdline_p)
 
        e820_setup_gap();
 
-#ifdef CONFIG_IOMMU
-       iommu_hole_init();
-#endif
-
 #ifdef CONFIG_VT
 #if defined(CONFIG_VGA_CONSOLE)
        conswitchp = &vga_con;
index b83645a2e02d7cab9138be0025ff27416069a54d..2f5f5b11e9d0fe03c2fabe148c9cf4630de85618 100644 (file)
@@ -41,8 +41,6 @@
 #include <asm/proto.h>
 #include <asm/smp.h>
 #include <asm/sections.h>
-#include <asm/dma-mapping.h>
-#include <asm/swiotlb.h>
 
 #ifndef Dprintk
 #define Dprintk(x...)
@@ -587,10 +585,7 @@ void __init mem_init(void)
 {
        long codesize, reservedpages, datasize, initsize;
 
-#ifdef CONFIG_SWIOTLB
-       pci_swiotlb_init();
-#endif
-       no_iommu_init();
+       pci_iommu_alloc();
 
        /* How many end-of-memory variables you have, grandma! */
        max_low_pfn = end_pfn;
index 3374d34c4acdbe9a2bbf65b07db115a453c108eb..4dbc07c54f7ab4c5e7a6aea79fbf619bc0d16487 100644 (file)
@@ -39,8 +39,8 @@ int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq);
 #include <asm/scatterlist.h>
 #include <linux/string.h>
 #include <asm/page.h>
-#include <linux/dma-mapping.h> /* for have_iommu */
 
+extern void pci_iommu_alloc(void);
 extern int iommu_setup(char *opt);
 
 /* The PCI address space does equal the physical memory
index 9d3335b4e9b6ae26995cf30394dc7ef77aaff09a..038fe1f47e6fcb5804a5878270614289f545d9d4 100644 (file)
@@ -37,7 +37,6 @@ extern void ia32_sysenter_target(void);
 
 extern void config_acpi_tables(void);
 extern void ia32_syscall(void);
-extern void iommu_hole_init(void);
 
 extern int pmtimer_mark_offset(void);
 extern void pmtimer_resume(void);
@@ -101,13 +100,9 @@ extern int unsynchronized_tsc(void);
 
 extern void select_idle_routine(const struct cpuinfo_x86 *c);
 
-extern void gart_parse_options(char *);
-extern void __init no_iommu_init(void);
-
 extern unsigned long table_start, table_end;
 
 extern int exception_trace;
-extern int force_iommu, no_iommu;
 extern int using_apic_timer;
 extern int disable_apic;
 extern unsigned cpu_khz;
@@ -116,8 +111,13 @@ extern int skip_ioapic_setup;
 extern int acpi_ht;
 extern int acpi_disabled;
 
+extern void no_iommu_init(void);
+extern int force_iommu, no_iommu;
 extern int iommu_detected;
 #ifdef CONFIG_IOMMU
+extern void gart_iommu_init(void);
+extern void gart_parse_options(char *);
+extern void iommu_hole_init(void);
 extern int fallback_aper_order;
 extern int fallback_aper_force;
 extern int iommu_aperture;