From 0ad76ea8b036e930eda105993c24d748c391ab53 Mon Sep 17 00:00:00 2001 From: ETWen Date: Wed, 23 Sep 2026 14:43:28 +0800 Subject: [PATCH] feat(pwr): Log AMD CPU package power in the Script 4 loop avt_pmpower.sh runs AVTCMD -module pmm "get_pmdata()" and summarizes SktPwr, PPT Fast / Slow against their limits, and MemPwr. -p takes the AVTCMD path, -q drops the raw PM table. Exit 2 = AVTCMD missing, 3 = AVTCMD failed, 4 = nothing parsed. The values are SMU telemetry, not a measurement. Script 4 calls it every round after the two TH6_SWB power readbacks, so switch rails and CPU package power sit side by side in each sample. AVT is under NDA and not shipped in Blanton_Script. It has to be unpacked on the DUT at ~/AVT_Linux_NDA_2.8.37/ beforehand; otherwise the call exits 2 each round and the loop continues without the reading. Without -q the full PM table is logged once a minute. Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_01UniUXkxgCG2Ty74advL8Pd --- .../4_Blanton_Script_thermal_safety.ttl | 2 + .../Blanton_Script/avt_pmpower.sh | 137 ++++++++++++++++++ 2 files changed, 139 insertions(+) create mode 100644 src/Script_ABC_Blanton/Blanton_Script/avt_pmpower.sh diff --git a/src/Script_ABC_Blanton/4_Blanton_Script_thermal_safety.ttl b/src/Script_ABC_Blanton/4_Blanton_Script_thermal_safety.ttl index 903085c..4054489 100644 --- a/src/Script_ABC_Blanton/4_Blanton_Script_thermal_safety.ttl +++ b/src/Script_ABC_Blanton/4_Blanton_Script_thermal_safety.ttl @@ -152,6 +152,8 @@ while 1 sendln "~/Blanton_Script/TH6_SWB0_power_readback.sh" wait prompt_sonic_root sendln "~/Blanton_Script/TH6_SWB1_power_readback.sh" + wait prompt_sonic_root + sendln "~/Blanton_Script/avt_pmpower.sh -p ~/AVT_Linux_NDA_2.8.37/AVTCMD" ; Background jobs Check wait prompt_sonic_root diff --git a/src/Script_ABC_Blanton/Blanton_Script/avt_pmpower.sh b/src/Script_ABC_Blanton/Blanton_Script/avt_pmpower.sh new file mode 100644 index 0000000..6471344 --- /dev/null +++ b/src/Script_ABC_Blanton/Blanton_Script/avt_pmpower.sh @@ -0,0 +1,137 @@ +#!/bin/bash +#=============================================================================== +# Script : avt_pmpower.sh +# Purpose : Dump AMD AVT PM table (get_pmdata) and summarize package power. +# +# Author : ETWen +# Date : 20260923 +# +# Version History +# V1.0.0 20260923 Initial Version +# +# Usage : ./avt_pmpower.sh [-p ] [-q] [-h] +# -p Path to AVTCMD (default: $AVTCMD_PATH or ./AVTCMD) +# -q Quiet: summary only, suppress raw PM table +# -h Help +# +# Exit : 0 ok / 1 usage / 2 AVTCMD not found / 3 AVTCMD failed +# 4 parse failed (no power fields found) +# +# Note : Values come from SMU telemetry, not direct measurement. Absolute +# accuracy depends on BIOS SVI telemetry calibration. Cross-check +# against VR PMBus READ_POUT when accuracy matters. +#=============================================================================== + +set -u +set -o pipefail + +#------------------------------------------------------------------------------ +# Defaults +#------------------------------------------------------------------------------ +AVTCMD_BIN="${AVTCMD_PATH:-./AVTCMD}" +AVT_MODULE="pmm" +AVT_CMD="get_pmdata()" +QUIET=0 + +#------------------------------------------------------------------------------ +# usage - print help +#------------------------------------------------------------------------------ +usage() { + sed -n '/^# Usage/,/^# Exit/p' "$0" | sed 's/^# \{0,1\}//' +} + +#------------------------------------------------------------------------------ +# Argument parsing +#------------------------------------------------------------------------------ +while getopts ":p:qh" opt; do + case "$opt" in + p) AVTCMD_BIN="$OPTARG" ;; + q) QUIET=1 ;; + h) usage; exit 0 ;; + :) echo "ERROR: -$OPTARG requires an argument" >&2; usage >&2; exit 1 ;; + \?) echo "ERROR: unknown option -$OPTARG" >&2; usage >&2; exit 1 ;; + esac +done + +#------------------------------------------------------------------------------ +# Pre-flight check +#------------------------------------------------------------------------------ +if [ ! -x "$AVTCMD_BIN" ]; then + echo "ERROR: AVTCMD not found or not executable: $AVTCMD_BIN" >&2 + echo " Use -p or export AVTCMD_PATH=" >&2 + exit 2 +fi + +if [ "$(id -u)" -ne 0 ]; then + echo "WARN : not running as root, AVTCMD may fail to access SMU." >&2 +fi + +#------------------------------------------------------------------------------ +# Collect PM table +#------------------------------------------------------------------------------ +RAW="$("$AVTCMD_BIN" -module "$AVT_MODULE" "$AVT_CMD" 2>&1)" +RC=$? +if [ $RC -ne 0 ]; then + echo "ERROR: AVTCMD exited with code $RC" >&2 + echo "$RAW" >&2 + exit 3 +fi + +if [ "$QUIET" -eq 0 ]; then + printf '%s\n' "$RAW" +fi + +#------------------------------------------------------------------------------ +# Parse & summarize +# - split on whitespace and comma, keep only "key:number" tokens +# - bracketed tokens ([Pkg:0], [MISC]) are skipped by the regex anchor +#------------------------------------------------------------------------------ +printf '%s\n' "$RAW" | awk ' +{ + n = split($0, a, /[ ,]+/) + for (i = 1; i <= n; i++) { + if (a[i] ~ /^[A-Za-z0-9_()]+:[-0-9.]+$/) { + split(a[i], kv, ":") + m[kv[1]] = kv[2] + found++ + } + } +} + +# pct - usage against limit, guard divide-by-zero +function pct(v, l) { + return (l > 0) ? sprintf("%5.1f%%", 100 * v / l) : " n/a" +} + +# has - field present in PM table +function has(k) { + return (k in m) +} + +END { + if (found == 0) { + print "ERROR: no PM fields parsed, PM table format may have changed." > "/dev/stderr" + exit 4 + } + + print "===== Package Power (live) =====" + + if (has("SktPwr(W)")) + printf "%-9s: %7.2f W\n", "SktPwr", m["SktPwr(W)"] + + if (has("PPT_VALUE_FAST")) + printf "%-9s: %7.2f / %3d W %s\n", "PPT Fast", + m["PPT_VALUE_FAST"], m["PPT_LIMIT_FAST"], + pct(m["PPT_VALUE_FAST"], m["PPT_LIMIT_FAST"]) + + if (has("PPT_VALUE_SLOW")) + printf "%-9s: %7.2f / %3d W %s (%ss avg)\n", "PPT Slow", + m["PPT_VALUE_SLOW"], m["PPT_LIMIT_SLOW"], + pct(m["PPT_VALUE_SLOW"], m["PPT_LIMIT_SLOW"]), + (has("SlowPPTTimeConstant") ? m["SlowPPTTimeConstant"] : "?") + + if (has("MemPwr(W)")) + printf "%-9s: %7.2f W\n", "MemPwr", m["MemPwr(W)"] +} +' +exit $?