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