1#!/bin/bash
2# SPDX-License-Identifier: BSD-3-Clause
3# Copyright(c) 2018 Intel Corporation. All rights reserved.
4
5# stop on most errors
6set -e
7
8SUPPORTED_PLATFORMS=(byt cht bdw hsw apl skl kbl cnl sue icl jsl \
9                    imx8 imx8x imx8m imx8ulp tgl tgl-h rn)
10BUILD_ROM=no
11BUILD_DEBUG=no
12BUILD_FORCE_UP=no
13BUILD_JOBS=$(nproc --all)
14BUILD_VERBOSE=
15PLATFORMS=()
16
17SOF_TOP=$(cd "$(dirname "$0")/.." && pwd)
18
19# As CMake forks one compiler process for each source file, the XTensa
20# compiler spends much more time idle waiting for the license server
21# over the network than actually using CPU or disk. A factor 3 has been
22# found optimal for 16 nproc 25ms away from the server; your mileage may
23# vary.
24#
25# The entire, purely local gcc build is so fast (~ 1s) that observing
26# any difference between -j nproc and -j nproc*N is practically
27# impossible so let's not waste RAM when building with gcc.
28
29if [ -n "$XTENSA_TOOLS_ROOT" ]; then
30    BUILD_JOBS=$((BUILD_JOBS * 3))
31fi
32
33
34die()
35{
36	>&2 printf '%s ERROR: ' "$0"
37	# We want die() to be usable exactly like printf
38	# shellcheck disable=SC2059
39	>&2 printf "$@"
40	exit 1
41}
42
43print_usage()
44{
45    cat <<EOF
46Re-configures and re-builds SOF using the corresponding compiler and the
47<platform>_defconfig file. Implements and saves the manual configuration
48described in
49https://thesofproject.github.io/latest/developer_guides/firmware/cmake.html
50
51usage: $0 [options] platform(s)
52
53       -r Build rom if available (gcc only)
54       -a Build all platforms
55       -u Force UP ARCH
56       -d Enable debug build
57       -c Interactive menuconfig
58       -o arg, copies src/arch/xtensa/configs/override/<arg>.config
59	  to the build directory after invoking CMake and before Make.
60       -k Configure rimage to use a non-default \${RIMAGE_PRIVATE_KEY}
61           DEPRECATED: use the more flexible \${PRIVATE_KEY_OPTION} below.
62       -v Verbose Makefile log
63       -j n Set number of make build jobs. Jobs=#cores when no flag. \
64Infinte when not specified.
65       -m path to MEU tool. CMake disables rimage signing which produces a
66          .uns[igned] file signed by MEU. For a non-default key use the
67          PRIVATE_KEY_OPTION, see below.
68
69To use a non-default key you must define the right CMake parameter in the
70following environment variable:
71
72     PRIVATE_KEY_OPTION='-DMEU_PRIVATE_KEY=path/to/key'  $0  -m /path/to/meu ...
73or:
74     PRIVATE_KEY_OPTION='-DRIMAGE_PRIVATE_KEY=path/to/key'  $0 ...
75
76This script supports XtensaTools but only when installed in a specific
77directory structure, example:
78
79myXtensa/
80└── install/
81    ├── builds/
82    │   ├── RD-2012.5-linux/
83    │   │   └── Intel_HiFiEP/
84    │   └── RG-2017.8-linux/
85    │       ├── LX4_langwell_audio_17_8/
86    │       └── X4H3I16w2D48w3a_2017_8/
87    └── tools/
88        ├── RD-2012.5-linux/
89        │   └── XtensaTools/
90        └── RG-2017.8-linux/
91            └── XtensaTools/
92
93$ XTENSA_TOOLS_ROOT=/path/to/myXtensa $0 ...
94
95Supported platforms ${SUPPORTED_PLATFORMS[*]}
96
97EOF
98}
99
100# parse the args
101while getopts "rudj:ckvao:m:" OPTION; do
102        case "$OPTION" in
103		r) BUILD_ROM=yes ;;
104		u) BUILD_FORCE_UP=yes ;;
105		d) BUILD_DEBUG=yes ;;
106		j) BUILD_JOBS=$OPTARG ;;
107		c) MAKE_MENUCONFIG=yes ;;
108		k) USE_PRIVATE_KEY=yes ;;
109		o) OVERRIDE_CONFIG=$OPTARG ;;
110		v) BUILD_VERBOSE='VERBOSE=1' ;;
111		a) PLATFORMS=("${SUPPORTED_PLATFORMS[@]}") ;;
112		m) MEU_TOOL_PATH=$OPTARG ;;
113		*) print_usage; exit 1 ;;
114        esac
115done
116shift $((OPTIND-1))
117
118#default signing tool
119SIGNING_TOOL=RIMAGE
120
121if [ -n "${OVERRIDE_CONFIG}" ]
122then
123	OVERRIDE_CONFIG="${SOF_TOP}/src/arch/xtensa/configs/override/$OVERRIDE_CONFIG.config"
124	[ -f "${OVERRIDE_CONFIG}" ] || die 'Invalid override config file %s\n' "${OVERRIDE_CONFIG}"
125fi
126
127if [ -n "${MEU_TOOL_PATH}" ]
128then
129	[ -d "${MEU_TOOL_PATH}" ] || die 'Invalid MEU TOOL PATH %s\n' "${MEU_TOOL_PATH}"
130	MEU_PATH_OPTION=-DMEU_PATH="${MEU_TOOL_PATH}"
131	SIGNING_TOOL=MEU
132fi
133
134# parse platform args
135for arg in "$@"; do
136	platform=none
137	for i in "${SUPPORTED_PLATFORMS[@]}"; do
138		if [ x"$i" = x"$arg" ]; then
139			PLATFORMS=("${PLATFORMS[@]}" "$i")
140			platform=$i
141			shift || true
142			break
143		fi
144	done
145	if [ "$platform" == "none" ]; then
146		echo "Error: Unknown platform specified: $arg"
147		echo "Supported platforms are: ${SUPPORTED_PLATFORMS[*]}"
148		exit 1
149	fi
150done
151
152# check target platform(s) have been passed in
153if [ ${#PLATFORMS[@]} -eq 0 ];
154then
155	echo "Error: No platforms specified. Supported are: " \
156		"${SUPPORTED_PLATFORMS[*]}"
157	print_usage
158	exit 1
159fi
160
161if [ "x$USE_PRIVATE_KEY" == "xyes" ]
162then
163	>&2 printf \
164	    'WARNING: -k and RIMAGE_PRIVATE_KEY are deprecated, see usage.\n'
165	if [ -z ${RIMAGE_PRIVATE_KEY+x} ]
166	then
167		echo "Error: No variable specified for RIMAGE_PRIVATE_KEY"
168		exit 1
169	fi
170	PRIVATE_KEY_OPTION="-DRIMAGE_PRIVATE_KEY=${RIMAGE_PRIVATE_KEY}"
171fi
172
173OLDPATH=$PATH
174CURDIR="$(pwd)"
175
176# build platforms
177for platform in "${PLATFORMS[@]}"
178do
179	HAVE_ROM='no'
180	DEFCONFIG_PATCH=''
181
182	case $platform in
183		byt)
184			PLATFORM="baytrail"
185			XTENSA_CORE="Intel_HiFiEP"
186			HOST="xtensa-byt-elf"
187			XTENSA_TOOLS_VERSION="RD-2012.5-linux"
188			;;
189		cht)
190			PLATFORM="cherrytrail"
191			XTENSA_CORE="CHT_audio_hifiep"
192			HOST="xtensa-byt-elf"
193			XTENSA_TOOLS_VERSION="RD-2012.5-linux"
194			;;
195		bdw)
196			PLATFORM="broadwell"
197			XTENSA_CORE="LX4_langwell_audio_17_8"
198			HOST="xtensa-hsw-elf"
199			XTENSA_TOOLS_VERSION="RG-2017.8-linux"
200			;;
201		hsw)
202			PLATFORM="haswell"
203			XTENSA_CORE="LX4_langwell_audio_17_8"
204			HOST="xtensa-hsw-elf"
205			XTENSA_TOOLS_VERSION="RG-2017.8-linux"
206			;;
207		apl)
208			PLATFORM="apollolake"
209			XTENSA_CORE="X4H3I16w2D48w3a_2017_8"
210
211			# test APL compiler aliases
212			if command -v xtensa-bxt-elf-gcc; then
213				HOST="xtensa-bxt-elf"
214			else
215				HOST="xtensa-apl-elf"
216			fi
217
218			XTENSA_TOOLS_VERSION="RG-2017.8-linux"
219			HAVE_ROM='yes'
220			;;
221		skl)
222			PLATFORM="skylake"
223			XTENSA_CORE="X4H3I16w2D48w3a_2017_8"
224
225			# test APL compiler aliases
226			if command -v xtensa-bxt-elf-gcc; then
227				HOST="xtensa-bxt-elf"
228			else
229				HOST="xtensa-apl-elf"
230			fi
231
232			XTENSA_TOOLS_VERSION="RG-2017.8-linux"
233			HAVE_ROM='yes'
234			;;
235		kbl)
236			PLATFORM="kabylake"
237			XTENSA_CORE="X4H3I16w2D48w3a_2017_8"
238
239			# test APL compiler aliases
240			if command -v xtensa-bxt-elf-gcc; then
241				HOST="xtensa-bxt-elf"
242			else
243				HOST="xtensa-apl-elf"
244			fi
245
246			XTENSA_TOOLS_VERSION="RG-2017.8-linux"
247			HAVE_ROM='yes'
248			;;
249		cnl)
250			PLATFORM="cannonlake"
251			XTENSA_CORE="X6H3CNL_2017_8"
252			HOST="xtensa-cnl-elf"
253			XTENSA_TOOLS_VERSION="RG-2017.8-linux"
254			HAVE_ROM='yes'
255			;;
256		sue)
257			PLATFORM="suecreek"
258			XTENSA_CORE="X6H3CNL_2017_8"
259			HOST="xtensa-cnl-elf"
260			XTENSA_TOOLS_VERSION="RG-2017.8-linux"
261			HAVE_ROM='yes'
262			;;
263		icl)
264			PLATFORM="icelake"
265			XTENSA_CORE="X6H3CNL_2017_8"
266			HOST="xtensa-cnl-elf"
267			XTENSA_TOOLS_VERSION="RG-2017.8-linux"
268			HAVE_ROM='yes'
269			;;
270		tgl)
271			PLATFORM="tgplp"
272			XTENSA_CORE="cavs2x_LX6HiFi3_2017_8"
273			HOST="xtensa-cnl-elf"
274			XTENSA_TOOLS_VERSION="RG-2017.8-linux"
275			HAVE_ROM='yes'
276			# default key for TGL
277			if [ -z "$PRIVATE_KEY_OPTION" ]
278			then
279	PRIVATE_KEY_OPTION="-D${SIGNING_TOOL}_PRIVATE_KEY=$SOF_TOP/keys/otc_private_key_3k.pem"
280			fi
281			;;
282		tgl-h)
283			PLATFORM="tgph"
284			XTENSA_CORE="cavs2x_LX6HiFi3_2017_8"
285			HOST="xtensa-cnl-elf"
286			XTENSA_TOOLS_VERSION="RG-2017.8-linux"
287			HAVE_ROM='yes'
288			# default key for TGL
289			if [ -z "$PRIVATE_KEY_OPTION" ]
290			then
291	PRIVATE_KEY_OPTION="-D${SIGNING_TOOL}_PRIVATE_KEY=$SOF_TOP/keys/otc_private_key_3k.pem"
292			fi
293			;;
294		jsl)
295			PLATFORM="jasperlake"
296			XTENSA_CORE="X6H3CNL_2017_8"
297			HOST="xtensa-cnl-elf"
298			XTENSA_TOOLS_VERSION="RG-2017.8-linux"
299			HAVE_ROM='yes'
300			;;
301		imx8)
302			PLATFORM="imx8"
303			XTENSA_CORE="hifi4_nxp_v3_3_1_2_2017"
304			HOST="xtensa-imx-elf"
305			XTENSA_TOOLS_VERSION="RG-2017.8-linux"
306			;;
307		imx8x)
308			PLATFORM="imx8x"
309			XTENSA_CORE="hifi4_nxp_v3_3_1_2_2017"
310			HOST="xtensa-imx-elf"
311			XTENSA_TOOLS_VERSION="RG-2017.8-linux"
312			;;
313		imx8m)
314			PLATFORM="imx8m"
315			XTENSA_CORE="hifi4_mscale_v0_0_2_2017"
316			HOST="xtensa-imx8m-elf"
317			XTENSA_TOOLS_VERSION="RG-2017.8-linux"
318			;;
319		imx8ulp)
320			PLATFORM="imx8ulp"
321			XTENSA_CORE="hifi4_nxp2_ulp_prod"
322			HOST="xtensa-imx8ulp-elf"
323			XTENSA_TOOLS_VERSION="RG-2017.8-linux"
324			;;
325		rn)
326			PLATFORM="renoir"
327			ARCH="xtensa"
328			XTENSA_CORE="ACP_3_1_001_PROD"
329			HOST="xtensa-rn-elf"
330			XTENSA_TOOLS_VERSION="RF-2016.4-linux"
331			;;
332
333	esac
334
335	if [ -n "$XTENSA_TOOLS_ROOT" ]
336	then
337		XTENSA_TOOLS_DIR="$XTENSA_TOOLS_ROOT/install/tools/$XTENSA_TOOLS_VERSION"
338		XTENSA_BUILDS_DIR="$XTENSA_TOOLS_ROOT/install/builds/$XTENSA_TOOLS_VERSION"
339
340		# make sure the required version of xtensa tools is installed
341		if [ -d "$XTENSA_TOOLS_DIR" ]
342			then
343				XCC="xt-xcc"
344			else
345				XCC="none"
346				>&2 printf 'WARNING: %s
347\t is not a directory, reverting to gcc\n' "$XTENSA_TOOLS_DIR"
348		fi
349	fi
350
351	# CMake uses ROOT_DIR for includes and libraries a bit like
352	# --sysroot would.
353	ROOT="$SOF_TOP/../xtensa-root/$HOST"
354
355	if [ "$XCC" == "xt-xcc" ]
356	then
357		TOOLCHAIN=xt
358		ROOT="$XTENSA_BUILDS_DIR/$XTENSA_CORE/xtensa-elf"
359		export XTENSA_SYSTEM=$XTENSA_BUILDS_DIR/$XTENSA_CORE/config
360		printf 'XTENSA_SYSTEM=%s\n' "${XTENSA_SYSTEM}"
361		PATH=$XTENSA_TOOLS_DIR/XtensaTools/bin:$OLDPATH
362		COMPILER="xcc"
363	else
364		TOOLCHAIN=$HOST
365		PATH=$SOF_TOP/../$HOST/bin:$OLDPATH
366		COMPILER="gcc"
367
368		case "$platform" in
369			byt|cht|cnl|sue) DEFCONFIG_PATCH="_gcc";;
370			*)	     DEFCONFIG_PATCH="";;
371		esac
372	fi
373
374	BUILD_DIR=build_${platform}_${COMPILER}
375	printf "Build in %s\n" "$BUILD_DIR"
376
377	# only delete binary related to this build
378	rm -fr "$BUILD_DIR"
379	mkdir "$BUILD_DIR"
380	cd "$BUILD_DIR"
381
382	printf 'PATH=%s\n' "$PATH"
383	( set -x # log the main commands and their parameters
384	cmake -DTOOLCHAIN="$TOOLCHAIN" \
385		-DROOT_DIR="$ROOT" \
386		-DMEU_OPENSSL="${MEU_OPENSSL}" \
387		"${MEU_PATH_OPTION}" \
388		"${PRIVATE_KEY_OPTION}" \
389		-DINIT_CONFIG=${PLATFORM}${DEFCONFIG_PATCH}_defconfig \
390		"$SOF_TOP"
391	)
392
393	if [ -n "$OVERRIDE_CONFIG" ]
394	then
395		cp "$OVERRIDE_CONFIG" override.config
396	fi
397
398	if [[ "x$MAKE_MENUCONFIG" == "xyes" ]]
399	then
400		cmake --build .  --  menuconfig
401	fi
402
403	if [[ "x$BUILD_DEBUG" == "xyes" ]]
404	then
405		echo "CONFIG_DEBUG=y" >> override.config
406	fi
407
408	if [[ "x$BUILD_ROM" == "xyes" && "x$HAVE_ROM" == "xyes" ]]
409	then
410		echo "CONFIG_BUILD_VM_ROM=y" >> override.config
411	fi
412
413	# override default ARCH if BUILD_FORCE_UP is set
414	if [ "x$BUILD_FORCE_UP" == "xyes" ]
415	then
416		echo "Force building UP(xtensa)..."
417		echo "CONFIG_MULTICORE=n" >> override.config
418	fi
419
420	if [ -e override.config ]
421	then
422		cmake --build .  --  overrideconfig
423	fi
424
425	cmake --build .  --  bin -j "${BUILD_JOBS}" ${BUILD_VERBOSE}
426
427	cd "$CURDIR"
428done # for platform in ...
429
430# list all the images
431ls -l build_*/*.ri build_*/src/arch/xtensa/rom*.bin || true
432ls -l build_*/sof
433