aboutsummaryrefslogtreecommitdiffstats
path: root/arch
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 /arch
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>
Diffstat (limited to 'arch')
-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
3 files changed, 49 insertions, 20 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