[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>

+62 -23
+33 -8
arch/i386/kernel/acpi/boot.c
··· 159 #endif 160 161 #ifdef CONFIG_PCI_MMCONFIG 162 - static int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) 163 { 164 struct acpi_table_mcfg *mcfg; 165 166 if (!phys_addr || !size) 167 return -EINVAL; ··· 178 return -ENODEV; 179 } 180 181 - if (mcfg->base_reserved) { 182 - printk(KERN_ERR PREFIX "MMCONFIG not in low 4GB of memory\n"); 183 return -ENODEV; 184 } 185 186 - pci_mmcfg_base_addr = mcfg->base_address; 187 188 return 0; 189 } 190 - #else 191 - #define acpi_parse_mcfg NULL 192 - #endif /* !CONFIG_PCI_MMCONFIG */ 193 194 #ifdef CONFIG_X86_LOCAL_APIC 195 static int __init ··· 1165 acpi_process_madt(); 1166 1167 acpi_table_parse(ACPI_HPET, acpi_parse_hpet); 1168 - acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); 1169 1170 return 0; 1171 }
··· 159 #endif 160 161 #ifdef CONFIG_PCI_MMCONFIG 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) 167 { 168 struct acpi_table_mcfg *mcfg; 169 + unsigned long i; 170 + int config_size; 171 172 if (!phys_addr || !size) 173 return -EINVAL; ··· 172 return -ENODEV; 173 } 174 175 + /* how many config structures do we have */ 176 + pci_mmcfg_config_num = 0; 177 + i = size - sizeof(struct acpi_table_mcfg); 178 + while (i >= sizeof(struct acpi_table_mcfg_config)) { 179 + ++pci_mmcfg_config_num; 180 + i -= sizeof(struct acpi_table_mcfg_config); 181 + }; 182 + if (pci_mmcfg_config_num == 0) { 183 + printk(KERN_ERR PREFIX "MMCONFIG has no entries\n"); 184 return -ENODEV; 185 } 186 187 + config_size = pci_mmcfg_config_num * sizeof(*pci_mmcfg_config); 188 + pci_mmcfg_config = kmalloc(config_size, GFP_KERNEL); 189 + if (!pci_mmcfg_config) { 190 + printk(KERN_WARNING PREFIX 191 + "No memory for MCFG config tables\n"); 192 + return -ENOMEM; 193 + } 194 + 195 + memcpy(pci_mmcfg_config, &mcfg->config, config_size); 196 + for (i = 0; i < pci_mmcfg_config_num; ++i) { 197 + if (mcfg->config[i].base_reserved) { 198 + printk(KERN_ERR PREFIX 199 + "MMCONFIG not in low 4GB of memory\n"); 200 + return -ENODEV; 201 + } 202 + } 203 204 return 0; 205 } 206 + #endif /* CONFIG_PCI_MMCONFIG */ 207 208 #ifdef CONFIG_X86_LOCAL_APIC 209 static int __init ··· 1139 acpi_process_madt(); 1140 1141 acpi_table_parse(ACPI_HPET, acpi_parse_hpet); 1142 1143 return 0; 1144 }
+7 -5
arch/i386/pci/mmconfig.c
··· 11 12 #include <linux/pci.h> 13 #include <linux/init.h> 14 #include "pci.h" 15 - 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)) 20 ··· 25 26 static inline void pci_exp_set_dev_base(int bus, int devfn) 27 { 28 - u32 dev_base = pci_mmcfg_base_addr | (bus << 20) | (devfn << 12); 29 if (dev_base != mmcfg_last_accessed_device) { 30 mmcfg_last_accessed_device = dev_base; 31 set_fixmap_nocache(FIX_PCIE_MCFG, dev_base); ··· 99 { 100 if ((pci_probe & PCI_PROBE_MMCONF) == 0) 101 goto out; 102 - if (!pci_mmcfg_base_addr) 103 goto out; 104 105 /* Kludge for now. Don't use mmconfig on AMD systems because
··· 11 12 #include <linux/pci.h> 13 #include <linux/init.h> 14 + #include <linux/acpi.h> 15 #include "pci.h" 16 17 #define mmcfg_virt_addr ((void __iomem *) fix_to_virt(FIX_PCIE_MCFG)) 18 ··· 27 28 static inline void pci_exp_set_dev_base(int bus, int devfn) 29 { 30 + u32 dev_base = pci_mmcfg_config[0].base_address | (bus << 20) | (devfn << 12); 31 if (dev_base != mmcfg_last_accessed_device) { 32 mmcfg_last_accessed_device = dev_base; 33 set_fixmap_nocache(FIX_PCIE_MCFG, dev_base); ··· 101 { 102 if ((pci_probe & PCI_PROBE_MMCONF) == 0) 103 goto out; 104 + 105 + acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); 106 + if ((pci_mmcfg_config_num == 0) || 107 + (pci_mmcfg_config == NULL) || 108 + (pci_mmcfg_config[0].base_address == 0)) 109 goto out; 110 111 /* Kludge for now. Don't use mmconfig on AMD systems because
+9 -7
arch/x86_64/pci/mmconfig.c
··· 7 8 #include <linux/pci.h> 9 #include <linux/init.h> 10 #include "pci.h" 11 12 #define MMCONFIG_APER_SIZE (256*1024*1024) 13 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 */ 18 - char *pci_mmcfg_virt; 19 20 static inline char *pci_dev_base(unsigned int bus, unsigned int devfn) 21 { ··· 75 { 76 if ((pci_probe & PCI_PROBE_MMCONF) == 0) 77 return 0; 78 - if (!pci_mmcfg_base_addr) 79 return 0; 80 81 /* Kludge for now. Don't use mmconfig on AMD systems because ··· 90 return 0; 91 92 /* RED-PEN i386 doesn't do _nocache right now */ 93 - pci_mmcfg_virt = ioremap_nocache(pci_mmcfg_base_addr, MMCONFIG_APER_SIZE); 94 if (!pci_mmcfg_virt) { 95 printk("PCI: Cannot map mmconfig aperture\n"); 96 return 0; 97 } 98 99 - printk(KERN_INFO "PCI: Using MMCONFIG at %x\n", pci_mmcfg_base_addr); 100 raw_pci_ops = &pci_mmcfg; 101 pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; 102
··· 7 8 #include <linux/pci.h> 9 #include <linux/init.h> 10 + #include <linux/acpi.h> 11 #include "pci.h" 12 13 #define MMCONFIG_APER_SIZE (256*1024*1024) 14 15 /* Static virtual mapping of the MMCONFIG aperture */ 16 + static char *pci_mmcfg_virt; 17 18 static inline char *pci_dev_base(unsigned int bus, unsigned int devfn) 19 { ··· 77 { 78 if ((pci_probe & PCI_PROBE_MMCONF) == 0) 79 return 0; 80 + 81 + acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); 82 + if ((pci_mmcfg_config_num == 0) || 83 + (pci_mmcfg_config == NULL) || 84 + (pci_mmcfg_config[0].base_address == 0)) 85 return 0; 86 87 /* Kludge for now. Don't use mmconfig on AMD systems because ··· 88 return 0; 89 90 /* RED-PEN i386 doesn't do _nocache right now */ 91 + pci_mmcfg_virt = ioremap_nocache(pci_mmcfg_config[0].base_address, MMCONFIG_APER_SIZE); 92 if (!pci_mmcfg_virt) { 93 printk("PCI: Cannot map mmconfig aperture\n"); 94 return 0; 95 } 96 97 + printk(KERN_INFO "PCI: Using MMCONFIG at %x\n", pci_mmcfg_config[0].base_address); 98 raw_pci_ops = &pci_mmcfg; 99 pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; 100
+13 -3
include/linux/acpi.h
··· 342 343 /* PCI MMCONFIG */ 344 345 struct acpi_table_mcfg { 346 struct acpi_table_header header; 347 u8 reserved[8]; 348 - u32 base_address; 349 - u32 base_reserved; 350 } __attribute__ ((packed)); 351 352 /* Table Handlers */ ··· 399 int acpi_get_table_header_early (enum acpi_table_id id, struct acpi_table_header **header); 400 int acpi_table_parse_madt (enum acpi_madt_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 void acpi_table_print (struct acpi_table_header *header, unsigned long phys_addr); 403 void acpi_table_print_madt_entry (acpi_table_entry_header *madt); 404 void acpi_table_print_srat_entry (acpi_table_entry_header *srat); ··· 421 422 extern int acpi_mp_config; 423 424 - extern u32 pci_mmcfg_base_addr; 425 426 extern int sbf_port ; 427
··· 342 343 /* PCI MMCONFIG */ 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)); 354 struct acpi_table_mcfg { 355 struct acpi_table_header header; 356 u8 reserved[8]; 357 + struct acpi_table_mcfg_config config[0]; 358 } __attribute__ ((packed)); 359 360 /* Table Handlers */ ··· 391 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); 393 int acpi_table_parse_srat (enum acpi_srat_entry_id id, acpi_madt_entry_handler handler, unsigned int max_entries); 394 + int acpi_parse_mcfg (unsigned long phys_addr, unsigned long size); 395 void acpi_table_print (struct acpi_table_header *header, unsigned long phys_addr); 396 void acpi_table_print_madt_entry (acpi_table_entry_header *madt); 397 void acpi_table_print_srat_entry (acpi_table_entry_header *srat); ··· 412 413 extern int acpi_mp_config; 414 415 + extern struct acpi_table_mcfg_config *pci_mmcfg_config; 416 + extern int pci_mmcfg_config_num; 417 418 extern int sbf_port ; 419