1
2#include <linux/kernel.h>
3#include <linux/types.h>
4#include <linux/init.h>
5#include <linux/bootmem.h>
6#include <linux/mmzone.h>
7#include <linux/pci_ids.h>
8#include <linux/pci.h>
9#include <linux/bitops.h>
10#include <linux/ioport.h>
11#include <asm/e820.h>
12#include <asm/io.h>
13#include <asm/proto.h>
14#include <asm/pci-direct.h>
15#include <asm/dma.h>
16#include <asm/k8.h>
17
18int iommu_aperture;
19int iommu_aperture_disabled __initdata = 0;
20int iommu_aperture_allowed __initdata = 0;
21
22int fallback_aper_order __initdata = 1; /* 64MB */
23int fallback_aper_force __initdata = 0;
24
25int fix_aperture __initdata = 1;
26
27static struct resource gart_resource = {
28	.name	= "GART",
29	.flags	= IORESOURCE_MEM,
30};
31
32static void __init insert_aperture_resource(u32 aper_base, u32 aper_size)
33{
34	gart_resource.start = aper_base;
35	gart_resource.end = aper_base + aper_size - 1;
36	insert_resource(&iomem_resource, &gart_resource);
37}
38
39/* This code runs before the PCI subsystem is initialized, so just
40   access the northbridge directly. */
41
42static u32 __init allocate_aperture(void)
43{
44	u32 aper_size;
45	void *p;
46
47	if (fallback_aper_order > 7)
48		fallback_aper_order = 7;
49	aper_size = (32 * 1024 * 1024) << fallback_aper_order;
50
51	/*
52	 * Aperture has to be naturally aligned. This means an 2GB aperture won't
53	 * have much chance of finding a place in the lower 4GB of memory.
54	 * Unfortunately we cannot move it up because that would make the
55	 * IOMMU useless.
56	 */
57	p = __alloc_bootmem_nopanic(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(__pa(p), aper_size);
63		return 0;
64	}
65	printk("Mapping aperture over %d KB of RAM @ %lx\n",
66	       aper_size >> 10, __pa(p));
67	insert_aperture_resource((u32)__pa(p), aper_size);
68	return (u32)__pa(p);
69}
70
71static int __init aperture_valid(u64 aper_base, u32 aper_size)
72{
73	if (!aper_base)
74		return 0;
75	if (aper_size < 64*1024*1024) {
76		printk("Aperture too small (%d MB)\n", aper_size>>20);
77		return 0;
78	}
79	if (aper_base + aper_size > 0x100000000UL) {
80		printk("Aperture beyond 4GB. Ignoring.\n");
81		return 0;
82	}
83	if (e820_any_mapped(aper_base, aper_base + aper_size, E820_RAM)) {
84		printk("Aperture pointing to e820 RAM. Ignoring.\n");
85		return 0;
86	}
87	return 1;
88}
89
90/* Find a PCI capability */
91static __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 */
112static __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(aper, (32*1024*1024) << *order))
144	    return 0;
145	return (u32)aper;
146}
147
148static __u32 __init search_agp_bridge(u32 *order, int *valid_agp)
149{
150	int num, slot, func;
151
152	/* Poor man's PCI discovery */
153	for (num = 0; num < 256; num++) {
154		for (slot = 0; slot < 32; slot++) {
155			for (func = 0; func < 8; func++) {
156				u32 class, cap;
157				u8 type;
158				class = read_pci_config(num,slot,func,
159							PCI_CLASS_REVISION);
160				if (class == 0xffffffff)
161					break;
162
163				switch (class >> 16) {
164				case PCI_CLASS_BRIDGE_HOST:
165				case PCI_CLASS_BRIDGE_OTHER: /* needed? */
166					/* AGP bridge? */
167					cap = find_cap(num,slot,func,PCI_CAP_ID_AGP);
168					if (!cap)
169						break;
170					*valid_agp = 1;
171					return read_agp(num,slot,func,cap,order);
172				}
173
174				/* No multi-function device? */
175				type = read_pci_config_byte(num,slot,func,
176							       PCI_HEADER_TYPE);
177				if (!(type & 0x80))
178					break;
179			}
180		}
181	}
182	printk("No AGP bridge found\n");
183	return 0;
184}
185
186void __init iommu_hole_init(void)
187{
188	int fix, num;
189	u32 aper_size, aper_alloc = 0, aper_order = 0, last_aper_order = 0;
190	u64 aper_base, last_aper_base = 0;
191	int valid_agp = 0;
192
193	if (iommu_aperture_disabled || !fix_aperture || !early_pci_allowed())
194		return;
195
196	printk("Checking aperture...\n");
197
198	fix = 0;
199	for (num = 24; num < 32; num++) {
200		if (!early_is_k8_nb(read_pci_config(0, num, 3, 0x00)))
201			continue;
202
203		iommu_detected = 1;
204		iommu_aperture = 1;
205
206		aper_order = (read_pci_config(0, num, 3, 0x90) >> 1) & 7;
207		aper_size = (32 * 1024 * 1024) << aper_order;
208		aper_base = read_pci_config(0, num, 3, 0x94) & 0x7fff;
209		aper_base <<= 25;
210
211		printk("CPU %d: aperture @ %Lx size %u MB\n", num-24,
212		       aper_base, aper_size>>20);
213
214		if (!aperture_valid(aper_base, aper_size)) {
215			fix = 1;
216			break;
217		}
218
219		if ((last_aper_order && aper_order != last_aper_order) ||
220		    (last_aper_base && aper_base != last_aper_base)) {
221			fix = 1;
222			break;
223		}
224		last_aper_order = aper_order;
225		last_aper_base = aper_base;
226	}
227
228	if (!fix && !fallback_aper_force) {
229		if (last_aper_base) {
230			unsigned long n = (32 * 1024 * 1024) << last_aper_order;
231			insert_aperture_resource((u32)last_aper_base, n);
232		}
233		return;
234	}
235
236	if (!fallback_aper_force)
237		aper_alloc = search_agp_bridge(&aper_order, &valid_agp);
238
239	if (aper_alloc) {
240		/* Got the aperture from the AGP bridge */
241	} else if (swiotlb && !valid_agp) {
242		/* Do nothing */
243	} else if ((!no_iommu && end_pfn > MAX_DMA32_PFN) ||
244		   force_iommu ||
245		   valid_agp ||
246		   fallback_aper_force) {
247		printk("Your BIOS doesn't leave a aperture memory hole\n");
248		printk("Please enable the IOMMU option in the BIOS setup\n");
249		printk("This costs you %d MB of RAM\n",
250		       32 << fallback_aper_order);
251
252		aper_order = fallback_aper_order;
253		aper_alloc = allocate_aperture();
254		if (!aper_alloc) {
255			/* Could disable AGP and IOMMU here, but it's probably
256			   not worth it. But the later users cannot deal with
257			   bad apertures and turning on the aperture over memory
258			   causes very strange problems, so it's better to
259			   panic early. */
260			panic("Not enough memory for aperture");
261		}
262	} else {
263		return;
264	}
265
266	/* Fix up the north bridges */
267	for (num = 24; num < 32; num++) {
268		if (!early_is_k8_nb(read_pci_config(0, num, 3, 0x00)))
269			continue;
270
271		/* Don't enable translation yet. That is done later.
272		   Assume this BIOS didn't initialise the GART so
273		   just overwrite all previous bits */
274		write_pci_config(0, num, 3, 0x90, aper_order<<1);
275		write_pci_config(0, num, 3, 0x94, aper_alloc>>25);
276	}
277}
278