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