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 /* Indicate if the mmcfg resources have been placed into the resource table. */
28 static int __initdata pci_mmcfg_resources_inserted;
30 /* K8 systems have some devices (typically in the builtin northbridge)
31 that are only accessible using type1
32 Normally this can be expressed in the MCFG by not listing them
33 and assigning suitable _SEGs, but this isn't implemented in some BIOS.
34 Instead try to discover all devices on bus 0 that are unreachable using MM
35 and fallback for them. */
36 static void __init unreachable_devices(void)
39 /* Use the max bus number from ACPI here? */
40 for (bus = 0; bus < PCI_MMCFG_MAX_CHECK_BUS; bus++) {
41 for (i = 0; i < 32; i++) {
42 unsigned int devfn = PCI_DEVFN(i, 0);
45 pci_conf1_read(0, bus, devfn, 0, 4, &val1);
46 if (val1 == 0xffffffff)
49 if (pci_mmcfg_arch_reachable(0, bus, devfn)) {
50 raw_pci_ops->read(0, bus, devfn, 0, 4, &val2);
54 set_bit(i + 32 * bus, pci_mmcfg_fallback_slots);
55 printk(KERN_NOTICE "PCI: No mmconfig possible on device"
56 " %02x:%02x\n", bus, i);
61 static const char __init *pci_mmcfg_e7520(void)
64 pci_conf1_read(0, 0, PCI_DEVFN(0,0), 0xce, 2, &win);
67 if(win == 0x0000 || win == 0xf000)
68 pci_mmcfg_config_num = 0;
70 pci_mmcfg_config_num = 1;
71 pci_mmcfg_config = kzalloc(sizeof(pci_mmcfg_config[0]), GFP_KERNEL);
72 if (!pci_mmcfg_config)
74 pci_mmcfg_config[0].address = win << 16;
75 pci_mmcfg_config[0].pci_segment = 0;
76 pci_mmcfg_config[0].start_bus_number = 0;
77 pci_mmcfg_config[0].end_bus_number = 255;
80 return "Intel Corporation E7520 Memory Controller Hub";
83 static const char __init *pci_mmcfg_intel_945(void)
85 u32 pciexbar, mask = 0, len = 0;
87 pci_mmcfg_config_num = 1;
89 pci_conf1_read(0, 0, PCI_DEVFN(0,0), 0x48, 4, &pciexbar);
93 pci_mmcfg_config_num = 0;
96 switch ((pciexbar >> 1) & 3) {
110 pci_mmcfg_config_num = 0;
113 /* Errata #2, things break when not aligned on a 256Mb boundary */
114 /* Can only happen in 64M/128M mode */
116 if ((pciexbar & mask) & 0x0fffffffU)
117 pci_mmcfg_config_num = 0;
119 /* Don't hit the APIC registers and their friends */
120 if ((pciexbar & mask) >= 0xf0000000U)
121 pci_mmcfg_config_num = 0;
123 if (pci_mmcfg_config_num) {
124 pci_mmcfg_config = kzalloc(sizeof(pci_mmcfg_config[0]), GFP_KERNEL);
125 if (!pci_mmcfg_config)
127 pci_mmcfg_config[0].address = pciexbar & mask;
128 pci_mmcfg_config[0].pci_segment = 0;
129 pci_mmcfg_config[0].start_bus_number = 0;
130 pci_mmcfg_config[0].end_bus_number = (len >> 20) - 1;
133 return "Intel Corporation 945G/GZ/P/PL Express Memory Controller Hub";
136 struct pci_mmcfg_hostbridge_probe {
139 const char *(*probe)(void);
142 static struct pci_mmcfg_hostbridge_probe pci_mmcfg_probes[] __initdata = {
143 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH, pci_mmcfg_e7520 },
144 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82945G_HB, pci_mmcfg_intel_945 },
147 static int __init pci_mmcfg_check_hostbridge(void)
154 pci_conf1_read(0, 0, PCI_DEVFN(0,0), 0, 4, &l);
156 device = (l >> 16) & 0xffff;
158 pci_mmcfg_config_num = 0;
159 pci_mmcfg_config = NULL;
162 for (i = 0; !name && i < ARRAY_SIZE(pci_mmcfg_probes); i++) {
163 if (pci_mmcfg_probes[i].vendor == vendor &&
164 pci_mmcfg_probes[i].device == device)
165 name = pci_mmcfg_probes[i].probe();
169 printk(KERN_INFO "PCI: Found %s %s MMCONFIG support.\n",
170 name, pci_mmcfg_config_num ? "with" : "without");
176 static void __init pci_mmcfg_insert_resources(unsigned long resource_flags)
178 #define PCI_MMCFG_RESOURCE_NAME_LEN 19
180 struct resource *res;
184 res = kcalloc(PCI_MMCFG_RESOURCE_NAME_LEN + sizeof(*res),
185 pci_mmcfg_config_num, GFP_KERNEL);
187 printk(KERN_ERR "PCI: Unable to allocate MMCONFIG resources\n");
191 names = (void *)&res[pci_mmcfg_config_num];
192 for (i = 0; i < pci_mmcfg_config_num; i++, res++) {
193 struct acpi_mcfg_allocation *cfg = &pci_mmcfg_config[i];
194 num_buses = cfg->end_bus_number - cfg->start_bus_number + 1;
196 snprintf(names, PCI_MMCFG_RESOURCE_NAME_LEN, "PCI MMCONFIG %u",
198 res->start = cfg->address;
199 res->end = res->start + (num_buses << 20) - 1;
200 res->flags = IORESOURCE_MEM | resource_flags;
201 insert_resource(&iomem_resource, res);
202 names += PCI_MMCFG_RESOURCE_NAME_LEN;
205 /* Mark that the resources have been inserted. */
206 pci_mmcfg_resources_inserted = 1;
209 static void __init pci_mmcfg_reject_broken(int type)
211 typeof(pci_mmcfg_config[0]) *cfg;
213 if ((pci_mmcfg_config_num == 0) ||
214 (pci_mmcfg_config == NULL) ||
215 (pci_mmcfg_config[0].address == 0))
218 cfg = &pci_mmcfg_config[0];
221 * Handle more broken MCFG tables on Asus etc.
222 * They only contain a single entry for bus 0-0.
224 if (pci_mmcfg_config_num == 1 &&
225 cfg->pci_segment == 0 &&
226 (cfg->start_bus_number | cfg->end_bus_number) == 0) {
227 printk(KERN_ERR "PCI: start and end of bus number is 0. "
228 "Rejected as broken MCFG.\n");
233 * Only do this check when type 1 works. If it doesn't work
234 * assume we run on a Mac and always use MCFG
236 if (type == 1 && !e820_all_mapped(cfg->address,
237 cfg->address + MMCONFIG_APER_MIN,
239 printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %Lx is not"
240 " E820-reserved\n", cfg->address);
246 printk(KERN_ERR "PCI: Not using MMCONFIG.\n");
247 kfree(pci_mmcfg_config);
248 pci_mmcfg_config = NULL;
249 pci_mmcfg_config_num = 0;
252 void __init pci_mmcfg_init(int type)
254 int known_bridge = 0;
256 if ((pci_probe & PCI_PROBE_MMCONF) == 0)
259 if (type == 1 && pci_mmcfg_check_hostbridge())
263 acpi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg);
264 pci_mmcfg_reject_broken(type);
267 if ((pci_mmcfg_config_num == 0) ||
268 (pci_mmcfg_config == NULL) ||
269 (pci_mmcfg_config[0].address == 0))
272 if (pci_mmcfg_arch_init()) {
274 unreachable_devices();
276 pci_mmcfg_insert_resources(IORESOURCE_BUSY);
277 pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
280 * Signal not to attempt to insert mmcfg resources because
281 * the architecture mmcfg setup could not initialize.
283 pci_mmcfg_resources_inserted = 1;
287 static int __init pci_mmcfg_late_insert_resources(void)
290 * If resources are already inserted or we are not using MMCONFIG,
291 * don't insert the resources.
293 if ((pci_mmcfg_resources_inserted == 1) ||
294 (pci_probe & PCI_PROBE_MMCONF) == 0 ||
295 (pci_mmcfg_config_num == 0) ||
296 (pci_mmcfg_config == NULL) ||
297 (pci_mmcfg_config[0].address == 0))
301 * Attempt to insert the mmcfg resources but not with the busy flag
302 * marked so it won't cause request errors when __request_region is
305 pci_mmcfg_insert_resources(0);
311 * Perform MMCONFIG resource insertion after PCI initialization to allow for
312 * misprogrammed MCFG tables that state larger sizes but actually conflict
313 * with other system resources.
315 late_initcall(pci_mmcfg_late_insert_resources);