1#!/bin/bash 2# SPDX-License-Identifier: BSD-3-Clause 3# Copyright(c) 2018 Intel Corporation. All rights reserved. 4set -e 5 6SUPPORTED_PLATFORMS=(byt cht bdw hsw apl icl skl kbl cnl imx8 imx8x imx8m) 7 8SOF_DIR=$(cd "$(dirname "$0")" && cd .. && pwd) 9 10: "${SOF_BUILDS:=${SOF_DIR}}" 11 12rm -f dump-*.txt 13 14die() 15{ 16 >&2 printf '%s ERROR: ' "$0" 17 # We want die() to be usable exactly like printf 18 # shellcheck disable=SC2059 19 >&2 printf "$@" 20 exit 1 21} 22 23print_usage() 24{ 25 cat <<EOF 26usage: qemu-check.sh [ platform(s) ] 27 Supported platforms are ${SUPPORTED_PLATFORMS[*]} 28 Runs all supported platforms by default. 29EOF 30} 31 32find_qemu_xtensa() 33{ 34 local xhs=xtensa-host.sh 35 for d in . ../qemu* qemu*; do 36 if test -e "$d"/$xhs; then 37 printf '%s' "$d"/$xhs; 38 return 39 fi 40 done 41 die '%s not found\n' $xhs 42} 43 44 45while getopts "" OPTION; do 46 case "$OPTION" in 47 *) print_usage; exit 1 ;; 48 esac 49done 50shift $((OPTIND-1)) 51 52PLATFORMS=() 53if [ "$#" -eq 0 ]; then 54 PLATFORMS=("${SUPPORTED_PLATFORMS[@]}") 55else 56 for arg in "$@"; do 57 platform=unknown 58 for sp in "${SUPPORTED_PLATFORMS[@]}"; do 59 if [ x"$sp" = x"$arg" ]; then 60 PLATFORMS=("${PLATFORMS[@]}" "$sp") 61 platform=$sp 62 shift 63 break 64 fi 65 done 66 if [ "$platform" = "unknown" ]; then 67 echo "Error: Unknown platform specified: $arg" 68 echo "Supported platforms: ${SUPPORTED_PLATFORMS[*]}" 69 exit 1 70 fi 71 done 72fi 73 74for platform in "${PLATFORMS[@]}" 75do 76 FWNAME="sof-$platform.ri" 77 PLATFORM=$platform 78 # reset variable to avoid issue in random order 79 ROM='' 80 OUTBOX_OFFSET='' 81 82 has_rom=false 83 case "$platform" in 84 byt) 85 READY_IPC="00 88 02 70 00 00 00 80" 86 SHM_IPC_REG=qemu-bridge-shim-io 87 SHM_MBOX=qemu-bridge-mbox-io 88 ;; 89 cht) 90 READY_IPC="00 88 02 70 00 00 00 80" 91 SHM_IPC_REG=qemu-bridge-shim-io 92 SHM_MBOX=qemu-bridge-mbox-io 93 ;; 94 bdw) 95 READY_IPC="00 3c 01 80" 96 OUTBOX_OFFSET="9e000" 97 SHM_IPC_REG=qemu-bridge-shim-io 98 SHM_MBOX=qemu-bridge-dram-mem 99 ;; 100 hsw) 101 # This READY_IPC value comes from: 102 # shim_write(SHIM_IPCD, outbox | SHIM_IPCD_BUSY); 103 # outbox=MAILBOX_HOST_OFFSET >> 3; 104 # MAILBOX_HOST_OFFSET>>3 = 0xFC00 105 # IPC_DIPCIDR_BUSY = BIT(31) 106 READY_IPC="00 fc 00 80" 107 OUTBOX_OFFSET="7e000" 108 SHM_IPC_REG=qemu-bridge-shim-io 109 SHM_MBOX=qemu-bridge-dram-mem # some DMA traces visible here 110 ;; 111 apl) 112 # This READY_IPC value comes from: 113 # ipc_write(IPC_DIPCIDR, IPC_DIPCIDR_BUSY | header); 114 # header = FE_READY = 0x7 115 # IPC_DIPCIDR_BUSY = BIT(31) 116 # So "00 00 00 f0" is just "F0000000" 117 READY_IPC="00 00 00 f0" 118 SHM_IPC_REG="qemu-bridge-ipc(|-dsp)-io" 119 OUTBOX_OFFSET="7000" 120 SHM_MBOX=qemu-bridge-hp-sram-mem 121 has_rom=true 122 ;; 123 skl) 124 READY_IPC="00 00 00 f0" 125 SHM_IPC_REG="qemu-bridge-ipc(|-dsp)-io" 126 OUTBOX_OFFSET="7000" 127 SHM_MBOX=qemu-bridge-hp-sram-mem 128 has_rom=true 129 ;; 130 kbl) 131 READY_IPC="00 00 00 f0" 132 SHM_IPC_REG="qemu-bridge-ipc(|-dsp)-io" 133 OUTBOX_OFFSET="7000" 134 SHM_MBOX=qemu-bridge-hp-sram-mem 135 has_rom=true 136 ;; 137 cnl) 138 READY_IPC="00 00 00 f0" 139 SHM_IPC_REG="qemu-bridge-ipc(|-dsp)-io" 140 OUTBOX_OFFSET="5000" 141 SHM_MBOX=qemu-bridge-hp-sram-mem 142 has_rom=true 143 ;; 144 icl) 145 READY_IPC="00 00 00 f0" 146 SHM_IPC_REG="qemu-bridge-ipc(|-dsp)-io" 147 OUTBOX_OFFSET="5000" 148 SHM_MBOX=qemu-bridge-hp-sram-mem 149 has_rom=true 150 ;; 151 imx8 | imx8x | imx8m) 152 READY_IPC="00 00 00 00 00 00 04 c0" 153 SHM_IPC_REG=qemu-bridge-mu-io 154 SHM_MBOX=qemu-bridge-mbox-io 155 ;; 156 esac 157 158 if $has_rom; then 159 ROM=(-r "${SOF_BUILDS}/build_${platform}_gcc/src/arch/xtensa/rom-$platform.bin") 160 fi 161 162 xtensa_host_sh=$(find_qemu_xtensa) 163 164 ret=0 165 ( set -x 166 167 ${xtensa_host_sh} "$PLATFORM" -k \ 168 "${SOF_BUILDS}"/build_"${platform}"_gcc/src/arch/xtensa/"$FWNAME" \ 169 "${ROM[@]}" \ 170 -o 2.0 "${SOF_BUILDS}"/dump-"$platform".txt 171 # dump log into sof.git incase running in docker 172 ) || ret=$? # this defeats set -e 173 # See 'man timeout' 174 test $ret = 124 || die 'qemu failed before we stopped it!\n' 175 176 # use regular expression to match the SHM IPC REG file name, one of: 177 # /dev/shm/qemu-bridge-{shim,ipc,dsp}-io 178 SHM_IPC_REG_FILE=$(ls /dev/shm/ | grep -E $SHM_IPC_REG) || true 179 180 test -e /dev/shm/"${SHM_IPC_REG_FILE}" || 181 die '%s: %s not found in /dev/shm/\n' "$0" "$SHM_IPC_REG" 182 183 # Check if ready ipc header is in the ipc regs doorbell 184 # registers or shared memory for older platforms. 185 # See: 186 # - 'adsp_reg_space' in qemu/ 187 # - shim_write() or ipc_write() in sof/ 188 IPC_REG=$(hexdump -C /dev/shm/"$SHM_IPC_REG_FILE" | 189 grep "$READY_IPC") || true 190 191 # Check if ready ipc message is in the mbox-io / sram-mem 192 # See "struct sof_ipc_fw_ready" and 193 # objdump -s -j .fw_ready -s build/sof 194 READY_MSG="6c 00 00 00 00 00 00 70" 195 IPC_MSG=$(hexdump -C /dev/shm/$SHM_MBOX | grep -A 4 "$READY_MSG" | 196 grep -A 4 "$OUTBOX_OFFSET") || true 197 198 if [ "$IPC_REG" ]; then 199 echo "ipc reg dump:" 200 # directly output the log to be nice to look 201 hexdump -C /dev/shm/"$SHM_IPC_REG_FILE" | grep "$READY_IPC" 202 if [ "$IPC_MSG" ]; then 203 echo "ipc message dump:" 204 # directly output the log to be nice to look 205 hexdump -C /dev/shm/$SHM_MBOX | grep -A 4 "$READY_MSG" | grep -A 4 "$OUTBOX_OFFSET" 206 else 207 echo "Error mailbox failed" 208 fi 209 else 210 echo "Error ipc reg failed" 211 fi 212 213 if [[ "$IPC_REG" && "$IPC_MSG" ]]; then 214 echo "Boot success"; 215 else 216 echo "Error boot failed" 217 tail -n 50 "${SOF_BUILDS}"/dump-"$platform".txt 218 exit 2; 219 fi 220done 221