From 6202cbb34e47a342ab36f8f231dd415310bc92ae Mon Sep 17 00:00:00 2001 From: Srikanth Muppandam Date: Tue, 22 Jul 2025 13:43:56 +0530 Subject: [PATCH] baseport: remoteproc: adsp/cdsp/gpdsp/wpss tests: SoC-aware skips, RPMsg probe, shellcheck fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Discover RProc nodes via find_remoteproc_by_firmware() instead of hardcoded IDs. - Skip cleanly when a core isn’t present on the SoC (no more false FAILs). - Stop/Start paths now wait_for_state()/wait_remoteproc_state() with timeouts & polling. - Dump rproc logs around each transition (before/after stop/start) for easier CI debug. - Add generic RPMsg exercise: * Map rpmsg_ctrl* to the owning remoteproc. * Reuse/create endpoints and try an echo; mark PASS/FAIL/SKIPPED accordingly. - CDSP: handle multi-instance (cdsp0/cdsp1…/gpdsp0/gpdsp1...) and print per-instance boot/stop/start/ping results. - WPSS: keep driver fallback (ath11k/ath11xx) if remoteproc is absent: * Validate firmware via /lib/firmware/ath11k blobs, dmesg strings, and wlan*/ath* netdev presence. * POSIX-safe globbing instead of grep-regex for interface detection. - Ensure .res contains only “TESTNAME ”; everything else goes to log. - ShellCheck cleanup: SC2143, SC2181, SC3037, SC2034, etc. (no unused vars, no `$?` chains, printf over echo -e). - Added/updated helpers in functestlib.sh (rpmsg_* helpers, dump_rproc_logs, wait_remoteproc_state, etc.). - Protect concurrent runs with acquire_test_lock()/release_test_lock(). - Added DT check for each adsp/cdsp/wpss tests - Added dt_has_remoteproc_fw to read the /proc/device-tree for the given fw. Signed-off-by: Srikanth Muppandam --- .../Kernel/Baseport/adsp_remoteproc/run.sh | 159 ++++++-- .../Kernel/Baseport/cdsp_remoteproc/run.sh | 159 ++++++-- .../Kernel/Baseport/gpdsp_remoteproc/run.sh | 170 +++++++++ .../Kernel/Baseport/wpss_remoteproc/run.sh | 206 ++++++++-- Runner/utils/functestlib.sh | 358 ++++++++++++++++-- 5 files changed, 924 insertions(+), 128 deletions(-) create mode 100644 Runner/suites/Kernel/Baseport/gpdsp_remoteproc/run.sh diff --git a/Runner/suites/Kernel/Baseport/adsp_remoteproc/run.sh b/Runner/suites/Kernel/Baseport/adsp_remoteproc/run.sh index 870cb0e9..2b1f209c 100755 --- a/Runner/suites/Kernel/Baseport/adsp_remoteproc/run.sh +++ b/Runner/suites/Kernel/Baseport/adsp_remoteproc/run.sh @@ -29,44 +29,139 @@ fi . "$TOOLS/functestlib.sh" TESTNAME="adsp_remoteproc" -firmware_name="adsp" -res_file="./$TESTNAME.res" -LOG_FILE="./$TESTNAME.log" - +RES_FILE="./$TESTNAME.res" +FW="adsp" + test_path=$(find_test_case_by_name "$TESTNAME") cd "$test_path" || exit 1 log_info "-----------------------------------------------------------------------------------------" log_info "------------------- Starting $TESTNAME Testcase ----------------------------" log_info "=== Test Initialization ===" - -if ! validate_remoteproc_running "$firmware_name" "$LOG_FILE" 15 2; then - log_fail "$firmware_name remoteproc is not in running state after bootup" - echo "$TESTNAME FAIL" > "$res_file" - exit 1 + +# Tunables +STOP_TO="${STOP_TO:-10}" +START_TO="${START_TO:-10}" +POLL_I="${POLL_I:-1}" + +log_info "DEBUG: STOP_TO=$STOP_TO START_TO=$START_TO POLL_I=$POLL_I" + +# DT check for entries +if dt_has_remoteproc_fw "$FW"; then + log_info "DT indicates $FW is present" +else + log_skip "$TESTNAME SKIP – $FW not described in DT" + echo "$TESTNAME SKIP" >"$RES_FILE" + exit 0 fi - -log_pass "$firmware_name remoteproc validated as running" - -rproc_path=$(get_remoteproc_path_by_firmware "$firmware_name") - -stop_remoteproc "$rproc_path" || { - log_fail "$TESTNAME stop failed" - echo "$TESTNAME FAIL" > "$res_file" - exit 1 -} -log_pass "$firmware_name stop successful" - -log_info "Restarting $firmware_name" -start_remoteproc "$rproc_path" || { - log_fail "$TESTNAME start failed" - echo "$TESTNAME FAIL" > "$res_file" + +# Enumerate ADSP remoteproc entries +# get_remoteproc_by_firmware prints: "path|state|firmware|name" +entries="$(get_remoteproc_by_firmware "$FW" "" all)" || entries="" +if [ -z "$entries" ]; then + fail_and_exit "$FW present in DT but no /sys/class/remoteproc entry found" +fi + +count_instances=$(printf '%s\n' "$entries" | wc -l) +log_info "Found $count_instances $FW instance(s)" + +inst_fail=0 +RESULT_LINES="" + +tmp_list="$(mktemp)" +printf '%s\n' "$entries" >"$tmp_list" + +while IFS='|' read -r rpath rstate rfirm rname; do + [ -n "$rpath" ] || continue + + inst_id="$(basename "$rpath")" + log_info "---- $inst_id: path=$rpath state=$rstate firmware=$rfirm name=$rname ----" + + boot_res="PASS" + stop_res="NA" + start_res="NA" + ping_res="SKIPPED" + + # Boot check + if [ "$rstate" = "running" ]; then + log_pass "$inst_id: boot check PASS" + else + log_fail "$inst_id: boot check FAIL (state=$rstate)" + boot_res="FAIL" + inst_fail=$((inst_fail + 1)) + RESULT_LINES="$RESULT_LINES + $inst_id: boot=$boot_res, stop=$stop_res, start=$start_res, ping=$ping_res" + continue + fi + + # Stop + dump_rproc_logs "$rpath" before-stop + t0=$(date +%s) + log_info "$inst_id: stopping" + if stop_remoteproc "$rpath" && wait_remoteproc_state "$rpath" offline "$STOP_TO" "$POLL_I"; then + t1=$(date +%s) + log_pass "$inst_id: stop PASS ($((t1 - t0))s)" + stop_res="PASS" + else + dump_rproc_logs "$rpath" after-stop-fail + log_fail "$inst_id: stop FAIL" + stop_res="FAIL" + inst_fail=$((inst_fail + 1)) + RESULT_LINES="$RESULT_LINES + $inst_id: boot=$boot_res, stop=$stop_res, start=$start_res, ping=$ping_res" + continue + fi + dump_rproc_logs "$rpath" after-stop + + # Start + dump_rproc_logs "$rpath" before-start + t2=$(date +%s) + log_info "$inst_id: starting" + if start_remoteproc "$rpath" && wait_remoteproc_state "$rpath" running "$START_TO" "$POLL_I"; then + t3=$(date +%s) + log_pass "$inst_id: start PASS ($((t3 - t2))s)" + start_res="PASS" + else + dump_rproc_logs "$rpath" after-start-fail + log_fail "$inst_id: start FAIL" + start_res="FAIL" + inst_fail=$((inst_fail + 1)) + RESULT_LINES="$RESULT_LINES + $inst_id: boot=$boot_res, stop=$stop_res, start=$start_res, ping=$ping_res" + continue + fi + dump_rproc_logs "$rpath" after-start + + # Optional RPMsg ping + if CTRL_DEV=$(find_rpmsg_ctrl_for "$FW"); then + log_info "$inst_id: RPMsg ctrl dev: $CTRL_DEV" + if rpmsg_ping_generic "$CTRL_DEV"; then + log_pass "$inst_id: rpmsg ping PASS" + ping_res="PASS" + else + log_warn "$inst_id: rpmsg ping FAIL" + ping_res="FAIL" + inst_fail=$((inst_fail + 1)) + fi + else + log_info "$inst_id: no RPMsg channel, skipping ping" + fi + + RESULT_LINES="$RESULT_LINES + $inst_id: boot=$boot_res, stop=$stop_res, start=$start_res, ping=$ping_res" + +done <"$tmp_list" +rm -f "$tmp_list" + +# Summary +log_info "Instance results:$RESULT_LINES" + +if [ "$inst_fail" -gt 0 ]; then + log_fail "One or more $FW instance(s) failed ($inst_fail/$count_instances)" + echo "$TESTNAME FAIL" >"$RES_FILE" exit 1 -} - -log_pass "$firmware_name PASS" -echo "$TESTNAME PASS" > "$res_file" - -log_info "------------------- Completed $TESTNAME Testcase ----------------------------" +fi + +log_pass "All $count_instances $FW instance(s) passed" +echo "$TESTNAME PASS" >"$RES_FILE" exit 0 - \ No newline at end of file diff --git a/Runner/suites/Kernel/Baseport/cdsp_remoteproc/run.sh b/Runner/suites/Kernel/Baseport/cdsp_remoteproc/run.sh index def45b50..cb53922a 100755 --- a/Runner/suites/Kernel/Baseport/cdsp_remoteproc/run.sh +++ b/Runner/suites/Kernel/Baseport/cdsp_remoteproc/run.sh @@ -2,6 +2,7 @@ # Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. # SPDX-License-Identifier: BSD-3-Clause-Clear + # Robustly find and source init_env SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" INIT_ENV="" @@ -29,9 +30,8 @@ fi . "$TOOLS/functestlib.sh" TESTNAME="cdsp_remoteproc" -firmware_name="cdsp" -res_file="./$TESTNAME.res" -LOG_FILE="./$TESTNAME.log" +RES_FILE="./$TESTNAME.res" +FW="cdsp" test_path=$(find_test_case_by_name "$TESTNAME") cd "$test_path" || exit 1 @@ -39,34 +39,131 @@ cd "$test_path" || exit 1 log_info "-----------------------------------------------------------------------------------------" log_info "------------------- Starting $TESTNAME Testcase ----------------------------" log_info "=== Test Initialization ===" - -if ! validate_remoteproc_running "$firmware_name" "$LOG_FILE" 15 2; then - log_fail "$firmware_name remoteproc is not in running state after bootup" - echo "$TESTNAME FAIL" > "$res_file" - exit 1 + +# Timeouts (can be overridden via env) +STOP_TO="${STOP_TO:-10}" +START_TO="${START_TO:-10}" +POLL_I="${POLL_I:-1}" + +log_info "DEBUG: STOP_TO=$STOP_TO START_TO=$START_TO POLL_I=$POLL_I" + +# --- Device Tree gate ---------------------------------------------------- +if dt_has_remoteproc_fw "$FW"; then + log_info "DT indicates $FW is present" +else + log_skip "$TESTNAME SKIP – $FW not described in DT" + echo "${TESTNAME} SKIP" >"$RES_FILE" + exit 0 fi - -log_pass "$firmware_name remoteproc validated as running" - -rproc_path=$(get_remoteproc_path_by_firmware "$firmware_name") - -stop_remoteproc "$rproc_path" || { - log_fail "$TESTNAME stop failed" - echo "$TESTNAME FAIL" > "$res_file" - exit 1 -} -log_pass "$firmware_name stop successful" - -log_info "Restarting $firmware_name" -start_remoteproc "$rproc_path" || { - log_fail "$TESTNAME start failed" - echo "$TESTNAME FAIL" > "$res_file" + +# ---------- Discover all matching remoteproc entries ---------- +# get_remoteproc_by_firmware prints: "path|state|firmware|name" +entries="$(get_remoteproc_by_firmware "$FW" "" all)" || entries="" +if [ -z "$entries" ]; then + fail_and_exit "$FW present in DT but no /sys/class/remoteproc entry found" +fi + +count_instances=$(printf '%s\n' "$entries" | wc -l) +log_info "Found $count_instances $FW instance(s)" + +inst_fail=0 +RESULT_LINES="" + +# Avoid subshell var-scope issues: feed loop from a temp file +tmp_list="$(mktemp)" +printf '%s\n' "$entries" >"$tmp_list" + +while IFS='|' read -r rpath rstate rfirm rname; do + [ -n "$rpath" ] || continue # safety + + inst_id="$(basename "$rpath")" + log_info "---- $inst_id: path=$rpath state=$rstate firmware=$rfirm name=$rname ----" + + boot_res="PASS" + stop_res="NA" + start_res="NA" + ping_res="SKIPPED" + + # Boot check + if [ "$rstate" = "running" ]; then + log_pass "$inst_id: boot check PASS" + else + log_fail "$inst_id: boot check FAIL (state=$rstate)" + boot_res="FAIL" + inst_fail=$((inst_fail + 1)) + RESULT_LINES="$RESULT_LINES + $inst_id: boot=$boot_res, stop=$stop_res, start=$start_res, ping=$ping_res" + continue + fi + + # Stop + dump_rproc_logs "$rpath" before-stop + t0=$(date +%s) + log_info "$inst_id: stopping" + if stop_remoteproc "$rpath" && wait_remoteproc_state "$rpath" offline "$STOP_TO" "$POLL_I"; then + t1=$(date +%s) + log_pass "$inst_id: stop PASS ($((t1 - t0))s)" + stop_res="PASS" + else + dump_rproc_logs "$rpath" after-stop-fail + log_fail "$inst_id: stop FAIL" + stop_res="FAIL" + inst_fail=$((inst_fail + 1)) + RESULT_LINES="$RESULT_LINES + $inst_id: boot=$boot_res, stop=$stop_res, start=$start_res, ping=$ping_res" + continue + fi + dump_rproc_logs "$rpath" after-stop + + # Start + dump_rproc_logs "$rpath" before-start + t2=$(date +%s) + log_info "$inst_id: starting" + if start_remoteproc "$rpath" && wait_remoteproc_state "$rpath" running "$START_TO" "$POLL_I"; then + t3=$(date +%s) + log_pass "$inst_id: start PASS ($((t3 - t2))s)" + start_res="PASS" + else + dump_rproc_logs "$rpath" after-start-fail + log_fail "$inst_id: start FAIL" + start_res="FAIL" + inst_fail=$((inst_fail + 1)) + RESULT_LINES="$RESULT_LINES + $inst_id: boot=$boot_res, stop=$stop_res, start=$start_res, ping=$ping_res" + continue + fi + dump_rproc_logs "$rpath" after-start + + # Optional RPMsg ping + if CTRL_DEV=$(find_rpmsg_ctrl_for "$FW"); then + log_info "$inst_id: RPMsg ctrl dev: $CTRL_DEV" + if rpmsg_ping_generic "$CTRL_DEV"; then + log_pass "$inst_id: rpmsg ping PASS" + ping_res="PASS" + else + log_warn "$inst_id: rpmsg ping FAIL" + ping_res="FAIL" + inst_fail=$((inst_fail + 1)) + fi + else + log_info "$inst_id: no RPMsg channel, skipping ping" + fi + + RESULT_LINES="$RESULT_LINES + $inst_id: boot=$boot_res, stop=$stop_res, start=$start_res, ping=$ping_res" + +done <"$tmp_list" +rm -f "$tmp_list" + +# ---------- Summary ---------- +log_info "Instance results:$RESULT_LINES" + +if [ "$inst_fail" -gt 0 ]; then + log_fail "One or more $FW instance(s) failed ($inst_fail/$count_instances)" + echo "$TESTNAME FAIL" >"$RES_FILE" exit 1 -} - -log_pass "$firmware_name PASS" -echo "$TESTNAME PASS" > "$res_file" - -log_info "------------------- Completed $TESTNAME Testcase ----------------------------" +fi + +log_pass "All $count_instances $FW instance(s) passed" +echo "$TESTNAME PASS" >"$RES_FILE" exit 0 - \ No newline at end of file diff --git a/Runner/suites/Kernel/Baseport/gpdsp_remoteproc/run.sh b/Runner/suites/Kernel/Baseport/gpdsp_remoteproc/run.sh new file mode 100644 index 00000000..2186555e --- /dev/null +++ b/Runner/suites/Kernel/Baseport/gpdsp_remoteproc/run.sh @@ -0,0 +1,170 @@ +#!/bin/sh + +# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +# SPDX-License-Identifier: BSD-3-Clause-Clear +# +# Robustly find and source init_env +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +INIT_ENV="" +SEARCH="$SCRIPT_DIR" +while [ "$SEARCH" != "/" ]; do + if [ -f "$SEARCH/init_env" ]; then + INIT_ENV="$SEARCH/init_env" + break + fi + SEARCH=$(dirname "$SEARCH") +done + +if [ -z "$INIT_ENV" ]; then + echo "[ERROR] Could not find init_env (starting at $SCRIPT_DIR)" >&2 + exit 1 +fi + +# Only source if not already loaded (idempotent) +if [ -z "$__INIT_ENV_LOADED" ]; then + # shellcheck disable=SC1090 + . "$INIT_ENV" +fi +# Always source functestlib.sh, using $TOOLS exported by init_env +# shellcheck disable=SC1090,SC1091 +. "$TOOLS/functestlib.sh" + +TESTNAME="gpdsp_remoteproc" +RES_FILE="./$TESTNAME.res" +FW="gpdsp" + +test_path=$(find_test_case_by_name "$TESTNAME") +cd "$test_path" || exit 1 + +log_info "-----------------------------------------------------------------------------------------" +log_info "------------------- Starting $TESTNAME Testcase ----------------------------" +log_info "=== Test Initialization ===" + +# Tunables +STOP_TO="${STOP_TO:-10}" +START_TO="${START_TO:-10}" +POLL_I="${POLL_I:-1}" + +log_info "DEBUG: STOP_TO=$STOP_TO START_TO=$START_TO POLL_I=$POLL_I" + +# DT check for entries +if dt_has_remoteproc_fw "$FW"; then + log_info "DT indicates $FW is present" +else + log_skip "$TESTNAME SKIP – $FW not described in DT" + echo "$TESTNAME SKIP" >"$RES_FILE" + exit 0 +fi + +# Enumerate GPDSP remoteproc entries +# get_remoteproc_by_firmware prints lines like: "path|state|firmware|name" +entries="$(get_remoteproc_by_firmware "$FW" "" all)" || entries="" +if [ -z "$entries" ]; then + log_fail "$FW present in DT but no /sys/class/remoteproc entry found" + echo "$TESTNAME FAIL" >"$RES_FILE" + exit 1 +fi + +count_instances=$(printf '%s\n' "$entries" | wc -l) +log_info "Found $count_instances $FW instance(s)" + +inst_fail=0 +RESULT_LINES="" + +tmp_list="$(mktemp)" +printf '%s\n' "$entries" >"$tmp_list" + +while IFS='|' read -r rpath rstate rfirm rname; do + [ -n "$rpath" ] || continue + + inst_id="$(basename "$rpath")" + log_info "---- $inst_id: path=$rpath state=$rstate firmware=$rfirm name=$rname ----" + + boot_res="PASS" + stop_res="NA" + start_res="NA" + ping_res="SKIPPED" + + # Boot check + if [ "$rstate" = "running" ]; then + log_pass "$inst_id: boot check PASS" + else + log_fail "$inst_id: boot check FAIL (state=$rstate)" + boot_res="FAIL" + inst_fail=$((inst_fail + 1)) + RESULT_LINES="$RESULT_LINES + $inst_id: boot=$boot_res, stop=$stop_res, start=$start_res, ping=$ping_res" + continue + fi + + # Stop + dump_rproc_logs "$rpath" before-stop + t0=$(date +%s) + log_info "$inst_id: stopping" + if stop_remoteproc "$rpath" && wait_remoteproc_state "$rpath" offline "$STOP_TO" "$POLL_I"; then + t1=$(date +%s) + log_pass "$inst_id: stop PASS ($((t1 - t0))s)" + stop_res="PASS" + else + dump_rproc_logs "$rpath" after-stop-fail + log_fail "$inst_id: stop FAIL" + stop_res="FAIL" + inst_fail=$((inst_fail + 1)) + RESULT_LINES="$RESULT_LINES + $inst_id: boot=$boot_res, stop=$stop_res, start=$start_res, ping=$ping_res" + continue + fi + dump_rproc_logs "$rpath" after-stop + + # Start + dump_rproc_logs "$rpath" before-start + t2=$(date +%s) + log_info "$inst_id: starting" + if start_remoteproc "$rpath" && wait_remoteproc_state "$rpath" running "$START_TO" "$POLL_I"; then + t3=$(date +%s) + log_pass "$inst_id: start PASS ($((t3 - t2))s)" + start_res="PASS" + else + dump_rproc_logs "$rpath" after-start-fail + log_fail "$inst_id: start FAIL" + start_res="FAIL" + inst_fail=$((inst_fail + 1)) + RESULT_LINES="$RESULT_LINES + $inst_id: boot=$boot_res, stop=$stop_res, start=$start_res, ping=$ping_res" + continue + fi + dump_rproc_logs "$rpath" after-start + + # Optional RPMsg ping + if CTRL_DEV=$(find_rpmsg_ctrl_for "$FW"); then + log_info "$inst_id: RPMsg ctrl dev: $CTRL_DEV" + if rpmsg_ping_generic "$CTRL_DEV"; then + log_pass "$inst_id: rpmsg ping PASS" + ping_res="PASS" + else + log_warn "$inst_id: rpmsg ping FAIL" + ping_res="FAIL" + inst_fail=$((inst_fail + 1)) + fi + else + log_info "$inst_id: no RPMsg channel, skipping ping" + fi + + RESULT_LINES="$RESULT_LINES + $inst_id: boot=$boot_res, stop=$stop_res, start=$start_res, ping=$ping_res" + +done <"$tmp_list" +rm -f "$tmp_list" + +# Summary +log_info "Instance results:$RESULT_LINES" + +if [ "$inst_fail" -gt 0 ]; then + log_fail "One or more $FW instance(s) failed ($inst_fail/$count_instances)" + echo "$TESTNAME FAIL" >"$RES_FILE" + exit 1 +fi + +log_pass "All $count_instances $FW instance(s) passed" +echo "$TESTNAME PASS" >"$RES_FILE" +exit 0 diff --git a/Runner/suites/Kernel/Baseport/wpss_remoteproc/run.sh b/Runner/suites/Kernel/Baseport/wpss_remoteproc/run.sh index a6a5c131..05faaa4a 100755 --- a/Runner/suites/Kernel/Baseport/wpss_remoteproc/run.sh +++ b/Runner/suites/Kernel/Baseport/wpss_remoteproc/run.sh @@ -29,44 +29,178 @@ fi . "$TOOLS/functestlib.sh" TESTNAME="wpss_remoteproc" -firmware_name="wpss" -res_file="./$TESTNAME.res" -LOG_FILE="./$TESTNAME.log" - -test_path=$(find_test_case_by_name "$TESTNAME") -cd "$test_path" || exit 1 - +FW="wpss" +RES_FILE="./$TESTNAME.res" + log_info "-----------------------------------------------------------------------------------------" log_info "------------------- Starting $TESTNAME Testcase ----------------------------" log_info "=== Test Initialization ===" - -if ! validate_remoteproc_running "$firmware_name" "$LOG_FILE" 15 2; then - log_fail "$firmware_name remoteproc is not in running state after bootup" - echo "$TESTNAME FAIL" > "$res_file" - exit 1 + +# Tunables +STOP_TO="${STOP_TO:-10}" +START_TO="${START_TO:-10}" +POLL_I="${POLL_I:-1}" + +# ---------- Try remoteproc path ---------- +rp_entries="" +dt_says_present=0 + +if dt_has_remoteproc_fw "$FW"; then + dt_says_present=1 + log_info "DT indicates $FW is present" + # prints: path|state|firmware|name (multiple lines) + rp_entries="$(get_remoteproc_by_firmware "$FW" "" all)" || rp_entries="" +else + log_info "DT does NOT list $FW – may be driver-loaded (ath11k) on this platform" fi - -log_pass "$firmware_name remoteproc validated as running" - -rproc_path=$(get_remoteproc_path_by_firmware "$firmware_name") - -stop_remoteproc "$rproc_path" || { - log_fail "$TESTNAME stop failed" - echo "$TESTNAME FAIL" > "$res_file" - exit 1 -} -log_pass "$firmware_name stop successful" - -log_info "Restarting $firmware_name" -start_remoteproc "$rproc_path" || { - log_fail "$TESTNAME start failed" - echo "$TESTNAME FAIL" > "$res_file" - exit 1 -} - -log_pass "$firmware_name PASS" -echo "$TESTNAME PASS" > "$res_file" - -log_info "------------------- Completed $TESTNAME Testcase ----------------------------" + +if [ -n "$rp_entries" ]; then + log_info "Remoteproc mode selected (found $(printf '%s\n' "$rp_entries" | wc -l) instance(s))" + + inst_fail=0 + RESULT_LINES="" + tmp_list="$(mktemp)" + printf '%s\n' "$rp_entries" >"$tmp_list" + + while IFS='|' read -r rpath rstate rfirm rname; do + [ -n "$rpath" ] || continue + inst="$(basename "$rpath")" + + log_info "---- $inst: path=$rpath state=$rstate firmware=$rfirm name=$rname ----" + + boot_res="PASS" + stop_res="NA" + start_res="NA" + ping_res="SKIPPED" + + # Boot check + if [ "$rstate" = "running" ]; then + log_pass "$inst: boot check PASS" + else + log_fail "$inst: boot check FAIL (state=$rstate)" + boot_res="FAIL" + inst_fail=$((inst_fail + 1)) + RESULT_LINES="$RESULT_LINES + $inst: boot=$boot_res, stop=$stop_res, start=$start_res, ping=$ping_res" + continue + fi + + # Stop + dump_rproc_logs "$rpath" before-stop + t0=$(date +%s) + log_info "$inst: stopping" + if stop_remoteproc "$rpath" && wait_remoteproc_state "$rpath" offline "$STOP_TO" "$POLL_I"; then + t1=$(date +%s) + log_pass "$inst: stop PASS ($((t1 - t0))s)" + stop_res="PASS" + else + dump_rproc_logs "$rpath" after-stop-fail + log_fail "$inst: stop FAIL" + stop_res="FAIL" + inst_fail=$((inst_fail + 1)) + RESULT_LINES="$RESULT_LINES + $inst: boot=$boot_res, stop=$stop_res, start=$start_res, ping=$ping_res" + continue + fi + dump_rproc_logs "$rpath" after-stop + + # Start + dump_rproc_logs "$rpath" before-start + t2=$(date +%s) + log_info "$inst: starting" + if start_remoteproc "$rpath" && wait_remoteproc_state "$rpath" running "$START_TO" "$POLL_I"; then + t3=$(date +%s) + log_pass "$inst: start PASS ($((t3 - t2))s)" + start_res="PASS" + else + dump_rproc_logs "$rpath" after-start-fail + log_fail "$inst: start FAIL" + start_res="FAIL" + inst_fail=$((inst_fail + 1)) + RESULT_LINES="$RESULT_LINES + $inst: boot=$boot_res, stop=$stop_res, start=$start_res, ping=$ping_res" + continue + fi + dump_rproc_logs "$rpath" after-start + + # RPMsg ping (optional) + if CTRL_DEV=$(find_rpmsg_ctrl_for "$FW"); then + log_info "$inst: RPMsg ctrl dev: $CTRL_DEV" + if rpmsg_ping_generic "$CTRL_DEV"; then + log_pass "$inst: rpmsg ping PASS" + ping_res="PASS" + else + log_warn "$inst: rpmsg ping FAIL" + ping_res="FAIL" + inst_fail=$((inst_fail + 1)) + fi + else + log_info "$inst: no RPMsg channel, skipping ping" + fi + + RESULT_LINES="$RESULT_LINES + $inst: boot=$boot_res, stop=$stop_res, start=$start_res, ping=$ping_res" + + done <"$tmp_list" + rm -f "$tmp_list" + + log_info "Instance results:$RESULT_LINES" + + if [ "$inst_fail" -gt 0 ]; then + log_fail "One or more $FW instance(s) failed ($inst_fail)" + echo "$TESTNAME FAIL" >"$RES_FILE" + exit 1 + fi + + log_pass "All $FW remoteproc instance(s) passed" + echo "$TESTNAME PASS" >"$RES_FILE" + exit 0 +fi + +# ---------- Fallback: ath11k driver mode ---------- +log_info "Remoteproc instance not used → checking ath11k driver path" + +# Is ath11k/ath11xx loaded? +if lsmod | grep -qE '^ath11k(_pci)?\b'; then + log_pass "ath11k driver is loaded" +else + # Try modprobe quietly + if command -v modprobe >/dev/null 2>&1 && modprobe ath11k_pci 2>/dev/null; then + log_info "Loaded ath11k_pci via modprobe" + fi + + if lsmod | grep -qE '^ath11k(_pci)?\b'; then + log_pass "ath11k driver loaded (post-modprobe)" + else + # If DT said WPSS present but neither remoteproc nor driver -> FAIL + if [ "$dt_says_present" -eq 1 ]; then + fail_and_exit "DT lists $FW but no remoteproc and ath11k not loaded" + fi + log_skip "$TESTNAME SKIP – neither remoteproc nor ath11k path available" + echo "$TESTNAME SKIP" >"$RES_FILE" + exit 0 + fi +fi + +# Firmware presence check (paths may vary, so just log) +if [ -d /lib/firmware/ath11k ]; then + log_info "Found /lib/firmware/ath11k directory" +else + log_warn "No /lib/firmware/ath11k directory found" +fi + +# Dmesg scan for errors/success +scan_dmesg_errors "ath11k|wpss" "." "crash|timeout|fail" "fw_version|firmware" +# (Return codes from scan_dmesg_errors are informational; it logs itself) + +# Net interface presence is informative +set -- /sys/class/net/wlan[0-9]* 2>/dev/null +if [ -e "$1" ]; then + log_info "wlan interface present (ath11k up)" +else + log_info "No wlan interface yet (maybe not brought up)" +fi +# Final result for driver path: PASS if we got here +log_pass "WPSS driver path checks passed" +echo "$TESTNAME PASS" >"$RES_FILE" exit 0 - \ No newline at end of file diff --git a/Runner/utils/functestlib.sh b/Runner/utils/functestlib.sh index 79a52983..18292b50 100755 --- a/Runner/utils/functestlib.sh +++ b/Runner/utils/functestlib.sh @@ -1011,54 +1011,183 @@ bt_l2ping_check() { return 1 fi } -# Find remoteproc path by firmware substring -get_remoteproc_path_by_firmware() { - name="$1" - idx="" - path="" - idx=$(cat /sys/class/remoteproc/remoteproc*/firmware 2>/dev/null | grep -n "$name" | cut -d: -f1 | head -n1) - [ -z "$idx" ] && return 1 - idx=$((idx - 1)) - path="/sys/class/remoteproc/remoteproc${idx}" - [ -d "$path" ] && echo "$path" && return 0 + +############################################################################### +# get_remoteproc_by_firmware [outfile] [all] +# - If outfile is given: append *all* matches as "|||" +# (one per line) and return 0 if at least one match. +# - If no outfile: print the *first* match to stdout and return 0. +# - Returns 1 if nothing matched, 3 if misuse (no fw argument). +############################################################################### +get_remoteproc_by_firmware() { + fw="$1" + out="$2" # optional: filepath to append results + list_all="$3" # set to "all" to continue past first match + + [ -n "$fw" ] || return 3 # misuse if no firmware provided + + found=0 + for p in /sys/class/remoteproc/remoteproc*; do + [ -d "$p" ] || continue + + # read name, firmware, state + name="" + [ -r "$p/name" ] && IFS= read -r name <"$p/name" + firmware="" + [ -r "$p/firmware" ] && IFS= read -r firmware <"$p/firmware" + state="unknown" + [ -r "$p/state" ] && IFS= read -r state <"$p/state" + + case "$name $firmware" in + *"$fw"*) + line="${p}|${state}|${firmware}|${name}" + if [ -n "$out" ]; then + printf '%s\n' "$line" >>"$out" + found=1 + continue + fi + + # print to stdout and possibly stop + printf '%s\n' "$line" + found=1 + [ "$list_all" = "all" ] || return 0 + ;; + esac + done + + # if we appended to a file, success if found>=1 + if [ "$found" -eq 1 ]; then + return 0 + else + return 1 + fi +} + +# ------------------------------------------------------------------------------ +# dt_has_remoteproc_fw +# Return: +# 0 = DT describes this remoteproc firmware +# 1 = DT does not describe it +# 3 = misuse (no argument) +# ------------------------------------------------------------------------------ +dt_has_remoteproc_fw() { + fw="$1" + [ -n "$fw" ] || return 3 + + base="/proc/device-tree" + [ -d "$base" ] || return 1 + + # lower-case match key + fw_lc=$(printf '%s\n' "$fw" | tr '[:upper:]' '[:lower:]') + + # new fast-path (any smp2p-* or remoteproc-* directory) + found=0 + for d in "$base"/smp2p-"$fw"* "$base"/remoteproc-"$fw"*; do + [ -d "$d" ] && found=1 && break + done + [ "$found" -eq 1 ] && return 0 + + # 2) Shallow find (/dev/null | grep -q .; then + return 0 + fi + + # 3) Grep soc@0 and aliases for a first match + if grep -Iq -m1 -F "$fw_lc" "$base/soc@0" "$base/aliases" 2>/dev/null; then + return 0 + fi + + # 4) Fallback: grep entire DT tree + if grep -Iq -m1 -F "$fw_lc" "$base" 2>/dev/null; then + return 0 + fi + return 1 } # Get remoteproc state get_remoteproc_state() { - rproc_path="$1" - [ -f "$rproc_path/state" ] && cat "$rproc_path/state" + rp="$1" + [ -z "$rp" ] && { printf '\n'; return 1; } + + case "$rp" in + /sys/*) rpath="$rp" ;; + *) rpath="/sys/class/remoteproc/$rp" ;; + esac + + state_file="$rpath/state" + if [ -r "$state_file" ]; then + IFS= read -r state < "$state_file" || state="" + printf '%s\n' "$state" + return 0 + fi + printf '\n' + return 1 } -# Wait for a remoteproc to reach a specific state +# wait_remoteproc_state wait_remoteproc_state() { - rproc_path="$1" - target="$2" - retries="${3:-6}" - i=0 - while [ $i -lt "$retries" ]; do - state=$(get_remoteproc_state "$rproc_path") - [ "$state" = "$target" ] && return 0 - sleep 1 - i=$((i+1)) + rp="$1"; want="$2"; to=${3:-10}; poll=${4:-1} + + case "$rp" in + /sys/*) rpath="$rp" ;; + *) rpath="/sys/class/remoteproc/$rp" ;; + esac + + start_ts=$(date +%s) + while :; do + cur=$(get_remoteproc_state "$rpath") + [ "$cur" = "$want" ] && return 0 + + now_ts=$(date +%s) + [ $((now_ts - start_ts)) -ge "$to" ] && { + log_info "Waiting for state='$want' timed out (got='$cur')..." + return 1 + } + sleep "$poll" done - return 1 } # Stop remoteproc stop_remoteproc() { rproc_path="$1" - echo stop > "$rproc_path/state" - wait_remoteproc_state "$rproc_path" "offline" 6 + + # Resolve to a real sysfs dir if only a name was given + case "$rproc_path" in + /sys/*) path="$rproc_path" ;; + remoteproc*) path="/sys/class/remoteproc/$rproc_path" ;; + *) path="$rproc_path" ;; # last resort, assume caller passed full path + esac + + statef="$path/state" + if [ ! -w "$statef" ]; then + log_warn "stop_remoteproc: state file not found/writable: $statef" + return 1 + fi + + printf 'stop\n' >"$statef" 2>/dev/null || return 1 + wait_remoteproc_state "$path" offline 6 } - + # Start remoteproc start_remoteproc() { rproc_path="$1" - echo start > "$rproc_path/state" - wait_remoteproc_state "$rproc_path" "running" 6 + + case "$rproc_path" in + /sys/*) path="$rproc_path" ;; + remoteproc*) path="/sys/class/remoteproc/$rproc_path" ;; + *) path="$rproc_path" ;; + esac + + statef="$path/state" + if [ ! -w "$statef" ]; then + log_warn "start_remoteproc: state file not found/writable: $statef" + return 1 + fi + + printf 'start\n' >"$statef" 2>/dev/null || return 1 + wait_remoteproc_state "$path" running 6 } - # Validate remoteproc running state with retries and logging validate_remoteproc_running() { fw_name="$1" @@ -1096,6 +1225,177 @@ validate_remoteproc_running() { return 1 } +# acquire_test_lock +acquire_test_lock() { + lockfile="/var/lock/$1.lock" + exec 9>"$lockfile" + if ! flock -n 9; then + log_warn "Could not acquire lock on $lockfile → SKIP" + echo "$1 SKIP" > "./$1.res" + exit 0 + fi + log_info "Acquired lock on $lockfile" +} + +# release_test_lock +release_test_lock() { + flock -u 9 + log_info "Released lock" +} + +# summary_report +# Appends a machine‐readable summary line to the test log +summary_report() { + test="$1" + mode="$2" + stop_t="$3" + start_t="$4" + rp="$5" + log_info "Summary for ${test}: mode=${mode} stop_time_s=${stop_t} start_time_s=${start_t} rpmsg=${rp}" +} + +# dump_rproc_logs