Skip to content

Commit 45d8a6f

Browse files
committed
pcireg: Add PCI bridge information reporting
1 parent 1dd3304 commit 45d8a6f

1 file changed

Lines changed: 76 additions & 14 deletions

File tree

pcireg/pcireg.c

Lines changed: 76 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,24 @@ static const char *devsel[] = {
8080
"Slow",
8181
"Invalid"
8282
};
83+
static const char *bridge_flags[] = {
84+
"Parity",
85+
"SErr",
86+
"ISA",
87+
"VGA",
88+
NULL,
89+
"MasterAbort",
90+
"SecReset",
91+
"FastB2B",
92+
"PriMTimeout",
93+
"SecMTimeout",
94+
"TimeoutStat",
95+
"TimeoutSErr",
96+
NULL,
97+
NULL,
98+
NULL,
99+
NULL
100+
};
83101

84102
static int term_width;
85103
static FILE *pciids_f = NULL;
@@ -764,8 +782,8 @@ static int
764782
dump_info(uint8_t bus, uint8_t dev, uint8_t func)
765783
{
766784
char *temp;
767-
int i;
768-
uint8_t header_type, subsys_reg, num_bars;
785+
int i, j;
786+
uint8_t header_type, subsys_reg, num_bars, exprom_reg;
769787
multi_t reg_val;
770788

771789
/* Print banner message. */
@@ -816,21 +834,25 @@ dump_info(uint8_t bus, uint8_t dev, uint8_t func)
816834
case 0x00: /* standard */
817835
subsys_reg = 0x2c;
818836
num_bars = 6;
837+
exprom_reg = 0x30;
838+
break;
839+
840+
case 0x01: /* PCI bridge */
841+
subsys_reg = 0xff;
842+
num_bars = 2;
843+
exprom_reg = 0x38;
819844
break;
820845

821846
case 0x02: /* CardBus bridge */
822847
subsys_reg = 0x40;
823848
num_bars = 0;
824-
break;
825-
826-
case 0x03: /* PCI bridge and others */
827-
subsys_reg = 0xff;
828-
num_bars = 2;
849+
exprom_reg = 0xff;
829850
break;
830851

831852
default: /* others */
832853
subsys_reg = 0xff;
833854
num_bars = 0;
855+
exprom_reg = 0xff;
834856
break;
835857
}
836858
if (subsys_reg != 0xff) {
@@ -873,6 +895,12 @@ dump_info(uint8_t bus, uint8_t dev, uint8_t func)
873895
info_flags_helper(reg_val.u16[1], status_flags);
874896
printf(" DEVSEL[%s]", devsel[(reg_val.u16[1] >> 9) & 3]);
875897

898+
/* Print bridge flags if this is a bridge. */
899+
if ((header_type & 0x7f) == 0x01) {
900+
printf("\n Bridge:");
901+
info_flags_helper(pci_readw(bus, dev, func, 0x3e), bridge_flags);
902+
}
903+
876904
/* Read revision and class ID. */
877905
reg_val.u32 = pci_readl(bus, dev, func, 0x08);
878906

@@ -934,9 +962,8 @@ dump_info(uint8_t bus, uint8_t dev, uint8_t func)
934962
}
935963

