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