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