Skip to content

Instantly share code, notes, and snippets.

@ross-newman
Created August 22, 2019 14:34
Show Gist options
  • Save ross-newman/1e02d36b0a1b8d927632e57581262626 to your computer and use it in GitHub Desktop.
Save ross-newman/1e02d36b0a1b8d927632e57581262626 to your computer and use it in GitHub Desktop.
IDT PCIe Switch probing with busybox
#!/bin/bash
## Determine architecture
arch=$(arch)
if [ "$arch" == "ppc" ]; then
echo "PowerPC Host detected"
## When one card installed
dev0mem0=0xf80300000
## When no card installed
# dev0mem0=0xf80100000
else
# Assume Intel x86 host
echo "Intel Host detected not supported"
exit -1
fi
size=$1
value=0xdeadbeef
function bswap32() {
value=$(printf "0x%08x" $(($bar + $1)) )
# Check if PPC host and endian swap
if [ "$arch" == "ppc" ]; then
value=$(echo 0x${value:8:2}${value:6:2}${value:4:2}${value:2:2})
fi
}
function bswap16() {
value=$(printf "0x%04x" $(($bar + $1)) )
# Check if PPC host and endian swap
if [ "$arch" == "ppc" ]; then
value=$(echo 0x${value:4:2}${value:2:2})
fi
}
function globalAddressSpaceRead() {
register=$(printf "0x%04x" $1 )
comment="$2"
registers=$4
portmode=""
GASAADDR=$(($dev0mem0 + 0xFF8))
GASADATA=$(($dev0mem0 + 0xFFC))
## Manage endianness
bswap32 $register
$(busybox devmem $GASAADDR 32 $value)
data=$(busybox devmem $GASADATA 32)
bswap32 $data
printf "0x%04x 0x%08x %s\n" $1 $value "$comment"
## Print extra stuff depending on register range
if [ "$registers" == "1" ]; then
## Print some extra info
case "$3" in
1) printf "\t\e[1;31mPciStatus : 0x%04x\e[m\n" $((($value >> 16) & 0xff)) ;; ## Red
16) if [ $(( $value >> 20 & 0xf )) == 5 ]; then
dir="Upstream"
else
dir="Downstream"
fi
printf "\tLinkCap %s port \n" $dir
;;
18) printf "\t\e[1;31mPciDevStatus : 0x%04x\e[m\n" $((($value >> 16) & 0xff)) ;;
19) printf "\tLinkCap Width x%d Gen%d Port %d\n" $((($value >> 4) & 0xf)) $(($value & 0xf)) $((($value >> 24) & 0xff)) ;;
20) printf "\t\e[1;32mLinkSta Width x%d Gen%d\e[m\n" $((($value >> 20) & 0xf)) $(($value >> 16 & 0xf)) ;;
esac
fi
if [ "$registers" == "6" ]; then
## Print some extra info
case "$3" in
0)
case $(($value & 0xf)) in
0) portmode="Disabled" ;;
1) portmode="Downstream switch port" ;;
2) portmode="Upstream switch port" ;;
3) portmode="NT function" ;;
4) portmode="Upstream switch port with NT function" ;;
5) portmode="Unattached" ;;
6) portmode="Upstream switch port with DMA function" ;;
7) portmode="Upstream switch port with NT and DMA functions" ;;
8) portmode="NT with DMA function" ;;
esac
printf "\tPortMode : %s\n" "$portmode"
printf "\tDeviceNumber : 0x%x\n" $((($value >> 10) & 0x1f))
;;
1)
up=$((($value >> 4) & 0x1))
if [ $up == "1" ]; then
printf "\e[1;32m"
else
printf "\e[1;31m"
fi
if [ $((($value >> 5) & 0x1)) == "0" ]; then
linkmode="Upstream"
else
linkmode="Downstream"
fi
case $((($value >> 6) & 0xf)) in
0) portmode="Disabled" ;;
1) portmode="Downstream switch port" ;;
2) portmode="Upstream switch port" ;;
3) portmode="NT function" ;;
4) portmode="Upstream switch port with NT function" ;;
5) portmode="Unattached" ;;
6) portmode="Upstream switch port with DMA function" ;;
7) portmode="Upstream switch port with NT and DMA functions" ;;
8) portmode="NT with DMA function" ;;
esac
printf "\tLinkUp : 0x%s\n" $up
printf "\tLinkMode : %s\n" "$linkmode"
printf "\tPortMode : %s (0x%x)\n" "$portmode" $((($value >> 6) & 0xf))
printf "\tDeviceNumber : 0x%x\n" $((($value >> 16) & 0x1f))
printf "\e[m"
;;
esac
fi
if [ "$registers" == "7" ]; then
## Print some extra info
case "$3" in
1)
printf "\tTempreture : %f Degrees C\n" $((($value & 0xff) >> 1))
;;
esac
fi
}
## Dump Global Address Space Registers
function globalAddressSpaceDump() {
field=$1
length=$(($2-1))
registers=$3
for i in $( eval echo {0..$length})
do
comment=""
if [ $registers == "1" ]; then
case "$i" in
0) comment="DID - Device Identification Register (0x0000) / VID - Vendor Identification Register (0x111D)" ;;
1) comment="PCISTS - PCI Status Register (0x0000) / PCICMD - PCI Command Register (0x0000)" ;;
2) comment="CCODE - Class Code Register (0x00) / RID - Revision Identification Register (0x00)" ;;
3) comment="PLTIMER - Primary Latency Timer (0x00) / CLS - Cache Line Size Register (0x00) / HDR - Header Type Register (0x00) / BIST - Built-in Self Test Register" ;;
4) comment="BAR0 - Base Address Register 0" ;;
5) comment="BAR0 - Base Address Register 1" ;;
6) comment="PBUSN - Primary Bus Number Register / SBUSN - Secondary Bus Number Register" ;;
16) comment="PCIECAP - PCI Express Capability" ;;
17) comment="PCIEDCAP - PCI Express Device Capabilities" ;;
18) comment="PCIEDSTS - PCI Express Device Status / PCIEDCTL - PCI Express Device Control" ;;
19) comment="PCIELCAP - PCI Express Link Capabilities" ;;
20) comment="PCIELSTS - PCI Express Link Status / PCIELCTL - PCI Express Link Control" ;;
esac
fi
if [ $registers == "2" ]; then
case "$i" in
0) comment="SWCTL - Switch Control" ;;
1) comment="BCVSTS - Boot Configuration Vector Status" ;;
2) comment="PCLKMODE - Port Clocking Mode" ;;
3) comment="(undefined)" ;;
4) comment="STK0CFG - Stack Configuration" ;;
5) comment="STK1CFG - Stack Configuration" ;;
6) comment="STK2CFG - Stack Configuration" ;;
7) comment="STK3CFG - Stack Configuration" ;;
esac
fi
if [ $registers == "3" ]; then
case "$i" in
0) comment="RDRAINDELAY - Reset Drain Delay" ;;
1) comment="POMCDELAY - Port Operating Mode Change Drain Delay" ;;
2) comment="(undefined)" ;;
3) comment="SEDELAY - Side Effect Delay" ;;
esac
fi
if [ $registers == "6" ]; then
case "$i" in
0) comment="SWPORT[23:0]CTL - Switch Port x Control" ;;
1) comment="SWPORT[23:0]STS - Switch Port x Status" ;;
esac
fi
if [ $registers == "7" ]; then
case "$i" in
0) comment="TMPCTL - Temperature Sensor Control" ;;
1) comment="TMPSTS - Temperature Sensor Status" ;;
esac
fi
reg=$(($field+($i*4)))
globalAddressSpaceRead $reg "$comment" $i $registers
if [ $i == "0" ]; then
if [ $registers == "1" ]; then
if [ $value == "0x00000000" ]; then
# First register should not be zero
return 0
fi
fi
fi
done
}
## Dump the PCI Configuration Space
function dump() {
mem=$1
width=16
stride=2
adjustment=0
for i in {0..64}
do
comment=""
case "$i" in
0) comment='VID Vendor Identification Register (0x111D)';;
1) comment="DID - Device Identification Register (-)" ;;
2) comment="PCICMD - PCI Command Register (0x0000)" ;;
3) comment="PCISTS - PCI Status Register (0x00)" ;;
4) comment="RID - Revision Identification Register (-) / CCODE - Class Code Register (-)" ;;
5) comment="(undefined)" ;;
6) comment="CLS - Cache Line Size Register (0x00) / PLTIMER - Primary Latency Timer (0x00)" ;;
7) comment="HDR - Header Type Register (0x00) / BIST - Built-in Self Test Register (0x00)" ;;
8) comment="BAR0 - Base Address Register 0 (0x0000)" ;;
9) comment="BAR0 - Base Address Register 0 (0x0000)" ;;
10) comment="BAR1 - Base Address Register 1 (0x0000)" ;;
11) comment="BAR1 - Base Address Register 1 (0x0000)" ;;
12) comment="PBUSN - Primary Bus Number Register (0x00) / SBUSN - Secondary Bus Number Register (0x0000)" ;;
13) comment="SUBUSN - Subordinate Bus Number Register (0x00) / SLTIMER - Secondary Latency Timer Register (0x0000)" ;;
14) comment="IOBASE - I/O Base Register (0x00) / IOLIMIT - I/O Limit Registerr (0x0000)" ;;
15) comment="SECSTS - Secondary Status Register (0x0000)" ;;
16) comment="MBASE - Memory Base Register (0xFFF0)" ;;
32) comment="PCIECAP - PCI Express Capability" ;;
33) comment="PCIEDCAP - PCI Express Device Capabilities" ;;
34) comment="PCIEDCTL - PCI Express Device Control" ;;
35) comment="PCIECAP - PCI Express Capability" ;;
esac
if [ "$i" == "0" ]; then
printf "\nPCI Configuration Space\n"
printf "=======================\n"
fi
if [ "$i" == "32" ]; then
printf "\nPCI Express Capabilities Header\n"
printf "===============================\n"
width=32
stride=4
adjustment=0x40
fi
currentAddr=$(($mem+i*$stride-$adjustment))
value=$(busybox devmem $currentAddr $width)
if [ "$stride" == "2" ]; then
bswap16 $value
else
bswap32 $value
fi
if [ $stride == "4" ]; then
printf "0x%03x 0x%08x 0x%08x %s\n" $(($i*2)) $currentAddr $value "$comment"
else
printf "0x%03x 0x%08x 0x%04x %s\n" $(($i*2)) $currentAddr $value "$comment"
fi
done
}
## Dump Proprietary Port Specific Registers
function dumpPortSpecific() {
port=$1
mem=$(($2 + $3))
offset=$3
stride=4
for i in {0..64}
do
comment=""
case "$i" in
0) comment="PORTCTL - Port Control (0x0000) / P2PINTSTS - PCI-to-PCI Bridge Interrupt Status (0x0000)";;
1) comment="P2PINTSTS - PCI-to-PCI Bridge Interrupt Status (0x00000000)";;
2) comment="P2PINTMSK - PCI-to-PCI Bridge Interrupt Mask (0x00000000)";;
3) comment="(undefined)";;
4) comment="P2PSDATA - PCI-to-PCI Bridge Signal Data (0x00000000)";;
5) comment="P2PGSIGNAL - PCI-to-PCI Bridge Global Signal (0x00000000)";;
6) comment="(undefined)";;
7) comment="(undefined)";;
8) comment="(undefined)";;
9) comment="PAERMSK - Port AER Mask";;
10) comment="(undefined)";;
11) comment="(undefined)";;
12) comment="PCIESCTLIV - PCI Express Slot Control Initial Value";;
esac
if [ "$i" == "0" ]; then
printf "\nProprietary Port Specific Registers\n"
printf "===================================\n"
fi
currentAddr=$(($mem+i*$stride))
value=$(busybox devmem $currentAddr $width)
bswap32 $value
printf "0x%03x 0x%08x 0x%08x %s\n" $(($offset+$i*$stride)) $currentAddr $value "$comment"
done
}
#lspci -d 111d:808e -nn -v -xxx
lspci -s 01:00.1 -nn -v -xxx
portSpecificRegisterOffset=0x400
## Dump PCI configuration
dump $dev0mem0
## Dump Proprietary Port Specific Registers
dumpPortSpecific 0 $dev0mem0 $portSpecificRegisterOffset
## Dump Global Address Space
globalAddressSpaceRead 0x1000
## Dump all 24 Ports
for i in {0..23}
do
printf "\nGlobal Address Space - Port %d PCI-to-PCI Bridge Registers\n" $i
printf "===========================================================\n"
globalAddressSpaceDump $(($i*0x4000)) 32 1
done
printf "\nGlobal Address Space - Configuration Status Registers\n" $i
printf "=======================================================\n"
globalAddressSpaceDump 0x3e000 8 2
printf "\nGlobal Address Space - \n" $i
printf "========================\n"
globalAddressSpaceDump 0x3e080 8 3
printf "\nGlobal Address Space - Switch Partition\n" $i
printf "=========================================\n"
globalAddressSpaceDump 0x3e100 4 4
## Dump all 24 Ports
for i in {0..23}
do
printf "\nGlobal Address Space - Port %d Status and Control\n" $i
printf "==================================================\n"
globalAddressSpaceDump $(($i*0x0020+0x3e200)) 3 6
done
printf "\nGlobal Address Space - Tempreture\n" $i
printf "====================================================\n"
globalAddressSpaceDump 0x3f1d4 2 7
@ross-newman
Copy link
Author

Specifically for the IDT® 89HPES24NT24G2 PCI Express® Switch

Registers as per User Manual IDT_89H24NT24G2_MAN_20140822.pdf August 2014

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment