250 lines
5.3 KiB
Bash
Executable File
250 lines
5.3 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
usage() {
|
|
cat <<-EOF
|
|
Usage: $0 [-rs] [-rj <board>] [-rh <board ip>] [tests]
|
|
|
|
If no tests are specified, all tests are processed.
|
|
|
|
Options:
|
|
-rs Run on simulator
|
|
-rj <board> Run on board via JTAG
|
|
-rh <ip> Run on board ip
|
|
-j <num> Num jobs to run
|
|
EOF
|
|
exit ${1:-1}
|
|
}
|
|
|
|
: ${MAKE:=make}
|
|
boardip=
|
|
boardjtag=
|
|
run_sim=false
|
|
run_jtag=false
|
|
run_host=false
|
|
jobs=`getconf _NPROCESSORS_ONLN 2>/dev/null || echo 1`
|
|
: $(( jobs += 1 ))
|
|
while [ -n "$1" ] ; do
|
|
case $1 in
|
|
-rs) run_sim=true;;
|
|
-rj) boardjtag=$2; shift; run_jtag=true;;
|
|
-rh) boardip=$2; shift; run_host=true;;
|
|
-j) jobs=$2; shift;;
|
|
-*) usage;;
|
|
*) break;;
|
|
esac
|
|
shift
|
|
done
|
|
${run_jtag} || ${run_host} || ${run_sim} || run_sim=true
|
|
|
|
if ${run_host} && [ -z "${boardip}" ] ; then
|
|
usage
|
|
fi
|
|
|
|
cd "${0%/*}" || exit 1
|
|
|
|
dorsh() {
|
|
# rsh sucks and does not pass up its exit status, so we have to:
|
|
# on board:
|
|
# - send all output to stdout
|
|
# - send exit status to stderr
|
|
# on host:
|
|
# - swap stdout and stderr
|
|
# - pass exit status to `exit`
|
|
# - send stderr back to stdout and up
|
|
(exit \
|
|
$(rsh -l root $boardip \
|
|
'(/tmp/'$1') 2>&1; ret=$?; echo $ret 1>&2; [ $ret -eq 0 ] && rm -f /tmp/'$1 \
|
|
3>&1 1>&2 2>&3) \
|
|
2>&1) 2>&1
|
|
}
|
|
|
|
dojtag() {
|
|
if grep -q CHECKREG ${1%.x} ; then
|
|
echo "DBGA does not work via JTAG"
|
|
exit 77
|
|
fi
|
|
|
|
cat <<-EOF > commands
|
|
target remote localhost:2000
|
|
load
|
|
|
|
b *_pass
|
|
commands
|
|
exit 0
|
|
end
|
|
|
|
b *_fail
|
|
commands
|
|
exit 1
|
|
end
|
|
|
|
# we're executing at EVT1, so this doesn't really help ...
|
|
set ((long *)0xFFE02000)[3] = _fail
|
|
set ((long *)0xFFE02000)[5] = _fail
|
|
|
|
c
|
|
EOF
|
|
bfin-elf-gdb -x commands "$1"
|
|
ret=$?
|
|
rm -f commands
|
|
exit ${ret}
|
|
}
|
|
|
|
testit() {
|
|
local name=$1 x=$2 y=`echo $2 | sed 's:\.[xX]$::'` out rsh_out addr
|
|
shift; shift
|
|
local fail=`grep xfail ${y}`
|
|
if [ "${name}" = "HOST" -a ! -f $x ] ; then
|
|
return
|
|
fi
|
|
printf '%-5s %-40s' ${name} ${x}
|
|
out=`"$@" ${x} 2>&1`
|
|
(pf "${out}")
|
|
if [ $? -ne 0 ] ; then
|
|
if [ "${name}" = "SIM" ] ; then
|
|
tmp=`echo ${out} | awk '{print $3}' | sed 's/://'`
|
|
tmp1=`expr index "${out}" "program stopped with signal 4"`
|
|
if [ ${tmp1} -eq 1 ] ; then
|
|
printf 'illegal instruction\n'
|
|
elif [ -n "${tmp}" ] ; then
|
|
printf 'FAIL at line '
|
|
addr=`echo $out | sed 's:^[A-Za-z ]*::' | sed 's:^0x[0-9][0-9] ::' | sed 's:^[A-Za-z ]*::' | awk '{print $1}'`
|
|
bfin-elf-addr2line -e ${x} ${addr} | awk -F "/" '{print $NF}'
|
|
fi
|
|
elif [ "${name}" = "HOST" ] ; then
|
|
rsh_out=`rsh -l root $boardip '/bin/dmesg -c | /bin/grep -e DBGA -e "FAULT "'`
|
|
tmp=`echo ${rsh_out} | sed 's:\].*$::' | awk '{print $NF}' | awk -F ":" '{print $NF}'`
|
|
if [ -n "${tmp}" ] ; then
|
|
echo "${rsh_out}"
|
|
printf 'FAIL at line '
|
|
bfin-elf-addr2line -e ${x} $(echo ${rsh_out} | sed 's:\].*$::' | awk '{print $NF}') | awk -F "/" '{print $NF}'
|
|
fi
|
|
fi
|
|
ret=$(( ret + 1 ))
|
|
if [ -z "${fail}" ] ; then
|
|
unexpected_fail=$(( unexpected_fail + 1 ))
|
|
echo "!!!Expected Pass, but fail"
|
|
fi
|
|
else
|
|
if [ ! -z "${fail}" ] ; then
|
|
unexpected_pass=$(( unexpected_pass + 1 ))
|
|
echo "!!!Expected fail, but pass"
|
|
else
|
|
expected_pass=$(( expected_pass + 1 ))
|
|
fi
|
|
fi
|
|
}
|
|
|
|
pf() {
|
|
local ret=$?
|
|
if [ ${ret} -eq 0 ] ; then
|
|
echo "PASS"
|
|
elif [ ${ret} -eq 77 ] ; then
|
|
echo "SKIP $*"
|
|
else
|
|
echo "FAIL! $*"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
[ $# -eq 0 ] && set -- *.[Ss]
|
|
bins_hw=$( (${run_sim} || ${run_jtag}) && printf '%s.x ' "$@")
|
|
if ${run_host} ; then
|
|
for files in "$@" ; do
|
|
tmp=`grep -e CYCLES -e TESTSET -e CLI -e STI -e RTX -e RTI -e SEQSTAT $files -l`
|
|
if [ -z "${tmp}" ] ; then
|
|
bins_host=`echo "${bins_host} ${files}.X"`
|
|
else
|
|
echo "skipping ${files}, since it isn't userspace friendly"
|
|
fi
|
|
done
|
|
fi
|
|
if [ -n "${bins_hw}" ] ; then
|
|
bins_all="${bins_hw}"
|
|
fi
|
|
|
|
if [ -n "${bins_host}" ] ; then
|
|
bins_all="${bins_all} ${bins_host}"
|
|
fi
|
|
|
|
if [ -z "${bins_all}" ] ; then
|
|
exit
|
|
fi
|
|
|
|
printf 'Compiling tests: '
|
|
${MAKE} -s -j ${bins_all}
|
|
pf
|
|
|
|
if ${run_jtag} ; then
|
|
printf 'Setting up gdbproxy (see gdbproxy.log): '
|
|
killall -q bfin-gdbproxy
|
|
bfin-gdbproxy -q bfin --reset --board=${boardjtag} --init-sdram >gdbproxy.log 2>&1 &
|
|
t=0
|
|
while [ ${t} -lt 5 ] ; do
|
|
if netstat -nap 2>&1 | grep -q ^tcp.*:2000.*gdbproxy ; then
|
|
break
|
|
else
|
|
: $(( t += 1 ))
|
|
sleep 1
|
|
fi
|
|
done
|
|
pf
|
|
fi
|
|
|
|
if ${run_host} ; then
|
|
printf 'Uploading tests to board "%s": ' "${boardip}"
|
|
rcp ${bins_host} root@${boardip}:/tmp/
|
|
pf
|
|
rsh -l root $boardip '/bin/dmesg -c' > /dev/null
|
|
fi
|
|
|
|
SIM="../../../bfin/run"
|
|
if [ ! -x ${SIM} ] ; then
|
|
SIM="bfin-elf-run"
|
|
fi
|
|
echo "Using sim: ${SIM}"
|
|
|
|
ret=0
|
|
unexpected_fail=0
|
|
unexpected_pass=0
|
|
expected_pass=0
|
|
pids=()
|
|
for s in "$@" ; do
|
|
(
|
|
out=$(
|
|
${run_sim} && testit SIM ${s}.x ${SIM} `sed -n '/^# sim:/s|^[^:]*:||p' ${s}`
|
|
${run_jtag} && testit JTAG ${s}.x dojtag
|
|
${run_host} && testit HOST ${s}.X dorsh
|
|
)
|
|
case $out in
|
|
*PASS*) ;;
|
|
*) echo "$out" ;;
|
|
esac
|
|
) &
|
|
pids+=( $! )
|
|
if [[ ${#pids[@]} -gt ${jobs} ]] ; then
|
|
wait ${pids[0]}
|
|
pids=( ${pids[@]:1} )
|
|
fi
|
|
done
|
|
wait
|
|
|
|
killall -q bfin-gdbproxy
|
|
if [ ${ret} -eq 0 ] ; then
|
|
rm -f gdbproxy.log
|
|
# ${MAKE} -s clean &
|
|
exit 0
|
|
else
|
|
echo number of failures ${ret}
|
|
if [ ${unexpected_pass} -gt 0 ] ; then
|
|
echo "Unexpected passes: ${unexpected_pass}"
|
|
fi
|
|
if [ ${unexpected_fail} -gt 0 ] ; then
|
|
echo "Unexpected fails: ${unexpected_fail}"
|
|
fi
|
|
if [ ${expected_pass} -gt 0 ] ; then
|
|
echo "passes : ${expected_pass}"
|
|
fi
|
|
exit 1
|
|
fi
|