diff --git a/src/runtime_src/core/tools/xbutil2/xbutil-bash-completion b/src/runtime_src/core/tools/xbutil2/xbutil-bash-completion index e3fe997facb..f5cc7d56d06 100755 --- a/src/runtime_src/core/tools/xbutil2/xbutil-bash-completion +++ b/src/runtime_src/core/tools/xbutil2/xbutil-bash-completion @@ -1,7 +1,35 @@ # bash completion for xrt-smi -*- shell-script -*- # SPDX-License-Identifier: Apache-2.0 # Copyright (C) 2021-2022 Xilinx, Inc. All rights reserved. -# +# Copyright (C) 2024-2026 Advanced Micro Devices, Inc. All rights reserved. + +# Extract enum values for a named option from xrt-smi help output. +# $1: option name to match (e.g. "--report") +# Remaining args: passed to xrt-smi before --help (e.g. "examine --advanced") +_xrt_smi_enum() +{ + local opt="$1"; shift + xrt-smi "$@" --help 2>&1 | awk -v opt="$opt" ' + index($0, opt) { found=1; next } + found && /^[[:space:]]+[a-z]/ && / - / { print $1; next } + found && /^[[:space:]]+-/ { exit } + found && !/^[[:space:]]/ { exit } + ' | tr '\n' ' ' +} + +# Extract all option flags from xrt-smi help output. +# All args are passed to xrt-smi before --help. +_xrt_smi_options() +{ + xrt-smi "$@" --help 2>&1 | awk ' + /^[[:space:]]+-/ { + for (i = 1; i <= NF; i++) { + if ($i == "-") break + if ($i ~ /^-/) { gsub(/,/, "", $i); print $i } + } + } + ' | tr '\n' ' ' +} # Generates the command word options dependant on the previous word # using COMPREPLY @@ -10,11 +38,11 @@ # # Parameters: # 1: The complete list of options for the previous word -_command_word_xbutil_completion() +_xrt_smi_completion() { # Get the righthand most word on the command line local cur=${COMP_WORDS[COMP_CWORD]} - # The previous word + # The previous word local prev=${COMP_WORDS[COMP_CWORD-1]} # The BDFs (for devices) contain colons which breaks the autocomplete @@ -22,102 +50,230 @@ _command_word_xbutil_completion() # words _get_comp_words_by_ref -n : cur prev - # Each defined case requires an argument so no reply is given - # All other cases default to using `compgen` output to format COMPREPLY + local commands="configure examine validate advanced" + local globalModifiers="--verbose --batch --force --advanced" + + # Check for terminal options first - no completions after these + local i + for (( i=1; i < COMP_CWORD; i++ )); do + case ${COMP_WORDS[i]} in + --version) + # --version is terminal at top level, no more completions + COMPREPLY=() + return + ;; + esac + done + + # Detect if --advanced flag is present + local hasAdvanced=0 advFlag="" + for (( i=1; i < COMP_CWORD; i++ )); do + case ${COMP_WORDS[i]} in + --advanced) + hasAdvanced=1 + advFlag="--advanced" + break + ;; + esac + done + + # Search for a command in the current command line + # Global options like --verbose can appear before the command + local commandWord="" + for (( i=1; i < COMP_CWORD; i++ )); do + case ${COMP_WORDS[i]} in + configure|examine|validate|advanced) + commandWord=${COMP_WORDS[i]} + break + ;; + esac + done + + # Detect sub-option context (OptionOptions that consume remaining args) + local subOption="" + for (( i=1; i < COMP_CWORD; i++ )); do + case ${COMP_WORDS[i]} in + --event-trace|--firmware-log|--context-health|--force-preemption|\ + --read-mem|--write-mem|--read-aie-reg|--aie-clock) + subOption=${COMP_WORDS[i]} + break + ;; + esac + done + + # Handle sub-option specific completions + if [[ -n "${subOption}" ]]; then + case ${prev} in + -d|--device) + local devices + devices=$(ls -d /sys/class/accel/accel*/device 2>/dev/null | xargs -I{} readlink {} | xargs -n1 basename 2>/dev/null) + COMPREPLY=($(compgen -W "${devices}" -- "${cur}")) + __ltrim_colon_completions "${cur}" + return + ;; + -o|--output|-i|--input|--raw) + _filedir + return + ;; + esac + local subOptions="" + case ${subOption} in + --event-trace) + if [[ "${commandWord}" == "examine" ]]; then + subOptions="--device -d --help -h --status --watch --raw --payload-version" + elif [[ "${commandWord}" == "configure" ]]; then + subOptions="--device -d --help -h --enable --disable --list-categories --categories" + fi + ;; + --firmware-log) + if [[ "${commandWord}" == "examine" ]]; then + subOptions="--device -d --help -h --status --watch --raw --payload-version" + elif [[ "${commandWord}" == "configure" ]]; then + subOptions="--device -d --help -h --enable --disable --log-level" + fi + ;; + --context-health) + subOptions="--device -d --help -h --watch --ctx-id --pid" + ;; + --force-preemption) + subOptions="--device -d --help enable disable status" + ;; + --read-mem) + subOptions="--device -d --output -o --address --size --count --help" + ;; + --write-mem) + subOptions="--input -i --device -d --address --size --count --fill -f --help" + ;; + --read-aie-reg) + subOptions="--device -d --row --col --reg --help" + ;; + --aie-clock) + subOptions="--device -d --partition -p --set -s --get -g --help -h" + ;; + esac + COMPREPLY=($(compgen -W "${subOptions}" -- "${cur}")) + __ltrim_colon_completions "${cur}" + return + fi + + # Handle options that require arguments case ${prev} in -d|--device) - options="" + # List available device BDFs by reading symlinks from /sys/class/accel/ + local devices + devices=$(ls -d /sys/class/accel/accel*/device 2>/dev/null | xargs -I{} readlink {} | xargs -n1 basename 2>/dev/null) + COMPREPLY=($(compgen -W "${devices}" -- "${cur}")) + __ltrim_colon_completions "${cur}" + return + ;; + -f|--format) + # Format options: JSON or JSON-2020.2 + COMPREPLY=($(compgen -W "JSON JSON-2020.2" -- "${cur}")) + return + ;; + --pmode) + # Performance mode options (dynamically from device) + local vals + vals=$(_xrt_smi_enum "--pmode" configure ${advFlag}) + [[ -z "$vals" ]] && vals="default powersaver balanced performance turbo" + COMPREPLY=($(compgen -W "${vals}" -- "${cur}")) + return ;; - -u|--user) + -o|--output) # The _filedir function is defined in the bash-completion script typically found in # /usr/share/bash-completion/bash_completions. This populates the COMP_REPLY with # All files and directories are specified by the last argument in the command line # when a tab completion event is triggered. _filedir - options="" - ;; - -f|--format) - options="" + return ;; - -o|--output) + -i|--input) _filedir - options="" - ;; - -t|--type) - options="" + return ;; -p|--path) - _filedir - options="" + _filedir -d + return ;; - --p2p) - options="" + --report) + # Report types for examine command (dynamically from device) + local vals + vals=$(_xrt_smi_enum "--report" examine ${advFlag}) + [[ -z "$vals" ]] && vals="aie-partitions all host platform" + COMPREPLY=($(compgen -W "${vals}" -- "${cur}")) + return + ;; + --run) + # Test types for validate command (dynamically from device) + local vals + vals=$(_xrt_smi_enum "--run" validate ${advFlag}) + [[ -z "$vals" ]] && vals="all latency throughput" + COMPREPLY=($(compgen -W "${vals}" -- "${cur}")) + return + ;; + -r) + # -r is --report for examine, --run for validate + local vals + if [[ "${commandWord}" == "validate" ]]; then + vals=$(_xrt_smi_enum "--run" validate ${advFlag}) + [[ -z "$vals" ]] && vals="all latency throughput" + else + vals=$(_xrt_smi_enum "--report" examine ${advFlag}) + [[ -z "$vals" ]] && vals="aie-partitions all host platform" + fi + COMPREPLY=($(compgen -W "${vals}" -- "${cur}")) + return + ;; + --force-preemption) + COMPREPLY=($(compgen -W "enable disable status" -- "${cur}")) + return ;; --host-mem) - options="" + COMPREPLY=($(compgen -W "enable disable" -- "${cur}")) + return ;; - # The -r option is used for multiple commands so extra processing is needed in here - -r|--report|--run) - options="" + --p2p) + COMPREPLY=($(compgen -W "enable disable validate" -- "${cur}")) + return ;; - *) - # Default to using the passed in options if no particular option is used - options=$1 + -h|--help) + # --help is terminal, no more completions + COMPREPLY=() + return ;; esac - # The format of the compgen commands options is seperated from the current word using a --. - # The -- character signifies the end of command options. All following arguments are positional. - COMPREPLY+=($(compgen -W "$options" -- $cur)) - # 2nd part of getting around colons in the suggested keywords - __ltrim_colon_completions "$cur" -} -# The main function populating the COMPREPLY -_xbutil_completion() -{ - commonSubCommands="--verbose --batch --force --help -h --version" - # COMP_CWORD is the current index of the cursor in the command line - # 0 is the first argument (xrt-smi), 1 is the desired command for xrt-smi, - # 2 is an option for the command, etc. - case ${COMP_CWORD} in - # Case for command after xrt-smi - 1) - options="program validate examine configure reset ${commonSubCommands}" - ;; - # Case for options after the above command is entered - *) - # Command word is used to specify further options as the command expands - commandWord=${COMP_WORDS[1]} - # Options that appear for all commands - commonSubCommands="--device -d ${commonSubCommands}" - # Once a command is identified the options will always be the same + # Build completion options based on context + local options="" + + if [[ -z "${commandWord}" ]]; then + # No command found yet, suggest commands and global options + options="${commands} ${globalModifiers} --help -h --version" + else + # Dynamically get available options from help output + options=$(_xrt_smi_options ${commandWord} ${advFlag}) + if [[ -n "${options}" ]]; then + # Add --advanced since it's a global option not shown in subcommand help + options="${options} --advanced" + else + # Fallback to static options + local commonOptions="--device -d --help -h ${globalModifiers}" case ${commandWord} in - "program") - options="--user -u ${commonSubCommands}" - ;; - "validate") - options="--run -r --format -f --output -o --path -p ${commonSubCommands}" - ;; - "examine") - options="--report -r --format -f --output -o ${commonSubCommands}" - ;; - "configure") - options="--host-mem --p2p --size ${commonSubCommands}" - ;; - "reset") - options="--type -t ${commonSubCommands}" - ;; - # Return an empty reply if an invalid command is entered - *) - options="" - ;; + configure) options="--pmode ${commonOptions}" ;; + examine) options="--report -r --format -f --output -o ${commonOptions}" ;; + validate) options="--run -r --format -f --output -o ${commonOptions}" ;; + advanced) options="--read-mem --write-mem --device -d --help" ;; esac - ;; - esac - _command_word_xbutil_completion "${options}" + fi + fi + + # The format of the compgen commands options is seperated from the current word using a --. + # The -- character signifies the end of command options. All following arguments are positional. + COMPREPLY=($(compgen -W "${options}" -- "${cur}")) + # 2nd part of getting around colons in the suggested keywords + __ltrim_colon_completions "${cur}" } -complete -F _xbutil_completion xrt-smi -echo Autocomplete enabled for the xrt-smi command +complete -F _xrt_smi_completion xrt-smi # ex: filetype=sh diff --git a/src/runtime_src/core/tools/xbutil2/xbutil-csh-completion b/src/runtime_src/core/tools/xbutil2/xbutil-csh-completion index 39f6de6c377..0b815c04e19 100755 --- a/src/runtime_src/core/tools/xbutil2/xbutil-csh-completion +++ b/src/runtime_src/core/tools/xbutil2/xbutil-csh-completion @@ -1,12 +1,24 @@ #!/bin/csh -f # SPDX-License-Identifier: Apache-2.0 # Copyright (C) 2021-2022 Xilinx, Inc. All rights reserved. -# +# Copyright (C) 2024-2026 Advanced Micro Devices, Inc. All rights reserved. # parse out required variables set list = "$COMMAND_LINE" -# The command word associated with this xrt-smi invocation -set commandWord = `echo $list | awk 'BEGIN{FS=" "}{print $2}'` +# Search for command word anywhere in the line (global options can come before command) +# This handles cases like: xrt-smi --verbose validate +set commandWord = `echo $list | tr ' ' '\n' | grep -E '^(configure|examine|validate|advanced)$' | head -1` +# Check for terminal options (--version) - no completions after these +set hasVersion = `echo $list | tr ' ' '\n' | grep -E '^--version$' | head -1` +# Check for --advanced flag +set hasAdvanced = `echo $list | tr ' ' '\n' | grep -E '^--advanced$' | head -1` +if ("$hasAdvanced" != "") then + set advFlag = "--advanced" +else + set advFlag = "" +endif +# Check for sub-option context (OptionOptions that consume remaining args) +set subOption = `echo $list | tr ' ' '\n' | grep -E '^--(event-trace|firmware-log|context-health|force-preemption|read-mem|write-mem|read-aie-reg|aie-clock)$' | head -1` # Get the number of arguments. This script turns spaces into ampersands to count # the number of commands. This script is NOT space in path name friendly. set argsplit=(`echo "$list" | sed -e "s/ /@/g"`) @@ -21,71 +33,140 @@ set previousWord = `echo $argsplit | awk 'BEGIN{FS="@"}{NF=NF-1;print $NF}'` # This is the word on the righthand side set currentWord = `echo $argsplit | awk 'BEGIN{FS="@"}{print $NF}'` +# Check for terminal option --version first +if ("$hasVersion" != "") then + # --version is terminal, no more completions + echo "" + exit 0 +endif -# The options for the current command line statement -set programOptions = "--verbose --batch --force --help -h --version" -# Handle the default xrt-smi options first -if($commandCount == "1") then - set programOptions="${programOptions} program validate examine configure reset" -else - set commonSubCommands="--device -d ${programOptions}" +# Handle sub-option specific completions +if ("$subOption" != "") then + switch($subOption) + case "--event-trace": + if ("$commandWord" == "examine") then + echo --device -d --help -h --status --watch --raw --payload-version + else if ("$commandWord" == "configure") then + echo --device -d --help -h --enable --disable --list-categories --categories + endif + exit 0 + case "--firmware-log": + if ("$commandWord" == "examine") then + echo --device -d --help -h --status --watch --raw --payload-version + else if ("$commandWord" == "configure") then + echo --device -d --help -h --enable --disable --log-level + endif + exit 0 + case "--context-health": + echo --device -d --help -h --watch --ctx-id --pid + exit 0 + case "--force-preemption": + echo --device -d --help enable disable status + exit 0 + case "--read-mem": + echo --device -d --output -o --address --size --count --help + exit 0 + case "--write-mem": + echo --input -i --device -d --address --size --count --fill -f --help + exit 0 + case "--read-aie-reg": + echo --device -d --row --col --reg --help + exit 0 + case "--aie-clock": + echo --device -d --partition -p --set -s --get -g --help -h + exit 0 + endsw +endif - # First handle the gathering of all options unique to each command - switch($commandWord) - case "program": - set programOptions="${programOptions} --user -u" - breaksw - case "validate": - set programOptions="${programOptions} --run -r --format -f --output -o --path -p" - breaksw - case "examine": - set programOptions="${programOptions} --report -r --format -f --output -o" - breaksw - case "configure": - set programOptions="${programOptions} --host-mem --p2p --size" - breaksw - case "reset": - set programOptions="${programOptions} --type -t" - breaksw - # Return an empty reply if an invalid command is entered - default: - breaksw - endsw +# Handle options that require arguments first +# If an option is "missing" from this list check the wrapper. It is most likely defined there as a +# file search completion +switch($previousWord) + case "device": + case "d": + # List available device BDFs by reading symlinks from /sys/class/accel/ + # Output one per line to avoid escaping issues with colons + ls -d /sys/class/accel/accel*/device |& xargs -I {} readlink {} |& xargs -n1 basename + exit 0 + case "format": + case "f": + # Format options + echo JSON JSON-2020.2 + exit 0 + case "pmode": + # Performance mode options (dynamically from device) + set vals = `xrt-smi configure $advFlag --help |& awk '/--pmode/{ f=1; next } f && /^[[:space:]]+[a-z]/ && / - /{ print \$1; next } f && /^[[:space:]]+-/{ exit } f && !/^[[:space:]]/{ exit }'` + if ("$vals" == "") set vals = "default powersaver balanced performance turbo" + echo $vals + exit 0 + case "report": + # Report types for examine command (dynamically from device) + set vals = `xrt-smi examine $advFlag --help |& awk '/--report/{ f=1; next } f && /^[[:space:]]+[a-z]/ && / - /{ print \$1; next } f && /^[[:space:]]+-/{ exit } f && !/^[[:space:]]/{ exit }'` + if ("$vals" == "") set vals = "aie-partitions all host platform" + echo $vals + exit 0 + case "run": + # Test types for validate command (dynamically from device) + set vals = `xrt-smi validate $advFlag --help |& awk '/--run/{ f=1; next } f && /^[[:space:]]+[a-z]/ && / - /{ print \$1; next } f && /^[[:space:]]+-/{ exit } f && !/^[[:space:]]/{ exit }'` + if ("$vals" == "") set vals = "all latency throughput" + echo $vals + exit 0 + case "r": + # -r is --report for examine, --run for validate + if ("$commandWord" == "validate") then + set vals = `xrt-smi validate $advFlag --help |& awk '/--run/{ f=1; next } f && /^[[:space:]]+[a-z]/ && / - /{ print \$1; next } f && /^[[:space:]]+-/{ exit } f && !/^[[:space:]]/{ exit }'` + if ("$vals" == "") set vals = "all latency throughput" + else + set vals = `xrt-smi examine $advFlag --help |& awk '/--report/{ f=1; next } f && /^[[:space:]]+[a-z]/ && / - /{ print \$1; next } f && /^[[:space:]]+-/{ exit } f && !/^[[:space:]]/{ exit }'` + if ("$vals" == "") set vals = "aie-partitions all host platform" + endif + echo $vals + exit 0 + case "forcepreemption": + echo enable disable status + exit 0 + case "hostmem": + echo enable disable + exit 0 + case "p2p": + echo enable disable validate + exit 0 + case "help": + case "h": + # --help is terminal, no more completions + echo "" + exit 0 +endsw - # If the current word requires an argument, clear the option list - # If an option is "missing" from this list check the wrapper. It is most likely defined there as a - # file search completion - switch($previousWord) - case "device": - case "d": - set programOptions="" - breaksw - case "format": - case "f": - set programOptions="" - breaksw - case "type": - case "t": - set programOptions="" - breaksw - case "p2p": - set programOptions="" - breaksw - case "hostmem": - set programOptions="" - breaksw - # -r shorthand applies to multiple commands under xrt-smi and requires additional processing - # Assuming we want to add something here one day - case "report": - case "run": - case "r": - set programOptions="" - breaksw - # do not modify the option list if the argument is not required - default: - breaksw - endsw -endif +# Build completion options based on context +set commonOpts = "--device -d --help -h --verbose --batch --force --advanced" -# Printout the options for complete to register them -echo $programOptions +if ("$commandWord" == "") then + # No command found yet, suggest commands and global options + echo configure examine validate advanced --verbose --batch --force --advanced --help -h --version +else + # Dynamically get available options from help output + set opts = `xrt-smi $commandWord $advFlag --help |& awk '/^[[:space:]]+-/{ for(i=1;i<=NF;i++){ if(\$i=="-") break; if(\$i~/^-/){ gsub(/,/,"",\$i); print \$i } } }'` + if ("$opts" != "") then + # Add --advanced since it is a global option not shown in subcommand help + echo $opts --advanced + else + # Fallback to static options + switch($commandWord) + case "configure": + echo --pmode $commonOpts + breaksw + case "examine": + echo --report -r --format -f --output -o $commonOpts + breaksw + case "validate": + echo --run -r --format -f --output -o $commonOpts + breaksw + case "advanced": + echo --read-mem --write-mem --device -d --help + breaksw + default: + breaksw + endsw + endif +endif diff --git a/src/runtime_src/core/tools/xbutil2/xbutil-csh-completion-wrapper b/src/runtime_src/core/tools/xbutil2/xbutil-csh-completion-wrapper index 5bd6c952539..b9a0a06d345 100644 --- a/src/runtime_src/core/tools/xbutil2/xbutil-csh-completion-wrapper +++ b/src/runtime_src/core/tools/xbutil2/xbutil-csh-completion-wrapper @@ -1,10 +1,10 @@ #!/bin/csh -f # SPDX-License-Identifier: Apache-2.0 # Copyright (C) 2021-2022 Xilinx, Inc. All rights reserved. -# +# Copyright (C) 2024-2026 Advanced Micro Devices, Inc. All rights reserved. -# Enable autocompletion for the xrt-smi and xbmgmt commands -alias __xbutil_completion_csh tcsh $XILINX_XRT/share/completions/xrt-smi-csh-completion +# Enable autocompletion for the xrt-smi command +alias __xrt_smi_completion_csh tcsh $XILINX_XRT/share/completions/xrt-smi-csh-completion # TCSH is very unfriendly when performing file completions inside the aliased script # to get around this we add certain options that default to file/directory searches here # The options that bypass the completion script are identified (using the n as the first parameter) by their name @@ -13,6 +13,5 @@ alias __xbutil_completion_csh tcsh $XILINX_XRT/share/completions/xrt-smi-csh-com # n/--test/-f -> A tab completion event following the --test option will display available files in the current directory # # The options that bypass the script parsing are as follows: -# -u, --user, -o, --output, -p, --path -complete xrt-smi 'n/-u/f/' 'n/--user/f/' 'n/-o/f/' 'n/--output/f/' 'n/-p/f/' 'n/--path/f/' 'p/*/`__xbutil_completion_csh`/' -echo Autocomplete enabled for the xrt-smi command +# -o, --output +complete xrt-smi 'n/-o/f/' 'n/--output/f/' 'n/-i/f/' 'n/--input/f/' 'n/-p/f/' 'n/--path/f/' 'n/--raw/f/' 'p/*/`__xrt_smi_completion_csh`/'