eepro100 annotations
[linux-2.6/openmoko-kernel/knife-kernel.git] / arch / x86 / pci / mmconfig-shared.c
blob4df637e34f813da1e47839c75d9cd3fc502bc560
1 /*
2 * mmconfig-shared.c - Low-level direct PCI config space access via
3 * MMCONFIG - common code between i386 and x86-64.
5 * This code does:
6 * - known chipset handling
7 * - ACPI decoding and validation
9 * Per-architecture code takes care of the mappings and accesses
10 * themselves.
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>
19 #include "pci.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)
38 int i, bus;
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);
43 u32 val1, val2;
45 pci_conf1_read(0, bus, devfn, 0, 4, &val1);
46 if (val1 == 0xffffffff)
47 continue;
49 if (pci_mmcfg_arch_reachable(0, bus, devfn)) {
50 raw_pci_ops->read(0, bus, devfn, 0, 4, &val2);
51 if (val1 == val2)
52 continue;
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)
63 u32 win;
64 pci_conf1_read(0, 0, PCI_DEVFN(0,0), 0xce, 2, &win);
66 win = win & 0xf000;
67 if(win == 0x0000 || win == 0xf000)
68 pci_mmcfg_config_num = 0;
69 else {
70 pci_mmcfg_config_num = 1;
71 pci_mmcfg_config = kzalloc(sizeof(pci_mmcfg_config[0]), GFP_KERNEL);
72 if (!pci_mmcfg_config)
73 return NULL;
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);
91 /* Enable bit */
92 if (!(pciexbar & 1))
93 pci_mmcfg_config_num = 0;
95 /* Size bits */
96 switch ((pciexbar >> 1) & 3) {
97 case 0:
98 mask = 0xf0000000U;
99 len = 0x10000000U;
100 break;
101 case 1:
102 mask = 0xf8000000U;
103 len = 0x08000000U;
104 break;
105 case 2:
106 mask = 0xfc000000U;
107 len = 0x04000000U;
108 break;
109 default:
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)
126 return NULL;
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 {
137 u32 vendor;
138 u32 device;
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)
149 u32 l;
150 u16 vendor, device;
151 int i;
152 const char *name;
154 pci_conf1_read(0, 0, PCI_DEVFN(0,0), 0, 4, &l);
155 vendor = l & 0xffff;
156 device = (l >> 16) & 0xffff;
158 pci_mmcfg_config_num = 0;
159 pci_mmcfg_config = NULL;
160 name = 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();
168 if (name) {
169 printk(KERN_INFO "PCI: Found %s %s MMCONFIG support.\n",
170 name, pci_mmcfg_config_num ? "with" : "without");
173 return name != NULL;
176 static void __init pci_mmcfg_insert_resources(unsigned long resource_flags)
178 #define PCI_MMCFG_RESOURCE_NAME_LEN 19
179 int i;
180 struct resource *res;
181 char *names;
182 unsigned num_buses;
184 res = kcalloc(PCI_MMCFG_RESOURCE_NAME_LEN + sizeof(*res),
185 pci_mmcfg_config_num, GFP_KERNEL);
186 if (!res) {
187 printk(KERN_ERR "PCI: Unable to allocate MMCONFIG resources\n");
188 return;
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;
195 res->name = names;
196 snprintf(names, PCI_MMCFG_RESOURCE_NAME_LEN, "PCI MMCONFIG %u",
197 cfg->pci_segment);
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))
216 return;
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");
229 goto reject;
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,
238 E820_RESERVED)) {
239 printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %Lx is not"
240 " E820-reserved\n", cfg->address);
241 goto reject;
243 return;
245 reject:
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)
257 return;
259 if (type == 1 && pci_mmcfg_check_hostbridge())
260 known_bridge = 1;
262 if (!known_bridge) {
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))
270 return;
272 if (pci_mmcfg_arch_init()) {
273 if (type == 1)
274 unreachable_devices();
275 if (known_bridge)
276 pci_mmcfg_insert_resources(IORESOURCE_BUSY);
277 pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
278 } else {
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))
298 return 1;
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
303 * called.
305 pci_mmcfg_insert_resources(0);
307 return 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);