1#!/usr/bin/env bash 2 3if [ -z "${BASH_VERSINFO[0]}" ] || [ "${BASH_VERSINFO[0]}" -lt 4 ] ; then 4 echo "Error: Bash version 4 or newer is required for the kvm-unit-tests" 5 exit 1 6fi 7 8srcdir=$(cd "$(dirname "$0")"; pwd) 9prefix=/usr/local 10cc=gcc 11ld=ld 12objcopy=objcopy 13objdump=objdump 14ar=ar 15addr2line=addr2line 16arch=`uname -m | sed -e 's/i.86/i386/;s/arm.*/arm/;s/ppc64.*/ppc64/'` 17host=$arch 18cross_prefix= 19endian="" 20pretty_print_stacks=yes 21environ_default=yes 22u32_long= 23wa_divide= 24vmm="qemu" 25errata_force=0 26erratatxt="$srcdir/errata.txt" 27host_key_document= 28page_size= 29 30usage() { 31 cat <<-EOF 32 Usage: $0 [options] 33 34 Options include: 35 --arch=ARCH architecture to compile for ($arch) 36 --processor=PROCESSOR processor to compile for ($arch) 37 --vmm=VMM virtual machine monitor to compile for (qemu 38 or kvmtool, default is qemu) (arm/arm64 only) 39 --cross-prefix=PREFIX cross compiler prefix 40 --cc=CC c compiler to use ($cc) 41 --ld=LD ld linker to use ($ld) 42 --prefix=PREFIX where to install things ($prefix) 43 --endian=ENDIAN endianness to compile for (little or big, ppc64 only) 44 --[enable|disable]-pretty-print-stacks 45 enable or disable pretty stack printing (enabled by default) 46 --[enable|disable]-default-environ 47 enable or disable the generation of a default environ when 48 no environ is provided by the user (enabled by default) 49 --erratatxt=FILE specify a file to use instead of errata.txt. Use 50 '--erratatxt=' to ensure no file is used. 51 --host-key-document=HOST_KEY_DOCUMENT 52 Specify the machine-specific host-key document for creating 53 a PVM image with 'genprotimg' (s390x only) 54 --page-size=PAGE_SIZE 55 Specify the page size (translation granule) (4k, 16k or 56 64k, default is 64k, arm64 only) 57EOF 58 exit 1 59} 60 61while [[ "$1" = -* ]]; do 62 opt="$1"; shift 63 arg= 64 if [[ "$opt" = *=* ]]; then 65 arg="${opt#*=}" 66 opt="${opt%%=*}" 67 fi 68 case "$opt" in 69 --prefix) 70 prefix="$arg" 71 ;; 72 --arch) 73 arch="$arg" 74 ;; 75 --processor) 76 processor="$arg" 77 ;; 78 --vmm) 79 vmm="$arg" 80 ;; 81 --cross-prefix) 82 cross_prefix="$arg" 83 ;; 84 --endian) 85 endian="$arg" 86 ;; 87 --cc) 88 cc="$arg" 89 ;; 90 --ld) 91 ld="$arg" 92 ;; 93 --enable-pretty-print-stacks) 94 pretty_print_stacks=yes 95 ;; 96 --disable-pretty-print-stacks) 97 pretty_print_stacks=no 98 ;; 99 --enable-default-environ) 100 environ_default=yes 101 ;; 102 --disable-default-environ) 103 environ_default=no 104 ;; 105 --erratatxt) 106 erratatxt= 107 [ "$arg" ] && erratatxt=$(eval realpath "$arg") 108 ;; 109 --host-key-document) 110 host_key_document="$arg" 111 ;; 112 --page-size) 113 page_size="$arg" 114 ;; 115 --help) 116 usage 117 ;; 118 *) 119 usage 120 ;; 121 esac 122done 123 124if [ "$erratatxt" ] && [ ! -f "$erratatxt" ]; then 125 echo "erratatxt: $erratatxt does not exist or is not a regular file" 126 exit 1 127fi 128 129arch_name=$arch 130[ "$arch" = "aarch64" ] && arch="arm64" 131[ "$arch_name" = "arm64" ] && arch_name="aarch64" 132 133if [ -z "$page_size" ]; then 134 [ "$arch" = "arm64" ] && page_size="65536" 135 [ "$arch" = "arm" ] && page_size="4096" 136else 137 if [ "$arch" != "arm64" ]; then 138 echo "--page-size is not supported for $arch" 139 usage 140 fi 141 142 if [ "${page_size: -1}" = "K" ] || [ "${page_size: -1}" = "k" ]; then 143 page_size=$(( ${page_size%?} * 1024 )) 144 fi 145 if [ "$page_size" != "4096" ] && [ "$page_size" != "16384" ] && 146 [ "$page_size" != "65536" ]; then 147 echo "arm64 doesn't support page size of $page_size" 148 usage 149 fi 150fi 151 152[ -z "$processor" ] && processor="$arch" 153 154if [ "$processor" = "arm64" ]; then 155 processor="cortex-a57" 156elif [ "$processor" = "arm" ]; then 157 processor="cortex-a15" 158fi 159 160if [ "$arch" = "i386" ] || [ "$arch" = "x86_64" ]; then 161 testdir=x86 162elif [ "$arch" = "arm" ] || [ "$arch" = "arm64" ]; then 163 testdir=arm 164 if [ "$vmm" = "qemu" ]; then 165 arm_uart_early_addr=0x09000000 166 elif [ "$vmm" = "kvmtool" ]; then 167 arm_uart_early_addr=0x3f8 168 errata_force=1 169 else 170 echo '--vmm must be one of "qemu" or "kvmtool"!' 171 usage 172 fi 173elif [ "$arch" = "ppc64" ]; then 174 testdir=powerpc 175 firmware="$testdir/boot_rom.bin" 176 if [ "$endian" != "little" ] && [ "$endian" != "big" ]; then 177 echo "You must provide endianness (big or little)!" 178 usage 179 fi 180else 181 testdir=$arch 182fi 183if [ ! -d "$srcdir/$testdir" ]; then 184 echo "$testdir does not exist!" 185 exit 1 186fi 187if [ -f "$srcdir/$testdir/run" ]; then 188 ln -fs "$srcdir/$testdir/run" $testdir-run 189fi 190 191# check if uint32_t needs a long format modifier 192cat << EOF > lib-test.c 193__UINT32_TYPE__ 194EOF 195u32_long=$("$cross_prefix$cc" -E lib-test.c | grep -v '^#' | grep -q long && echo yes) 196rm -f lib-test.c 197 198# check if slash can be used for division 199if [ "$arch" = "i386" ] || [ "$arch" = "x86_64" ]; then 200 cat << EOF > lib-test.S 201foo: 202 movl (8 / 2), %eax 203EOF 204 wa_divide=$("$cross_prefix$cc" -c lib-test.S >/dev/null 2>&1 || echo yes) 205 rm -f lib-test.{o,S} 206fi 207 208# require enhanced getopt 209getopt -T > /dev/null 210if [ $? -ne 4 ]; then 211 echo "Enhanced getopt is not available, add it to your PATH?" 212 exit 1 213fi 214 215# Are we in a separate build tree? If so, link the Makefile 216# and shared stuff so that 'make' and run_tests.sh work. 217if test ! -e Makefile; then 218 echo "linking Makefile..." 219 ln -s "$srcdir/Makefile" . 220 221 echo "linking tests..." 222 mkdir -p $testdir 223 ln -sf "$srcdir/$testdir/run" $testdir/ 224 ln -sf "$srcdir/$testdir/unittests.cfg" $testdir/ 225 ln -sf "$srcdir/run_tests.sh" 226 227 echo "linking scripts..." 228 ln -sf "$srcdir/scripts" 229fi 230 231# link lib/asm for the architecture 232rm -f lib/asm 233asm="asm-generic" 234if [ -d "$srcdir/lib/$arch/asm" ]; then 235 asm="$srcdir/lib/$arch/asm" 236elif [ -d "$srcdir/lib/$testdir/asm" ]; then 237 asm="$srcdir/lib/$testdir/asm" 238fi 239mkdir -p lib 240ln -sf "$asm" lib/asm 241 242 243# create the config 244cat <<EOF > config.mak 245SRCDIR=$srcdir 246PREFIX=$prefix 247HOST=$host 248ARCH=$arch 249ARCH_NAME=$arch_name 250PROCESSOR=$processor 251CC=$cross_prefix$cc 252LD=$cross_prefix$ld 253OBJCOPY=$cross_prefix$objcopy 254OBJDUMP=$cross_prefix$objdump 255AR=$cross_prefix$ar 256ADDR2LINE=$cross_prefix$addr2line 257TEST_DIR=$testdir 258FIRMWARE=$firmware 259ENDIAN=$endian 260PRETTY_PRINT_STACKS=$pretty_print_stacks 261ENVIRON_DEFAULT=$environ_default 262ERRATATXT=$erratatxt 263U32_LONG_FMT=$u32_long 264WA_DIVIDE=$wa_divide 265GENPROTIMG=${GENPROTIMG-genprotimg} 266HOST_KEY_DOCUMENT=$host_key_document 267EOF 268 269cat <<EOF > lib/config.h 270#ifndef CONFIG_H 271#define CONFIG_H 1 272/* 273 * Generated file. DO NOT MODIFY. 274 * 275 */ 276 277EOF 278if [ "$arch" = "arm" ] || [ "$arch" = "arm64" ]; then 279cat <<EOF >> lib/config.h 280 281#define CONFIG_UART_EARLY_BASE ${arm_uart_early_addr} 282#define CONFIG_ERRATA_FORCE ${errata_force} 283#define CONFIG_PAGE_SIZE _AC(${page_size}, UL) 284 285EOF 286fi 287echo "#endif" >> lib/config.h 288