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