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