blob: f9fbebe8128a917e0ee048be789327bc7727a558 [file] [log] [blame]
Leonardo Sandoval9dfdd1b2020-08-06 17:08:11 -05001#!/usr/bin/env bash
Fathi Boudra422bf772019-12-02 11:10:16 +02002#
Boyan Karatotev27057342025-07-28 09:56:23 +01003# Copyright (c) 2019-2025 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}"
Juan Pablo Conde3feb7f12023-10-21 13:14:47 -050023export tfut_root="${tfut_root:-$workspace/tfut}"
Zelalem219df412020-05-17 19:21:20 -050024cc_root="${cc_root:-$ccpathspec}"
Olivier Deprez0a9a3482019-12-16 14:10:31 +010025spm_root="${spm_root:-$workspace/spm}"
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +000026rmm_root="${rmm_root:-$workspace/tf-rmm}"
Zelalem219df412020-05-17 19:21:20 -050027
Fathi Boudra422bf772019-12-02 11:10:16 +020028# Refspecs
29tf_refspec="$TF_REFSPEC"
30tftf_refspec="$TFTF_REFSPEC"
Olivier Deprez0a9a3482019-12-16 14:10:31 +010031spm_refspec="$SPM_REFSPEC"
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +000032rmm_refspec="$RMM_REFSPEC"
Juan Pablo Conde3feb7f12023-10-21 13:14:47 -050033tfut_gerrit_refspec="$TFUT_GERRIT_REFSPEC"
Fathi Boudra422bf772019-12-02 11:10:16 +020034
35test_config="${TEST_CONFIG:?}"
36test_group="${TEST_GROUP:?}"
37build_configs="${BUILD_CONFIG:?}"
38run_config="${RUN_CONFIG:?}"
Zelalem219df412020-05-17 19:21:20 -050039cc_config="${CC_ENABLE:-}"
Fathi Boudra422bf772019-12-02 11:10:16 +020040
Boyan Karatotev97de8d82025-03-06 15:22:21 +000041export archive="$artefacts"
Fathi Boudra422bf772019-12-02 11:10:16 +020042build_log="$artefacts/build.log"
Boyan Karatotevde2cd442025-07-28 09:50:29 +010043
44fiptool_path() {
45 echo $tf_build_root/$(get_tf_opt PLAT)/${bin_mode}/tools/fiptool/fiptool
46}
47
48cert_create_path() {
49 echo $tf_build_root/$(get_tf_opt PLAT)/${bin_mode}/tools/cert_create/cert_create
50}
Fathi Boudra422bf772019-12-02 11:10:16 +020051
52# Validate $bin_mode
53case "$bin_mode" in
54 "" | debug | release)
55 ;;
56 *)
57 die "Invalid value for bin_mode: $bin_mode"
58 ;;
59esac
60
61# File to save any environem
62hook_env_file="$(mktempfile)"
63
Fathi Boudra422bf772019-12-02 11:10:16 +020064# Echo from a build wrapper. Print to descriptor 3 that's opened by the build
65# function.
66echo_w() {
67 echo $echo_flags "$@" >&3
68}
69
70# Print a separator to the log file. Intended to be used at the tail end of a pipe
71log_separator() {
72 {
73 echo
74 echo "----------"
75 } >> "$build_log"
76
77 tee -a "$build_log"
78
79 {
80 echo "----------"
81 echo
82 } >> "$build_log"
83}
84
85# Call function $1 if it's defined
86call_func() {
87 if type "${1:?}" &>/dev/null; then
88 echo
89 echo "> ${2:?}:$1()"
90 eval "$1"
91 echo "< $2:$1()"
92 fi
93}
94
Paul Sokolovskybe6510c2024-08-15 21:54:00 +030095# Retry a command a number of times if it fails. Intended for I/O commands
96# in a CI environment which may be flaky.
97function retry() {
98 for i in $(seq 1 3); do
99 if "$@"; then
100 return 0
101 fi
102 sleep $(( i * 5 ))
103 done
104 return 1
105}
106
Fathi Boudra422bf772019-12-02 11:10:16 +0200107# Call hook $1 in all chosen fragments if it's defined. Hooks are invoked from
108# within a subshell, so any variables set within a hook are lost. Should a
109# variable needs to be set from within a hook, the function 'set_hook_var'
110# should be used
111call_hook() {
112 local func="$1"
113 local config_fragment
114
115 [ -z "$func" ] && return 0
116
Boyan Karatotev7b6a93b2025-08-27 16:00:59 +0100117 echo "=== Calling hooks: $1 ===" &>>"$build_log"
Paul Sokolovskye9962cd2021-12-17 18:39:40 +0300118
Fathi Boudra422bf772019-12-02 11:10:16 +0200119 : >"$hook_env_file"
120
Nicola Mazzucato7fc5abd2024-02-23 21:32:48 +0000121 if [ "$run_config_candidates" ]; then
122 for config_fragment in $run_config_candidates; do
Fathi Boudra422bf772019-12-02 11:10:16 +0200123 (
124 source "$ci_root/run_config/$config_fragment"
125 call_func "$func" "$config_fragment"
Boyan Karatotev7b6a93b2025-08-27 16:00:59 +0100126 ) &>>"$build_log" || fail_build
Fathi Boudra422bf772019-12-02 11:10:16 +0200127 done
128 fi
129
Juan Pablo Conde2ecf1862024-01-16 20:12:43 -0600130 if [ "$run_config_tfut_candidates" ]; then
131 for config_fragment in $run_config_tfut_candidates; do
132 (
133 source "$ci_root/run_config_tfut/$config_fragment"
134 call_func "$func" "$config_fragment"
Boyan Karatotev7b6a93b2025-08-27 16:00:59 +0100135 ) &>>"$build_log" || fail_build
Juan Pablo Conde2ecf1862024-01-16 20:12:43 -0600136 done
137 fi
138
Fathi Boudra422bf772019-12-02 11:10:16 +0200139 # Also source test config file
140 (
141 unset "$func"
142 source "$test_config_file"
143 call_func "$func" "$(basename $test_config_file)"
144 )
145
146 # Have any variables set take effect
147 source "$hook_env_file"
Paul Sokolovskye9962cd2021-12-17 18:39:40 +0300148
Boyan Karatotev7b6a93b2025-08-27 16:00:59 +0100149 echo "=== End calling hooks: $1 ===" &>>"$build_log"
Fathi Boudra422bf772019-12-02 11:10:16 +0200150}
151
152# Set a variable from within a hook
153set_hook_var() {
154 echo "export $1=\"${2?}\"" >> "$hook_env_file"
155}
156
157# Append to an array from within a hook
158append_hook_var() {
159 echo "export $1+=\"${2?}\"" >> "$hook_env_file"
160}
161
162# Have the main build script source a file
163source_later() {
164 echo "source ${1?}" >> "$hook_env_file"
165}
166
167# Setup TF build wrapper function by pointing to a script containing a function
168# that will be called with the TF build commands.
169setup_tf_build_wrapper() {
170 source_later "$ci_root/script/${wrapper?}_wrapper.sh"
171 set_hook_var "tf_build_wrapper" "${wrapper}_wrapper"
172 echo "Setup $wrapper build wrapper."
173}
174
175# Collect .bin files for archiving
176collect_build_artefacts() {
177 if [ ! -d "${from:?}" ]; then
178 return
179 fi
180
Manish V Badarkhe84c3a482025-04-16 08:15:38 +0100181 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 +0200182 echo "You probably are running local CI on local repositories."
183 echo "Did you set 'dont_clean' but forgot to run 'distclean'?"
184 die
185 fi
186}
187
Manish Pandey1e7be852020-11-09 16:04:48 +0000188# Collect SPM/hafnium artefacts with "secure_" appended to the files
189# generated for SPM(secure hafnium).
190collect_spm_artefacts() {
Madhukar Pappireddyc683cf62021-11-01 14:38:32 -0500191 if [ -d "${non_secure_from:?}" ]; then
192 find "$non_secure_from" \( -name "*.bin" -o -name '*.elf' \) -exec cp -t "${to:?}" '{}' +
Manish Pandey1e7be852020-11-09 16:04:48 +0000193 fi
194
Madhukar Pappireddyc683cf62021-11-01 14:38:32 -0500195 if [ -d "${secure_from:?}" ]; then
196 for f in $(find "$secure_from" \( -name "*.bin" -o -name '*.elf' \)); do cp -- "$f" "${to:?}"/secure_$(basename $f); done
197 fi
Manish Pandey1e7be852020-11-09 16:04:48 +0000198}
199
Juan Pablo Conde3feb7f12023-10-21 13:14:47 -0500200collect_tfut_artefacts() {
201 if [ ! -d "${from:?}" ]; then
202 return
203 fi
204
205 pushd "$tfut_root/build"
206 artefact_list=$(python3 "$ci_root/script/get_ut_test_list.py")
207 for artefact in $artefact_list; do
208 cp -t "${to:?}" "$from/$artefact"
209 done
210 echo "$artefact_list" | tr ' ' '\n' > "${to:?}/tfut_artefacts.txt"
211 popd
212}
213
Edward Potapovdb31e702025-06-30 16:28:40 -0500214collect_tfut_coverage() {
215 if [ "$coverage" != "ON" ]; then
216 return
217 fi
218
219 pushd "$tfut_root/build"
220 touch "${to:?}/tfut_coverage.txt"
221 popd
222}
223
Javier Almansa Sobrino412d3612020-05-22 17:53:12 +0100224# Map the UART ID used for expect with the UART descriptor and port
225# used by the FPGA automation tools.
226map_uart() {
227 local port="${port:?}"
228 local descriptor="${descriptor:?}"
229 local baudrate="${baudrate:?}"
230 local run_root="${archive:?}/run"
231
232 local uart_dir="$run_root/uart${uart:?}"
233 mkdir -p "$uart_dir"
234
235 echo "$port" > "$uart_dir/port"
236 echo "$descriptor" > "$uart_dir/descriptor"
237 echo "$baudrate" > "$uart_dir/baudrate"
238
239 echo "UART${uart} mapped to port ${port} with descriptor ${descriptor} and baudrate ${baudrate}"
240}
241
Fathi Boudra422bf772019-12-02 11:10:16 +0200242# Arrange environment varibles to be set when expect scripts are launched
243set_expect_variable() {
244 local var="${1:?}"
245 local val="${2?}"
246
247 local run_root="${archive:?}/run"
248 local uart_dir="$run_root/uart${uart:?}"
249 mkdir -p "$uart_dir"
250
251 env_file="$uart_dir/env" quote="1" emit_env "$var" "$val"
252 echo "UART$uart: env has $@"
253}
254
255# Place the binary package a pointer to expect script, and its parameters
256track_expect() {
257 local file="${file:?}"
258 local timeout="${timeout-600}"
259 local run_root="${archive:?}/run"
260
261 local uart_dir="$run_root/uart${uart:?}"
262 mkdir -p "$uart_dir"
263
264 echo "$file" > "$uart_dir/expect"
265 echo "$timeout" > "$uart_dir/timeout"
Paul Sokolovskybfa8bab2023-01-25 19:34:51 +0700266 if [ -n "$lava_timeout" ]; then
267 set_run_env "lava_timeout" "$lava_timeout"
268 fi
Fathi Boudra422bf772019-12-02 11:10:16 +0200269
Paul Sokolovskybfa8bab2023-01-25 19:34:51 +0700270 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 +0200271
Chris Kayfab6edc2022-11-17 19:18:32 +0000272 if [ ! -z "${port}" ]; then
273 echo "${port}" > "$uart_dir/port"
274 fi
275
Fathi Boudra422bf772019-12-02 11:10:16 +0200276 # The run script assumes UART0 to be primary. If we're asked to set any
277 # other UART to be primary, set a run environment variable to signal
278 # that to the run script
279 if upon "$set_primary"; then
280 echo "Primary UART set to UART$uart."
281 set_run_env "primary_uart" "$uart"
282 fi
Madhukar Pappireddy1e953722021-11-08 15:23:02 -0600283
284 # UART used by payload(such as tftf, Linux) may not be the same as the
285 # primary UART. Set a run environment variable to track the payload
286 # UART which is tracked to check if the test has finished sucessfully.
287 if upon "$set_payload_uart"; then
288 echo "Payload uses UART$uart."
289 set_run_env "payload_uart" "$uart"
290 fi
Fathi Boudra422bf772019-12-02 11:10:16 +0200291}
292
293# Extract a FIP in $1 using fiptool
294extract_fip() {
295 local fip="$1"
296
297 if is_url "$1"; then
298 url="$1" fetch_file
299 fip="$(basename "$1")"
300 fi
301
Boyan Karatotevde2cd442025-07-28 09:50:29 +0100302 fiptool=$(fiptool_path)
Fathi Boudra422bf772019-12-02 11:10:16 +0200303 "$fiptool" unpack "$fip"
304 echo "Extracted FIP: $fip"
305}
306
307# Report build failure by printing a the tail end of build log. Archive the
308# build log for later inspection
309fail_build() {
310 local log_path
311
312 if upon "$jenkins_run"; then
313 log_path="$BUILD_URL/artifact/artefacts/build.log"
314 else
315 log_path="$build_log"
316 fi
317
318 echo
Boyan Karatotev7c0b09d2025-08-27 16:02:26 +0100319 echo "Build failed!"
Fathi Boudra422bf772019-12-02 11:10:16 +0200320 echo
321 echo "See $log_path for full output"
322 echo
323 cp -t "$archive" "$build_log"
324 exit 1;
325}
326
327# Build a FIP with supplied arguments
328build_fip() {
329 (
330 echo "Building FIP with arguments: $@"
331 local tf_env="$workspace/tf.env"
332
333 if [ -f "$tf_env" ]; then
334 set -a
335 source "$tf_env"
336 set +a
337 fi
338
Slava Andrianov192ee172025-06-11 15:40:43 -0500339 if [ "$(get_tf_opt MEASURED_BOOT)" = 1 ]; then
340 # These are needed for accurate hash verification
341 local build_args_path="${workspace}/fip_build_args"
342 echo $@ > $build_args_path
343 archive_file $build_args_path
344 fi
345
Boyan Karatotev99e12312025-05-02 15:00:24 +0100346 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 +0200347 ${fip_targets:-fip} &>>"$build_log" || fail_build
348 )
349}
350
Sandrine Bailleux189fdb32023-10-20 13:41:22 +0200351# Build any extra rule from TF-A makefile with supplied arguments.
352#
353# This is useful in case you need to build something else than firmware binaries
354# or the FIP.
355build_tf_extra() {
356 (
357 tf_extra_rules=${tf_extra_rules:?}
358 echo "Building extra TF rule(s): $tf_extra_rules"
359 echo " Arguments: $@"
360
361 local tf_env="$workspace/tf.env"
362
363 if [ -f "$tf_env" ]; then
364 set -a
365 source "$tf_env"
366 set +a
367 fi
368
Boyan Karatotev99e12312025-05-02 15:00:24 +0100369 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 +0200370 ${tf_extra_rules} &>>"$build_log" || fail_build
371 )
372}
373
Fathi Boudra422bf772019-12-02 11:10:16 +0200374fip_update() {
Boyan Karatotevde2cd442025-07-28 09:50:29 +0100375 fiptool=$(fiptool_path)
Fathi Boudra422bf772019-12-02 11:10:16 +0200376 # Before the update process, check if the given image is supported by
377 # the fiptool. It's assumed that both fiptool and cert_create move in
Chris Kay197b1022023-08-16 21:31:41 +0100378 # tandem, and therefore, if one has support, the other has it too.
379 if ! ("$fiptool" update 2>&1 || true) | grep -qe "\s\+--${bin_name:?}"; then
Fathi Boudra422bf772019-12-02 11:10:16 +0200380 return 1
381 fi
382
383 if not_upon "$(get_tf_opt TRUSTED_BOARD_BOOT)"; then
384 echo "Updating FIP image: $bin_name"
385 # Update HW config. Without TBBR, it's only a matter of using
386 # the update sub-command of fiptool
387 "$fiptool" update "--$bin_name" "${src:-}" \
388 "$archive/fip.bin"
389 else
390 echo "Updating FIP image (TBBR): $bin_name"
391 # With TBBR, we need to unpack, re-create certificates, and then
392 # recreate the FIP.
393 local fip_dir="$(mktempdir)"
394 local bin common_args stem
395 local rot_key="$(get_tf_opt ROT_KEY)"
396
397 rot_key="${rot_key:?}"
398 if ! is_abs "$rot_key"; then
399 rot_key="$tf_root/$rot_key"
400 fi
401
402 # Arguments only for cert_create
403 local cert_args="-n"
404 cert_args+=" --tfw-nvctr ${nvctr:-31}"
405 cert_args+=" --ntfw-nvctr ${nvctr:-223}"
406 cert_args+=" --key-alg ${KEY_ALG:-rsa}"
407 cert_args+=" --rot-key $rot_key"
408
409 local dyn_config_opts=(
Zelalem1af7a7b2020-08-04 17:34:32 -0500410 "fw-config"
Fathi Boudra422bf772019-12-02 11:10:16 +0200411 "hw-config"
412 "tb-fw-config"
413 "nt-fw-config"
414 "soc-fw-config"
415 "tos-fw-config"
416 )
417
418 # Binaries without key certificates
419 declare -A has_no_key_cert
420 for bin in "tb-fw" "${dyn_config_opts[@]}"; do
421 has_no_key_cert["$bin"]="1"
422 done
423
424 # Binaries without certificates
425 declare -A has_no_cert
426 for bin in "hw-config" "${dyn_config_opts[@]}"; do
427 has_no_cert["$bin"]="1"
428 done
429
430 pushd "$fip_dir"
431
432 # Unpack FIP
433 "$fiptool" unpack "$archive/fip.bin" &>>"$build_log"
434
435 # Remove all existing certificates
436 rm -f *-cert.bin
437
438 # Copy the binary to be updated
439 cp -f "$src" "${bin_name}.bin"
440
441 # FIP unpack dumps binaries with the same name as the option
442 # used to pack it; likewise for certificates. Reverse-engineer
443 # the command line from the binary output.
444 common_args="--trusted-key-cert trusted_key.crt"
445 for bin in *.bin; do
446 stem="${bin%%.bin}"
447 common_args+=" --$stem $bin"
448 if not_upon "${has_no_cert[$stem]}"; then
449 common_args+=" --$stem-cert $stem.crt"
450 fi
451 if not_upon "${has_no_key_cert[$stem]}"; then
452 common_args+=" --$stem-key-cert $stem-key.crt"
453 fi
454 done
455
456 # Create certificates
Boyan Karatotevde2cd442025-07-28 09:50:29 +0100457 cert_create=$(cert_create_path)
Fathi Boudra422bf772019-12-02 11:10:16 +0200458 "$cert_create" $cert_args $common_args &>>"$build_log"
459
460 # Recreate and archive FIP
461 "$fiptool" create $common_args "fip.bin" &>>"$build_log"
462 archive_file "fip.bin"
463
464 popd
465 fi
466}
467
468# Update hw-config in FIP, and remove the original DTB afterwards.
469update_fip_hw_config() {
470 # The DTB needs to be loaded by the model (and not updated in the FIP)
Madhukar Pappireddy9062ebf2021-03-02 17:07:06 -0600471 # in configs:
472 # 1. Where BL2 isn't present
473 # 2. Where we boot to Linux directly as BL33
Fathi Boudra422bf772019-12-02 11:10:16 +0200474 case "1" in
475 "$(get_tf_opt RESET_TO_BL31)" | \
Madhukar Pappireddy9062ebf2021-03-02 17:07:06 -0600476 "$(get_tf_opt ARM_LINUX_KERNEL_AS_BL33)" | \
Fathi Boudra422bf772019-12-02 11:10:16 +0200477 "$(get_tf_opt RESET_TO_SP_MIN)" | \
Maksims Svecovs7a0da522023-03-06 16:28:27 +0000478 "$(get_tf_opt RESET_TO_BL2)")
Fathi Boudra422bf772019-12-02 11:10:16 +0200479 return 0;;
480 esac
481
482 if bin_name="hw-config" src="$archive/dtb.bin" fip_update; then
483 # Remove the DTB so that model won't load it
484 rm -f "$archive/dtb.bin"
485 fi
486}
487
Fathi Boudra422bf772019-12-02 11:10:16 +0200488get_tftf_opt() {
489 (
490 name="${1:?}"
491 if config_valid "$tftf_config_file"; then
492 source "$tftf_config_file"
493 echo "${!name}"
494 fi
495 )
496}
497
498get_tf_opt() {
499 (
500 name="${1:?}"
501 if config_valid "$tf_config_file"; then
502 source "$tf_config_file"
503 echo "${!name}"
504 fi
505 )
506}
507
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +0000508get_rmm_opt() {
509 (
510 name="${1:?}"
Manish V Badarkhea3505272025-04-17 14:20:42 +0100511 default="$2"
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +0000512 if config_valid "$rmm_config_file"; then
513 source "$rmm_config_file"
Manish V Badarkhea3505272025-04-17 14:20:42 +0100514 # If !name is not defined, go with the default
515 # value (if defined)
516 if [ -z "${!name}" ]; then
517 echo "$default"
518 else
519 echo "${!name}"
520 fi
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +0000521 fi
522 )
523}
524
Fathi Boudra422bf772019-12-02 11:10:16 +0200525build_tf() {
526 (
527 env_file="$workspace/tf.env"
528 config_file="${tf_build_config:-$tf_config_file}"
529
530 # Build fiptool and all targets by default
Harrison Mutai32de9d02023-06-12 14:23:37 +0100531 build_targets="${tf_build_targets:-fiptool all}"
Fathi Boudra422bf772019-12-02 11:10:16 +0200532
533 source "$config_file"
534
535 # If it is a TBBR build, extract the MBED TLS library from archive
Manish V Badarkhe8f125012021-12-21 05:47:52 +0000536 if [ "$(get_tf_opt TRUSTED_BOARD_BOOT)" = 1 ] ||
Manish V Badarkhef43e3f52022-06-21 20:37:25 +0100537 [ "$(get_tf_opt MEASURED_BOOT)" = 1 ] ||
538 [ "$(get_tf_opt DRTM_SUPPORT)" = 1 ]; then
Fathi Boudra422bf772019-12-02 11:10:16 +0200539 mbedtls_dir="$workspace/mbedtls"
540 if [ ! -d "$mbedtls_dir" ]; then
541 mbedtls_ar="$workspace/mbedtls.tar.gz"
542
543 url="$mbedtls_archive" saveas="$mbedtls_ar" fetch_file
544 mkdir "$mbedtls_dir"
Leonardo Sandovalec9e16c2020-09-09 14:32:40 -0500545 extract_tarball $mbedtls_ar $mbedtls_dir --strip-components=1
Fathi Boudra422bf772019-12-02 11:10:16 +0200546 fi
547
548 emit_env "MBEDTLS_DIR" "$mbedtls_dir"
549 fi
Jimmy Brisson0d5e12c2023-05-16 14:51:51 -0500550 if [ "$(get_tf_opt PLATFORM_TEST)" = "tfm-testsuite" ] &&
551 not_upon "${TF_M_TESTS_PATH}"; then
552 emit_env "TF_M_TESTS_PATH" "$WORKSPACE/tf-m-tests"
553 fi
554 if [ "$(get_tf_opt PLATFORM_TEST)" = "tfm-testsuite" ] &&
555 not_upon "${TF_M_EXTRAS_PATH}"; then
556 emit_env "TF_M_EXTRAS_PATH" "$WORKSPACE/tf-m-extras"
557 fi
David Vincze82db6932024-02-21 12:05:50 +0100558 if [ "$(get_tf_opt DICE_PROTECTION_ENVIRONMENT)" = 1 ] &&
559 not_upon "${QCBOR_DIR}"; then
560 emit_env "QCBOR_DIR" "$WORKSPACE/qcbor"
561 fi
Slava Andrianov192ee172025-06-11 15:40:43 -0500562
563 # Hash verification only occurs if there is a sufficient amount of
564 # information in the event log, which is as long as EVENT_LOG_LEVEL
565 # is set to at least 20 or if it is a debug build
566 if [[ ("$(get_tf_opt MEASURED_BOOT)" -eq 1) &&
567 (($bin_mode == "debug") || ("$(get_tf_opt EVENT_LOG_LEVEL)" -ge 20)) ]]; then
568 # This variable is later exported to the expect scripts so
569 # the hashes in the TF-A event log can be verified
570 set_run_env "verify_hashes" "1"
571 fi
Fathi Boudra422bf772019-12-02 11:10:16 +0200572 if [ -f "$env_file" ]; then
573 set -a
574 source "$env_file"
575 set +a
576 fi
577
Harrison Mutai013f6332022-02-16 16:06:33 +0000578 if is_arm_jenkins_env || upon "$local_ci"; then
579 path_list=(
580 "$llvm_dir/bin"
581 )
582 extend_path "PATH" "path_list"
583 fi
584
Boyan Karatotev97de8d82025-03-06 15:22:21 +0000585 pushd "$tf_root"
Fathi Boudra422bf772019-12-02 11:10:16 +0200586
587 # Always distclean when running on Jenkins. Skip distclean when running
588 # locally and explicitly requested.
589 if upon "$jenkins_run" || not_upon "$dont_clean"; then
Boyan Karatotev97de8d82025-03-06 15:22:21 +0000590 make distclean BUILD_BASE=$tf_build_root &>>"$build_log" || fail_build
Fathi Boudra422bf772019-12-02 11:10:16 +0200591 fi
592
593 # Log build command line. It is left unfolded on purpose to assist
594 # copying to clipboard.
595 cat <<EOF | log_separator >/dev/null
596
597Build command line:
Boyan Karatotev97de8d82025-03-06 15:22:21 +0000598 $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 +0200599
Paul Sokolovsky7f71b072023-10-16 12:59:09 +0300600CC version:
601$(${CC-${CROSS_COMPILE}gcc} -v 2>&1)
Fathi Boudra422bf772019-12-02 11:10:16 +0200602EOF
603
Javier Almansa Sobrinoe8363182020-11-10 16:40:53 +0000604 if not_upon "$local_ci"; then
605 connect_debugger=0
606 fi
607
Fathi Boudra422bf772019-12-02 11:10:16 +0200608 # Build TF. Since build output is being directed to the build log, have
609 # descriptor 3 point to the current terminal for build wrappers to vent.
Harrison Mutai6361dbe2023-02-16 14:12:40 +0000610 $tf_build_wrapper poetry run make $make_j_opts $(cat "$config_file") \
Boyan Karatotev97de8d82025-03-06 15:22:21 +0000611 DEBUG="$DEBUG" V=1 BUILD_BASE="$tf_build_root" SPIN_ON_BL1_EXIT="$connect_debugger" \
Fathi Boudra422bf772019-12-02 11:10:16 +0200612 $build_targets 3>&1 &>>"$build_log" || fail_build
Harrison Mutai32de9d02023-06-12 14:23:37 +0100613
Harrison Mutai6dafb5f2023-07-18 15:21:48 +0100614 if [ "$build_targets" != "doc" ]; then
Chris Kay9ab2d952025-05-29 13:46:24 +0100615 (poetry run memory --root "$tf_build_root" symbols 2>&1 || true) | tee -a "${build_log}"
616
617 for map in $(find "${tf_build_root}" -name '*.map'); do
618 (poetry run memory --root "${tf_build_root}" summary "${map}" 2>&1 || true) | tee -a "${build_log}"
619 done
Harrison Mutai6dafb5f2023-07-18 15:21:48 +0100620 fi
Boyan Karatotev97de8d82025-03-06 15:22:21 +0000621 popd
Fathi Boudra422bf772019-12-02 11:10:16 +0200622 )
623}
624
625build_tftf() {
626 (
627 config_file="${tftf_build_config:-$tftf_config_file}"
628
629 # Build tftf target by default
630 build_targets="${tftf_build_targets:-all}"
631
632 source "$config_file"
633
634 cd "$tftf_root"
635
636 # Always distclean when running on Jenkins. Skip distclean when running
637 # locally and explicitly requested.
638 if upon "$jenkins_run" || not_upon "$dont_clean"; then
Boyan Karatotev97de8d82025-03-06 15:22:21 +0000639 make distclean BUILD_BASE="$tftf_build_root" &>>"$build_log" || fail_build
Fathi Boudra422bf772019-12-02 11:10:16 +0200640 fi
641
642 # TFTF build system cannot reliably deal with -j option, so we avoid
643 # using that.
644
645 # Log build command line
646 cat <<EOF | log_separator >/dev/null
647
648Build command line:
Boyan Karatotev97de8d82025-03-06 15:22:21 +0000649 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 +0200650
651EOF
652
Boyan Karatotev97de8d82025-03-06 15:22:21 +0000653 make $make_j_opts $(cat "$config_file") DEBUG="$DEBUG" V=1 BUILD_BASE="$tftf_build_root" \
Fathi Boudra422bf772019-12-02 11:10:16 +0200654 $build_targets &>>"$build_log" || fail_build
655 )
656}
657
Zelalem219df412020-05-17 19:21:20 -0500658build_cc() {
659# Building code coverage plugin
660 ARM_DIR=/arm
661 pvlibversion=$(/arm/devsys-tools/abs/detag "SysGen:PVModelLib:$model_version::trunk")
662 PVLIB_HOME=$warehouse/SysGen/PVModelLib/$model_version/${pvlibversion}/external
663 if [ -n "$(find "$ARM_DIR" -maxdepth 0 -type d -empty 2>/dev/null)" ]; then
664 echo "Error: Arm warehouse not mounted. Please mount the Arm warehouse to your /arm local folder"
665 exit -1
666 fi # Error if arm warehouse not found
667 cd "$ccpathspec/scripts/tools/code_coverage/fastmodel_baremetal/bmcov"
668
669 make -C model-plugin PVLIB_HOME=$PVLIB_HOME &>>"$build_log"
670}
671
Olivier Deprez0a9a3482019-12-16 14:10:31 +0100672build_spm() {
673 (
674 env_file="$workspace/spm.env"
675 config_file="${spm_build_config:-$spm_config_file}"
676
677 source "$config_file"
678
679 if [ -f "$env_file" ]; then
680 set -a
681 source "$env_file"
682 set +a
683 fi
684
685 cd "$spm_root"
686
687 # Always clean when running on Jenkins. Skip clean when running
688 # locally and explicitly requested.
689 if upon "$jenkins_run" || not_upon "$dont_clean"; then
690 # make clean fails on a fresh repo where the project has not
691 # yet been built. Hence only clean if out/reference directory
692 # already exists.
693 if [ -d "out/reference" ]; then
694 make clean &>>"$build_log" || fail_build
695 fi
696 fi
697
698 # Log build command line. It is left unfolded on purpose to assist
699 # copying to clipboard.
700 cat <<EOF | log_separator >/dev/null
701
702Build command line:
Boyan Karatotev27057342025-07-28 09:56:23 +0100703 make $make_j_opts OUT=$spm_build_root $(cat "$config_file" | tr '\n' ' ')
Olivier Deprez0a9a3482019-12-16 14:10:31 +0100704
705EOF
706
707 # Build SPM. Since build output is being directed to the build log, have
708 # descriptor 3 point to the current terminal for build wrappers to vent.
Boyan Karatotev27057342025-07-28 09:56:23 +0100709 make $make_j_opts OUT=$spm_build_root $(cat "$config_file") 3>&1 &>>"$build_log" \
Olivier Deprez0a9a3482019-12-16 14:10:31 +0100710 || fail_build
711 )
712}
Zelalem219df412020-05-17 19:21:20 -0500713
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +0000714build_rmm() {
715 (
716 env_file="$workspace/rmm.env"
717 config_file="${rmm_build_config:-$rmm_config_file}"
718
719 # Build fiptool and all targets by default
Manish V Badarkhe8cbbabf2025-08-20 11:27:12 +0100720 export CROSS_COMPILE="aarch64-none-elf-"
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +0000721
722 source "$config_file"
723
724 if [ -f "$env_file" ]; then
725 set -a
726 source "$env_file"
727 set +a
728 fi
729
730 cd "$rmm_root"
731
732 if [ -f "$rmm_root/requirements.txt" ]; then
733 export PATH="$HOME/.local/bin:$PATH"
734 python3 -m pip install --upgrade pip
735 python3 -m pip install -r "$rmm_root/requirements.txt"
736 fi
737
738 # Always distclean when running on Jenkins. Skip distclean when running
739 # locally and explicitly requested.
740 if upon "$jenkins_run" || not_upon "$dont_clean"; then
741 # Remove 'rmm\build' folder
742 echo "Removing $rmm_build_root..."
743 rm -rf $rmm_build_root
744 fi
745
Manish V Badarkhea3505272025-04-17 14:20:42 +0100746 if not_upon "$local_ci"; then
747 connect_debugger=0
748 fi
749
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +0000750 # Log build command line. It is left unfolded on purpose to assist
751 # copying to clipboard.
752 cat <<EOF | log_separator >/dev/null
753
754Build command line:
Manish V Badarkhea3505272025-04-17 14:20:42 +0100755 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}
756 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 +0000757
Manish V Badarkhea3505272025-04-17 14:20:42 +0100758EOF
759 cmake \
760 -DRMM_CONFIG=${plat}_defcfg $cmake_gen \
761 -S $rmm_root -B $rmm_build_root \
762 -DRMM_TOOLCHAIN=$rmm_toolchain \
763 -DRMM_FPU_USE_AT_REL2=$rmm_fpu_use_at_rel2 \
764 -DATTEST_EL3_TOKEN_SIGN=$rmm_attest_el3_token_sign \
765 -DRMM_V1_1=$rmm_v1_1 \
766 ${extra_options}
767 cmake --build $rmm_build_root --config $cmake_build_type $make_j_opts -v ${extra_targets+-- $extra_targets} 3>&1 &>>"$build_log" || fail_build
768 )
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +0000769}
770
Juan Pablo Conde3feb7f12023-10-21 13:14:47 -0500771build_tfut() {
772 (
773 config_file="${tfut_build_config:-$tfut_config_file}"
774
775 # Build tfut target by default
776 build_targets="${tfut_build_targets:-all}"
777
778 source "$config_file"
779
780 mkdir -p "$tfut_root/build"
781 cd "$tfut_root/build"
782
783 # Always distclean when running on Jenkins. Skip distclean when running
784 # locally and explicitly requested.
785 if upon "$jenkins_run" || not_upon "$dont_clean"; then
786 #make clean &>>"$build_log" || fail_build
787 rm -Rf * || fail_build
788 fi
789
790 #Override build targets only if the run config did not set them.
791 if [ $build_targets == "all" ]; then
792 tests_line=$(cat "$config_file" | { grep "tests=" || :; })
793 if [ -z "$tests_line" ]; then
794 build_targets=$(echo "$tests_line" | awk -F= '{ print $NF }')
795 fi
796 fi
797
Juan Pablo Conde2ecf1862024-01-16 20:12:43 -0600798 #TODO: extract vars from env to use them for cmake
799
800 test -f "$config_file"
801
802 config=$(cat "$config_file" | grep -v "tests=") \
803 && cmake_config=$(echo "$config" | sed -e 's/^/\-D/')
Juan Pablo Conde3feb7f12023-10-21 13:14:47 -0500804
805 # Check if cmake is installed
806 if ! command -v cmake &> /dev/null
807 then
808 echo "cmake could not be found"
809 exit 1
810 fi
811
812 # Log build command line
813 cat <<EOF | log_separator >/dev/null
814
815Build command line:
Edward Potapovdb31e702025-06-30 16:28:40 -0500816cmake $(echo "$cmake_config") -G"Unix Makefiles" --debug-output -DCMAKE_VERBOSE_MAKEFILE -DCOVERAGE="$COVERAGE" -DUNIT_TEST_PROJECT_PATH="$tf_root" ..
Juan Pablo Conde3feb7f12023-10-21 13:14:47 -0500817 make $(echo "$config" | tr '\n' ' ') DEBUG=$DEBUG V=1 $build_targets
818
819EOF
820 cmake $(echo "$cmake_config") -G"Unix Makefiles" --debug-output \
821 -DCMAKE_VERBOSE_MAKEFILE=ON \
Edward Potapovdb31e702025-06-30 16:28:40 -0500822 -DCOVERAGE="$COVERAGE" \
Juan Pablo Conde3feb7f12023-10-21 13:14:47 -0500823 -DUNIT_TEST_PROJECT_PATH="$tf_root" \
824 .. &>> "$build_log" || fail_build
825 echo "Done with cmake" >> "$build_log"
826 make $(echo "$config") VERBOSE=1 \
827 $build_targets &>> "$build_log" || fail_build
828 )
829
830}
831
Fathi Boudra422bf772019-12-02 11:10:16 +0200832# Set metadata for the whole package so that it can be used by both Jenkins and
833# shell
834set_package_var() {
835 env_file="$artefacts/env" emit_env "$@"
836}
837
838set_tf_build_targets() {
839 echo "Set build target to '${targets:?}'"
840 set_hook_var "tf_build_targets" "$targets"
841}
842
843set_tftf_build_targets() {
844 echo "Set build target to '${targets:?}'"
845 set_hook_var "tftf_build_targets" "$targets"
846}
847
Olivier Deprez0a9a3482019-12-16 14:10:31 +0100848set_spm_build_targets() {
849 echo "Set build target to '${targets:?}'"
850 set_hook_var "spm_build_targets" "$targets"
851}
852
Juan Pablo Conde2ecf1862024-01-16 20:12:43 -0600853add_tfut_build_targets() {
854 echo "Add TFUT build targets '${targets:?}'"
855 append_hook_var "tfut_build_targets" "$targets "
Juan Pablo Conde3feb7f12023-10-21 13:14:47 -0500856}
857
Daniel Boulbyb8d2a462022-03-07 13:55:25 +0000858set_spm_out_dir() {
859 echo "Set SPMC binary build to '${out_dir:?}'"
860 set_hook_var "spm_secure_out_dir" "$out_dir"
861}
Fathi Boudra422bf772019-12-02 11:10:16 +0200862# Look under $archive directory for known files such as blX images, kernel, DTB,
863# initrd etc. For each known file foo, if foo.bin exists, then set variable
864# foo_bin to the path of the file. Make the path relative to the workspace so as
865# to remove any @ characters, which Jenkins inserts for parallel runs. If the
866# file doesn't exist, unset its path.
867set_default_bin_paths() {
868 local image image_name image_path path
869 local archive="${archive:?}"
870 local set_vars
871 local var
872
873 pushd "$archive"
874
875 for file in *.bin; do
876 # Get a shell variable from the file's stem
877 var_name="${file%%.*}_bin"
878 var_name="$(echo "$var_name" | sed -r 's/[^[:alnum:]]/_/g')"
879
880 # Skip setting the variable if it's already
881 if [ "${!var_name}" ]; then
882 echo "Note: not setting $var_name; already set to ${!var_name}"
883 continue
884 else
885 set_vars+="$var_name "
886 fi
887
888 eval "$var_name=$file"
889 done
890
891 echo "Binary paths set for: "
892 {
893 for var in $set_vars; do
894 echo -n "\$$var "
895 done
896 } | fmt -80 | sed 's/^/ /'
897 echo
898
899 popd
900}
901
902gen_model_params() {
903 local model_param_file="$archive/model_params"
Javier Almansa Sobrinoe8363182020-11-10 16:40:53 +0000904 [ "$connect_debugger" ] && [ "$connect_debugger" -eq 1 ] && wait_debugger=1
Fathi Boudra422bf772019-12-02 11:10:16 +0200905
906 set_default_bin_paths
907 echo "Generating model parameter for $model..."
908 source "$ci_root/model/${model:?}.sh"
909 archive_file "$model_param_file"
910}
911
912set_model_path() {
Govindraj Rajadc196f02025-07-31 16:10:15 -0500913 local input_path="${1:?}"
914
915 if upon "$retain_paths"; then
916 set_run_env "model_path" "$(basename "$input_path")"
917 return
918 fi
919
920 set_run_env "model_path" "$input_path"
Fathi Boudra422bf772019-12-02 11:10:16 +0200921}
922
Zelalem1af7a7b2020-08-04 17:34:32 -0500923set_model_env() {
924 local var="${1:?}"
925 local val="${2?}"
926 local run_root="${archive:?}/run"
927
928 mkdir -p "$run_root"
929 echo "export $var=$val" >> "$run_root/model_env"
930}
Fathi Boudra422bf772019-12-02 11:10:16 +0200931set_run_env() {
932 local var="${1:?}"
933 local val="${2?}"
934 local run_root="${archive:?}/run"
935
936 mkdir -p "$run_root"
937 env_file="$run_root/env" quote="1" emit_env "$var" "$val"
938}
939
940show_head() {
941 # Display HEAD descripton
942 pushd "$1"
943 git show --quiet --no-color | sed 's/^/ > /g'
944 echo
945 popd
946}
947
948# Choose debug binaries to run; by default, release binaries are chosen to run
949use_debug_bins() {
950 local run_root="${archive:?}/run"
951
952 echo "Choosing debug binaries for execution"
953 set_package_var "BIN_MODE" "debug"
954}
955
956assert_can_git_clone() {
957 local name="${1:?}"
958 local dir="${!name}"
959
960 # If it doesn't exist, it can be cloned into
961 if [ ! -e "$dir" ]; then
962 return 0
963 fi
964
965 # If it's a directory, it must be a Git clone already
966 if [ -d "$dir" ] && [ -d "$dir/.git" ]; then
967 # No need to clone again
968 echo "Using existing git clone for $name: $dir"
969 return 1
970 fi
971
972 die "Path $dir exists but is not a git clone"
973}
974
975clone_repo() {
976 if ! is_url "${clone_url?}"; then
977 # For --depth to take effect on local paths, it needs to use the
978 # file:// scheme.
979 clone_url="file://$clone_url"
980 fi
981
982 git clone -q --depth 1 "$clone_url" "${where?}"
983 if [ "$refspec" ]; then
984 pushd "$where"
985 git fetch -q --depth 1 origin "$refspec"
986 git checkout -q FETCH_HEAD
987 popd
988 fi
989}
990
991build_unstable() {
992 echo "--BUILD UNSTABLE--" | tee -a "$build_log"
993}
994
995undo_patch_record() {
996 if [ ! -f "${patch_record:?}" ]; then
997 return
998 fi
999
1000 # Undo patches in reverse
1001 echo
1002 for patch_name in $(tac "$patch_record"); do
1003 echo "Undoing $patch_name..."
1004 if ! git apply -R "$ci_root/patch/$patch_name"; then
1005 if upon "$local_ci"; then
1006 echo
1007 echo "Your local directory may have been dirtied."
1008 echo
1009 fi
1010 fail_build
1011 fi
1012 done
1013
1014 rm -f "$patch_record"
1015}
1016
1017undo_local_patches() {
1018 pushd "$tf_root"
1019 patch_record="$tf_patch_record" undo_patch_record
1020 popd
1021
1022 if [ -d "$tftf_root" ]; then
1023 pushd "$tftf_root"
1024 patch_record="$tftf_patch_record" undo_patch_record
1025 popd
1026 fi
1027}
1028
1029undo_tftf_patches() {
1030 pushd "$tftf_root"
1031 patch_record="$tftf_patch_record" undo_patch_record
1032 popd
1033}
1034
1035undo_tf_patches() {
1036 pushd "$tf_root"
1037 patch_record="$tf_patch_record" undo_patch_record
1038 popd
1039}
1040
1041apply_patch() {
1042 # If skip_patches is set, the developer has applied required patches
1043 # manually. They probably want to keep them applied for debugging
1044 # purposes too. This means we don't have to apply/revert them as part of
1045 # build process.
1046 if upon "$skip_patches"; then
1047 echo "Skipped applying ${1:?}..."
1048 return 0
1049 else
1050 echo "Applying ${1:?}..."
1051 fi
1052
Sandrine Bailleux4cb8c222023-09-13 13:48:15 +02001053 if git apply --reverse --check < "$ci_root/patch/$1" 2> /dev/null; then
Jimmy Brissonf134e4c2023-03-22 13:20:20 -05001054 echo "Skipping already applied ${1:?}"
1055 return 0
1056 fi
1057
Fathi Boudra422bf772019-12-02 11:10:16 +02001058 if git apply < "$ci_root/patch/$1"; then
1059 echo "$1" >> "${patch_record:?}"
1060 else
1061 if upon "$local_ci"; then
1062 undo_local_patches
1063 fi
1064 fail_build
1065 fi
1066}
1067
Fathi Boudra422bf772019-12-02 11:10:16 +02001068apply_tf_patch() {
Boyan Karatotevfaf9a9d2025-07-28 09:52:05 +01001069 root="$tf_root"
1070 new_root="$archive/tfa_mirror"
1071
1072 # paralell builds are only used locally. Don't do for CI since this will
1073 # have a speed penalty. Also skip if this was already done as a single
1074 # job may apply many patches.
1075 if upon "$local_ci" && [[ ! -d $new_root ]]; then
1076 root=$new_root
1077 diff=$(mktempfile)
1078
1079 # get anything still uncommitted
1080 pushd $tf_root
1081 git diff HEAD > $diff
1082 popd
1083
1084 # git will hard link when cloning locally, no need for --depth=1
Boyan Karatotevf1ba4d42025-09-25 11:37:21 +01001085 git clone "$tf_root" $root --shallow-submodules --recurse-submodules
Boyan Karatotevfaf9a9d2025-07-28 09:52:05 +01001086
1087 tf_root=$root # next apply_tf_patch will run in the same hook
1088 set_hook_var "tf_root" "$root" # for anyone outside the hook
1089
1090 # apply uncommited changes so they are picked up in the build
1091 pushd $tf_root
1092 git apply $diff &> /dev/null || true
1093 popd
1094
1095 fi
1096
1097 pushd "$root"
Fathi Boudra422bf772019-12-02 11:10:16 +02001098 patch_record="$tf_patch_record" apply_patch "$1"
1099 popd
1100}
1101
Fathi Boudra422bf772019-12-02 11:10:16 +02001102mkdir -p "$workspace"
1103mkdir -p "$archive"
1104set_package_var "TEST_CONFIG" "$test_config"
1105
1106{
1107echo
1108echo "CONFIGURATION: $test_group/$test_config"
1109echo
1110} |& log_separator
1111
1112tf_config="$(echo "$build_configs" | awk -F, '{print $1}')"
1113tftf_config="$(echo "$build_configs" | awk -F, '{print $2}')"
Chris Kay4f7846a2025-08-04 19:56:35 +01001114spm_config="$(echo "$build_configs" | awk -F, '{print $3}')"
1115rmm_config="$(echo "$build_configs" | awk -F, '{print $4}')"
Juan Pablo Conde3feb7f12023-10-21 13:14:47 -05001116tfut_config="$(echo "$build_configs" | awk -F, '{print $5}')"
Fathi Boudra422bf772019-12-02 11:10:16 +02001117
1118test_config_file="$ci_root/group/$test_group/$test_config"
1119
1120tf_config_file="$ci_root/tf_config/$tf_config"
1121tftf_config_file="$ci_root/tftf_config/$tftf_config"
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001122spm_config_file="$ci_root/spm_config/$spm_config"
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +00001123rmm_config_file="$ci_root/rmm_config/$rmm_config"
Juan Pablo Conde3feb7f12023-10-21 13:14:47 -05001124tfut_config_file="$ci_root/tfut_config/$tfut_config"
Fathi Boudra422bf772019-12-02 11:10:16 +02001125
1126# File that keeps track of applied patches
1127tf_patch_record="$workspace/tf_patches"
1128tftf_patch_record="$workspace/tftf_patches"
1129
Juan Pablo Conde84bf39f2024-01-12 22:09:49 -06001130# Split run config into TF and TFUT components
1131run_config_tfa="$(echo "$run_config" | awk -F, '{print $1}')"
1132run_config_tfut="$(echo "$run_config" | awk -F, '{print $2}')"
1133
Fathi Boudra422bf772019-12-02 11:10:16 +02001134pushd "$workspace"
1135
1136if ! config_valid "$tf_config"; then
1137 tf_config=
1138else
1139 echo "Trusted Firmware config:"
1140 echo
1141 sort "$tf_config_file" | sed '/^\s*$/d;s/^/\t/'
1142 echo
1143fi
1144
1145if ! config_valid "$tftf_config"; then
1146 tftf_config=
1147else
1148 echo "Trusted Firmware TF config:"
1149 echo
1150 sort "$tftf_config_file" | sed '/^\s*$/d;s/^/\t/'
1151 echo
1152fi
1153
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001154if ! config_valid "$spm_config"; then
1155 spm_config=
1156else
1157 echo "SPM config:"
1158 echo
1159 sort "$spm_config_file" | sed '/^\s*$/d;s/^/\t/'
Zelalem219df412020-05-17 19:21:20 -05001160 echo
1161fi
1162
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +00001163# File that keeps track of applied patches
1164rmm_patch_record="$workspace/rmm_patches"
1165
1166if ! config_valid "$rmm_config"; then
1167 rmm_config=
1168else
1169 echo "Trusted Firmware RMM config:"
1170 echo
1171 sort "$rmm_config_file" | sed '/^\s*$/d;s/^/\t/'
1172 echo
1173fi
1174
Juan Pablo Conde3feb7f12023-10-21 13:14:47 -05001175if ! config_valid "$tfut_config"; then
1176 tfut_config=
1177else
1178 echo "TFUT config:"
1179 echo
1180 sort "$tfut_config_file" | sed '/^\s*$/d;s/^/\t/'
1181 echo
1182fi
1183
Juan Pablo Conde84bf39f2024-01-12 22:09:49 -06001184if ! config_valid "$run_config_tfa"; then
1185 run_config_tfa=
Fathi Boudra422bf772019-12-02 11:10:16 +02001186fi
1187
Juan Pablo Conde3feb7f12023-10-21 13:14:47 -05001188if { [ "$tf_config" ] || [ "$tfut_config" ]; } && assert_can_git_clone "tf_root"; then
Fathi Boudra422bf772019-12-02 11:10:16 +02001189 # If the Trusted Firmware repository has already been checked out, use
1190 # that location. Otherwise, clone one ourselves.
1191 echo "Cloning Trusted Firmware..."
1192 clone_url="${TF_CHECKOUT_LOC:-$tf_src_repo_url}" where="$tf_root" \
1193 refspec="$TF_REFSPEC" clone_repo &>>"$build_log"
1194 show_head "$tf_root"
1195fi
1196
1197if [ "$tftf_config" ] && assert_can_git_clone "tftf_root"; then
1198 # If the Trusted Firmware TF repository has already been checked out,
1199 # use that location. Otherwise, clone one ourselves.
1200 echo "Cloning Trusted Firmware TF..."
1201 clone_url="${TFTF_CHECKOUT_LOC:-$tftf_src_repo_url}" where="$tftf_root" \
1202 refspec="$TFTF_REFSPEC" clone_repo &>>"$build_log"
1203 show_head "$tftf_root"
1204fi
1205
Zelalem219df412020-05-17 19:21:20 -05001206if [ -n "$cc_config" ] ; then
1207 if [ "$cc_config" -eq 1 ] && assert_can_git_clone "cc_root"; then
1208 # Copy code coverage repository
1209 echo "Cloning Code Coverage..."
1210 git clone -q $cc_src_repo_url cc_plugin --depth 1 -b $cc_src_repo_tag > /dev/null
1211 show_head "$cc_root"
1212 fi
1213fi
1214
Daniel Boulby25385ab2023-12-14 14:36:25 +00001215if [ "$spm_config" ] ; then
1216 if assert_can_git_clone "spm_root"; then
1217 # If the SPM repository has already been checked out, use
1218 # that location. Otherwise, clone one ourselves.
1219 echo "Cloning SPM..."
1220 clone_url="${SPM_CHECKOUT_LOC:-$spm_src_repo_url}" \
1221 where="$spm_root" refspec="$SPM_REFSPEC" \
1222 clone_repo &>>"$build_log"
1223 fi
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001224
1225 # Query git submodules
1226 pushd "$spm_root"
Daniel Boulby25385ab2023-12-14 14:36:25 +00001227 # Check if submodules need initialising
Paul Sokolovskyad274422024-09-01 10:27:56 +03001228
1229 # This handling is needed to reliably fetch submodules
1230 # in CI environment.
1231 for subm in $(git submodule status | awk '/^-/ {print $2}'); do
1232 for i in $(seq 1 7); do
1233 git submodule init $subm
1234 if git submodule update $subm; then
1235 break
1236 fi
1237 git submodule deinit --force $subm
1238 echo "Retrying $subm"
1239 sleep $((RANDOM % 10 + 5))
1240 done
1241 done
1242
1243 git submodule status
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001244 popd
1245
1246 show_head "$spm_root"
1247fi
1248
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +00001249if [ "$rmm_config" ] && assert_can_git_clone "rmm_root"; then
Manish V Badarkhe41909452025-04-11 12:06:45 +01001250 # If the RMM repository has already been checked out,
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +00001251 # use that location. Otherwise, clone one ourselves.
1252 echo "Cloning TF-RMM..."
1253 clone_url="${RMM_CHECKOUT_LOC:-$rmm_src_repo_url}" where="$rmm_root" \
1254 refspec="$RMM_REFSPEC" clone_repo &>>"$build_log"
1255 show_head "$rmm_root"
1256fi
1257
Juan Pablo Conde3feb7f12023-10-21 13:14:47 -05001258if [ "$tfut_config" ] && assert_can_git_clone "tfut_root"; then
1259 # If the Trusted Firmware UT repository has already been checked out,
1260 # use that location. Otherwise, clone one ourselves.
1261 echo "Cloning Trusted Firmware UT..."
1262 clone_url="${TFUT_CHECKOUT_LOC:-$tfut_src_repo_url}" where="$tfut_root" \
1263 refspec="$TFUT_GERRIT_REFSPEC" clone_repo &>>"$build_log"
1264 show_head "$tfut_root"
1265fi
1266
Juan Pablo Conde84bf39f2024-01-12 22:09:49 -06001267if [ "$run_config_tfa" ]; then
1268 # Get candidates for TF-A run config
Nicola Mazzucato7fc5abd2024-02-23 21:32:48 +00001269 run_config_candidates="$("$ci_root/script/gen_run_config_candidates.py" \
Juan Pablo Conde84bf39f2024-01-12 22:09:49 -06001270 "$run_config_tfa")"
Nicola Mazzucato7fc5abd2024-02-23 21:32:48 +00001271 if [ -z "$run_config_candidates" ]; then
Fathi Boudra422bf772019-12-02 11:10:16 +02001272 die "No run config candidates!"
1273 else
1274 echo
1275 echo "Chosen fragments:"
1276 echo
Nicola Mazzucato7fc5abd2024-02-23 21:32:48 +00001277 echo "$run_config_candidates" | sed 's/^\|\n/\t/g'
Fathi Boudra422bf772019-12-02 11:10:16 +02001278 echo
Harrison Mutai4dfe1192024-07-03 12:35:38 +00001279
1280 if [ ! -n "$bin_mode" ]; then
1281 if echo $run_config_candidates | grep -wq "debug"; then
1282 bin_mode="debug"
1283 else
1284 bin_mode="release"
1285 fi
1286 fi
Fathi Boudra422bf772019-12-02 11:10:16 +02001287 fi
1288fi
1289
Juan Pablo Conde2ecf1862024-01-16 20:12:43 -06001290if [ "$run_config_tfut" ]; then
1291 # Get candidates for run TFUT config
1292 run_config_tfut_candidates="$("$ci_root/script/gen_run_config_candidates.py" \
1293 "--unit-testing" "$run_config_tfut")"
1294 if [ -z "$run_config_tfut_candidates" ]; then
1295 die "No run TFUT config candidates!"
1296 else
1297 echo
1298 echo "Chosen fragments:"
1299 echo
1300 echo "$run_config_tfut_candidates" | sed 's/^\|\n/\t/g'
1301 fi
1302fi
1303
Fathi Boudra422bf772019-12-02 11:10:16 +02001304call_hook "test_setup"
1305echo
1306
1307if upon "$local_ci"; then
1308 # For local runs, since each config is tried in sequence, it's
1309 # advantageous to run jobs in parallel
1310 if [ "$make_j" ]; then
1311 make_j_opts="-j $make_j"
1312 else
1313 n_cores="$(getconf _NPROCESSORS_ONLN)" 2>/dev/null || true
1314 if [ "$n_cores" ]; then
1315 make_j_opts="-j $n_cores"
1316 fi
1317 fi
1318fi
1319
Harrison Mutai07043e92023-07-06 09:41:12 +01001320# Install python build dependencies
1321if is_arm_jenkins_env; then
1322 source "$ci_root/script/install_python_deps.sh"
1323fi
1324
Juan Pablo Conde3feb7f12023-10-21 13:14:47 -05001325# Install c-picker dependency
1326if config_valid "$tfut_config"; then
1327 echo "started building"
1328 python3 -m venv .venv
1329 source .venv/bin/activate
1330
1331 if ! python3 -m pip show c-picker &> /dev/null; then
1332 echo "Installing c-picker"
1333 pip install git+https://git.trustedfirmware.org/TS/trusted-services.git@topics/c-picker || {
1334 echo "c-picker was not installed!"
1335 exit 1
1336 }
1337 echo "c-picker was installed"
1338 else
1339 echo "c-picker is already installed"
1340 fi
1341fi
1342
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +00001343# Print CMake version
1344cmake_ver=$(echo `cmake --version | sed -n '1p'`)
1345echo "Using $cmake_ver"
1346
1347# Check for Ninja
1348if [ -x "$(command -v ninja)" ]; then
1349 # Print Ninja version
1350 ninja_ver=$(echo `ninja --version | sed -n '1p'`)
1351 echo "Using ninja $ninja_ver"
1352 export cmake_gen="-G Ninja"
1353else
1354 echo 'Ninja is not installed'
1355 export cmake_gen=""
1356fi
1357
1358undo_rmm_patches() {
1359 pushd "$rmm_root"
1360 patch_record="$rmm_patch_record" undo_patch_record
1361 popd
1362}
1363
Fathi Boudra422bf772019-12-02 11:10:16 +02001364modes="${bin_mode:-debug release}"
1365for mode in $modes; do
Paul Sokolovskye9962cd2021-12-17 18:39:40 +03001366 echo "===== Building package in mode: $mode ====="
Fathi Boudra422bf772019-12-02 11:10:16 +02001367 # Build with a temporary archive
1368 build_archive="$archive/$mode"
1369 mkdir "$build_archive"
1370
1371 if [ "$mode" = "debug" ]; then
Zelalem219df412020-05-17 19:21:20 -05001372 export bin_mode="debug"
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +00001373 cmake_build_type="Debug"
Fathi Boudra422bf772019-12-02 11:10:16 +02001374 DEBUG=1
1375 else
Zelalem219df412020-05-17 19:21:20 -05001376 export bin_mode="release"
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +00001377 cmake_build_type="Release"
Fathi Boudra422bf772019-12-02 11:10:16 +02001378 DEBUG=0
1379 fi
1380
1381 # Perform builds in a subshell so as not to pollute the current and
1382 # subsequent builds' environment
1383
Zelalem219df412020-05-17 19:21:20 -05001384 if config_valid "$cc_config"; then
1385 # Build code coverage plugin
1386 build_cc
1387 fi
1388
Fathi Boudra422bf772019-12-02 11:10:16 +02001389 # TFTF build
1390 if config_valid "$tftf_config"; then
1391 (
1392 echo "##########"
1393
Manish V Badarkhe3bd3fea2020-11-08 15:17:00 +00001394 plat_utils="$(get_tf_opt PLAT_UTILS)"
1395 if [ -z ${plat_utils} ]; then
1396 # Source platform-specific utilities.
1397 plat="$(get_tftf_opt PLAT)"
1398 plat_utils="$ci_root/${plat}_utils.sh"
1399 else
1400 # Source platform-specific utilities by
1401 # using plat_utils name.
1402 plat_utils="$ci_root/${plat_utils}.sh"
1403 fi
1404
Fathi Boudra422bf772019-12-02 11:10:16 +02001405 if [ -f "$plat_utils" ]; then
1406 source "$plat_utils"
1407 fi
1408
1409 archive="$build_archive"
Boyan Karatotev97de8d82025-03-06 15:22:21 +00001410 tftf_build_root="$archive/build/tftf"
1411 mkdir -p ${tftf_build_root}
Fathi Boudra422bf772019-12-02 11:10:16 +02001412
1413 echo "Building Trusted Firmware TF ($mode) ..." |& log_separator
1414
1415 # Call pre-build hook
1416 call_hook pre_tftf_build
1417
1418 build_tftf
1419
1420 from="$tftf_build_root" to="$archive" collect_build_artefacts
1421
1422 # Clear any local changes made by applied patches
1423 undo_tftf_patches
1424
1425 echo "##########"
1426 echo
1427 )
1428 fi
1429
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001430 # SPM build
1431 if config_valid "$spm_config"; then
1432 (
1433 echo "##########"
1434
1435 # Get platform name from spm_config file
1436 plat="$(echo "$spm_config" | awk -F- '{print $1}')"
1437 plat_utils="$ci_root/${plat}_utils.sh"
1438 if [ -f "$plat_utils" ]; then
1439 source "$plat_utils"
1440 fi
1441
Daniel Boulbyb8d2a462022-03-07 13:55:25 +00001442 # Call pre-build hook
1443 call_hook pre_spm_build
1444
Manish Pandey1e7be852020-11-09 16:04:48 +00001445 # SPM build generates two sets of binaries, one for normal and other
1446 # for Secure world. We need both set of binaries for CI.
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001447 archive="$build_archive"
Boyan Karatotev27057342025-07-28 09:56:23 +01001448 spm_build_root="$archive/build/spm"
1449
1450 spm_secure_build_root="$spm_build_root/$spm_secure_out_dir"
1451 spm_ns_build_root="$spm_build_root/$spm_non_secure_out_dir"
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001452
Daniel Boulbyb8d2a462022-03-07 13:55:25 +00001453 echo "spm_build_root is $spm_build_root"
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001454 echo "Building SPM ($mode) ..." |& log_separator
1455
1456 # NOTE: mode has no effect on SPM build (for now), hence debug
1457 # mode is built but subsequent build using release mode just
1458 # goes through with "nothing to do".
1459 build_spm
1460
1461 # Show SPM/Hafnium binary details
Boyan Karatotev27057342025-07-28 09:56:23 +01001462 cksum $spm_secure_build_root/hafnium.bin
Madhukar Pappireddyc683cf62021-11-01 14:38:32 -05001463
1464 # Some platforms only have secure configuration enabled. Hence,
1465 # non secure hanfnium binary might not be built.
Boyan Karatotev27057342025-07-28 09:56:23 +01001466 if [ -f $spm_ns_build_root/hafnium.bin ]; then
1467 cksum $spm_ns_build_root/hafnium.bin
Madhukar Pappireddyc683cf62021-11-01 14:38:32 -05001468 fi
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001469
Boyan Karatotev27057342025-07-28 09:56:23 +01001470 secure_from="$spm_secure_build_root" non_secure_from="$spm_ns_build_root" to="$archive" collect_spm_artefacts
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001471
1472 echo "##########"
1473 echo
1474 )
1475 fi
1476
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +00001477 # TF RMM build
1478 if config_valid "$rmm_config"; then
1479 (
1480 echo "##########"
1481
1482 plat_utils="$(get_rmm_opt PLAT_UTILS)"
1483 if [ -z ${plat_utils} ]; then
1484 # Source platform-specific utilities.
1485 plat="$(get_rmm_opt PLAT)"
Manish V Badarkhea3505272025-04-17 14:20:42 +01001486 extra_options="$(get_rmm_opt EXTRA_OPTIONS)"
1487 extra_targets="$(get_rmm_opt EXTRA_TARGETS "")"
1488 rmm_toolchain="$(get_rmm_opt TOOLCHAIN gnu)"
1489 rmm_fpu_use_at_rel2="$(get_rmm_opt RMM_FPU_USE_AT_REL2 OFF)"
1490 rmm_attest_el3_token_sign="$(get_rmm_opt ATTEST_EL3_TOKEN_SIGN OFF)"
1491 rmm_v1_1="$(get_rmm_opt RMM_V1_1 ON)"
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +00001492 plat_utils="$ci_root/${plat}_utils.sh"
1493 else
1494 # Source platform-specific utilities by
1495 # using plat_utils name.
1496 plat_utils="$ci_root/${plat_utils}.sh"
1497 fi
1498
1499 if [ -f "$plat_utils" ]; then
1500 source "$plat_utils"
1501 fi
1502
1503 archive="$build_archive"
1504 rmm_build_root="$rmm_root/build"
1505
1506 echo "Building Trusted Firmware RMM ($mode) ..." |& log_separator
1507
1508 #call_hook pre_rmm_build
1509 build_rmm
1510
1511 # Collect all rmm.* files: rmm.img, rmm.elf, rmm.dump, rmm.map
1512 from="$rmm_build_root" to="$archive" collect_build_artefacts
1513
1514 # Clear any local changes made by applied patches
1515 undo_rmm_patches
1516
1517 echo "##########"
1518 )
1519 fi
1520
Fathi Boudra422bf772019-12-02 11:10:16 +02001521 # TF build
1522 if config_valid "$tf_config"; then
1523 (
1524 echo "##########"
1525
Manish V Badarkhe3bd3fea2020-11-08 15:17:00 +00001526 plat_utils="$(get_tf_opt PLAT_UTILS)"
Madhukar Pappireddy2f284e12021-08-30 16:06:14 -05001527 export plat_variant="$(get_tf_opt TARGET_PLATFORM)"
1528
Manish V Badarkhe3bd3fea2020-11-08 15:17:00 +00001529 if [ -z ${plat_utils} ]; then
1530 # Source platform-specific utilities.
1531 plat="$(get_tf_opt PLAT)"
1532 plat_utils="$ci_root/${plat}_utils.sh"
1533 else
1534 # Source platform-specific utilities by
1535 # using plat_utils name.
1536 plat_utils="$ci_root/${plat_utils}.sh"
1537 fi
1538
Fathi Boudra422bf772019-12-02 11:10:16 +02001539 if [ -f "$plat_utils" ]; then
1540 source "$plat_utils"
1541 fi
1542
Chris Kaye5a486b2023-08-04 11:50:31 +00001543 fvp_tsram_size="$(get_tf_opt FVP_TRUSTED_SRAM_SIZE)"
1544 fvp_tsram_size="${fvp_tsram_size:-256}"
1545
Harrison Mutaidc703402024-08-02 14:40:16 +00001546 poetry -C "$tf_root" install --without docs
Chris Kayd0837902021-11-17 10:17:52 +00001547
Fathi Boudra422bf772019-12-02 11:10:16 +02001548 archive="$build_archive"
Boyan Karatotev97de8d82025-03-06 15:22:21 +00001549 tf_build_root="$archive/build/tfa"
1550 mkdir -p ${tf_build_root}
Fathi Boudra422bf772019-12-02 11:10:16 +02001551
1552 echo "Building Trusted Firmware ($mode) ..." |& log_separator
1553
1554 # Call pre-build hook
1555 call_hook pre_tf_build
1556
1557 build_tf
1558
1559 # Call post-build hook
1560 call_hook post_tf_build
1561
1562 # Pre-archive hook
1563 call_hook pre_tf_archive
1564
1565 from="$tf_build_root" to="$archive" collect_build_artefacts
1566
1567 # Post-archive hook
1568 call_hook post_tf_archive
1569
1570 call_hook fetch_tf_resource
1571 call_hook post_fetch_tf_resource
1572
Chris Kay4e8aaf12022-09-01 15:21:55 +01001573 # Generate LAVA job files if necessary
1574 call_hook generate_lava_job_template
1575 call_hook generate_lava_job
1576
Fathi Boudra422bf772019-12-02 11:10:16 +02001577 # Clear any local changes made by applied patches
1578 undo_tf_patches
1579
1580 echo "##########"
1581 )
1582 fi
1583
Juan Pablo Conde3feb7f12023-10-21 13:14:47 -05001584 # TFUT build
1585 if config_valid "$tfut_config"; then
1586 (
1587 echo "##########"
1588
1589 archive="$build_archive"
1590 tfut_build_root="$tfut_root/build"
1591
1592 echo "Building Trusted Firmware UT ($mode) ..." |& log_separator
1593
Juan Pablo Conde2ecf1862024-01-16 20:12:43 -06001594 # Clean TFUT build targets
1595 set_hook_var "tfut_build_targets" ""
1596
Juan Pablo Conde3feb7f12023-10-21 13:14:47 -05001597 # Call pre-build hook
1598 call_hook pre_tfut_build
1599
1600 build_tfut
1601
1602 from="$tfut_build_root" to="$archive" collect_tfut_artefacts
1603
Edward Potapovdb31e702025-06-30 16:28:40 -05001604 to="$archive" coverage="$COVERAGE" collect_tfut_coverage
1605
Juan Pablo Conde3feb7f12023-10-21 13:14:47 -05001606 echo "##########"
1607 echo
1608 )
1609 fi
Fathi Boudra422bf772019-12-02 11:10:16 +02001610 echo
1611 echo
1612done
1613
Juan Pablo Conde3feb7f12023-10-21 13:14:47 -05001614if config_valid "$tfut_config"; then
1615 deactivate
1616fi
1617
Fathi Boudra422bf772019-12-02 11:10:16 +02001618call_hook pre_package
1619
1620call_hook post_package
1621
1622if upon "$jenkins_run" && upon "$artefacts_receiver" && [ -d "artefacts" ]; then
Zelalem219df412020-05-17 19:21:20 -05001623 source "$CI_ROOT/script/send_artefacts.sh" "artefacts"
Fathi Boudra422bf772019-12-02 11:10:16 +02001624fi
1625
1626echo
1627echo "Done"