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