Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
p9-debug/occtoolp9
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
executable file
2331 lines (2174 sloc)
95.4 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# IBM_PROLOG_BEGIN_TAG | |
# This is an automatically generated prolog. | |
# | |
# $Source: src/tools/occtoolp9 $ | |
# | |
# OpenPOWER OnChipController Project | |
# | |
# Contributors Listed Below - COPYRIGHT 2017,2020 | |
# [+] International Business Machines Corp. | |
# | |
# | |
# Licensed under the Apache License, Version 2.0 (the "License"); | |
# you may not use this file except in compliance with the License. | |
# You may obtain a copy of the License at | |
# | |
# http://www.apache.org/licenses/LICENSE-2.0 | |
# | |
# Unless required by applicable law or agreed to in writing, software | |
# distributed under the License is distributed on an "AS IS" BASIS, | |
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | |
# implied. See the License for the specific language governing | |
# permissions and limitations under the License. | |
# | |
# IBM_PROLOG_END_TAG | |
blue="" | |
red="" | |
green="" | |
bold="" | |
normal="" | |
if [ $TERM == "xterm-color" ] || [ $TERM == "xterm" ]; then | |
blue="\033[34;1m"; | |
red="\033[31;1m"; | |
green="\033[32;1m"; | |
bold="\033[1m"; | |
normal="\033[0m"; | |
fi | |
binfile="binary.bin" | |
inputfile="" | |
G_powerArch="p9"; | |
cmd_sram_addr="fffbe000" | |
doorbell_addr="6d035" | |
rsp_sram_addr="fffbf000" | |
poll_version="20" | |
occ_cmd="" | |
occ_cmd_data="" | |
action="" | |
newFlags="" | |
let in_safe=0 | |
let toolkit=0 | |
guidList=() | |
guidListCount=0 | |
bmcRestSystem="" | |
temp_filename="/tmp/${USER}_occtoolp9.tmp"; | |
interface="cronus" | |
if [ -z "$BMCIP" ]; then | |
if [ -n "$BMC_IP_ADDRESS" ]; then | |
BMCIP=$BMC_IP_ADDRESS | |
interface="ipmi" | |
fi | |
else | |
interface="ipmi" | |
fi | |
sudo="" | |
if [ -e /usr/sbin/opal-prd ]; then | |
if [ "$USER" != "root" ]; then | |
sudo="sudo" | |
fi | |
interface="opal" | |
fi | |
function convertToBinary | |
{ | |
infile=$1 | |
outfile=$2 | |
hexStringBuffer="" | |
if [ -n "$outfile" ]; then | |
if [ $verbose -ne 0 ]; then | |
echo "convertToBinary: Reading ${infile}..." | |
fi | |
let skipped_bytes=0 | |
while IFS= read -r line | |
do | |
if [ ${#line} -ge 2 ]; then | |
if [[ "${line}" =~ "~[" ]]; then | |
# Strip off header data | |
#~[0x0000] 07000002 09801003 14010000 00000000 *................* | |
#echo "LINE : $line" | |
strippedLine=`echo $line | sed 's/.*~\[//'` | |
#echo "LINE2: $strippedLine" | |
# strip off offset and only keep hex data | |
strippedLine=`echo ${strippedLine:8:36} | sed 's#\s##g'` | |
#echo "LINE3: $strippedLine" | |
#strippedLine=`echo ${strippedLine:10:36} | sed 's#\s##g'` | |
if [ $skipped_bytes -eq 0 ]; then | |
# Skip response header | |
let rsp_length=0x${strippedLine:6:4} | |
#echo "Rsp Length: $rsp_length" | |
strippedLine="${strippedLine:10}"; | |
let skipped_bytes=5 | |
fi | |
else | |
strippedLine=`echo $line | sed 's#\s##g'` | |
fi | |
#if [ $verbose -ne 0 ]; then | |
# echo "READ: $line / $strippedLine" | |
#fi | |
hexStringBuffer="${hexStringBuffer}$strippedLine" | |
fi | |
done < $infile | |
if [ -e "$outfile" ]; then | |
rm $outfile | |
fi | |
for ((i = 0; i < ${#hexStringBuffer}; i+=2)); do | |
byte="${hexStringBuffer:$i:2}" | |
echo -n -e "\x$byte" >> $outfile | |
done | |
if [ -e "$outfile" ]; then | |
if [ $verbose -ne 0 ]; then | |
echo "Converted $infile to binary: $outfile"; | |
fi | |
fi | |
else | |
echo "ERROR: No output file name specified for convertToBinary" | |
fi | |
} # end convertToBinary() | |
function display_sensor_usage | |
{ | |
echo " Sensor Types: 0xFFFF=All (default)," | |
echo " 0x1=Generic, 0x2=Current, 0x4=Voltage, 0x8=Temperature," | |
echo " 0x10=Utilization, 0x20=Time, 0x40=Frequency, 0x80=Power," | |
echo " 0x200=Performance, 0x400=WOF" | |
echo " Sensor Locations: 0xFFFF=All (default)," | |
echo " 0x1=System, 0x2=Processor, 0x4=Partition, 0x8=Memory," | |
echo " 0x10=VRM, 0x20=OCC 0x40=Core, 0x80=GPU, 0x100==Quad" | |
} | |
function usage | |
{ | |
echo "Usage: occtoolp9 <options> <command>" | |
echo " OCC Debug Tool (via opal-prd or CRONUS)" | |
echo "" | |
echo " commands:" | |
echo " -h = help" | |
echo " -p = Send POLL command to the OCC" | |
echo " -X CC DDDDDD... = Send CC command to the OCC with specified cmd data (all data in hex)" | |
# echo " -X 53 0500000001LLLLTTTT = list first 50 OCC sensors (LLLL=Location,TTTT=Type)" | |
# echo " -X 53 0600003d = get sensor details for GUID 0x003d" | |
echo " -S TYPE=0xTT,LOC=0xLL = List full details for specified sensors (type and/or location are optional)" | |
echo " -S type=0xTT,loc=0xLL = List cur/min/max for specified sensors (type and/or location are optional)" | |
display_sensor_usage | |
echo " -S guid=0xGGGG = Get sensor details for specified GUID" | |
echo " -SL = List all OCC sensors" | |
echo " -SL0 = List all OCC sensors (including sensors with 0 readings)" | |
echo " -SCLEAR = Clear min/max for all OCC sensors" | |
echo " -trace Collect OCC Trace hex data (use -TRACE when using non-binary GPE code)" | |
echo " -s stringFile = specify string file for parsing traces (CRONUS only)" | |
echo " -wof Display WOF status" | |
echo "" | |
echo " OPAL-PRD Only Commands:" | |
echo " -I = HTMGT info" | |
echo " -IF <newValue> = Read/Set HTMGT internalFlags" | |
echo " -ES = Attempt to Exit Safe mode" | |
echo " -W = Get WOF reset reasons for ALL OCCs" | |
echo "" | |
echo " CRONUS Only Commands:" | |
echo " -P = Send POLL command to the OCC and collect/purge any elog, if found" | |
echo " -CMDRSP = Dump OCC Command/Response buffers from SRAM" | |
echo "" | |
echo " options:" | |
# echo " -b <BMC-ip-address> = send poll via IPMI/BMC" | |
# echo " address is optional if BMCIP is set" | |
echo " -o # = send command to OCC# (default 0)" | |
echo " -v = verbose (dump raw data)" | |
# echo " -f <filename> = parse response from specified filename" | |
# echo " -A = force IPMI userid of admin (vs ADMIN)" | |
# echo " -SM = use ADMIN/ADMIN (SuperMicro default)" | |
# echo " -pw BMC_PW = specified BMC password" | |
echo " -pt = parse OCC response w/o seq/cmd/rsp/len/csum (from opal-prd passthru or syslog)" | |
# echo " -oldbmc = send IPMI cmds without OCC instance number (prior to Aug 2015)" | |
echo " -nocolor = skip highlighting" | |
echo " -ch # = which cronus channel to use (default is 3)" | |
echo "" | |
# echo " TODO:" | |
# echo " -OF OCC FFDC" | |
echo " Last update 1/30/2020" # TODO: update on commit | |
exit 0 | |
} | |
bmc=""; | |
let verbose=0 | |
quiet="-quiet" | |
let purge=0 | |
# Default OCC/Processor | |
let occ=0 | |
let node=0 | |
let bmcFound=0 | |
number=$RANDOM | |
let "number %= 126" | |
let number=$number+1 | |
sequence=$(printf "%02x" $number) | |
let seqMismatch=0 | |
let channel=3 | |
let only_non_zero_sensors=1 | |
let skip_header=0 | |
let sensor_summary=0 | |
let use_gpe_string=1 | |
string_file="" | |
if [ -n "$bmcId" ]; then | |
bmcId="$bmcId" | |
elif [ -n "$adminId" ]; then | |
bmcId="$adminId" | |
else | |
bmcId="ADMIN" | |
fi | |
if [ -n "$bmcPw" ]; then | |
bmcPw="$bmcPw" | |
else | |
bmcPw="admin" | |
fi | |
let sendOccInstance=1 | |
let sensor_type=0xFFFF # all types | |
let sensor_loc=0xFFFF # all locations | |
let sensor_guid=0xFFFF | |
let passThru=0 | |
while [ -n "$(echo $1 | grep '-')" ]; do | |
case $1 in | |
#### COMMANDS: | |
-h ) usage; exit 0;; | |
-p ) occ_cmd="00" | |
occ_cmd_data=$poll_version | |
;; | |
-s ) | |
shift | |
if [ -s "$1" ]; then | |
string_file="$1" | |
else | |
echo "ERROR: -s option requires occStringFile location" | |
exit 16 | |
fi | |
;; | |
-S ) | |
shift | |
if [[ "$1" =~ "type=" ]] || [[ "$1" =~ "loc=" ]] || | |
[[ "$1" =~ "TYPE=" ]] || [[ "$1" =~ "LOC=" ]]; then | |
if [[ "$1" =~ "type=" ]]; then | |
let sensor_type=${1#*type=}; | |
fi | |
if [[ "$1" =~ "loc=" ]]; then | |
let sensor_loc=${1##*loc=}; | |
fi | |
if [[ "$1" =~ "TYPE=" ]]; then | |
let sensor_type=${1#*TYPE=}; | |
action="SensorList" # display full sensor data (slower) | |
fi | |
if [[ "$1" =~ "LOC=" ]]; then | |
let sensor_loc=${1##*LOC=}; | |
action="SensorList" # display full sensor data (slower) | |
fi | |
# If user specified type/loc then list all sensors | |
let only_non_zero_sensors=0 | |
if [ -z "$action" ]; then | |
occ_cmd="40" # DEBUG_PASS_THROUGH | |
occ_cmd_data=$(printf "07%04X%04X" $sensor_type $sensor_loc) # GET_AME_SENSOR | |
fi | |
elif [[ "$1" =~ "guid=" ]]; then | |
action="SensorDump" | |
let sensor_guid=${1#*guid=}; | |
elif [[ "$1" =~ "GUID=" ]]; then | |
action="SensorDump" | |
let sensor_summary=1 | |
let skip_header=1 | |
let sensor_guid=${1#*guid=}; | |
else | |
echo "ERROR: -S option requires Type/Location (-S type=0xFF,loc=0xFF)" | |
display_sensor_usage | |
exit 13 | |
fi | |
;; | |
-SL ) | |
action="SensorList" | |
;; | |
-SL0 ) | |
action="SensorList" | |
let only_non_zero_sensors=0 | |
;; | |
-SCLEAR ) | |
action="SensorClear" | |
;; | |
-tk ) | |
let toolkit=1 | |
let channel=2 | |
;; | |
-trace ) | |
action="trace" | |
;; | |
-TRACE ) | |
let use_gpe_string=0 | |
action="trace" | |
;; | |
-wof ) | |
occ_cmd="40" # DEBUG_PASS_THROUGH | |
occ_cmd_data="01" # WOF Data Structure | |
;; | |
-X ) | |
if [ -n "$2" ] && [ "${2:0:1}" != "-" ] && ( [ ${#2} -eq 2 ] || [ ${#2} -eq 4 ] ); then | |
shift | |
if [ "${1:0:2}" == "0x" ]; then | |
occ_cmd="${1:2:2}" | |
else | |
occ_cmd="$1" | |
fi | |
if [ -n "$2" ] && [ "${2:0:1}" != "-" ]; then | |
# Command Data | |
shift | |
let odd_length="${#1} & 1" | |
if [ $odd_length -eq 0 ]; then | |
if [ "${1:0:2}" == "0x" ]; then | |
occ_cmd_data="${1:2}" | |
else | |
occ_cmd_data="$1" | |
fi | |
else | |
echo -e "${red}ERROR: OCC command data must be even number of HEX digits (${#1} specified)${normal}" | |
exit 12 | |
fi | |
fi | |
else | |
echo -e "${red}ERROR: -X requires 2 byte command (in HEX)${normal}" | |
exit 12 | |
fi | |
;; | |
#### OPAL-PRD ONLY COMMANDS/OPTIONS: | |
-ES ) | |
action="ExitSafe" | |
;; | |
-I ) | |
action="TMGTInfo" | |
;; | |
-W ) | |
action="WOFRR" | |
;; | |
-IF ) | |
action="TMGTFlags" | |
if [ -n "$2" ]; then | |
let newFlags=$2 | |
fi | |
;; | |
#### CRONUS ONLY COMMANDS/OPTIONS: | |
-ch ) | |
if [ -n "$2" ]; then | |
let channel=$2 | |
shift; | |
else | |
echo -e "${red}ERROR: -ch requires channel number${normal}" | |
exit 13 | |
fi | |
;; | |
-CMDRSP ) | |
if [ "$interface" == "cronus" ]; then | |
action="CmdRspBuffer" | |
else | |
echo "ERROR: -CMDRSP only supported via CRONUS" | |
exit 1 | |
fi | |
;; | |
-P ) occ_cmd="00" | |
occ_cmd_data=$poll_version | |
let purge=1 | |
;; | |
### OPTIONS: | |
-A ) bmcId="admin" | |
;; | |
-b ) | |
if [ -z "$2" ] || [ "`echo $2 | cut -c1`" == "-" ]; then | |
if [ "$BMCIP" != "" ]; then | |
bmc=$BMCIP | |
interface="ipmi" | |
else | |
echo -e "${red}ERROR: -b requires BMCIP${normal}" | |
exit 12 | |
fi | |
else | |
bmc=$2 | |
interface="ipmi" | |
shift | |
fi | |
if [ $verbose -ne 0 ]; then | |
echo "BMC: $bmc"; | |
fi | |
;; | |
-B ) | |
if [ -z "$2" ] || [ "`echo $2 | cut -c1`" == "-" ]; then | |
if [ "$BMCIP" != "" ]; then | |
bmc=$BMCIP | |
bmcRestSystem="root:0penBmc@$bmc" | |
interface="rest" | |
else | |
echo -e "${red}ERROR: -B requires system info: uid:pw@systemnameORip${normal}" | |
exit 13 | |
fi | |
else | |
bmcRestSystem="$2" | |
bmc="${bmcRestSystem/*@}" | |
interface="rest" | |
shift | |
fi | |
if [ $verbose -ne 0 ]; then | |
echo "BMC: $bmc"; | |
echo "BMC Rest Authentication: $bmcRestSystem"; | |
fi | |
;; | |
-f ) | |
if [ -n "$2" ] && [ -e "$2" ]; then | |
inputfile="$2" | |
shift | |
else | |
echo -e "${red}ERROR: -f requires a input filename${normal}" | |
exit -2; | |
fi;; | |
-nocolor ) blue=""; red=""; green=""; bold=""; normal="" | |
;; | |
-o ) | |
if [ -z "$2" ] || [ "`echo $2 | cut -c1`" == "-" ]; then | |
echo -e "${red}ERROR: -o requires OCC instance number${normal}" | |
exit 13 | |
else | |
let occ=$2 | |
shift | |
fi;; | |
-oldbmc ) let sendOccInstance=0 | |
;; | |
-pt ) let passThru=1 | |
;; | |
-pw ) | |
if [ -n "$2" ]; then | |
bmcPw="$2" | |
shift | |
else | |
echo -e "${red}ERROR: -pw requires BMC password${normal}" | |
exit 13 | |
fi | |
;; | |
-SM ) bmcPw="ADMIN" | |
;; | |
-v ) let verbose=1; quiet="" | |
;; | |
* ) echo -e "${red}ERROR: unknown option $1${normal}"; exit 1 | |
;; | |
esac | |
shift | |
done | |
#echo "OCC${occ}, BMC: ${bmc}, purge=$purge, verbose=$verbose" | |
# Force Call Home: ipmitool -H 9.3.29.129 -I lanplus -U admin -P admin raw 0x3a 0x0d 0x40 0x24 | |
# For Error w/Reset (pmc failure): putscom pu 1010842 1000000000180000 -p0 | |
function sendOccCmdRest | |
{ | |
let cmd=0x$1 | |
data=$2 | |
let cmd_data_length=${#data}/2 | |
for ((i = 0; i < ${#data}; i+=2)); do | |
let byte=0x${occ_cmd_data:$i:2} | |
if [ $i -eq 0 ]; then | |
cmd_data_string="${byte}" | |
else | |
cmd_data_string="${cmd_data_string},${byte}" | |
fi | |
done | |
outName="/tmp/occ_cmd.txt" | |
if [ -z "$inputfile" ]; then | |
if [ -e "${outName}" ]; then | |
if [ $verbose -ne 0 ]; then | |
echo "--> removing ${outName}" | |
fi | |
rm ${outName} | |
fi | |
#if [ $verbose -ne 0 ]; then | |
#echo -e "${bold}==> ipmitool -H $bmc -I lanplus -U $bmcId -P $bmcPw raw 0x3a 0x0d ${occInstance} 0x00 0x10${normal}" | |
#fi | |
#ipmitool -H $bmc -I lanplus -U $bmcId -P $bmcPw raw 0x3a 0x0d ${occInstance} 0x00 0x10 > ${outName} | |
# -s = silent (no progress info) | |
# -k = insecure | |
echo -e "${bold}==> curl -k https://${bmcRestSystem}/org/open_power/control/enumerate${normal}" | |
curl -s -k https://${bmcRestSystem}/org/open_power/control/enumerate | grep -e occ -e Active | |
echo -e "${bold}==> curl -k -X POST -d '{\"data\": [[${cmd},$(($cmd_data_length>>8)),$(($cmd_data_length&0xFF)),${cmd_data_string}']]}' https://${bmcRestSystem}/org/open_power/control/occ${occ}/action/Send" | |
curl -s -k -X POST -d '{"data": [['${cmd}','$(($cmd_data_length>>8))','$(($cmd_data_length&0xFF))','${cmd_data_string}']]}' https://${bmcRestSystem}/org/open_power/control/occ${occ}/action/Send > ${outName} | |
#echo "#####2222" | |
#curl -k -X POST -d '{"data": [[0,0,1,32]]}' https://${bmcRestSystem}/org/open_power/control/occ0/action/Send | |
let rc=$? | |
else | |
outName="$inputfile" | |
echo "grep -q 'opal-prd: HBRT: HTMGT:' $inputfile" | |
grep -q 'opal-prd: HBRT: HTMGT:' $inputfile | |
if [ $? -eq 0 ]; then | |
echo "Converting $inputfile" | |
# Convert opal-prd poll rsp to "XX XX XX XX" format | |
cat $inputfile | sed 's/.*HBRT: HTMGT:.*\] //' | sed 's/ .*//' | sed 's/ //g' | sed 's/\(..\)/\1 /g' > ${inputfile}.filtered | |
else | |
cat $inputfile | sed 's/ //g' | sed 's/\(..\)/\1 /g' > ${inputfile}.filtered | |
fi | |
if [ -s "${inputfile}.filtered" ]; then | |
outName="${inputfile}.filtered" | |
fi | |
echo -e "${bold}==> Reading data from ${outName}${normal}" | |
let rc=0; | |
fi | |
if [ $verbose -ne 0 ]; then | |
echo "--> cat ${outName}" | |
cat ${outName} | |
#let occRspLength=`wc -w ${outName} | awk '{print $1}'` | |
#echo "<-- $occRspLength bytes" | |
fi | |
if [ $rc -ne 0 ]; then | |
echo -e "${red}ERROR: failed sending POLL to OCC via IPMI/BMC (rc=$rc)${normal}" | |
exit 8 | |
fi | |
if [ -e "${outName}" ]; then | |
options="" | |
if [ $verbose -eq 0 ]; then | |
options="-q" | |
fi | |
# TODO: Convert to BINARY: | |
#{ | |
# "data": [ | |
# 1, | |
# 0, | |
# 0, | |
# 2, | |
# 239, | |
#... | |
# 255, | |
# 0, | |
# 0, | |
# 82, | |
# 213 | |
# ], | |
# "message": "200 OK", | |
# "status": "ok" | |
#} | |
if [ -e "${outName}.bin" ]; then | |
binfile="${outName}.bin" | |
else | |
echo -e "${red}ERROR: ${outName}.bin not found...${normal}" | |
exit 7 | |
fi | |
else | |
echo -e "${red}ERROR: ${outName} not found...${normal}" | |
exit 9 | |
fi | |
} # end sendOccCmdRest() | |
function sendOccCmdIpmi | |
{ | |
let bmcOccInstance=$occ+1 | |
outName="/tmp/occ_cmd.txt" | |
if [ -z "$inputfile" ]; then | |
if [ -e "${outName}" ]; then | |
if [ $verbose -ne 0 ]; then | |
echo "--> removing ${outName}" | |
fi | |
rm ${outName} | |
fi | |
if [ $sendOccInstance -ne 0 ]; then | |
occInstance=$(printf "0x%02x" $bmcOccInstance) | |
else | |
occInstance="" | |
fi | |
#if [ $verbose -ne 0 ]; then | |
echo -e "${bold}==> ipmitool -H $bmc -I lanplus -U $bmcId -P $bmcPw raw 0x3a 0x0d ${occInstance} 0x00 0x10${normal}" | |
#fi | |
ipmitool -H $bmc -I lanplus -U $bmcId -P $bmcPw raw 0x3a 0x0d ${occInstance} 0x00 0x10 > ${outName} | |
let rc=$? | |
else | |
outName="$inputfile" | |
echo "grep -q 'opal-prd: HBRT: HTMGT:' $inputfile" | |
grep -q 'opal-prd: HBRT: HTMGT:' $inputfile | |
if [ $? -eq 0 ]; then | |
echo "Converting $inputfile" | |
# Convert opal-prd poll rsp to "XX XX XX XX" format | |
cat $inputfile | sed 's/.*HBRT: HTMGT:.*\] //' | sed 's/ .*//' | sed 's/ //g' | sed 's/\(..\)/\1 /g' > ${inputfile}.filtered | |
else | |
cat $inputfile | sed 's/ //g' | sed 's/\(..\)/\1 /g' > ${inputfile}.filtered | |
fi | |
if [ -s "${inputfile}.filtered" ]; then | |
outName="${inputfile}.filtered" | |
fi | |
echo -e "${bold}==> Reading data from ${outName}${normal}" | |
let rc=0; | |
fi | |
if [ $verbose -ne 0 ]; then | |
echo "--> cat ${outName}" | |
cat ${outName} | |
#let occRspLength=`wc -w ${outName} | awk '{print $1}'` | |
#echo "<-- $occRspLength bytes" | |
fi | |
if [ $rc -ne 0 ]; then | |
echo -e "${red}ERROR: failed sending POLL to OCC via IPMI/BMC (rc=$rc)${normal}" | |
exit 8 | |
fi | |
if [ -e "${outName}" ]; then | |
options="" | |
if [ $verbose -eq 0 ]; then | |
options="-q" | |
fi | |
if [ -e "${outName}.bin" ]; then | |
binfile="${outName}.bin" | |
else | |
echo -e "${red}ERROR: ${outName}.bin not found...${normal}" | |
exit 7 | |
fi | |
else | |
echo -e "${red}ERROR: ${outName} not found...${normal}" | |
exit 9 | |
fi | |
} # end sendOccCmdIpmi() | |
function send_occ_cmd | |
{ | |
#if [ -z "$bmc" ] && [ -z "$inputfile" ] && [ -n "$occ_cmd" ]; then | |
# Clean up rsp file if still exists | |
if [ -e "${binfile}" ]; then | |
rm -f ${binfile} | |
fi | |
let cmd_data_length=${#occ_cmd_data}/2 | |
let csum=0x"$sequence"+0x$occ_cmd+$cmd_data_length; # seq# + cmd + length | |
if [ "$interface" == "cronus" ]; then | |
if [ $sensor_summary -eq 0 ]; then | |
echo -e "${blue}Sending 0x$occ_cmd command to OCC${occ} w/$cmd_data_length bytes of data (via cronus)...${normal}" | |
fi | |
# First, store the command in command buffer in SRAM | |
#TODO: Checksums for lengths > 255 bytes!! | |
if [ $cmd_data_length -gt 0 ]; then | |
for ((i = 0; i < ${#occ_cmd_data}; i+=2)); do | |
let byte=0x${occ_cmd_data:$i:2} | |
let csum=$csum+$byte | |
done | |
fi | |
cmdString=`printf "%s%s%04X${occ_cmd_data}%04X" $sequence $occ_cmd $cmd_data_length $csum` | |
if [ $verbose -ne 0 ]; then | |
echo -e "${bold}==> putsram $cmd_sram_addr ${cmdString} -p${occ} -ch $channel $quiet (write $occ_cmd command to OCC SRAM)${normal}" | |
fi | |
putsram $cmd_sram_addr ${cmdString} -p${occ} -ch $channel $quiet | |
let rc=$? | |
if [ $rc -ne 0 ]; then | |
echo -e "${red}ERROR: failed writing $occ_cmd command to OCC SRAM (rc=$rc)${normal}" | |
echo -e "${bold}==> getsram $rsp_sram_addr 128 -all -ch $channel $quiet (read OCC rsp buffer from SRAM)${normal}" | |
getsram $rsp_sram_addr -ch 3 128 -all | |
exit 1; | |
fi | |
# Second, send a doorbell to OCC | |
if [ $verbose -ne 0 ]; then | |
echo -e "${bold}==> putscom pu $doorbell_addr 0101000000000000 -p${occ} $quiet (send doorbell to OCC)${normal}" | |
fi | |
putscom pu $doorbell_addr 0101000000000000 -p${occ} $quiet | |
let rc=$? | |
if [ $rc -ne 0 ]; then | |
echo -e "${red}ERROR: failed sending doorbell to OCC (rc=$rc)${normal}" | |
fi | |
# Third, collect response from response buffer in SRAa | |
if [ $verbose -ne 0 ]; then | |
echo -e "${bold}==> getsram $rsp_sram_addr 1024 -p${occ} -ch $channel $quiet (read POLL response from SRAM)${normal}" | |
fi | |
getsram $rsp_sram_addr 1024 -p${occ} -ch $channel $quiet -fb ${binfile} | |
let rc=$? | |
if [ $rc -ne 0 ]; then | |
echo -e "${red}ERROR: failed reading POLL response from SRAM (rc=$rc)${normal}" | |
exit 2; | |
fi | |
elif [ "$interface" == "opal" ]; then | |
if [ $sensor_summary -eq 0 ]; then | |
echo -e "${blue}Sending 0x$occ_cmd command to OCC${occ} w/$cmd_data_length bytes of data (via opal-prd)...${normal}" | |
fi | |
# First, store the command in command buffer in SRAM | |
opal_occ_cmd_data=`printf "0x%02X 0x%s" $occ $occ_cmd` | |
if [ $cmd_data_length -gt 0 ]; then | |
for ((i = 0; i < ${#occ_cmd_data}; i+=2)); do | |
let byte=0x${occ_cmd_data:$i:2} | |
opal_occ_cmd_data=`printf "%s 0x%02X" "$opal_occ_cmd_data" $byte` | |
done | |
fi | |
if [ $verbose -ne 0 ]; then | |
echo -e "${bold}==> $sudo opal-prd --expert-mode htmgt-passthru 0x03 $opal_occ_cmd_data${normal}" | |
fi | |
rsp_file="/tmp/occtoolp9_rsp.txt" | |
$sudo opal-prd --expert-mode htmgt-passthru 0x03 $opal_occ_cmd_data | sed 's/\s//g' > $rsp_file | |
# get status of first cmd in piped cmdline | |
let rc=${PIPESTATUS[0]} | |
#let rc=$? | |
if [ $rc -ne 0 ]; then | |
echo -e "${red}ERROR: opal-prd passthrough failed sending $occ_cmd command to OCC$occ (rc=$rc)${normal}" | |
if [ -e /var/log/syslog ]; then | |
echo "==> tail /var/log/syslog" | |
$sudo tail /var/log/syslog | |
fi | |
exit 30 | |
else | |
#echo "Parsing poll data:" | |
#./occ_poll -pt -f /tmp/htmgt.bin | |
if [ $verbose -ne 0 ]; then | |
echo "Converting $rsp_file to $binfile..." | |
fi | |
convertToBinary $rsp_file $binfile | |
fi | |
elif [ "$interface" == "rest" ]; then | |
echo -e "${blue}Polling OCC${occ} (via BMC/REST)...${normal}" | |
sendOccCmdRest $occ_cmd $occ_cmd_data | |
else | |
if [ -z "$inputfile" ]; then | |
echo -e "${blue}Polling OCC${occ} (via BMC/IPMI)...${normal}" | |
sendOccCmdIpmi | |
fi | |
fi | |
} # end send_occ_cmd() | |
function parse_rsp_poll | |
{ | |
# Response Data | |
let rstatus="0x`hexdump -s $offset -n 1 -e '"%02X"' ${binfile}`" | |
flags=""; | |
let bitset="$rstatus & 0x80"; | |
if [ $bitset -ne 0 ]; then flags=" Master"; fi | |
let bitset="$rstatus & 0x40"; | |
if [ $bitset -ne 0 ]; then flags="$flags CollectFIR"; fi | |
let bitset="$rstatus & 0x10"; | |
if [ $bitset -ne 0 ]; then flags="$flags OCCPmcrOwner"; fi | |
let bitset="$rstatus & 0x08"; | |
if [ $bitset -ne 0 ]; then flags="$flags SIMICS"; fi | |
let bitset="$rstatus & 0x02"; | |
if [ $bitset -ne 0 ]; then flags="$flags ObsReady"; fi | |
let bitset="$rstatus & 0x01"; | |
if [ $bitset -ne 0 ]; then flags="$flags ActReady"; fi | |
if [ -n "$flags" ]; then flags="($flags)"; fi | |
printf " Status: 0x%02X $flags\n" $rstatus | |
let offset=$offset+1 | |
let xstatus="0x`hexdump -s $offset -n 1 -e '"%02X"' ${binfile}`" | |
flags="" | |
let bitset="$xstatus & 0x80"; | |
if [ $bitset -ne 0 ]; then flags=" DVFS-OT"; fi | |
let bitset="$xstatus & 0x40"; | |
if [ $bitset -ne 0 ]; then flags="$flags DVFS-power"; fi | |
let bitset="$xstatus & 0x20"; | |
if [ $bitset -ne 0 ]; then flags="$flags MemThrottle-OT"; fi | |
let bitset="$xstatus & 0x10"; | |
if [ $bitset -ne 0 ]; then flags="$flags QckPwrDrop"; fi | |
let bitset="$xstatus & 0x08"; | |
if [ $bitset -ne 0 ]; then flags="$flags DVFS-Vdd-OT"; fi | |
if [ -n "$flags" ]; then | |
flags="($flags )"; | |
echo -en "$bold"; | |
fi | |
printf " ExtStatus: 0x%02X $flags\n" $xstatus | |
echo -en "$normal"; | |
let offset=$offset+1 | |
hexdump -s $offset -n 1 -e '" OCCs: 0x%02X\n"' ${binfile} | |
let offset=$offset+1 | |
hexdump -s $offset -n 1 -e '" CfgNeed: 0x%02X\n"' ${binfile} | |
let offset=$offset+1 | |
let state="0x`hexdump -s $offset -n 1 -e '"%02X"' ${binfile}`" | |
flags="UNKNOWN"; | |
if [ $state -eq 1 ]; then flags="STANDBY"; | |
elif [ $state -eq 2 ]; then flags="OBSERVATION"; | |
elif [ $state -eq 3 ]; then flags="ACTIVE"; | |
elif [ $state -eq 4 ]; then | |
flags="SAFE"; | |
echo -en "$red"; | |
elif [ $state -eq 5 ]; then flags="CHARACTERIZATION"; | |
fi | |
printf " State: 0x%02X ($flags)\n" $state | |
echo -en "$normal"; | |
let offset=$offset+1 | |
hexdump -s $offset -n 2 -e '" reserved: 0x" 2/1 "%02X" "\n"' ${binfile} | |
let offset=$offset+2 | |
let elogId=0x`hexdump -s $offset -n 1 -e '1/1 "%02X"' ${binfile}` | |
if [ $elogId -ne 0 ]; then | |
echo -en "$red"; | |
fi | |
printf " ElogID: 0x%02X\n" $elogId | |
let offset=$offset+1 | |
let elogAddr="0x`hexdump -s $offset -n 4 -e '4/1 "%02X"' ${binfile}`" | |
printf " ElogAddr: 0x%08X\n" $elogAddr | |
let offset=$offset+4 | |
let elogLen="0x`hexdump -s $offset -n 2 -e '2/1 "%02X"' ${binfile}`" | |
printf " Elog Len: 0x%04X\n" $elogLen | |
let offset=$offset+2 | |
echo -en "$normal"; | |
hexdump -s $offset -n 1 -e '" Elog Source: 0x%02X\n"' ${binfile} | |
let offset=$offset+1 | |
hexdump -s $offset -n 1 -e '" GPU config: 0x%02X\n"' ${binfile} | |
let offset=$offset+1 | |
if [ $occRspLength -gt 17 ]; then | |
hexdump -s $offset -n 16 -e '" Code Level: " 16 "%_p" "\n"' ${binfile} | |
let offset=$offset+16 | |
hexdump -s $offset -n 6 -e '" Sensor Tag: " 6 "%_p" "\n"' ${binfile} | |
let offset=$offset+6 | |
if [ $occRspLength -gt 39 ]; then | |
#let offset=43 | |
let numSensorBlocks="0x`hexdump -s $offset -n 1 -e '4/1 "%02X"' ${binfile}`" | |
echo "Sensor Blocks: $numSensorBlocks" | |
let offset=$offset+1 | |
let sensorVers="0x`hexdump -s $offset -n 1 -e '4/1 "%02X"' ${binfile}`" | |
echo " Sensor Vers: $sensorVers" | |
let offset=$offset+1 | |
if [ $verbose -ne 0 ]; then | |
echo "Raw Sensor Data:" | |
hexdump -C -s $offset ${binfile} | |
fi | |
while [ $numSensorBlocks -gt 0 ]; do | |
sensor="`hexdump -s $offset -n 4 -e '4/1 "%_u"' ${binfile}`" | |
let offset=$offset+5 | |
let sensorFormat="0x`hexdump -s $offset -n 1 -e '4/1 "%02X"' ${binfile}`" | |
let offset=$offset+1 | |
let sensorLength="0x`hexdump -s $offset -n 1 -e '4/1 "%02X"' ${binfile}`" | |
let offset=$offset+1 | |
let numSensors="0x`hexdump -s $offset -n 1 -e '4/1 "%02X"' ${binfile}`" | |
let offset=$offset+1 | |
# TEMP: degrees C, FREQ: MHz, POWR: 4Byte tag, 4Byte accumulator, 2Byte current reading | |
echo -e " ${bold}Sensor: $sensor - format:$sensorFormat / $numSensors sensors ($sensorLength bytes/sensor)${normal}" | |
indent=" "; | |
if [ $G_powerArch == "p9" ]; then | |
if [ "$sensor" == "TEMP" ]; then | |
echo "$indent SSSSSSSS FF TT (SSSS = Sensor ID, FF is FRU type, TT is temp in C)"; | |
elif [ "$sensor" == "FREQ" ]; then | |
echo "$indent SSSSSSSS FFFF (SSSS = Sensor ID, FFFF is freq in MHz)"; | |
elif [ "$sensor" == "POWR" ]; then | |
if [ $sensorFormat -ne $((0xA0)) ]; then | |
echo "$indent SSSSSSSS FF CH rrrr TTTTTTTT AAAAAAAAAAAAAAAA CCCC (SS=Sensor ID, FF=Function ID," | |
echo " CH=APSS Channel, TT=Update Tag, AA=Accumulator, CC=current reading (W)" | |
else | |
echo "$indent SSSSSSSS UUUU CCCC TTTTTTTT AAAAAAAAAAAAAAAA (SS=Sensor ID," | |
echo " UU=Update Time (us), CC=current reading (W), TT=Update Tag, AA=Accumulator)" | |
fi | |
elif [ "$sensor" == "EXTN" ]; then | |
echo "$indent NNNNNNNN FF 00 DDDDDDDDDDDD (NNNN = Name/Sensor ID, FF is flags, DDDD is value)"; | |
fi | |
else | |
#p8 | |
if [ "$sensor" == "TEMP" ]; then | |
echo "$indent SSSS TTTT (SSSS = Sensor ID, TTTT is temp in C)"; | |
elif [ "$sensor" == "FREQ" ]; then | |
echo "$indent SSSS FFFF (SSSS = Sensor ID, FFFF is freq in MHz)"; | |
elif [ "$sensor" == "POWR" ]; then | |
echo "$indent SSSS TTTTTTTT AAAAAAAA CCCC (SS = Sensor ID, TT = Update Tag"; | |
echo " AA = Accumulator, CC = current reading in Watts)"; | |
fi | |
fi | |
while [ $numSensors -gt 0 ]; do | |
if [ $G_powerArch == "p9" ]; then | |
#hexdump -s $offset -n $sensorLength -e '" " 16/1 "%02X" "\n"' ${binfile} | |
if [ "$sensor" == "TEMP" ]; then | |
#hexdump -s $offset -n $sensorLength -e '"=0x" 2/1 "%02X" " "1/2 "%d" "\n"' ${binfile} | |
#hexdump -s $offset -n $sensorLength -e '" " 4/1 "%02X" " " 1/1 "%02X" " " 1/1 "%02X""\n"' ${binfile} | |
for ((i = 0; i < $sensorLength; i+=6)); do | |
let index=$offset+$i | |
sensor_id=`hexdump -s $index -n 4 -e '4/1 "%02X"' ${binfile}`; | |
let index+=4 | |
let fru_type=0x`hexdump -s $index -n 1 -e '1/1 "%02X"' ${binfile}`; | |
get_fru_string $fru_type | |
let index+=1 | |
let value=0x`hexdump -s $index -n 1 -e '1/1 "%02X"' ${binfile}`; | |
printf " $sensor_id %02X %02X " $fru_type $value; | |
if [ $fru_type -eq 3 ]; then # vrm ot | |
if [ $value -eq 0 ]; then | |
printf "(VRM not over-temperature)\n" $fru_type $value; | |
else | |
printf "(VRM Over-Temperature)\n" $fru_type $value; | |
fi | |
else | |
if [ $value -eq 0 ]; then | |
printf "(N/A %s)\n" $fru_string; | |
elif [ $value -ne $((0xFF)) ]; then | |
printf "(%2dC %s)\n" $value $fru_string; | |
else | |
printf "(ERROR)\n" $fru_type $value; | |
fi | |
fi | |
done | |
elif [ "$sensor" == "FREQ" ]; then | |
#hexdump -s $offset -n $sensorLength -e '" " 4/1 "%02X" " " 2/1 "%02X" "\n"' ${binfile} | |
for ((i = 0; i < $sensorLength; i+=6)); do | |
let index=$offset+$i | |
sensor_id=`hexdump -s $index -n 4 -e '4/1 "%02X"' ${binfile}`; | |
let index+=4 | |
let value=0x`hexdump -s $index -n 2 -e '2/1 "%02X"' ${binfile}`; | |
printf " $sensor_id %04X" $value; | |
if [ $value -ne 0 ]; then | |
printf " (%dMHz)\n" $value; | |
else | |
printf "\n"; | |
fi | |
done | |
elif [ "$sensor" == "POWR" ]; then | |
if [ $sensorFormat -ne $((0xA0)) ]; then | |
#hexdump -s $offset -n $sensorLength -e '" " 4/1 "%02X" " " 1/1 "%02X" " " 1/1 "%02X" " " 2/1 "%02X" " " 4/1 "%02X" " " 8/1 "%02X" " " 2/1 "%02X" "\n"' ${binfile} | |
pwr="`hexdump -s $offset -n 22 -e '4/1 "%02X" " " 1/1 "%02X" " " 1/1 "%02X" " " 2/1 "%02X" " " 4/1 "%02X" " " 8/1 "%02X" " " 2/1 "%02X"' ${binfile}`" | |
let func=0x${pwr:9:2} | |
get_function_id $func | |
printf " $pwr $funcid_name\n"; | |
else | |
# APSS-less | |
let reading_offset=$offset+6 | |
let power="0x`hexdump -s $reading_offset -n 2 -e '2/1 "%02X"' ${binfile}`"; | |
hexdump -s $offset -n 20 -e '" System: " 4/1 "%02X" " " 2/1 "%02X" " " 2/1 "%02X" " " 4/1 "%02X" " " 8/1 "%02X" " ('$power' W)\n"' ${binfile} | |
let power_offset=$offset+20 | |
let reading_offset=$power_offset+6 | |
let power="0x`hexdump -s $reading_offset -n 2 -e '2/1 "%02X"' ${binfile}`"; | |
hexdump -s $power_offset -n 20 -e '" Processor: " 4/1 "%02X" " " 2/1 "%02X" " " 2/1 "%02X" " " 4/1 "%02X" " " 8/1 "%02X" " ('$power' W)\n"' ${binfile} | |
let power_offset=$power_offset+20 | |
let power="0x`hexdump -s $power_offset -n 2 -e '2/1 "%02X"' ${binfile}`"; | |
hexdump -s $power_offset -n 14 -e '" Vdd: " 2/1 "%02X" " " 4/1 "%02X" " " 8/1 "%02X" " ('$power' W)\n"' ${binfile} | |
let power_offset=$power_offset+14 | |
let power="0x`hexdump -s $power_offset -n 2 -e '2/1 "%02X"' ${binfile}`"; | |
hexdump -s $power_offset -n 14 -e '" Vdn: " 2/1 "%02X" " " 4/1 "%02X" " " 8/1 "%02X" " ('$power' W)\n"' ${binfile} | |
fi | |
elif [ "$sensor" == "CAPS" ]; then | |
let capoffset=$offset | |
let pcap="0x`hexdump -s $capoffset -n 2 -e '4/1 "%02X"' ${binfile}`"; | |
let capoffset+=2 | |
printf "$indent Current Power Cap: %6d Watts\n" $pcap; | |
let pcap="0x`hexdump -s $capoffset -n 2 -e '4/1 "%02X"' ${binfile}`"; | |
let capoffset+=2 | |
printf "$indent Current Power: %6d Watts (output power)\n" $pcap; | |
let pcap="0x`hexdump -s $capoffset -n 2 -e '4/1 "%02X"' ${binfile}`"; | |
let capoffset+=2 | |
printf "$indent N Power Cap: %6d Watts (cap without redundant power)\n" $pcap; | |
let pcap="0x`hexdump -s $capoffset -n 2 -e '4/1 "%02X"' ${binfile}`"; | |
let capoffset+=2 | |
printf "$indent Max Power Cap: %6d Watts\n" $pcap; | |
let pcap="0x`hexdump -s $capoffset -n 2 -e '4/1 "%02X"' ${binfile}`"; | |
let capoffset+=2 | |
printf "$indent Hard Min Power Cap: %6d Watts\n" $pcap; | |
let pcap="0x`hexdump -s $capoffset -n 2 -e '4/1 "%02X"' ${binfile}`"; | |
let capoffset+=2 | |
if [ $sensorFormat -gt 2 ]; then | |
printf "$indent Soft Min Power Cap: %6d Watts\n" $pcap; | |
let pcap="0x`hexdump -s $capoffset -n 2 -e '4/1 "%02X"' ${binfile}`"; | |
let capoffset+=2 | |
fi | |
printf "$indent User Power Cap: %6d Watts\n" $pcap; | |
let pcap="0x`hexdump -s $capoffset -n 1 -e '4/1 "%02X"' ${binfile}`"; | |
let capoffset+=1 | |
printf "$indent User Power Limit Source: %d\n" $pcap; | |
elif [ "$sensor" == "EXTN" ]; then | |
sensor_id=`hexdump -s $offset -n 4 -e '4/1 "%02X"' ${binfile}`; | |
let flag_offset=$offset+4 | |
let flags="0x`hexdump -s $flag_offset -n 1 -e '"%02X"' ${binfile}`"; | |
let is_sensor="$flags & 0x80"; | |
if [ $is_sensor -eq 0 ]; then | |
# Dump name as ASCII | |
if [ $sensor_id == "45525248" ]; then # ERRH (error history) | |
#hexdump -s $offset -n $sensorLength -e '" " 4/1 "%_p" " " 1/1 "%02X" " " 1/1 "%02X" " " 2/1 "%02X" " " 2/1 "%02X" " " 2/1 "%02X""\n"' ${binfile} | |
hist_data=`hexdump -s $offset -n $sensorLength -e ' 4/1 "%_p" " " 1/1 "%02X" " " 1/1 "%02X" " " 6/1 "%02X""\n"' ${binfile}` | |
let hist_id=0x${hist_data:13:2} | |
let hist_count=0x${hist_data:15:2} | |
get_history_name $hist_id | |
history_desc="${hist_name}:${hist_count}" | |
let hist_id=0x${hist_data:17:2} | |
if [ $hist_id -gt 0 ]; then | |
let hist_count=0x${hist_data:19:2} | |
get_history_name $hist_id | |
history_desc="$history_desc, ${hist_name}:${hist_count}" | |
let hist_id=0x${hist_data:21:2} | |
if [ $hist_id -gt 0 ]; then | |
let hist_count=0x${hist_data:23:2} | |
get_history_name $hist_id | |
history_desc="$history_desc, ${hist_name}:${hist_count}" | |
fi | |
fi | |
printf " $hist_data $history_desc\n"; | |
#printf " $pwr $funcid_name\n"; | |
elif [ $sensor_id == "464D494E" ] || [ $sensor_id == "464E4F4D" ] || [ $sensor_id == "46540000" ] || [ $sensor_id == "46555400" ]; then # FMIN,FNOM,FT,FUT | |
freq_data=`hexdump -s $offset -n $sensorLength -e ' 4/1 "%_p" " " 1/1 "%02X" " " 1/1 "%02X" " " 6/1 "%02X""\n"' ${binfile}` | |
let freq_pstate=0x${freq_data:13:2} | |
let freq_value=0x${freq_data:15:4} | |
if [ $freq_value != 0 ]; then | |
printf " $freq_data pSstate: %3d / %d MHz\n" $freq_pstate $freq_value; | |
else | |
printf " $freq_data N/A\n"; | |
fi | |
elif [ $sensor_id == "434C4950" ]; then # CLIP | |
freq_data=`hexdump -s $offset -n $sensorLength -e ' 4/1 "%_p" " " 1/1 "%02X" " " 1/1 "%02X" " " 6/1 "%02X""\n"' ${binfile}` | |
let freq_pstate=0x${freq_data:13:2} | |
if [ $freq_pstate -eq 0 ]; then | |
hexdump -s $offset -n $sensorLength -e '" " 4/1 "%_p" " " 1/1 "%02X" " " 1/1 "%02X" " " 6/1 "%02X"" OCC is NOT clipping the pstate\n"' ${binfile} | |
else | |
hexdump -s $offset -n $sensorLength -e '" " 4/1 "%_p" " " 1/1 "%02X" " " 1/1 "%02X" " " 6/1 "%02X""\n"' ${binfile} | |
fi | |
else | |
hexdump -s $offset -n $sensorLength -e '" " 4/1 "%_p" " " 1/1 "%02X" " " 1/1 "%02X" " " 6/1 "%02X""\n"' ${binfile} | |
fi | |
else | |
# Dump sensor number in hex | |
hexdump -s $offset -n $sensorLength -e '" " 4/1 "%02X" " " 1/1 "%02X" " " 1/1 "%02X" " " 6/1 "%02X""\n"' ${binfile} | |
fi | |
else | |
echo -e "${red}ERROR: Unknown sensor eye catcher: $sensor${normal}"; | |
fi | |
else | |
#p8 | |
#hexdump -s $offset -n $sensorLength -e '" " 16/1 "%02X" "\n"' ${binfile} | |
if [ "$sensor" == "TEMP" ]; then | |
hexdump -s $offset -n $sensorLength -e '" " 2/1 "%02X" " " 2/1 "%02X" "\n"' ${binfile} | |
#hexdump -s $offset -n $sensorLength -e '"=0x" 2/1 "%02X" " "1/2 "%d" "\n"' ${binfile} | |
elif [ "$sensor" == "FREQ" ]; then | |
hexdump -s $offset -n $sensorLength -e '" " 2/1 "%02X" " " 2/1 "%02X" "\n"' ${binfile} | |
elif [ "$sensor" == "POWR" ]; then | |
hexdump -s $offset -n $sensorLength -e '" " 2/1 "%02X" " " 4/1 "%02X" " " 4/1 "%02X" " " 2/1 "%02X" "\n"' ${binfile} | |
elif [ "$sensor" == "CAPS" ]; then | |
let capoffset=$offset | |
let pcap="0x`hexdump -s $capoffset -n 2 -e '4/1 "%02X"' ${binfile}`"; | |
let capoffset+=2 | |
printf "$indent Current Power Cap: %6d Watts\n" $pcap; | |
let pcap="0x`hexdump -s $capoffset -n 2 -e '4/1 "%02X"' ${binfile}`"; | |
let capoffset+=2 | |
printf "$indent Current Power: %6d Watts (output power)\n" $pcap; | |
let pcap="0x`hexdump -s $capoffset -n 2 -e '4/1 "%02X"' ${binfile}`"; | |
let capoffset+=2 | |
printf "$indent N Power Cap: %6d Watts (cap without redundant power)\n" $pcap; | |
let pcap="0x`hexdump -s $capoffset -n 2 -e '4/1 "%02X"' ${binfile}`"; | |
let capoffset+=2 | |
printf "$indent Max Power Cap: %6d Watts\n" $pcap; | |
let pcap="0x`hexdump -s $capoffset -n 2 -e '4/1 "%02X"' ${binfile}`"; | |
let capoffset+=2 | |
printf "$indent Min Power Cap: %6d Watts\n" $pcap; | |
let pcap="0x`hexdump -s $capoffset -n 2 -e '4/1 "%02X"' ${binfile}`"; | |
let capoffset+=2 | |
printf "$indent User Power Cap: %6d Watts\n" $pcap; | |
else | |
echo -e "${red}ERROR: Unknown sensor eye catcher: $sensor${normal}"; | |
fi | |
fi | |
let offset=$offset+$sensorLength | |
let numSensors=$numSensors-1 | |
done | |
let numSensorBlocks=$numSensorBlocks-1 | |
done # end sensors | |
else | |
echo "...rsp truncated (only read $occRspLength bytes)" | |
fi | |
else | |
echo "...rsp truncated (only read $occRspLength bytes)" | |
fi | |
} # end parse_rsp_poll() | |
# Determine name/description associated with APSS Function IDs | |
function get_function_id | |
{ | |
let funcid=$1 | |
case $funcid in | |
1 ) funcid_name="Mem Proc 0" ;; | |
2 ) funcid_name="Mem Proc 1" ;; | |
3 ) funcid_name="Mem Proc 2" ;; | |
4 ) funcid_name="Mem Proc 3" ;; | |
5 ) funcid_name="Proc 0" ;; | |
6 ) funcid_name="Proc 1" ;; | |
7 ) funcid_name="Proc 2" ;; | |
8 ) funcid_name="Proc 3" ;; | |
9 ) funcid_name="Proc 0 cache/io/pcie" ;; | |
10 ) funcid_name="Proc 1 cache/io/pcie" ;; | |
11 ) funcid_name="Proc 2 cache/io/pcie" ;; | |
12 ) funcid_name="Proc 3 cache/io/pcie" ;; | |
13 ) funcid_name="IO A" ;; | |
14 ) funcid_name="IO B" ;; | |
15 ) funcid_name="IO C" ;; | |
16 ) funcid_name="Fans A" ;; | |
17 ) funcid_name="Fans B" ;; | |
18 ) funcid_name="Storage A" ;; | |
19 ) funcid_name="Storage B" ;; | |
20 ) funcid_name="(12V voltage sense)" ;; | |
21 ) funcid_name="(ground remote sense)" ;; | |
22 ) funcid_name="Total System Power" ;; | |
23 ) funcid_name="Memory Cache (Centaur)" ;; | |
24 ) funcid_name="Proc 0 GPU 0" ;; | |
25 ) funcid_name="Mem Proc 0-0" ;; | |
26 ) funcid_name="Mem Proc 0-1" ;; | |
27 ) funcid_name="Mem Proc 0-2" ;; | |
28 ) funcid_name="(12V standby current)" ;; | |
29 ) funcid_name="Proc 0 GPU 1" ;; | |
30 ) funcid_name="Proc 0 GPU 2" ;; | |
31 ) funcid_name="Proc 1 GPU 0" ;; | |
32 ) funcid_name="Proc 1 GPU 1" ;; | |
33 ) funcid_name="Proc 1 GPU 2" ;; | |
34 ) funcid_name="Proc 0 GPU 0 (Voltage 2)" ;; | |
35 ) funcid_name="Proc 0 GPU 1 (Voltage 2)" ;; | |
36 ) funcid_name="Proc 1 GPU 0 (Voltage 2)" ;; | |
37 ) funcid_name="Proc 1 GPU 1 (Voltage 2)" ;; | |
38 ) funcid_name="(Voltage 2 sense)" ;; | |
39 ) funcid_name="Total System Power (Voltage 2)" ;; | |
* ) funcid_name="" ;; | |
esac | |
#printf "$funcid => $funcid_name\n"; | |
} | |
# Determine name/description associated with APSS Function IDs | |
function get_history_name | |
{ | |
let id=$1 | |
case $id in | |
1 ) hist_name="VddCurrent" ;; | |
2 ) hist_name="VddVoltage" ;; | |
3 ) hist_name="VdnCurrent" ;; | |
4 ) hist_name="VdnVoltage" ;; | |
5 ) hist_name="DimmI2cPort0" ;; | |
6 ) hist_name="DimmI2cPort1" ;; | |
7 ) hist_name="VddOverTemp" ;; | |
8 ) hist_name="VdnOverTemp" ;; | |
9 ) hist_name="VddOverCurrent" ;; | |
10 ) hist_name="VdnOverCurrent" ;; | |
11 ) hist_name="ApssData" ;; | |
12 ) hist_name="ApssComplete" ;; | |
13 ) hist_name="ApssTimeout" ;; | |
14 ) hist_name="DcomTxSlvInbox" ;; | |
15 ) hist_name="DcomRxSlvInbox" ;; | |
16 ) hist_name="DcomTxSlvOutbox" ;; | |
17 ) hist_name="DcomRxSlvOutbox" ;; | |
18 ) hist_name="DcomMstPbaxSend" ;; | |
19 ) hist_name="DcomSlvPbaxSend" ;; | |
20 ) hist_name="DcomMstPbaxRead" ;; | |
21 ) hist_name="DcomSlvPbaxRead" ;; | |
22 ) hist_name="Gpe0NotIdle" ;; | |
23 ) hist_name="Gpe1NotIdle" ;; | |
24 ) hist_name="24x7Disabled" ;; | |
25 ) hist_name="CeffRatioVdd" ;; | |
26 ) hist_name="VddTemp" ;; | |
27 ) hist_name="OverPcapIgn" ;; | |
28 ) hist_name="VFRTTimeoutIgn" ;; | |
29 ) hist_name="WOFControlTimeoutIgn" ;; | |
30 ) hist_name="PstateChangeIngored" ;; | |
31 ) hist_name="VddCurrentRolloverMax" ;; | |
32 ) hist_name="CoreSmallDroop" ;; | |
33 ) hist_name="CoreLargeDroop" ;; | |
* ) hist_name="" ;; | |
esac | |
#printf "$funcid => $funcid_name\n"; | |
} | |
function get_fru_string | |
{ | |
let fru=$1 | |
case $fru in | |
0 ) fru_string="core" ;; | |
1 ) fru_string="centaur" ;; | |
2 ) fru_string="dimm" ;; | |
3 ) fru_string="vrm-ot" ;; | |
4 ) fru_string="gpu" ;; | |
5 ) fru_string="gpu-mem" ;; | |
6 ) fru_string="vrm-vdd" ;; | |
* ) fru_string="" ;; | |
esac | |
} | |
let displayed_header=0 | |
function parse_rsp_mfg | |
{ | |
# Response Data | |
let subcmd="0x${occ_cmd_data:0:2}" | |
if [ $subcmd -eq 5 ]; then # LIST SENSORS | |
printf " MFG Sub Cmd: 0x%02X (List Sensors)\n" $subcmd | |
let more_sensors="0x`hexdump -s $offset -n 1 -e '4/1 "%02X"' ${binfile}`" | |
if [ $skip_header -eq 0 ] || [ $verbose -ne 0 ]; then | |
printf " truncated?: %d (1 = list was truncated due to space)\n" $more_sensors | |
fi | |
let offset=$offset+1 | |
let count="0x`hexdump -s $offset -n 1 -e '4/1 "%02X"' ${binfile}`" | |
printf " Num Sensors: %d\n" $count | |
let offset=$offset+1 | |
let index=0 | |
while [ $index -lt $count ]; | |
do | |
let index=$index+1 | |
let guid="0x`hexdump -s $offset -n 2 -e '4/1 "%02X"' ${binfile}`" | |
#printf " GUID[%2d]: 0x%04X\n" $index $guid | |
let offset=$offset+2 | |
name="`hexdump -s $offset -n 16 -v -e '"%_p"' ${binfile}`" | |
#printf " Sensor Name[%2d]: %s\n" $index $name | |
let offset=$offset+16 | |
let sample="0x`hexdump -s $offset -n 2 -e '4/1 "%02X"' ${binfile}`" | |
#printf "Latest Sample[%2d]: %6d $units (0x%04X)\n" $index $sample $sample | |
printf " [%2d] GUID: 0x%04X / %s Sample: %6d $units (0x%04X)\n" $index $guid $name $sample $sample | |
let guidList[$guidListCount]=$guid | |
let guidListCount=$guidListCount+1 | |
let offset=$offset+2 | |
let last_sensor=$guid | |
done | |
elif [ $subcmd -eq 6 ]; then # GET SENSOR INFO | |
if [ $sensor_summary -eq 0 ]; then | |
printf " MFG Sub Cmd: 0x%02X (Get Sensor Info)\n" $subcmd | |
fi | |
let unit_offset=$offset+29 | |
units="`hexdump -s $unit_offset -n 4 -v -e '"%_p"' ${binfile} | sed 's/\\.//g'`" | |
if [ "$units" == "%" ]; then | |
units="%%" | |
fi | |
let guid="0x`hexdump -s $offset -n 2 -e '4/1 "%02X"' ${binfile}`" | |
let offset=$offset+2 | |
if [ $sensor_summary -eq 0 ]; then | |
printf " GUID: 0x%04X\n" $guid | |
let sample="0x`hexdump -s $offset -n 2 -e '4/1 "%02X"' ${binfile}`" | |
printf "Latest Sample: %6d $units (0x%04X)\n" $sample $sample | |
let offset=$offset+2 | |
let sensStatus="0x`hexdump -s $offset -n 1 -e '"%02X"' ${binfile}`" | |
printf " Status: 0x%02X\n" $sensStatus | |
let offset=$offset+1 | |
let sample="0x`hexdump -s $offset -n 4 -e '4/1 "%02X"' ${binfile}`" | |
printf " Accumulator: %d (0x%08X)\n" $sample $sample | |
let offset=$offset+4 | |
let sample="0x`hexdump -s $offset -n 2 -e '4/1 "%02X"' ${binfile}`" | |
printf " Min Sample: %6d $units (0x%04X)\n" $sample $sample | |
let offset=$offset+2 | |
let sample="0x`hexdump -s $offset -n 2 -e '4/1 "%02X"' ${binfile}`" | |
printf " Max Sample: %6d $units (0x%04X)\n" $sample $sample | |
let offset=$offset+2 | |
name="`hexdump -s $offset -n 16 -v -e '"%_p"' ${binfile}`" | |
echo " Sensor Name: $name" | |
let offset=$offset+16 | |
#units="`hexdump -s $offset -n 4 -v -e '"%_p"' ${binfile}`" | |
echo " Units: $units" | |
let offset=$offset+4 | |
let sample="0x`hexdump -s $offset -n 4 -e '4/1 "%02X"' ${binfile}`" | |
printf " Update Freq: 0x%08X\n" $sample | |
let offset=$offset+4 | |
let sample="0x`hexdump -s $offset -n 4 -e '4/1 "%02X"' ${binfile}`" | |
let mantissa="($sample >> 8)"; | |
let exponent="($sample & 0xFF)"; | |
if [ $exponent -gt 128 ]; then | |
let exponent=$exponent-256; | |
fi | |
printf " Scale Factor: 0x%08X (%dx10^%d)\n" $sample $mantissa $exponent | |
let offset=$offset+4 | |
let sample="0x`hexdump -s $offset -n 2 -e '4/1 "%02X"' ${binfile}`" | |
printf " Sen Location: 0x%04X\n" $sample | |
let offset=$offset+2 | |
let sample="0x`hexdump -s $offset -n 2 -e '4/1 "%02X"' ${binfile}`" | |
printf " Sensor Type: 0x%04X\n" $sample | |
let offset=$offset+2 | |
else | |
let sample="0x`hexdump -s $offset -n 2 -e '4/1 "%02X"' ${binfile}`" | |
let offset=$offset+2 | |
let sensStatus="0x`hexdump -s $offset -n 1 -e '"%02X"' ${binfile}`" | |
let offset=$offset+1 | |
let acc="0x`hexdump -s $offset -n 4 -e '4/1 "%02X"' ${binfile}`" | |
let offset=$offset+4 | |
let sample_min="0x`hexdump -s $offset -n 2 -e '4/1 "%02X"' ${binfile}`" | |
let offset=$offset+2 | |
let sample_max="0x`hexdump -s $offset -n 2 -e '4/1 "%02X"' ${binfile}`" | |
let offset=$offset+2 | |
name="`hexdump -s $offset -n 16 -v -e '"%_p"' ${binfile}`" | |
let offset=$offset+16 | |
let offset=$offset+4 | |
let freq="0x`hexdump -s $offset -n 4 -e '4/1 "%02X"' ${binfile}`" | |
let offset=$offset+4 | |
let scale="0x`hexdump -s $offset -n 4 -e '4/1 "%02X"' ${binfile}`" | |
let offset=$offset+4 | |
let sloc="0x`hexdump -s $offset -n 2 -e '4/1 "%02X"' ${binfile}`" | |
let offset=$offset+2 | |
let stype="0x`hexdump -s $offset -n 2 -e '4/1 "%02X"' ${binfile}`" | |
if [ $displayed_header -eq 0 ]; then | |
printf " GUID Name Sample Min Max U Stat Accum UpdFreq ScaleFactr Loc Type\n" | |
let displayed_header=1 | |
fi | |
if [ $sensStatus -eq 0 ]; then | |
printf " 0x%04X %s %6d %6d %6d %-4s 0x%02X 0x%08X 0x%08X 0x%08X 0x%04X 0x%04X\n" \ | |
$guid $name $sample $sample_min $sample_max $units $sensStatus $acc $freq $scale $sloc $stype | |
fi | |
# ignore any extra bytes | |
let offset=$end_of_rsp_data | |
fi | |
else | |
printf " MFG Sub Cmd: 0x%02X\n" $subcmd | |
let remaining_bytes=$end_of_rsp_data-$offset | |
#hexdump -C -s $offset ${binfile} | |
hexdump -C -s $offset -n $remaining_bytes ${binfile} | |
let offset=$offset+$remaining_bytes | |
fi | |
let remaining_bytes=$end_of_rsp_data-$offset | |
if [ $remaining_bytes -gt 0 ]; then | |
echo "Remaining data:" | |
hexdump -C -s $offset -n $remaining_bytes ${binfile} | |
fi | |
} # end parse_rsp_mfg() | |
function parse_rsp_debugpt | |
{ | |
# Response Data | |
let offset=0 | |
let subcmd="0x${occ_cmd_data:0:2}" | |
if [ $subcmd -eq 3 ]; then # Trace Buffer | |
printf " DEBUG Sub Cmd: 0x%02X (Trace Buffer)\n" $subcmd | |
printf " Trace Buffer: $ascii (0x%s)\n" ${occ_cmd_data:6:8} | |
echo -e $(echo "${occ_cmd_data:6:6}" | sed -e 's/\(..\)/\\x\1/g') | |
#if [ "${occ_cmd_data:6:4}" == "4750" ]; then # "GP" | |
# echo "==> ppe2fsp ${binfile} ${binfile}.bin" | |
# ppe2fsp ${binfile} ${binfile}.bin | |
# echo "==> xxd ${bindfile}.bin" | |
# xxd ${bindfile}.bin | |
#fi | |
elif [ $subcmd -eq 1 ]; then # WOF Data Structure | |
#let elogAddr="0x`hexdump -s $offset -n 4 -e '4/1 "%02X"' ${binfile}`" | |
#xxd -l 32 ${binfile} | |
#echo "WOF status:" | |
let offset=0 | |
if [ "$interface" == "cronus" ]; then | |
let offset=4 | |
fi | |
let wof_status=0x`hexdump -s $offset -n 4 -e '4/1 "%02X"' ${binfile}` | |
#echo "wof_status=$wof_status"; | |
flags="" | |
if [ $wof_status -eq 0 ]; then | |
flags="Enabled"; | |
else | |
let bitset="$wof_status & 0x04000000"; | |
if [ $bitset -ne 0 ]; then flags="$flags DivideByZeroVdn"; fi | |
let bitset="$wof_status & 0x02000000"; | |
if [ $bitset -ne 0 ]; then flags="$flags ResetDebugCmd"; fi | |
let bitset="$wof_status & 0x01000000"; | |
if [ $bitset -ne 0 ]; then flags="$flags UserDisabledWof"; fi | |
let bitset="$wof_status & 0x00800000"; | |
if [ $bitset -ne 0 ]; then flags="$flags IpcFailure"; fi | |
let bitset="$wof_status & 0x00400000"; | |
if [ $bitset -ne 0 ]; then flags="$flags NoConfiguredCores"; fi | |
let bitset="$wof_status & 0x00200000"; | |
if [ $bitset -ne 0 ]; then flags="$flags UnsupportedFreq"; fi | |
let bitset="$wof_status & 0x00100000"; | |
if [ $bitset -ne 0 ]; then flags="$flags ResetLimitReached"; fi | |
let bitset="$wof_status & 0x00080000"; | |
if [ $bitset -ne 0 ]; then flags="$flags SystemWofDisabled"; fi | |
let bitset="$wof_status & 0x00040000"; | |
if [ $bitset -ne 0 ]; then flags="$flags OppbWofDisabled"; fi | |
let bitset="$wof_status & 0x00020000"; | |
if [ $bitset -ne 0 ]; then flags="$flags OccWofDisabled"; fi | |
let bitset="$wof_status & 0x00010000"; | |
if [ $bitset -ne 0 ]; then flags="$flags UTurboIsZero"; fi | |
let bitset="$wof_status & 0x00008000"; | |
if [ $bitset -ne 0 ]; then flags="$flags DriverWofDisabled"; fi | |
let bitset="$wof_status & 0x00004000"; | |
if [ $bitset -ne 0 ]; then flags="$flags VfrtAlignmentError"; fi | |
let bitset="$wof_status & 0x00002000"; | |
if [ $bitset -ne 0 ]; then flags="$flags ControlReqFailure"; fi | |
let bitset="$wof_status & 0x00001000"; | |
if [ $bitset -ne 0 ]; then flags="$flags VfrtReqFailure"; fi | |
let bitset="$wof_status & 0x00000800"; | |
if [ $bitset -ne 0 ]; then flags="$flags DivideByZeroVdd"; fi | |
let bitset="$wof_status & 0x00000400"; | |
if [ $bitset -ne 0 ]; then flags="$flags ModeNoSupport"; fi | |
let bitset="$wof_status & 0x00000200"; | |
if [ $bitset -ne 0 ]; then flags="$flags ModeChange"; fi | |
let bitset="$wof_status & 0x00000100"; | |
if [ $bitset -ne 0 ]; then flags="$flags StateChange"; fi | |
let bitset="$wof_status & 0x00000080"; | |
if [ $bitset -ne 0 ]; then flags="$flags ControLReqTimeout"; fi | |
let bitset="$wof_status & 0x00000040"; | |
if [ $bitset -ne 0 ]; then flags="$flags VfrtReqTimeout"; fi | |
let bitset="$wof_status & 0x00000020"; | |
if [ $bitset -ne 0 ]; then flags="$flags PstateProtocolOff"; fi | |
let bitset="$wof_status & 0x00000010"; | |
if [ $bitset -ne 0 ]; then flags="$flags PgpeWofDisabled"; fi | |
let bitset="$wof_status & 0x00000008"; | |
if [ $bitset -ne 0 ]; then flags="$flags PgpeReqNotIdle"; fi | |
let bitset="$wof_status & 0x00000004"; | |
if [ $bitset -ne 0 ]; then flags="$flags InvalidVddVdn"; fi | |
let bitset="$wof_status & 0x00000002"; | |
if [ $bitset -ne 0 ]; then flags="$flags InvalidActiveQuads"; fi | |
let bitset="$wof_status & 0x00000001"; | |
if [ $bitset -ne 0 ]; then flags="$flags NoWofHeaderMask"; fi | |
fi | |
printf " WOF Status: 0x%08X ($flags )\n" $wof_status | |
# Set verbose flag so full dump of data is done (including repeated lines) | |
let verbose=1 | |
elif [ $subcmd -eq 7 ]; then # GET AME SENSOR | |
printf " DEBUG Sub Cmd: 0x%02X (AME PassThru)\n" $subcmd | |
let data="0x${occ_cmd_data:2:4}" | |
printf " Type: 0x%s\n" ${occ_cmd_data:2:4} | |
printf " Location: 0x%s\n\n" ${occ_cmd_data:6:4} | |
let offset=0 | |
if [ "$interface" == "cronus" ]; then | |
let offset=5 # Skip RSP header | |
fi | |
let num_sensors=0x`hexdump -s $offset -n 2 -e '2/1 "%02X"' ${binfile}` | |
let rsp_length=$(stat -c%s "$binfile") | |
printf "Number of sensors retrieved: %d\n" $num_sensors | |
printf -- "--------------------------------------\n" | |
let offset=$offset+2 | |
printf "Sensor GSID Current Min Max IPMI Sensor\n" | |
for ((i = 0; i < $num_sensors; i+=1)); do | |
# Read name as string | |
name=`hexdump -s $offset -n 16 -e '16/1 "%c"' ${binfile}` | |
printf "%-16s" $name | |
let offset=$offset+16 | |
# Read data as hex | |
data=`hexdump -s $offset -n 12 -e '12/1 "%02X"' ${binfile}` | |
printf " 0x${data:0:4}" #GSID | |
let data_val=0x${data:4:4} | |
printf " %6d" $data_val # Current | |
let data_val=0x${data:8:4} | |
printf " %6d" $data_val # Min | |
let data_val=0x${data:12:4} | |
printf " %6d" $data_val # Max | |
printf " 0x${data:16:8}\n" # IPMI Sensor | |
let offset=$offset+12 | |
if [ $offset -gt $rsp_length ]; then | |
printf "...data truncated (rsp length=$rsp_length)\n" | |
break; | |
fi | |
done | |
fi | |
if [ $offset -lt $end_of_rsp_data ]; then | |
# Dump response as hex data | |
let remaining_bytes=$end_of_rsp_data-$offset | |
if [ $verbose -ne 0 ]; then | |
# -v to display all repeated data (like remaining 00s) | |
hexdump -C -v -s $offset -n $remaining_bytes ${binfile} | |
else | |
hexdump -C -s $offset -n $remaining_bytes ${binfile} | |
fi | |
fi | |
} | |
function handle_occ_rsp | |
{ | |
if [ -e "$binfile" ]; then | |
let occRspLength=`wc -c ${binfile} | awk '{print $1}'` | |
else | |
let occRspLength=0 | |
fi | |
if [ "$interface" == "cronus" ]; then | |
if [ $skip_header -eq 0 ] || [ $verbose -ne 0 ]; then | |
echo "" | |
if [ "$occ_cmd" == "00" ]; then | |
echo -e "${blue}POLL Response:${normal}" | |
else | |
echo -e "${blue}$occ_cmd Command Response:${normal}" | |
fi | |
if [ $verbose -ne 0 ]; then | |
#echo "==> wc -c ${binfile} | awk '{print $1}'" | |
echo "... $occRspLength bytes" | |
fi | |
fi | |
if [ $verbose -ne 0 ]; then | |
echo "--> $binfile is $occRspLength bytes long" | |
echo "Raw Rsp Header: (32 bytes)" | |
hexdump -C -n 32 ${binfile} | |
fi | |
fi | |
### Response Header | |
let offset=0 | |
let rspStatus=0 | |
if [ "$interface" == "opal" ]; then | |
let offset=0 | |
let end_of_rsp_data=$occRspLength | |
let length=$end_of_rsp_data | |
elif [ -z $bmc ] && [ -z "$inputfile" ]; then | |
let expSeq=0x"${sequence}" | |
let rspSeq=0x`hexdump -s $offset -n 1 -e '"%02X"' ${binfile}` | |
if [ $rspSeq -eq $expSeq ]; then | |
if [ $skip_header -eq 0 ] || [ $verbose -ne 0 ]; then | |
printf " Rsp Sequence: 0x%02X\n" $rspSeq; | |
fi | |
else | |
echo -e -n "${red}" | |
printf " Rsp Sequence: 0x%02X MISMATCH - expected 0x%02X\n" $rspSeq $expSeq; | |
echo -e -n "${normal}" | |
let seqMismatch=1 | |
fi | |
let offset=$offset+1 | |
if [ $skip_header -eq 0 ] || [ $verbose -ne 0 ]; then | |
hexdump -s $offset -n 1 -e '" Command: 0x%02X\n"' ${binfile} | |
fi | |
let offset=$offset+1 | |
if [ $skip_header -eq 0 ] || [ $verbose -ne 0 ]; then | |
hexdump -s $offset -n 1 -e '" RSP Status: 0x%02X\n"' ${binfile} | |
fi | |
let rspStatus=0x`hexdump -s $offset -n 1 -e '"%02X"' ${binfile}`; | |
let offset=$offset+1 | |
let length="0x`hexdump -s $offset -n 2 -e '2/1 "%02X"' ${binfile}`" | |
let offset=$offset+2 | |
let end_of_rsp_data=$offset+$length | |
elif [ -n "$inputfile" ]; then | |
if [ $passThru -eq 0 ]; then | |
# USED TO PARSE POLL RESPONSES FROM syslog file (must be formated as just hex with spaces between each byte) | |
let rspSeq=0x`hexdump -s $offset -n 1 -e '"%02X"' ${binfile}` | |
printf " Rsp Sequence: 0x%02X\n" $rspSeq; | |
let offset=$offset+1 | |
hexdump -s $offset -n 1 -e '" Command: 0x%02X\n"' ${binfile} | |
let offset=$offset+1 | |
hexdump -s $offset -n 1 -e '" RSP Status: 0x%02X\n"' ${binfile} | |
let rspStatus=0x`hexdump -s $offset -n 1 -e '"%02X"' ${binfile}`; | |
let offset=$offset+1 | |
let length="0x`hexdump -s $offset -n 2 -e '2/1 "%02X"' ${binfile}`" | |
printf " Length: 0x%04X\n" $length | |
let offset=$offset+2 | |
else | |
let offset=0 | |
let end_of_rsp_data=$occRspLength | |
fi | |
elif [ $sendOccInstance -ne 0 ]; then | |
let compCode=0x`hexdump -s $offset -n 1 -e '"%02X"' ${binfile}` | |
compCodeString="(Success)" | |
if [ $compCode -ne 0 ]; then | |
compCodeString="(Failure)" | |
fi | |
printf "AMI Comp Code: 0x%02X $compCodeString\n" $compCode | |
let offset=$offset+1 | |
printf "AMI Rsp Length: %d bytes\n" $occRspLength | |
else | |
hexdump -s $offset -n 1 -e '" RSP Status: 0x%02X\n"' ${binfile} | |
let rspStatus=0x`hexdump -s $offset -n 1 -e '"%02X"' ${binfile}`; | |
let offset=$offset+1 | |
fi | |
if [ $skip_header -eq 0 ] || [ $verbose -ne 0 ]; then | |
printf "Rsp Data Length: 0x%04X\n" $length | |
fi | |
# Check for exception | |
let key="$rspStatus & 0xF0" | |
let elogId=0 | |
if [ $key -eq 224 ]; then | |
printf "${red}OCC EXCEPTION STATUS FOUND: 0x%02X ${normal}\n" $rspStatus; | |
echo "Exception Data:" | |
#hexdump -s $offset -n $length -e '" " 2/1 "%02X" " " 2/1 "%02X" "\n"' ${binfile} | |
hexdump -C -v -s $offset -n $length ${binfile} | |
echo "" | |
let seqMismatch=0 | |
else | |
if [ "$occ_cmd" == "00" ]; then # POLL COMMAND | |
parse_rsp_poll | |
if [ $elogId -ne 0 ] && [ $elogAddr -ne 0 ] ; then | |
process_elog | |
fi | |
elif [ "$occ_cmd" == "40" ]; then # DEBUG PASS THROUGH COMMAND | |
parse_rsp_debugpt | |
elif [ "$occ_cmd" == "53" ]; then # MFG TEST COMMAND | |
parse_rsp_mfg | |
else | |
# Dump response as hex data | |
let remaining_bytes=$end_of_rsp_data-$offset | |
if [ $remaining_bytes -gt 0 ]; then | |
echo "Response Data:" | |
fi | |
if [ $verbose -ne 0 ]; then | |
# -v to display all repeated data (like remaining 00s) | |
hexdump -C -v -s $offset -n $remaining_bytes ${binfile} | |
else | |
hexdump -C -s $offset -n $remaining_bytes ${binfile} | |
fi | |
fi | |
fi | |
} # end handle_occ_rsp() | |
function process_elog | |
{ | |
if [ "$interface" == "cronus" ]; then | |
#if [ -z $bmc ] && [ -z "$inputfile" ]; then | |
echo "" | |
printf "${bold}==> Retrieving elog from POLL (id 0x%02X, addr 0x%08X, len 0x%04X)${normal}\n" $elogId $elogAddr $elogLen; | |
if [ $verbose -ne 0 ]; then | |
printf "${bold}==> getsram %08X %d -p${occ} -ch $channel $quiet (read ELOG data from SRAM)${normal}\n" $elogAddr $elogLen | |
fi | |
sramAddr=`printf "%08X" $elogAddr` | |
echo "getsram $sramAddr $elogLen -p${occ} -ch $channel $quiet -fb elog.bin" | |
getsram $sramAddr $elogLen -p${occ} -ch $channel $quiet -fb elog.bin | |
let rc=$? | |
if [ $rc -ne 0 ]; then | |
echo -e "${red}ERROR: failed reading Elog data from SRAM (rc=$rc)${normal}" | |
exit 3; | |
fi | |
if [ $verbose -ne 0 ]; then | |
echo "Raw Elog:" | |
hexdump -C -s 0 elog.bin | |
else | |
echo "" | |
fi | |
echo "" | |
let offset=4 | |
hexdump -s $offset -n 1 -e '" Return Code: 0x2A%02X\n"' elog.bin | |
let offset=$offset+1 | |
let sev="0x`hexdump -s $offset -n 1 -e '"%02X"' elog.bin`" | |
flags="Unknown" | |
if [ $sev -eq 0 ]; then flags="Informational"; | |
elif [ $sev -eq 1 ]; then flags="Recoverable"; | |
elif [ $sev -eq 2 ]; then flags="Unrecoverable"; fi | |
printf " Severity: 0x%02X ($flags)\n" $sev | |
let offset=$offset+1 | |
flags="" | |
let actions="0x`hexdump -s $offset -n 1 -e '"%02X"' elog.bin`" | |
let bitset="$actions & 0x80"; | |
if [ $bitset -ne 0 ]; then flags="ResetRqd"; fi | |
let bitset="$actions & 0x40"; | |
if [ $bitset -ne 0 ]; then flags="$flags SafeModeRqd"; fi | |
if [ -n "$flags" ]; then flags="($flags)"; fi | |
printf " Actions: 0x%02X $flags\n" $actions | |
let offset=$offset+5 | |
hexdump -s $offset -n 1 -e '" MaxCallouts: 0x%02X\n"' elog.bin | |
let offset=$offset+1 | |
echo " Callouts: tt cccccccccccccccc pp rrrr (type, callout, priority, rsvd)" | |
hexdump -v -s $offset -n 72 -e '" " 1/1 "%02X" " " 8/1 "%02X" " " 1/1 "%02X" " " 2/1 "%02X" "\n"' elog.bin | |
let offset=$offset+72 | |
if [ $verbose -ne 0 ] || [ $purge -ne 0 ]; then | |
echo "Remaining Elog Data:" | |
# hexdump -C -s $offset -n 64 -e '"%06.6_ax: " 4/1 "%02X" " " 4/1 "%02X" " " 4/1 "%02X" " " 4/1 "%02X" "\n"' elog.bin | |
hexdump -C -s $offset elog.bin | |
# hexdump -C -s $offset -n 64 -x elog.bin | |
else | |
echo " (add -v parm to display full elog data OR -p to dump then purge elog)" | |
fi | |
rm elog.bin | |
if [ $purge -ne 0 ]; then | |
printf "${bold}==> Sending CLEAR ELOG command (id 0x%02X)${normal}\n" $elogId; | |
if [ -z $bmc ] && [ -z "$inputfile" ]; then | |
# First, store the clear elog command in command buffer in SRAM | |
let csum=0xCC+0x12+0x01+$elogId | |
clearElogCmd=`printf "cc120001%02X%04X" $elogId $csum` | |
if [ $verbose -ne 0 ]; then | |
echo -e "${bold}==> putsram $cmd_sram_addr $clearElogCmd -p${occ} -ch $channel $quiet (write CLEAR_ELOG command to OCC SRAM)${normal}" | |
fi | |
putsram $cmd_sram_addr $clearElogCmd -p${occ} -ch $channel $quiet | |
let rc=$? | |
if [ $rc -ne 0 ]; then | |
echo -e "${red}ERROR: failed writing CLEAR_ELOG command to OCC SRAM (rc=$rc)${normal}" | |
exit 1; | |
fi | |
# Second, send a doorbell to OCC | |
if [ $verbose -ne 0 ]; then | |
echo -e "${bold}==> putscom pu $doorbell_addr 0101000000000000 -p${occ} $quiet (send doorbell to OCC)${normal}" | |
fi | |
putscom pu $doorbell_addr 0101000000000000 -p${occ} $quiet | |
let rc=$? | |
if [ $rc -ne 0 ]; then | |
echo -e "${red}ERROR: failed sendingn doorbell to OCC (rc=$rc)${normal}" | |
fi | |
# Third, collect response from response buffer in SRAa | |
if [ $verbose -ne 0 ]; then | |
echo -e "${bold}==> getsram $rsp_sram_addr 16 -p${occ} -ch $channel $quiet (read CLEAR_ELOG response from SRAM)${normal}" | |
fi | |
getsram $rsp_sram_addr 16 -p${occ} -ch $channel $quiet | |
let rc=$? | |
if [ $rc -ne 0 ]; then | |
echo -e "${red}ERROR: failed reading CLEAR_ELOG response from SRAM (rc=$rc)${normal}" | |
exit 2; | |
fi | |
else | |
if [ $verbose -ne 0 ]; then | |
echo -e "${bold}==> ipmitool -H $bmc -I lanplus -U $bmcId -P $bmcPw raw 0x3a 0x0d 0x12 $elogId${normal}" | |
fi | |
ipmitool -H $bmc -I lanplus -U $bmcId -P $bmcPw raw 0x3a 0x0d 0x12 $elogId | |
let rc=$? | |
if [ $rc -ne 0 ]; then | |
echo -e "${red}ERROR: failed sending CLEAR_ELOG $elogId to OCC via IPMI/BMC (rc=$rc)${normal}" | |
exit 8 | |
fi | |
fi | |
else | |
printf "${bold}==> Ignoring elog from POLL (id 0x%02X, addr 0x%08X, len 0x%04X)${normal}\n" $elogId $elogAddr $elogLen; | |
fi | |
else | |
printf "\n${red}Note: Unable to read elog sram data via $interface, use cronus (OCC logid 0x%02X, addr 0x%08X, len 0x%04X)${normal}\n" $elogId $elogAddr $elogLen; | |
fi | |
} # end process_elog() | |
function tmgt_info | |
{ | |
### Dump HTMGT and OCC states and status | |
echo "==> opal-prd --expert-mode htmgt-passthru 0x01" | |
$sudo opal-prd --expert-mode htmgt-passthru 0x01 | sed 's/\s//g' > $temp_filename | |
# get status of first cmd in piped cmdline | |
let rc=${PIPESTATUS[0]} | |
#echo "020003030000000000002ada00000000" > $temp_filename | |
#echo "000301010100000000000000c3100300" >> $temp_filename | |
#echo "01030000010000000000000003900200" >> $temp_filename | |
#let rc=0 | |
if [ $verbose -ne 0 ]; then | |
echo -n "Raw Data:" | |
cat $temp_filename | |
echo "" | |
fi | |
let inSafe=0 | |
let numOccs=0 | |
if [ $rc -eq 0 ]; then | |
let lineno=0 | |
while read line; do | |
if [ ${#line} -gt 2 ]; then | |
let lineno=$lineno+1 | |
if [ ${lineno} -eq 1 ]; then | |
let numOccs=0x${line:0:2} | |
let master=0x${line:2:2} | |
let state=0x${line:4:2} | |
if [ $state -eq 4 ]; then | |
let in_safe=1 | |
fi | |
let targState=0x${line:6:2} | |
let count=0x${line:8:2} | |
let cumulativeResetCount=0x${line:10:2} | |
let version=0x${line:12:2} | |
let safe=0x${line:14:2} | |
safeRc=${line:20:4} | |
let safeInst=0x${line:24:8} | |
if [ $state -eq 1 ]; then | |
stateText="STANDBY" | |
elif [ $state -eq 2 ]; then | |
stateText="OBSERV " | |
elif [ $state -eq 3 ]; then | |
stateText="ACTIVE " | |
elif [ $state -eq 4 ]; then | |
stateText="SAFE " | |
elif [ $state -eq 5 ]; then | |
stateText="CHARACT" | |
elif [ $state -eq $((0x85)) ]; then | |
stateText="RESET " | |
elif [ $state -eq $((0x87)) ]; then | |
stateText="TRANSIT" | |
elif [ $state -eq $((0x88)) ]; then | |
stateText="LOADING" | |
elif [ $state -eq $((0x89)) ]; then | |
stateText="" | |
else | |
stateText="UNDEFIN" | |
fi | |
if [ $safe -ne 0 ]; then | |
let inSafe=1 | |
echo "HTMGT State: $stateText($(printf "0x%02X" $state)), $numOccs OCC (master:OCC$master), resetCount:$count, (SAFE MODE: rc=0x${safeRc}/OCC$safeInst)" | |
else | |
if [ $safeRc == "0000" ]; then | |
echo "HTMGT State: $stateText($(printf "0x%02X" $state)), $numOccs OCC (master:OCC$master), resetCount:$count" | |
else | |
echo "HTMGT State: $stateText($(printf "0x%02X" $state)), $numOccs OCC (master:OCC$master), resetCount:$count (last reset due to rc=0x${safeRc}/OCC$safeInst)" | |
fi | |
fi | |
if [ $cumulativeResetCount -ne 0 ]; then | |
echo " : PM Complex Resets since boot: $cumulativeResetCount" | |
fi | |
else | |
let inst=0x${line:0:2} | |
let state=0x${line:2:2} | |
let role=0x${line:4:2} # | |
let capab=0x${line:6:2} # | |
let occComm=0x${line:8:2} | |
# 3 bytes reserved | |
let failed=0x${line:16:2} | |
let needReset=0x${line:18:2} | |
let resetReason=0x${line:20:2} # | |
let wof_reset_count=0x${line:22:1} | |
let count=0x${line:23:1} | |
pollRsp=${line:24:8} | |
let pollRspExtStatus=0x${pollRsp:2:2} | |
type="Slave " | |
if [ $master -eq $inst ]; then | |
type="Master" | |
fi | |
if [ $state -eq 1 ]; then | |
stateText="STANDBY" | |
elif [ $state -eq 2 ]; then | |
stateText="OBSERV " | |
elif [ $state -eq 3 ]; then | |
stateText="ACTIVE " | |
elif [ $state -eq 4 ]; then | |
stateText="SAFE " | |
elif [ $state -eq 5 ]; then | |
stateText="CHARACT" | |
elif [ $state -eq $((0x85)) ]; then | |
stateText="RESET " | |
elif [ $state -eq $((0x87)) ]; then | |
stateText="TRANSIT" | |
elif [ $state -eq $((0x88)) ]; then | |
stateText="LOADING" | |
elif [ $state -eq $((0x89)) ]; then | |
stateText="" | |
else | |
stateText="UNDEFIN" | |
fi | |
flags="" | |
if [ $occComm -eq 0 ]; then | |
flags="${flags}NOCOMM " | |
elif [ $failed -ne 0 ]; then | |
flags="${flags}FAILED " | |
elif [ $needReset -ne 0 ]; then | |
flags="${flags}NEEDSRESET " | |
fi | |
if [ $pollRspExtStatus -eq 0 ]; then | |
echo "OCC${inst}: $type $stateText($(printf "0x%02X" $state)) resetCount:$count wofResets:$wof_reset_count $flags pollRsp:0x${pollRsp}..." | |
else | |
extflags=""; | |
let bitset="$pollRspExtStatus & 0x80"; | |
if [ $bitset -ne 0 ]; then extflags="$extflags Throttle-ProcOverTemp"; fi | |
let bitset="$pollRspExtStatus & 0x40"; | |
if [ $bitset -ne 0 ]; then extflags="$extflags Throttle-Power"; fi | |
let bitset="$pollRspExtStatus & 0x20"; | |
if [ $bitset -ne 0 ]; then extflags="$extflags MemThrot-OverTemp"; fi | |
let bitset="$pollRspExtStatus & 0x10"; | |
if [ $bitset -ne 0 ]; then extflags="$extflags QuickPowerDrop"; fi | |
let bitset="$pollRspExtStatus & 0x08"; | |
if [ $bitset -ne 0 ]; then extflags="$extflags Throttle-VddOverTemp"; fi | |
echo "OCC${inst}: $type $stateText($(printf "0x%02X" $state)) resetCount:$count wofResets:$wof_reset_count $flags pollRsp:0x${pollRsp}... ($extflags )" | |
fi | |
fi | |
fi | |
done < $temp_filename | |
else | |
echo "ERROR: opal-prd occ passthru command failed with rc=$rc" | |
fi | |
if [ -e "$temp_filename" ]; then | |
rm -rf $temp_filename | |
fi | |
if [ $rc -eq 0 ] && [ $inSafe -ne 0 ]; then | |
let rc=4 | |
fi | |
} # end tmgt_info() | |
function wof_reset_reasons | |
{ | |
### Dump WOF reset reasons and OCC instance ID | |
echo "==> opal-prd --expert-mode htmgt-passthru 0x0A" | |
$sudo opal-prd --expert-mode htmgt-passthru 0x0A | sed 's/\s//g' > /tmp/wofrr.bin | |
# get status of first cmd in piped cmdline | |
let rc=${PIPESTATUS[0]} | |
if [ $rc -eq 0 ]; then | |
while read line; do | |
if [ ${#line} -gt 0 ]; then | |
#First read the output data into one variable | |
alldata=$alldata$line | |
fi | |
done < /tmp/wofrr.bin | |
else | |
echo "ERROR: opal-prd occ passthru command failed with rc=$rc" | |
fi | |
# Data length should be multiple of 10. Each OCC has a 2 digit ID followed | |
# by the 8 digit WOF Reset reason vector | |
if [ $((${#alldata}%10)) -ne 0 ]; then | |
echo "ERROR: Data is unexpected length. Aborting..." | |
else | |
numOccs=$((${#alldata}/10)) | |
current_index=0 | |
for (( i=0; i<$numOccs; i++ )) | |
do | |
#Move to the next 10 digit block | |
current_line=${alldata:${current_index}:10} | |
#Extract OCC Instance | |
let occId=0x${current_line:0:2} | |
#Extract wof_disabled bit vector | |
let wofRR=0x${current_line:2:8} | |
printf "OCC%X WOF Reset Reasons: 0x%08X\n" $occId $wofRR | |
#Increment index | |
current_index=$current_index+10 | |
done | |
fi | |
} # end wof_reset_reasons | |
function tmgt_flags | |
{ | |
### Dump HTMGT Internal Flags | |
echo "==> opal-prd --expert-mode htmgt-passthru 0x02" | |
$sudo opal-prd --expert-mode htmgt-passthru 0x02 | |
let flagvalue=0x`$sudo opal-prd --expert-mode htmgt-passthru 0x02 | tr -d '\r\n' | sed 's/\s//g1'` | |
flags=""; | |
let halt_src="$flagvalue >> 24" | |
let bitset="$flagvalue & 0x00800000"; | |
if [ $bitset -ne 0 ]; then flags="$flags HaltOnSrc:$(printf '0x2A%02X' $halt_src)"; fi | |
let bitset="$flagvalue & 0x00000800"; | |
if [ $bitset -ne 0 ]; then flags="$flags DisableMemConfig"; fi | |
let bitset="$flagvalue & 0x00000100"; | |
if [ $bitset -ne 0 ]; then flags="$flags HaltOnResetFail"; fi | |
let bitset="$flagvalue & 0x00000080"; | |
if [ $bitset -ne 0 ]; then flags="$flags ExtResetDisable"; fi | |
let bitset="$flagvalue & 0x00000040"; | |
if [ $bitset -ne 0 ]; then flags="$flags DisableMemThrot"; fi | |
let bitset="$flagvalue & 0x00000020"; | |
if [ $bitset -ne 0 ]; then flags="$flags IgnoreOccState"; fi | |
let bitset="$flagvalue & 0x00000010"; | |
if [ $bitset -ne 0 ]; then flags="$flags HoldOccsInReset"; fi | |
let bitset="$flagvalue & 0x00000008"; | |
if [ $bitset -ne 0 ]; then flags="$flags LoadDisabled"; fi | |
let bitset="$flagvalue & 0x00000004"; | |
if [ $bitset -ne 0 ]; then flags="$flags TerminateOnErr"; fi | |
let bitset="$flagvalue & 0x00000002"; | |
if [ $bitset -ne 0 ]; then flags="$flags ResetDisabled"; fi | |
let bitset="$flagvalue & 0x00000001"; | |
if [ $bitset -ne 0 ]; then flags="$flags ExternalOverride"; fi | |
let bitset="$flagvalue & 0x007FF600"; | |
if [ $bitset -ne 0 ]; then flags="$flags UnknownBit"; fi | |
printf "Flags: 0x%08X $flags\n" $flagvalue | |
if [ -n "$newFlags" ]; then | |
newFlagValue=`printf "%08X" $newFlags` | |
echo "Updating internalFlags to: $newFlagValue" | |
### Set HTMGT Internal Flags | |
echo "==> opal-prd --expert-mode htmgt-passthru 0x02 0x${newFlagValue:0:2} 0x${newFlagValue:2:2} 0x${newFlagValue:4:2} 0x${newFlagValue:6:2}" | |
$sudo opal-prd --expert-mode htmgt-passthru 0x02 0x${newFlagValue:0:2} 0x${newFlagValue:2:2} 0x${newFlagValue:4:2} 0x${newFlagValue:6:2} | |
fi | |
} | |
function occ_ffdc | |
{ | |
echo "" | |
let numOccs=1 | |
while [ $numOccs -gt 0 ]; do | |
echo "`hostname` OCC$occ FFDC Data: (`date`)" | |
echo "==> opal-prd --expert-mode htmgt-passthru 0x03 $occ 0x42 0x00" | |
$sudo opal-prd --expert-mode htmgt-passthru 0x03 $occ 0x42 0x00 | |
let rc=${PIPESTATUS[0]} | |
echo "" | |
let occ=$occ+1 | |
let numOccs=$numOccs-1 | |
done | |
} # end occ_ffdc() | |
function occ_trace | |
{ | |
echo "" | |
let numOccs=1 | |
while [ $numOccs -gt 0 ]; do | |
echo "`hostname` OCC$occ Trace: (`date`)" | |
occ_cmd="40" # DEBUG_PASS_THROUGH | |
occ_cmd_data="03010045525200" # ERR traces | |
send_occ_cmd | |
handle_occ_rsp | |
occ_cmd_data="030100494D5000" # IMP traces | |
send_occ_cmd | |
handle_occ_rsp | |
occ_cmd_data="030100494E4600" # INF traces | |
send_occ_cmd | |
handle_occ_rsp | |
occ_cmd_data="03010047503000" # GP0 traces | |
send_occ_cmd | |
handle_occ_rsp | |
# Need to run: ppe2fsp infile outfile | |
occ_cmd_data="03010047503100" # GP1 traces | |
send_occ_cmd | |
handle_occ_rsp | |
# Need to run: ppe2fsp infile outfile | |
let occ=$occ+1 | |
let numOccs=$numOccs-1 | |
done | |
} # end occ_trace() | |
function occ_trace_cronus | |
{ | |
echo "" | |
let numOccs=1 | |
if [ -z "$string_file" ]; then | |
if [ -e "./occStringFile" ]; then | |
string_file="./occStringFile" | |
elif [ -e "/tmp/occStringFile" ]; then | |
string_file="/tmp/occStringFile" | |
elif [ -e "/nfs/occStringFile" ]; then | |
string_file="/nfs/occStringFile" | |
else | |
echo "WARNING: unable to find occStringFile" | |
fi | |
fi | |
let min_sram_size=4 | |
if [ $toolkit -ne 0 ]; then | |
let min_sram_size=8 | |
fi | |
while [ $numOccs -gt 0 ]; do | |
echo -e "${bold}Collecting OCC$occ Trace via cronus: (`date`)${normal}" | |
# Confirm eyecatcher is correct | |
if [ $verbose -ne 0 ]; then | |
echo "==> getsram fffb4003 $min_sram_size -ch $channel -p$occ -n$node -exp 42455252" | |
fi | |
getsram fffb4003 $min_sram_size -ch $channel -p$occ -n$node | |
getsram fffb4003 $min_sram_size -ch $channel -p$occ -n$node -exp 42455252 # "BERR" | |
let foundERR=$? | |
if [ $foundERR -eq 0 ]; then | |
# Remove old files | |
rm -f ./occTrace*.bin ./occTrace.ppe | |
echo -e "${bold}==> getsram fffb4000 8192 -p$occ -n$node -fb ./occTraceERR.bin -ch $channel ${normal}" | |
getsram fffb4000 8192 -p$occ -n$node -fb ./occTraceERR.bin -ch $channel | |
echo -e "${bold}==> getsram fffb6000 8192 -p$occ -n$node -fb ./occTraceINF.bin -ch $channel ${normal}" | |
getsram fffb6000 8192 -p$occ -n$node -fb ./occTraceINF.bin -ch $channel | |
echo -e "${bold}==> getsram fffb8000 8192 -p$occ -n$node -fb ./occTraceIMP.bin -ch $channel ${normal}" | |
getsram fffb8000 8192 -p$occ -n$node -fb ./occTraceIMP.bin -ch $channel | |
if [ -e "./ppe2fsp" ]; then | |
ppe2fsp_cmd="./ppe2fsp" | |
else | |
echo -e "${red}Unable to find ppe2fsp to convert GPE traces to FSP trace format${normal}" | |
echo "NOTE: Command is available in occ/obj/ppetools/ppe2fsp" | |
ppe2fsp_cmd=""; | |
fi | |
GPE0ADDR=`getsram fffb3c10 $min_sram_size -ch $channel | grep 00000000 | awk '{print $2}'` | |
GPE0SIZEHEX=`getsram fffb3c14 $min_sram_size -ch $channel | grep 00000000 | awk '{print $2}'` | |
#echo "gpe0 $GPE0ADDR $GPE0SIZEHEX $GPE0SIZE" | |
#GPE0SIZE=`echo \$((16#$GPE0SIZEHEX))` | |
let GPE0SIZE=0x${GPE0SIZEHEX} | |
if [ $GPE0SIZE -gt 2048 ]; then | |
echo -e "${red}WARNING: GPE0 trace size (0x${GPE0SIZEHEX}) looks too large! Using 2048${normal}" | |
let GPE0SIZE=2048 | |
fi | |
echo "gpe0 $GPE0ADDR $GPE0SIZEHEX $GPE0SIZE" | |
let gpe_addr=0x$GPE0ADDR | |
if [ $gpe_addr -ne 0 ]; then | |
echo -e "${bold}==> getsram $GPE0ADDR $GPE0SIZE -ch $channel -p$occ -n$node -fb ./occTraceGPE0.ppe ${normal}" | |
getsram $GPE0ADDR $GPE0SIZE -ch $channel -p$occ -n$node -fb ./occTraceGPE0.ppe | |
if [ -n "$ppe2fsp_cmd" ]; then | |
echo -e "${bold}==> $ppe2fsp_cmd ./occTraceGPE0.ppe ./occTraceGPE0.bin ${normal}" | |
$ppe2fsp_cmd ./occTraceGPE0.ppe ./occTraceGPE0.bin | |
if [ $? -eq 0 ]; then | |
rm -f ./occTraceGPE0.ppe | |
else | |
echo -e "${red}ERROR: Unable to convert occTraceGPE0.ppe to FSP trace format${normal}" | |
rm -f ./occTraceGPE0.bin | |
fi | |
else | |
echo -e "${red}ERROR: unable to find ppe2fsp to convert GPE traces to FSP trace format${normal}" | |
fi | |
fi | |
GPE1ADDR=`getsram fffb3c18 $min_sram_size -ch $channel | grep 00000000 | awk '{print $2}'` | |
GPE1SIZEHEX=`getsram fffb3c1c $min_sram_size -ch $channel | grep 00000000 | awk '{print $2}'` | |
#GPE1SIZE=`echo \$((16#$GPE1SIZEHEX))` | |
let GPE1SIZE=0x${GPE1SIZEHEX} | |
if [ $GPE0SIZE -gt 2048 ]; then | |
echo -e "${red}WARNING: GPE1 trace size (0x${GPE1SIZEHEX}) looks too large! Using 2048${normal}" | |
let GPE1SIZE=2048 | |
fi | |
echo "gpe1 $GPE1ADDR $GPE1SIZEHEX $GPE1SIZE" | |
if [ $gpe_addr -ne 0 ]; then | |
echo -e "${bold}==> getsram $GPE1ADDR $GPE1SIZE -ch $channel -p$occ -n$node -fb ./occTraceGPE1.ppe ${normal}" | |
getsram $GPE1ADDR $GPE1SIZE -ch $channel -p$occ -n$node -fb ./occTraceGPE1.ppe | |
if [ -n "$ppe2fsp_cmd" ]; then | |
echo -e "${bold}==> $ppe2fsp_cmd ./occTraceGPE1.ppe ./occTraceGPE1.bin ${normal}" | |
$ppe2fsp_cmd ./occTraceGPE1.ppe ./occTraceGPE1.bin | |
if [ $? -eq 0 ]; then | |
rm -f ./occTraceGPE1.ppe | |
else | |
echo -e "${red}ERROR: Unable to convert occTraceGPE1.ppe to FSP trace format${normal}" | |
rm -f ./occTraceGPE1.bin | |
fi | |
fi | |
fi | |
if [ -e "./fsp-trace" ]; then | |
fsptrace_cmd="./fsp-trace" | |
else | |
#echo -e "${red}Unable to find fsp-trace to parse FSP traces${normal}" | |
fsptrace_cmd="fsp-trace"; | |
fi | |
if [ -n "$string_file" ]; then | |
if [ -n "$fsptrace_cmd" ]; then | |
echo -e "${bold}==> $fsptrace_cmd -s $string_file ./occTrace*.bin ${normal}" | |
$fsptrace_cmd -s $string_file ./occTrace*.bin | |
fi | |
else | |
echo "To parse: fsp-trace -s OCC_STRING_FILENAME ./occTrace*.bin" | |
fi | |
else | |
echo "ERROR: ERR eyecatcher was not found! ABORTING TRACE COLLECTION" | |
fi | |
let occ=$occ+1 | |
let numOccs=$numOccs-1 | |
done | |
} # end occ_trace() | |
if [ $passThru -eq 1 ] && [ -z "$inputfile" ]; then | |
# No input file specified, check clipboard for hex data to parse | |
inputfile="/tmp/occtool.temp.txt" | |
echo "Extracting copy buffer into ${inputfile}..." | |
xselection PRIMARY > $inputfile | |
fi | |
if [ $passThru -eq 1 ] && [ -n "$inputfile" ]; then | |
convertToBinary $inputfile $binfile | |
fi | |
if [ -n "$action" ]; then | |
if [ "$action" == "SensorDump" ]; then | |
# -X 53 0600003d = get sensor details for GUID 0x003d" | |
occ_cmd="53" # MFG TEST COMMAND | |
occ_cmd_data=`printf "0600%04X" $sensor_guid` | |
#echo "==> $occ_cmd $occ_cmd_data" | |
send_occ_cmd | |
handle_occ_rsp | |
elif [ "$action" == "SensorClear" ]; then | |
occ_cmd="41" # AME PASS THROUGH COMMAND | |
occ_cmd_data="3C0021" # Clear Min/Max for all sensors | |
send_occ_cmd | |
handle_occ_rsp | |
elif [ "$action" == "SensorList" ]; then | |
printf " Sensor Type: 0x%04X\n" $sensor_type | |
printf "Sensor Location: 0x%04X\n" $sensor_loc | |
if [ $only_non_zero_sensors -eq 1 ]; then | |
printf " (only displaying non-zero sensors)\n" | |
fi | |
# Collect the list of applicable sensors (and their sample value) | |
let more_sensors=1 | |
let first_sensor=0 | |
let skip_header=1 | |
while [ $more_sensors -ne 0 ]; do | |
# -X 53 0500000001LLLLTTTT = list first 50 OCC sensors (LLLL=Location,TTTT=Type)" | |
occ_cmd="53" # MFG TEST COMMAND | |
occ_cmd_data=`printf "0500%04X%02X%04X%04X" $first_sensor $only_non_zero_sensors $sensor_loc $sensor_type` | |
send_occ_cmd | |
handle_occ_rsp # will update more_sensors and last_sensor | |
let first_sensor=$last_sensor+1 | |
done; | |
# Display sensor details (min, max, etc for each one) | |
if [ $guidListCount -gt 0 ]; then | |
printf "\nSensor Details: (found $guidListCount sensors, details only for Status of 0x00)\n"; | |
let index=0 | |
let sensor_summary=1 | |
while [ $index -lt $guidListCount ]; do | |
# -X 53 0600003d = get sensor details for GUID 0x003d" | |
occ_cmd="53" # MFG TEST COMMAND | |
occ_cmd_data=`printf "0600%04X" ${guidList[$index]}` | |
send_occ_cmd | |
handle_occ_rsp | |
let index=$index+1 | |
done; | |
fi | |
elif [ "$action" == "OCCFFDC" ]; then | |
occ_ffdc | |
elif [ "$action" == "ExitSafe" ]; then | |
if [ "$interface" == "opal" ]; then | |
### Dump HTMGT and OCC states and status | |
tmgt_info | |
if [ $in_safe -ne 0 ]; then | |
### Attempt to exit safe mode | |
echo "==> opal-prd --expert-mode htmgt-passthru 0x05" | |
$sudo opal-prd --expert-mode htmgt-passthru 0x05 | |
let rc=$? | |
echo "return status: $rc" | |
else | |
echo "System is not currently in safe mode!" | |
fi | |
else | |
echo -e "${red}ERROR: Command only supported with opal-prd${normal} (not $interface)" | |
fi | |
elif [ "$action" == "TMGTInfo" ]; then | |
if [ "$interface" == "opal" ]; then | |
tmgt_info | |
else | |
echo -e "${red}ERROR: Command only supported with opal-prd${normal} (not $interface)" | |
fi | |
elif [ "$action" == "WOFRR" ]; then | |
if [ "$interface" == "opal" ]; then | |
wof_reset_reasons | |
else | |
echo -e "${red}ERROR: Command only supported with opal-prd${normal} (not $interface)" | |
fi | |
elif [ "$action" == "TMGTFlags" ]; then | |
if [ "$interface" == "opal" ]; then | |
tmgt_flags | |
else | |
echo -e "${red}ERROR: Command only supported with opal-prd${normal} (not $interface)" | |
fi | |
elif [ "$action" == "trace" ]; then | |
if [ "$interface" == "opal" ]; then | |
occ_trace $occ | |
elif [ "$interface" == "cronus" ]; then | |
occ_trace_cronus | |
fi | |
elif [ "$action" == "CmdRspBuffer" ]; then | |
let buffer_size=128 | |
echo "OCC Command Buffers from SRAM ($cmd_sram_addr):" | |
if [ $verbose -ne 0 ]; then | |
echo -e "${bold}==> getsram $cmd_sram_addr $buffer_size -pall -ch $channel $quiet (read $cmd response from SRAM)${normal}" | |
fi | |
if [ -e "${binfile}" ]; then | |
rm ${binfile} | |
fi | |
getsram $cmd_sram_addr $buffer_size -pall -ch $channel $quiet | |
let rc=$? | |
if [ $rc -ne 0 ]; then | |
echo -e "${red}ERROR: failed reading response buffer from SRAM (rc=$rc)${normal}" | |
exit 2; | |
fi | |
echo "OCC Response Buffers from SRAM ($rsp_sram_addr):" | |
if [ $verbose -ne 0 ]; then | |
echo -e "${bold}==> getsram $rsp_sram_addr $buffer_size -pall -ch $channel $quiet (read $cmd response from SRAM)${normal}" | |
fi | |
if [ -e "${binfile}" ]; then | |
rm ${binfile} | |
fi | |
getsram $rsp_sram_addr $buffer_size -pall -ch $channel $quiet | |
let rc=$? | |
if [ $rc -ne 0 ]; then | |
echo -e "${red}ERROR: failed reading response buffer from SRAM (rc=$rc)${normal}" | |
exit 2; | |
fi | |
else | |
echo -e "${red}ERROR: internal action of $action is not implemented by occtoolp9 script${normal}"; | |
fi | |
else | |
if [ $passThru -eq 1 ]; then | |
occ_cmd="00" | |
handle_occ_rsp | |
elif [ -n "$occ_cmd" ]; then | |
# Send user specified command | |
send_occ_cmd | |
handle_occ_rsp | |
else | |
usage | |
exit 0 | |
fi | |
fi | |
#cleanup | |
if [ -e "${binfile}" ]; then | |
rm ${binfile} | |
fi | |
if [ $seqMismatch -ne 0 ]; then | |
echo "" | |
echo -e "${red}Warning: sequence number mismatch!${normal} (Response data is stale!)" | |
exit 9 | |
fi | |