xref: /kvm-unit-tests/configure (revision 6afb94812d924a754e2d44f6c5de9e1859b2df28)
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 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" ]; then
212    echo "--[enable|disable]-efi is not supported for $arch"
213    usage
214fi
215
216if [ -z "$page_size" ]; then
217    [ "$arch" = "arm64" ] && page_size="65536"
218    [ "$arch" = "arm" ] && page_size="4096"
219else
220    if [ "$arch" != "arm64" ]; then
221        echo "--page-size is not supported for $arch"
222        usage
223    fi
224
225    if [ "${page_size: -1}" = "K" ] || [ "${page_size: -1}" = "k" ]; then
226        page_size=$(( ${page_size%?} * 1024 ))
227    fi
228    if [ "$page_size" != "4096" ] && [ "$page_size" != "16384" ] &&
229           [ "$page_size" != "65536" ]; then
230        echo "arm64 doesn't support page size of $page_size"
231        usage
232    fi
233fi
234
235[ -z "$processor" ] && processor="$arch"
236
237if [ "$processor" = "arm64" ]; then
238    processor="cortex-a57"
239elif [ "$processor" = "arm" ]; then
240    processor="cortex-a15"
241fi
242
243if [ "$arch" = "i386" ] || [ "$arch" = "x86_64" ]; then
244    testdir=x86
245elif [ "$arch" = "arm" ] || [ "$arch" = "arm64" ]; then
246    testdir=arm
247    if [ "$target" = "qemu" ]; then
248        arm_uart_early_addr=0x09000000
249    elif [ "$target" = "kvmtool" ]; then
250        arm_uart_early_addr=0x1000000
251        errata_force=1
252    else
253        echo "--target must be one of 'qemu' or 'kvmtool'!"
254        usage
255    fi
256
257    if [ "$earlycon" ]; then
258        IFS=, read -r name type_addr addr <<<"$earlycon"
259        if [ "$name" != "uart" ] && [ "$name" != "uart8250" ] &&
260                [ "$name" != "pl011" ]; then
261            echo "unknown earlycon name: $name"
262            usage
263        fi
264
265        if [ "$name" = "pl011" ]; then
266            if [ -z "$addr" ]; then
267                addr=$type_addr
268            else
269                if [ "$type_addr" != "mmio32" ]; then
270                    echo "unknown $name earlycon type: $type_addr"
271                    usage
272                fi
273            fi
274        else
275            if [ "$type_addr" != "mmio" ]; then
276                echo "unknown $name earlycon type: $type_addr"
277                usage
278            fi
279        fi
280
281        if [ -z "$addr" ]; then
282            echo "missing $name earlycon address"
283            usage
284        fi
285        if [[ $addr =~ ^0(x|X)[0-9a-fA-F]+$ ]] ||
286                [[ $addr =~ ^[0-9]+$ ]]; then
287            arm_uart_early_addr=$addr
288        else
289            echo "invalid $name earlycon address: $addr"
290            usage
291        fi
292    fi
293elif [ "$arch" = "ppc64" ]; then
294    testdir=powerpc
295    firmware="$testdir/boot_rom.bin"
296    if [ "$endian" != "little" ] && [ "$endian" != "big" ]; then
297        echo "You must provide endianness (big or little)!"
298        usage
299    fi
300else
301    testdir=$arch
302fi
303if [ ! -d "$srcdir/$testdir" ]; then
304    echo "$testdir does not exist!"
305    exit 1
306fi
307if [ -f "$srcdir/$testdir/run" ]; then
308    ln -fs "$srcdir/$testdir/run" $testdir-run
309fi
310
311testsubdir=$testdir
312if [ "$efi" = "y" ]; then
313    testsubdir=$testdir/efi
314fi
315
316# check if uint32_t needs a long format modifier
317cat << EOF > lib-test.c
318__UINT32_TYPE__
319EOF
320u32_long=$("$cross_prefix$cc" -E lib-test.c | grep -v '^#' | grep -q long && echo yes)
321rm -f lib-test.c
322
323# check if slash can be used for division
324if [ "$arch" = "i386" ] || [ "$arch" = "x86_64" ]; then
325  cat << EOF > lib-test.S
326foo:
327    movl (8 / 2), %eax
328EOF
329  wa_divide=$("$cross_prefix$cc" -c lib-test.S >/dev/null 2>&1 || echo yes)
330  rm -f lib-test.{o,S}
331fi
332
333# warn if enhanced getopt is unavailable
334getopt -T > /dev/null
335if [ $? -ne 4 ]; then
336    echo "Without enhanced getopt you won't be able to use run_tests.sh."
337    echo "Add it to your PATH?"
338fi
339
340# Are we in a separate build tree? If so, link the Makefile
341# and shared stuff so that 'make' and run_tests.sh work.
342if test ! -e Makefile; then
343    echo "linking Makefile..."
344    ln -s "$srcdir/Makefile" .
345
346    echo "linking tests..."
347    mkdir -p $testsubdir
348    ln -sf "$srcdir/$testdir/run" $testdir/
349    if test "$testdir" != "$testsubdir"; then
350        ln -sf "$srcdir/$testsubdir/run" $testsubdir/
351    fi
352    ln -sf "$srcdir/$testdir/unittests.cfg" $testdir/
353    ln -sf "$srcdir/run_tests.sh"
354
355    if [ -d "$srcdir/$testdir/snippets" ]; then
356        mkdir -p "$testdir/snippets/c"
357    fi
358
359    echo "linking scripts..."
360    ln -sf "$srcdir/scripts"
361fi
362
363# link lib/asm for the architecture
364rm -f lib/asm
365asm="asm-generic"
366if [ -d "$srcdir/lib/$arch/asm" ]; then
367	asm="$srcdir/lib/$arch/asm"
368elif [ -d "$srcdir/lib/$testdir/asm" ]; then
369	asm="$srcdir/lib/$testdir/asm"
370fi
371mkdir -p lib
372ln -sf "$asm" lib/asm
373
374
375# create the config
376cat <<EOF > config.mak
377SRCDIR=$srcdir
378PREFIX=$prefix
379HOST=$host
380ARCH=$arch
381ARCH_NAME=$arch_name
382PROCESSOR=$processor
383CC=$cross_prefix$cc
384CFLAGS=$cflags
385LD=$cross_prefix$ld
386OBJCOPY=$cross_prefix$objcopy
387OBJDUMP=$cross_prefix$objdump
388READELF=$cross_prefix$readelf
389AR=$cross_prefix$ar
390ADDR2LINE=$cross_prefix$addr2line
391TEST_DIR=$testdir
392TEST_SUBDIR=$testsubdir
393FIRMWARE=$firmware
394ENDIAN=$endian
395PRETTY_PRINT_STACKS=$pretty_print_stacks
396ENVIRON_DEFAULT=$environ_default
397ERRATATXT=$erratatxt
398U32_LONG_FMT=$u32_long
399WA_DIVIDE=$wa_divide
400GENPROTIMG=${GENPROTIMG-genprotimg}
401HOST_KEY_DOCUMENT=$host_key_document
402CONFIG_DUMP=$enable_dump
403CONFIG_EFI=$efi
404CONFIG_WERROR=$werror
405GEN_SE_HEADER=$gen_se_header
406EOF
407if [ "$arch" = "arm" ] || [ "$arch" = "arm64" ]; then
408    echo "TARGET=$target" >> config.mak
409fi
410
411cat <<EOF > lib/config.h
412#ifndef _CONFIG_H_
413#define _CONFIG_H_
414/*
415 * Generated file. DO NOT MODIFY.
416 *
417 */
418
419EOF
420if [ "$arch" = "arm" ] || [ "$arch" = "arm64" ]; then
421cat <<EOF >> lib/config.h
422
423#define CONFIG_UART_EARLY_BASE ${arm_uart_early_addr}
424#define CONFIG_ERRATA_FORCE ${errata_force}
425#define CONFIG_PAGE_SIZE _AC(${page_size}, UL)
426
427EOF
428fi
429echo "#endif" >> lib/config.h
430