From: Andi Kleen Date: Sat, 16 Apr 2005 22:25:13 +0000 (-0700) Subject: [PATCH] x86_64: Use the e820 hole to map the IOMMU/AGP aperture X-Git-Tag: v2.6.12-rc3~151 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ece90303ec7e2e8d8610eb03ee7648755dd8efe7;p=linux-2.6 [PATCH] x86_64: Use the e820 hole to map the IOMMU/AGP aperture This might save memory on some Opteron systems without AGP bridge. Signed-off-by: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- diff --git a/arch/x86_64/kernel/aperture.c b/arch/x86_64/kernel/aperture.c index 4baa99fe1e..a491f72cc9 100644 --- a/arch/x86_64/kernel/aperture.c +++ b/arch/x86_64/kernel/aperture.c @@ -33,11 +33,13 @@ int fallback_aper_force __initdata = 0; 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)) +static struct resource aper_res = { + .name = "Aperture", + .flags = IORESOURCE_MEM, +}; + 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; /* - * 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", @@ -66,7 +81,7 @@ static u32 __init allocate_aperture(void) 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); } @@ -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; } + /* Don't check the resource here because the aperture is usually + in an e820 reserved area, and we allocated these earlier. */ 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; @@ -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"); - printk("This costs you %d MB of RAM\n", - 32 << fallback_aper_order); aper_order = fallback_aper_order; aper_alloc = allocate_aperture();