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.
11 * $Id: aperture.c,v 1.7 2003/08/01 03:36:18 ak Exp $
13 #include <linux/config.h>
14 #include <linux/kernel.h>
15 #include <linux/types.h>
16 #include <linux/init.h>
17 #include <linux/bootmem.h>
18 #include <linux/mmzone.h>
19 #include <linux/pci_ids.h>
20 #include <linux/pci.h>
21 #include <linux/bitops.h>
24 #include <asm/proto.h>
25 #include <asm/pci-direct.h>
28 int iommu_aperture_disabled __initdata = 0;
29 int iommu_aperture_allowed __initdata = 0;
31 int fallback_aper_order __initdata = 1; /* 64MB */
32 int fallback_aper_force __initdata = 0;
34 int fix_aperture __initdata = 1;
36 /* This code runs before the PCI subsystem is initialized, so just
37 access the northbridge directly. */
39 #define NB_ID_3 (PCI_VENDOR_ID_AMD | (0x1103<<16))
41 static u32 __init allocate_aperture(void)
43 pg_data_t *nd0 = NODE_DATA(0);
47 if (fallback_aper_order > 7)
48 fallback_aper_order = 7;
49 aper_size = (32 * 1024 * 1024) << fallback_aper_order;
52 * Aperture has to be naturally aligned. This means an 2GB aperture won't
53 * have much chances to find a place in the lower 4GB of memory.
54 * Unfortunately we cannot move it up because that would make the
57 p = __alloc_bootmem_node(nd0, aper_size, aper_size, 0);
58 if (!p || __pa(p)+aper_size > 0xffffffff) {
59 printk("Cannot allocate aperture memory hole (%p,%uK)\n",
62 free_bootmem_node(nd0, (unsigned long)p, aper_size);
65 printk("Mapping aperture over %d KB of RAM @ %lx\n",
66 aper_size >> 10, __pa(p));
70 static int __init aperture_valid(char *name, u64 aper_base, u32 aper_size)
74 if (aper_size < 64*1024*1024) {
75 printk("Aperture from %s too small (%d MB)\n", name, aper_size>>20);
78 if (aper_base + aper_size >= 0xffffffff) {
79 printk("Aperture from %s beyond 4GB. Ignoring.\n",name);
82 if (e820_mapped(aper_base, aper_base + aper_size, E820_RAM)) {
83 printk("Aperture from %s pointing to e820 RAM. Ignoring.\n",name);
89 /* Find a PCI capability */
90 static __u32 __init find_cap(int num, int slot, int func, int cap)
94 if (!(read_pci_config_16(num,slot,func,PCI_STATUS) & PCI_STATUS_CAP_LIST))
96 pos = read_pci_config_byte(num,slot,func,PCI_CAPABILITY_LIST);
97 for (bytes = 0; bytes < 48 && pos >= 0x40; bytes++) {
100 id = read_pci_config_byte(num,slot,func,pos+PCI_CAP_LIST_ID);
105 pos = read_pci_config_byte(num,slot,func,pos+PCI_CAP_LIST_NEXT);
110 /* Read a standard AGPv3 bridge header */
111 static __u32 __init read_agp(int num, int slot, int func, int cap, u32 *order)
116 u32 aper_low, aper_hi;
119 printk("AGP bridge at %02x:%02x:%02x\n", num, slot, func);
120 apsizereg = read_pci_config_16(num,slot,func, cap + 0x14);
121 if (apsizereg == 0xffffffff) {
122 printk("APSIZE in AGP bridge unreadable\n");
126 apsize = apsizereg & 0xfff;
127 /* Some BIOS use weird encodings not in the AGPv3 table. */
130 nbits = hweight16(apsize);
132 if ((int)*order < 0) /* < 32MB */
135 aper_low = read_pci_config(num,slot,func, 0x10);
136 aper_hi = read_pci_config(num,slot,func,0x14);
137 aper = (aper_low & ~((1<<22)-1)) | ((u64)aper_hi << 32);
139 printk("Aperture from AGP @ %Lx size %u MB (APSIZE %x)\n",
140 aper, 32 << *order, apsizereg);
142 if (!aperture_valid("AGP bridge", aper, (32*1024*1024) << *order))
147 /* Look for an AGP bridge. Windows only expects the aperture in the
148 AGP bridge and some BIOS forget to initialize the Northbridge too.
149 Work around this here.
151 Do an PCI bus scan by hand because we're running before the PCI
154 All K8 AGP bridges are AGPv3 compliant, so we can do this scan
155 generically. It's probably overkill to always scan all slots because
156 the AGP bridges should be always an own bus on the HT hierarchy,
157 but do it here for future safety. */
158 static __u32 __init search_agp_bridge(u32 *order, int *valid_agp)
162 /* Poor man's PCI discovery */
163 for (num = 0; num < 32; num++) {
164 for (slot = 0; slot < 32; slot++) {
165 for (func = 0; func < 8; func++) {
168 class = read_pci_config(num,slot,func,
170 if (class == 0xffffffff)
173 switch (class >> 16) {
174 case PCI_CLASS_BRIDGE_HOST:
175 case PCI_CLASS_BRIDGE_OTHER: /* needed? */
177 cap = find_cap(num,slot,func,PCI_CAP_ID_AGP);
181 return read_agp(num,slot,func,cap,order);
184 /* No multi-function device? */
185 type = read_pci_config_byte(num,slot,func,
192 printk("No AGP bridge found\n");
196 void __init iommu_hole_init(void)
199 u32 aper_size, aper_alloc = 0, aper_order = 0, last_aper_order = 0;
200 u64 aper_base, last_aper_base = 0;
203 if (iommu_aperture_disabled || !fix_aperture)
206 printk("Checking aperture...\n");
209 for (num = 24; num < 32; num++) {
211 if (read_pci_config(0, num, 3, 0x00) != NB_ID_3)
216 aper_order = (read_pci_config(0, num, 3, 0x90) >> 1) & 7;
217 aper_size = (32 * 1024 * 1024) << aper_order;
218 aper_base = read_pci_config(0, num, 3, 0x94) & 0x7fff;
221 printk("CPU %d: aperture @ %Lx size %u MB\n", num-24,
222 aper_base, aper_size>>20);
224 sprintf(name, "northbridge cpu %d", num-24);
226 if (!aperture_valid(name, aper_base, aper_size)) {
231 if ((last_aper_order && aper_order != last_aper_order) ||
232 (last_aper_base && aper_base != last_aper_base)) {
236 last_aper_order = aper_order;
237 last_aper_base = aper_base;
240 if (!fix && !fallback_aper_force)
243 if (!fallback_aper_force)
244 aper_alloc = search_agp_bridge(&aper_order, &valid_agp);
247 /* Got the aperture from the AGP bridge */
248 } else if (swiotlb && !valid_agp) {
250 } else if ((!no_iommu && end_pfn >= 0xffffffff>>PAGE_SHIFT) ||
253 fallback_aper_force) {
254 printk("Your BIOS doesn't leave a aperture memory hole\n");
255 printk("Please enable the IOMMU option in the BIOS setup\n");
256 printk("This costs you %d MB of RAM\n",
257 32 << fallback_aper_order);
259 aper_order = fallback_aper_order;
260 aper_alloc = allocate_aperture();
262 /* Could disable AGP and IOMMU here, but it's probably
263 not worth it. But the later users cannot deal with
264 bad apertures and turning on the aperture over memory
265 causes very strange problems, so it's better to
267 panic("Not enough memory for aperture");
273 /* Fix up the north bridges */
274 for (num = 24; num < 32; num++) {
275 if (read_pci_config(0, num, 3, 0x00) != NB_ID_3)
278 /* Don't enable translation yet. That is done later.
279 Assume this BIOS didn't initialise the GART so
280 just overwrite all previous bits */
281 write_pci_config(0, num, 3, 0x90, aper_order<<1);
282 write_pci_config(0, num, 3, 0x94, aper_alloc>>25);