| #!/bin/bash |
| # MCA error codes validation |
| # ./mcaerr_test -a [-b status] [-p processor] |
| # ./mcaerr_test -s status [-p processor] |
| |
| g_testall=0 |
| g_processor="" |
| g_hstat=0x8000000000000000 |
| g_status="" |
| g_tests_dir="$(cd "$(dirname "$0")" && pwd)" |
| g_input_dir=$g_tests_dir/../input |
| g_tmp_dir=/tmp/mcaerr-tmp |
| # save failed MCA error codes during testing |
| g_fail_code_log=$g_tests_dir/fail_mcacode_log |
| # save undefined MCA error codes during testing |
| g_unknown_code_log=$g_tests_dir/unknown_mcacode_log |
| # input file for 'mcelog --ascii' |
| g_fname="" |
| # the expected string parsed from raw MCA error codes. |
| g_expect="" |
| |
| logfile_prepare() |
| { |
| if [ -f $g_fail_code_log ]; then |
| : > $g_fail_code_log |
| else |
| touch $g_fail_code_log |
| fi |
| |
| if [ -f $g_unknown_code_log ]; then |
| : > $g_unknown_code_log |
| else |
| touch $g_unknown_code_log |
| fi |
| } |
| |
| validate_mca() |
| { |
| local mca_prefix="MCA:" |
| local m_ecode=$1 |
| local buserr_expect |
| |
| # masked F bit in MCA error code |
| if [[ "$1" -ge 0x1000 ]]; then |
| m_ecode=$(($1 & ~0x1000)) |
| fi |
| |
| g_fname=$(printf "mca-%0x" $1) |
| g_expect=$(cat ./${g_fname}-expect) |
| if [[ "$m_ecode" -ge 0x0800 && "$m_ecode" -lt 0x1000 ]]; then |
| mca_prefix="MCA: BUS error:" |
| buserr_expect="BUS error: $g_expect" |
| echo "expect: $buserr_expect" |
| else |
| echo "expect: $g_expect" |
| fi |
| if mcelog --no-dmi --ascii --file $g_fname | grep "$mca_prefix" | grep -q "$g_expect" ; then |
| return 0 |
| else |
| return 1 |
| fi |
| } |
| |
| test_all() |
| { |
| local m_status |
| local rc |
| local fail_cnt=0 |
| local pass_cnt=0 |
| local ignore_cnt=0 |
| |
| if [ ! -d $g_tmp_dir ]; then |
| mkdir $g_tmp_dir |
| fi |
| pushd ./ > /dev/null |
| cd $g_tmp_dir |
| echo "++++++++++Start validating all MCA error codes...++++++++++" |
| for ecode in `seq 0x0000 0x0fff` |
| do |
| m_status=$(($g_hstat | $ecode)) |
| printf "m_status=0x%lx\n" $m_status |
| $g_input_dir/GENMCA $m_status "$g_processor" |
| case $? in |
| 0) |
| validate_mca $ecode |
| rc=$? |
| if [ $rc -eq 0 ]; then |
| printf "code 0x%x: [PASS]\n" $ecode |
| let "pass_cnt += 1" |
| else |
| printf "code 0x%x: [FAIL]\n" $ecode | tee -a $g_fail_code_log |
| let "fail_cnt += 1" |
| fi |
| ;; |
| 2) |
| printf "code 0x%x: [IGNORE]\n" $ecode | tee -a $g_unknown_code_log |
| let "ignore_cnt += 1" |
| ;; |
| *) |
| echo "It won't go here!" |
| exit 1 |
| ;; |
| esac |
| |
| done |
| echo "++++++++++End validating all MCA error codes++++++++++" |
| printf "PASS: %d, FAIL: %d, IGNORE: %d\n" $pass_cnt $fail_cnt $ignore_cnt |
| popd > /dev/null |
| rm -rf $g_tmp_dir |
| } |
| |
| test_one() |
| { |
| local m_ecode |
| local rc |
| |
| [ -z "$g_status" ] && usage |
| m_ecode=$(($g_status & 0xffff)) |
| $g_input_dir/GENMCA $g_status "$g_processor" |
| case $? in |
| 0) |
| validate_mca $m_ecode |
| rc=$? |
| if [ $rc -eq 0 ]; then |
| printf "code 0x%x: [PASS]\n" $m_ecode |
| else |
| printf "code 0x%x: [FAIL]\n" $m_ecode |
| fi |
| echo "Content of the generated input_file lists below:" |
| cat $g_fname |
| rm -rf $g_fname |
| rm -rf ${g_fname}-expect |
| ;; |
| 2) |
| printf "code %x: [IGNORE]\n" $m_ecode |
| ;; |
| *) |
| echo "It won't go here!" |
| exit 1 |
| ;; |
| esac |
| } |
| |
| usage() |
| { |
| echo "Usage:" |
| echo -e "\t${0##*/} -a [-b status] [-p processor]" |
| echo -e "\t${0##*/} -s status [-p processor]" |
| echo -e "\t\t-a --- do all MCA error codes validation" |
| echo -e "\t\t-b --- 'status' is same as the '-s' option, but the lowest 16 bits are masked." |
| echo -e "\t\t-s --- only run MCA error codes test related to 'status' value," |
| echo -e "\t\t 'status' is the 64-bit IA32_MCi_Status value, i.e., 0x8000000000000002." |
| echo -e "\t\t-p --- modify 'PROCESSOR' part of the tested input file with 'processor' value," |
| echo -e "\t\t 'processor' must be formated as 'vendor:CPUID', vendor:0 - Intel," |
| echo -e "\t\t i.e., 0:0x50650, the default value." |
| exit 1 |
| } |
| |
| [ "x$1" == "x" ] && usage |
| while getopts ":ab:hp:s:" opt |
| do |
| case $opt in |
| a) g_testall=1;; |
| b) g_hstat=$(($OPTARG & ~0xffff));; |
| h) usage;; |
| p) g_processor="$OPTARG";; |
| s) g_status=$OPTARG;; |
| *) usage;; |
| esac |
| done |
| |
| if [ "$g_testall" == "1" ]; then |
| logfile_prepare |
| test_all |
| else |
| test_one |
| fi |