Skip to contentSkip to conversation

x86: early dump pci conf space

PATCH In review Yinghai Lu 3 participants 13 messages May 21, 2008 – May 25, 2008

Subsystems (3)
lore
Share & tools
lore

Yinghai Lu

author
#0 lore raw

PATCH 1/1 x86: early dump pci conf space

so we can printout pci config before kernel touch it

also fix write_pci_config_byte with offset
and add write_pci_config_16

arch/x86/kernel/setup_64.c +5 -0
Index: linux-2.6/arch/x86/kernel/setup_64.c
===================================================================
@@ -350,6 +350,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();
arch/x86/pci/common.c +4 -0
Index: linux-2.6/arch/x86/pci/common.c
===================================================================
@@ -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;
@@ -489,6 +490,9 @@ char * __devinit  pcibios_setup(char *st
 	} 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;
arch/x86/pci/early.c +59 -1

69 lines not on this page · raw message

include/asm-x86/pci-direct.h +4 -0
Index: linux-2.6/include/asm-x86/pci-direct.h
===================================================================
@@ -11,7 +11,11 @@ extern u8 read_pci_config_byte(u8 bus, u
 extern u16 read_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset);
 extern void write_pci_config(u8 bus, u8 slot, u8 func, u8 offset, u32 val);
 extern void write_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset, u8 val);
+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
#1 lore raw
Quoted 4 lines · Yinghai Lu

so we can printout pci config before kernel touch it

also fix write_pci_config_byte with offset
and add write_pci_config_16

I like the idea. Can you submit the write config byte fix separately? I'll queue it up for 2.6.27 unless there are other comments.

Thanks,
Jesse

author
#2 lore raw

PATCH 1/1 x86: early dump pci conf space v2

In reply to Yinghai Lu

so we can printout pci config before kernel touch it

arch/x86/kernel/setup_64.c +5 -0
Index: linux-2.6/arch/x86/kernel/setup_64.c
===================================================================
@@ -350,6 +350,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();
arch/x86/pci/common.c +4 -0
Index: linux-2.6/arch/x86/pci/common.c
===================================================================
@@ -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;
@@ -489,6 +490,9 @@ char * __devinit  pcibios_setup(char *st
 	} 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;
arch/x86/pci/early.c +51 -0

54 lines not on this page · raw message

include/asm-x86/pci-direct.h +3 -0
Index: linux-2.6/include/asm-x86/pci-direct.h
===================================================================
@@ -14,4 +14,7 @@ extern void write_pci_config_byte(u8 bus
 
 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
#3 lore raw

Re: [PATCH] x86: early dump pci conf space v2

Quoted 3 lines · Yinghai Lu

so we can printout pci config before kernel touch it

Also applied to linux-next, this is a nice debugging feature.

Thanks,
Jesse

#4 lore raw

Re: [PATCH] x86: early dump pci conf space v2

In reply to Yinghai Lu
Quoted 4 lines · Yinghai Lu

so we can printout pci config before kernel touch it

Yinghai,
No offense, but my first thought was this is debug code that should be maintained outside the kernel.org tree. It will rarely get used. Just want people to think about this before saying "great, add it!"

(And this isn't a stab at Jesse since I think he's doing a better job than I could. I saw his previous reply to this mail.)

Having debugged lots of PCI resource and config issues, I understand why this is useful and do NOT object to it being included in the tree.

The boot option also needs to be added to Documentation/ . At least if you want people to use it. :)
Perhaps Jesse can suggest a preferred location.

Quoted 29 lines

Index: linux-2.6/arch/x86/kernel/setup_64.c
===================================================================

arch/x86/kernel/setup_64.c +5 -0
@@ -350,6 +350,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: linux-2.6/arch/x86/pci/common.c
===================================================================

arch/x86/pci/common.c +1 -0
@@ -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;

