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