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>
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 /* This code runs before the PCI subsystem is initialized, so just
38 access the northbridge directly. */
40 #define NB_ID_3 (PCI_VENDOR_ID_AMD | (0x1103<<16))
42 static u32 __init
allocate_aperture(void)
44 pg_data_t
*nd0
= NODE_DATA(0);
48 if (fallback_aper_order
> 7)
49 fallback_aper_order
= 7;
50 aper_size
= (32 * 1024 * 1024) << fallback_aper_order
;
53 * Aperture has to be naturally aligned. This means an 2GB aperture won't
54 * have much chances to find a place in the lower 4GB of memory.
55 * Unfortunately we cannot move it up because that would make the
58 p
= __alloc_bootmem_node(nd0
, aper_size
, aper_size
, 0);
59 if (!p
|| __pa(p
)+aper_size
> 0xffffffff) {
60 printk("Cannot allocate aperture memory hole (%p,%uK)\n",
63 free_bootmem_node(nd0
, (unsigned long)p
, aper_size
);
66 printk("Mapping aperture over %d KB of RAM @ %lx\n",
67 aper_size
>> 10, __pa(p
));
71 static int __init
aperture_valid(char *name
, u64 aper_base
, u32 aper_size
)
75 if (aper_size
< 64*1024*1024) {
76 printk("Aperture from %s too small (%d MB)\n", name
, aper_size
>>20);
79 if (aper_base
+ aper_size
>= 0xffffffff) {
80 printk("Aperture from %s beyond 4GB. Ignoring.\n",name
);
83 if (e820_mapped(aper_base
, aper_base
+ aper_size
, E820_RAM
)) {
84 printk("Aperture from %s pointing to e820 RAM. Ignoring.\n",name
);
90 /* Find a PCI capability */
91 static __u32 __init
find_cap(int num
, int slot
, int func
, int cap
)
95 if (!(read_pci_config_16(num
,slot
,func
,PCI_STATUS
) & PCI_STATUS_CAP_LIST
))
97 pos
= read_pci_config_byte(num
,slot
,func
,PCI_CAPABILITY_LIST
);
98 for (bytes
= 0; bytes
< 48 && pos
>= 0x40; bytes
++) {
101 id
= read_pci_config_byte(num
,slot
,func
,pos
+PCI_CAP_LIST_ID
);
106 pos
= read_pci_config_byte(num
,slot
,func
,pos
+PCI_CAP_LIST_NEXT
);
111 /* Read a standard AGPv3 bridge header */
112 static __u32 __init
read_agp(int num
, int slot
, int func
, int cap
, u32
*order
)
117 u32 aper_low
, aper_hi
;
120 printk("AGP bridge at %02x:%02x:%02x\n", num
, slot
, func
);
121 apsizereg
= read_pci_config_16(num
,slot
,func
, cap
+ 0x14);
122 if (apsizereg
== 0xffffffff) {
123 printk("APSIZE in AGP bridge unreadable\n");
127 apsize
= apsizereg
& 0xfff;
128 /* Some BIOS use weird encodings not in the AGPv3 table. */
131 nbits
= hweight16(apsize
);
133 if ((int)*order
< 0) /* < 32MB */
136 aper_low
= read_pci_config(num
,slot
,func
, 0x10);
137 aper_hi
= read_pci_config(num
,slot
,func
,0x14);
138 aper
= (aper_low
& ~((1<<22)-1)) | ((u64
)aper_hi
<< 32);
140 printk("Aperture from AGP @ %Lx size %u MB (APSIZE %x)\n",
141 aper
, 32 << *order
, apsizereg
);
143 if (!aperture_valid("AGP bridge", aper
, (32*1024*1024) << *order
))
148 /* Look for an AGP bridge. Windows only expects the aperture in the
149 AGP bridge and some BIOS forget to initialize the Northbridge too.
150 Work around this here.
152 Do an PCI bus scan by hand because we're running before the PCI
155 All K8 AGP bridges are AGPv3 compliant, so we can do this scan
156 generically. It's probably overkill to always scan all slots because
157 the AGP bridges should be always an own bus on the HT hierarchy,
158 but do it here for future safety. */
159 static __u32 __init
search_agp_bridge(u32
*order
, int *valid_agp
)
163 /* Poor man's PCI discovery */
164 for (num
= 0; num
< 32; num
++) {
165 for (slot
= 0; slot
< 32; slot
++) {
166 for (func
= 0; func
< 8; func
++) {
169 class = read_pci_config(num
,slot
,func
,
171 if (class == 0xffffffff)
174 switch (class >> 16) {
175 case PCI_CLASS_BRIDGE_HOST
:
176 case PCI_CLASS_BRIDGE_OTHER
: /* needed? */
178 cap
= find_cap(num
,slot
,func
,PCI_CAP_ID_AGP
);
182 return read_agp(num
,slot
,func
,cap
,order
);
185 /* No multi-function device? */
186 type
= read_pci_config_byte(num
,slot
,func
,
193 printk("No AGP bridge found\n");
197 void __init
iommu_hole_init(void)
200 u32 aper_size
, aper_alloc
= 0, aper_order
= 0, last_aper_order
= 0;
201 u64 aper_base
, last_aper_base
= 0;
204 if (iommu_aperture_disabled
|| !fix_aperture
)
207 printk("Checking aperture...\n");
210 for (num
= 24; num
< 32; num
++) {
212 if (read_pci_config(0, num
, 3, 0x00) != NB_ID_3
)
217 aper_order
= (read_pci_config(0, num
, 3, 0x90) >> 1) & 7;
218 aper_size
= (32 * 1024 * 1024) << aper_order
;
219 aper_base
= read_pci_config(0, num
, 3, 0x94) & 0x7fff;
222 printk("CPU %d: aperture @ %Lx size %u MB\n", num
-24,
223 aper_base
, aper_size
>>20);
225 sprintf(name
, "northbridge cpu %d", num
-24);
227 if (!aperture_valid(name
, aper_base
, aper_size
)) {
232 if ((last_aper_order
&& aper_order
!= last_aper_order
) ||
233 (last_aper_base
&& aper_base
!= last_aper_base
)) {
237 last_aper_order
= aper_order
;
238 last_aper_base
= aper_base
;
241 if (!fix
&& !fallback_aper_force
)
244 if (!fallback_aper_force
)
245 aper_alloc
= search_agp_bridge(&aper_order
, &valid_agp
);
248 /* Got the aperture from the AGP bridge */
249 } else if (swiotlb
&& !valid_agp
) {
251 } else if ((!no_iommu
&& end_pfn
>= MAX_DMA32_PFN
) ||
254 fallback_aper_force
) {
255 printk("Your BIOS doesn't leave a aperture memory hole\n");
256 printk("Please enable the IOMMU option in the BIOS setup\n");
257 printk("This costs you %d MB of RAM\n",
258 32 << fallback_aper_order
);
260 aper_order
= fallback_aper_order
;
261 aper_alloc
= allocate_aperture();
263 /* Could disable AGP and IOMMU here, but it's probably
264 not worth it. But the later users cannot deal with
265 bad apertures and turning on the aperture over memory
266 causes very strange problems, so it's better to
268 panic("Not enough memory for aperture");
274 /* Fix up the north bridges */
275 for (num
= 24; num
< 32; num
++) {
276 if (read_pci_config(0, num
, 3, 0x00) != NB_ID_3
)
279 /* Don't enable translation yet. That is done later.
280 Assume this BIOS didn't initialise the GART so
281 just overwrite all previous bits */
282 write_pci_config(0, num
, 3, 0x90, aper_order
<<1);
283 write_pci_config(0, num
, 3, 0x94, aper_alloc
>>25);