arch/x86/pci/common.c char * __devinit pcibios_setup(char *st · line 493

Quoted 4 lines
arch/x86/pci/common.c +1 -0
@@ -489,6 +490,9 @@ char * __devinit  pcibios_setup(char *st
 	} else if (!strcmp(str, "use_crs")) {
 		pci_probe |= PCI_USE__CRS;
 		return NULL;
+	} else if (!strcmp(str, "earlydump")) {

Please call this "pci_early_dump" (I prefer with underscores but don't care). Don't want it confused with kernel dumps (LKCD) or any other general debugging tools.

thanks,
grant

Quoted 80 lines
arch/x86/pci/common.c +2 -0
+		pci_early_dump_regs = 1;
+		return NULL;
 	} else if (!strcmp(str, "routeirq")) {
 		pci_routeirq = 1;
 		return NULL;

Index: linux-2.6/arch/x86/pci/early.c
===================================================================

arch/x86/pci/early.c +51 -0
@@ -57,3 +57,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: linux-2.6/include/asm-x86/pci-direct.h
===================================================================

include/asm-x86/pci-direct.h +3 -1
@@ -14,4 +14,7 @@ extern void write_pci_config_byte(u8 bus
 
 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
--

To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

author
#5 lore raw

Re: [PATCH] x86: early dump pci conf space v2

Quoted 11 lines · Grant Grundler
Quoted 4 lines · Yinghai Lu

so we can printout pci config before kernel touch it

Yinghai,
No offense, but my first thought was this is debug code that should be maintained outside the kernel.org tree. It will rarely get used. Just want people to think about this before saying "great, add it!"

Quoted 5 lines

(And this isn't a stab at Jesse since I think he's doing a better job than I could. I saw his previous reply to this mail.)

Having debugged lots of PCI resource and config issues, I understand why this is useful and do NOT object to it being included in the tree.

could print out the setting from buggy BIOS, or first kernel. and don't need the reporter apply debug patch again...

Quoted 4 lines

The boot option also needs to be added to Documentation/ . At least if you want people to use it. :)
Perhaps Jesse can suggest a preferred location.

we could add it.
..

Quoted 4 lines

Please call this "pci_early_dump" (I prefer with underscores but don't care). Don't want it confused with kernel dumps (LKCD) or any other general debugging tools.

so you want pci_early_dump instead of pci=earlydump? or pci=early_dump?

YH

#6 lore raw

Re: [PATCH] x86: early dump pci conf space v2

Quoted 6 lines · Yinghai Lu
Quoted 3 lines

Please call this "pci_early_dump" (I prefer with underscores but don't care). Don't want it confused with kernel dumps (LKCD) or any other general debugging tools.

so you want pci_early_dump instead of pci=earlydump? or pci=early_dump?

Or early_config_dump, I don't have a strong preference (but Grant's right that a pci_ prefix should be on there somewhere, either pci= or pci_).

Can you send me a replacement for the patch that added it once you come up with something?

Thanks,
Jesse

#7 lore raw

Re: [PATCH] x86: early dump pci conf space v2

In reply to Yinghai Lu

On Thu, May 22, 2008 at 11:38:24PM -0700, Yinghai Lu wrote:
...

Quoted 5 lines
Quoted 2 lines

Having debugged lots of PCI resource and config issues, I understand why this is useful and do NOT object to it being included in the tree.

could print out the setting from buggy BIOS, or first kernel. and don't need the reporter apply debug patch again...

Yes, I understood. Here are some more details on why my first reaction was negative:
o Most of the time the system can boot anyway and we get lspci -v output, /proc/iomem, etc. If that's not true, then other parts of the kernel need to be more robust (e.g. drivers crashing because resources aren't assigned.

o Bringing up linux on a new platform is NOT something we've generally had to do via email. Usually someone with kernel/IO experience is involved and can build new kernels.

Quoted 6 lines
Quoted 2 lines

At least if you want people to use it. :)
Perhaps Jesse can suggest a preferred location.

we could add it.
..

Quoted 1 line
Quoted 6 lines
Quoted 3 lines

Please call this "pci_early_dump" (I prefer with underscores but don't care). Don't want it confused with kernel dumps (LKCD) or any other general debugging tools.

so you want pci_early_dump instead of pci=earlydump? or pci=early_dump?

Sorry, I misread the patch.
I was thinking of "pci_early_dump" as a seperate option but either "pci=" option is fine.

thanks,
grant

#8 lore raw

Re: [PATCH] x86: early dump pci conf space v2

In reply to Grant Grundler
Quoted 10 lines · Grant Grundler
Quoted 3 lines · Yinghai Lu

so we can printout pci config before kernel touch it

Yinghai,
No offense, but my first thought was this is debug code that should be maintained outside the kernel.org tree. It will rarely get used. Just want people to think about this before saying "great, add it!"

Quoted 5 lines

(And this isn't a stab at Jesse since I think he's doing a better job than I could. I saw his previous reply to this mail.)

Having debugged lots of PCI resource and config issues, I understand why this is useful and do NOT object to it being included in the tree.

Yeah I thought about this too, but:
1) it's definitely useful for debugging PCI issues, and much easier for
everyone if it's in-tree
2) it only bloats x86 kernels ;)

Documentation is definitely needed though, thanks for catching that.

Thanks,
Jesse

author
#9 lore raw

PATCH 1/1 x86: early dump pci conf space v3

In reply to Yinghai Lu

so we can printout pci config before kernel touch it
v3: change to pci=early_config_dump

arch/x86/kernel/setup_64.c +5 -0
Index: linux-2.6/arch/x86/kernel/setup_64.c
===================================================================
@@ -350,6 +350,11 @@ void __init setup_arch(char **cmdline_p)
 
 	parse_early_param();
 
+#ifdef CONFIG_PCI
+	if (pci_early_config_dump)
+		early_dump_pci_devices();
+#endif
+
 #ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT
 	if (init_ohci1394_dma_early)
 		init_ohci1394_dma_on_all_controllers();
arch/x86/pci/common.c +4 -0
Index: linux-2.6/arch/x86/pci/common.c
===================================================================
@@ -20,6 +20,7 @@
 unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 |
 				PCI_PROBE_MMCONF;
 
+unsigned int pci_early_config_dump;
 static int pci_bf_sort;
 int pci_routeirq;
 int pcibios_last_bus = -1;
@@ -489,6 +490,9 @@ char * __devinit  pcibios_setup(char *st
 	} else if (!strcmp(str, "use_crs")) {
 		pci_probe |= PCI_USE__CRS;
 		return NULL;
+	} else if (!strcmp(str, "early_config_dump")) {
+		pci_early_config_dump = 1;
+		return NULL;
 	} else if (!strcmp(str, "routeirq")) {
 		pci_routeirq = 1;
 		return NULL;
arch/x86/pci/early.c +54 -0

57 lines not on this page · raw message

include/asm-x86/pci-direct.h +3 -0
Index: linux-2.6/include/asm-x86/pci-direct.h
===================================================================
@@ -14,4 +14,7 @@ extern void write_pci_config_byte(u8 bus
 
 extern int early_pci_allowed(void);
 
+extern unsigned int pci_early_config_dump;
+extern void early_dump_pci_device(u8 bus, u8 slot, u8 func);
+extern void early_dump_pci_devices(void);
 #endif
Documentation/kernel-parameters.txt +2 -0
Index: linux-2.6/Documentation/kernel-parameters.txt
===================================================================
@@ -1570,6 +1570,8 @@ and is between 256 and 4096 characters. 
 		cbmemsize=nn[KMG]	The fixed amount of bus space which is
 				reserved for the CardBus bridge's memory
 				window. The default value is 64 megabytes.
+		early_config_dump	[X86] print out pci config space
+				registers early before kernel touch any
 
 	pcmv=		[HW,PCMCIA] BadgePAD 4
 
arch/x86/kernel/setup_32.c +6 -0
Index: linux-2.6/arch/x86/kernel/setup_32.c
===================================================================
@@ -46,6 +46,7 @@
 #include <linux/dmi.h>
 #include <linux/pfn.h>
 #include <linux/pci.h>
+#include <asm/pci-direct.h>
 #include <linux/init_ohci1394_dma.h>
 #include <linux/kvm_para.h>
 
@@ -692,6 +693,11 @@ void __init setup_arch(char **cmdline_p)
 
 	parse_early_param();
 
+#ifdef CONFIG_PCI
+	if (pci_early_config_dump)
+		early_dump_pci_devices();
+#endif
+
 	finish_e820_parsing();
 
 	strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
Acked-by on v1 1/1
#10 lore raw

Re: [PATCH] x86: early dump pci conf space v3

Quoted 3 lines · Yinghai Lu

so we can printout pci config before kernel touch it
v3: change to pci=early_config_dump

...

Documentation/kernel-parameters.txt and is between 256 and 4096 characters. · line 1574

Quoted 10 lines

Index: linux-2.6/Documentation/kernel-parameters.txt
===================================================================

Documentation/kernel-parameters.txt +2 -0
@@ -1570,6 +1570,8 @@ and is between 256 and 4096 characters. 
 		cbmemsize=nn[KMG]	The fixed amount of bus space which is
 				reserved for the CardBus bridge's memory
 				window. The default value is 64 megabytes.
+		early_config_dump	[X86] print out pci config space
+				registers early before kernel touch any

A bit of wordsmithing here:

early_config_dump [X86] print out pci config space
registers before the kernel touches any PCI resources. This can help determine what PCI quirks need to do to compensate for broken BIOS.

Rest of the patch:

thanks,
grant

author
#11 lore raw

PATCH 1/1 x86: write_pci_config_byte fix offset

In reply to Yinghai Lu

also add write_pci_config_16

arch/x86/pci/early.c +8 -1
Index: linux-2.6/arch/x86/pci/early.c
===================================================================
@@ -49,7 +49,14 @@ void write_pci_config_byte(u8 bus, u8 sl
 {
 	PDprintk("%x writing to %x: %x\n", slot, offset, val);
 	outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
-	outb(val, 0xcfc);
+	outb(val, 0xcfc + (offset&3));
+}
+
+void write_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset, u16 val)
+{
+	PDprintk("%x writing to %x: %x\n", slot, offset, val);
+	outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
+	outw(val, 0xcfc + (offset&2));
 }
 
 int early_pci_allowed(void)
include/asm-x86/pci-direct.h +1 -0
Index: linux-2.6/include/asm-x86/pci-direct.h
===================================================================
@@ -11,6 +11,7 @@ extern u8 read_pci_config_byte(u8 bus, u
 extern u16 read_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset);
 extern void write_pci_config(u8 bus, u8 slot, u8 func, u8 offset, u32 val);
 extern void write_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset, u8 val);
+extern void write_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset, u16 val);
 
 extern int early_pci_allowed(void);