xref: /kvm-unit-tests/configure (revision dbd3800490429358367c717669aab76678429ef1)
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
11cflags=
12ld=ld
13objcopy=objcopy
14objdump=objdump
15ar=ar
16addr2line=addr2line
17arch=$(uname -m | sed -e 's/i.86/i386/;s/arm.*/arm/;s/ppc64.*/ppc64/')
18host=$arch
19cross_prefix=
20endian=""
21pretty_print_stacks=yes
22environ_default=yes
23u32_long=
24wa_divide=
25target=
26errata_force=0
27erratatxt="$srcdir/errata.txt"
28host_key_document=
29page_size=
30earlycon=
31
32usage() {
33    cat <<-EOF
34	Usage: $0 [options]
35
36	Options include:
37	    --arch=ARCH            architecture to compile for ($arch)
38	    --processor=PROCESSOR  processor to compile for ($arch)
39	    --target=TARGET        target platform that the tests will be running on (qemu or
40	                           kvmtool, default is qemu) (arm/arm64 only)
41	    --cross-prefix=PREFIX  cross compiler prefix
42	    --cc=CC                c compiler to use ($cc)
43	    --cflags=FLAGS         extra options to be passed to the c compiler
44	    --ld=LD                ld linker to use ($ld)
45	    --prefix=PREFIX        where to install things ($prefix)
46	    --endian=ENDIAN        endianness to compile for (little or big, ppc64 only)
47	    --[enable|disable]-pretty-print-stacks
48	                           enable or disable pretty stack printing (enabled by default)
49	    --[enable|disable]-default-environ
50	                           enable or disable the generation of a default environ when
51	                           no environ is provided by the user (enabled by default)
52	    --erratatxt=FILE       specify a file to use instead of errata.txt. Use
53	                           '--erratatxt=' to ensure no file is used.
54	    --host-key-document=HOST_KEY_DOCUMENT
55	                           Specify the machine-specific host-key document for creating
56	                           a PVM image with 'genprotimg' (s390x only)
57	    --page-size=PAGE_SIZE
58	                           Specify the page size (translation granule) (4k, 16k or
59	                           64k, default is 64k, arm64 only)
60	    --earlycon=EARLYCON
61	                           Specify the UART name, type and address (optional, arm and
62	                           arm64 only). The specified address will overwrite the UART
63	                           address set by the --target option. EARLYCON can be one of
64	                           (case sensitive):
65	               uart[8250],mmio,ADDR
66	                           Specify an 8250 compatible UART at address ADDR. Supported
67	                           register stride is 8 bit only.
68	               pl011,ADDR
69	               pl011,mmio32,ADDR
70	                           Specify a PL011 compatible UART at address ADDR. Supported
71	                           register stride is 32 bit only.
72EOF
73    exit 1
74}
75
76while [[ "$1" = -* ]]; do
77    opt="$1"; shift
78    arg=
79    if [[ "$opt" = *=* ]]; then
80	arg="${opt#*=}"
81	opt="${opt%%=*}"
82    fi
83    case "$opt" in
84	--prefix)
85	    prefix="$arg"
86	    ;;
87        --arch)
88	    arch="$arg"
89	    ;;
90        --processor)
91	    processor="$arg"
92	    ;;
93	--target)
94	    target="$arg"
95	    ;;
96	--cross-prefix)
97	    cross_prefix="$arg"
98	    ;;
99	--endian)
100	    endian="$arg"
101	    ;;
102	--cc)
103	    cc="$arg"
104	    ;;
105	--cflags)
106	    cflags="$arg"
107	    ;;
108	--ld)
109	    ld="$arg"
110	    ;;
111	--enable-pretty-print-stacks)
112	    pretty_print_stacks=yes
113	    ;;
114	--disable-pretty-print-stacks)
115	    pretty_print_stacks=no
116	    ;;
117	--enable-default-environ)
118	    environ_default=yes
119	    ;;
120	--disable-default-environ)
121	    environ_default=no
122	    ;;
123	--erratatxt)
124	    erratatxt=
125	    [ "$arg" ] && erratatxt=$(eval realpath "$arg")
126	    ;;
127	--host-key-document)
128	    host_key_document="$arg"
129	    ;;
130	--page-size)
131	    page_size="$arg"
132	    ;;
133	--earlycon)
134	    earlycon="$arg"
135	    ;;
136	--help)
137	    usage
138	    ;;
139	*)
140	    usage
141	    ;;
142    esac
143done
144
145if [ -n "$host_key_document" ] && [ ! -f "$host_key_document" ]; then
146    echo "Host key document doesn't exist at the specified location."
147    exit 1
148fi
149
150if [ "$erratatxt" ] && [ ! -f "$erratatxt" ]; then
151    echo "erratatxt: $erratatxt does not exist or is not a regular file"
152    exit 1
153fi
154
155arch_name=$arch
156[ "$arch" = "aarch64" ] && arch="arm64"
157[ "$arch_name" = "arm64" ] && arch_name="aarch64"
158
159if [ -z "$target" ]; then
160    target="qemu"
161else
162    if [ "$arch" != "arm64" ] && [ "$arch" != "arm" ]; then
163        echo "--target is not supported for $arch"
164        usage
165    fi
166fi
167
168if [ -z "$page_size" ]; then
169    [ "$arch" = "arm64" ] && page_size="65536"
170    [ "$arch" = "arm" ] && page_size="4096"
171else
172    if [ "$arch" != "arm64" ]; then
173        echo "--page-size is not supported for $arch"
174        usage
175    fi
176
177    if [ "${page_size: -1}" = "K" ] || [ "${page_size: -1}" = "k" ]; then
178        page_size=$(( ${page_size%?} * 1024 ))
179    fi
180    if [ "$page_size" != "4096" ] && [ "$page_size" != "16384" ] &&
181           [ "$page_size" != "65536" ]; then
182        echo "arm64 doesn't support page size of $page_size"
183        usage
184    fi
185fi
186
187[ -z "$processor" ] && processor="$arch"
188
189if [ "$processor" = "arm64" ]; then
190    processor="cortex-a57"
191elif [ "$processor" = "arm" ]; then
192    processor="cortex-a15"
193fi
194
195if [ "$arch" = "i386" ] || [ "$arch" = "x86_64" ]; then
196    testdir=x86
197elif [ "$arch" = "arm" ] || [ "$arch" = "arm64" ]; then
198    testdir=arm
199    if [ "$target" = "qemu" ]; then
200        arm_uart_early_addr=0x09000000
201    elif [ "$target" = "kvmtool" ]; then
202        arm_uart_early_addr=0x1000000
203        errata_force=1
204    else
205        echo "--target must be one of 'qemu' or 'kvmtool'!"
206        usage
207    fi
208
209    if [ "$earlycon" ]; then
210        IFS=, read -r name type_addr addr <<<"$earlycon"
211        if [ "$name" != "uart" ] && [ "$name" != "uart8250" ] &&
212                [ "$name" != "pl011" ]; then
213            echo "unknown earlycon name: $name"
214            usage
215        fi
216
217        if [ "$name" = "pl011" ]; then
218            if [ -z "$addr" ]; then
219                addr=$type_addr
220            else
221                if [ "$type_addr" != "mmio32" ]; then
222                    echo "unknown $name earlycon type: $type_addr"
223                    usage
224                fi
225            fi
226        else
227            if [ "$type_addr" != "mmio" ]; then
228                echo "unknown $name earlycon type: $type_addr"
229                usage
230            fi
231        fi
232
233        if [ -z "$addr" ]; then
234            echo "missing $name earlycon address"
235            usage
236        fi
237        if [[ $addr =~ ^0(x|X)[0-9a-fA-F]+$ ]] ||
238                [[ $addr =~ ^[0-9]+$ ]]; then
239            arm_uart_early_addr=$addr
240        else
241            echo "invalid $name earlycon address: $addr"
242            usage
243        fi
244    fi
245elif [ "$arch" = "ppc64" ]; then
246    testdir=powerpc
247    firmware="$testdir/boot_rom.bin"
248    if [ "$endian" != "little" ] && [ "$endian" != "big" ]; then
249        echo "You must provide endianness (big or little)!"
250        usage
251    fi
252else
253    testdir=$arch
254fi
255if [ ! -d "$srcdir/$testdir" ]; then
256    echo "$testdir does not exist!"
257    exit 1
258fi
259if [ -f "$srcdir/$testdir/run" ]; then
260    ln -fs "$srcdir/$testdir/run" $testdir-run
261fi
262
263# check if uint32_t needs a long format modifier
264cat << EOF > lib-test.c
265__UINT32_TYPE__
266EOF
267u32_long=$("$cross_prefix$cc" -E lib-test.c | grep -v '^#' | grep -q long && echo yes)
268rm -f lib-test.c
269
270# check if slash can be used for division
271if [ "$arch" = "i386" ] || [ "$arch" = "x86_64" ]; then
272  cat << EOF > lib-test.S
273foo:
274    movl (8 / 2), %eax
275EOF
276  wa_divide=$("$cross_prefix$cc" -c lib-test.S >/dev/null 2>&1 || echo yes)
277  rm -f lib-test.{o,S}
278fi
279
280# require enhanced getopt
281getopt -T > /dev/null
282if [ $? -ne 4 ]; then
283    echo "Enhanced getopt is not available, add it to your PATH?"
284    exit 1
285fi
286
287# Are we in a separate build tree? If so, link the Makefile
288# and shared stuff so that 'make' and run_tests.sh work.
289if test ! -e Makefile; then
290    echo "linking Makefile..."
291    ln -s "$srcdir/Makefile" .
292
293    echo "linking tests..."
294    mkdir -p $testdir
295    ln -sf "$srcdir/$testdir/run" $testdir/
296    ln -sf "$srcdir/$testdir/unittests.cfg" $testdir/
297    ln -sf "$srcdir/run_tests.sh"
298
299    if [ -d "$srcdir/$testdir/snippets" ]; then
300        mkdir -p "$testdir/snippets/c"
301    fi
302
303    echo "linking scripts..."
304    ln -sf "$srcdir/scripts"
305fi
306
307# link lib/asm for the architecture
308rm -f lib/asm
309asm="asm-generic"
310if [ -d "$srcdir/lib/$arch/asm" ]; then
311	asm="$srcdir/lib/$arch/asm"
312elif [ -d "$srcdir/lib/$testdir/asm" ]; then
313	asm="$srcdir/lib/$testdir/asm"
314fi
315mkdir -p lib
316ln -sf "$asm" lib/asm
317
318
319# create the config
320cat <<EOF > config.mak
321SRCDIR=$srcdir
322PREFIX=$prefix
323HOST=$host
324ARCH=$arch
325ARCH_NAME=$arch_name
326PROCESSOR=$processor
327CC=$cross_prefix$cc
328CFLAGS=$cflags
329LD=$cross_prefix$ld
330OBJCOPY=$cross_prefix$objcopy
331OBJDUMP=$cross_prefix$objdump
332AR=$cross_prefix$ar
333ADDR2LINE=$cross_prefix$addr2line
334TEST_DIR=$testdir
335FIRMWARE=$firmware
336ENDIAN=$endian
337PRETTY_PRINT_STACKS=$pretty_print_stacks
338ENVIRON_DEFAULT=$environ_default
339ERRATATXT=$erratatxt
340U32_LONG_FMT=$u32_long
341WA_DIVIDE=$wa_divide
342GENPROTIMG=${GENPROTIMG-genprotimg}
343HOST_KEY_DOCUMENT=$host_key_document
344EOF
345if [ "$arch" = "arm" ] || [ "$arch" = "arm64" ]; then
346    echo "TARGET=$target" >> config.mak
347fi
348
349cat <<EOF > lib/config.h
350#ifndef _CONFIG_H_
351#define _CONFIG_H_
352/*
353 * Generated file. DO NOT MODIFY.
354 *
355 */
356
357EOF
358if [ "$arch" = "arm" ] || [ "$arch" = "arm64" ]; then
359cat <<EOF >> lib/config.h
360
361#define CONFIG_UART_EARLY_BASE ${arm_uart_early_addr}
362#define CONFIG_ERRATA_FORCE ${errata_force}
363#define CONFIG_PAGE_SIZE _AC(${page_size}, UL)
364
365EOF
366fi
367echo "#endif" >> lib/config.h
368