aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2005-06-23 20:35:56 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2005-06-28 00:52:47 -0400
commit545493917dc90298e1c38f018ad893f5518928e7 (patch)
tree1c809616d3113785c0f7dd3039ea3b05c99c6440
parentd18c3db58bc544fce6662ca7edba616ca9788a70 (diff)
[PATCH] PCI: add proper MCFG table parsing to ACPI core.
This patch is the first step in properly handling the MCFG PCI table. It defines the structures properly, and saves off the table so that the pci mmconfig code can access it. It moves the parsing of the table a little later in the boot process, but still before the information is needed. Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-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