[PATCH] x86_64: Use the e820 hole to map the IOMMU/AGP aperture
authorAndi Kleen <ak@suse.de>
Sat, 16 Apr 2005 22:25:13 +0000 (15:25 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Sat, 16 Apr 2005 22:25:13 +0000 (15:25 -0700)
This might save memory on some Opteron systems without AGP bridge.

Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
arch/x86_64/kernel/aperture.c

index 4baa99fe1e5c95b95a77c6e87b71acf4fe5b5a8b..a491f72cc96663a79bf26a5e8f642cbab55dac26 100644 (file)
@@ -33,11 +33,13 @@ int fallback_aper_force __initdata = 0;
 
 int fix_aperture __initdata = 1;
 
 
 int fix_aperture __initdata = 1;
 
-/* This code runs before the PCI subsystem is initialized, so just 
-   access the northbridge directly. */
-
 #define NB_ID_3 (PCI_VENDOR_ID_AMD | (0x1103<<16))
 
 #define NB_ID_3 (PCI_VENDOR_ID_AMD | (0x1103<<16))
 
+static struct resource aper_res = {
+       .name = "Aperture",
+       .flags = IORESOURCE_MEM,
+};
+
 static u32 __init allocate_aperture(void) 
 {
 #ifdef CONFIG_DISCONTIGMEM
 static u32 __init allocate_aperture(void) 
 {
 #ifdef CONFIG_DISCONTIGMEM
@@ -53,11 +55,24 @@ static u32 __init allocate_aperture(void)
        aper_size = (32 * 1024 * 1024) << fallback_aper_order; 
 
        /* 
        aper_size = (32 * 1024 * 1024) << fallback_aper_order; 
 
        /* 
-        * Aperture has to be naturally aligned. This means an 2GB aperture won't 
-        * have much chances to find a place in the lower 4GB of memory. 
-        * Unfortunately we cannot move it up because that would make the 
-        * IOMMU useless.
+        * Aperture has to be naturally aligned. This means an 2GB
+        * aperture won't have much chances to find a place in the
+        * lower 4GB of memory.  Unfortunately we cannot move it up
+        * because that would make the IOMMU useless.
         */
         */
+
+       /* First try to find some free unused space */
+       if (!allocate_resource(&iomem_resource, &aper_res,
+                              aper_size,
+                              0, 0xffffffff,
+                              aper_size,
+                              NULL, NULL)) {
+               printk(KERN_INFO "Putting aperture at %lx-%lx\n",
+                      aper_res.start, aper_res.end);
+               return aper_res.start;
+       }
+
+       /* No free space found. Go on to waste some memory... */
        p = __alloc_bootmem_node(nd0, aper_size, aper_size, 0); 
        if (!p || __pa(p)+aper_size > 0xffffffff) {
                printk("Cannot allocate aperture memory hole (%p,%uK)\n",
        p = __alloc_bootmem_node(nd0, aper_size, aper_size, 0); 
        if (!p || __pa(p)+aper_size > 0xffffffff) {
                printk("Cannot allocate aperture memory hole (%p,%uK)\n",
@@ -66,7 +81,7 @@ static u32 __init allocate_aperture(void)
                        free_bootmem_node(nd0, (unsigned long)p, aper_size); 
                return 0;
        }
                        free_bootmem_node(nd0, (unsigned long)p, aper_size); 
                return 0;
        }
-       printk("Mapping aperture over %d KB of RAM @ %lx\n",  
+       printk("Mapping aperture over %d KB of precious RAM @ %lx\n",
               aper_size >> 10, __pa(p)); 
        return (u32)__pa(p); 
 }
               aper_size >> 10, __pa(p)); 
        return (u32)__pa(p); 
 }
@@ -87,10 +102,16 @@ static int __init aperture_valid(char *name, u64 aper_base, u32 aper_size)
                printk("Aperture from %s pointing to e820 RAM. Ignoring.\n",name);
                return 0; 
        } 
                printk("Aperture from %s pointing to e820 RAM. Ignoring.\n",name);
                return 0; 
        } 
+       /* Don't check the resource here because the aperture is usually
+          in an e820 reserved area, and we allocated these earlier. */
        return 1;
 } 
 
        return 1;
 } 
 
-/* Find a PCI capability */ 
+/*
+ * Find a PCI capability.
+ * This code runs before the PCI subsystem is initialized, so just
+ * access the northbridge directly.
+ */
 static __u32 __init find_cap(int num, int slot, int func, int cap) 
 { 
        u8 pos;
 static __u32 __init find_cap(int num, int slot, int func, int cap) 
 { 
        u8 pos;
@@ -255,8 +276,6 @@ void __init iommu_hole_init(void)
                   fallback_aper_force) { 
                printk("Your BIOS doesn't leave a aperture memory hole\n");
                printk("Please enable the IOMMU option in the BIOS setup\n");
                   fallback_aper_force) { 
                printk("Your BIOS doesn't leave a aperture memory hole\n");
                printk("Please enable the IOMMU option in the BIOS setup\n");
-               printk("This costs you %d MB of RAM\n",
-                      32 << fallback_aper_order);
 
                aper_order = fallback_aper_order;
                aper_alloc = allocate_aperture();
 
                aper_order = fallback_aper_order;
                aper_alloc = allocate_aperture();