2 * mmconfig-shared.c - Low-level direct PCI config space access via
3 * MMCONFIG - common code between i386 and x86-64.
6 * - ACPI decoding and validation
8 * Per-architecture code takes care of the mappings and accesses
12 #include <linux/pci.h>
13 #include <linux/init.h>
14 #include <linux/acpi.h>
15 #include <linux/bitmap.h>
20 /* aperture is up to 256MB but BIOS may reserve less */
21 #define MMCONFIG_APER_MIN (2 * 1024*1024)
22 #define MMCONFIG_APER_MAX (256 * 1024*1024)
24 /* Verify the first 16 busses. We assume that systems with more busses
26 #define PCI_MMCFG_MAX_CHECK_BUS 16
28 DECLARE_BITMAP(pci_mmcfg_fallback_slots, 32*PCI_MMCFG_MAX_CHECK_BUS);
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 __init void unreachable_devices(void)
39 /* Use the max bus number from ACPI here? */
40 for (k = 0; k < PCI_MMCFG_MAX_CHECK_BUS; k++) {
41 for (i = 0; i < 32; i++) {
44 pci_conf1_read(0, k, PCI_DEVFN(i,0), 0, 4, &val1);
45 if (val1 == 0xffffffff)
48 raw_pci_ops->read(0, k, PCI_DEVFN(i, 0), 0, 4, &val2);
50 set_bit(i + 32*k, pci_mmcfg_fallback_slots);
51 printk(KERN_NOTICE "PCI: No mmconfig possible"
52 " on device %02x:%02x\n", k, i);
58 void __init pci_mmcfg_init(int type)
60 if ((pci_probe & PCI_PROBE_MMCONF) == 0)
63 acpi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg);
65 if ((pci_mmcfg_config_num == 0) ||
66 (pci_mmcfg_config == NULL) ||
67 (pci_mmcfg_config[0].address == 0))
70 /* Only do this check when type 1 works. If it doesn't work
71 assume we run on a Mac and always use MCFG */
73 !e820_all_mapped(pci_mmcfg_config[0].address,
74 pci_mmcfg_config[0].address + MMCONFIG_APER_MIN,
76 printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %Lx is not E820-reserved\n",
77 pci_mmcfg_config[0].address);
78 printk(KERN_ERR "PCI: Not using MMCONFIG.\n");
82 if (pci_mmcfg_arch_init()) {
83 unreachable_devices();
84 pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;