浏览代码

PCI/x86: early dump pci conf space v2

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>
Yinghai Lu 17 年之前
父节点
当前提交
e3f2baebf4
共有 4 个文件被更改,包括 63 次插入0 次删除
  1. 5 0
      arch/x86/kernel/setup_64.c
  2. 4 0
      arch/x86/pci/common.c
  3. 51 0
      arch/x86/pci/early.c
  4. 3 0
      include/asm-x86/pci-direct.h

+ 5 - 0
arch/x86/kernel/setup_64.c

@@ -361,6 +361,11 @@ void __init setup_arch(char **cmdline_p)
 
 
 	parse_early_param();
 	parse_early_param();
 
 
+#ifdef CONFIG_PCI
+	if (pci_early_dump_regs)
+		early_dump_pci_devices();
+#endif
+
 #ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT
 #ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT
 	if (init_ohci1394_dma_early)
 	if (init_ohci1394_dma_early)
 		init_ohci1394_dma_on_all_controllers();
 		init_ohci1394_dma_on_all_controllers();

+ 4 - 0
arch/x86/pci/common.c

@@ -20,6 +20,7 @@
 unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 |
 unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 |
 				PCI_PROBE_MMCONF;
 				PCI_PROBE_MMCONF;
 
 
+unsigned int pci_early_dump_regs;
 static int pci_bf_sort;
 static int pci_bf_sort;
 int pci_routeirq;
 int pci_routeirq;
 int pcibios_last_bus = -1;
 int pcibios_last_bus = -1;
@@ -511,6 +512,9 @@ char * __devinit  pcibios_setup(char *str)
 	} else if (!strcmp(str, "use_crs")) {
 	} else if (!strcmp(str, "use_crs")) {
 		pci_probe |= PCI_USE__CRS;
 		pci_probe |= PCI_USE__CRS;
 		return NULL;
 		return NULL;
+	} else if (!strcmp(str, "earlydump")) {
+		pci_early_dump_regs = 1;
+		return NULL;
 	} else if (!strcmp(str, "routeirq")) {
 	} else if (!strcmp(str, "routeirq")) {
 		pci_routeirq = 1;
 		pci_routeirq = 1;
 		return NULL;
 		return NULL;

+ 51 - 0
arch/x86/pci/early.c

@@ -64,3 +64,54 @@ int early_pci_allowed(void)
 	return (pci_probe & (PCI_PROBE_CONF1|PCI_PROBE_NOEARLY)) ==
 	return (pci_probe & (PCI_PROBE_CONF1|PCI_PROBE_NOEARLY)) ==
 			PCI_PROBE_CONF1;
 			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;
+			}
+		}
+	}
+}
+

+ 3 - 0
include/asm-x86/pci-direct.h

@@ -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 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
 #endif