blob: 825e76efed5ec50ad63f7f4c9f2e00b12aa7a42b [file] [log] [blame]
Leonardo Sandoval9dfdd1b2020-08-06 17:08:11 -05001#!/usr/bin/env bash
Fathi Boudra422bf772019-12-02 11:10:16 +02002#
David Vincze82db6932024-02-21 12:05:50 +01003# Copyright (c) 2019-2024 Arm Limited. All rights reserved.
Fathi Boudra422bf772019-12-02 11:10:16 +02004#
5# SPDX-License-Identifier: BSD-3-Clause
6#
7
8# Builds a package with Trusted Firwmare and other payload binaries. The package
9# is meant to be executed by run_package.sh
10
11set -e
12
13ci_root="$(readlink -f "$(dirname "$0")/..")"
14source "$ci_root/utils.sh"
15
16if [ ! -d "$workspace" ]; then
17 die "Directory $workspace doesn't exist"
18fi
19
20# Directory to where the source code e.g. for Trusted Firmware is checked out.
Zelalem219df412020-05-17 19:21:20 -050021export tf_root="${tf_root:-$workspace/trusted_firmware}"
22export tftf_root="${tftf_root:-$workspace/trusted_firmware_tf}"
Zelalem219df412020-05-17 19:21:20 -050023cc_root="${cc_root:-$ccpathspec}"
Olivier Deprez0a9a3482019-12-16 14:10:31 +010024spm_root="${spm_root:-$workspace/spm}"
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +000025rmm_root="${rmm_root:-$workspace/tf-rmm}"
Zelalem219df412020-05-17 19:21:20 -050026
Fathi Boudra422bf772019-12-02 11:10:16 +020027# Refspecs
28tf_refspec="$TF_REFSPEC"
29tftf_refspec="$TFTF_REFSPEC"
Olivier Deprez0a9a3482019-12-16 14:10:31 +010030spm_refspec="$SPM_REFSPEC"
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +000031rmm_refspec="$RMM_REFSPEC"
Fathi Boudra422bf772019-12-02 11:10:16 +020032
33test_config="${TEST_CONFIG:?}"
34test_group="${TEST_GROUP:?}"
35build_configs="${BUILD_CONFIG:?}"
36run_config="${RUN_CONFIG:?}"
Zelalem219df412020-05-17 19:21:20 -050037cc_config="${CC_ENABLE:-}"
Fathi Boudra422bf772019-12-02 11:10:16 +020038
Boyan Karatotev97de8d82025-03-06 15:22:21 +000039export archive="$artefacts"
Fathi Boudra422bf772019-12-02 11:10:16 +020040build_log="$artefacts/build.log"
41fiptool="$tf_root/tools/fiptool/fiptool"
42cert_create="$tf_root/tools/cert_create/cert_create"
43
44# Validate $bin_mode
45case "$bin_mode" in
46 "" | debug | release)
47 ;;
48 *)
49 die "Invalid value for bin_mode: $bin_mode"
50 ;;
51esac
52
53# File to save any environem
54hook_env_file="$(mktempfile)"
55
56# Check if a config is valid
57config_valid() {
58 local config="${1?}"
59 if [ -z "$config" ] || [ "$(basename "$config")" = "nil" ]; then
60 return 1
61 fi
62
63 return 0
64}
65
66# Echo from a build wrapper. Print to descriptor 3 that's opened by the build
67# function.
68echo_w() {
69 echo $echo_flags "$@" >&3
70}
71
72# Print a separator to the log file. Intended to be used at the tail end of a pipe
73log_separator() {
74 {
75 echo
76 echo "----------"
77 } >> "$build_log"
78
79 tee -a "$build_log"
80
81 {
82 echo "----------"
83 echo
84 } >> "$build_log"
85}
86
87# Call function $1 if it's defined
88call_func() {
89 if type "${1:?}" &>/dev/null; then
90 echo
91 echo "> ${2:?}:$1()"
92 eval "$1"
93 echo "< $2:$1()"
94 fi
95}
96
Paul Sokolovskybe6510c2024-08-15 21:54:00 +030097# Retry a command a number of times if it fails. Intended for I/O commands
98# in a CI environment which may be flaky.
99function retry() {
100 for i in $(seq 1 3); do
101 if "$@"; then
102 return 0
103 fi
104 sleep $(( i * 5 ))
105 done
106 return 1
107}
108
Fathi Boudra422bf772019-12-02 11:10:16 +0200109# Call hook $1 in all chosen fragments if it's defined. Hooks are invoked from
110# within a subshell, so any variables set within a hook are lost. Should a
111# variable needs to be set from within a hook, the function 'set_hook_var'
112# should be used
113call_hook() {
114 local func="$1"
115 local config_fragment
116
117 [ -z "$func" ] && return 0
118
Paul Sokolovskye9962cd2021-12-17 18:39:40 +0300119 echo "=== Calling hooks: $1 ==="
120
Fathi Boudra422bf772019-12-02 11:10:16 +0200121 : >"$hook_env_file"
122
Nicola Mazzucato7fc5abd2024-02-23 21:32:48 +0000123 if [ "$run_config_candidates" ]; then
124 for config_fragment in $run_config_candidates; do
Fathi Boudra422bf772019-12-02 11:10:16 +0200125 (
126 source "$ci_root/run_config/$config_fragment"
127 call_func "$func" "$config_fragment"
128 )
129 done
130 fi
131
132 # Also source test config file
133 (
134 unset "$func"
135 source "$test_config_file"
136 call_func "$func" "$(basename $test_config_file)"
137 )
138
139 # Have any variables set take effect
140 source "$hook_env_file"
Paul Sokolovskye9962cd2021-12-17 18:39:40 +0300141
142 echo "=== End calling hooks: $1 ==="
Fathi Boudra422bf772019-12-02 11:10:16 +0200143}
144
145# Set a variable from within a hook
146set_hook_var() {
147 echo "export $1=\"${2?}\"" >> "$hook_env_file"
148}
149
150# Append to an array from within a hook
151append_hook_var() {
152 echo "export $1+=\"${2?}\"" >> "$hook_env_file"
153}
154
155# Have the main build script source a file
156source_later() {
157 echo "source ${1?}" >> "$hook_env_file"
158}
159
160# Setup TF build wrapper function by pointing to a script containing a function
161# that will be called with the TF build commands.
162setup_tf_build_wrapper() {
163 source_later "$ci_root/script/${wrapper?}_wrapper.sh"
164 set_hook_var "tf_build_wrapper" "${wrapper}_wrapper"
165 echo "Setup $wrapper build wrapper."
166}
167
168# Collect .bin files for archiving
169collect_build_artefacts() {
170 if [ ! -d "${from:?}" ]; then
171 return
172 fi
173
Manish V Badarkhe84c3a482025-04-16 08:15:38 +0100174 if ! find "$from" \( -name "*.bin" -o -name '*.elf' -o -name '*.dtb' -o -name '*.axf' -o -name '*.stm32' -o -name '*.img' \) -exec cp -t "${to:?}" '{}' +; then
Fathi Boudra422bf772019-12-02 11:10:16 +0200175 echo "You probably are running local CI on local repositories."
176 echo "Did you set 'dont_clean' but forgot to run 'distclean'?"
177 die
178 fi
179}
180
Manish Pandey1e7be852020-11-09 16:04:48 +0000181# Collect SPM/hafnium artefacts with "secure_" appended to the files
182# generated for SPM(secure hafnium).
183collect_spm_artefacts() {
Madhukar Pappireddyc683cf62021-11-01 14:38:32 -0500184 if [ -d "${non_secure_from:?}" ]; then
185 find "$non_secure_from" \( -name "*.bin" -o -name '*.elf' \) -exec cp -t "${to:?}" '{}' +
Manish Pandey1e7be852020-11-09 16:04:48 +0000186 fi
187
Madhukar Pappireddyc683cf62021-11-01 14:38:32 -0500188 if [ -d "${secure_from:?}" ]; then
189 for f in $(find "$secure_from" \( -name "*.bin" -o -name '*.elf' \)); do cp -- "$f" "${to:?}"/secure_$(basename $f); done
190 fi
Manish Pandey1e7be852020-11-09 16:04:48 +0000191}
192
Javier Almansa Sobrino412d3612020-05-22 17:53:12 +0100193# Map the UART ID used for expect with the UART descriptor and port
194# used by the FPGA automation tools.
195map_uart() {
196 local port="${port:?}"
197 local descriptor="${descriptor:?}"
198 local baudrate="${baudrate:?}"
199 local run_root="${archive:?}/run"
200
201 local uart_dir="$run_root/uart${uart:?}"
202 mkdir -p "$uart_dir"
203
204 echo "$port" > "$uart_dir/port"
205 echo "$descriptor" > "$uart_dir/descriptor"
206 echo "$baudrate" > "$uart_dir/baudrate"
207
208 echo "UART${uart} mapped to port ${port} with descriptor ${descriptor} and baudrate ${baudrate}"
209}
210
Fathi Boudra422bf772019-12-02 11:10:16 +0200211# Arrange environment varibles to be set when expect scripts are launched
212set_expect_variable() {
213 local var="${1:?}"
214 local val="${2?}"
215
216 local run_root="${archive:?}/run"
217 local uart_dir="$run_root/uart${uart:?}"
218 mkdir -p "$uart_dir"
219
220 env_file="$uart_dir/env" quote="1" emit_env "$var" "$val"
221 echo "UART$uart: env has $@"
222}
223
224# Place the binary package a pointer to expect script, and its parameters
225track_expect() {
226 local file="${file:?}"
227 local timeout="${timeout-600}"
228 local run_root="${archive:?}/run"
229
230 local uart_dir="$run_root/uart${uart:?}"
231 mkdir -p "$uart_dir"
232
233 echo "$file" > "$uart_dir/expect"
234 echo "$timeout" > "$uart_dir/timeout"
Paul Sokolovskybfa8bab2023-01-25 19:34:51 +0700235 if [ -n "$lava_timeout" ]; then
236 set_run_env "lava_timeout" "$lava_timeout"
237 fi
Fathi Boudra422bf772019-12-02 11:10:16 +0200238
Paul Sokolovskybfa8bab2023-01-25 19:34:51 +0700239 echo "UART$uart to be tracked with $file; timeout ${timeout}s; lava_timeout ${lava_timeout:-N/A}s"
Fathi Boudra422bf772019-12-02 11:10:16 +0200240
Chris Kayfab6edc2022-11-17 19:18:32 +0000241 if [ ! -z "${port}" ]; then
242 echo "${port}" > "$uart_dir/port"
243 fi
244
Fathi Boudra422bf772019-12-02 11:10:16 +0200245 # The run script assumes UART0 to be primary. If we're asked to set any
246 # other UART to be primary, set a run environment variable to signal
247 # that to the run script
248 if upon "$set_primary"; then
249 echo "Primary UART set to UART$uart."
250 set_run_env "primary_uart" "$uart"
251 fi
Madhukar Pappireddy1e953722021-11-08 15:23:02 -0600252
253 # UART used by payload(such as tftf, Linux) may not be the same as the
254 # primary UART. Set a run environment variable to track the payload
255 # UART which is tracked to check if the test has finished sucessfully.
256 if upon "$set_payload_uart"; then
257 echo "Payload uses UART$uart."
258 set_run_env "payload_uart" "$uart"
259 fi
Fathi Boudra422bf772019-12-02 11:10:16 +0200260}
261
262# Extract a FIP in $1 using fiptool
263extract_fip() {
264 local fip="$1"
265
266 if is_url "$1"; then
267 url="$1" fetch_file
268 fip="$(basename "$1")"
269 fi
270
271 "$fiptool" unpack "$fip"
272 echo "Extracted FIP: $fip"
273}
274
275# Report build failure by printing a the tail end of build log. Archive the
276# build log for later inspection
277fail_build() {
278 local log_path
279
280 if upon "$jenkins_run"; then
281 log_path="$BUILD_URL/artifact/artefacts/build.log"
282 else
283 log_path="$build_log"
284 fi
285
286 echo
Leonardo Sandovalae97eda2020-11-12 10:07:03 -0600287 echo "Build failed! Full build log below:"
Fathi Boudra422bf772019-12-02 11:10:16 +0200288 echo "[...]"
289 echo
Leonardo Sandovalae97eda2020-11-12 10:07:03 -0600290 cat "$build_log"
Fathi Boudra422bf772019-12-02 11:10:16 +0200291 echo
292 echo "See $log_path for full output"
293 echo
294 cp -t "$archive" "$build_log"
295 exit 1;
296}
297
298# Build a FIP with supplied arguments
299build_fip() {
300 (
301 echo "Building FIP with arguments: $@"
302 local tf_env="$workspace/tf.env"
303
304 if [ -f "$tf_env" ]; then
305 set -a
306 source "$tf_env"
307 set +a
308 fi
309
Boyan Karatotev99e12312025-05-02 15:00:24 +0100310 make -C "$tf_root" $make_j_opts $(cat "$tf_config_file") DEBUG="$DEBUG" BUILD_BASE=$tf_build_root V=1 "$@" \
Fathi Boudra422bf772019-12-02 11:10:16 +0200311 ${fip_targets:-fip} &>>"$build_log" || fail_build
312 )
313}
314
Sandrine Bailleux189fdb32023-10-20 13:41:22 +0200315# Build any extra rule from TF-A makefile with supplied arguments.
316#
317# This is useful in case you need to build something else than firmware binaries
318# or the FIP.
319build_tf_extra() {
320 (
321 tf_extra_rules=${tf_extra_rules:?}
322 echo "Building extra TF rule(s): $tf_extra_rules"
323 echo " Arguments: $@"
324
325 local tf_env="$workspace/tf.env"
326
327 if [ -f "$tf_env" ]; then
328 set -a
329 source "$tf_env"
330 set +a
331 fi
332
Boyan Karatotev99e12312025-05-02 15:00:24 +0100333 make -C "$tf_root" $make_j_opts $(cat "$tf_config_file") DEBUG="$DEBUG" V=1 BUILD_BASE=$tf_build_root "$@" \
Sandrine Bailleux189fdb32023-10-20 13:41:22 +0200334 ${tf_extra_rules} &>>"$build_log" || fail_build
335 )
336}
337
Fathi Boudra422bf772019-12-02 11:10:16 +0200338fip_update() {
339 # Before the update process, check if the given image is supported by
340 # the fiptool. It's assumed that both fiptool and cert_create move in
Chris Kay197b1022023-08-16 21:31:41 +0100341 # tandem, and therefore, if one has support, the other has it too.
342 if ! ("$fiptool" update 2>&1 || true) | grep -qe "\s\+--${bin_name:?}"; then
Fathi Boudra422bf772019-12-02 11:10:16 +0200343 return 1
344 fi
345
346 if not_upon "$(get_tf_opt TRUSTED_BOARD_BOOT)"; then
347 echo "Updating FIP image: $bin_name"
348 # Update HW config. Without TBBR, it's only a matter of using
349 # the update sub-command of fiptool
350 "$fiptool" update "--$bin_name" "${src:-}" \
351 "$archive/fip.bin"
352 else
353 echo "Updating FIP image (TBBR): $bin_name"
354 # With TBBR, we need to unpack, re-create certificates, and then
355 # recreate the FIP.
356 local fip_dir="$(mktempdir)"
357 local bin common_args stem
358 local rot_key="$(get_tf_opt ROT_KEY)"
359
360 rot_key="${rot_key:?}"
361 if ! is_abs "$rot_key"; then
362 rot_key="$tf_root/$rot_key"
363 fi
364
365 # Arguments only for cert_create
366 local cert_args="-n"
367 cert_args+=" --tfw-nvctr ${nvctr:-31}"
368 cert_args+=" --ntfw-nvctr ${nvctr:-223}"
369 cert_args+=" --key-alg ${KEY_ALG:-rsa}"
370 cert_args+=" --rot-key $rot_key"
371
372 local dyn_config_opts=(
Zelalem1af7a7b2020-08-04 17:34:32 -0500373 "fw-config"
Fathi Boudra422bf772019-12-02 11:10:16 +0200374 "hw-config"
375 "tb-fw-config"
376 "nt-fw-config"
377 "soc-fw-config"
378 "tos-fw-config"
379 )
380
381 # Binaries without key certificates
382 declare -A has_no_key_cert
383 for bin in "tb-fw" "${dyn_config_opts[@]}"; do
384 has_no_key_cert["$bin"]="1"
385 done
386
387 # Binaries without certificates
388 declare -A has_no_cert
389 for bin in "hw-config" "${dyn_config_opts[@]}"; do
390 has_no_cert["$bin"]="1"
391 done
392
393 pushd "$fip_dir"
394
395 # Unpack FIP
396 "$fiptool" unpack "$archive/fip.bin" &>>"$build_log"
397
398 # Remove all existing certificates
399 rm -f *-cert.bin
400
401 # Copy the binary to be updated
402 cp -f "$src" "${bin_name}.bin"
403
404 # FIP unpack dumps binaries with the same name as the option
405 # used to pack it; likewise for certificates. Reverse-engineer
406 # the command line from the binary output.
407 common_args="--trusted-key-cert trusted_key.crt"
408 for bin in *.bin; do
409 stem="${bin%%.bin}"
410 common_args+=" --$stem $bin"
411 if not_upon "${has_no_cert[$stem]}"; then
412 common_args+=" --$stem-cert $stem.crt"
413 fi
414 if not_upon "${has_no_key_cert[$stem]}"; then
415 common_args+=" --$stem-key-cert $stem-key.crt"
416 fi
417 done
418
419 # Create certificates
420 "$cert_create" $cert_args $common_args &>>"$build_log"
421
422 # Recreate and archive FIP
423 "$fiptool" create $common_args "fip.bin" &>>"$build_log"
424 archive_file "fip.bin"
425
426 popd
427 fi
428}
429
430# Update hw-config in FIP, and remove the original DTB afterwards.
431update_fip_hw_config() {
432 # The DTB needs to be loaded by the model (and not updated in the FIP)
Madhukar Pappireddy9062ebf2021-03-02 17:07:06 -0600433 # in configs:
434 # 1. Where BL2 isn't present
435 # 2. Where we boot to Linux directly as BL33
Fathi Boudra422bf772019-12-02 11:10:16 +0200436 case "1" in
437 "$(get_tf_opt RESET_TO_BL31)" | \
Madhukar Pappireddy9062ebf2021-03-02 17:07:06 -0600438 "$(get_tf_opt ARM_LINUX_KERNEL_AS_BL33)" | \
Fathi Boudra422bf772019-12-02 11:10:16 +0200439 "$(get_tf_opt RESET_TO_SP_MIN)" | \
Maksims Svecovs7a0da522023-03-06 16:28:27 +0000440 "$(get_tf_opt RESET_TO_BL2)")
Fathi Boudra422bf772019-12-02 11:10:16 +0200441 return 0;;
442 esac
443
444 if bin_name="hw-config" src="$archive/dtb.bin" fip_update; then
445 # Remove the DTB so that model won't load it
446 rm -f "$archive/dtb.bin"
447 fi
448}
449
Fathi Boudra422bf772019-12-02 11:10:16 +0200450get_tftf_opt() {
451 (
452 name="${1:?}"
453 if config_valid "$tftf_config_file"; then
454 source "$tftf_config_file"
455 echo "${!name}"
456 fi
457 )
458}
459
460get_tf_opt() {
461 (
462 name="${1:?}"
463 if config_valid "$tf_config_file"; then
464 source "$tf_config_file"
465 echo "${!name}"
466 fi
467 )
468}
469
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +0000470get_rmm_opt() {
471 (
472 name="${1:?}"
Manish V Badarkhea3505272025-04-17 14:20:42 +0100473 default="$2"
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +0000474 if config_valid "$rmm_config_file"; then
475 source "$rmm_config_file"
Manish V Badarkhea3505272025-04-17 14:20:42 +0100476 # If !name is not defined, go with the default
477 # value (if defined)
478 if [ -z "${!name}" ]; then
479 echo "$default"
480 else
481 echo "${!name}"
482 fi
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +0000483 fi
484 )
485}
486
Fathi Boudra422bf772019-12-02 11:10:16 +0200487build_tf() {
488 (
489 env_file="$workspace/tf.env"
490 config_file="${tf_build_config:-$tf_config_file}"
491
492 # Build fiptool and all targets by default
Harrison Mutai32de9d02023-06-12 14:23:37 +0100493 build_targets="${tf_build_targets:-fiptool all}"
Fathi Boudra422bf772019-12-02 11:10:16 +0200494
495 source "$config_file"
496
497 # If it is a TBBR build, extract the MBED TLS library from archive
Manish V Badarkhe8f125012021-12-21 05:47:52 +0000498 if [ "$(get_tf_opt TRUSTED_BOARD_BOOT)" = 1 ] ||
Manish V Badarkhef43e3f52022-06-21 20:37:25 +0100499 [ "$(get_tf_opt MEASURED_BOOT)" = 1 ] ||
500 [ "$(get_tf_opt DRTM_SUPPORT)" = 1 ]; then
Fathi Boudra422bf772019-12-02 11:10:16 +0200501 mbedtls_dir="$workspace/mbedtls"
502 if [ ! -d "$mbedtls_dir" ]; then
503 mbedtls_ar="$workspace/mbedtls.tar.gz"
504
505 url="$mbedtls_archive" saveas="$mbedtls_ar" fetch_file
506 mkdir "$mbedtls_dir"
Leonardo Sandovalec9e16c2020-09-09 14:32:40 -0500507 extract_tarball $mbedtls_ar $mbedtls_dir --strip-components=1
Fathi Boudra422bf772019-12-02 11:10:16 +0200508 fi
509
510 emit_env "MBEDTLS_DIR" "$mbedtls_dir"
511 fi
Jimmy Brisson0d5e12c2023-05-16 14:51:51 -0500512 if [ "$(get_tf_opt PLATFORM_TEST)" = "tfm-testsuite" ] &&
513 not_upon "${TF_M_TESTS_PATH}"; then
514 emit_env "TF_M_TESTS_PATH" "$WORKSPACE/tf-m-tests"
515 fi
516 if [ "$(get_tf_opt PLATFORM_TEST)" = "tfm-testsuite" ] &&
517 not_upon "${TF_M_EXTRAS_PATH}"; then
518 emit_env "TF_M_EXTRAS_PATH" "$WORKSPACE/tf-m-extras"
519 fi
David Vincze82db6932024-02-21 12:05:50 +0100520 if [ "$(get_tf_opt DICE_PROTECTION_ENVIRONMENT)" = 1 ] &&
521 not_upon "${QCBOR_DIR}"; then
522 emit_env "QCBOR_DIR" "$WORKSPACE/qcbor"
523 fi
Fathi Boudra422bf772019-12-02 11:10:16 +0200524 if [ -f "$env_file" ]; then
525 set -a
526 source "$env_file"
527 set +a
528 fi
529
Harrison Mutai013f6332022-02-16 16:06:33 +0000530 if is_arm_jenkins_env || upon "$local_ci"; then
531 path_list=(
532 "$llvm_dir/bin"
533 )
534 extend_path "PATH" "path_list"
535 fi
536
Boyan Karatotev97de8d82025-03-06 15:22:21 +0000537 pushd "$tf_root"
Fathi Boudra422bf772019-12-02 11:10:16 +0200538
539 # Always distclean when running on Jenkins. Skip distclean when running
540 # locally and explicitly requested.
541 if upon "$jenkins_run" || not_upon "$dont_clean"; then
Boyan Karatotev97de8d82025-03-06 15:22:21 +0000542 make distclean BUILD_BASE=$tf_build_root &>>"$build_log" || fail_build
Fathi Boudra422bf772019-12-02 11:10:16 +0200543 fi
544
545 # Log build command line. It is left unfolded on purpose to assist
546 # copying to clipboard.
547 cat <<EOF | log_separator >/dev/null
548
549Build command line:
Boyan Karatotev97de8d82025-03-06 15:22:21 +0000550 $tf_build_wrapper make $make_j_opts $(cat "$config_file" | tr '\n' ' ') DEBUG=$DEBUG V=1 BUILD_BASE=$tf_build_root $build_targets
Fathi Boudra422bf772019-12-02 11:10:16 +0200551
Paul Sokolovsky7f71b072023-10-16 12:59:09 +0300552CC version:
553$(${CC-${CROSS_COMPILE}gcc} -v 2>&1)
Fathi Boudra422bf772019-12-02 11:10:16 +0200554EOF
555
Javier Almansa Sobrinoe8363182020-11-10 16:40:53 +0000556 if not_upon "$local_ci"; then
557 connect_debugger=0
558 fi
559
Fathi Boudra422bf772019-12-02 11:10:16 +0200560 # Build TF. Since build output is being directed to the build log, have
561 # descriptor 3 point to the current terminal for build wrappers to vent.
Harrison Mutai6361dbe2023-02-16 14:12:40 +0000562 $tf_build_wrapper poetry run make $make_j_opts $(cat "$config_file") \
Boyan Karatotev97de8d82025-03-06 15:22:21 +0000563 DEBUG="$DEBUG" V=1 BUILD_BASE="$tf_build_root" SPIN_ON_BL1_EXIT="$connect_debugger" \
Fathi Boudra422bf772019-12-02 11:10:16 +0200564 $build_targets 3>&1 &>>"$build_log" || fail_build
Harrison Mutai32de9d02023-06-12 14:23:37 +0100565
Harrison Mutai6dafb5f2023-07-18 15:21:48 +0100566 if [ "$build_targets" != "doc" ]; then
Chris Kay9ab2d952025-05-29 13:46:24 +0100567 (poetry run memory --root "$tf_build_root" symbols 2>&1 || true) | tee -a "${build_log}"
568
569 for map in $(find "${tf_build_root}" -name '*.map'); do
570 (poetry run memory --root "${tf_build_root}" summary "${map}" 2>&1 || true) | tee -a "${build_log}"
571 done
Harrison Mutai6dafb5f2023-07-18 15:21:48 +0100572 fi
Boyan Karatotev97de8d82025-03-06 15:22:21 +0000573 popd
Fathi Boudra422bf772019-12-02 11:10:16 +0200574 )
575}
576
577build_tftf() {
578 (
579 config_file="${tftf_build_config:-$tftf_config_file}"
580
581 # Build tftf target by default
582 build_targets="${tftf_build_targets:-all}"
583
584 source "$config_file"
585
586 cd "$tftf_root"
587
588 # Always distclean when running on Jenkins. Skip distclean when running
589 # locally and explicitly requested.
590 if upon "$jenkins_run" || not_upon "$dont_clean"; then
Boyan Karatotev97de8d82025-03-06 15:22:21 +0000591 make distclean BUILD_BASE="$tftf_build_root" &>>"$build_log" || fail_build
Fathi Boudra422bf772019-12-02 11:10:16 +0200592 fi
593
594 # TFTF build system cannot reliably deal with -j option, so we avoid
595 # using that.
596
597 # Log build command line
598 cat <<EOF | log_separator >/dev/null
599
600Build command line:
Boyan Karatotev97de8d82025-03-06 15:22:21 +0000601 make $make_j_opts $(cat "$config_file" | tr '\n' ' ') DEBUG=$DEBUG V=1 BUILD_BASE="$tftf_build_root" $build_targets
Fathi Boudra422bf772019-12-02 11:10:16 +0200602
603EOF
604
Boyan Karatotev97de8d82025-03-06 15:22:21 +0000605 make $make_j_opts $(cat "$config_file") DEBUG="$DEBUG" V=1 BUILD_BASE="$tftf_build_root" \
Fathi Boudra422bf772019-12-02 11:10:16 +0200606 $build_targets &>>"$build_log" || fail_build
607 )
608}
609
Zelalem219df412020-05-17 19:21:20 -0500610build_cc() {
611# Building code coverage plugin
612 ARM_DIR=/arm
613 pvlibversion=$(/arm/devsys-tools/abs/detag "SysGen:PVModelLib:$model_version::trunk")
614 PVLIB_HOME=$warehouse/SysGen/PVModelLib/$model_version/${pvlibversion}/external
615 if [ -n "$(find "$ARM_DIR" -maxdepth 0 -type d -empty 2>/dev/null)" ]; then
616 echo "Error: Arm warehouse not mounted. Please mount the Arm warehouse to your /arm local folder"
617 exit -1
618 fi # Error if arm warehouse not found
619 cd "$ccpathspec/scripts/tools/code_coverage/fastmodel_baremetal/bmcov"
620
621 make -C model-plugin PVLIB_HOME=$PVLIB_HOME &>>"$build_log"
622}
623
Olivier Deprez0a9a3482019-12-16 14:10:31 +0100624build_spm() {
625 (
626 env_file="$workspace/spm.env"
627 config_file="${spm_build_config:-$spm_config_file}"
628
629 source "$config_file"
630
631 if [ -f "$env_file" ]; then
632 set -a
633 source "$env_file"
634 set +a
635 fi
636
637 cd "$spm_root"
638
639 # Always clean when running on Jenkins. Skip clean when running
640 # locally and explicitly requested.
641 if upon "$jenkins_run" || not_upon "$dont_clean"; then
642 # make clean fails on a fresh repo where the project has not
643 # yet been built. Hence only clean if out/reference directory
644 # already exists.
645 if [ -d "out/reference" ]; then
646 make clean &>>"$build_log" || fail_build
647 fi
648 fi
649
650 # Log build command line. It is left unfolded on purpose to assist
651 # copying to clipboard.
652 cat <<EOF | log_separator >/dev/null
653
654Build command line:
655 make $make_j_opts $(cat "$config_file" | tr '\n' ' ')
656
657EOF
658
659 # Build SPM. Since build output is being directed to the build log, have
660 # descriptor 3 point to the current terminal for build wrappers to vent.
661 make $make_j_opts $(cat "$config_file") 3>&1 &>>"$build_log" \
662 || fail_build
663 )
664}
Zelalem219df412020-05-17 19:21:20 -0500665
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +0000666build_rmm() {
667 (
668 env_file="$workspace/rmm.env"
669 config_file="${rmm_build_config:-$rmm_config_file}"
670
671 # Build fiptool and all targets by default
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +0000672 export CROSS_COMPILE="${aarch64_none_elf_prefix}"
673
674 source "$config_file"
675
676 if [ -f "$env_file" ]; then
677 set -a
678 source "$env_file"
679 set +a
680 fi
681
682 cd "$rmm_root"
683
684 if [ -f "$rmm_root/requirements.txt" ]; then
685 export PATH="$HOME/.local/bin:$PATH"
686 python3 -m pip install --upgrade pip
687 python3 -m pip install -r "$rmm_root/requirements.txt"
688 fi
689
690 # Always distclean when running on Jenkins. Skip distclean when running
691 # locally and explicitly requested.
692 if upon "$jenkins_run" || not_upon "$dont_clean"; then
693 # Remove 'rmm\build' folder
694 echo "Removing $rmm_build_root..."
695 rm -rf $rmm_build_root
696 fi
697
Manish V Badarkhea3505272025-04-17 14:20:42 +0100698 if not_upon "$local_ci"; then
699 connect_debugger=0
700 fi
701
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +0000702 # Log build command line. It is left unfolded on purpose to assist
703 # copying to clipboard.
704 cat <<EOF | log_separator >/dev/null
705
706Build command line:
Manish V Badarkhea3505272025-04-17 14:20:42 +0100707 cmake -DRMM_CONFIG=${plat}_defcfg "$cmake_gen" -S $rmm_root -B $rmm_build_root -DRMM_TOOLCHAIN=$rmm_toolchain -DRMM_FPU_USE_AT_REL2=$rmm_fpu_use_at_rel2 -DATTEST_EL3_TOKEN_SIGN=$rmm_attest_el3_token_sign -DRMM_V1_1=$rmm_v1_1 ${extra_options}
708 cmake --build $rmm_build_root --config $cmake_build_type $make_j_opts -v ${extra_targets+-- $extra_targets}
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +0000709
Manish V Badarkhea3505272025-04-17 14:20:42 +0100710EOF
711 cmake \
712 -DRMM_CONFIG=${plat}_defcfg $cmake_gen \
713 -S $rmm_root -B $rmm_build_root \
714 -DRMM_TOOLCHAIN=$rmm_toolchain \
715 -DRMM_FPU_USE_AT_REL2=$rmm_fpu_use_at_rel2 \
716 -DATTEST_EL3_TOKEN_SIGN=$rmm_attest_el3_token_sign \
717 -DRMM_V1_1=$rmm_v1_1 \
718 ${extra_options}
719 cmake --build $rmm_build_root --config $cmake_build_type $make_j_opts -v ${extra_targets+-- $extra_targets} 3>&1 &>>"$build_log" || fail_build
720 )
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +0000721}
722
Fathi Boudra422bf772019-12-02 11:10:16 +0200723# Set metadata for the whole package so that it can be used by both Jenkins and
724# shell
725set_package_var() {
726 env_file="$artefacts/env" emit_env "$@"
727}
728
729set_tf_build_targets() {
730 echo "Set build target to '${targets:?}'"
731 set_hook_var "tf_build_targets" "$targets"
732}
733
734set_tftf_build_targets() {
735 echo "Set build target to '${targets:?}'"
736 set_hook_var "tftf_build_targets" "$targets"
737}
738
Olivier Deprez0a9a3482019-12-16 14:10:31 +0100739set_spm_build_targets() {
740 echo "Set build target to '${targets:?}'"
741 set_hook_var "spm_build_targets" "$targets"
742}
743
Daniel Boulbyb8d2a462022-03-07 13:55:25 +0000744set_spm_out_dir() {
745 echo "Set SPMC binary build to '${out_dir:?}'"
746 set_hook_var "spm_secure_out_dir" "$out_dir"
747}
Fathi Boudra422bf772019-12-02 11:10:16 +0200748# Look under $archive directory for known files such as blX images, kernel, DTB,
749# initrd etc. For each known file foo, if foo.bin exists, then set variable
750# foo_bin to the path of the file. Make the path relative to the workspace so as
751# to remove any @ characters, which Jenkins inserts for parallel runs. If the
752# file doesn't exist, unset its path.
753set_default_bin_paths() {
754 local image image_name image_path path
755 local archive="${archive:?}"
756 local set_vars
757 local var
758
759 pushd "$archive"
760
761 for file in *.bin; do
762 # Get a shell variable from the file's stem
763 var_name="${file%%.*}_bin"
764 var_name="$(echo "$var_name" | sed -r 's/[^[:alnum:]]/_/g')"
765
766 # Skip setting the variable if it's already
767 if [ "${!var_name}" ]; then
768 echo "Note: not setting $var_name; already set to ${!var_name}"
769 continue
770 else
771 set_vars+="$var_name "
772 fi
773
774 eval "$var_name=$file"
775 done
776
777 echo "Binary paths set for: "
778 {
779 for var in $set_vars; do
780 echo -n "\$$var "
781 done
782 } | fmt -80 | sed 's/^/ /'
783 echo
784
785 popd
786}
787
788gen_model_params() {
789 local model_param_file="$archive/model_params"
Javier Almansa Sobrinoe8363182020-11-10 16:40:53 +0000790 [ "$connect_debugger" ] && [ "$connect_debugger" -eq 1 ] && wait_debugger=1
Fathi Boudra422bf772019-12-02 11:10:16 +0200791
792 set_default_bin_paths
793 echo "Generating model parameter for $model..."
794 source "$ci_root/model/${model:?}.sh"
795 archive_file "$model_param_file"
796}
797
798set_model_path() {
799 set_run_env "model_path" "${1:?}"
800}
801
Zelalem1af7a7b2020-08-04 17:34:32 -0500802set_model_env() {
803 local var="${1:?}"
804 local val="${2?}"
805 local run_root="${archive:?}/run"
806
807 mkdir -p "$run_root"
808 echo "export $var=$val" >> "$run_root/model_env"
809}
Fathi Boudra422bf772019-12-02 11:10:16 +0200810set_run_env() {
811 local var="${1:?}"
812 local val="${2?}"
813 local run_root="${archive:?}/run"
814
815 mkdir -p "$run_root"
816 env_file="$run_root/env" quote="1" emit_env "$var" "$val"
817}
818
819show_head() {
820 # Display HEAD descripton
821 pushd "$1"
822 git show --quiet --no-color | sed 's/^/ > /g'
823 echo
824 popd
825}
826
827# Choose debug binaries to run; by default, release binaries are chosen to run
828use_debug_bins() {
829 local run_root="${archive:?}/run"
830
831 echo "Choosing debug binaries for execution"
832 set_package_var "BIN_MODE" "debug"
833}
834
835assert_can_git_clone() {
836 local name="${1:?}"
837 local dir="${!name}"
838
839 # If it doesn't exist, it can be cloned into
840 if [ ! -e "$dir" ]; then
841 return 0
842 fi
843
844 # If it's a directory, it must be a Git clone already
845 if [ -d "$dir" ] && [ -d "$dir/.git" ]; then
846 # No need to clone again
847 echo "Using existing git clone for $name: $dir"
848 return 1
849 fi
850
851 die "Path $dir exists but is not a git clone"
852}
853
854clone_repo() {
855 if ! is_url "${clone_url?}"; then
856 # For --depth to take effect on local paths, it needs to use the
857 # file:// scheme.
858 clone_url="file://$clone_url"
859 fi
860
861 git clone -q --depth 1 "$clone_url" "${where?}"
862 if [ "$refspec" ]; then
863 pushd "$where"
864 git fetch -q --depth 1 origin "$refspec"
865 git checkout -q FETCH_HEAD
866 popd
867 fi
868}
869
870build_unstable() {
871 echo "--BUILD UNSTABLE--" | tee -a "$build_log"
872}
873
874undo_patch_record() {
875 if [ ! -f "${patch_record:?}" ]; then
876 return
877 fi
878
879 # Undo patches in reverse
880 echo
881 for patch_name in $(tac "$patch_record"); do
882 echo "Undoing $patch_name..."
883 if ! git apply -R "$ci_root/patch/$patch_name"; then
884 if upon "$local_ci"; then
885 echo
886 echo "Your local directory may have been dirtied."
887 echo
888 fi
889 fail_build
890 fi
891 done
892
893 rm -f "$patch_record"
894}
895
896undo_local_patches() {
897 pushd "$tf_root"
898 patch_record="$tf_patch_record" undo_patch_record
899 popd
900
901 if [ -d "$tftf_root" ]; then
902 pushd "$tftf_root"
903 patch_record="$tftf_patch_record" undo_patch_record
904 popd
905 fi
906}
907
908undo_tftf_patches() {
909 pushd "$tftf_root"
910 patch_record="$tftf_patch_record" undo_patch_record
911 popd
912}
913
914undo_tf_patches() {
915 pushd "$tf_root"
916 patch_record="$tf_patch_record" undo_patch_record
917 popd
918}
919
920apply_patch() {
921 # If skip_patches is set, the developer has applied required patches
922 # manually. They probably want to keep them applied for debugging
923 # purposes too. This means we don't have to apply/revert them as part of
924 # build process.
925 if upon "$skip_patches"; then
926 echo "Skipped applying ${1:?}..."
927 return 0
928 else
929 echo "Applying ${1:?}..."
930 fi
931
Sandrine Bailleux4cb8c222023-09-13 13:48:15 +0200932 if git apply --reverse --check < "$ci_root/patch/$1" 2> /dev/null; then
Jimmy Brissonf134e4c2023-03-22 13:20:20 -0500933 echo "Skipping already applied ${1:?}"
934 return 0
935 fi
936
Fathi Boudra422bf772019-12-02 11:10:16 +0200937 if git apply < "$ci_root/patch/$1"; then
938 echo "$1" >> "${patch_record:?}"
939 else
940 if upon "$local_ci"; then
941 undo_local_patches
942 fi
943 fail_build
944 fi
945}
946
947apply_tftf_patch() {
948 pushd "$tftf_root"
949 patch_record="$tftf_patch_record" apply_patch "$1"
950 popd
951}
952
953apply_tf_patch() {
954 pushd "$tf_root"
955 patch_record="$tf_patch_record" apply_patch "$1"
956 popd
957}
958
Fathi Boudra422bf772019-12-02 11:10:16 +0200959mkdir -p "$workspace"
960mkdir -p "$archive"
961set_package_var "TEST_CONFIG" "$test_config"
962
963{
964echo
965echo "CONFIGURATION: $test_group/$test_config"
966echo
967} |& log_separator
968
969tf_config="$(echo "$build_configs" | awk -F, '{print $1}')"
970tftf_config="$(echo "$build_configs" | awk -F, '{print $2}')"
Chris Kay4f7846a2025-08-04 19:56:35 +0100971spm_config="$(echo "$build_configs" | awk -F, '{print $3}')"
972rmm_config="$(echo "$build_configs" | awk -F, '{print $4}')"
Fathi Boudra422bf772019-12-02 11:10:16 +0200973
974test_config_file="$ci_root/group/$test_group/$test_config"
975
976tf_config_file="$ci_root/tf_config/$tf_config"
977tftf_config_file="$ci_root/tftf_config/$tftf_config"
Olivier Deprez0a9a3482019-12-16 14:10:31 +0100978spm_config_file="$ci_root/spm_config/$spm_config"
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +0000979rmm_config_file="$ci_root/rmm_config/$rmm_config"
Fathi Boudra422bf772019-12-02 11:10:16 +0200980
981# File that keeps track of applied patches
982tf_patch_record="$workspace/tf_patches"
983tftf_patch_record="$workspace/tftf_patches"
984
985pushd "$workspace"
986
987if ! config_valid "$tf_config"; then
988 tf_config=
989else
990 echo "Trusted Firmware config:"
991 echo
992 sort "$tf_config_file" | sed '/^\s*$/d;s/^/\t/'
993 echo
994fi
995
996if ! config_valid "$tftf_config"; then
997 tftf_config=
998else
999 echo "Trusted Firmware TF config:"
1000 echo
1001 sort "$tftf_config_file" | sed '/^\s*$/d;s/^/\t/'
1002 echo
1003fi
1004
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001005if ! config_valid "$spm_config"; then
1006 spm_config=
1007else
1008 echo "SPM config:"
1009 echo
1010 sort "$spm_config_file" | sed '/^\s*$/d;s/^/\t/'
Zelalem219df412020-05-17 19:21:20 -05001011 echo
1012fi
1013
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +00001014# File that keeps track of applied patches
1015rmm_patch_record="$workspace/rmm_patches"
1016
1017if ! config_valid "$rmm_config"; then
1018 rmm_config=
1019else
1020 echo "Trusted Firmware RMM config:"
1021 echo
1022 sort "$rmm_config_file" | sed '/^\s*$/d;s/^/\t/'
1023 echo
1024fi
1025
Fathi Boudra422bf772019-12-02 11:10:16 +02001026if ! config_valid "$run_config"; then
1027 run_config=
1028fi
1029
1030if [ "$tf_config" ] && assert_can_git_clone "tf_root"; then
1031 # If the Trusted Firmware repository has already been checked out, use
1032 # that location. Otherwise, clone one ourselves.
1033 echo "Cloning Trusted Firmware..."
1034 clone_url="${TF_CHECKOUT_LOC:-$tf_src_repo_url}" where="$tf_root" \
1035 refspec="$TF_REFSPEC" clone_repo &>>"$build_log"
1036 show_head "$tf_root"
1037fi
1038
1039if [ "$tftf_config" ] && assert_can_git_clone "tftf_root"; then
1040 # If the Trusted Firmware TF repository has already been checked out,
1041 # use that location. Otherwise, clone one ourselves.
1042 echo "Cloning Trusted Firmware TF..."
1043 clone_url="${TFTF_CHECKOUT_LOC:-$tftf_src_repo_url}" where="$tftf_root" \
1044 refspec="$TFTF_REFSPEC" clone_repo &>>"$build_log"
1045 show_head "$tftf_root"
1046fi
1047
Zelalem219df412020-05-17 19:21:20 -05001048if [ -n "$cc_config" ] ; then
1049 if [ "$cc_config" -eq 1 ] && assert_can_git_clone "cc_root"; then
1050 # Copy code coverage repository
1051 echo "Cloning Code Coverage..."
1052 git clone -q $cc_src_repo_url cc_plugin --depth 1 -b $cc_src_repo_tag > /dev/null
1053 show_head "$cc_root"
1054 fi
1055fi
1056
Daniel Boulby25385ab2023-12-14 14:36:25 +00001057if [ "$spm_config" ] ; then
1058 if assert_can_git_clone "spm_root"; then
1059 # If the SPM repository has already been checked out, use
1060 # that location. Otherwise, clone one ourselves.
1061 echo "Cloning SPM..."
1062 clone_url="${SPM_CHECKOUT_LOC:-$spm_src_repo_url}" \
1063 where="$spm_root" refspec="$SPM_REFSPEC" \
1064 clone_repo &>>"$build_log"
1065 fi
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001066
1067 # Query git submodules
1068 pushd "$spm_root"
Daniel Boulby25385ab2023-12-14 14:36:25 +00001069 # Check if submodules need initialising
Paul Sokolovskyad274422024-09-01 10:27:56 +03001070
1071 # This handling is needed to reliably fetch submodules
1072 # in CI environment.
1073 for subm in $(git submodule status | awk '/^-/ {print $2}'); do
1074 for i in $(seq 1 7); do
1075 git submodule init $subm
1076 if git submodule update $subm; then
1077 break
1078 fi
1079 git submodule deinit --force $subm
1080 echo "Retrying $subm"
1081 sleep $((RANDOM % 10 + 5))
1082 done
1083 done
1084
1085 git submodule status
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001086 popd
1087
1088 show_head "$spm_root"
1089fi
1090
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +00001091if [ "$rmm_config" ] && assert_can_git_clone "rmm_root"; then
Manish V Badarkhe41909452025-04-11 12:06:45 +01001092 # If the RMM repository has already been checked out,
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +00001093 # use that location. Otherwise, clone one ourselves.
1094 echo "Cloning TF-RMM..."
1095 clone_url="${RMM_CHECKOUT_LOC:-$rmm_src_repo_url}" where="$rmm_root" \
1096 refspec="$RMM_REFSPEC" clone_repo &>>"$build_log"
1097 show_head "$rmm_root"
1098fi
1099
Fathi Boudra422bf772019-12-02 11:10:16 +02001100if [ "$run_config" ]; then
1101 # Get candidates for run config
Nicola Mazzucato7fc5abd2024-02-23 21:32:48 +00001102 run_config_candidates="$("$ci_root/script/gen_run_config_candidates.py" \
Fathi Boudra422bf772019-12-02 11:10:16 +02001103 "$run_config")"
Nicola Mazzucato7fc5abd2024-02-23 21:32:48 +00001104 if [ -z "$run_config_candidates" ]; then
Fathi Boudra422bf772019-12-02 11:10:16 +02001105 die "No run config candidates!"
1106 else
1107 echo
1108 echo "Chosen fragments:"
1109 echo
Nicola Mazzucato7fc5abd2024-02-23 21:32:48 +00001110 echo "$run_config_candidates" | sed 's/^\|\n/\t/g'
Fathi Boudra422bf772019-12-02 11:10:16 +02001111 echo
Harrison Mutai4dfe1192024-07-03 12:35:38 +00001112
1113 if [ ! -n "$bin_mode" ]; then
1114 if echo $run_config_candidates | grep -wq "debug"; then
1115 bin_mode="debug"
1116 else
1117 bin_mode="release"
1118 fi
1119 fi
Fathi Boudra422bf772019-12-02 11:10:16 +02001120 fi
1121fi
1122
1123call_hook "test_setup"
1124echo
1125
1126if upon "$local_ci"; then
1127 # For local runs, since each config is tried in sequence, it's
1128 # advantageous to run jobs in parallel
1129 if [ "$make_j" ]; then
1130 make_j_opts="-j $make_j"
1131 else
1132 n_cores="$(getconf _NPROCESSORS_ONLN)" 2>/dev/null || true
1133 if [ "$n_cores" ]; then
1134 make_j_opts="-j $n_cores"
1135 fi
1136 fi
1137fi
1138
Harrison Mutai07043e92023-07-06 09:41:12 +01001139# Install python build dependencies
1140if is_arm_jenkins_env; then
1141 source "$ci_root/script/install_python_deps.sh"
1142fi
1143
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +00001144# Print CMake version
1145cmake_ver=$(echo `cmake --version | sed -n '1p'`)
1146echo "Using $cmake_ver"
1147
1148# Check for Ninja
1149if [ -x "$(command -v ninja)" ]; then
1150 # Print Ninja version
1151 ninja_ver=$(echo `ninja --version | sed -n '1p'`)
1152 echo "Using ninja $ninja_ver"
1153 export cmake_gen="-G Ninja"
1154else
1155 echo 'Ninja is not installed'
1156 export cmake_gen=""
1157fi
1158
1159undo_rmm_patches() {
1160 pushd "$rmm_root"
1161 patch_record="$rmm_patch_record" undo_patch_record
1162 popd
1163}
1164
Fathi Boudra422bf772019-12-02 11:10:16 +02001165modes="${bin_mode:-debug release}"
1166for mode in $modes; do
Paul Sokolovskye9962cd2021-12-17 18:39:40 +03001167 echo "===== Building package in mode: $mode ====="
Fathi Boudra422bf772019-12-02 11:10:16 +02001168 # Build with a temporary archive
1169 build_archive="$archive/$mode"
1170 mkdir "$build_archive"
1171
1172 if [ "$mode" = "debug" ]; then
Zelalem219df412020-05-17 19:21:20 -05001173 export bin_mode="debug"
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +00001174 cmake_build_type="Debug"
Fathi Boudra422bf772019-12-02 11:10:16 +02001175 DEBUG=1
1176 else
Zelalem219df412020-05-17 19:21:20 -05001177 export bin_mode="release"
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +00001178 cmake_build_type="Release"
Fathi Boudra422bf772019-12-02 11:10:16 +02001179 DEBUG=0
1180 fi
1181
1182 # Perform builds in a subshell so as not to pollute the current and
1183 # subsequent builds' environment
1184
Zelalem219df412020-05-17 19:21:20 -05001185 if config_valid "$cc_config"; then
1186 # Build code coverage plugin
1187 build_cc
1188 fi
1189
Fathi Boudra422bf772019-12-02 11:10:16 +02001190 # TFTF build
1191 if config_valid "$tftf_config"; then
1192 (
1193 echo "##########"
1194
Manish V Badarkhe3bd3fea2020-11-08 15:17:00 +00001195 plat_utils="$(get_tf_opt PLAT_UTILS)"
1196 if [ -z ${plat_utils} ]; then
1197 # Source platform-specific utilities.
1198 plat="$(get_tftf_opt PLAT)"
1199 plat_utils="$ci_root/${plat}_utils.sh"
1200 else
1201 # Source platform-specific utilities by
1202 # using plat_utils name.
1203 plat_utils="$ci_root/${plat_utils}.sh"
1204 fi
1205
Fathi Boudra422bf772019-12-02 11:10:16 +02001206 if [ -f "$plat_utils" ]; then
1207 source "$plat_utils"
1208 fi
1209
1210 archive="$build_archive"
Boyan Karatotev97de8d82025-03-06 15:22:21 +00001211 tftf_build_root="$archive/build/tftf"
1212 mkdir -p ${tftf_build_root}
Fathi Boudra422bf772019-12-02 11:10:16 +02001213
1214 echo "Building Trusted Firmware TF ($mode) ..." |& log_separator
1215
1216 # Call pre-build hook
1217 call_hook pre_tftf_build
1218
1219 build_tftf
1220
1221 from="$tftf_build_root" to="$archive" collect_build_artefacts
1222
1223 # Clear any local changes made by applied patches
1224 undo_tftf_patches
1225
1226 echo "##########"
1227 echo
1228 )
1229 fi
1230
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001231 # SPM build
1232 if config_valid "$spm_config"; then
1233 (
1234 echo "##########"
1235
1236 # Get platform name from spm_config file
1237 plat="$(echo "$spm_config" | awk -F- '{print $1}')"
1238 plat_utils="$ci_root/${plat}_utils.sh"
1239 if [ -f "$plat_utils" ]; then
1240 source "$plat_utils"
1241 fi
1242
Daniel Boulbyb8d2a462022-03-07 13:55:25 +00001243 # Call pre-build hook
1244 call_hook pre_spm_build
1245
Manish Pandey1e7be852020-11-09 16:04:48 +00001246 # SPM build generates two sets of binaries, one for normal and other
1247 # for Secure world. We need both set of binaries for CI.
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001248 archive="$build_archive"
Manish Pandey1e7be852020-11-09 16:04:48 +00001249 spm_build_root="$spm_root/out/reference/$spm_secure_out_dir"
1250 hafnium_build_root="$spm_root/out/reference/$spm_non_secure_out_dir"
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001251
Daniel Boulbyb8d2a462022-03-07 13:55:25 +00001252 echo "spm_build_root is $spm_build_root"
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001253 echo "Building SPM ($mode) ..." |& log_separator
1254
1255 # NOTE: mode has no effect on SPM build (for now), hence debug
1256 # mode is built but subsequent build using release mode just
1257 # goes through with "nothing to do".
1258 build_spm
1259
1260 # Show SPM/Hafnium binary details
Madhukar Pappireddyc683cf62021-11-01 14:38:32 -05001261 cksum $spm_build_root/hafnium.bin
1262
1263 # Some platforms only have secure configuration enabled. Hence,
1264 # non secure hanfnium binary might not be built.
1265 if [ -f $hafnium_build_root/hafnium.bin ]; then
1266 cksum $hafnium_build_root/hafnium.bin
1267 fi
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001268
Manish Pandey1e7be852020-11-09 16:04:48 +00001269 secure_from="$spm_build_root" non_secure_from="$hafnium_build_root" to="$archive" collect_spm_artefacts
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001270
1271 echo "##########"
1272 echo
1273 )
1274 fi
1275
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +00001276 # TF RMM build
1277 if config_valid "$rmm_config"; then
1278 (
1279 echo "##########"
1280
1281 plat_utils="$(get_rmm_opt PLAT_UTILS)"
1282 if [ -z ${plat_utils} ]; then
1283 # Source platform-specific utilities.
1284 plat="$(get_rmm_opt PLAT)"
Manish V Badarkhea3505272025-04-17 14:20:42 +01001285 extra_options="$(get_rmm_opt EXTRA_OPTIONS)"
1286 extra_targets="$(get_rmm_opt EXTRA_TARGETS "")"
1287 rmm_toolchain="$(get_rmm_opt TOOLCHAIN gnu)"
1288 rmm_fpu_use_at_rel2="$(get_rmm_opt RMM_FPU_USE_AT_REL2 OFF)"
1289 rmm_attest_el3_token_sign="$(get_rmm_opt ATTEST_EL3_TOKEN_SIGN OFF)"
1290 rmm_v1_1="$(get_rmm_opt RMM_V1_1 ON)"
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +00001291 plat_utils="$ci_root/${plat}_utils.sh"
1292 else
1293 # Source platform-specific utilities by
1294 # using plat_utils name.
1295 plat_utils="$ci_root/${plat_utils}.sh"
1296 fi
1297
1298 if [ -f "$plat_utils" ]; then
1299 source "$plat_utils"
1300 fi
1301
1302 archive="$build_archive"
1303 rmm_build_root="$rmm_root/build"
1304
1305 echo "Building Trusted Firmware RMM ($mode) ..." |& log_separator
1306
1307 #call_hook pre_rmm_build
1308 build_rmm
1309
1310 # Collect all rmm.* files: rmm.img, rmm.elf, rmm.dump, rmm.map
1311 from="$rmm_build_root" to="$archive" collect_build_artefacts
1312
1313 # Clear any local changes made by applied patches
1314 undo_rmm_patches
1315
1316 echo "##########"
1317 )
1318 fi
1319
Fathi Boudra422bf772019-12-02 11:10:16 +02001320 # TF build
1321 if config_valid "$tf_config"; then
1322 (
1323 echo "##########"
1324
Manish V Badarkhe3bd3fea2020-11-08 15:17:00 +00001325 plat_utils="$(get_tf_opt PLAT_UTILS)"
Madhukar Pappireddy2f284e12021-08-30 16:06:14 -05001326 export plat_variant="$(get_tf_opt TARGET_PLATFORM)"
1327
Manish V Badarkhe3bd3fea2020-11-08 15:17:00 +00001328 if [ -z ${plat_utils} ]; then
1329 # Source platform-specific utilities.
1330 plat="$(get_tf_opt PLAT)"
1331 plat_utils="$ci_root/${plat}_utils.sh"
1332 else
1333 # Source platform-specific utilities by
1334 # using plat_utils name.
1335 plat_utils="$ci_root/${plat_utils}.sh"
1336 fi
1337
Fathi Boudra422bf772019-12-02 11:10:16 +02001338 if [ -f "$plat_utils" ]; then
1339 source "$plat_utils"
1340 fi
1341
Chris Kaye5a486b2023-08-04 11:50:31 +00001342 fvp_tsram_size="$(get_tf_opt FVP_TRUSTED_SRAM_SIZE)"
1343 fvp_tsram_size="${fvp_tsram_size:-256}"
1344
Harrison Mutaidc703402024-08-02 14:40:16 +00001345 poetry -C "$tf_root" install --without docs
Chris Kayd0837902021-11-17 10:17:52 +00001346
Fathi Boudra422bf772019-12-02 11:10:16 +02001347 archive="$build_archive"
Boyan Karatotev97de8d82025-03-06 15:22:21 +00001348 tf_build_root="$archive/build/tfa"
1349 mkdir -p ${tf_build_root}
Fathi Boudra422bf772019-12-02 11:10:16 +02001350
1351 echo "Building Trusted Firmware ($mode) ..." |& log_separator
1352
1353 # Call pre-build hook
1354 call_hook pre_tf_build
1355
1356 build_tf
1357
1358 # Call post-build hook
1359 call_hook post_tf_build
1360
1361 # Pre-archive hook
1362 call_hook pre_tf_archive
1363
1364 from="$tf_build_root" to="$archive" collect_build_artefacts
1365
1366 # Post-archive hook
1367 call_hook post_tf_archive
1368
1369 call_hook fetch_tf_resource
1370 call_hook post_fetch_tf_resource
1371
Chris Kay4e8aaf12022-09-01 15:21:55 +01001372 # Generate LAVA job files if necessary
1373 call_hook generate_lava_job_template
1374 call_hook generate_lava_job
1375
Fathi Boudra422bf772019-12-02 11:10:16 +02001376 # Clear any local changes made by applied patches
1377 undo_tf_patches
1378
1379 echo "##########"
1380 )
1381 fi
1382
1383 echo
1384 echo
1385done
1386
1387call_hook pre_package
1388
1389call_hook post_package
1390
1391if upon "$jenkins_run" && upon "$artefacts_receiver" && [ -d "artefacts" ]; then
Zelalem219df412020-05-17 19:21:20 -05001392 source "$CI_ROOT/script/send_artefacts.sh" "artefacts"
Fathi Boudra422bf772019-12-02 11:10:16 +02001393fi
1394
1395echo
1396echo "Done"