[PATCH] mmconfig: Reserve resources but only when we're sure about them.
[powerpc.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  * - known chipset handling
7  * - ACPI decoding and validation
8  *
9  * Per-architecture code takes care of the mappings and accesses
10  * themselves.
11  */
12
13 #include <linux/pci.h>
14 #include <linux/init.h>
15 #include <linux/acpi.h>
16 #include <linux/bitmap.h>
17 #include <asm/e820.h>
18
19 #include "pci.h"
20
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)
24
25 /* Verify the first 16 busses. We assume that systems with more busses
26    get MCFG right. */
27 #define PCI_MMCFG_MAX_CHECK_BUS 16
28
29 DECLARE_BITMAP(pci_mmcfg_fallback_slots, 32*PCI_MMCFG_MAX_CHECK_BUS);
30
31 /* K8 systems have some devices (typically in the builtin northbridge)
32    that are only accessible using type1
33    Normally this can be expressed in the MCFG by not listing them
34    and assigning suitable _SEGs, but this isn't implemented in some BIOS.
35    Instead try to discover all devices on bus 0 that are unreachable using MM
36    and fallback for them. */
37 static __init void unreachable_devices(void)
38 {
39         int i, k;
40         /* Use the max bus number from ACPI here? */
41         for (k = 0; k < PCI_MMCFG_MAX_CHECK_BUS; k++) {
42                 for (i = 0; i < 32; i++) {
43                         u32 val1, val2;
44
45                         pci_conf1_read(0, k, PCI_DEVFN(i,0), 0, 4, &val1);
46                         if (val1 == 0xffffffff)
47                                 continue;
48
49                         raw_pci_ops->read(0, k, PCI_DEVFN(i, 0), 0, 4, &val2);
50                         if (val1 != val2) {
51                                 set_bit(i + 32*k, pci_mmcfg_fallback_slots);
52                                 printk(KERN_NOTICE "PCI: No mmconfig possible"
53                                        " on device %02x:%02x\n", k, i);
54                         }
55                 }
56         }
57 }
58
59 static __init const char *pci_mmcfg_e7520(void)
60 {
61         u32 win;
62         pci_conf1_read(0, 0, PCI_DEVFN(0,0), 0xce, 2, &win);
63
64         pci_mmcfg_config_num = 1;
65         pci_mmcfg_config = kzalloc(sizeof(pci_mmcfg_config[0]), GFP_KERNEL);
66         if (!pci_mmcfg_config)
67                 return NULL;
68         pci_mmcfg_config[0].address = (win & 0xf000) << 16;
69         pci_mmcfg_config[0].pci_segment = 0;
70         pci_mmcfg_config[0].start_bus_number = 0;
71         pci_mmcfg_config[0].end_bus_number = 255;
72
73         return "Intel Corporation E7520 Memory Controller Hub";
74 }
75
76 static __init const char *pci_mmcfg_intel_945(void)
77 {
78         u32 pciexbar, mask = 0, len = 0;
79
80         pci_mmcfg_config_num = 1;
81
82         pci_conf1_read(0, 0, PCI_DEVFN(0,0), 0x48, 4, &pciexbar);
83
84         /* Enable bit */
85         if (!(pciexbar & 1))
86                 pci_mmcfg_config_num = 0;
87
88         /* Size bits */
89         switch ((pciexbar >> 1) & 3) {
90         case 0:
91                 mask = 0xf0000000U;
92                 len  = 0x10000000U;
93                 break;
94         case 1:
95                 mask = 0xf8000000U;
96                 len  = 0x08000000U;
97                 break;
98         case 2:
99                 mask = 0xfc000000U;
100                 len  = 0x04000000U;
101                 break;
102         default:
103                 pci_mmcfg_config_num = 0;
104         }
105
106         /* Errata #2, things break when not aligned on a 256Mb boundary */
107         /* Can only happen in 64M/128M mode */
108
109         if ((pciexbar & mask) & 0x0fffffffU)
110                 pci_mmcfg_config_num = 0;
111
112         if (pci_mmcfg_config_num) {
113                 pci_mmcfg_config = kzalloc(sizeof(pci_mmcfg_config[0]), GFP_KERNEL);
114                 if (!pci_mmcfg_config)
115                         return NULL;
116                 pci_mmcfg_config[0].address = pciexbar & mask;
117                 pci_mmcfg_config[0].pci_segment = 0;
118                 pci_mmcfg_config[0].start_bus_number = 0;
119                 pci_mmcfg_config[0].end_bus_number = (len >> 20) - 1;
120         }
121
122         return "Intel Corporation 945G/GZ/P/PL Express Memory Controller Hub";
123 }
124
125 struct pci_mmcfg_hostbridge_probe {
126         u32 vendor;
127         u32 device;
128         const char *(*probe)(void);
129 };
130
131 static __initdata struct pci_mmcfg_hostbridge_probe pci_mmcfg_probes[] = {
132         { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH, pci_mmcfg_e7520 },
133         { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82945G_HB, pci_mmcfg_intel_945 },
134 };
135
136 static int __init pci_mmcfg_check_hostbridge(void)
137 {
138         u32 l;
139         u16 vendor, device;
140         int i;
141         const char *name;
142
143         pci_conf1_read(0, 0, PCI_DEVFN(0,0), 0, 4, &l);
144         vendor = l & 0xffff;
145         device = (l >> 16) & 0xffff;
146
147         pci_mmcfg_config_num = 0;
148         pci_mmcfg_config = NULL;
149         name = NULL;
150
151         for (i = 0; !name && i < ARRAY_SIZE(pci_mmcfg_probes); i++)
152                 if ((pci_mmcfg_probes[i].vendor == PCI_ANY_ID ||
153                      pci_mmcfg_probes[i].vendor == vendor) &&
154                     (pci_mmcfg_probes[i].device == PCI_ANY_ID ||
155                      pci_mmcfg_probes[i].device == device))
156                         name = pci_mmcfg_probes[i].probe();
157
158         if (name) {
159                 if (pci_mmcfg_config_num)
160                         printk(KERN_INFO "PCI: Found %s with MMCONFIG support.\n", name);
161                 else
162                         printk(KERN_INFO "PCI: Found %s without MMCONFIG support.\n",
163                                name);
164         }
165
166         return name != NULL;
167 }
168
169 static __init void pci_mmcfg_insert_resources(void)
170 {
171 #define PCI_MMCFG_RESOURCE_NAME_LEN 19
172         int i;
173         struct resource *res;
174         char *names;
175         unsigned num_buses;
176
177         res = kcalloc(PCI_MMCFG_RESOURCE_NAME_LEN + sizeof(*res),
178                         pci_mmcfg_config_num, GFP_KERNEL);
179
180         if (!res) {
181                 printk(KERN_ERR "PCI: Unable to allocate MMCONFIG resources\n");
182                 return;
183         }
184
185         names = (void *)&res[pci_mmcfg_config_num];
186         for (i = 0; i < pci_mmcfg_config_num; i++, res++) {
187                 num_buses = pci_mmcfg_config[i].end_bus_number -
188                     pci_mmcfg_config[i].start_bus_number + 1;
189                 res->name = names;
190                 snprintf(names, PCI_MMCFG_RESOURCE_NAME_LEN, "PCI MMCONFIG %u",
191                         pci_mmcfg_config[i].pci_segment);
192                 res->start = pci_mmcfg_config[i].address;
193                 res->end = res->start + (num_buses << 20) - 1;
194                 res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
195                 insert_resource(&iomem_resource, res);
196                 names += PCI_MMCFG_RESOURCE_NAME_LEN;
197         }
198 }
199
200 void __init pci_mmcfg_init(int type)
201 {
202         int known_bridge = 0;
203
204         if ((pci_probe & PCI_PROBE_MMCONF) == 0)
205                 return;
206
207         if (type == 1 && pci_mmcfg_check_hostbridge())
208                 known_bridge = 1;
209
210         if (!known_bridge)
211                 acpi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg);
212
213         if ((pci_mmcfg_config_num == 0) ||
214             (pci_mmcfg_config == NULL) ||
215             (pci_mmcfg_config[0].address == 0))
216                 return;
217
218         /* Only do this check when type 1 works. If it doesn't work
219            assume we run on a Mac and always use MCFG */
220         if (type == 1 && !known_bridge &&
221             !e820_all_mapped(pci_mmcfg_config[0].address,
222                              pci_mmcfg_config[0].address + MMCONFIG_APER_MIN,
223                              E820_RESERVED)) {
224                 printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %Lx is not E820-reserved\n",
225                                 pci_mmcfg_config[0].address);
226                 printk(KERN_ERR "PCI: Not using MMCONFIG.\n");
227                 return;
228         }
229
230         if (pci_mmcfg_arch_init()) {
231                 if (type == 1)
232                         unreachable_devices();
233                 if (known_bridge)
234                         pci_mmcfg_insert_resources();
235                 pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
236         }
237 }