2 * Firmware replacement code.
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.
10 * Copyright 2002 Andi Kleen, SuSE Labs.
12 #include <linux/config.h>
13 #include <linux/kernel.h>
14 #include <linux/types.h>
15 #include <linux/init.h>
16 #include <linux/bootmem.h>
17 #include <linux/mmzone.h>
18 #include <linux/pci_ids.h>
19 #include <linux/pci.h>
20 #include <linux/bitops.h>
23 #include <asm/proto.h>
24 #include <asm/pci-direct.h>
29 int iommu_aperture_disabled __initdata = 0;
30 int iommu_aperture_allowed __initdata = 0;
32 int fallback_aper_order __initdata = 1; /* 64MB */
33 int fallback_aper_force __initdata = 0;
35 int fix_aperture __initdata = 1;
37 /* This code runs before the PCI subsystem is initialized, so just
38 access the northbridge directly. */
40 static u32 __init allocate_aperture(void)
42 pg_data_t *nd0 = NODE_DATA(0);
46 if (fallback_aper_order > 7)
47 fallback_aper_order = 7;
48 aper_size = (32 * 1024 * 1024) << fallback_aper_order;
51 * Aperture has to be naturally aligned. This means an 2GB aperture won't
52 * have much chances to find a place in the lower 4GB of memory.
53 * Unfortunately we cannot move it up because that would make the
56 p = __alloc_bootmem_node(nd0, aper_size, aper_size, 0);
57 if (!p || __pa(p)+aper_size > 0xffffffff) {
58 printk("Cannot allocate aperture memory hole (%p,%uK)\n",
61 free_bootmem_node(nd0, __pa(p), aper_size);
64 printk("Mapping aperture over %d KB of RAM @ %lx\n",
65 aper_size >> 10, __pa(p));
69 static int __init aperture_valid(u64 aper_base, u32 aper_size)
73 if (aper_size < 64*1024*1024) {
74 printk("Aperture too small (%d MB)\n", aper_size>>20);
77 if (aper_base + aper_size >= 0xffffffff) {
78 printk("Aperture beyond 4GB. Ignoring.\n");
81 if (e820_any_mapped(aper_base, aper_base + aper_size, E820_RAM)) {
82 printk("Aperture pointing to e820 RAM. Ignoring.\n");
88 /* Find a PCI capability */
89 static __u32 __init find_cap(int num, int slot, int func, int cap)
93 if (!(read_pci_config_16(num,slot,func,PCI_STATUS) & PCI_STATUS_CAP_LIST))
95 pos = read_pci_config_byte(num,slot,func,PCI_CAPABILITY_LIST);
96 for (bytes = 0; bytes < 48 && pos >= 0x40; bytes++) {
99 id = read_pci_config_byte(num,slot,func,pos+PCI_CAP_LIST_ID);
104 pos = read_pci_config_byte(num,slot,func,pos+PCI_CAP_LIST_NEXT);
109 /* Read a standard AGPv3 bridge header */
110 static __u32 __init read_agp(int num, int slot, int func, int cap, u32 *order)
115 u32 aper_low, aper_hi;
118 printk("AGP bridge at %02x:%02x:%02x\n", num, slot, func);
119 apsizereg = read_pci_config_16(num,slot,func, cap + 0x14);
120 if (apsizereg == 0xffffffff) {
121 printk("APSIZE in AGP bridge unreadable\n");
125 apsize = apsizereg & 0xfff;
126 /* Some BIOS use weird encodings not in the AGPv3 table. */
129 nbits = hweight16(apsize);
131 if ((int)*order < 0) /* < 32MB */
134 aper_low = read_pci_config(num,slot,func, 0x10);
135 aper_hi = read_pci_config(num,slot,func,0x14);
136 aper = (aper_low & ~((1<<22)-1)) | ((u64)aper_hi << 32);
138 printk("Aperture from AGP @ %Lx size %u MB (APSIZE %x)\n",
139 aper, 32 << *order, apsizereg);
141 if (!aperture_valid(aper, (32*1024*1024) << *order))
146 /* Look for an AGP bridge. Windows only expects the aperture in the
147 AGP bridge and some BIOS forget to initialize the Northbridge too.
148 Work around this here.
150 Do an PCI bus scan by hand because we're running before the PCI
153 All K8 AGP bridges are AGPv3 compliant, so we can do this scan
154 generically. It's probably overkill to always scan all slots because
155 the AGP bridges should be always an own bus on the HT hierarchy,
156 but do it here for future safety. */
157 static __u32 __init search_agp_bridge(u32 *order, int *valid_agp)
161 /* Poor man's PCI discovery */
162 for (num = 0; num < 256; num++) {
163 for (slot = 0; slot < 32; slot++) {
164 for (func = 0; func < 8; func++) {
167 class = read_pci_config(num,slot,func,
169 if (class == 0xffffffff)
172 switch (class >> 16) {
173 case PCI_CLASS_BRIDGE_HOST:
174 case PCI_CLASS_BRIDGE_OTHER: /* needed? */
176 cap = find_cap(num,slot,func,PCI_CAP_ID_AGP);
180 return read_agp(num,slot,func,cap,order);
183 /* No multi-function device? */
184 type = read_pci_config_byte(num,slot,func,
191 printk("No AGP bridge found\n");
195 void __init iommu_hole_init(void)
198 u32 aper_size, aper_alloc = 0, aper_order = 0, last_aper_order = 0;
199 u64 aper_base, last_aper_base = 0;
202 if (iommu_aperture_disabled || !fix_aperture)
205 printk("Checking aperture...\n");
208 for (num = 24; num < 32; num++) {
209 if (!early_is_k8_nb(read_pci_config(0, num, 3, 0x00)))
215 aper_order = (read_pci_config(0, num, 3, 0x90) >> 1) & 7;
216 aper_size = (32 * 1024 * 1024) << aper_order;
217 aper_base = read_pci_config(0, num, 3, 0x94) & 0x7fff;
220 printk("CPU %d: aperture @ %Lx size %u MB\n", num-24,
221 aper_base, aper_size>>20);
223 if (!aperture_valid(aper_base, aper_size)) {
228 if ((last_aper_order && aper_order != last_aper_order) ||
229 (last_aper_base && aper_base != last_aper_base)) {
233 last_aper_order = aper_order;
234 last_aper_base = aper_base;
237 if (!fix && !fallback_aper_force)
240 if (!fallback_aper_force)
241 aper_alloc = search_agp_bridge(&aper_order, &valid_agp);
244 /* Got the aperture from the AGP bridge */
245 } else if (swiotlb && !valid_agp) {
247 } else if ((!no_iommu && end_pfn > MAX_DMA32_PFN) ||
250 fallback_aper_force) {
251 printk("Your BIOS doesn't leave a aperture memory hole\n");
252 printk("Please enable the IOMMU option in the BIOS setup\n");
253 printk("This costs you %d MB of RAM\n",
254 32 << fallback_aper_order);
256 aper_order = fallback_aper_order;
257 aper_alloc = allocate_aperture();
259 /* Could disable AGP and IOMMU here, but it's probably
260 not worth it. But the later users cannot deal with
261 bad apertures and turning on the aperture over memory
262 causes very strange problems, so it's better to
264 panic("Not enough memory for aperture");
270 /* Fix up the north bridges */
271 for (num = 24; num < 32; num++) {
272 if (!early_is_k8_nb(read_pci_config(0, num, 3, 0x00)))
275 /* Don't enable translation yet. That is done later.
276 Assume this BIOS didn't initialise the GART so
277 just overwrite all previous bits */
278 write_pci_config(0, num, 3, 0x90, aper_order<<1);
279 write_pci_config(0, num, 3, 0x94, aper_alloc>>25);