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