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