allow coexistance of N build and AC build.
[tomato.git] / release / src-rt-6.x / linux / linux-2.6 / arch / i386 / pci / mmconfig-shared.c
blobc7cabeed4d7b589cc9637ab326d71ae68efba1da
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 /* K8 systems have some devices (typically in the builtin northbridge)
28 that are only accessible using type1
29 Normally this can be expressed in the MCFG by not listing them
30 and assigning suitable _SEGs, but this isn't implemented in some BIOS.
31 Instead try to discover all devices on bus 0 that are unreachable using MM
32 and fallback for them. */
33 static void __init unreachable_devices(void)
35 int i, bus;
36 /* Use the max bus number from ACPI here? */
37 for (bus = 0; bus < PCI_MMCFG_MAX_CHECK_BUS; bus++) {
38 for (i = 0; i < 32; i++) {
39 unsigned int devfn = PCI_DEVFN(i, 0);
40 u32 val1, val2;
42 pci_conf1_read(0, bus, devfn, 0, 4, &val1);
43 if (val1 == 0xffffffff)
44 continue;
46 if (pci_mmcfg_arch_reachable(0, bus, devfn)) {
47 raw_pci_ops->read(0, bus, devfn, 0, 4, &val2);
48 if (val1 == val2)
49 continue;
51 set_bit(i + 32 * bus, pci_mmcfg_fallback_slots);
52 printk(KERN_NOTICE "PCI: No mmconfig possible on device"
53 " %02x:%02x\n", bus, i);
58 static const char __init *pci_mmcfg_e7520(void)
60 u32 win;
61 pci_conf1_read(0, 0, PCI_DEVFN(0,0), 0xce, 2, &win);
63 win = win & 0xf000;
64 if(win == 0x0000 || win == 0xf000)
65 pci_mmcfg_config_num = 0;
66 else {
67 pci_mmcfg_config_num = 1;
68 pci_mmcfg_config = kzalloc(sizeof(pci_mmcfg_config[0]), GFP_KERNEL);
69 if (!pci_mmcfg_config)
70 return NULL;
71 pci_mmcfg_config[0].address = win << 16;
72 pci_mmcfg_config[0].pci_segment = 0;
73 pci_mmcfg_config[0].start_bus_number = 0;
74 pci_mmcfg_config[0].end_bus_number = 255;
77 return "Intel Corporation E7520 Memory Controller Hub";
80 static const char __init *pci_mmcfg_intel_945(void)
82 u32 pciexbar, mask = 0, len = 0;
84 pci_mmcfg_config_num = 1;
86 pci_conf1_read(0, 0, PCI_DEVFN(0,0), 0x48, 4, &pciexbar);
88 /* Enable bit */
89 if (!(pciexbar & 1))
90 pci_mmcfg_config_num = 0;
92 /* Size bits */
93 switch ((pciexbar >> 1) & 3) {
94 case 0:
95 mask = 0xf0000000U;
96 len = 0x10000000U;
97 break;
98 case 1:
99 mask = 0xf8000000U;
100 len = 0x08000000U;
101 break;
102 case 2:
103 mask = 0xfc000000U;
104 len = 0x04000000U;
105 break;
106 default:
107 pci_mmcfg_config_num = 0;
110 /* Errata #2, things break when not aligned on a 256Mb boundary */
111 /* Can only happen in 64M/128M mode */
113 if ((pciexbar & mask) & 0x0fffffffU)
114 pci_mmcfg_config_num = 0;
116 /* Don't hit the APIC registers and their friends */
117 if ((pciexbar & mask) >= 0xf0000000U)
118 pci_mmcfg_config_num = 0;
120 if (pci_mmcfg_config_num) {
121 pci_mmcfg_config = kzalloc(sizeof(pci_mmcfg_config[0]), GFP_KERNEL);
122 if (!pci_mmcfg_config)
123 return NULL;
124 pci_mmcfg_config[0].address = pciexbar & mask;
125 pci_mmcfg_config[0].pci_segment = 0;
126 pci_mmcfg_config[0].start_bus_number = 0;
127 pci_mmcfg_config[0].end_bus_number = (len >> 20) - 1;
130 return "Intel Corporation 945G/GZ/P/PL Express Memory Controller Hub";
133 struct pci_mmcfg_hostbridge_probe {
134 u32 vendor;
135 u32 device;
136 const char *(*probe)(void);
139 static struct pci_mmcfg_hostbridge_probe pci_mmcfg_probes[] __initdata = {
140 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH, pci_mmcfg_e7520 },
141 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82945G_HB, pci_mmcfg_intel_945 },
144 static int __init pci_mmcfg_check_hostbridge(void)
146 u32 l;
147 u16 vendor, device;
148 int i;
149 const char *name;
151 pci_conf1_read(0, 0, PCI_DEVFN(0,0), 0, 4, &l);
152 vendor = l & 0xffff;
153 device = (l >> 16) & 0xffff;
155 pci_mmcfg_config_num = 0;
156 pci_mmcfg_config = NULL;
157 name = NULL;
159 for (i = 0; !name && i < ARRAY_SIZE(pci_mmcfg_probes); i++) {
160 if (pci_mmcfg_probes[i].vendor == vendor &&
161 pci_mmcfg_probes[i].device == device)
162 name = pci_mmcfg_probes[i].probe();
165 if (name) {
166 printk(KERN_INFO "PCI: Found %s %s MMCONFIG support.\n",
167 name, pci_mmcfg_config_num ? "with" : "without");
170 return name != NULL;
173 static void __init pci_mmcfg_insert_resources(void)
175 #define PCI_MMCFG_RESOURCE_NAME_LEN 19
176 int i;
177 struct resource *res;
178 char *names;
179 unsigned num_buses;
181 res = kcalloc(PCI_MMCFG_RESOURCE_NAME_LEN + sizeof(*res),
182 pci_mmcfg_config_num, GFP_KERNEL);
183 if (!res) {
184 printk(KERN_ERR "PCI: Unable to allocate MMCONFIG resources\n");
185 return;
188 names = (void *)&res[pci_mmcfg_config_num];
189 for (i = 0; i < pci_mmcfg_config_num; i++, res++) {
190 struct acpi_mcfg_allocation *cfg = &pci_mmcfg_config[i];
191 num_buses = cfg->end_bus_number - cfg->start_bus_number + 1;
192 res->name = names;
193 snprintf(names, PCI_MMCFG_RESOURCE_NAME_LEN, "PCI MMCONFIG %u",
194 cfg->pci_segment);
195 res->start = cfg->address;
196 res->end = res->start + (num_buses << 20) - 1;
197 res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
198 insert_resource(&iomem_resource, res);
199 names += PCI_MMCFG_RESOURCE_NAME_LEN;
203 static void __init pci_mmcfg_reject_broken(int type)
205 typeof(pci_mmcfg_config[0]) *cfg;
207 if ((pci_mmcfg_config_num == 0) ||
208 (pci_mmcfg_config == NULL) ||
209 (pci_mmcfg_config[0].address == 0))
210 return;
212 cfg = &pci_mmcfg_config[0];
215 * Handle more broken MCFG tables on Asus etc.
216 * They only contain a single entry for bus 0-0.
218 if (pci_mmcfg_config_num == 1 &&
219 cfg->pci_segment == 0 &&
220 (cfg->start_bus_number | cfg->end_bus_number) == 0) {
221 printk(KERN_ERR "PCI: start and end of bus number is 0. "
222 "Rejected as broken MCFG.\n");
223 goto reject;
227 * Only do this check when type 1 works. If it doesn't work
228 * assume we run on a Mac and always use MCFG
230 if (type == 1 && !e820_all_mapped(cfg->address,
231 cfg->address + MMCONFIG_APER_MIN,
232 E820_RESERVED)) {
233 printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %Lx is not"
234 " E820-reserved\n", cfg->address);
235 goto reject;
237 return;
239 reject:
240 printk(KERN_ERR "PCI: Not using MMCONFIG.\n");
241 kfree(pci_mmcfg_config);
242 pci_mmcfg_config = NULL;
243 pci_mmcfg_config_num = 0;
246 void __init pci_mmcfg_init(int type)
248 int known_bridge = 0;
250 if ((pci_probe & PCI_PROBE_MMCONF) == 0)
251 return;
253 if (type == 1 && pci_mmcfg_check_hostbridge())
254 known_bridge = 1;
256 if (!known_bridge) {
257 acpi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg);
258 pci_mmcfg_reject_broken(type);
261 if ((pci_mmcfg_config_num == 0) ||
262 (pci_mmcfg_config == NULL) ||
263 (pci_mmcfg_config[0].address == 0))
264 return;
266 if (pci_mmcfg_arch_init()) {
267 if (type == 1)
268 unreachable_devices();
269 if (known_bridge)
270 pci_mmcfg_insert_resources();
271 pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;