aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/pci/mmconfig.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386/pci/mmconfig.c')
-rw-r--r--arch/i386/pci/mmconfig.c41
1 files changed, 39 insertions, 2 deletions
diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c
index 972180f738d9..05be8db58a8c 100644
--- a/arch/i386/pci/mmconfig.c
+++ b/arch/i386/pci/mmconfig.c
@@ -151,6 +151,38 @@ static struct pci_raw_ops pci_mmcfg = {
151 .write = pci_mmcfg_write, 151 .write = pci_mmcfg_write,
152}; 152};
153 153
154
155static __init void pci_mmcfg_insert_resources(void)
156{
157#define PCI_MMCFG_RESOURCE_NAME_LEN 19
158 int i;
159 struct resource *res;
160 char *names;
161 unsigned num_buses;
162
163 res = kcalloc(PCI_MMCFG_RESOURCE_NAME_LEN + sizeof(*res),
164 pci_mmcfg_config_num, GFP_KERNEL);
165
166 if (!res) {
167 printk(KERN_ERR "PCI: Unable to allocate MMCONFIG resources\n");
168 return;
169 }
170
171 names = (void *)&res[pci_mmcfg_config_num];
172 for (i = 0; i < pci_mmcfg_config_num; i++, res++) {
173 num_buses = pci_mmcfg_config[i].end_bus_number -
174 pci_mmcfg_config[i].start_bus_number + 1;
175 res->name = names;
176 snprintf(names, PCI_MMCFG_RESOURCE_NAME_LEN, "PCI MMCONFIG %u",
177 pci_mmcfg_config[i].pci_segment_group_number);
178 res->start = pci_mmcfg_config[i].base_address;
179 res->end = res->start + (num_buses << 20) - 1;
180 res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
181 insert_resource(&iomem_resource, res);
182 names += PCI_MMCFG_RESOURCE_NAME_LEN;
183 }
184}
185
154/* K8 systems have some devices (typically in the builtin northbridge) 186/* K8 systems have some devices (typically in the builtin northbridge)
155 that are only accessible using type1 187 that are only accessible using type1
156 Normally this can be expressed in the MCFG by not listing them 188 Normally this can be expressed in the MCFG by not listing them
@@ -187,7 +219,9 @@ static __init void unreachable_devices(void)
187 } 219 }
188} 220}
189 221
190void __init pci_mmcfg_init(void) 222
223
224void __init pci_mmcfg_init(int type)
191{ 225{
192 if ((pci_probe & PCI_PROBE_MMCONF) == 0) 226 if ((pci_probe & PCI_PROBE_MMCONF) == 0)
193 return; 227 return;
@@ -198,7 +232,9 @@ void __init pci_mmcfg_init(void)
198 (pci_mmcfg_config[0].base_address == 0)) 232 (pci_mmcfg_config[0].base_address == 0))
199 return; 233 return;
200 234
201 if (!e820_all_mapped(pci_mmcfg_config[0].base_address, 235 /* Only do this check when type 1 works. If it doesn't work
236 assume we run on a Mac and always use MCFG */
237 if (type == 1 && !e820_all_mapped(pci_mmcfg_config[0].base_address,
202 pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN, 238 pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN,
203 E820_RESERVED)) { 239 E820_RESERVED)) {
204 printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %x is not E820-reserved\n", 240 printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %x is not E820-reserved\n",
@@ -212,4 +248,5 @@ void __init pci_mmcfg_init(void)
212 pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; 248 pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
213 249
214 unreachable_devices(); 250 unreachable_devices();
251 pci_mmcfg_insert_resources();
215} 252}