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 #define NB_ID_3 (PCI_VENDOR_ID_AMD | (0x1103<<16))
38 static struct resource aper_res
= {
40 .flags
= IORESOURCE_MEM
,
43 static u32 __init
allocate_aperture(void)
45 #ifdef CONFIG_DISCONTIGMEM
46 pg_data_t
*nd0
= NODE_DATA(0);
48 pg_data_t
*nd0
= &contig_page_data
;
53 if (fallback_aper_order
> 7)
54 fallback_aper_order
= 7;
55 aper_size
= (32 * 1024 * 1024) << fallback_aper_order
;
58 * Aperture has to be naturally aligned. This means an 2GB
59 * aperture won't have much chances to find a place in the
60 * lower 4GB of memory. Unfortunately we cannot move it up
61 * because that would make the IOMMU useless.
64 /* First try to find some free unused space */
65 if (!allocate_resource(&iomem_resource
, &aper_res
,
70 printk(KERN_INFO
"Putting aperture at %lx-%lx\n",
71 aper_res
.start
, aper_res
.end
);
72 return aper_res
.start
;
75 /* No free space found. Go on to waste some memory... */
76 p
= __alloc_bootmem_node(nd0
, aper_size
, aper_size
, 0);
77 if (!p
|| __pa(p
)+aper_size
> 0xffffffff) {
78 printk("Cannot allocate aperture memory hole (%p,%uK)\n",
81 free_bootmem_node(nd0
, (unsigned long)p
, aper_size
);
84 printk("Mapping aperture over %d KB of precious RAM @ %lx\n",
85 aper_size
>> 10, __pa(p
));
89 static int __init
aperture_valid(char *name
, u64 aper_base
, u32 aper_size
)
93 if (aper_size
< 64*1024*1024) {
94 printk("Aperture from %s too small (%d MB)\n", name
, aper_size
>>20);
97 if (aper_base
+ aper_size
>= 0xffffffff) {
98 printk("Aperture from %s beyond 4GB. Ignoring.\n",name
);
101 if (e820_mapped(aper_base
, aper_base
+ aper_size
, E820_RAM
)) {
102 printk("Aperture from %s pointing to e820 RAM. Ignoring.\n",name
);
105 /* Don't check the resource here because the aperture is usually
106 in an e820 reserved area, and we allocated these earlier. */
111 * Find a PCI capability.
112 * This code runs before the PCI subsystem is initialized, so just
113 * access the northbridge directly.
115 static __u32 __init
find_cap(int num
, int slot
, int func
, int cap
)
119 if (!(read_pci_config_16(num
,slot
,func
,PCI_STATUS
) & PCI_STATUS_CAP_LIST
))
121 pos
= read_pci_config_byte(num
,slot
,func
,PCI_CAPABILITY_LIST
);
122 for (bytes
= 0; bytes
< 48 && pos
>= 0x40; bytes
++) {
125 id
= read_pci_config_byte(num
,slot
,func
,pos
+PCI_CAP_LIST_ID
);
130 pos
= read_pci_config_byte(num
,slot
,func
,pos
+PCI_CAP_LIST_NEXT
);
135 /* Read a standard AGPv3 bridge header */
136 static __u32 __init
read_agp(int num
, int slot
, int func
, int cap
, u32
*order
)
141 u32 aper_low
, aper_hi
;
144 printk("AGP bridge at %02x:%02x:%02x\n", num
, slot
, func
);
145 apsizereg
= read_pci_config_16(num
,slot
,func
, cap
+ 0x14);
146 if (apsizereg
== 0xffffffff) {
147 printk("APSIZE in AGP bridge unreadable\n");
151 apsize
= apsizereg
& 0xfff;
152 /* Some BIOS use weird encodings not in the AGPv3 table. */
155 nbits
= hweight16(apsize
);
157 if ((int)*order
< 0) /* < 32MB */
160 aper_low
= read_pci_config(num
,slot
,func
, 0x10);
161 aper_hi
= read_pci_config(num
,slot
,func
,0x14);
162 aper
= (aper_low
& ~((1<<22)-1)) | ((u64
)aper_hi
<< 32);
164 printk("Aperture from AGP @ %Lx size %u MB (APSIZE %x)\n",
165 aper
, 32 << *order
, apsizereg
);
167 if (!aperture_valid("AGP bridge", aper
, (32*1024*1024) << *order
))
172 /* Look for an AGP bridge. Windows only expects the aperture in the
173 AGP bridge and some BIOS forget to initialize the Northbridge too.
174 Work around this here.
176 Do an PCI bus scan by hand because we're running before the PCI
179 All K8 AGP bridges are AGPv3 compliant, so we can do this scan
180 generically. It's probably overkill to always scan all slots because
181 the AGP bridges should be always an own bus on the HT hierarchy,
182 but do it here for future safety. */
183 static __u32 __init
search_agp_bridge(u32
*order
, int *valid_agp
)
187 /* Poor man's PCI discovery */
188 for (num
= 0; num
< 32; num
++) {
189 for (slot
= 0; slot
< 32; slot
++) {
190 for (func
= 0; func
< 8; func
++) {
193 class = read_pci_config(num
,slot
,func
,
195 if (class == 0xffffffff)
198 switch (class >> 16) {
199 case PCI_CLASS_BRIDGE_HOST
:
200 case PCI_CLASS_BRIDGE_OTHER
: /* needed? */
202 cap
= find_cap(num
,slot
,func
,PCI_CAP_ID_AGP
);
206 return read_agp(num
,slot
,func
,cap
,order
);
209 /* No multi-function device? */
210 type
= read_pci_config_byte(num
,slot
,func
,
217 printk("No AGP bridge found\n");
221 void __init
iommu_hole_init(void)
224 u32 aper_size
, aper_alloc
= 0, aper_order
, last_aper_order
= 0;
225 u64 aper_base
, last_aper_base
= 0;
228 if (iommu_aperture_disabled
|| !fix_aperture
)
231 printk("Checking aperture...\n");
234 for (num
= 24; num
< 32; num
++) {
236 if (read_pci_config(0, num
, 3, 0x00) != NB_ID_3
)
241 aper_order
= (read_pci_config(0, num
, 3, 0x90) >> 1) & 7;
242 aper_size
= (32 * 1024 * 1024) << aper_order
;
243 aper_base
= read_pci_config(0, num
, 3, 0x94) & 0x7fff;
246 printk("CPU %d: aperture @ %Lx size %u MB\n", num
-24,
247 aper_base
, aper_size
>>20);
249 sprintf(name
, "northbridge cpu %d", num
-24);
251 if (!aperture_valid(name
, aper_base
, aper_size
)) {
256 if ((last_aper_order
&& aper_order
!= last_aper_order
) ||
257 (last_aper_base
&& aper_base
!= last_aper_base
)) {
261 last_aper_order
= aper_order
;
262 last_aper_base
= aper_base
;
265 if (!fix
&& !fallback_aper_force
)
268 if (!fallback_aper_force
)
269 aper_alloc
= search_agp_bridge(&aper_order
, &valid_agp
);
272 /* Got the aperture from the AGP bridge */
273 } else if ((!no_iommu
&& end_pfn
>= 0xffffffff>>PAGE_SHIFT
) ||
276 fallback_aper_force
) {
277 printk("Your BIOS doesn't leave a aperture memory hole\n");
278 printk("Please enable the IOMMU option in the BIOS setup\n");
280 aper_order
= fallback_aper_order
;
281 aper_alloc
= allocate_aperture();
283 /* Could disable AGP and IOMMU here, but it's probably
284 not worth it. But the later users cannot deal with
285 bad apertures and turning on the aperture over memory
286 causes very strange problems, so it's better to
288 panic("Not enough memory for aperture");
294 /* Fix up the north bridges */
295 for (num
= 24; num
< 32; num
++) {
296 if (read_pci_config(0, num
, 3, 0x00) != NB_ID_3
)
299 /* Don't enable translation yet. That is done later.
300 Assume this BIOS didn't initialise the GART so
301 just overwrite all previous bits */
302 write_pci_config(0, num
, 3, 0x90, aper_order
<<1);
303 write_pci_config(0, num
, 3, 0x94, aper_alloc
>>25);