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