diff options
Diffstat (limited to 'arch')
-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 |
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 |
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 | ||