[PATCH] mmconfig: Share parts of mmconfig code between i386 and x86-64
[deliverable/linux.git] / arch / i386 / pci / mmconfig-shared.c
1 /*
2 * mmconfig-shared.c - Low-level direct PCI config space access via
3 * MMCONFIG - common code between i386 and x86-64.
4 *
5 * This code does:
6 * - ACPI decoding and validation
7 *
8 * Per-architecture code takes care of the mappings and accesses
9 * themselves.
10 */
11
12 #include <linux/pci.h>
13 #include <linux/init.h>
14 #include <linux/acpi.h>
15 #include <linux/bitmap.h>
16 #include <asm/e820.h>
17
18 #include "pci.h"
19
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)
23
24 /* Verify the first 16 busses. We assume that systems with more busses
25 get MCFG right. */
26 #define PCI_MMCFG_MAX_CHECK_BUS 16
27
28 DECLARE_BITMAP(pci_mmcfg_fallback_slots, 32*PCI_MMCFG_MAX_CHECK_BUS);
29
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)
37 {
38 int i, k;
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++) {
42 u32 val1, val2;
43
44 pci_conf1_read(0, k, PCI_DEVFN(i,0), 0, 4, &val1);
45 if (val1 == 0xffffffff)
46 continue;
47
48 raw_pci_ops->read(0, k, PCI_DEVFN(i, 0), 0, 4, &val2);
49 if (val1 != 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);
53 }
54 }
55 }
56 }
57
58 void __init pci_mmcfg_init(int type)
59 {
60 if ((pci_probe & PCI_PROBE_MMCONF) == 0)
61 return;
62
63 acpi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg);
64
65 if ((pci_mmcfg_config_num == 0) ||
66 (pci_mmcfg_config == NULL) ||
67 (pci_mmcfg_config[0].address == 0))
68 return;
69
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 */
72 if (type == 1 &&
73 !e820_all_mapped(pci_mmcfg_config[0].address,
74 pci_mmcfg_config[0].address + MMCONFIG_APER_MIN,
75 E820_RESERVED)) {
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");
79 return;
80 }
81
82 if (pci_mmcfg_arch_init()) {
83 unreachable_devices();
84 pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
85 }
86 }
This page took 0.068154 seconds and 5 git commands to generate.