Skip to content

Commit f71722c

Browse files
committed
bin: add system support data collection
Backported from origin/main 5420fb0 Includes the latest DRAM ECC status, with/without sudo, and temperature. Signed-off-by: Joachim Wiberg <[email protected]>
1 parent 5ea9968 commit f71722c

File tree

4 files changed

+823
-0
lines changed

4 files changed

+823
-0
lines changed
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
#!/bin/sh
2+
3+
set -e
4+
5+
# Build a map of phandle -> device tree node path for all PHY nodes
6+
build_phandle_map()
7+
{
8+
for phy_node in /sys/firmware/devicetree/base/cp*/config-space*/mdio*/switch*/mdio/ethernet-phy@* \
9+
/sys/firmware/devicetree/base/cp*/config-space*/mdio*/ethernet-phy@*; do
10+
[ -f "$phy_node/phandle" ] || continue
11+
12+
phandle=$(od -An -t x4 -N 4 "$phy_node/phandle" 2>/dev/null | tr -d ' ')
13+
if [ -n "$phandle" ]; then
14+
echo "$phandle:$phy_node"
15+
fi
16+
done
17+
}
18+
19+
build_phy_map()
20+
{
21+
phandle_map=$(build_phandle_map)
22+
23+
# Build a mapping of PHY of_node path -> interface name
24+
for iface in /sys/class/net/*; do
25+
[ -d "$iface" ] || continue
26+
27+
iface_name=$(basename "$iface")
28+
29+
# Try regular phydev approach first (for non-DSA interfaces)
30+
if [ -L "$iface/phydev/of_node" ]; then
31+
phy_of_node=$(readlink -f "$iface/phydev/of_node" 2>/dev/null)
32+
if [ -n "$phy_of_node" ]; then
33+
echo "$phy_of_node:$iface_name"
34+
continue
35+
fi
36+
fi
37+
38+
# For DSA interfaces, resolve via of_node's phy-handle
39+
if [ -L "$iface/of_node" ]; then
40+
iface_of_node=$(readlink -f "$iface/of_node" 2>/dev/null)
41+
[ -n "$iface_of_node" ] || continue
42+
43+
# Try to read phy-handle property (4-byte phandle)
44+
if [ -f "$iface_of_node/phy-handle" ]; then
45+
phy_phandle=$(od -An -t x4 -N 4 "$iface_of_node/phy-handle" 2>/dev/null | tr -d ' ')
46+
47+
if [ -n "$phy_phandle" ]; then
48+
# Look up the PHY node path from our phandle map
49+
phy_of_node=$(echo "$phandle_map" | grep "^$phy_phandle:" | cut -d: -f2)
50+
if [ -n "$phy_of_node" ]; then
51+
echo "$phy_of_node:$iface_name"
52+
fi
53+
fi
54+
fi
55+
fi
56+
done
57+
}
58+
59+
zone_map()
60+
{
61+
type="$1"
62+
63+
case "$type" in
64+
ap-ic-thermal)
65+
echo "Application processor interconnect"
66+
;;
67+
ap-cpu[0-9]*-thermal)
68+
cpu=${type#ap-cpu}
69+
cpu=${cpu%-thermal}
70+
echo "Application processor core $cpu"
71+
;;
72+
cp[0-9]*-ic-thermal)
73+
cp=${type%%-*}
74+
cp=${cp#cp}
75+
echo "Communication processor $cp interconnect"
76+
;;
77+
*)
78+
echo "$type"
79+
;;
80+
esac
81+
}
82+
83+
thermal_zones()
84+
{
85+
echo "Thermal Zones"
86+
echo "============="
87+
echo
88+
89+
for zone in /sys/class/thermal/thermal_zone*; do
90+
[ -d "$zone" ] || continue
91+
92+
name=$(basename "$zone")
93+
type=$(cat "$zone/type" 2>/dev/null || echo "unknown")
94+
data=$(cat "$zone/temp" 2>/dev/null)
95+
desc=$(zone_map "$type")
96+
97+
if [ -n "$data" ] && [ "$data" != "N/A" ]; then
98+
# Convert millidegrees to degrees Celsius
99+
temp_c=$(awk "BEGIN {printf \"%.1f\", $data / 1000}")
100+
printf "%-20s %8s°C %s\n" "$name" "$temp_c" "$desc"
101+
else
102+
printf "%-20s %8s %s\n" "$name" "N/A" "$desc"
103+
fi
104+
done
105+
echo
106+
}
107+
108+
hwmon()
109+
{
110+
tmpfile=$(mktemp)
111+
112+
echo "Hardware Monitors"
113+
echo "================="
114+
echo
115+
116+
phy_map=$(build_phy_map)
117+
118+
for hwmon in /sys/class/hwmon/hwmon*; do
119+
[ -d "$hwmon" ] || continue
120+
121+
name=$(basename "$hwmon")
122+
data=$(cat "$hwmon/temp1_input" 2>/dev/null)
123+
124+
# Try to find the associated network interface
125+
iface=
126+
if [ -L "$hwmon/of_node" ]; then
127+
hwmon_of_node=$(readlink -f "$hwmon/of_node" 2>/dev/null)
128+
if [ -n "$hwmon_of_node" ]; then
129+
iface=$(echo "$phy_map" | grep "^$hwmon_of_node:" | cut -d: -f2)
130+
fi
131+
fi
132+
133+
if [ -n "$iface" ]; then
134+
description="Phy $iface temperature"
135+
else
136+
description="N/A"
137+
fi
138+
139+
if [ -n "$data" ] && [ "$data" != "N/A" ]; then
140+
# Convert millidegrees to degrees Celsius
141+
temp_c=$(awk "BEGIN {printf \"%.1f\", $data / 1000}")
142+
# Format: sortkey|hwmon|temp|description (sortkey for natural sort by interface)
143+
printf "%s|%-20s %8s°C %s\n" "$iface" "$name" "$temp_c" "$description" >> "$tmpfile"
144+
else
145+
printf "%s|%-20s %8s %s\n" "$iface" "$name" "N/A" "$description" >> "$tmpfile"
146+
fi
147+
done
148+
149+
# Sort by interface name naturally (e2 before e10), with N/A entries at the end
150+
# Then strip the sort key before displaying
151+
sort -V -t'|' -k1,1 "$tmpfile" | cut -d'|' -f2-
152+
rm -f "$tmpfile"
153+
echo
154+
}
155+
156+
[ -n "$1" ] || { echo "usage: $0 OUT-DIR"; exit 1; }
157+
work="$1"/system
158+
mkdir -p "${work}"
159+
160+
thermal_zones > "${work}"/temperature.txt
161+
hwmon >> "${work}"/temperature.txt
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#!/bin/sh
2+
3+
set -e
4+
5+
ecc_stat()
6+
{
7+
local chan=
8+
local base=
9+
10+
for chan in 0 1; do
11+
base=$((0xf0020360 + 0x200 * chan))
12+
13+
echo "DRAM Channel $chan ECC Status"
14+
echo -n " Log config: "; devmem $((base + 0x0)) 32
15+
echo -n " 1b errors: "; devmem $((base + 0x4)) 32
16+
echo -n " Info 0: "; devmem $((base + 0x8)) 32
17+
echo -n " Info 1: "; devmem $((base + 0xc)) 32
18+
echo
19+
done
20+
}
21+
22+
[ -n "$1" ] || { echo "usage: $0 OUT-DIR"; exit 1; }
23+
work="$1"/marvell-cn913x
24+
mkdir -p "${work}"
25+
26+
ecc_stat >"${work}"/ecc-stat

src/bin/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ DISTCLEANFILES = *~ *.d
22
ACLOCAL_AMFLAGS = -I m4
33

44
bin_PROGRAMS = copy erase files
5+
sbin_SCRIPTS = support
56

67
# Bash completion
78
bashcompdir = $(datadir)/bash-completion/completions

0 commit comments

Comments
 (0)