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/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>
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 static struct resource gart_resource = {
39 .flags = IORESOURCE_MEM,
42 static void __init insert_aperture_resource(u32 aper_base, u32 aper_size)
44 gart_resource.start = aper_base;
45 gart_resource.end = aper_base + aper_size - 1;
46 insert_resource(&iomem_resource, &gart_resource);
49 /* This code runs before the PCI subsystem is initialized, so just
50 access the northbridge directly. */
52 static u32 __init allocate_aperture(void)
54 pg_data_t *nd0 = NODE_DATA(0);
58 if (fallback_aper_order > 7)
59 fallback_aper_order = 7;
60 aper_size = (32 * 1024 * 1024) << fallback_aper_order;
63 * Aperture has to be naturally aligned. This means an 2GB aperture won't
64 * have much chance of finding a place in the lower 4GB of memory.
65 * Unfortunately we cannot move it up because that would make the
68 p = __alloc_bootmem_node(nd0, aper_size, aper_size, 0);
69 if (!p || __pa(p)+aper_size > 0xffffffff) {
70 printk("Cannot allocate aperture memory hole (%p,%uK)\n",
73 free_bootmem_node(nd0, __pa(p), aper_size);
76 printk("Mapping aperture over %d KB of RAM @ %lx\n",
77 aper_size >> 10, __pa(p));
78 insert_aperture_resource((u32)__pa(p), aper_size);
82 static int __init aperture_valid(u64 aper_base, u32 aper_size)
86 if (aper_size < 64*1024*1024) {
87 printk("Aperture too small (%d MB)\n", aper_size>>20);
90 if (aper_base + aper_size >= 0xffffffff) {
91 printk("Aperture beyond 4GB. Ignoring.\n");
94 if (e820_any_mapped(aper_base, aper_base + aper_size, E820_RAM)) {
95 printk("Aperture pointing to e820 RAM. Ignoring.\n");
101 /* Find a PCI capability */
102 static __u32 __init find_cap(int num, int slot, int func, int cap)
106 if (!(read_pci_config_16(num,slot,func,PCI_STATUS) & PCI_STATUS_CAP_LIST))
108 pos = read_pci_config_byte(num,slot,func,PCI_CAPABILITY_LIST);
109 for (bytes = 0; bytes < 48 && pos >= 0x40; bytes++) {
112 id = read_pci_config_byte(num,slot,func,pos+PCI_CAP_LIST_ID);
117 pos = read_pci_config_byte(num,slot,func,pos+PCI_CAP_LIST_NEXT);
122 /* Read a standard AGPv3 bridge header */
123 static __u32 __init read_agp(int num, int slot, int func, int cap, u32 *order)
128 u32 aper_low, aper_hi;
131 printk("AGP bridge at %02x:%02x:%02x\n", num, slot, func);
132 apsizereg = read_pci_config_16(num,slot,func, cap + 0x14);
133 if (apsizereg == 0xffffffff) {
134 printk("APSIZE in AGP bridge unreadable\n");
138 apsize = apsizereg & 0xfff;
139 /* Some BIOS use weird encodings not in the AGPv3 table. */
142 nbits = hweight16(apsize);
144 if ((int)*order < 0) /* < 32MB */
147 aper_low = read_pci_config(num,slot,func, 0x10);
148 aper_hi = read_pci_config(num,slot,func,0x14);
149 aper = (aper_low & ~((1<<22)-1)) | ((u64)aper_hi << 32);
151 printk("Aperture from AGP @ %Lx size %u MB (APSIZE %x)\n",
152 aper, 32 << *order, apsizereg);
154 if (!aperture_valid(aper, (32*1024*1024) << *order))
159 /* Look for an AGP bridge. Windows only expects the aperture in the
160 AGP bridge and some BIOS forget to initialize the Northbridge too.
161 Work around this here.
163 Do an PCI bus scan by hand because we're running before the PCI
166 All K8 AGP bridges are AGPv3 compliant, so we can do this scan
167 generically. It's probably overkill to always scan all slots because
168 the AGP bridges should be always an own bus on the HT hierarchy,
169 but do it here for future safety. */
170 static __u32 __init search_agp_bridge(u32 *order, int *valid_agp)
174 /* Poor man's PCI discovery */
175 for (num = 0; num < 256; num++) {
176 for (slot = 0; slot < 32; slot++) {
177 for (func = 0; func < 8; func++) {
180 class = read_pci_config(num,slot,func,
182 if (class == 0xffffffff)
185 switch (class >> 16) {
186 case PCI_CLASS_BRIDGE_HOST:
187 case PCI_CLASS_BRIDGE_OTHER: /* needed? */
189 cap = find_cap(num,slot,func,PCI_CAP_ID_AGP);
193 return read_agp(num,slot,func,cap,order);
196 /* No multi-function device? */
197 type = read_pci_config_byte(num,slot,func,
204 printk("No AGP bridge found\n");
208 void __init iommu_hole_init(void)
211 u32 aper_size, aper_alloc = 0, aper_order = 0, last_aper_order = 0;
212 u64 aper_base, last_aper_base = 0;
215 if (iommu_aperture_disabled || !fix_aperture || !early_pci_allowed())
218 printk("Checking aperture...\n");
221 for (num = 24; num < 32; num++) {
222 if (!early_is_k8_nb(read_pci_config(0, num, 3, 0x00)))
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;
233 printk("CPU %d: aperture @ %Lx size %u MB\n", num-24,
234 aper_base, aper_size>>20);
236 if (!aperture_valid(aper_base, aper_size)) {
241 if ((last_aper_order && aper_order != last_aper_order) ||
242 (last_aper_base && aper_base != last_aper_base)) {
246 last_aper_order = aper_order;
247 last_aper_base = aper_base;
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);
258 if (!fallback_aper_force)
259 aper_alloc = search_agp_bridge(&aper_order, &valid_agp);
262 /* Got the aperture from the AGP bridge */
263 } else if (swiotlb && !valid_agp) {
265 } else if ((!no_iommu && end_pfn > MAX_DMA32_PFN) ||
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);
274 aper_order = fallback_aper_order;
275 aper_alloc = allocate_aperture();
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
282 panic("Not enough memory for aperture");
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)))
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);