1fe0aed19SLeo Yan#!/bin/sh 2fe0aed19SLeo Yan# Check Arm CoreSight trace data recording and synthesized samples 3fe0aed19SLeo Yan 4fe0aed19SLeo Yan# Uses the 'perf record' to record trace data with Arm CoreSight sinks; 5fe0aed19SLeo Yan# then verify if there have any branch samples and instruction samples 6fe0aed19SLeo Yan# are generated by CoreSight with 'perf script' and 'perf report' 7fe0aed19SLeo Yan# commands. 8fe0aed19SLeo Yan 9fe0aed19SLeo Yan# SPDX-License-Identifier: GPL-2.0 10fe0aed19SLeo Yan# Leo Yan <leo.yan@linaro.org>, 2020 11fe0aed19SLeo Yan 1211d45d4fSLeo Yanglb_err=0 13fe0aed19SLeo Yan 14fe0aed19SLeo Yanskip_if_no_cs_etm_event() { 15fe0aed19SLeo Yan perf list | grep -q 'cs_etm//' && return 0 16fe0aed19SLeo Yan 17fe0aed19SLeo Yan # cs_etm event doesn't exist 18fe0aed19SLeo Yan return 2 19fe0aed19SLeo Yan} 20fe0aed19SLeo Yan 21fe0aed19SLeo Yanskip_if_no_cs_etm_event || exit 2 22fe0aed19SLeo Yan 23133fe2e6SJames Clarkperfdata=$(mktemp /tmp/__perf_test.perf.data.XXXXX) 24133fe2e6SJames Clarkfile=$(mktemp /tmp/temporary_file.XXXXX) 25133fe2e6SJames Clark 26fe0aed19SLeo Yancleanup_files() 27fe0aed19SLeo Yan{ 28fe0aed19SLeo Yan rm -f ${perfdata} 29fe0aed19SLeo Yan rm -f ${file} 30133fe2e6SJames Clark rm -f "${perfdata}.old" 310ed4b531SAnushree Mathur trap - EXIT TERM INT 32133fe2e6SJames Clark exit $glb_err 33fe0aed19SLeo Yan} 34fe0aed19SLeo Yan 350ed4b531SAnushree Mathurtrap cleanup_files EXIT TERM INT 36fe0aed19SLeo Yan 37fe0aed19SLeo Yanrecord_touch_file() { 38fe0aed19SLeo Yan echo "Recording trace (only user mode) with path: CPU$2 => $1" 39fe0aed19SLeo Yan rm -f $file 40fe0aed19SLeo Yan perf record -o ${perfdata} -e cs_etm/@$1/u --per-thread \ 4146355e3dSLeo Yan -- taskset -c $2 touch $file > /dev/null 2>&1 42fe0aed19SLeo Yan} 43fe0aed19SLeo Yan 44fe0aed19SLeo Yanperf_script_branch_samples() { 45fe0aed19SLeo Yan echo "Looking at perf.data file for dumping branch samples:" 46fe0aed19SLeo Yan 47fe0aed19SLeo Yan # Below is an example of the branch samples dumping: 48fe0aed19SLeo Yan # touch 6512 1 branches:u: ffffb220824c strcmp+0xc (/lib/aarch64-linux-gnu/ld-2.27.so) 49fe0aed19SLeo Yan # touch 6512 1 branches:u: ffffb22082e0 strcmp+0xa0 (/lib/aarch64-linux-gnu/ld-2.27.so) 50fe0aed19SLeo Yan # touch 6512 1 branches:u: ffffb2208320 strcmp+0xe0 (/lib/aarch64-linux-gnu/ld-2.27.so) 5146355e3dSLeo Yan perf script -F,-time -i ${perfdata} 2>&1 | \ 52818448e9STiezhu Yang grep -E " +$1 +[0-9]+ .* +branches:(.*:)? +" > /dev/null 2>&1 53fe0aed19SLeo Yan} 54fe0aed19SLeo Yan 55fe0aed19SLeo Yanperf_report_branch_samples() { 56fe0aed19SLeo Yan echo "Looking at perf.data file for reporting branch samples:" 57fe0aed19SLeo Yan 58fe0aed19SLeo Yan # Below is an example of the branch samples reporting: 59fe0aed19SLeo Yan # 73.04% 73.04% touch libc-2.27.so [.] _dl_addr 60fe0aed19SLeo Yan # 7.71% 7.71% touch libc-2.27.so [.] getenv 61fe0aed19SLeo Yan # 2.59% 2.59% touch ld-2.27.so [.] strcmp 6246355e3dSLeo Yan perf report --stdio -i ${perfdata} 2>&1 | \ 63818448e9STiezhu Yang grep -E " +[0-9]+\.[0-9]+% +[0-9]+\.[0-9]+% +$1 " > /dev/null 2>&1 64fe0aed19SLeo Yan} 65fe0aed19SLeo Yan 66fe0aed19SLeo Yanperf_report_instruction_samples() { 67fe0aed19SLeo Yan echo "Looking at perf.data file for instruction samples:" 68fe0aed19SLeo Yan 69fe0aed19SLeo Yan # Below is an example of the instruction samples reporting: 70fe0aed19SLeo Yan # 68.12% touch libc-2.27.so [.] _dl_addr 71fe0aed19SLeo Yan # 5.80% touch libc-2.27.so [.] getenv 72fe0aed19SLeo Yan # 4.35% touch ld-2.27.so [.] _dl_fixup 73fe180a52SJames Clark perf report --itrace=i20i --stdio -i ${perfdata} 2>&1 | \ 74818448e9STiezhu Yang grep -E " +[0-9]+\.[0-9]+% +$1" > /dev/null 2>&1 75fe0aed19SLeo Yan} 76fe0aed19SLeo Yan 7711d45d4fSLeo Yanarm_cs_report() { 7811d45d4fSLeo Yan if [ $2 != 0 ]; then 7911d45d4fSLeo Yan echo "$1: FAIL" 8011d45d4fSLeo Yan glb_err=$2 8111d45d4fSLeo Yan else 8211d45d4fSLeo Yan echo "$1: PASS" 8311d45d4fSLeo Yan fi 8411d45d4fSLeo Yan} 8511d45d4fSLeo Yan 86fe0aed19SLeo Yanis_device_sink() { 87fe0aed19SLeo Yan # If the node of "enable_sink" is existed under the device path, this 88fe0aed19SLeo Yan # means the device is a sink device. Need to exclude 'tpiu' since it 89fe0aed19SLeo Yan # cannot support perf PMU. 90818448e9STiezhu Yang echo "$1" | grep -E -q -v "tpiu" 91fe0aed19SLeo Yan 920ed4b531SAnushree Mathur if [ $? -eq 0 ] && [ -e "$1/enable_sink" ]; then 93fe0aed19SLeo Yan 94fe0aed19SLeo Yan pmu_dev="/sys/bus/event_source/devices/cs_etm/sinks/$2" 95fe0aed19SLeo Yan 96fe0aed19SLeo Yan # Warn if the device is not supported by PMU 97fe0aed19SLeo Yan if ! [ -f $pmu_dev ]; then 98fe0aed19SLeo Yan echo "PMU doesn't support $pmu_dev" 99fe0aed19SLeo Yan fi 100fe0aed19SLeo Yan 101fe0aed19SLeo Yan return 0 102fe0aed19SLeo Yan fi 103fe0aed19SLeo Yan 104fe0aed19SLeo Yan # Otherwise, it's not a sink device 105fe0aed19SLeo Yan return 1 106fe0aed19SLeo Yan} 107fe0aed19SLeo Yan 108fe0aed19SLeo Yanarm_cs_iterate_devices() { 109fe0aed19SLeo Yan for dev in $1/connections/out\:*; do 110fe0aed19SLeo Yan 111fe0aed19SLeo Yan # Skip testing if it's not a directory 112fe0aed19SLeo Yan ! [ -d $dev ] && continue; 113fe0aed19SLeo Yan 114fe0aed19SLeo Yan # Read out its symbol link file name 115fe0aed19SLeo Yan path=`readlink -f $dev` 116fe0aed19SLeo Yan 117fe0aed19SLeo Yan # Extract device name from path, e.g. 118fe0aed19SLeo Yan # path = '/sys/devices/platform/20010000.etf/tmc_etf0' 119fe0aed19SLeo Yan # `> device_name = 'tmc_etf0' 120fe0aed19SLeo Yan device_name=$(basename $path) 121fe0aed19SLeo Yan 122db2ac2e4SLeo Yan if is_device_sink $path $device_name; then 123fe0aed19SLeo Yan 124fe0aed19SLeo Yan record_touch_file $device_name $2 && 125fe0aed19SLeo Yan perf_script_branch_samples touch && 126fe0aed19SLeo Yan perf_report_branch_samples touch && 127fe0aed19SLeo Yan perf_report_instruction_samples touch 128fe0aed19SLeo Yan 129fe0aed19SLeo Yan err=$? 13011d45d4fSLeo Yan arm_cs_report "CoreSight path testing (CPU$2 -> $device_name)" $err 131fe0aed19SLeo Yan fi 132fe0aed19SLeo Yan 133fe0aed19SLeo Yan arm_cs_iterate_devices $dev $2 134fe0aed19SLeo Yan done 135fe0aed19SLeo Yan} 136fe0aed19SLeo Yan 137fe0aed19SLeo Yanarm_cs_etm_traverse_path_test() { 138fe0aed19SLeo Yan # Iterate for every ETM device 139fe0aed19SLeo Yan for dev in /sys/bus/coresight/devices/etm*; do 140fe0aed19SLeo Yan 141fe0aed19SLeo Yan # Find the ETM device belonging to which CPU 142fe0aed19SLeo Yan cpu=`cat $dev/cpu` 143fe0aed19SLeo Yan 144fe0aed19SLeo Yan # Use depth-first search (DFS) to iterate outputs 145fe0aed19SLeo Yan arm_cs_iterate_devices $dev $cpu 146fe0aed19SLeo Yan done 147fe0aed19SLeo Yan} 148fe0aed19SLeo Yan 149fe0aed19SLeo Yanarm_cs_etm_system_wide_test() { 150fe0aed19SLeo Yan echo "Recording trace with system wide mode" 15146355e3dSLeo Yan perf record -o ${perfdata} -e cs_etm// -a -- ls > /dev/null 2>&1 152fe0aed19SLeo Yan 153d1efa4a0SJames Clark # System-wide mode should include perf samples so test for that 154d1efa4a0SJames Clark # instead of ls 155fe0aed19SLeo Yan perf_script_branch_samples perf && 156fe0aed19SLeo Yan perf_report_branch_samples perf && 157fe0aed19SLeo Yan perf_report_instruction_samples perf 158fe0aed19SLeo Yan 159fe0aed19SLeo Yan err=$? 16011d45d4fSLeo Yan arm_cs_report "CoreSight system wide testing" $err 161fe0aed19SLeo Yan} 162fe0aed19SLeo Yan 163fe0aed19SLeo Yanarm_cs_etm_snapshot_test() { 164fe0aed19SLeo Yan echo "Recording trace with snapshot mode" 165fe0aed19SLeo Yan perf record -o ${perfdata} -e cs_etm// -S \ 16646355e3dSLeo Yan -- dd if=/dev/zero of=/dev/null > /dev/null 2>&1 & 167fe0aed19SLeo Yan PERFPID=$! 168fe0aed19SLeo Yan 169fe0aed19SLeo Yan # Wait for perf program 170fe0aed19SLeo Yan sleep 1 171fe0aed19SLeo Yan 172fe0aed19SLeo Yan # Send signal to snapshot trace data 173fe0aed19SLeo Yan kill -USR2 $PERFPID 174fe0aed19SLeo Yan 175fe0aed19SLeo Yan # Stop perf program 176fe0aed19SLeo Yan kill $PERFPID 177fe0aed19SLeo Yan wait $PERFPID 178fe0aed19SLeo Yan 179fe0aed19SLeo Yan perf_script_branch_samples dd && 180fe0aed19SLeo Yan perf_report_branch_samples dd && 181fe0aed19SLeo Yan perf_report_instruction_samples dd 182fe0aed19SLeo Yan 183fe0aed19SLeo Yan err=$? 18411d45d4fSLeo Yan arm_cs_report "CoreSight snapshot testing" $err 185fe0aed19SLeo Yan} 186fe0aed19SLeo Yan 187d1efa4a0SJames Clarkarm_cs_etm_basic_test() { 188d1efa4a0SJames Clark echo "Recording trace with '$*'" 189d3ced099SJames Clark perf record -o ${perfdata} "$@" -m,8M -- ls > /dev/null 2>&1 190d1efa4a0SJames Clark 191d1efa4a0SJames Clark perf_script_branch_samples ls && 192d1efa4a0SJames Clark perf_report_branch_samples ls && 193d1efa4a0SJames Clark perf_report_instruction_samples ls 194d1efa4a0SJames Clark 195d1efa4a0SJames Clark err=$? 196d1efa4a0SJames Clark arm_cs_report "CoreSight basic testing with '$*'" $err 197d1efa4a0SJames Clark} 198d1efa4a0SJames Clark 199fe0aed19SLeo Yanarm_cs_etm_traverse_path_test 200fe0aed19SLeo Yanarm_cs_etm_system_wide_test 201fe0aed19SLeo Yanarm_cs_etm_snapshot_test 202d1efa4a0SJames Clark 203d1efa4a0SJames Clark# Test all combinations of per-thread, system-wide and normal mode with 204d1efa4a0SJames Clark# and without timestamps 205d1efa4a0SJames Clarkarm_cs_etm_basic_test -e cs_etm/timestamp=0/ --per-thread 206d1efa4a0SJames Clarkarm_cs_etm_basic_test -e cs_etm/timestamp=1/ --per-thread 207d1efa4a0SJames Clarkarm_cs_etm_basic_test -e cs_etm/timestamp=0/ -a 208d1efa4a0SJames Clarkarm_cs_etm_basic_test -e cs_etm/timestamp=1/ -a 209d1efa4a0SJames Clarkarm_cs_etm_basic_test -e cs_etm/timestamp=0/ 210d1efa4a0SJames Clarkarm_cs_etm_basic_test -e cs_etm/timestamp=1/ 211d1efa4a0SJames Clark 21211d45d4fSLeo Yanexit $glb_err 213