Skip to contentSkip to conversation

MMCONFIG: validate against ACPI motherboard resources (revised)

PATCH New Robert Hancock 1 participant 1 message Jun 7, 2007 ACPI

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 MMCONFIG: validate against ACPI motherboard resources (revised)

This path adds validation of the MMCONFIG table against the ACPI reserved motherboard resources. If the MMCONFIG table is found to be reserved in ACPI, we don't bother checking the E820 table. The PCI Express firmware spec apparently tells BIOS developers that reservation in ACPI is required and E820 reservation is optional, so checking against ACPI first makes sense. Many BIOSes don't reserve the MMCONFIG region in E820 even though it is perfectly functional, the existing check needlessly disables MMCONFIG in these cases.

In order to do this, MMCONFIG setup has been split into two phases. If PCI configuration type 1 is not available then MMCONFIG is enabled early as before. Otherwise, it is enabled later after the ACPI interpreter is enabled, since we need to be able to execute control methods in order to check the ACPI reserved resources. Presently this is just triggered off the end of ACPI interpreter initialization.

There are a few other behavioral changes here:

-Validate all MMCONFIG configurations provided, not just the first one.

-Validate the entire required length of each configuration according to the provided ending bus number is reserved, not just the minimum required allocation.

-Validate that the area is reserved even if we read it from the chipset directly and not from the MCFG table. This catches the case where the BIOS didn't set the location properly in the chipset and has mapped it over other things it shouldn't have.

This also cleans up the MMCONFIG initialization functions so that they simply do nothing if MMCONFIG is not compiled in.

Based on an original patch by Rajesh Shah from Intel.

---

This should fix up the compile error in the previous version with CONFIG_PCI_MMCONFIG=n.

arch/i386/pci/init.c +2 -3
diff -rup --exclude-from=linux-2.6.22-rc4-mm1edit/Documentation/dontdiff linux-2.6.22-rc4-mm1/arch/i386/pci/init.c linux-2.6.22-rc4-mm1edit/arch/i386/pci/init.c
@@ -1,4 +1,5 @@
 #include <linux/pci.h>
+#include <asm/pci.h>
 #include <linux/init.h>
 #include "pci.h"
 
@@ -11,9 +12,7 @@ static __init int pci_access_init(void)
 #ifdef CONFIG_PCI_DIRECT
 	type = pci_direct_probe();
 #endif
-#ifdef CONFIG_PCI_MMCONFIG
-	pci_mmcfg_init(type);
-#endif
+	pci_mmcfg_early_init(type);
 	if (raw_pci_ops)
 		return 0;
 #ifdef CONFIG_PCI_BIOS
arch/i386/pci/mmconfig-shared.c +133 -19

187 lines not on this page · raw message

arch/i386/pci/pci.h +0 -1
diff -rup --exclude-from=linux-2.6.22-rc4-mm1edit/Documentation/dontdiff linux-2.6.22-rc4-mm1/arch/i386/pci/pci.h linux-2.6.22-rc4-mm1edit/arch/i386/pci/pci.h
@@ -91,7 +91,6 @@ extern int pci_conf1_read(unsigned int s
 extern int pci_direct_probe(void);
 extern void pci_direct_init(int type);
 extern void pci_pcbios_init(void);
-extern void pci_mmcfg_init(int type);
 extern void pcibios_sort(void);
 
 /* pci-mmconfig.c */
drivers/acpi/bus.c +5 -0
diff -rup --exclude-from=linux-2.6.22-rc4-mm1edit/Documentation/dontdiff linux-2.6.22-rc4-mm1/drivers/acpi/bus.c linux-2.6.22-rc4-mm1edit/drivers/acpi/bus.c
@@ -34,6 +34,8 @@
 #include <linux/proc_fs.h>
 #ifdef CONFIG_X86
 #include <asm/mpspec.h>
+#include <linux/pci.h>
+#include <asm/pci.h>
 #endif
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
@@ -755,6 +757,9 @@ static int __init acpi_init(void)
 	result = acpi_bus_init();
 
 	if (!result) {
+#ifdef CONFIG_X86
+		pci_mmcfg_late_init();
+#endif		
 #ifdef CONFIG_PM_LEGACY
 		if (!PM_IS_ACTIVE())
 			pm_active = 1;
include/asm-i386/pci.h +8 -0
diff -rup --exclude-from=linux-2.6.22-rc4-mm1edit/Documentation/dontdiff linux-2.6.22-rc4-mm1/include/asm-i386/pci.h linux-2.6.22-rc4-mm1edit/include/asm-i386/pci.h
@@ -30,6 +30,14 @@ void pcibios_penalize_isa_irq(int irq, i
 struct irq_routing_table *pcibios_get_irq_routing_table(void);
 int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq);
 
+#ifdef CONFIG_PCI_MMCONFIG
+extern void __init pci_mmcfg_early_init(int type);
+extern void __init pci_mmcfg_late_init(void);
+#else
+#define pci_mmcfg_early_init(TYPE)	do { } while (0)
+#define pci_mmcfg_late_init(TYPE)	do { } while (0)
+#endif
+
 /* Dynamic DMA mapping stuff.
  * i386 has everything mapped statically.
  */
include/asm-x86_64/pci.h +8 -0
diff -rup --exclude-from=linux-2.6.22-rc4-mm1edit/Documentation/dontdiff linux-2.6.22-rc4-mm1/include/asm-x86_64/pci.h linux-2.6.22-rc4-mm1edit/include/asm-x86_64/pci.h
@@ -34,6 +34,14 @@ void pcibios_penalize_isa_irq(int irq, i
 struct irq_routing_table *pcibios_get_irq_routing_table(void);
 int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq);
 
+#ifdef CONFIG_PCI_MMCONFIG
+extern void __init pci_mmcfg_early_init(int type);
+extern void __init pci_mmcfg_late_init(void);
+#else
+#define pci_mmcfg_early_init(TYPE)	do { } while (0)
+#define pci_mmcfg_late_init(TYPE)	do { } while (0)
+#endif
+
 #include <linux/types.h>
 #include <linux/slab.h>
 #include <asm/scatterlist.h>