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