aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/i386/kernel/acpi/boot.c41
-rw-r--r--arch/i386/pci/mmconfig.c12
-rw-r--r--arch/x86_64/pci/mmconfig.c16
-rw-r--r--include/linux/acpi.h16
4 files changed, 62 insertions, 23 deletions
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c
index f5360d88bcf4..b7808a89d945 100644
--- a/arch/i386/kernel/acpi/boot.c
+++ b/arch/i386/kernel/acpi/boot.c
@@ -159,9 +159,15 @@ char *__acpi_map_table(unsigned long phys, unsigned long size)
159#endif 159#endif
160 160
161#ifdef CONFIG_PCI_MMCONFIG 161#ifdef CONFIG_PCI_MMCONFIG
162static int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) 162/* The physical address of the MMCONFIG aperture. Set from ACPI tables. */
163struct acpi_table_mcfg_config *pci_mmcfg_config;
164int pci_mmcfg_config_num;
165
166int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size)
163{ 167{
164 struct acpi_table_mcfg *mcfg; 168 struct acpi_table_mcfg *mcfg;
169 unsigned long i;
170 int config_size;
165 171
166 if (!phys_addr || !size) 172 if (!phys_addr || !size)
167 return -EINVAL; 173 return -EINVAL;
@@ -172,18 +178,38 @@ static int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size)
172 return -ENODEV; 178 return -ENODEV;
173 } 179 }
174 180
175 if (mcfg->base_reserved) { 181 /* how many config structures do we have */
176 printk(KERN_ERR PREFIX "MMCONFIG not in low 4GB of memory\n"); 182 pci_mmcfg_config_num = 0;
183 i = size - sizeof(struct acpi_table_mcfg);
184 while (i >= sizeof(struct acpi_table_mcfg_config)) {
185 ++pci_mmcfg_config_num;
186 i -= sizeof(struct acpi_table_mcfg_config);
187 };
188 if (pci_mmcfg_config_num == 0) {
189 printk(KERN_ERR PREFIX "MMCONFIG has no entries\n");
177 return -ENODEV; 190 return -ENODEV;
178 } 191 }
179 192
180 pci_mmcfg_base_addr = mcfg->base_address; 193 config_size = pci_mmcfg_config_num * sizeof(*pci_mmcfg_config);
194 pci_mmcfg_config = kmalloc(config_size, GFP_KERNEL);
195 if (!pci_mmcfg_config) {
196 printk(KERN_WARNING PREFIX
197 "No memory for MCFG config tables\n");
198 return -ENOMEM;
199 }
200
201 memcpy(pci_mmcfg_config, &mcfg->config, config_size);
202 for (i = 0; i < pci_mmcfg_config_num; ++i) {
203 if (mcfg->config[i].base_reserved) {
204 printk(KERN_ERR PREFIX
205 "MMCONFIG not in low 4GB of memory\n");
206 return -ENODEV;
207 }
208 }
181 209
182 return 0; 210 return 0;
183} 211}
184#else 212#endif /* CONFIG_PCI_MMCONFIG */
185#define acpi_parse_mcfg NULL
186#endif /* !CONFIG_PCI_MMCONFIG */
187 213
188#ifdef CONFIG_X86_LOCAL_APIC 214#ifdef CONFIG_X86_LOCAL_APIC
189static int __init 215static int __init
@@ -1139,7 +1165,6 @@ int __init acpi_boot_init(void)
1139 acpi_process_madt(); 1165 acpi_process_madt();
1140 1166
1141 acpi_table_parse(ACPI_HPET, acpi_parse_hpet); 1167 acpi_table_parse(ACPI_HPET, acpi_parse_hpet);
1142 acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg);
1143 1168
1144 return 0; 1169 return 0;
1145} 1170}
diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c
index 021a50aa51f4..5fbaa9132258 100644
--- a/arch/i386/pci/mmconfig.c
+++ b/arch/i386/pci/mmconfig.c
@@ -11,11 +11,9 @@
11 11
12#include <linux/pci.h> 12#include <linux/pci.h>
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/acpi.h>
14#include "pci.h" 15#include "pci.h"
15 16
16/* The physical address of the MMCONFIG aperture. Set from ACPI tables. */
17u32 pci_mmcfg_base_addr;
18
19#define mmcfg_virt_addr ((void __iomem *) fix_to_virt(FIX_PCIE_MCFG)) 17#define mmcfg_virt_addr ((void __iomem *) fix_to_virt(FIX_PCIE_MCFG))
20 18
21/* The base address of the last MMCONFIG device accessed */ 19/* The base address of the last MMCONFIG device accessed */
@@ -27,7 +25,7 @@ static u32 mmcfg_last_accessed_device;
27 25
28static inline void pci_exp_set_dev_base(int bus, int devfn) 26static inline void pci_exp_set_dev_base(int bus, int devfn)
29{ 27{
30 u32 dev_base = pci_mmcfg_base_addr | (bus << 20) | (devfn << 12); 28 u32 dev_base = pci_mmcfg_config[0].base_address | (bus << 20) | (devfn << 12);
31 if (dev_base != mmcfg_last_accessed_device) { 29 if (dev_base != mmcfg_last_accessed_device) {
32 mmcfg_last_accessed_device = dev_base; 30 mmcfg_last_accessed_device = dev_base;
33 set_fixmap_nocache(FIX_PCIE_MCFG, dev_base); 31 set_fixmap_nocache(FIX_PCIE_MCFG, dev_base);
@@ -101,7 +99,11 @@ static int __init pci_mmcfg_init(void)
101{ 99{
102 if ((pci_probe & PCI_PROBE_MMCONF) == 0) 100 if ((pci_probe & PCI_PROBE_MMCONF) == 0)
103 goto out; 101 goto out;
104 if (!pci_mmcfg_base_addr) 102
103 acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg);
104 if ((pci_mmcfg_config_num == 0) ||
105 (pci_mmcfg_config == NULL) ||
106 (pci_mmcfg_config[0].base_address == 0))
105 goto out; 107 goto out;
106 108
107 /* Kludge for now. Don't use mmconfig on AMD systems because 109 /* Kludge for now. Don't use mmconfig on AMD systems because
diff --git a/arch/x86_64/pci/mmconfig.c b/arch/x86_64/pci/mmconfig.c
index b693c232fd07..09cfcc1234b9 100644
--- a/arch/x86_64/pci/mmconfig.c
+++ b/arch/x86_64/pci/mmconfig.c
@@ -7,15 +7,13 @@
7 7
8#include <linux/pci.h> 8#include <linux/pci.h>
9#include <linux/init.h> 9#include <linux/init.h>
10#include <linux/acpi.h>
10#include "pci.h" 11#include "pci.h"
11 12
12#define MMCONFIG_APER_SIZE (256*1024*1024) 13#define MMCONFIG_APER_SIZE (256*1024*1024)
13 14
14/* The physical address of the MMCONFIG aperture. Set from ACPI tables. */
15u32 pci_mmcfg_base_addr;
16
17/* Static virtual mapping of the MMCONFIG aperture */ 15/* Static virtual mapping of the MMCONFIG aperture */
18char *pci_mmcfg_virt; 16static char *pci_mmcfg_virt;
19 17
20static inline char *pci_dev_base(unsigned int bus, unsigned int devfn) 18static inline char *pci_dev_base(unsigned int bus, unsigned int devfn)
21{ 19{
@@ -77,7 +75,11 @@ static int __init pci_mmcfg_init(void)
77{ 75{
78 if ((pci_probe & PCI_PROBE_MMCONF) == 0) 76 if ((pci_probe & PCI_PROBE_MMCONF) == 0)
79 return 0; 77 return 0;
80 if (!pci_mmcfg_base_addr) 78
79 acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg);
80 if ((pci_mmcfg_config_num == 0) ||
81 (pci_mmcfg_config == NULL) ||
82 (pci_mmcfg_config[0].base_address == 0))
81 return 0; 83 return 0;
82 84
83 /* Kludge for now. Don't use mmconfig on AMD systems because 85 /* Kludge for now. Don't use mmconfig on AMD systems because
@@ -88,13 +90,13 @@ static int __init pci_mmcfg_init(void)
88 return 0; 90 return 0;
89 91
90 /* RED-PEN i386 doesn't do _nocache right now */ 92 /* RED-PEN i386 doesn't do _nocache right now */
91 pci_mmcfg_virt = ioremap_nocache(pci_mmcfg_base_addr, MMCONFIG_APER_SIZE); 93 pci_mmcfg_virt = ioremap_nocache(pci_mmcfg_config[0].base_address, MMCONFIG_APER_SIZE);
92 if (!pci_mmcfg_virt) { 94 if (!pci_mmcfg_virt) {
93 printk("PCI: Cannot map mmconfig aperture\n"); 95 printk("PCI: Cannot map mmconfig aperture\n");
94 return 0; 96 return 0;
95 } 97 }
96 98
97 printk(KERN_INFO "PCI: Using MMCONFIG at %x\n", pci_mmcfg_base_addr); 99 printk(KERN_INFO "PCI: Using MMCONFIG at %x\n", pci_mmcfg_config[0].base_address);
98 raw_pci_ops = &pci_mmcfg; 100 raw_pci_ops = &pci_mmcfg;
99 pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; 101 pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
100 102
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index f5bc298707e1..ef8483673aa3 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -342,11 +342,19 @@ struct acpi_table_ecdt {
342 342
343/* PCI MMCONFIG */ 343/* PCI MMCONFIG */
344 344
345/* Defined in PCI Firmware Specification 3.0 */
346struct acpi_table_mcfg_config {
347 u32 base_address;
348 u32 base_reserved;
349 u16 pci_segment_group_number;
350 u8 start_bus_number;
351 u8 end_bus_number;
352 u8 reserved[4];
353} __attribute__ ((packed));
345struct acpi_table_mcfg { 354struct acpi_table_mcfg {
346 struct acpi_table_header header; 355 struct acpi_table_header header;
347 u8 reserved[8]; 356 u8 reserved[8];
348 u32 base_address; 357 struct acpi_table_mcfg_config config[0];
349 u32 base_reserved;
350} __attribute__ ((packed)); 358} __attribute__ ((packed));
351 359
352/* Table Handlers */ 360/* Table Handlers */
@@ -391,6 +399,7 @@ int acpi_table_parse (enum acpi_table_id id, acpi_table_handler handler);
391int acpi_get_table_header_early (enum acpi_table_id id, struct acpi_table_header **header); 399int acpi_get_table_header_early (enum acpi_table_id id, struct acpi_table_header **header);
392int acpi_table_parse_madt (enum acpi_madt_entry_id id, acpi_madt_entry_handler handler, unsigned int max_entries); 400int acpi_table_parse_madt (enum acpi_madt_entry_id id, acpi_madt_entry_handler handler, unsigned int max_entries);
393int acpi_table_parse_srat (enum acpi_srat_entry_id id, acpi_madt_entry_handler handler, unsigned int max_entries); 401int acpi_table_parse_srat (enum acpi_srat_entry_id id, acpi_madt_entry_handler handler, unsigned int max_entries);
402int acpi_parse_mcfg (unsigned long phys_addr, unsigned long size);
394void acpi_table_print (struct acpi_table_header *header, unsigned long phys_addr); 403void acpi_table_print (struct acpi_table_header *header, unsigned long phys_addr);
395void acpi_table_print_madt_entry (acpi_table_entry_header *madt); 404void acpi_table_print_madt_entry (acpi_table_entry_header *madt);
396void acpi_table_print_srat_entry (acpi_table_entry_header *srat); 405void acpi_table_print_srat_entry (acpi_table_entry_header *srat);
@@ -412,7 +421,8 @@ int acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base);
412 421
413extern int acpi_mp_config; 422extern int acpi_mp_config;
414 423
415extern u32 pci_mmcfg_base_addr; 424extern struct acpi_table_mcfg_config *pci_mmcfg_config;
425extern int pci_mmcfg_config_num;
416 426
417extern int sbf_port ; 427extern int sbf_port ;
418 428