xref: /linux/arch/x86/kernel/aperture_64.c (revision 98366c20a275e957416e9516db5dcb7195b4e101)
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/gart.h>
24 #include <asm/pci-direct.h>
25 #include <asm/dma.h>
26 #include <asm/k8.h>
27 
28 int gart_iommu_aperture;
29 int gart_iommu_aperture_disabled __initdata = 0;
30 int gart_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 gart_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 (gart_iommu_aperture_disabled || !fix_aperture ||
215 	    !early_pci_allowed())
216 		return;
217 
218 	printk(KERN_INFO  "Checking aperture...\n");
219 
220 	fix = 0;
221 	for (num = 24; num < 32; num++) {
222 		if (!early_is_k8_nb(read_pci_config(0, num, 3, 0x00)))
223 			continue;
224 
225 		iommu_detected = 1;
226 		gart_iommu_aperture = 1;
227 
228 		aper_order = (read_pci_config(0, num, 3, 0x90) >> 1) & 7;
229 		aper_size = (32 * 1024 * 1024) << aper_order;
230 		aper_base = read_pci_config(0, num, 3, 0x94) & 0x7fff;
231 		aper_base <<= 25;
232 
233 		printk("CPU %d: aperture @ %Lx size %u MB\n", num-24,
234 		       aper_base, aper_size>>20);
235 
236 		if (!aperture_valid(aper_base, aper_size)) {
237 			fix = 1;
238 			break;
239 		}
240 
241 		if ((last_aper_order && aper_order != last_aper_order) ||
242 		    (last_aper_base && aper_base != last_aper_base)) {
243 			fix = 1;
244 			break;
245 		}
246 		last_aper_order = aper_order;
247 		last_aper_base = aper_base;
248 	}
249 
250 	if (!fix && !fallback_aper_force) {
251 		if (last_aper_base) {
252 			unsigned long n = (32 * 1024 * 1024) << last_aper_order;
253 			insert_aperture_resource((u32)last_aper_base, n);
254 		}
255 		return;
256 	}
257 
258 	if (!fallback_aper_force)
259 		aper_alloc = search_agp_bridge(&aper_order, &valid_agp);
260 
261 	if (aper_alloc) {
262 		/* Got the aperture from the AGP bridge */
263 	} else if (swiotlb && !valid_agp) {
264 		/* Do nothing */
265 	} else if ((!no_iommu && end_pfn > MAX_DMA32_PFN) ||
266 		   force_iommu ||
267 		   valid_agp ||
268 		   fallback_aper_force) {
269 		printk("Your BIOS doesn't leave a aperture memory hole\n");
270 		printk("Please enable the IOMMU option in the BIOS setup\n");
271 		printk("This costs you %d MB of RAM\n",
272 		       32 << fallback_aper_order);
273 
274 		aper_order = fallback_aper_order;
275 		aper_alloc = allocate_aperture();
276 		if (!aper_alloc) {
277 			/* Could disable AGP and IOMMU here, but it's probably
278 			   not worth it. But the later users cannot deal with
279 			   bad apertures and turning on the aperture over memory
280 			   causes very strange problems, so it's better to
281 			   panic early. */
282 			panic("Not enough memory for aperture");
283 		}
284 	} else {
285 		return;
286 	}
287 
288 	/* Fix up the north bridges */
289 	for (num = 24; num < 32; num++) {
290 		if (!early_is_k8_nb(read_pci_config(0, num, 3, 0x00)))
291 			continue;
292 
293 		/* Don't enable translation yet. That is done later.
294 		   Assume this BIOS didn't initialise the GART so
295 		   just overwrite all previous bits */
296 		write_pci_config(0, num, 3, 0x90, aper_order<<1);
297 		write_pci_config(0, num, 3, 0x94, aper_alloc>>25);
298 	}
299 }
300