1#!/bin/sh 2# Copyright (c) 2022-2024 Intel Corporation 3# SPDX-License-Identifier: Apache-2.0 4set -e 5 6# Twister integration tool for a remote ssh-accessible cAVS audio DSP 7# host (e.g. an Up Squared board running Linux). Can be used as the 8# hook for both --device-serial-pty and --west-flash, for example: 9# 10# export CAVS_OLD_FLASHER=1 11# export CAVS_HOST=tgl2 12# export CAVS_KEY=$HOME/otc_private_key_3k.pem 13# export CAVS_RIMAGE=$HOME/rimage 14# 15# twister -p intel_adsp/cavs25 --device-testing \ 16# --device-serial-pty=$ZEPHYR_BASE/soc/intel/intel_adsp/tools/cavstwist.sh \ 17# --west-flash=$ZEPHYR_BASE/soc/intel/intel_adsp/tools/cavstwist.sh 18# 19# The CAVS_OLD_FLASHER is necessary because now the client-server-based 20# cavstool works by default. This is to tell the build system to use 21# the misc-flasher as the runner. Please remember to do the command 22# "unset CAVS_OLD_FLASHER" when you are going to switch to the 23# client-server-based intel_adsp runner. 24# 25# The device at CAVS_HOST must be accessible via non-interactive ssh 26# access and the remote account must have password-free sudo ability. 27# (The intent is that isolating the host like this to be a CAVS test 28# unit means that simple device access at root is acceptable.) 29# 30# The signing key must be correct for your device. In general we want 31# to be using the SOF-curated "community" keys. Note that cAVS 2.5 32# uses a different (longer) key than the earlier platforms. 33# 34# CAVS_RIMAGE must be the path to a current, checked out and built (!) 35# rimage tool from SOF: https://github.com/thesofproject/rimage 36# 37# Alternatively, pass a built "zephyr.elf" file (in a complete build 38# tree, not just a standalone file) as the single argument and the 39# script will synchronously flash the device and begin emitting its 40# logs to standard output. 41# 42# Implementation notes: 43# 44# Twister has frustrating runtime behavior with this device. The 45# flash tool is run via west as part of the build, has a working 46# directory in the build tree, and is passed the build directory as 47# its command line argument. The console/serial tool is run globally 48# in $ZEPHYR_BASE. But the console script has no arguments, and thus 49# can't find the test directory! And worse, the scripts are 50# asynchronous and may start in either order, but our console script 51# can't be allowed to run until after the flash. If it does, it will 52# pull old data (from the last test run!) out of the buffer and 53# confuse twister. 54# 55# So the solution here is to have the console script do the trace 56# reading AND the flashing. The flash script merely signs the binary 57# and places it into ZEPHYR_BASE for the console script to find. The 58# console script then just has to wait for the binary to appear (which 59# solves the ordering problem), flash it, delete it (so as not to 60# confuse the next test run), and emit the adsplog output as expected. 61# 62# And notice the race protection: it's possible twister will run a 63# signing script IMMEDIATELY, simultaneous with the last flash script. 64# This may thus clobber the version that the other script hasn't seen 65# yet. So we add an extra wait step in the signing path for the 66# loader to "accept" the file. 67# 68######################################################################## 69 70# Three configuration variables to set. Have to be passed via the 71# environment because this script is launched from twister. 72 73if [ -z "$CAVS_HOST" -o -z "$CAVS_KEY" -o -z "$CAVS_RIMAGE" ]; then 74 echo "Missing cavstwist.sh configuration, must have:" 1>&2 75 echo " export CAVS_HOST=ssh_host_name[:port]" 1>&2 76 echo " export CAVS_KEY=/path/to/signing_key.pem" 1>&2 77 echo " export CAVS_RIMAGE=/path/to/built/rimage/dir" 1>&2 78 exit 1 79fi 80 81######################################################################## 82 83CAVSTOOL=$ZEPHYR_BASE/soc/intel/intel_adsp/tools/cavstool.py 84IMAGE=$ZEPHYR_BASE/_cavstmp.ri 85IMAGE2=$ZEPHYR_BASE/_cavstmp2.ri 86 87if [ "$1" = "" ]; then 88 # Twister --device-serial-pty mode 89 DO_LOAD=1 90elif [ "$(basename $1)" = "zephyr.elf" ]; then 91 # Standalone mode (argument is a path to zephyr.elf) 92 BLDDIR=$(dirname $(dirname $1)) 93 DO_SIGN=1 94 DO_LOAD=1 95else 96 # Twister --west-flash mode 97 BLDDIR=$1 98 DO_SIGN=1 99fi 100 101if [ "$DO_SIGN" = "1" ]; then 102 # Wait for the last flasher to accept the old file 103 while [ -e $IMAGE ]; do 104 sleep 0.1 105 done 106 107 ELF=$BLDDIR/zephyr/zephyr.elf.mod 108 BOOT=$BLDDIR/zephyr/bootloader.elf.mod 109 (cd $BLDDIR; 110 west sign --tool-data=$CAVS_RIMAGE/config -t rimage -- -k $CAVS_KEY) 111 cp $BLDDIR/zephyr/zephyr.ri $IMAGE 112fi 113 114if [ "$DO_LOAD" = "1" ]; then 115 while [ ! -e $IMAGE ]; do 116 sleep 0.1 117 done 118 119 # Must "accept" the file so the next signing script knows it's OK 120 # to write a new one 121 mv $IMAGE $IMAGE2 122 scp $IMAGE2 $CAVSTOOL scp://$CAVS_HOST 123 rm -f $IMAGE2 124 125 # Twister seems to overlap tests by a tiny bit, and of course the 126 # remote system might have other junk running from manual testing. 127 # If something is doing log reading at the moment of firmware 128 # load, it tends fairly reliably to hang the DSP. Kill it. 129 ssh ssh://$CAVS_HOST "sudo pkill -9 -f cavstool" ||: 130 131 exec ssh ssh://$CAVS_HOST "sudo ./$(basename $CAVSTOOL) $(basename $IMAGE2)" 132fi 133