ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / arch / x86_64 / kernel / aperture.c
1 /* 
2  * Firmware replacement code.
3  * 
4  * Work around broken BIOSes that don't set an aperture or only set the
5  * aperture in the AGP bridge. 
6  * If all fails map the aperture over some low memory.  This is cheaper than 
7  * doing bounce buffering. The memory is lost. This is done at early boot 
8  * because only the bootmem allocator can allocate 32+MB. 
9  * 
10  * Copyright 2002 Andi Kleen, SuSE Labs.
11  * $Id: aperture.c,v 1.7 2003/08/01 03:36:18 ak Exp $
12  */
13 #include <linux/config.h>
14 #include <linux/kernel.h>
15 #include <linux/types.h>
16 #include <linux/init.h>
17 #include <linux/bootmem.h>
18 #include <linux/mmzone.h>
19 #include <linux/pci_ids.h>
20 #include <linux/pci.h>
21 #include <linux/bitops.h>
22 #include <asm/e820.h>
23 #include <asm/io.h>
24 #include <asm/proto.h>
25 #include <asm/pci-direct.h>
26
27 int iommu_aperture;
28 int iommu_aperture_disabled __initdata = 0;
29 int iommu_aperture_allowed __initdata = 0;
30
31 int fallback_aper_order __initdata = 1; /* 64MB */
32 int fallback_aper_force __initdata = 0; 
33
34 /* This code runs before the PCI subsystem is initialized, so just 
35    access the northbridge directly. */
36
37 #define NB_ID_3 (PCI_VENDOR_ID_AMD | (0x1103<<16))
38
39 static u32 __init allocate_aperture(void) 
40 {
41 #ifdef CONFIG_DISCONTIGMEM
42         pg_data_t *nd0 = NODE_DATA(0);
43 #else
44         pg_data_t *nd0 = &contig_page_data;
45 #endif  
46         u32 aper_size;
47         void *p; 
48
49         if (fallback_aper_order > 7) 
50                 fallback_aper_order = 7; 
51         aper_size = (32 * 1024 * 1024) << fallback_aper_order; 
52
53         /* 
54          * Aperture has to be naturally aligned. This means an 2GB aperture won't 
55          * have much chances to find a place in the lower 4GB of memory. 
56          * Unfortunately we cannot move it up because that would make the 
57          * IOMMU useless.
58          */
59         p = __alloc_bootmem_node(nd0, aper_size, aper_size, 0); 
60         if (!p || __pa(p)+aper_size > 0xffffffff) {
61                 printk("Cannot allocate aperture memory hole (%p,%uK)\n",
62                        p, aper_size>>10);
63                 if (p)
64                         free_bootmem_node(nd0, (unsigned long)p, aper_size); 
65                 return 0;
66         }
67         printk("Mapping aperture over %d KB of RAM @ %lx\n",  
68                aper_size >> 10, __pa(p)); 
69         return (u32)__pa(p); 
70 }
71
72 static int __init aperture_valid(char *name, u64 aper_base, u32 aper_size) 
73
74         if (!aper_base) 
75                 return 0;
76         if (aper_size < 64*1024*1024) { 
77                 printk("Aperture from %s too small (%d MB)\n", name, aper_size>>20); 
78                 return 0;
79         }
80         if (aper_base + aper_size >= 0xffffffff) { 
81                 printk("Aperture from %s beyond 4GB. Ignoring.\n",name);
82                 return 0; 
83         }
84         if (e820_mapped(aper_base, aper_base + aper_size, E820_RAM)) {  
85                 printk("Aperture from %s pointing to e820 RAM. Ignoring.\n",name);
86                 return 0; 
87         } 
88         return 1;
89
90
91 /* Find a PCI capability */ 
92 static __u32 __init find_cap(int num, int slot, int func, int cap) 
93
94         u8 pos;
95         int bytes;
96         if (!(read_pci_config_16(num,slot,func,PCI_STATUS) & PCI_STATUS_CAP_LIST))
97                 return 0;
98         pos = read_pci_config_byte(num,slot,func,PCI_CAPABILITY_LIST);
99         for (bytes = 0; bytes < 48 && pos >= 0x40; bytes++) { 
100                 u8 id;
101                 pos &= ~3; 
102                 id = read_pci_config_byte(num,slot,func,pos+PCI_CAP_LIST_ID);
103                 if (id == 0xff)
104                         break;
105                 if (id == cap) 
106                         return pos; 
107                 pos = read_pci_config_byte(num,slot,func,pos+PCI_CAP_LIST_NEXT); 
108         } 
109         return 0;
110
111
112 /* Read a standard AGPv3 bridge header */
113 static __u32 __init read_agp(int num, int slot, int func, int cap, u32 *order)
114
115         u32 apsize;
116         u32 apsizereg;
117         int nbits;
118         u32 aper_low, aper_hi;
119         u64 aper;
120
121         printk("AGP bridge at %02x:%02x:%02x\n", num, slot, func);
122         apsizereg = read_pci_config_16(num,slot,func, cap + 0x14);
123         if (apsizereg == 0xffffffff) {
124                 printk("APSIZE in AGP bridge unreadable\n");
125                 return 0;
126         }
127
128         apsize = apsizereg & 0xfff;
129         /* Some BIOS use weird encodings not in the AGPv3 table. */
130         if (apsize & 0xff) 
131                 apsize |= 0xf00; 
132         nbits = hweight16(apsize);
133         *order = 7 - nbits;
134         if ((int)*order < 0) /* < 32MB */
135                 *order = 0;
136         
137         aper_low = read_pci_config(num,slot,func, 0x10);
138         aper_hi = read_pci_config(num,slot,func,0x14);
139         aper = (aper_low & ~((1<<22)-1)) | ((u64)aper_hi << 32);
140
141         printk("Aperture from AGP @ %Lx size %u MB (APSIZE %x)\n", 
142                aper, 32 << *order, apsizereg);
143
144         if (!aperture_valid("AGP bridge", aper, (32*1024*1024) << *order))
145             return 0;
146         return (u32)aper; 
147
148
149 /* Look for an AGP bridge. Windows only expects the aperture in the
150    AGP bridge and some BIOS forget to initialize the Northbridge too.
151    Work around this here. 
152
153    Do an PCI bus scan by hand because we're running before the PCI
154    subsystem. 
155
156    All K8 AGP bridges are AGPv3 compliant, so we can do this scan
157    generically. It's probably overkill to always scan all slots because
158    the AGP bridges should be always an own bus on the HT hierarchy, 
159    but do it here for future safety. */
160 static __u32 __init search_agp_bridge(u32 *order, int *valid_agp)
161 {
162         int num, slot, func;
163
164         /* Poor man's PCI discovery */
165         for (num = 0; num < 32; num++) { 
166                 for (slot = 0; slot < 32; slot++) { 
167                         for (func = 0; func < 8; func++) { 
168                                 u32 class, cap;
169                                 u8 type;
170                                 class = read_pci_config(num,slot,func,
171                                                         PCI_CLASS_REVISION);
172                                 if (class == 0xffffffff)
173                                         break; 
174                                 
175                                 switch (class >> 16) { 
176                                 case PCI_CLASS_BRIDGE_HOST:
177                                 case PCI_CLASS_BRIDGE_OTHER: /* needed? */
178                                         /* AGP bridge? */
179                                         cap = find_cap(num,slot,func,PCI_CAP_ID_AGP);
180                                         if (!cap)
181                                                 break;
182                                         *valid_agp = 1; 
183                                         return read_agp(num,slot,func,cap,order);
184                                 } 
185                                 
186                                 /* No multi-function device? */
187                                 type = read_pci_config_byte(num,slot,func,
188                                                                PCI_HEADER_TYPE);
189                                 if (!(type & 0x80))
190                                         break;
191                         } 
192                 } 
193         }
194         printk("No AGP bridge found\n"); 
195         return 0;
196 }
197
198 void __init iommu_hole_init(void) 
199
200         int fix, num; 
201         u32 aper_size, aper_alloc = 0, aper_order;
202         u64 aper_base; 
203         int valid_agp = 0;
204
205         if (iommu_aperture_disabled)
206                 return;
207
208         printk("Checking aperture...\n"); 
209
210         fix = 0;
211         for (num = 24; num < 32; num++) {               
212                 char name[30];
213                 if (read_pci_config(0, num, 3, 0x00) != NB_ID_3) 
214                         continue;       
215
216                 iommu_aperture = 1; 
217
218                 aper_order = (read_pci_config(0, num, 3, 0x90) >> 1) & 7; 
219                 aper_size = (32 * 1024 * 1024) << aper_order; 
220                 aper_base = read_pci_config(0, num, 3, 0x94) & 0x7fff;
221                 aper_base <<= 25; 
222
223                 printk("CPU %d: aperture @ %Lx size %u MB\n", num-24, 
224                        aper_base, aper_size>>20);
225                 
226                 sprintf(name, "northbridge cpu %d", num-24); 
227
228                 if (!aperture_valid(name, aper_base, aper_size)) { 
229                         fix = 1; 
230                         break; 
231                 } 
232         } 
233
234         if (!fix && !fallback_aper_force) 
235                 return; 
236
237         if (!fallback_aper_force)
238                 aper_alloc = search_agp_bridge(&aper_order, &valid_agp); 
239                 
240         if (aper_alloc) { 
241                 /* Got the aperture from the AGP bridge */
242         } else if ((!no_iommu && end_pfn >= 0xffffffff>>PAGE_SHIFT) ||
243                    force_iommu ||
244                    valid_agp || 
245                    fallback_aper_force) { 
246                 /* When there is a AGP bridge in the system assume the
247                    user wants to use the AGP driver too and needs an
248                    aperture.  However this case (AGP but no good
249                    aperture) should only happen with a more broken than
250                    usual BIOS, because it would even break Windows. */
251
252         printk("Your BIOS doesn't leave a aperture memory hole\n");
253         printk("Please enable the IOMMU option in the BIOS setup\n"); 
254                 printk("This costs you %d MB of RAM\n", 32 << fallback_aper_order); 
255  
256                 aper_order = fallback_aper_order;
257         aper_alloc = allocate_aperture(); 
258                 if (!aper_alloc) { 
259                         /* Could disable AGP and IOMMU here, but it's probably
260                            not worth it. But the later users cannot deal with
261                            bad apertures and turning on the aperture over memory
262                            causes very strange problems, so it's better to 
263                            panic early. */
264                         panic("Not enough memory for aperture");
265                 }
266         } else { 
267                 return; 
268         } 
269
270         /* Fix up the north bridges */
271         for (num = 24; num < 32; num++) {               
272                 if (read_pci_config(0, num, 3, 0x00) != NB_ID_3) 
273                         continue;       
274
275                 /* Don't enable translation yet. That is done later. 
276                    Assume this BIOS didn't initialise the GART so 
277                    just overwrite all previous bits */ 
278                 write_pci_config(0, num, 3, 0x90, aper_order<<1); 
279                 write_pci_config(0, num, 3, 0x94, aper_alloc>>25); 
280         } 
281