diff options
-rw-r--r-- | arch/i386/kernel/acpi/boot.c | 41 | ||||
-rw-r--r-- | arch/i386/pci/mmconfig.c | 12 | ||||
-rw-r--r-- | arch/x86_64/pci/mmconfig.c | 16 | ||||
-rw-r--r-- | include/linux/acpi.h | 16 |
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 |
162 | static int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) | 162 | /* The physical address of the MMCONFIG aperture. Set from ACPI tables. */ |
163 | struct acpi_table_mcfg_config *pci_mmcfg_config; | ||
164 | int pci_mmcfg_config_num; | ||
165 | |||
166 | int __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 |
189 | static int __init | 215 | static 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. */ | ||
17 | u32 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 | ||
28 | static inline void pci_exp_set_dev_base(int bus, int devfn) | 26 | static 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. */ | ||
15 | u32 pci_mmcfg_base_addr; | ||
16 | |||
17 | /* Static virtual mapping of the MMCONFIG aperture */ | 15 | /* Static virtual mapping of the MMCONFIG aperture */ |
18 | char *pci_mmcfg_virt; | 16 | static char *pci_mmcfg_virt; |
19 | 17 | ||
20 | static inline char *pci_dev_base(unsigned int bus, unsigned int devfn) | 18 | static 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 */ | ||
346 | struct 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)); | ||
345 | struct acpi_table_mcfg { | 354 | struct 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); | |||
391 | int acpi_get_table_header_early (enum acpi_table_id id, struct acpi_table_header **header); | 399 | int acpi_get_table_header_early (enum acpi_table_id id, struct acpi_table_header **header); |
392 | int acpi_table_parse_madt (enum acpi_madt_entry_id id, acpi_madt_entry_handler handler, unsigned int max_entries); | 400 | int acpi_table_parse_madt (enum acpi_madt_entry_id id, acpi_madt_entry_handler handler, unsigned int max_entries); |
393 | int acpi_table_parse_srat (enum acpi_srat_entry_id id, acpi_madt_entry_handler handler, unsigned int max_entries); | 401 | int acpi_table_parse_srat (enum acpi_srat_entry_id id, acpi_madt_entry_handler handler, unsigned int max_entries); |
402 | int acpi_parse_mcfg (unsigned long phys_addr, unsigned long size); | ||
394 | void acpi_table_print (struct acpi_table_header *header, unsigned long phys_addr); | 403 | void acpi_table_print (struct acpi_table_header *header, unsigned long phys_addr); |
395 | void acpi_table_print_madt_entry (acpi_table_entry_header *madt); | 404 | void acpi_table_print_madt_entry (acpi_table_entry_header *madt); |
396 | void acpi_table_print_srat_entry (acpi_table_entry_header *srat); | 405 | void 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 | ||
413 | extern int acpi_mp_config; | 422 | extern int acpi_mp_config; |
414 | 423 | ||
415 | extern u32 pci_mmcfg_base_addr; | 424 | extern struct acpi_table_mcfg_config *pci_mmcfg_config; |
425 | extern int pci_mmcfg_config_num; | ||
416 | 426 | ||
417 | extern int sbf_port ; | 427 | extern int sbf_port ; |
418 | 428 | ||