diff options
author | Andi Kleen <ak@suse.de> | 2005-04-16 18:25:13 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:25:13 -0400 |
commit | ece90303ec7e2e8d8610eb03ee7648755dd8efe7 (patch) | |
tree | 1a6b38b4afd5dae194c93a79152c3bb18460c38f /arch/x86_64 | |
parent | a1e9778203b15b86bc2219e87478d3be9acce735 (diff) |
[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 <ak@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/x86_64')
-rw-r--r-- | arch/x86_64/kernel/aperture.c | 41 |
1 files changed, 30 insertions, 11 deletions
diff --git a/arch/x86_64/kernel/aperture.c b/arch/x86_64/kernel/aperture.c index 4baa99fe1e5c..a491f72cc966 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; | |||
33 | 33 | ||
34 | int fix_aperture __initdata = 1; | 34 | int fix_aperture __initdata = 1; |
35 | 35 | ||
36 | /* This code runs before the PCI subsystem is initialized, so just | ||
37 | access the northbridge directly. */ | ||
38 | |||
39 | #define NB_ID_3 (PCI_VENDOR_ID_AMD | (0x1103<<16)) | 36 | #define NB_ID_3 (PCI_VENDOR_ID_AMD | (0x1103<<16)) |
40 | 37 | ||
38 | static struct resource aper_res = { | ||
39 | .name = "Aperture", | ||
40 | .flags = IORESOURCE_MEM, | ||
41 | }; | ||
42 | |||
41 | static u32 __init allocate_aperture(void) | 43 | static u32 __init allocate_aperture(void) |
42 | { | 44 | { |
43 | #ifdef CONFIG_DISCONTIGMEM | 45 | #ifdef CONFIG_DISCONTIGMEM |
@@ -53,11 +55,24 @@ static u32 __init allocate_aperture(void) | |||
53 | aper_size = (32 * 1024 * 1024) << fallback_aper_order; | 55 | aper_size = (32 * 1024 * 1024) << fallback_aper_order; |
54 | 56 | ||
55 | /* | 57 | /* |
56 | * Aperture has to be naturally aligned. This means an 2GB aperture won't | 58 | * Aperture has to be naturally aligned. This means an 2GB |
57 | * have much chances to find a place in the lower 4GB of memory. | 59 | * aperture won't have much chances to find a place in the |
58 | * Unfortunately we cannot move it up because that would make the | 60 | * lower 4GB of memory. Unfortunately we cannot move it up |
59 | * IOMMU useless. | 61 | * because that would make the IOMMU useless. |
60 | */ | 62 | */ |
63 | |||
64 | /* First try to find some free unused space */ | ||
65 | if (!allocate_resource(&iomem_resource, &aper_res, | ||
66 | aper_size, | ||
67 | 0, 0xffffffff, | ||
68 | aper_size, | ||
69 | NULL, NULL)) { | ||
70 | printk(KERN_INFO "Putting aperture at %lx-%lx\n", | ||
71 | aper_res.start, aper_res.end); | ||
72 | return aper_res.start; | ||
73 | } | ||
74 | |||
75 | /* No free space found. Go on to waste some memory... */ | ||
61 | p = __alloc_bootmem_node(nd0, aper_size, aper_size, 0); | 76 | p = __alloc_bootmem_node(nd0, aper_size, aper_size, 0); |
62 | if (!p || __pa(p)+aper_size > 0xffffffff) { | 77 | if (!p || __pa(p)+aper_size > 0xffffffff) { |
63 | printk("Cannot allocate aperture memory hole (%p,%uK)\n", | 78 | printk("Cannot allocate aperture memory hole (%p,%uK)\n", |
@@ -66,7 +81,7 @@ static u32 __init allocate_aperture(void) | |||
66 | free_bootmem_node(nd0, (unsigned long)p, aper_size); | 81 | free_bootmem_node(nd0, (unsigned long)p, aper_size); |
67 | return 0; | 82 | return 0; |
68 | } | 83 | } |
69 | printk("Mapping aperture over %d KB of RAM @ %lx\n", | 84 | printk("Mapping aperture over %d KB of precious RAM @ %lx\n", |
70 | aper_size >> 10, __pa(p)); | 85 | aper_size >> 10, __pa(p)); |
71 | return (u32)__pa(p); | 86 | return (u32)__pa(p); |
72 | } | 87 | } |
@@ -87,10 +102,16 @@ static int __init aperture_valid(char *name, u64 aper_base, u32 aper_size) | |||
87 | printk("Aperture from %s pointing to e820 RAM. Ignoring.\n",name); | 102 | printk("Aperture from %s pointing to e820 RAM. Ignoring.\n",name); |
88 | return 0; | 103 | return 0; |
89 | } | 104 | } |
105 | /* Don't check the resource here because the aperture is usually | ||
106 | in an e820 reserved area, and we allocated these earlier. */ | ||
90 | return 1; | 107 | return 1; |
91 | } | 108 | } |
92 | 109 | ||
93 | /* Find a PCI capability */ | 110 | /* |
111 | * Find a PCI capability. | ||
112 | * This code runs before the PCI subsystem is initialized, so just | ||
113 | * access the northbridge directly. | ||
114 | */ | ||
94 | static __u32 __init find_cap(int num, int slot, int func, int cap) | 115 | static __u32 __init find_cap(int num, int slot, int func, int cap) |
95 | { | 116 | { |
96 | u8 pos; | 117 | u8 pos; |
@@ -255,8 +276,6 @@ void __init iommu_hole_init(void) | |||
255 | fallback_aper_force) { | 276 | fallback_aper_force) { |
256 | printk("Your BIOS doesn't leave a aperture memory hole\n"); | 277 | printk("Your BIOS doesn't leave a aperture memory hole\n"); |
257 | printk("Please enable the IOMMU option in the BIOS setup\n"); | 278 | printk("Please enable the IOMMU option in the BIOS setup\n"); |
258 | printk("This costs you %d MB of RAM\n", | ||
259 | 32 << fallback_aper_order); | ||
260 | 279 | ||
261 | aper_order = fallback_aper_order; | 280 | aper_order = fallback_aper_order; |
262 | aper_alloc = allocate_aperture(); | 281 | aper_alloc = allocate_aperture(); |