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