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 /* This code runs before the PCI subsystem is initialized, so just
35 access the northbridge directly. */
37 #define NB_ID_3 (PCI_VENDOR_ID_AMD | (0x1103<<16))
39 static u32 __init allocate_aperture(void)
41 #ifdef CONFIG_DISCONTIGMEM
42 pg_data_t *nd0 = NODE_DATA(0);
44 pg_data_t *nd0 = &contig_page_data;
49 if (fallback_aper_order > 7)
50 fallback_aper_order = 7;
51 aper_size = (32 * 1024 * 1024) << fallback_aper_order;
54 * Aperture has to be naturally aligned. This means an 2GB aperture won't
55 * have much chances to find a place in the lower 4GB of memory.
56 * Unfortunately we cannot move it up because that would make the
59 p = __alloc_bootmem_node(nd0, aper_size, aper_size, 0);
60 if (!p || __pa(p)+aper_size > 0xffffffff) {
61 printk("Cannot allocate aperture memory hole (%p,%uK)\n",
64 free_bootmem_node(nd0, (unsigned long)p, aper_size);
67 printk("Mapping aperture over %d KB of RAM @ %lx\n",
68 aper_size >> 10, __pa(p));
72 static int __init aperture_valid(char *name, u64 aper_base, u32 aper_size)
76 if (aper_size < 64*1024*1024) {
77 printk("Aperture from %s too small (%d MB)\n", name, aper_size>>20);
80 if (aper_base + aper_size >= 0xffffffff) {
81 printk("Aperture from %s beyond 4GB. Ignoring.\n",name);
84 if (e820_mapped(aper_base, aper_base + aper_size, E820_RAM)) {
85 printk("Aperture from %s pointing to e820 RAM. Ignoring.\n",name);
91 /* Find a PCI capability */
92 static __u32 __init find_cap(int num, int slot, int func, int cap)
96 if (!(read_pci_config_16(num,slot,func,PCI_STATUS) & PCI_STATUS_CAP_LIST))
98 pos = read_pci_config_byte(num,slot,func,PCI_CAPABILITY_LIST);
99 for (bytes = 0; bytes < 48 && pos >= 0x40; bytes++) {
102 id = read_pci_config_byte(num,slot,func,pos+PCI_CAP_LIST_ID);
107 pos = read_pci_config_byte(num,slot,func,pos+PCI_CAP_LIST_NEXT);
112 /* Read a standard AGPv3 bridge header */
113 static __u32 __init read_agp(int num, int slot, int func, int cap, u32 *order)
118 u32 aper_low, aper_hi;
121 printk("AGP bridge at %02x:%02x:%02x\n", num, slot, func);
122 apsizereg = read_pci_config_16(num,slot,func, cap + 0x14);
123 if (apsizereg == 0xffffffff) {
124 printk("APSIZE in AGP bridge unreadable\n");
128 apsize = apsizereg & 0xfff;
129 /* Some BIOS use weird encodings not in the AGPv3 table. */
132 nbits = hweight16(apsize);
134 if ((int)*order < 0) /* < 32MB */
137 aper_low = read_pci_config(num,slot,func, 0x10);
138 aper_hi = read_pci_config(num,slot,func,0x14);
139 aper = (aper_low & ~((1<<22)-1)) | ((u64)aper_hi << 32);
141 printk("Aperture from AGP @ %Lx size %u MB (APSIZE %x)\n",
142 aper, 32 << *order, apsizereg);
144 if (!aperture_valid("AGP bridge", aper, (32*1024*1024) << *order))
149 /* Look for an AGP bridge. Windows only expects the aperture in the
150 AGP bridge and some BIOS forget to initialize the Northbridge too.
151 Work around this here.
153 Do an PCI bus scan by hand because we're running before the PCI
156 All K8 AGP bridges are AGPv3 compliant, so we can do this scan
157 generically. It's probably overkill to always scan all slots because
158 the AGP bridges should be always an own bus on the HT hierarchy,
159 but do it here for future safety. */
160 static __u32 __init search_agp_bridge(u32 *order, int *valid_agp)
164 /* Poor man's PCI discovery */
165 for (num = 0; num < 32; num++) {
166 for (slot = 0; slot < 32; slot++) {
167 for (func = 0; func < 8; func++) {
170 class = read_pci_config(num,slot,func,
172 if (class == 0xffffffff)
175 switch (class >> 16) {
176 case PCI_CLASS_BRIDGE_HOST:
177 case PCI_CLASS_BRIDGE_OTHER: /* needed? */
179 cap = find_cap(num,slot,func,PCI_CAP_ID_AGP);
183 return read_agp(num,slot,func,cap,order);
186 /* No multi-function device? */
187 type = read_pci_config_byte(num,slot,func,
194 printk("No AGP bridge found\n");
198 void __init iommu_hole_init(void)
201 u32 aper_size, aper_alloc = 0, aper_order;
205 if (iommu_aperture_disabled)
208 printk("Checking aperture...\n");
211 for (num = 24; num < 32; num++) {
213 if (read_pci_config(0, num, 3, 0x00) != NB_ID_3)
218 aper_order = (read_pci_config(0, num, 3, 0x90) >> 1) & 7;
219 aper_size = (32 * 1024 * 1024) << aper_order;
220 aper_base = read_pci_config(0, num, 3, 0x94) & 0x7fff;
223 printk("CPU %d: aperture @ %Lx size %u MB\n", num-24,
224 aper_base, aper_size>>20);
226 sprintf(name, "northbridge cpu %d", num-24);
228 if (!aperture_valid(name, aper_base, aper_size)) {
234 if (!fix && !fallback_aper_force)
237 if (!fallback_aper_force)
238 aper_alloc = search_agp_bridge(&aper_order, &valid_agp);
241 /* Got the aperture from the AGP bridge */
242 } else if ((!no_iommu && end_pfn >= 0xffffffff>>PAGE_SHIFT) ||
245 fallback_aper_force) {
246 /* When there is a AGP bridge in the system assume the
247 user wants to use the AGP driver too and needs an
248 aperture. However this case (AGP but no good
249 aperture) should only happen with a more broken than
250 usual BIOS, because it would even break Windows. */
252 printk("Your BIOS doesn't leave a aperture memory hole\n");
253 printk("Please enable the IOMMU option in the BIOS setup\n");
254 printk("This costs you %d MB of RAM\n", 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 (read_pci_config(0, num, 3, 0x00) != NB_ID_3)
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);