2 * mmconfig-shared.c - Low-level direct PCI config space access via
3 * MMCONFIG - common code between i386 and x86-64.
6 * - known chipset handling
7 * - ACPI decoding and validation
9 * Per-architecture code takes care of the mappings and accesses
13 #include <linux/pci.h>
14 #include <linux/init.h>
15 #include <linux/acpi.h>
16 #include <linux/bitmap.h>
21 /* aperture is up to 256MB but BIOS may reserve less */
22 #define MMCONFIG_APER_MIN (2 * 1024*1024)
23 #define MMCONFIG_APER_MAX (256 * 1024*1024)
25 DECLARE_BITMAP(pci_mmcfg_fallback_slots
, 32*PCI_MMCFG_MAX_CHECK_BUS
);
27 /* K8 systems have some devices (typically in the builtin northbridge)
28 that are only accessible using type1
29 Normally this can be expressed in the MCFG by not listing them
30 and assigning suitable _SEGs, but this isn't implemented in some BIOS.
31 Instead try to discover all devices on bus 0 that are unreachable using MM
32 and fallback for them. */
33 static void __init
unreachable_devices(void)
36 /* Use the max bus number from ACPI here? */
37 for (bus
= 0; bus
< PCI_MMCFG_MAX_CHECK_BUS
; bus
++) {
38 for (i
= 0; i
< 32; i
++) {
39 unsigned int devfn
= PCI_DEVFN(i
, 0);
42 pci_conf1_read(0, bus
, devfn
, 0, 4, &val1
);
43 if (val1
== 0xffffffff)
46 if (pci_mmcfg_arch_reachable(0, bus
, devfn
)) {
47 raw_pci_ops
->read(0, bus
, devfn
, 0, 4, &val2
);
51 set_bit(i
+ 32 * bus
, pci_mmcfg_fallback_slots
);
52 printk(KERN_NOTICE
"PCI: No mmconfig possible on device"
53 " %02x:%02x\n", bus
, i
);
58 static const char __init
*pci_mmcfg_e7520(void)
61 pci_conf1_read(0, 0, PCI_DEVFN(0,0), 0xce, 2, &win
);
63 pci_mmcfg_config_num
= 1;
64 pci_mmcfg_config
= kzalloc(sizeof(pci_mmcfg_config
[0]), GFP_KERNEL
);
65 if (!pci_mmcfg_config
)
67 pci_mmcfg_config
[0].address
= (win
& 0xf000) << 16;
68 pci_mmcfg_config
[0].pci_segment
= 0;
69 pci_mmcfg_config
[0].start_bus_number
= 0;
70 pci_mmcfg_config
[0].end_bus_number
= 255;
72 return "Intel Corporation E7520 Memory Controller Hub";
75 static const char __init
*pci_mmcfg_intel_945(void)
77 u32 pciexbar
, mask
= 0, len
= 0;
79 pci_mmcfg_config_num
= 1;
81 pci_conf1_read(0, 0, PCI_DEVFN(0,0), 0x48, 4, &pciexbar
);
85 pci_mmcfg_config_num
= 0;
88 switch ((pciexbar
>> 1) & 3) {
102 pci_mmcfg_config_num
= 0;
105 /* Errata #2, things break when not aligned on a 256Mb boundary */
106 /* Can only happen in 64M/128M mode */
108 if ((pciexbar
& mask
) & 0x0fffffffU
)
109 pci_mmcfg_config_num
= 0;
111 if (pci_mmcfg_config_num
) {
112 pci_mmcfg_config
= kzalloc(sizeof(pci_mmcfg_config
[0]), GFP_KERNEL
);
113 if (!pci_mmcfg_config
)
115 pci_mmcfg_config
[0].address
= pciexbar
& mask
;
116 pci_mmcfg_config
[0].pci_segment
= 0;
117 pci_mmcfg_config
[0].start_bus_number
= 0;
118 pci_mmcfg_config
[0].end_bus_number
= (len
>> 20) - 1;
121 return "Intel Corporation 945G/GZ/P/PL Express Memory Controller Hub";
124 struct pci_mmcfg_hostbridge_probe
{
127 const char *(*probe
)(void);
130 static struct pci_mmcfg_hostbridge_probe pci_mmcfg_probes
[] __initdata
= {
131 { PCI_VENDOR_ID_INTEL
, PCI_DEVICE_ID_INTEL_E7520_MCH
, pci_mmcfg_e7520
},
132 { PCI_VENDOR_ID_INTEL
, PCI_DEVICE_ID_INTEL_82945G_HB
, pci_mmcfg_intel_945
},
135 static int __init
pci_mmcfg_check_hostbridge(void)
142 pci_conf1_read(0, 0, PCI_DEVFN(0,0), 0, 4, &l
);
144 device
= (l
>> 16) & 0xffff;
146 pci_mmcfg_config_num
= 0;
147 pci_mmcfg_config
= NULL
;
150 for (i
= 0; !name
&& i
< ARRAY_SIZE(pci_mmcfg_probes
); i
++) {
151 if (pci_mmcfg_probes
[i
].vendor
== vendor
&&
152 pci_mmcfg_probes
[i
].device
== device
)
153 name
= pci_mmcfg_probes
[i
].probe();
157 printk(KERN_INFO
"PCI: Found %s %s MMCONFIG support.\n",
158 name
, pci_mmcfg_config_num
? "with" : "without");
164 static void __init
pci_mmcfg_insert_resources(void)
166 #define PCI_MMCFG_RESOURCE_NAME_LEN 19
168 struct resource
*res
;
172 res
= kcalloc(PCI_MMCFG_RESOURCE_NAME_LEN
+ sizeof(*res
),
173 pci_mmcfg_config_num
, GFP_KERNEL
);
175 printk(KERN_ERR
"PCI: Unable to allocate MMCONFIG resources\n");
179 names
= (void *)&res
[pci_mmcfg_config_num
];
180 for (i
= 0; i
< pci_mmcfg_config_num
; i
++, res
++) {
181 struct acpi_mcfg_allocation
*cfg
= &pci_mmcfg_config
[i
];
182 num_buses
= cfg
->end_bus_number
- cfg
->start_bus_number
+ 1;
184 snprintf(names
, PCI_MMCFG_RESOURCE_NAME_LEN
, "PCI MMCONFIG %u",
186 res
->start
= cfg
->address
;
187 res
->end
= res
->start
+ (num_buses
<< 20) - 1;
188 res
->flags
= IORESOURCE_MEM
| IORESOURCE_BUSY
;
189 insert_resource(&iomem_resource
, res
);
190 names
+= PCI_MMCFG_RESOURCE_NAME_LEN
;
194 static void __init
pci_mmcfg_reject_broken(void)
196 typeof(pci_mmcfg_config
[0]) *cfg
= &pci_mmcfg_config
[0];
199 * Handle more broken MCFG tables on Asus etc.
200 * They only contain a single entry for bus 0-0.
202 if (pci_mmcfg_config_num
== 1 &&
203 cfg
->pci_segment
== 0 &&
204 (cfg
->start_bus_number
| cfg
->end_bus_number
) == 0) {
205 kfree(pci_mmcfg_config
);
206 pci_mmcfg_config
= NULL
;
207 pci_mmcfg_config_num
= 0;
209 printk(KERN_ERR
"PCI: start and end of bus number is 0. "
210 "Rejected as broken MCFG.");
214 void __init
pci_mmcfg_init(int type
)
216 int known_bridge
= 0;
218 if ((pci_probe
& PCI_PROBE_MMCONF
) == 0)
221 if (type
== 1 && pci_mmcfg_check_hostbridge())
225 acpi_table_parse(ACPI_SIG_MCFG
, acpi_parse_mcfg
);
226 pci_mmcfg_reject_broken();
229 if ((pci_mmcfg_config_num
== 0) ||
230 (pci_mmcfg_config
== NULL
) ||
231 (pci_mmcfg_config
[0].address
== 0))
234 /* Only do this check when type 1 works. If it doesn't work
235 assume we run on a Mac and always use MCFG */
236 if (type
== 1 && !known_bridge
&&
237 !e820_all_mapped(pci_mmcfg_config
[0].address
,
238 pci_mmcfg_config
[0].address
+ MMCONFIG_APER_MIN
,
240 printk(KERN_ERR
"PCI: BIOS Bug: MCFG area at %Lx is not E820-reserved\n",
241 pci_mmcfg_config
[0].address
);
242 printk(KERN_ERR
"PCI: Not using MMCONFIG.\n");
246 if (pci_mmcfg_arch_init()) {
248 unreachable_devices();
250 pci_mmcfg_insert_resources();
251 pci_probe
= (pci_probe
& ~PCI_PROBE_MASK
) | PCI_PROBE_MMCONF
;