xref: /kvm-unit-tests/configure (revision 386ed5c2f9e98a2605817748c44c0cefa60dc88e)
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 4k, 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	                           and defaults to enabled when efi is enabled for riscv64.
99	                           (arm64 and riscv64 only)
100EOF
101    exit 1
102}
103
104while [[ "$1" = -* ]]; do
105    opt="$1"; shift
106    arg=
107    if [[ "$opt" = *=* ]]; then
108	arg="${opt#*=}"
109	opt="${opt%%=*}"
110    fi
111    case "$opt" in
112	--prefix)
113	    prefix="$arg"
114	    ;;
115        --arch)
116	    arch="$arg"
117	    ;;
118        --processor)
119	    processor="$arg"
120	    ;;
121	--target)
122	    target="$arg"
123	    ;;
124	--cross-prefix)
125	    cross_prefix="$arg"
126	    ;;
127	--endian)
128	    endian="$arg"
129	    ;;
130	--cc)
131	    cc="$arg"
132	    ;;
133	--cflags)
134	    cflags="$arg"
135	    ;;
136	--ld)
137	    ld="$arg"
138	    ;;
139	--enable-pretty-print-stacks)
140	    pretty_print_stacks=yes
141	    ;;
142	--disable-pretty-print-stacks)
143	    pretty_print_stacks=no
144	    ;;
145	--enable-default-environ)
146	    environ_default=yes
147	    ;;
148	--disable-default-environ)
149	    environ_default=no
150	    ;;
151	--erratatxt)
152	    erratatxt=
153	    [ "$arg" ] && erratatxt=$(eval realpath "$arg")
154	    ;;
155	--host-key-document)
156	    host_key_document="$arg"
157	    ;;
158	--gen-se-header)
159	    gen_se_header="$arg"
160	    ;;
161	--enable-dump)
162	    enable_dump=yes
163	    ;;
164	--disable-dump)
165	    enable_dump=no
166	    ;;
167	--page-size)
168	    page_size="$arg"
169	    ;;
170	--earlycon)
171	    earlycon="$arg"
172	    ;;
173	--enable-efi)
174	    efi=y
175	    ;;
176	--disable-efi)
177	    efi=n
178	    ;;
179	--enable-efi-direct)
180	    efi_direct=y
181	    ;;
182	--disable-efi-direct)
183	    efi_direct=n
184	    ;;
185	--enable-werror)
186	    werror=-Werror
187	    ;;
188	--disable-werror)
189	    werror=
190	    ;;
191	--help)
192	    usage
193	    ;;
194	*)
195	    echo "Unknown option '$opt'"
196	    echo
197	    usage
198	    ;;
199    esac
200done
201
202if [ -z "$efi" ] || [ "$efi" = "n" ]; then
203    [ "$efi_direct" = "y" ] && efi_direct=
204fi
205
206if [ -n "$host_key_document" ] && [ ! -f "$host_key_document" ]; then
207    echo "Host key document doesn't exist at the specified location."
208    exit 1
209fi
210
211if [ "$erratatxt" ] && [ ! -f "$erratatxt" ]; then
212    echo "erratatxt: $erratatxt does not exist or is not a regular file"
213    exit 1
214fi
215
216arch_name=$arch
217[ "$arch" = "aarch64" ] && arch="arm64"
218[ "$arch_name" = "arm64" ] && arch_name="aarch64"
219arch_libdir=$arch
220
221if [ "$arch" = "riscv" ]; then
222    echo "riscv32 or riscv64 must be specified"
223    exit 1
224fi
225
226if [ -z "$target" ]; then
227    target="qemu"
228else
229    if [ "$arch" != "arm64" ] && [ "$arch" != "arm" ]; then
230        echo "--target is not supported for $arch"
231        usage
232    fi
233fi
234
235if [ "$efi" ] && [ "$arch" != "x86_64" ] &&
236   [ "$arch" != "arm64" ] && [ "$arch" != "riscv64" ]; then
237    echo "--[enable|disable]-efi is not supported for $arch"
238    usage
239fi
240
241if [ "$efi" ] && [ "$arch" = "riscv64" ] && [ -z "$efi_direct" ]; then
242    efi_direct=y
243fi
244
245if [ -z "$page_size" ]; then
246    if [ "$arch" = "arm" ] || [ "$arch" = "arm64" ]; then
247        page_size="4096"
248    fi
249else
250    if [ "$arch" != "arm64" ]; then
251        echo "--page-size is not supported for $arch"
252        usage
253    fi
254
255    if [ "${page_size: -1}" = "K" ] || [ "${page_size: -1}" = "k" ]; then
256        page_size=$(( ${page_size%?} * 1024 ))
257    fi
258    if [ "$page_size" != "4096" ] && [ "$page_size" != "16384" ] &&
259           [ "$page_size" != "65536" ]; then
260        echo "arm64 doesn't support page size of $page_size"
261        usage
262    fi
263    if [ "$efi" = 'y' ] && [ "$page_size" != "4096" ]; then
264        echo "efi must use 4K pages"
265        exit 1
266    fi
267fi
268
269[ -z "$processor" ] && processor="$arch"
270
271if [ "$processor" = "arm64" ]; then
272    processor="cortex-a57"
273elif [ "$processor" = "arm" ]; then
274    processor="cortex-a15"
275fi
276
277if [ "$arch" = "i386" ] || [ "$arch" = "x86_64" ]; then
278    testdir=x86
279elif [ "$arch" = "arm" ] || [ "$arch" = "arm64" ]; then
280    testdir=arm
281    if [ "$target" = "qemu" ]; then
282        arm_uart_early_addr=0x09000000
283    elif [ "$target" = "kvmtool" ]; then
284        arm_uart_early_addr=0x1000000
285        errata_force=1
286    else
287        echo "--target must be one of 'qemu' or 'kvmtool'!"
288        usage
289    fi
290
291    if [ "$earlycon" ]; then
292        IFS=, read -r name type_addr addr <<<"$earlycon"
293        if [ "$name" != "uart" ] && [ "$name" != "uart8250" ] &&
294                [ "$name" != "pl011" ]; then
295            echo "unknown earlycon name: $name"
296            usage
297        fi
298
299        if [ "$name" = "pl011" ]; then
300            if [ -z "$addr" ]; then
301                addr=$type_addr
302            else
303                if [ "$type_addr" != "mmio32" ]; then
304                    echo "unknown $name earlycon type: $type_addr"
305                    usage
306                fi
307            fi
308        else
309            if [ "$type_addr" != "mmio" ]; then
310                echo "unknown $name earlycon type: $type_addr"
311                usage
312            fi
313        fi
314
315        if [ -z "$addr" ]; then
316            echo "missing $name earlycon address"
317            usage
318        fi
319        if [[ $addr =~ ^0(x|X)[0-9a-fA-F]+$ ]] ||
320                [[ $addr =~ ^[0-9]+$ ]]; then
321            arm_uart_early_addr=$addr
322        else
323            echo "invalid $name earlycon address: $addr"
324            usage
325        fi
326    fi
327elif [ "$arch" = "ppc64" ]; then
328    testdir=powerpc
329    firmware="$testdir/boot_rom.bin"
330    if [ "$endian" != "little" ] && [ "$endian" != "big" ]; then
331        echo "You must provide endianness (big or little)!"
332        usage
333    fi
334elif [ "$arch" = "riscv32" ] || [ "$arch" = "riscv64" ]; then
335    testdir=riscv
336    arch_libdir=riscv
337elif [ "$arch" = "s390x" ]; then
338    testdir=s390x
339else
340    echo "arch $arch is not supported!"
341    arch=
342    usage
343fi
344if [ ! -d "$srcdir/$testdir" ]; then
345    echo "$srcdir/$testdir does not exist!"
346    exit 1
347fi
348
349if [ "$efi" = "y" ] && [ -f "$srcdir/$testdir/efi/run" ]; then
350    ln -fs "$srcdir/$testdir/efi/run" $testdir-run
351elif [ -f "$srcdir/$testdir/run" ]; then
352    ln -fs "$srcdir/$testdir/run" $testdir-run
353fi
354
355testsubdir=$testdir
356if [ "$efi" = "y" ]; then
357    testsubdir=$testdir/efi
358fi
359
360# check if uint32_t needs a long format modifier
361cat << EOF > lib-test.c
362__UINT32_TYPE__
363EOF
364u32_long=$("$cross_prefix$cc" -E lib-test.c | grep -v '^#' | grep -q long && echo yes)
365rm -f lib-test.c
366
367# check if slash can be used for division
368if [ "$arch" = "i386" ] || [ "$arch" = "x86_64" ]; then
369  cat << EOF > lib-test.S
370foo:
371    movl (8 / 2), %eax
372EOF
373  wa_divide=$("$cross_prefix$cc" -c lib-test.S >/dev/null 2>&1 || echo yes)
374  rm -f lib-test.{o,S}
375fi
376
377# warn if enhanced getopt is unavailable
378getopt -T > /dev/null
379if [ $? -ne 4 ]; then
380    echo "Without enhanced getopt you won't be able to use run_tests.sh."
381    echo "Add it to your PATH?"
382fi
383
384# Are we in a separate build tree? If so, link the Makefile
385# and shared stuff so that 'make' and run_tests.sh work.
386if test ! -e Makefile; then
387    echo "linking Makefile..."
388    ln -s "$srcdir/Makefile" .
389
390    echo "linking tests..."
391    mkdir -p $testsubdir
392    ln -sf "$srcdir/$testdir/run" $testdir/
393    if test "$testdir" != "$testsubdir"; then
394        ln -sf "$srcdir/$testsubdir/run" $testsubdir/
395    fi
396    ln -sf "$srcdir/$testdir/unittests.cfg" $testdir/
397    ln -sf "$srcdir/run_tests.sh"
398
399    if [ -d "$srcdir/$testdir/snippets" ]; then
400        mkdir -p "$testdir/snippets/c"
401    fi
402
403    echo "linking scripts..."
404    ln -sf "$srcdir/scripts"
405fi
406
407# link lib/asm for the architecture
408rm -f lib/asm
409asm="asm-generic"
410if [ -d "$srcdir/lib/$arch/asm" ]; then
411	asm="$srcdir/lib/$arch/asm"
412elif [ -d "$srcdir/lib/$testdir/asm" ]; then
413	asm="$srcdir/lib/$testdir/asm"
414fi
415mkdir -p lib
416ln -sf "$asm" lib/asm
417
418
419# create the config
420cat <<EOF > config.mak
421# Shellcheck does not see these are used
422# shellcheck disable=SC2034
423# Shellcheck can give pointless quoting warnings for some commands
424# shellcheck disable=SC2209
425SRCDIR=$srcdir
426PREFIX=$prefix
427HOST=$host
428ARCH=$arch
429ARCH_NAME=$arch_name
430ARCH_LIBDIR=$arch_libdir
431PROCESSOR=$processor
432CC=$cross_prefix$cc
433CFLAGS=$cflags
434LD=$cross_prefix$ld
435OBJCOPY=$cross_prefix$objcopy
436OBJDUMP=$cross_prefix$objdump
437READELF=$cross_prefix$readelf
438AR=$cross_prefix$ar
439ADDR2LINE=$cross_prefix$addr2line
440TEST_DIR=$testdir
441TEST_SUBDIR=$testsubdir
442FIRMWARE=$firmware
443ENDIAN=$endian
444PRETTY_PRINT_STACKS=$pretty_print_stacks
445ENVIRON_DEFAULT=$environ_default
446ERRATATXT=$erratatxt
447U32_LONG_FMT=$u32_long
448WA_DIVIDE=$wa_divide
449GENPROTIMG=${GENPROTIMG-genprotimg}
450HOST_KEY_DOCUMENT=$host_key_document
451CONFIG_DUMP=$enable_dump
452CONFIG_EFI=$efi
453EFI_DIRECT=$efi_direct
454CONFIG_WERROR=$werror
455GEN_SE_HEADER=$gen_se_header
456EOF
457if [ "$arch" = "arm" ] || [ "$arch" = "arm64" ]; then
458    echo "TARGET=$target" >> config.mak
459fi
460
461cat <<EOF > lib/config.h
462#ifndef _CONFIG_H_
463#define _CONFIG_H_
464/*
465 * Generated file. DO NOT MODIFY.
466 *
467 */
468
469EOF
470if [ "$arch" = "arm" ] || [ "$arch" = "arm64" ]; then
471cat <<EOF >> lib/config.h
472
473#define CONFIG_UART_EARLY_BASE ${arm_uart_early_addr}
474#define CONFIG_ERRATA_FORCE ${errata_force}
475#define CONFIG_PAGE_SIZE _AC(${page_size}, UL)
476
477EOF
478elif [ "$arch" = "riscv32" ] || [ "$arch" = "riscv64" ]; then
479cat <<EOF >> lib/config.h
480
481#define CONFIG_UART_EARLY_BASE 0x10000000
482
483EOF
484fi
485echo "#endif" >> lib/config.h
486