PCI/x86: early dump pci conf space v2
authorYinghai Lu <yhlu.kernel@gmail.com>
Thu, 22 May 2008 21:35:11 +0000 (14:35 -0700)
committerJesse Barnes <jbarnes@virtuousgeek.org>
Tue, 10 Jun 2008 17:59:52 +0000 (10:59 -0700)
Allows us to dump PCI space before any kernel changes have been made.

Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
arch/x86/kernel/setup_64.c
arch/x86/pci/common.c
arch/x86/pci/early.c
include/asm-x86/pci-direct.h

index 6dff1286ad8adec4b9fc6bb7808c3a233c476fd2..524b6850b2c063a03f6d26bbccf1be2b18663e5e 100644 (file)
@@ -361,6 +361,11 @@ void __init setup_arch(char **cmdline_p)
 
        parse_early_param();
 
+#ifdef CONFIG_PCI
+       if (pci_early_dump_regs)
+               early_dump_pci_devices();
+#endif
+
 #ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT
        if (init_ohci1394_dma_early)
                init_ohci1394_dma_on_all_controllers();
index 3a5261bdff5d42dd04384f75556618cb5ec5b4ad..d19fd07bafd62d9927a0da675d80404b6db1136f 100644 (file)
@@ -20,6 +20,7 @@
 unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 |
                                PCI_PROBE_MMCONF;
 
+unsigned int pci_early_dump_regs;
 static int pci_bf_sort;
 int pci_routeirq;
 int pcibios_last_bus = -1;
@@ -511,6 +512,9 @@ char * __devinit  pcibios_setup(char *str)
        } else if (!strcmp(str, "use_crs")) {
                pci_probe |= PCI_USE__CRS;
                return NULL;
+       } else if (!strcmp(str, "earlydump")) {
+               pci_early_dump_regs = 1;
+               return NULL;
        } else if (!strcmp(str, "routeirq")) {
                pci_routeirq = 1;
                return NULL;
index 8e2821e8dac5aa78c13e31f3eac26b6962fad737..858dbe3399f9f79d5b318bef2767ffcb37153960 100644 (file)
@@ -64,3 +64,54 @@ int early_pci_allowed(void)
        return (pci_probe & (PCI_PROBE_CONF1|PCI_PROBE_NOEARLY)) ==
                        PCI_PROBE_CONF1;
 }
+
+void early_dump_pci_device(u8 bus, u8 slot, u8 func)
+{
+       int i;
+       int j;
+       u32 val;
+
+       printk("PCI: %02x:%02x:%02x", bus, slot, func);
+
+       for (i = 0; i < 256; i += 4) {
+               if (!(i & 0x0f))
+                       printk("\n%04x:",i);
+
+               val = read_pci_config(bus, slot, func, i);
+               for (j = 0; j < 4; j++) {
+                       printk(" %02x", val & 0xff);
+                       val >>= 8;
+               }
+       }
+       printk("\n");
+}
+
+void early_dump_pci_devices(void)
+{
+       unsigned bus, slot, func;
+
+       if (!early_pci_allowed())
+               return;
+
+       for (bus = 0; bus < 256; bus++) {
+               for (slot = 0; slot < 32; slot++) {
+                       for (func = 0; func < 8; func++) {
+                               u32 class;
+                               u8 type;
+                               class = read_pci_config(bus, slot, func,
+                                                       PCI_CLASS_REVISION);
+                               if (class == 0xffffffff)
+                                       break;
+
+                               early_dump_pci_device(bus, slot, func);
+
+                               /* No multi-function device? */
+                               type = read_pci_config_byte(bus, slot, func,
+                                                              PCI_HEADER_TYPE);
+                               if (!(type & 0x80))
+                                       break;
+                       }
+               }
+       }
+}
+
index 7bd40b4de751f8ca8c7801094f025b7e52b7bf14..80c775d9fe205810257fb8dc0013b997b5d61969 100644 (file)
@@ -15,4 +15,7 @@ extern void write_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset, u16 val);
 
 extern int early_pci_allowed(void);
 
+extern unsigned int pci_early_dump_regs;
+extern void early_dump_pci_device(u8 bus, u8 slot, u8 func);
+extern void early_dump_pci_devices(void);
 #endif