1#!/bin/bash 2# 3# SPDX-License-Identifier: BSD-3-Clause 4# 5# Copyright © 2019 Keith Packard 6# 7# Redistribution and use in source and binary forms, with or without 8# modification, are permitted provided that the following conditions 9# are met: 10# 11# 1. Redistributions of source code must retain the above copyright 12# notice, this list of conditions and the following disclaimer. 13# 14# 2. Redistributions in binary form must reproduce the above 15# copyright notice, this list of conditions and the following 16# disclaimer in the documentation and/or other materials provided 17# with the distribution. 18# 19# 3. Neither the name of the copyright holder nor the names of its 20# contributors may be used to endorse or promote products derived 21# from this software without specific prior written permission. 22# 23# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 26# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 27# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 28# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 29# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 30# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 32# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 33# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 34# OF THE POSSIBILITY OF SUCH DAMAGE. 35# 36 37qemu="qemu-system-arm" 38 39# select the program 40elf="$1" 41shift 42 43cpu=unknown 44machine=unknown 45memory= 46 47# 48# Map ELF information to required core type 49# 50 51cpu_arch=`arm-none-eabi-readelf -A "$elf" | awk '/Tag_CPU_arch:/ { print $2 }'` 52cpu_profile=`arm-none-eabi-readelf -A "$elf" | awk '/Tag_CPU_arch_profile:/ { print $2 }'` 53fp_arch=`arm-none-eabi-readelf -A "$elf" | awk '/Tag_FP_arch/ { print $2 }'` 54fp_use=`arm-none-eabi-readelf -A "$elf" | awk '/Tag_ABI_HardFP_use/ { print $2 }'` 55ram_addr=`arm-none-eabi-readelf -l "$elf" | awk '/LOAD.*RW/ { if (min_va == 0 || $3 < min_va) min_va = $3; } END { print(min_va); }'` 56 57case "$cpu_arch"/"$cpu_profile" in 58 v4T/) 59 cpu=ti925t 60 ;; 61 v5TE/|v5T/) 62 cpu=arm926 63 ;; 64 v6S-M/Microcontroller) 65 cpu=cortex-m0 66 ;; 67 v7/Application) 68 case "$fp_arch" in 69 VFPv3) 70 cpu=cortex-a9 71 ;; 72 VFPv3-D16) 73 cpu=cortex-a8 74 ;; 75 VFPv4) 76 cpu=cortex-a7 77 ;; 78 *) 79 cpu=cortex-a7 80 ;; 81 esac 82 ;; 83 v7/) 84 case "$fp_arch" in 85 VFPv3) 86 cpu=cortex-r5 87 ;; 88 VFPv3-D16) 89 cpu=cortex-r5f 90 ;; 91 *) 92 cpu=cortex-r5 93 ;; 94 esac 95 ;; 96 v7/Microcontroller) 97 case "$fp_arch" in 98 FPv5/FP-D16) 99 case "$fp_use" in 100 SP) 101 cpu=cortex-m4 102 ;; 103 *) 104 cpu=cortex-m7 105 ;; 106 esac 107 ;; 108 VFPv4-D16) 109 cpu=cortex-m7 110 ;; 111 *) 112 cpu=cortex-m3 113 ;; 114 esac 115 ;; 116 v7/Realtime) 117 cpu=cortex-r5f 118 ;; 119 v7E-M/Microcontroller) 120 cpu=cortex-m7 121 case "$fp_arch" in 122 FPv5/FP-D16) 123 case "$fp_use" in 124 SP) 125 cpu=cortex-m4 126 ;; 127 esac 128 ;; 129 VFPv4-D16) 130 cpu=cortex-m7 131 ;; 132 *) 133 cpu=cortex-m4 134 ;; 135 esac 136 ;; 137 138 v8-M.*/Microcontroller) 139 case "$fp_arch" in 140 FPv5/FP-D16) 141 case "$fp_use" in 142 SP) 143 cpu=cortex-m33 144 ;; 145 *) 146 cpu=cortex-m55 147 ;; 148 esac 149 ;; 150 *) 151 cpu=cortex-m33 152 ;; 153 esac 154 ;; 155 v8.1-M.mainline/Microcontroller) 156 cpu=cortex-m55 157 ;; 158 v8/Application) 159 cpu=cortex-a57 160 ;; 161esac 162 163# 164# Select a QEMU machine based on the CPU 165# 166case $cpu in 167 168 cortex-m0) 169 machine=microbit 170 memory="-global nrf51-soc.sram-size=2097152 -global nrf51-soc.flash-size=4194304" 171 ;; 172 173 # mps2-an385 offers a cortex-m3 processor 174 cortex-m3) 175 machine=mps2-an385 176 ;; 177 178 # mps2-an386 offers a cortex-m4 processor 179 cortex-m4) 180 machine=mps2-an386 181 ;; 182 183 # mps2-an500 offers a cortex-m7 processor 184 cortex-m7) 185 machine=mps2-an500 186 ;; 187 188 # mps2-an505 offers a cortex-m33 processor 189 cortex-m33) 190 machine=mps2-an505 191 ;; 192 193 # mps3-an547 offers a cortex-m55 processor 194 cortex-m55) 195 machine=mps3-an547 196 ;; 197 198 cortex-a57) 199 machine=none 200 cpu=max 201 memory="-m 1G" 202 ;; 203 204 cortex-a?) 205 case "$ram_addr" in 206 0x48*) 207 machine=vexpress-a9 208 cpu=cortex-a9 209 ;; 210 *) 211 machine=none 212 ;; 213 esac 214 memory="-m 1G" 215 ;; 216 217 # The 'none' machine supports many non-M 218 # processors 219 ti925t|arm*|cortex-a*|cortex-r*) 220 machine=none 221 memory="-m 1G" 222 ;; 223 224esac 225 226# 227# Make sure the target machine and cpu is supported by qemu 228# 229if $qemu -machine help | grep -q "^$machine "; then 230 if $qemu -machine $machine -cpu help | grep -q "^ *$cpu"; then 231 : 232 else 233 echo "Skipping $elf: unsupported cpu on $machine" 234 exit 77 235 fi 236else 237 echo "Skipping $elf: unsupported machine" 238 exit 77 239fi 240 241# Map stdio to a multiplexed character device so we can use it 242# for the monitor and semihosting output 243 244chardev=stdio,mux=on,id=stdio0 245 246# Point the semihosting driver at our new chardev 247 248cmdline="program-name" 249input="" 250done=0 251 252while [ "$done" != "1" ]; do 253 case "$1" in 254 --) 255 shift 256 done=1 257 ;; 258 -s|"") 259 done=1 260 ;; 261 *) 262 cmdline="$cmdline $1" 263 case "$input" in 264 "") 265 input="$1" 266 ;; 267 *) 268 input="$input $1" 269 ;; 270 esac 271 shift 272 ;; 273 esac 274done 275 276semi=enable=on,chardev=stdio0,arg="$cmdline" 277 278# Disable monitor 279 280mon=none 281 282# Disable serial 283 284serial=none 285 286export QEMU_AUDIO_DRV=none 287 288input_file=`mktemp` 289trap 'rm "$input_file"' 0 290echo "$input" > "$input_file" 291 292"$qemu" $memory \ 293 -chardev "$chardev" \ 294 -semihosting-config "$semi" \ 295 -monitor "$mon" \ 296 -serial "$serial" \ 297 -machine "$machine",accel=tcg \ 298 -cpu "$cpu" \ 299 -device loader,file="$elf",cpu-num=0 \ 300 -nographic \ 301 "$@" < $input_file 302 303result=$? 304 305if [ $result != 0 ]; then 306 case $cpu in 307 # Cortex-a8 qemu has minor floating point errors 308 # when run on i686 processors 309 cortex-a8) 310 test="$(uname -m)-$elf" 311 case "$test" in 312 i?86-*math_test|i?86-*math_test_?|i?86-*math_test_??) 313 echo "fp imprecise for $cpu on" "$(uname -m)" 314 result=77 315 ;; 316 esac 317 ;; 318 esac 319fi 320exit $result 321