936964
/* Read and print BARs. */
937-
putchar('\n');
965+
j = 0;
938966
for (i = 0; i < num_bars; i++) {
939-
940967
/* Read BAR. */
941968
reg_val.u32 = pci_readl(bus, dev, func, 0x10 + (i << 2));
942969

@@ -945,6 +972,10 @@ dump_info(uint8_t bus, uint8_t dev, uint8_t func)
945972
continue;
946973

947974
/* Print BAR index. */
975+
if (!j) {
976+
putchar('\n');
977+
j = 1;
978+
}
948979
printf("\nBAR %d: ", i);
949980

950981
/* Print BAR type, address and properties. */
@@ -963,7 +994,7 @@ dump_info(uint8_t bus, uint8_t dev, uint8_t func)
963994

964995
case 0x04:
965996
/* Next BAR has the upper 32 bits. */
966-
printf("%08X_%08X (64-bit", pci_readl(bus, dev, func, 0x14 + (i++ << 2)), reg_val.u32 & 0xfffffff0);
997+
printf("%08X'%08X (64-bit", pci_readl(bus, dev, func, 0x14 + (i++ << 2)), reg_val.u32 & 0xfffffff0);
967998
break;
968999

9691000
case 0x06:
@@ -977,10 +1008,41 @@ dump_info(uint8_t bus, uint8_t dev, uint8_t func)
9771008
}
9781009
}
9791010

980-
/* Read and print expansion ROM. */
981-
reg_val.u32 = pci_readl(bus, dev, func, 0x30);
982-
if (reg_val.u32 && (reg_val.u32 != 0xffffffff))
983-
printf("\nExpansion ROM: %08X (%sabled)", reg_val.u32 & 0xfffffffe, (reg_val.u8[0] & 1) ? "en" : "dis");
1011+
if ((header_type & 0x7f) == 0x01) {
1012+
/* Read and print PCI bridge specific registers. */
1013+
putchar('\n');
1014+
1015+
/* Read and print bus numbers. */
1016+
reg_val.u32 = pci_readl(bus, dev, func, 0x18);
1017+
printf("\nPCI bus: Primary[%02X] Secondary[%02X] Subordinate[%02X]", reg_val.u8[0], reg_val.u8[1], reg_val.u8[2]);
1018+
1019+
/* Read and print I/O range. */
1020+
reg_val.u16[0] = pci_readw(bus, dev, func, 0x1c);
1021+
printf("\n I/O: ");
1022+
if (reg_val.u8[0] & 1)
1023+
printf("%04X%04X-%04X%04X (32-bit)", pci_readw(bus, dev, func, 0x30), (reg_val.u8[0] & 0xf0) << 8, pci_readw(bus, dev, func, 0x32), reg_val.u16[0] | 0x0fff);
1024+
else
1025+
printf("%04X-%04X (16-bit)", (reg_val.u8[0] & 0xf0) << 8, reg_val.u16[0] | 0x0fff);
1026+
1027+
/* Read and print MMIO memory range. */
1028+
reg_val.u32 = pci_readl(bus, dev, func, 0x20);
1029+
printf("\n Memory: %08X-%08X (32-bit, not prefetchable)\n ", (reg_val.u32 & 0x0000fff0) << 16, reg_val.u32 | 0x000fffff);
1030+
1031+
/* Read and print prefetchable memory range. */
1032+
reg_val.u32 = pci_readl(bus, dev, func, 0x24);
1033+
if (reg_val.u16[0] & 1)
1034+
printf("%08X'%08X-%08X'%08X (64-bit", pci_readl(bus, dev, func, 0x28), (reg_val.u32 & 0x0000fff0) << 16, pci_readl(bus, dev, func, 0x2c), reg_val.u32 | 0x000fffff);
1035+
else
1036+
printf("%08X-%08X (32-bit", (reg_val.u32 & 0x0000fff0) << 16, reg_val.u32 | 0x000fffff);
1037+
printf(", prefetchable)");
1038+
}
1039+
1040+
if (exprom_reg != 0xff) {
1041+
/* Read and print expansion ROM. */
1042+
reg_val.u32 = pci_readl(bus, dev, func, exprom_reg);
1043+
if (reg_val.u32 && (reg_val.u32 != 0xffffffff))
1044+
printf("\nExpansion ROM: %08X (%sabled)", reg_val.u32 & 0xfffffffe, (reg_val.u8[0] & 1) ? "en" : "dis");
1045+
}
9841046

9851047
printf("\n");
9861048

0 commit comments

Comments
 (0)