diff --git a/Runner/suites/Kernel/DEBUG/CTI-Enable-Disable/CTI-Enable-Disable.yaml b/Runner/suites/Kernel/DEBUG/CTI-Enable-Disable/CTI-Enable-Disable.yaml new file mode 100644 index 00000000..053de18d --- /dev/null +++ b/Runner/suites/Kernel/DEBUG/CTI-Enable-Disable/CTI-Enable-Disable.yaml @@ -0,0 +1,16 @@ +metadata: + name: CTI-Enable-Disable + format: "Lava-Test Test Definition 1.0" + description: "Verifies that all Coresight CTI devices can be successfully enabled and disabled via sysfs." + os: + - linux + scope: + - coresight + - kernel + +run: + steps: + - REPO_PATH=$PWD || true + - cd Runner/suites/Kernel/DEBUG/CTI-Enable-Disable || true + - ./run.sh || true + - $REPO_PATH/Runner/utils/send-to-lava.sh CTI-Enable-Disable.res || true \ No newline at end of file diff --git a/Runner/suites/Kernel/DEBUG/CTI-Enable-Disable/README.md b/Runner/suites/Kernel/DEBUG/CTI-Enable-Disable/README.md new file mode 100644 index 00000000..e2104b23 --- /dev/null +++ b/Runner/suites/Kernel/DEBUG/CTI-Enable-Disable/README.md @@ -0,0 +1,83 @@ +# Coresight CTI Enable/Disable Test + +## Overview +This test validates the basic toggle functionality of the Coresight Cross Trigger Interface (CTI) drivers. It ensures that every CTI device exposed in sysfs can be turned on and off without errors. + +## Test Goals + +- Validate basic toggle functionality of Coresight CTI drivers. +- Ensure all sysfs-exposed CTI drivers can be enabled and disabled without errors. +- Verify that the device states are correctly reflected in sysfs after toggling. +- Ensure proper cleanup and reset of devices to a clean state after testing. + +## Prerequisites + +- Kernel must be built with Coresight CTI support. +- `sysfs` access to `/sys/bus/coresight/devices/`. +- Root priviledges needed. + +## Script Location + +``` +Runner/suites/Kernel/DEBUG/CTI-Enable-Disable/run.sh +``` + +## Files + +- `run.sh` - Main test script +- `CTI-Enable-Disable.res` - Summary result file with PASS/FAIL +- `CTI-Enable-Disable.log` - Full execution log. + +## How it works +1. **Preparation**: + * Disables `stm0`, `tmc_etr0`, and `tmc_etf0` to ensure a clean state. + * Enables `tmc_etf0` (Embedded Trace FIFO) as a sink, as some CTI configurations may require an active sink. +2. **Discovery**: Scans `/sys/bus/coresight/devices/` for any directory containing `cti`. +3. **Iteration**: For each CTI device: + * **Enable**: Writes `1` to the `enable` file. + * **Verify**: Reads the `enable` file; expects `1`. + * **Disable**: Writes `0` to the `enable` file. + * **Verify**: Reads the `enable` file; expects `0`. +4. **Cleanup**: Resets all devices to disabled state. + +## Usage + +Run the script directly. No iterations or special arguments are required for this basic test. + +```bash +./run.sh +``` + +## Example Output + +``` +[INFO] 2026-03-23 10:43:51 - ----------------------------------------------------------------------------------------- +[INFO] 2026-03-23 10:43:51 - -------------------Starting CTI-Enable-Disable Testcase---------------------------- +[INFO] 2026-03-23 10:43:51 - Saving state and resetting Coresight devices... +[INFO] 2026-03-23 10:43:51 - Testing Device: cti_sys0 +[PASS] 2026-03-23 10:43:51 - cti_sys0 Enabled Successfully +[PASS] 2026-03-23 10:43:51 - cti_sys0 Disabled Successfully +[PASS] 2026-03-23 10:43:51 - CTI Enable/Disable Test Completed Successfully +[INFO] 2026-03-23 10:43:51 - Restoring Coresight devices state... +[INFO] 2026-03-23 10:09:51 - -------------------CTI-Enable-Disable Testcase Finished---------------------------- +``` + +## Return Code + +- `0` — All CTI devices were toggled successfully +- `1` — One or more CTI devices failed to toggle + +## Integration in CI + +- Can be run standalone or via LAVA +- Result file `CTI-Enable-Disable.res` will be parsed by `result_parse.sh` + +## Notes + +- Some CTI cofigurations may require an active sink (like `tmc_etf0`) to function properly, which is handled in the preparation phase. +- Ensure no other trace/debug sessions are actively using the CTI devices before running this test. + +## License + +SPDX-License-Identifier: BSD-3-Clause. +(c) Qualcomm Technologies, Inc. and/or its subsidiaries. \ No newline at end of file diff --git a/Runner/suites/Kernel/DEBUG/CTI-Enable-Disable/run.sh b/Runner/suites/Kernel/DEBUG/CTI-Enable-Disable/run.sh new file mode 100755 index 00000000..0d241c1f --- /dev/null +++ b/Runner/suites/Kernel/DEBUG/CTI-Enable-Disable/run.sh @@ -0,0 +1,152 @@ +#!/bin/sh + +# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +# SPDX-License-Identifier: BSD-3-Clause + +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" >&2 + exit 1 +fi + +if [ -z "$__INIT_ENV_LOADED" ]; then + # shellcheck disable=SC1090 + . "$INIT_ENV" +fi + +# shellcheck disable=SC1090,SC1091 +. "$TOOLS/functestlib.sh" + +TESTNAME="CTI-Enable-Disable" +if command -v find_test_case_by_name >/dev/null 2>&1; then + test_path=$(find_test_case_by_name "$TESTNAME") + cd "$test_path" || exit 1 +else + cd "$SCRIPT_DIR" || exit 1 +fi + +res_file="./$TESTNAME.res" +log_info "-----------------------------------------------------------------------------------------" +log_info "-------------------Starting $TESTNAME Testcase----------------------------" +CS_BASE="/sys/bus/coresight/devices" +FAIL_COUNT=0 + +ORIG_ETF0_SINK="" +ORIG_ETR0_SINK="" +ORIG_STM0_SOURCE="" + +save_and_reset_devices() { + log_info "Saving state and resetting Coresight devices..." + if [ -f "$CS_BASE/tmc_etf0/enable_sink" ]; then + ORIG_ETF0_SINK=$(cat "$CS_BASE/tmc_etf0/enable_sink" 2>/dev/null) + echo 0 > "$CS_BASE/tmc_etf0/enable_sink" 2>/dev/null || true + fi + if [ -f "$CS_BASE/tmc_etr0/enable_sink" ]; then + ORIG_ETR0_SINK=$(cat "$CS_BASE/tmc_etr0/enable_sink" 2>/dev/null) + echo 0 > "$CS_BASE/tmc_etr0/enable_sink" 2>/dev/null || true + fi + if [ -f "$CS_BASE/stm0/enable_source" ]; then + ORIG_STM0_SOURCE=$(cat "$CS_BASE/stm0/enable_source" 2>/dev/null) + echo 0 > "$CS_BASE/stm0/enable_source" 2>/dev/null || true + fi +} + +cleanup() { + log_info "Restoring Coresight devices state..." + if [ -n "$ORIG_ETF0_SINK" ] && [ -f "$CS_BASE/tmc_etf0/enable_sink" ]; then + echo "$ORIG_ETF0_SINK" > "$CS_BASE/tmc_etf0/enable_sink" 2>/dev/null || true + fi + if [ -n "$ORIG_ETR0_SINK" ] && [ -f "$CS_BASE/tmc_etr0/enable_sink" ]; then + echo "$ORIG_ETR0_SINK" > "$CS_BASE/tmc_etr0/enable_sink" 2>/dev/null || true + fi + if [ -n "$ORIG_STM0_SOURCE" ] && [ -f "$CS_BASE/stm0/enable_source" ]; then + echo "$ORIG_STM0_SOURCE" > "$CS_BASE/stm0/enable_source" 2>/dev/null || true + fi +} + +trap cleanup EXIT + +if [ ! -d "$CS_BASE" ]; then + log_fail "Coresight directory not found: $CS_BASE" + echo "$TESTNAME FAIL" > "$res_file" + exit 1 +fi + +save_and_reset_devices + +if [ -f "$CS_BASE/tmc_etf0/enable_sink" ]; then + echo 1 > "$CS_BASE/tmc_etf0/enable_sink" +else + log_warn "tmc_etf0 not found, proceeding without it..." +fi + +CTI_LIST="" +for _dev in "$CS_BASE"/cti*; do + [ -e "$_dev" ] || continue + CTI_LIST="$CTI_LIST $(basename "$_dev")" +done + +if [ -z "$CTI_LIST" ]; then + log_fail "No CTI devices found." + echo "$TESTNAME FAIL" > "$res_file" + exit 1 +else + for cti in $CTI_LIST; do + dev_path="$CS_BASE/$cti" + + if [ ! -f "$dev_path/enable" ]; then + log_warn "Skipping $cti: 'enable' node not found" + continue + fi + + log_info "Testing Device: $cti" + + if ! echo 1 > "$dev_path/enable"; then + log_fail "$cti: Failed to write 1 to enable" + FAIL_COUNT=$((FAIL_COUNT + 1)) + continue + fi + + res=$(cat "$dev_path/enable") + if [ "$res" -eq 1 ]; then + log_pass "$cti Enabled Successfully" + else + log_fail "$cti Failed to Enable (Value: $res)" + FAIL_COUNT=$((FAIL_COUNT + 1)) + fi + + if ! echo 0 > "$dev_path/enable"; then + log_fail "$cti: Failed to write 0 to enable" + FAIL_COUNT=$((FAIL_COUNT + 1)) + continue + fi + + res=$(cat "$dev_path/enable") + if [ "$res" -eq 0 ]; then + log_pass "$cti Disabled Successfully" + else + log_fail "$cti Failed to Disable (Value: $res)" + FAIL_COUNT=$((FAIL_COUNT + 1)) + fi + done +fi + +if [ "$FAIL_COUNT" -eq 0 ]; then + log_pass "CTI Enable/Disable Test Completed Successfully" + echo "$TESTNAME PASS" > "$res_file" +else + log_fail "CTI Enable/Disable Test Failed ($FAIL_COUNT errors)" + echo "$TESTNAME FAIL" > "$res_file" +fi + +log_info "-------------------$TESTNAME Testcase Finished----------------------------" \ No newline at end of file diff --git a/Runner/suites/Kernel/DEBUG/CTI-Test/CTI-Test.yaml b/Runner/suites/Kernel/DEBUG/CTI-Test/CTI-Test.yaml new file mode 100644 index 00000000..b31a70a5 --- /dev/null +++ b/Runner/suites/Kernel/DEBUG/CTI-Test/CTI-Test.yaml @@ -0,0 +1,16 @@ +metadata: + name: CTI-Trigger-Map + format: "Lava-Test Test Definition 1.0" + description: "Validates Coresight Cross Trigger Interface (CTI) by mapping and unmapping triggers to channels." + os: + - linux + scope: + - coresight + - kernel + +run: + steps: + - REPO_PATH=$PWD || true + - cd Runner/suites/Kernel/DEBUG/CTI-Test || true + - ./run.sh || true + - $REPO_PATH/Runner/utils/send-to-lava.sh CTI-Test.res || true \ No newline at end of file diff --git a/Runner/suites/Kernel/DEBUG/CTI-Test/README.md b/Runner/suites/Kernel/DEBUG/CTI-Test/README.md new file mode 100644 index 00000000..fa414d44 --- /dev/null +++ b/Runner/suites/Kernel/DEBUG/CTI-Test/README.md @@ -0,0 +1,88 @@ +# CTI Test + +## Overview +This test verifies the functionality of the Coresight CTI (Cross Trigger Interface) driver. It ensures that hardware triggers can be successfully mapped (attached) to CTI channels and subsequently unmapped (detached). + +## Test Goals + +- Validate the core functionality of Coresight CTI driver. +- Ensure hardware triggers can be correctly attached to CTI channels. +- Validate compatibility across both Modern and Legacy sysfs interfaces. +- Prevent device low-power states during testing to ensure register accessibility. + +## Prerequisites + +- Kernel must be built with Coresight CTI support. +- `sysfs` access to `sys/module/lpm_levels/parameters/sleep_disabled`. +- `sysfs` access to `/sys/bus/coresight/devices/`. +- Root priviledges needed. + +## Script Location + +``` +Runner/suites/Kernel/DEBUG/CTI-Test/run.sh +``` + +## Files + +- `run.sh` - Main test script +- `CTI-Test.res` - Summary result file with PASS/FAIL +- `CTI-Test.log` - Full execution log. + +## How it works +1. **Sleep Disable**: Temporarily prevents the device from entering low-power modes (`/sys/module/lpm_levels/parameters/sleep_disabled`) to ensure CTI registers are accessible. +2. **Discovery**: Finds all CTI devices in `/sys/bus/coresight/devices/`. +3. **Mode Detection**: Checks for the existence of `enable` sysfs node to determine if the driver uses the Modern or Legacy sysfs interface. +4. **Configuration Parsing**: Reads the `devid` (Modern) or `show_info` (Legacy) to calculate the maximum number of triggers and channels supported by the hardware. +5. **Test Loop**: + * Iterates through a subset of triggers (randomized within valid range). + * Iterates through valid channels. + * **Attach**: writes `channel trigger` to `trigin_attach` / `trigout_attach`. + * **Verify**: Reads back via `chan_xtrigs_sel` and `chan_xtrigs_in`/`out` to confirm mapping. + * **Detach**: Unmaps the trigger and confirms the entry is cleared. +6. **Cleanup**: Restores the original LPM sleep setting. + +## Usage + +Run the script directly. No iterations or special arguments are required for this basic test. + +```bash +./run.sh +``` + +## Example Output + +``` +[INFO] 2026-03-24 04:56:37 - ----------------------------------------------------------------------------------------- +[INFO] 2026-03-24 04:56:37 - -------------------Starting CTI-Test Testcase---------------------------- +[INFO] 2026-03-24 04:56:37 - CTI Driver Version: Modern +[INFO] 2026-03-24 04:56:37 - Device: cti_sys0 (MaxTrig: 8, MaxCh: 4) +[INFO] 2026-03-24 04:56:37 - Attach trigin: trig 0 -> ch 0 on cti_sys0 +[INFO] 2026-03-24 04:56:37 - Attach trigout: trig 0 -> ch 0 on cti_sys0 +..... +[INFO] 2026-03-24 04:56:39 - Attach trigout: trig 7 -> ch 2 on cti_sys0 +[INFO] 2026-03-24 04:56:39 - Attach trigin: trig 7 -> ch 3 on cti_sys0 +[INFO] 2026-03-24 04:56:39 - Attach trigout: trig 7 -> ch 3 on cti_sys0 +[PASS] 2026-03-24 04:56:39 - CTI map/unmap Test PASS +[INFO] 2026-03-24 04:56:39 - -------------------CTI-Test Testcase Finished---------------------------- +``` + +## Return Code + +- `0` — All triggers and channels mapped/unmapped successfully across all CTI devices +- `1` — One or more mapping/unmapping operations failed + +## Integration in CI + +- Can be run standalone or via LAVA +- Result file `CTI-Test.res` will be parsed by `result_parse.sh` + +## Notes + +- The test iterates through a randomized subset of triggers rather than exhaustively testing every combination to optimize execution time while maintaining coverage. +- Disabling sleep modes is critical; if the device enters a low-power state, CTI registers may drop, causing false failures or system crashes. + +## License + +SPDX-License-Identifier: BSD-3-Clause. +(c) Qualcomm Technologies, Inc. and/or its subsidiaries. \ No newline at end of file diff --git a/Runner/suites/Kernel/DEBUG/CTI-Test/run.sh b/Runner/suites/Kernel/DEBUG/CTI-Test/run.sh new file mode 100755 index 00000000..71a28bf1 --- /dev/null +++ b/Runner/suites/Kernel/DEBUG/CTI-Test/run.sh @@ -0,0 +1,271 @@ +#!/bin/sh + +# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +# SPDX-License-Identifier: BSD-3-Clause + +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" >&2 + exit 1 +fi + +if [ -z "$__INIT_ENV_LOADED" ]; then + # shellcheck disable=SC1090 + . "$INIT_ENV" +fi + +# shellcheck disable=SC1090,SC1091 +. "$TOOLS/functestlib.sh" + +TESTNAME="CTI-Test" +if command -v find_test_case_by_name >/dev/null 2>&1; then + test_path=$(find_test_case_by_name "$TESTNAME") + cd "$test_path" || exit 1 +else + cd "$SCRIPT_DIR" || exit 1 +fi + +res_file="./$TESTNAME.res" +log_info "-----------------------------------------------------------------------------------------" +log_info "-------------------Starting $TESTNAME Testcase----------------------------" +CS_BASE="/sys/bus/coresight/devices" +LPM_SLEEP="/sys/module/lpm_levels/parameters/sleep_disabled" +ORIG_SLEEP_VAL="" +FAIL_COUNT=0 + +CTI_MAX_TRIGGERS=8 +CTI_MAX_CHANNELS=4 + +cleanup() { + if [ -f "$LPM_SLEEP" ] && [ -n "$ORIG_SLEEP_VAL" ]; then + log_info "Restoring LPM Sleep value: $ORIG_SLEEP_VAL" + echo "$ORIG_SLEEP_VAL" > "$LPM_SLEEP" 2>/dev/null + fi +} +trap cleanup EXIT + +setup_sleep() { + if [ -f "$LPM_SLEEP" ]; then + ORIG_SLEEP_VAL=$(cat "$LPM_SLEEP" 2>/dev/null) + if [ "$ORIG_SLEEP_VAL" != "Y" ] && [ "$ORIG_SLEEP_VAL" != "1" ]; then + log_info "Disabling LPM Sleep for test duration..." + echo 1 > "$LPM_SLEEP" 2>/dev/null + fi + fi +} + +map_cti_trigin() { + trig=$1; channel=$2; ctiname=$3; + cti_dev="$CS_BASE/$ctiname" + + [ ! -d "$cti_dev" ] && return + + log_info "Legacy: mapping trig $trig ch $channel to $ctiname" + [ -f "$cti_dev/map_trigin" ] && echo "$trig" "$channel" > "$cti_dev/map_trigin" 2>/dev/null + + trigin="" + channelin="" + [ -f "$cti_dev/show_trigin" ] && trigin=$(cut -b 4 "$cti_dev/show_trigin" 2>/dev/null) + [ -f "$cti_dev/show_trigin" ] && channelin=$(cut -b 8 "$cti_dev/show_trigin" 2>/dev/null) + + if [ -n "$trigin" ] && [ -n "$channelin" ] && [ "$trig" -eq "$trigin" ] && [ "$channel" -eq "$channelin" ] 2>/dev/null; then + [ -f "$cti_dev/unmap_trigin" ] && echo "$trig" "$channel" > "$cti_dev/unmap_trigin" 2>/dev/null + + trigin="" + [ -f "$cti_dev/show_trigin" ] && trigin=$(cut -b 4 "$cti_dev/show_trigin" 2>/dev/null) + if [ -n "$trigin" ]; then + log_warn "Failed to unmap $ctiname trigin" + FAIL_COUNT=$((FAIL_COUNT + 1)) + [ -f "$cti_dev/reset" ] && echo 1 > "$cti_dev/reset" 2>/dev/null + fi + else + log_warn "Failed to map $ctiname trigin $trig to channel $channel" + FAIL_COUNT=$((FAIL_COUNT + 1)) + [ -f "$cti_dev/reset" ] && echo 1 > "$cti_dev/reset" 2>/dev/null + fi +} + +set_trigin_attach() { + trig=$1; channel=$2; ctiname=$3; + cti_dev="$CS_BASE/$ctiname" + + [ ! -d "$cti_dev/channels" ] && return + + log_info "Attach trigin: trig $trig -> ch $channel on $ctiname" + + [ -f "$cti_dev/enable" ] && echo 1 > "$cti_dev/enable" 2>/dev/null + [ -f "$cti_dev/channels/trigin_attach" ] && echo "$channel" "$trig" > "$cti_dev/channels/trigin_attach" 2>/dev/null + [ -f "$cti_dev/channels/chan_xtrigs_sel" ] && echo "$channel" > "$cti_dev/channels/chan_xtrigs_sel" 2>/dev/null + + read_trig="" + [ -f "$cti_dev/channels/chan_xtrigs_in" ] && read_trig=$(cat "$cti_dev/channels/chan_xtrigs_in" 2>/dev/null) + + if [ -n "$read_trig" ] && [ "$trig" -eq "$read_trig" ] 2>/dev/null; then + [ -f "$cti_dev/channels/trigin_detach" ] && echo "$channel" "$trig" > "$cti_dev/channels/trigin_detach" 2>/dev/null + [ -f "$cti_dev/channels/chan_xtrigs_sel" ] && echo "$channel" > "$cti_dev/channels/chan_xtrigs_sel" 2>/dev/null + + read_trig="" + [ -f "$cti_dev/channels/chan_xtrigs_in" ] && read_trig=$(cat "$cti_dev/channels/chan_xtrigs_in" 2>/dev/null) + + if [ -n "$read_trig" ]; then + log_warn "Failed to detach trigin on $ctiname" + FAIL_COUNT=$((FAIL_COUNT + 1)) + [ -f "$cti_dev/reset" ] && echo 1 > "$cti_dev/reset" 2>/dev/null + fi + else + log_warn "Failed to attach trigin $trig to channel $channel on $ctiname" + FAIL_COUNT=$((FAIL_COUNT + 1)) + [ -f "$cti_dev/channels/chan_xtrigs_reset" ] && echo 1 > "$cti_dev/channels/chan_xtrigs_reset" 2>/dev/null + fi + + [ -f "$cti_dev/enable" ] && echo 0 > "$cti_dev/enable" 2>/dev/null +} + +set_trigout_attach() { + trig=$1; channel=$2; ctiname=$3; + cti_dev="$CS_BASE/$ctiname" + + [ ! -d "$cti_dev/channels" ] && return + + log_info "Attach trigout: trig $trig -> ch $channel on $ctiname" + + [ -f "$cti_dev/enable" ] && echo 1 > "$cti_dev/enable" 2>/dev/null + [ -f "$cti_dev/channels/trigout_attach" ] && echo "$channel" "$trig" > "$cti_dev/channels/trigout_attach" 2>/dev/null + [ -f "$cti_dev/channels/chan_xtrigs_sel" ] && echo "$channel" > "$cti_dev/channels/chan_xtrigs_sel" 2>/dev/null + + read_trig="" + [ -f "$cti_dev/channels/chan_xtrigs_out" ] && read_trig=$(cat "$cti_dev/channels/chan_xtrigs_out" 2>/dev/null) + + if [ -n "$read_trig" ] && [ "$trig" -eq "$read_trig" ] 2>/dev/null; then + [ -f "$cti_dev/channels/trigout_detach" ] && echo "$channel" "$trig" > "$cti_dev/channels/trigout_detach" 2>/dev/null + [ -f "$cti_dev/channels/chan_xtrigs_sel" ] && echo "$channel" > "$cti_dev/channels/chan_xtrigs_sel" 2>/dev/null + + read_trig="" + [ -f "$cti_dev/channels/chan_xtrigs_out" ] && read_trig=$(cat "$cti_dev/channels/chan_xtrigs_out" 2>/dev/null) + + if [ -n "$read_trig" ]; then + log_warn "Failed to detach trigout on $ctiname" + FAIL_COUNT=$((FAIL_COUNT + 1)) + [ -f "$cti_dev/reset" ] && echo 1 > "$cti_dev/reset" 2>/dev/null + fi + else + log_warn "Failed to attach trigout $trig to channel $channel on $ctiname" + FAIL_COUNT=$((FAIL_COUNT + 1)) + [ -f "$cti_dev/channels/chan_xtrigs_reset" ] && echo 1 > "$cti_dev/channels/chan_xtrigs_reset" 2>/dev/null + fi + + [ -f "$cti_dev/enable" ] && echo 0 > "$cti_dev/enable" 2>/dev/null +} + +setup_sleep + +CTI_DEVICES="" +if [ -d "$CS_BASE" ]; then + for _dev in "$CS_BASE"/cti*; do + [ -e "$_dev" ] || continue + CTI_DEVICES="$CTI_DEVICES $(basename "$_dev")" + done + CTI_DEVICES="${CTI_DEVICES# }" +fi + +if [ -z "$CTI_DEVICES" ]; then + log_fail "No CTI devices found in $CS_BASE" + echo "$TESTNAME FAIL" > "$res_file" + exit 1 +fi + +NEW_VER=0 +for cti in $CTI_DEVICES; do + if [ -f "$CS_BASE/$cti/enable" ]; then + NEW_VER=1 + break + fi +done + +log_info "CTI Driver Version: $( [ $NEW_VER -eq 1 ] && echo "Modern" || echo "Legacy" )" + +for cti in $CTI_DEVICES; do + if [ $NEW_VER -eq 1 ]; then + if [ -f "$CS_BASE/$cti/channels/chan_xtrigs_reset" ]; then + echo 1 > "$CS_BASE/$cti/channels/chan_xtrigs_reset" 2>/dev/null + fi + else + if [ -f "$CS_BASE/$cti/reset" ]; then + echo 1 > "$CS_BASE/$cti/reset" 2>/dev/null + fi + fi +done + +for cti in $CTI_DEVICES; do + cti_path="$CS_BASE/$cti" + + if [ $NEW_VER -eq 1 ]; then + if [ -f "$cti_path/mgmt/devid" ]; then + devid=$(cat "$cti_path/mgmt/devid" 2>/dev/null) + chmax=$(( (devid & 2064384) >> 16 )) 2>/dev/null || chmax=4 + trigmax=$(( (devid & 32640) >> 8 )) 2>/dev/null || trigmax=8 + else + chmax=4 + trigmax=8 + fi + else + if [ -f "$cti_path/show_info" ]; then + trigmax=$(cut -f1 -d ' ' "$cti_path/show_info" 2>/dev/null) + chmax=$(cut -f2 -d ' ' "$cti_path/show_info" 2>/dev/null) + else + chmax=4 + trigmax=8 + fi + fi + + [ -z "$trigmax" ] && trigmax=8 + [ -z "$chmax" ] && chmax=4 + + log_info "Device: $cti (MaxTrig: $trigmax, MaxCh: $chmax)" + + _trig=0 + while [ "$_trig" -lt "$trigmax" ]; do + if [ "$_trig" -lt "$CTI_MAX_TRIGGERS" ]; then + trig="$_trig" + else + trig=$(( _trig % CTI_MAX_TRIGGERS )) + fi + + limit_ch=$(( CTI_MAX_CHANNELS - 1 )) + + _ch=0 + while [ "$_ch" -le "$limit_ch" ]; do + if [ "$_ch" -le "$chmax" ]; then + if [ "$NEW_VER" -eq 1 ]; then + set_trigin_attach "$trig" "$_ch" "$cti" + set_trigout_attach "$trig" "$_ch" "$cti" + else + map_cti_trigin "$trig" "$_ch" "$cti" + fi + fi + _ch=$(( _ch + 1 )) + done + + _trig=$(( _trig + 1 )) + done +done + +if [ "$FAIL_COUNT" -eq 0 ]; then + log_pass "CTI map/unmap Test PASS" + echo "$TESTNAME PASS" > "$res_file" +else + log_fail "CTI map/unmap Test FAIL ($FAIL_COUNT errors)" + echo "$TESTNAME FAIL" > "$res_file" +fi + +log_info "-------------------$TESTNAME Testcase Finished----------------------------" \ No newline at end of file diff --git a/Runner/suites/Kernel/DEBUG/Node-Access/Node-Access.yaml b/Runner/suites/Kernel/DEBUG/Node-Access/Node-Access.yaml new file mode 100644 index 00000000..a430f8e5 --- /dev/null +++ b/Runner/suites/Kernel/DEBUG/Node-Access/Node-Access.yaml @@ -0,0 +1,16 @@ +metadata: + name: Sysfs-Node-Access + format: "Lava-Test Test Definition 1.0" + description: "Iterates through all Coresight sysfs nodes (excluding TPDM) and attempts to read them to ensure stability and permission correctness." + os: + - linux + scope: + - coresight + - kernel + +run: + steps: + - REPO_PATH=$PWD || true + - cd Runner/suites/Kernel/DEBUG/Node-Access || true + - ./run.sh || true + - $REPO_PATH/Runner/utils/send-to-lava.sh Node-Access.res || true \ No newline at end of file diff --git a/Runner/suites/Kernel/DEBUG/Node-Access/README.md b/Runner/suites/Kernel/DEBUG/Node-Access/README.md new file mode 100644 index 00000000..1b46714b --- /dev/null +++ b/Runner/suites/Kernel/DEBUG/Node-Access/README.md @@ -0,0 +1,84 @@ +# Node Access Test + +## Overview +This test acts as a "fuzz" or stability test for the Coresight driver sysfs interface. It iterates through every exposed Coresight device (excluding `tpdm`) and attempts to read every readable attribute. This ensures that reading status registers or configuration nodes does not crash the system or return unexpected I/O errors. + +## Test Goals + +- Perform stability/fuzz testing on the Coresight sysfs interface. +- Ensure reading exposed device attributes does not cause system crashes or hangs. +- Verify that readable nodes do not return unexpected I/O errors upon access. +- Validate the robustness of the `mgmt/subdirectory` nodes if present. + +## Prerequisites + +- Kernel must be built with Coresight support. +- `sysfs` access to `/sys/bus/coresight/devices/`. +- Root priviledges needed. + +## Script Location + +``` +Runner/suites/Kernel/DEBUG/Node-Access/run.sh +``` + +## Files + +- `run.sh` - Main test script +- `Node-Access.res` - Summary result file with PASS/FAIL +- `Node-Access.log` - Full execution log. + +## How it works +1. **Iterations**: Runs the scan loop 3 times. +2. **Discovery**: Scans `/sys/bus/coresight/devices/`. +3. **Exclusion**: Skips any path containing `tpdm` (Trace Port Debug Module). +4. **Reset**: Resets basic source/sink enables (`stm0`, `tmc_etf0`, `tmc_etr0`) before accessing a new device folder to ensure a clean state. +5. **Access**: + * Iterates all files in the device folder. + * Checks if the file is readable (`-r`). + * Performs a `cat` operation. + * Repeats the process for the `mgmt/` subdirectory if it exists. +6. **Verification**: Any read failure (exit code non-zero) increments the failure counter. + +## Usage + +Run the script directly. No iterations or special arguments are required for this basic test. + +```bash +./run.sh +``` + +## Example Output + +``` +[INFO] 2026-03-23 10:09:39 - ----------------------------------------------------------------------------------------- +[INFO] 2026-03-23 10:09:39 - -------------------Starting Node-Access Testcase---------------------------- +[INFO] 2026-03-23 10:09:39 - --- Iteration 1 / 3 Ongoing --- +[PASS] 2026-03-23 10:09:43 - Iteration 1 PASS +[INFO] 2026-03-23 10:09:43 - --- Iteration 2 / 3 Ongoing --- +[PASS] 2026-03-23 10:09:47 - Iteration 2 PASS +[INFO] 2026-03-23 10:09:47 - --- Iteration 3 / 3 Ongoing --- +[PASS] 2026-03-23 10:09:51 - Iteration 3 PASS +[PASS] 2026-03-23 10:09:51 - All sysfs nodes (except tpdm) Read Test PASS +[INFO] 2026-03-23 10:09:51 - -------------------Node-Access Testcase Finished---------------------------- +``` + +## Return Code + +- `0` — All readable nodes were accessed successfully across all iterations +- `1` — One or more readable nodes failed to be read or returned an error + +## Integration in CI + +- Can be run standalone or via LAVA +- Result file `Node-Access.res` will be parsed by `result_parse.sh` + +## Notes + +- tpdm devices are explicitly excluded from this test. +- The test runs 3 iterations to catch int4ermittent read failures or state-dependent crashes. + +## License + +SPDX-License-Identifier: BSD-3-Clause. +(c) Qualcomm Technologies, Inc. and/or its subsidiaries. \ No newline at end of file diff --git a/Runner/suites/Kernel/DEBUG/Node-Access/run.sh b/Runner/suites/Kernel/DEBUG/Node-Access/run.sh new file mode 100755 index 00000000..0c0adc5c --- /dev/null +++ b/Runner/suites/Kernel/DEBUG/Node-Access/run.sh @@ -0,0 +1,118 @@ +#!/bin/sh + +# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +# SPDX-License-Identifier: BSD-3-Clause + +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" >&2 + exit 1 +fi + +if [ -z "$__INIT_ENV_LOADED" ]; then + # shellcheck disable=SC1090 + . "$INIT_ENV" +fi + +# shellcheck disable=SC1090,SC1091 +. "$TOOLS/functestlib.sh" + +TESTNAME="Node-Access" +if command -v find_test_case_by_name >/dev/null 2>&1; then + test_path=$(find_test_case_by_name "$TESTNAME") + cd "$test_path" || exit 1 +else + cd "$SCRIPT_DIR" || exit 1 +fi + +res_file="./$TESTNAME.res" +log_info "-----------------------------------------------------------------------------------------" +log_info "-------------------Starting $TESTNAME Testcase----------------------------" +CS_BASE="/sys/bus/coresight/devices" +FAIL_COUNT=0 +ITERATIONS=3 + +reset_source_sink() { + log_info "Dynamically finding and resetting all Coresight sources and sinks..." + for _dev in "$CS_BASE"/*; do + [ -e "$_dev" ] || continue + + # Disable if it's a source + if [ -f "$_dev/enable_source" ]; then + echo 0 > "$_dev/enable_source" 2>/dev/null || true + fi + + # Disable if it's a sink + if [ -f "$_dev/enable_sink" ]; then + echo 0 > "$_dev/enable_sink" 2>/dev/null || true + fi + done +} + +if [ ! -d "$CS_BASE" ]; then + log_fail "Coresight directory $CS_BASE not found" + echo "$TESTNAME FAIL" > "$res_file" + exit 1 +fi + +set -- "$CS_BASE"/* +if [ ! -e "$1" ]; then + log_fail "No Coresight devices found inside $CS_BASE" + echo "$TESTNAME FAIL" > "$res_file" + exit 1 +fi + +reset_source_sink + +i=0 +while [ "$i" -lt "$ITERATIONS" ]; do + log_info "--- Iteration $((i+1)) / $ITERATIONS ---" + + for node_path in "$CS_BASE"/*; do + [ -d "$node_path" ] || continue + + case "$(basename "$node_path")" in + *tpdm*) + continue + ;; + esac + + for node in "$node_path"/*; do + if [ -f "$node" ] && [ -r "$node" ]; then + cat "$node" > /dev/null 2>&1 || true + fi + done + + if [ -d "$node_path/mgmt" ]; then + for snode in "$node_path"/mgmt/*; do + if [ -f "$snode" ] && [ -r "$snode" ]; then + if ! cat "$snode" > /dev/null 2>&1; then + log_fail "Failed to read mgmt node: $snode" + FAIL_COUNT=$((FAIL_COUNT + 1)) + fi + fi + done + fi + done + i=$((i+1)) +done + +if [ "$FAIL_COUNT" -eq 0 ]; then + log_pass "All sysfs nodes Read Test PASS" + echo "$TESTNAME PASS" > "$res_file" +else + log_fail "Sysfs nodes Read Test FAIL ($FAIL_COUNT errors)" + echo "$TESTNAME FAIL" > "$res_file" +fi + +log_info "-------------------$TESTNAME Testcase Finished----------------------------" \ No newline at end of file