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 #ifdef CONFIG_DISCONTIGMEM
44 pg_data_t *nd0 = NODE_DATA(0);
46 pg_data_t *nd0 = &contig_page_data;
51 if (fallback_aper_order > 7)
52 fallback_aper_order = 7;
53 aper_size = (32 * 1024 * 1024) << fallback_aper_order;
56 * Aperture has to be naturally aligned. This means an 2GB aperture won't
57 * have much chances to find a place in the lower 4GB of memory.
58 * Unfortunately we cannot move it up because that would make the
61 p = __alloc_bootmem_node(nd0, aper_size, aper_size, 0);
62 if (!p || __pa(p)+aper_size > 0xffffffff) {
63 printk("Cannot allocate aperture memory hole (%p,%uK)\n",
66 free_bootmem_node(nd0, (unsigned long)p, aper_size);
69 printk("Mapping aperture over %d KB of RAM @ %lx\n",
70 aper_size >> 10, __pa(p));
74 static int __init aperture_valid(char *name, u64 aper_base, u32 aper_size)
78 if (aper_size < 64*1024*1024) {
79 printk("Aperture from %s too small (%d MB)\n", name, aper_size>>20);
82 if (aper_base + aper_size >= 0xffffffff) {
83 printk("Aperture from %s beyond 4GB. Ignoring.\n",name);
86 if (e820_mapped(aper_base, aper_base + aper_size, E820_RAM)) {
87 printk("Aperture from %s pointing to e820 RAM. Ignoring.\n",name);
93 /* Find a PCI capability */
94 static __u32 __init find_cap(int num, int slot, int func, int cap)
98 if (!(read_pci_config_16(num,slot,func,PCI_STATUS) & PCI_STATUS_CAP_LIST))
100 pos = read_pci_config_byte(num,slot,func,PCI_CAPABILITY_LIST);
101 for (bytes = 0; bytes < 48 && pos >= 0x40; bytes++) {
104 id = read_pci_config_byte(num,slot,func,pos+PCI_CAP_LIST_ID);
109 pos = read_pci_config_byte(num,slot,func,pos+PCI_CAP_LIST_NEXT);
114 /* Read a standard AGPv3 bridge header */
115 static __u32 __init read_agp(int num, int slot, int func, int cap, u32 *order)
120 u32 aper_low, aper_hi;
123 printk("AGP bridge at %02x:%02x:%02x\n", num, slot, func);
124 apsizereg = read_pci_config_16(num,slot,func, cap + 0x14);
125 if (apsizereg == 0xffffffff) {
126 printk("APSIZE in AGP bridge unreadable\n");
130 apsize = apsizereg & 0xfff;
131 /* Some BIOS use weird encodings not in the AGPv3 table. */
134 nbits = hweight16(apsize);
136 if ((int)*order < 0) /* < 32MB */
139 aper_low = read_pci_config(num,slot,func, 0x10);
140 aper_hi = read_pci_config(num,slot,func,0x14);
141 aper = (aper_low & ~((1<<22)-1)) | ((u64)aper_hi << 32);
143 printk("Aperture from AGP @ %Lx size %u MB (APSIZE %x)\n",
144 aper, 32 << *order, apsizereg);
146 if (!aperture_valid("AGP bridge", aper, (32*1024*1024) << *order))
151 /* Look for an AGP bridge. Windows only expects the aperture in the
152 AGP bridge and some BIOS forget to initialize the Northbridge too.
153 Work around this here.
155 Do an PCI bus scan by hand because we're running before the PCI
158 All K8 AGP bridges are AGPv3 compliant, so we can do this scan
159 generically. It's probably overkill to always scan all slots because
160 the AGP bridges should be always an own bus on the HT hierarchy,
161 but do it here for future safety. */
162 static __u32 __init search_agp_bridge(u32 *order, int *valid_agp)
166 /* Poor man's PCI discovery */
167 for (num = 0; num < 32; num++) {
168 for (slot = 0; slot < 32; slot++) {
169 for (func = 0; func < 8; func++) {
172 class = read_pci_config(num,slot,func,
174 if (class == 0xffffffff)
177 switch (class >> 16) {
178 case PCI_CLASS_BRIDGE_HOST:
179 case PCI_CLASS_BRIDGE_OTHER: /* needed? */
181 cap = find_cap(num,slot,func,PCI_CAP_ID_AGP);
185 return read_agp(num,slot,func,cap,order);
188 /* No multi-function device? */
189 type = read_pci_config_byte(num,slot,func,
196 printk("No AGP bridge found\n");
200 void __init iommu_hole_init(void)
203 u32 aper_size, aper_alloc = 0, aper_order, last_aper_order = 0;
204 u64 aper_base, last_aper_base = 0;
207 if (iommu_aperture_disabled || !fix_aperture)
210 printk("Checking aperture...\n");
213 for (num = 24; num < 32; num++) {
215 if (read_pci_config(0, num, 3, 0x00) != NB_ID_3)
220 aper_order = (read_pci_config(0, num, 3, 0x90) >> 1) & 7;
221 aper_size = (32 * 1024 * 1024) << aper_order;
222 aper_base = read_pci_config(0, num, 3, 0x94) & 0x7fff;
225 printk("CPU %d: aperture @ %Lx size %u MB\n", num-24,
226 aper_base, aper_size>>20);
228 sprintf(name, "northbridge cpu %d", num-24);
230 if (!aperture_valid(name, aper_base, aper_size)) {
235 if ((last_aper_order && aper_order != last_aper_order) ||
236 (last_aper_base && aper_base != last_aper_base)) {
240 last_aper_order = aper_order;
241 last_aper_base = aper_base;
244 if (!fix && !fallback_aper_force)
247 if (!fallback_aper_force)
248 aper_alloc = search_agp_bridge(&aper_order, &valid_agp);
251 /* Got the aperture from the AGP bridge */
252 } else if ((!no_iommu && end_pfn >= 0xffffffff>>PAGE_SHIFT) ||
255 fallback_aper_force) {
256 printk("Your BIOS doesn't leave a aperture memory hole\n");
257 printk("Please enable the IOMMU option in the BIOS setup\n");
258 printk("This costs you %d MB of RAM\n",
259 32 << fallback_aper_order);
261 aper_order = fallback_aper_order;
262 aper_alloc = allocate_aperture();
264 /* Could disable AGP and IOMMU here, but it's probably
265 not worth it. But the later users cannot deal with
266 bad apertures and turning on the aperture over memory
267 causes very strange problems, so it's better to
269 panic("Not enough memory for aperture");
275 /* Fix up the north bridges */
276 for (num = 24; num < 32; num++) {
277 if (read_pci_config(0, num, 3, 0x00) != NB_ID_3)
280 /* Don't enable translation yet. That is done later.
281 Assume this BIOS didn't initialise the GART so
282 just overwrite all previous bits */
283 write_pci_config(0, num, 3, 0x90, aper_order<<1);
284 write_pci_config(0, num, 3, 0x94, aper_alloc>>25);