blob: d15071c58d1a362e610e9779a181b270a5355c21 [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
64# Check if a config is valid
65config_valid() {
66 local config="${1?}"
67 if [ -z "$config" ] || [ "$(basename "$config")" = "nil" ]; then
68 return 1
69 fi
70
71 return 0
72}
73
74# Echo from a build wrapper. Print to descriptor 3 that's opened by the build
75# function.
76echo_w() {
77 echo $echo_flags "$@" >&3
78}
79
80# Print a separator to the log file. Intended to be used at the tail end of a pipe
81log_separator() {
82 {
83 echo
84 echo "----------"
85 } >> "$build_log"
86
87 tee -a "$build_log"
88
89 {
90 echo "----------"
91 echo
92 } >> "$build_log"
93}
94
95# Call function $1 if it's defined
96call_func() {
97 if type "${1:?}" &>/dev/null; then
98 echo
99 echo "> ${2:?}:$1()"
100 eval "$1"
101 echo "< $2:$1()"
102 fi
103}
104
Paul Sokolovskybe6510c2024-08-15 21:54:00 +0300105# Retry a command a number of times if it fails. Intended for I/O commands
106# in a CI environment which may be flaky.
107function retry() {
108 for i in $(seq 1 3); do
109 if "$@"; then
110 return 0
111 fi
112 sleep $(( i * 5 ))
113 done
114 return 1
115}
116
Fathi Boudra422bf772019-12-02 11:10:16 +0200117# Call hook $1 in all chosen fragments if it's defined. Hooks are invoked from
118# within a subshell, so any variables set within a hook are lost. Should a
119# variable needs to be set from within a hook, the function 'set_hook_var'
120# should be used
121call_hook() {
122 local func="$1"
123 local config_fragment
124
125 [ -z "$func" ] && return 0
126
Paul Sokolovskye9962cd2021-12-17 18:39:40 +0300127 echo "=== Calling hooks: $1 ==="
128
Fathi Boudra422bf772019-12-02 11:10:16 +0200129 : >"$hook_env_file"
130
Nicola Mazzucato7fc5abd2024-02-23 21:32:48 +0000131 if [ "$run_config_candidates" ]; then
132 for config_fragment in $run_config_candidates; do
Fathi Boudra422bf772019-12-02 11:10:16 +0200133 (
134 source "$ci_root/run_config/$config_fragment"
135 call_func "$func" "$config_fragment"
136 )
137 done
138 fi
139
140 # Also source test config file
141 (
142 unset "$func"
143 source "$test_config_file"
144 call_func "$func" "$(basename $test_config_file)"
145 )
146
147 # Have any variables set take effect
148 source "$hook_env_file"
Paul Sokolovskye9962cd2021-12-17 18:39:40 +0300149
150 echo "=== End calling hooks: $1 ==="
Fathi Boudra422bf772019-12-02 11:10:16 +0200151}
152
153# Set a variable from within a hook
154set_hook_var() {
155 echo "export $1=\"${2?}\"" >> "$hook_env_file"
156}
157
158# Append to an array from within a hook
159append_hook_var() {
160 echo "export $1+=\"${2?}\"" >> "$hook_env_file"
161}
162
163# Have the main build script source a file
164source_later() {
165 echo "source ${1?}" >> "$hook_env_file"
166}
167
168# Setup TF build wrapper function by pointing to a script containing a function
169# that will be called with the TF build commands.
170setup_tf_build_wrapper() {
171 source_later "$ci_root/script/${wrapper?}_wrapper.sh"
172 set_hook_var "tf_build_wrapper" "${wrapper}_wrapper"
173 echo "Setup $wrapper build wrapper."
174}
175
176# Collect .bin files for archiving
177collect_build_artefacts() {
178 if [ ! -d "${from:?}" ]; then
179 return
180 fi
181
Manish V Badarkhe84c3a482025-04-16 08:15:38 +0100182 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 +0200183 echo "You probably are running local CI on local repositories."
184 echo "Did you set 'dont_clean' but forgot to run 'distclean'?"
185 die
186 fi
187}
188
Manish Pandey1e7be852020-11-09 16:04:48 +0000189# Collect SPM/hafnium artefacts with "secure_" appended to the files
190# generated for SPM(secure hafnium).
191collect_spm_artefacts() {
Madhukar Pappireddyc683cf62021-11-01 14:38:32 -0500192 if [ -d "${non_secure_from:?}" ]; then
193 find "$non_secure_from" \( -name "*.bin" -o -name '*.elf' \) -exec cp -t "${to:?}" '{}' +
Manish Pandey1e7be852020-11-09 16:04:48 +0000194 fi
195
Madhukar Pappireddyc683cf62021-11-01 14:38:32 -0500196 if [ -d "${secure_from:?}" ]; then
197 for f in $(find "$secure_from" \( -name "*.bin" -o -name '*.elf' \)); do cp -- "$f" "${to:?}"/secure_$(basename $f); done
198 fi
Manish Pandey1e7be852020-11-09 16:04:48 +0000199}
200
Juan Pablo Conde3feb7f12023-10-21 13:14:47 -0500201collect_tfut_artefacts() {
202 if [ ! -d "${from:?}" ]; then
203 return
204 fi
205
206 pushd "$tfut_root/build"
207 artefact_list=$(python3 "$ci_root/script/get_ut_test_list.py")
208 for artefact in $artefact_list; do
209 cp -t "${to:?}" "$from/$artefact"
210 done
211 echo "$artefact_list" | tr ' ' '\n' > "${to:?}/tfut_artefacts.txt"
212 popd
213}
214
Javier Almansa Sobrino412d3612020-05-22 17:53:12 +0100215# Map the UART ID used for expect with the UART descriptor and port
216# used by the FPGA automation tools.
217map_uart() {
218 local port="${port:?}"
219 local descriptor="${descriptor:?}"
220 local baudrate="${baudrate:?}"
221 local run_root="${archive:?}/run"
222
223 local uart_dir="$run_root/uart${uart:?}"
224 mkdir -p "$uart_dir"
225
226 echo "$port" > "$uart_dir/port"
227 echo "$descriptor" > "$uart_dir/descriptor"
228 echo "$baudrate" > "$uart_dir/baudrate"
229
230 echo "UART${uart} mapped to port ${port} with descriptor ${descriptor} and baudrate ${baudrate}"
231}
232
Fathi Boudra422bf772019-12-02 11:10:16 +0200233# Arrange environment varibles to be set when expect scripts are launched
234set_expect_variable() {
235 local var="${1:?}"
236 local val="${2?}"
237
238 local run_root="${archive:?}/run"
239 local uart_dir="$run_root/uart${uart:?}"
240 mkdir -p "$uart_dir"
241
242 env_file="$uart_dir/env" quote="1" emit_env "$var" "$val"
243 echo "UART$uart: env has $@"
244}
245
246# Place the binary package a pointer to expect script, and its parameters
247track_expect() {
248 local file="${file:?}"
249 local timeout="${timeout-600}"
250 local run_root="${archive:?}/run"
251
252 local uart_dir="$run_root/uart${uart:?}"
253 mkdir -p "$uart_dir"
254
255 echo "$file" > "$uart_dir/expect"
256 echo "$timeout" > "$uart_dir/timeout"
Paul Sokolovskybfa8bab2023-01-25 19:34:51 +0700257 if [ -n "$lava_timeout" ]; then
258 set_run_env "lava_timeout" "$lava_timeout"
259 fi
Fathi Boudra422bf772019-12-02 11:10:16 +0200260
Paul Sokolovskybfa8bab2023-01-25 19:34:51 +0700261 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 +0200262
Chris Kayfab6edc2022-11-17 19:18:32 +0000263 if [ ! -z "${port}" ]; then
264 echo "${port}" > "$uart_dir/port"
265 fi
266
Fathi Boudra422bf772019-12-02 11:10:16 +0200267 # The run script assumes UART0 to be primary. If we're asked to set any
268 # other UART to be primary, set a run environment variable to signal
269 # that to the run script
270 if upon "$set_primary"; then
271 echo "Primary UART set to UART$uart."
272 set_run_env "primary_uart" "$uart"
273 fi
Madhukar Pappireddy1e953722021-11-08 15:23:02 -0600274
275 # UART used by payload(such as tftf, Linux) may not be the same as the
276 # primary UART. Set a run environment variable to track the payload
277 # UART which is tracked to check if the test has finished sucessfully.
278 if upon "$set_payload_uart"; then
279 echo "Payload uses UART$uart."
280 set_run_env "payload_uart" "$uart"
281 fi
Fathi Boudra422bf772019-12-02 11:10:16 +0200282}
283
284# Extract a FIP in $1 using fiptool
285extract_fip() {
286 local fip="$1"
287
288 if is_url "$1"; then
289 url="$1" fetch_file
290 fip="$(basename "$1")"
291 fi
292
Boyan Karatotevde2cd442025-07-28 09:50:29 +0100293 fiptool=$(fiptool_path)
Fathi Boudra422bf772019-12-02 11:10:16 +0200294 "$fiptool" unpack "$fip"
295 echo "Extracted FIP: $fip"
296}
297
298# Report build failure by printing a the tail end of build log. Archive the
299# build log for later inspection
300fail_build() {
301 local log_path
302
303 if upon "$jenkins_run"; then
304 log_path="$BUILD_URL/artifact/artefacts/build.log"
305 else
306 log_path="$build_log"
307 fi
308
309 echo
Leonardo Sandovalae97eda2020-11-12 10:07:03 -0600310 echo "Build failed! Full build log below:"
Fathi Boudra422bf772019-12-02 11:10:16 +0200311 echo "[...]"
312 echo
Leonardo Sandovalae97eda2020-11-12 10:07:03 -0600313 cat "$build_log"
Fathi Boudra422bf772019-12-02 11:10:16 +0200314 echo
315 echo "See $log_path for full output"
316 echo
317 cp -t "$archive" "$build_log"
318 exit 1;
319}
320
321# Build a FIP with supplied arguments
322build_fip() {
323 (
324 echo "Building FIP with arguments: $@"
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
Slava Andrianov192ee172025-06-11 15:40:43 -0500333 if [ "$(get_tf_opt MEASURED_BOOT)" = 1 ]; then
334 # These are needed for accurate hash verification
335 local build_args_path="${workspace}/fip_build_args"
336 echo $@ > $build_args_path
337 archive_file $build_args_path
338 fi
339
Boyan Karatotev99e12312025-05-02 15:00:24 +0100340 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 +0200341 ${fip_targets:-fip} &>>"$build_log" || fail_build
342 )
343}
344
Sandrine Bailleux189fdb32023-10-20 13:41:22 +0200345# Build any extra rule from TF-A makefile with supplied arguments.
346#
347# This is useful in case you need to build something else than firmware binaries
348# or the FIP.
349build_tf_extra() {
350 (
351 tf_extra_rules=${tf_extra_rules:?}
352 echo "Building extra TF rule(s): $tf_extra_rules"
353 echo " Arguments: $@"
354
355 local tf_env="$workspace/tf.env"
356
357 if [ -f "$tf_env" ]; then
358 set -a
359 source "$tf_env"
360 set +a
361 fi
362
Boyan Karatotev99e12312025-05-02 15:00:24 +0100363 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 +0200364 ${tf_extra_rules} &>>"$build_log" || fail_build
365 )
366}
367
Fathi Boudra422bf772019-12-02 11:10:16 +0200368fip_update() {
Boyan Karatotevde2cd442025-07-28 09:50:29 +0100369 fiptool=$(fiptool_path)
Fathi Boudra422bf772019-12-02 11:10:16 +0200370 # Before the update process, check if the given image is supported by
371 # the fiptool. It's assumed that both fiptool and cert_create move in
Chris Kay197b1022023-08-16 21:31:41 +0100372 # tandem, and therefore, if one has support, the other has it too.
373 if ! ("$fiptool" update 2>&1 || true) | grep -qe "\s\+--${bin_name:?}"; then
Fathi Boudra422bf772019-12-02 11:10:16 +0200374 return 1
375 fi
376
377 if not_upon "$(get_tf_opt TRUSTED_BOARD_BOOT)"; then
378 echo "Updating FIP image: $bin_name"
379 # Update HW config. Without TBBR, it's only a matter of using
380 # the update sub-command of fiptool
381 "$fiptool" update "--$bin_name" "${src:-}" \
382 "$archive/fip.bin"
383 else
384 echo "Updating FIP image (TBBR): $bin_name"
385 # With TBBR, we need to unpack, re-create certificates, and then
386 # recreate the FIP.
387 local fip_dir="$(mktempdir)"
388 local bin common_args stem
389 local rot_key="$(get_tf_opt ROT_KEY)"
390
391 rot_key="${rot_key:?}"
392 if ! is_abs "$rot_key"; then
393 rot_key="$tf_root/$rot_key"
394 fi
395
396 # Arguments only for cert_create
397 local cert_args="-n"
398 cert_args+=" --tfw-nvctr ${nvctr:-31}"
399 cert_args+=" --ntfw-nvctr ${nvctr:-223}"
400 cert_args+=" --key-alg ${KEY_ALG:-rsa}"
401 cert_args+=" --rot-key $rot_key"
402
403 local dyn_config_opts=(
Zelalem1af7a7b2020-08-04 17:34:32 -0500404 "fw-config"
Fathi Boudra422bf772019-12-02 11:10:16 +0200405 "hw-config"
406 "tb-fw-config"
407 "nt-fw-config"
408 "soc-fw-config"
409 "tos-fw-config"
410 )
411
412 # Binaries without key certificates
413 declare -A has_no_key_cert
414 for bin in "tb-fw" "${dyn_config_opts[@]}"; do
415 has_no_key_cert["$bin"]="1"
416 done
417
418 # Binaries without certificates
419 declare -A has_no_cert
420 for bin in "hw-config" "${dyn_config_opts[@]}"; do
421 has_no_cert["$bin"]="1"
422 done
423
424 pushd "$fip_dir"
425
426 # Unpack FIP
427 "$fiptool" unpack "$archive/fip.bin" &>>"$build_log"
428
429 # Remove all existing certificates
430 rm -f *-cert.bin
431
432 # Copy the binary to be updated
433 cp -f "$src" "${bin_name}.bin"
434
435 # FIP unpack dumps binaries with the same name as the option
436 # used to pack it; likewise for certificates. Reverse-engineer
437 # the command line from the binary output.
438 common_args="--trusted-key-cert trusted_key.crt"
439 for bin in *.bin; do
440 stem="${bin%%.bin}"
441 common_args+=" --$stem $bin"
442 if not_upon "${has_no_cert[$stem]}"; then
443 common_args+=" --$stem-cert $stem.crt"
444 fi
445 if not_upon "${has_no_key_cert[$stem]}"; then
446 common_args+=" --$stem-key-cert $stem-key.crt"
447 fi
448 done
449
450 # Create certificates
Boyan Karatotevde2cd442025-07-28 09:50:29 +0100451 cert_create=$(cert_create_path)
Fathi Boudra422bf772019-12-02 11:10:16 +0200452 "$cert_create" $cert_args $common_args &>>"$build_log"
453
454 # Recreate and archive FIP
455 "$fiptool" create $common_args "fip.bin" &>>"$build_log"
456 archive_file "fip.bin"
457
458 popd
459 fi
460}
461
462# Update hw-config in FIP, and remove the original DTB afterwards.
463update_fip_hw_config() {
464 # The DTB needs to be loaded by the model (and not updated in the FIP)
Madhukar Pappireddy9062ebf2021-03-02 17:07:06 -0600465 # in configs:
466 # 1. Where BL2 isn't present
467 # 2. Where we boot to Linux directly as BL33
Fathi Boudra422bf772019-12-02 11:10:16 +0200468 case "1" in
469 "$(get_tf_opt RESET_TO_BL31)" | \
Madhukar Pappireddy9062ebf2021-03-02 17:07:06 -0600470 "$(get_tf_opt ARM_LINUX_KERNEL_AS_BL33)" | \
Fathi Boudra422bf772019-12-02 11:10:16 +0200471 "$(get_tf_opt RESET_TO_SP_MIN)" | \
Maksims Svecovs7a0da522023-03-06 16:28:27 +0000472 "$(get_tf_opt RESET_TO_BL2)")
Fathi Boudra422bf772019-12-02 11:10:16 +0200473 return 0;;
474 esac
475
476 if bin_name="hw-config" src="$archive/dtb.bin" fip_update; then
477 # Remove the DTB so that model won't load it
478 rm -f "$archive/dtb.bin"
479 fi
480}
481
Fathi Boudra422bf772019-12-02 11:10:16 +0200482get_tftf_opt() {
483 (
484 name="${1:?}"
485 if config_valid "$tftf_config_file"; then
486 source "$tftf_config_file"
487 echo "${!name}"
488 fi
489 )
490}
491
492get_tf_opt() {
493 (
494 name="${1:?}"
495 if config_valid "$tf_config_file"; then
496 source "$tf_config_file"
497 echo "${!name}"
498 fi
499 )
500}
501
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +0000502get_rmm_opt() {
503 (
504 name="${1:?}"
Manish V Badarkhea3505272025-04-17 14:20:42 +0100505 default="$2"
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +0000506 if config_valid "$rmm_config_file"; then
507 source "$rmm_config_file"
Manish V Badarkhea3505272025-04-17 14:20:42 +0100508 # If !name is not defined, go with the default
509 # value (if defined)
510 if [ -z "${!name}" ]; then
511 echo "$default"
512 else
513 echo "${!name}"
514 fi
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +0000515 fi
516 )
517}
518
Fathi Boudra422bf772019-12-02 11:10:16 +0200519build_tf() {
520 (
521 env_file="$workspace/tf.env"
522 config_file="${tf_build_config:-$tf_config_file}"
523
524 # Build fiptool and all targets by default
Harrison Mutai32de9d02023-06-12 14:23:37 +0100525 build_targets="${tf_build_targets:-fiptool all}"
Fathi Boudra422bf772019-12-02 11:10:16 +0200526
527 source "$config_file"
528
529 # If it is a TBBR build, extract the MBED TLS library from archive
Manish V Badarkhe8f125012021-12-21 05:47:52 +0000530 if [ "$(get_tf_opt TRUSTED_BOARD_BOOT)" = 1 ] ||
Manish V Badarkhef43e3f52022-06-21 20:37:25 +0100531 [ "$(get_tf_opt MEASURED_BOOT)" = 1 ] ||
532 [ "$(get_tf_opt DRTM_SUPPORT)" = 1 ]; then
Fathi Boudra422bf772019-12-02 11:10:16 +0200533 mbedtls_dir="$workspace/mbedtls"
534 if [ ! -d "$mbedtls_dir" ]; then
535 mbedtls_ar="$workspace/mbedtls.tar.gz"
536
537 url="$mbedtls_archive" saveas="$mbedtls_ar" fetch_file
538 mkdir "$mbedtls_dir"
Leonardo Sandovalec9e16c2020-09-09 14:32:40 -0500539 extract_tarball $mbedtls_ar $mbedtls_dir --strip-components=1
Fathi Boudra422bf772019-12-02 11:10:16 +0200540 fi
541
542 emit_env "MBEDTLS_DIR" "$mbedtls_dir"
543 fi
Jimmy Brisson0d5e12c2023-05-16 14:51:51 -0500544 if [ "$(get_tf_opt PLATFORM_TEST)" = "tfm-testsuite" ] &&
545 not_upon "${TF_M_TESTS_PATH}"; then
546 emit_env "TF_M_TESTS_PATH" "$WORKSPACE/tf-m-tests"
547 fi
548 if [ "$(get_tf_opt PLATFORM_TEST)" = "tfm-testsuite" ] &&
549 not_upon "${TF_M_EXTRAS_PATH}"; then
550 emit_env "TF_M_EXTRAS_PATH" "$WORKSPACE/tf-m-extras"
551 fi
David Vincze82db6932024-02-21 12:05:50 +0100552 if [ "$(get_tf_opt DICE_PROTECTION_ENVIRONMENT)" = 1 ] &&
553 not_upon "${QCBOR_DIR}"; then
554 emit_env "QCBOR_DIR" "$WORKSPACE/qcbor"
555 fi
Slava Andrianov192ee172025-06-11 15:40:43 -0500556
557 # Hash verification only occurs if there is a sufficient amount of
558 # information in the event log, which is as long as EVENT_LOG_LEVEL
559 # is set to at least 20 or if it is a debug build
560 if [[ ("$(get_tf_opt MEASURED_BOOT)" -eq 1) &&
561 (($bin_mode == "debug") || ("$(get_tf_opt EVENT_LOG_LEVEL)" -ge 20)) ]]; then
562 # This variable is later exported to the expect scripts so
563 # the hashes in the TF-A event log can be verified
564 set_run_env "verify_hashes" "1"
565 fi
Fathi Boudra422bf772019-12-02 11:10:16 +0200566 if [ -f "$env_file" ]; then
567 set -a
568 source "$env_file"
569 set +a
570 fi
571
Harrison Mutai013f6332022-02-16 16:06:33 +0000572 if is_arm_jenkins_env || upon "$local_ci"; then
573 path_list=(
574 "$llvm_dir/bin"
575 )
576 extend_path "PATH" "path_list"
577 fi
578
Boyan Karatotev97de8d82025-03-06 15:22:21 +0000579 pushd "$tf_root"
Fathi Boudra422bf772019-12-02 11:10:16 +0200580
581 # Always distclean when running on Jenkins. Skip distclean when running
582 # locally and explicitly requested.
583 if upon "$jenkins_run" || not_upon "$dont_clean"; then
Boyan Karatotev97de8d82025-03-06 15:22:21 +0000584 make distclean BUILD_BASE=$tf_build_root &>>"$build_log" || fail_build
Fathi Boudra422bf772019-12-02 11:10:16 +0200585 fi
586
587 # Log build command line. It is left unfolded on purpose to assist
588 # copying to clipboard.
589 cat <<EOF | log_separator >/dev/null
590
591Build command line:
Boyan Karatotev97de8d82025-03-06 15:22:21 +0000592 $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 +0200593
Paul Sokolovsky7f71b072023-10-16 12:59:09 +0300594CC version:
595$(${CC-${CROSS_COMPILE}gcc} -v 2>&1)
Fathi Boudra422bf772019-12-02 11:10:16 +0200596EOF
597
Javier Almansa Sobrinoe8363182020-11-10 16:40:53 +0000598 if not_upon "$local_ci"; then
599 connect_debugger=0
600 fi
601
Fathi Boudra422bf772019-12-02 11:10:16 +0200602 # Build TF. Since build output is being directed to the build log, have
603 # descriptor 3 point to the current terminal for build wrappers to vent.
Harrison Mutai6361dbe2023-02-16 14:12:40 +0000604 $tf_build_wrapper poetry run make $make_j_opts $(cat "$config_file") \
Boyan Karatotev97de8d82025-03-06 15:22:21 +0000605 DEBUG="$DEBUG" V=1 BUILD_BASE="$tf_build_root" SPIN_ON_BL1_EXIT="$connect_debugger" \
Fathi Boudra422bf772019-12-02 11:10:16 +0200606 $build_targets 3>&1 &>>"$build_log" || fail_build
Harrison Mutai32de9d02023-06-12 14:23:37 +0100607
Harrison Mutai6dafb5f2023-07-18 15:21:48 +0100608 if [ "$build_targets" != "doc" ]; then
Chris Kay9ab2d952025-05-29 13:46:24 +0100609 (poetry run memory --root "$tf_build_root" symbols 2>&1 || true) | tee -a "${build_log}"
610
611 for map in $(find "${tf_build_root}" -name '*.map'); do
612 (poetry run memory --root "${tf_build_root}" summary "${map}" 2>&1 || true) | tee -a "${build_log}"
613 done
Harrison Mutai6dafb5f2023-07-18 15:21:48 +0100614 fi
Boyan Karatotev97de8d82025-03-06 15:22:21 +0000615 popd
Fathi Boudra422bf772019-12-02 11:10:16 +0200616 )
617}
618
619build_tftf() {
620 (
621 config_file="${tftf_build_config:-$tftf_config_file}"
622
623 # Build tftf target by default
624 build_targets="${tftf_build_targets:-all}"
625
626 source "$config_file"
627
628 cd "$tftf_root"
629
630 # Always distclean when running on Jenkins. Skip distclean when running
631 # locally and explicitly requested.
632 if upon "$jenkins_run" || not_upon "$dont_clean"; then
Boyan Karatotev97de8d82025-03-06 15:22:21 +0000633 make distclean BUILD_BASE="$tftf_build_root" &>>"$build_log" || fail_build
Fathi Boudra422bf772019-12-02 11:10:16 +0200634 fi
635
636 # TFTF build system cannot reliably deal with -j option, so we avoid
637 # using that.
638
639 # Log build command line
640 cat <<EOF | log_separator >/dev/null
641
642Build command line:
Boyan Karatotev97de8d82025-03-06 15:22:21 +0000643 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 +0200644
645EOF
646
Boyan Karatotev97de8d82025-03-06 15:22:21 +0000647 make $make_j_opts $(cat "$config_file") DEBUG="$DEBUG" V=1 BUILD_BASE="$tftf_build_root" \
Fathi Boudra422bf772019-12-02 11:10:16 +0200648 $build_targets &>>"$build_log" || fail_build
649 )
650}
651
Zelalem219df412020-05-17 19:21:20 -0500652build_cc() {
653# Building code coverage plugin
654 ARM_DIR=/arm
655 pvlibversion=$(/arm/devsys-tools/abs/detag "SysGen:PVModelLib:$model_version::trunk")
656 PVLIB_HOME=$warehouse/SysGen/PVModelLib/$model_version/${pvlibversion}/external
657 if [ -n "$(find "$ARM_DIR" -maxdepth 0 -type d -empty 2>/dev/null)" ]; then
658 echo "Error: Arm warehouse not mounted. Please mount the Arm warehouse to your /arm local folder"
659 exit -1
660 fi # Error if arm warehouse not found
661 cd "$ccpathspec/scripts/tools/code_coverage/fastmodel_baremetal/bmcov"
662
663 make -C model-plugin PVLIB_HOME=$PVLIB_HOME &>>"$build_log"
664}
665
Olivier Deprez0a9a3482019-12-16 14:10:31 +0100666build_spm() {
667 (
668 env_file="$workspace/spm.env"
669 config_file="${spm_build_config:-$spm_config_file}"
670
671 source "$config_file"
672
673 if [ -f "$env_file" ]; then
674 set -a
675 source "$env_file"
676 set +a
677 fi
678
679 cd "$spm_root"
680
681 # Always clean when running on Jenkins. Skip clean when running
682 # locally and explicitly requested.
683 if upon "$jenkins_run" || not_upon "$dont_clean"; then
684 # make clean fails on a fresh repo where the project has not
685 # yet been built. Hence only clean if out/reference directory
686 # already exists.
687 if [ -d "out/reference" ]; then
688 make clean &>>"$build_log" || fail_build
689 fi
690 fi
691
692 # Log build command line. It is left unfolded on purpose to assist
693 # copying to clipboard.
694 cat <<EOF | log_separator >/dev/null
695
696Build command line:
Boyan Karatotev27057342025-07-28 09:56:23 +0100697 make $make_j_opts OUT=$spm_build_root $(cat "$config_file" | tr '\n' ' ')
Olivier Deprez0a9a3482019-12-16 14:10:31 +0100698
699EOF
700
701 # Build SPM. Since build output is being directed to the build log, have
702 # descriptor 3 point to the current terminal for build wrappers to vent.
Boyan Karatotev27057342025-07-28 09:56:23 +0100703 make $make_j_opts OUT=$spm_build_root $(cat "$config_file") 3>&1 &>>"$build_log" \
Olivier Deprez0a9a3482019-12-16 14:10:31 +0100704 || fail_build
705 )
706}
Zelalem219df412020-05-17 19:21:20 -0500707
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +0000708build_rmm() {
709 (
710 env_file="$workspace/rmm.env"
711 config_file="${rmm_build_config:-$rmm_config_file}"
712
713 # Build fiptool and all targets by default
Manish V Badarkhe8cbbabf2025-08-20 11:27:12 +0100714 export CROSS_COMPILE="aarch64-none-elf-"
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +0000715
716 source "$config_file"
717
718 if [ -f "$env_file" ]; then
719 set -a
720 source "$env_file"
721 set +a
722 fi
723
724 cd "$rmm_root"
725
726 if [ -f "$rmm_root/requirements.txt" ]; then
727 export PATH="$HOME/.local/bin:$PATH"
728 python3 -m pip install --upgrade pip
729 python3 -m pip install -r "$rmm_root/requirements.txt"
730 fi
731
732 # Always distclean when running on Jenkins. Skip distclean when running
733 # locally and explicitly requested.
734 if upon "$jenkins_run" || not_upon "$dont_clean"; then
735 # Remove 'rmm\build' folder
736 echo "Removing $rmm_build_root..."
737 rm -rf $rmm_build_root
738 fi
739
Manish V Badarkhea3505272025-04-17 14:20:42 +0100740 if not_upon "$local_ci"; then
741 connect_debugger=0
742 fi
743
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +0000744 # Log build command line. It is left unfolded on purpose to assist
745 # copying to clipboard.
746 cat <<EOF | log_separator >/dev/null
747
748Build command line:
Manish V Badarkhea3505272025-04-17 14:20:42 +0100749 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}
750 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 +0000751
Manish V Badarkhea3505272025-04-17 14:20:42 +0100752EOF
753 cmake \
754 -DRMM_CONFIG=${plat}_defcfg $cmake_gen \
755 -S $rmm_root -B $rmm_build_root \
756 -DRMM_TOOLCHAIN=$rmm_toolchain \
757 -DRMM_FPU_USE_AT_REL2=$rmm_fpu_use_at_rel2 \
758 -DATTEST_EL3_TOKEN_SIGN=$rmm_attest_el3_token_sign \
759 -DRMM_V1_1=$rmm_v1_1 \
760 ${extra_options}
761 cmake --build $rmm_build_root --config $cmake_build_type $make_j_opts -v ${extra_targets+-- $extra_targets} 3>&1 &>>"$build_log" || fail_build
762 )
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +0000763}
764
Juan Pablo Conde3feb7f12023-10-21 13:14:47 -0500765build_tfut() {
766 (
767 config_file="${tfut_build_config:-$tfut_config_file}"
768
769 # Build tfut target by default
770 build_targets="${tfut_build_targets:-all}"
771
772 source "$config_file"
773
774 mkdir -p "$tfut_root/build"
775 cd "$tfut_root/build"
776
777 # Always distclean when running on Jenkins. Skip distclean when running
778 # locally and explicitly requested.
779 if upon "$jenkins_run" || not_upon "$dont_clean"; then
780 #make clean &>>"$build_log" || fail_build
781 rm -Rf * || fail_build
782 fi
783
784 #Override build targets only if the run config did not set them.
785 if [ $build_targets == "all" ]; then
786 tests_line=$(cat "$config_file" | { grep "tests=" || :; })
787 if [ -z "$tests_line" ]; then
788 build_targets=$(echo "$tests_line" | awk -F= '{ print $NF }')
789 fi
790 fi
791
792 config=$(cat "$config_file" | grep -v "tests=")
793 cmake_config=$(echo "$config" | sed -e 's/^/\-D/')
794
795 # Check if cmake is installed
796 if ! command -v cmake &> /dev/null
797 then
798 echo "cmake could not be found"
799 exit 1
800 fi
801
802 # Log build command line
803 cat <<EOF | log_separator >/dev/null
804
805Build command line:
806 cmake $(echo "$cmake_config") -G"Unix Makefiles" --debug-output -DCMAKE_VERBOSE_MAKEFILE -DUNIT_TEST_PROJECT_PATH="$tf_root" ..
807 make $(echo "$config" | tr '\n' ' ') DEBUG=$DEBUG V=1 $build_targets
808
809EOF
810 cmake $(echo "$cmake_config") -G"Unix Makefiles" --debug-output \
811 -DCMAKE_VERBOSE_MAKEFILE=ON \
812 -DUNIT_TEST_PROJECT_PATH="$tf_root" \
813 .. &>> "$build_log" || fail_build
814 echo "Done with cmake" >> "$build_log"
815 make $(echo "$config") VERBOSE=1 \
816 $build_targets &>> "$build_log" || fail_build
817 )
818
819}
820
Fathi Boudra422bf772019-12-02 11:10:16 +0200821# Set metadata for the whole package so that it can be used by both Jenkins and
822# shell
823set_package_var() {
824 env_file="$artefacts/env" emit_env "$@"
825}
826
827set_tf_build_targets() {
828 echo "Set build target to '${targets:?}'"
829 set_hook_var "tf_build_targets" "$targets"
830}
831
832set_tftf_build_targets() {
833 echo "Set build target to '${targets:?}'"
834 set_hook_var "tftf_build_targets" "$targets"
835}
836
Olivier Deprez0a9a3482019-12-16 14:10:31 +0100837set_spm_build_targets() {
838 echo "Set build target to '${targets:?}'"
839 set_hook_var "spm_build_targets" "$targets"
840}
841
Juan Pablo Conde3feb7f12023-10-21 13:14:47 -0500842set_tfut_build_targets() {
843 echo "Set build target to '${targets:?}'"
844 set_hook_var "tfut_build_targets" "$targets"
845}
846
Daniel Boulbyb8d2a462022-03-07 13:55:25 +0000847set_spm_out_dir() {
848 echo "Set SPMC binary build to '${out_dir:?}'"
849 set_hook_var "spm_secure_out_dir" "$out_dir"
850}
Fathi Boudra422bf772019-12-02 11:10:16 +0200851# Look under $archive directory for known files such as blX images, kernel, DTB,
852# initrd etc. For each known file foo, if foo.bin exists, then set variable
853# foo_bin to the path of the file. Make the path relative to the workspace so as
854# to remove any @ characters, which Jenkins inserts for parallel runs. If the
855# file doesn't exist, unset its path.
856set_default_bin_paths() {
857 local image image_name image_path path
858 local archive="${archive:?}"
859 local set_vars
860 local var
861
862 pushd "$archive"
863
864 for file in *.bin; do
865 # Get a shell variable from the file's stem
866 var_name="${file%%.*}_bin"
867 var_name="$(echo "$var_name" | sed -r 's/[^[:alnum:]]/_/g')"
868
869 # Skip setting the variable if it's already
870 if [ "${!var_name}" ]; then
871 echo "Note: not setting $var_name; already set to ${!var_name}"
872 continue
873 else
874 set_vars+="$var_name "
875 fi
876
877 eval "$var_name=$file"
878 done
879
880 echo "Binary paths set for: "
881 {
882 for var in $set_vars; do
883 echo -n "\$$var "
884 done
885 } | fmt -80 | sed 's/^/ /'
886 echo
887
888 popd
889}
890
891gen_model_params() {
892 local model_param_file="$archive/model_params"
Javier Almansa Sobrinoe8363182020-11-10 16:40:53 +0000893 [ "$connect_debugger" ] && [ "$connect_debugger" -eq 1 ] && wait_debugger=1
Fathi Boudra422bf772019-12-02 11:10:16 +0200894
895 set_default_bin_paths
896 echo "Generating model parameter for $model..."
897 source "$ci_root/model/${model:?}.sh"
898 archive_file "$model_param_file"
899}
900
901set_model_path() {
902 set_run_env "model_path" "${1:?}"
903}
904
Zelalem1af7a7b2020-08-04 17:34:32 -0500905set_model_env() {
906 local var="${1:?}"
907 local val="${2?}"
908 local run_root="${archive:?}/run"
909
910 mkdir -p "$run_root"
911 echo "export $var=$val" >> "$run_root/model_env"
912}
Fathi Boudra422bf772019-12-02 11:10:16 +0200913set_run_env() {
914 local var="${1:?}"
915 local val="${2?}"
916 local run_root="${archive:?}/run"
917
918 mkdir -p "$run_root"
919 env_file="$run_root/env" quote="1" emit_env "$var" "$val"
920}
921
922show_head() {
923 # Display HEAD descripton
924 pushd "$1"
925 git show --quiet --no-color | sed 's/^/ > /g'
926 echo
927 popd
928}
929
930# Choose debug binaries to run; by default, release binaries are chosen to run
931use_debug_bins() {
932 local run_root="${archive:?}/run"
933
934 echo "Choosing debug binaries for execution"
935 set_package_var "BIN_MODE" "debug"
936}
937
938assert_can_git_clone() {
939 local name="${1:?}"
940 local dir="${!name}"
941
942 # If it doesn't exist, it can be cloned into
943 if [ ! -e "$dir" ]; then
944 return 0
945 fi
946
947 # If it's a directory, it must be a Git clone already
948 if [ -d "$dir" ] && [ -d "$dir/.git" ]; then
949 # No need to clone again
950 echo "Using existing git clone for $name: $dir"
951 return 1
952 fi
953
954 die "Path $dir exists but is not a git clone"
955}
956
957clone_repo() {
958 if ! is_url "${clone_url?}"; then
959 # For --depth to take effect on local paths, it needs to use the
960 # file:// scheme.
961 clone_url="file://$clone_url"
962 fi
963
964 git clone -q --depth 1 "$clone_url" "${where?}"
965 if [ "$refspec" ]; then
966 pushd "$where"
967 git fetch -q --depth 1 origin "$refspec"
968 git checkout -q FETCH_HEAD
969 popd
970 fi
971}
972
973build_unstable() {
974 echo "--BUILD UNSTABLE--" | tee -a "$build_log"
975}
976
977undo_patch_record() {
978 if [ ! -f "${patch_record:?}" ]; then
979 return
980 fi
981
982 # Undo patches in reverse
983 echo
984 for patch_name in $(tac "$patch_record"); do
985 echo "Undoing $patch_name..."
986 if ! git apply -R "$ci_root/patch/$patch_name"; then
987 if upon "$local_ci"; then
988 echo
989 echo "Your local directory may have been dirtied."
990 echo
991 fi
992 fail_build
993 fi
994 done
995
996 rm -f "$patch_record"
997}
998
999undo_local_patches() {
1000 pushd "$tf_root"
1001 patch_record="$tf_patch_record" undo_patch_record
1002 popd
1003
1004 if [ -d "$tftf_root" ]; then
1005 pushd "$tftf_root"
1006 patch_record="$tftf_patch_record" undo_patch_record
1007 popd
1008 fi
1009}
1010
1011undo_tftf_patches() {
1012 pushd "$tftf_root"
1013 patch_record="$tftf_patch_record" undo_patch_record
1014 popd
1015}
1016
1017undo_tf_patches() {
1018 pushd "$tf_root"
1019 patch_record="$tf_patch_record" undo_patch_record
1020 popd
1021}
1022
1023apply_patch() {
1024 # If skip_patches is set, the developer has applied required patches
1025 # manually. They probably want to keep them applied for debugging
1026 # purposes too. This means we don't have to apply/revert them as part of
1027 # build process.
1028 if upon "$skip_patches"; then
1029 echo "Skipped applying ${1:?}..."
1030 return 0
1031 else
1032 echo "Applying ${1:?}..."
1033 fi
1034
Sandrine Bailleux4cb8c222023-09-13 13:48:15 +02001035 if git apply --reverse --check < "$ci_root/patch/$1" 2> /dev/null; then
Jimmy Brissonf134e4c2023-03-22 13:20:20 -05001036 echo "Skipping already applied ${1:?}"
1037 return 0
1038 fi
1039
Fathi Boudra422bf772019-12-02 11:10:16 +02001040 if git apply < "$ci_root/patch/$1"; then
1041 echo "$1" >> "${patch_record:?}"
1042 else
1043 if upon "$local_ci"; then
1044 undo_local_patches
1045 fi
1046 fail_build
1047 fi
1048}
1049
Fathi Boudra422bf772019-12-02 11:10:16 +02001050apply_tf_patch() {
Boyan Karatotevfaf9a9d2025-07-28 09:52:05 +01001051 root="$tf_root"
1052 new_root="$archive/tfa_mirror"
1053
1054 # paralell builds are only used locally. Don't do for CI since this will
1055 # have a speed penalty. Also skip if this was already done as a single
1056 # job may apply many patches.
1057 if upon "$local_ci" && [[ ! -d $new_root ]]; then
1058 root=$new_root
1059 diff=$(mktempfile)
1060
1061 # get anything still uncommitted
1062 pushd $tf_root
1063 git diff HEAD > $diff
1064 popd
1065
1066 # git will hard link when cloning locally, no need for --depth=1
1067 git clone "$tf_root" $root --shallow-submodules
1068
1069 tf_root=$root # next apply_tf_patch will run in the same hook
1070 set_hook_var "tf_root" "$root" # for anyone outside the hook
1071
1072 # apply uncommited changes so they are picked up in the build
1073 pushd $tf_root
1074 git apply $diff &> /dev/null || true
1075 popd
1076
1077 fi
1078
1079 pushd "$root"
Fathi Boudra422bf772019-12-02 11:10:16 +02001080 patch_record="$tf_patch_record" apply_patch "$1"
1081 popd
1082}
1083
Fathi Boudra422bf772019-12-02 11:10:16 +02001084mkdir -p "$workspace"
1085mkdir -p "$archive"
1086set_package_var "TEST_CONFIG" "$test_config"
1087
1088{
1089echo
1090echo "CONFIGURATION: $test_group/$test_config"
1091echo
1092} |& log_separator
1093
1094tf_config="$(echo "$build_configs" | awk -F, '{print $1}')"
1095tftf_config="$(echo "$build_configs" | awk -F, '{print $2}')"
Chris Kay4f7846a2025-08-04 19:56:35 +01001096spm_config="$(echo "$build_configs" | awk -F, '{print $3}')"
1097rmm_config="$(echo "$build_configs" | awk -F, '{print $4}')"
Juan Pablo Conde3feb7f12023-10-21 13:14:47 -05001098tfut_config="$(echo "$build_configs" | awk -F, '{print $5}')"
Fathi Boudra422bf772019-12-02 11:10:16 +02001099
1100test_config_file="$ci_root/group/$test_group/$test_config"
1101
1102tf_config_file="$ci_root/tf_config/$tf_config"
1103tftf_config_file="$ci_root/tftf_config/$tftf_config"
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001104spm_config_file="$ci_root/spm_config/$spm_config"
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +00001105rmm_config_file="$ci_root/rmm_config/$rmm_config"
Juan Pablo Conde3feb7f12023-10-21 13:14:47 -05001106tfut_config_file="$ci_root/tfut_config/$tfut_config"
Fathi Boudra422bf772019-12-02 11:10:16 +02001107
1108# File that keeps track of applied patches
1109tf_patch_record="$workspace/tf_patches"
1110tftf_patch_record="$workspace/tftf_patches"
1111
1112pushd "$workspace"
1113
1114if ! config_valid "$tf_config"; then
1115 tf_config=
1116else
1117 echo "Trusted Firmware config:"
1118 echo
1119 sort "$tf_config_file" | sed '/^\s*$/d;s/^/\t/'
1120 echo
1121fi
1122
1123if ! config_valid "$tftf_config"; then
1124 tftf_config=
1125else
1126 echo "Trusted Firmware TF config:"
1127 echo
1128 sort "$tftf_config_file" | sed '/^\s*$/d;s/^/\t/'
1129 echo
1130fi
1131
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001132if ! config_valid "$spm_config"; then
1133 spm_config=
1134else
1135 echo "SPM config:"
1136 echo
1137 sort "$spm_config_file" | sed '/^\s*$/d;s/^/\t/'
Zelalem219df412020-05-17 19:21:20 -05001138 echo
1139fi
1140
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +00001141# File that keeps track of applied patches
1142rmm_patch_record="$workspace/rmm_patches"
1143
1144if ! config_valid "$rmm_config"; then
1145 rmm_config=
1146else
1147 echo "Trusted Firmware RMM config:"
1148 echo
1149 sort "$rmm_config_file" | sed '/^\s*$/d;s/^/\t/'
1150 echo
1151fi
1152
Juan Pablo Conde3feb7f12023-10-21 13:14:47 -05001153if ! config_valid "$tfut_config"; then
1154 tfut_config=
1155else
1156 echo "TFUT config:"
1157 echo
1158 sort "$tfut_config_file" | sed '/^\s*$/d;s/^/\t/'
1159 echo
1160fi
1161
Fathi Boudra422bf772019-12-02 11:10:16 +02001162if ! config_valid "$run_config"; then
1163 run_config=
1164fi
1165
Juan Pablo Conde3feb7f12023-10-21 13:14:47 -05001166if { [ "$tf_config" ] || [ "$tfut_config" ]; } && assert_can_git_clone "tf_root"; then
Fathi Boudra422bf772019-12-02 11:10:16 +02001167 # If the Trusted Firmware repository has already been checked out, use
1168 # that location. Otherwise, clone one ourselves.
1169 echo "Cloning Trusted Firmware..."
1170 clone_url="${TF_CHECKOUT_LOC:-$tf_src_repo_url}" where="$tf_root" \
1171 refspec="$TF_REFSPEC" clone_repo &>>"$build_log"
1172 show_head "$tf_root"
1173fi
1174
1175if [ "$tftf_config" ] && assert_can_git_clone "tftf_root"; then
1176 # If the Trusted Firmware TF repository has already been checked out,
1177 # use that location. Otherwise, clone one ourselves.
1178 echo "Cloning Trusted Firmware TF..."
1179 clone_url="${TFTF_CHECKOUT_LOC:-$tftf_src_repo_url}" where="$tftf_root" \
1180 refspec="$TFTF_REFSPEC" clone_repo &>>"$build_log"
1181 show_head "$tftf_root"
1182fi
1183
Zelalem219df412020-05-17 19:21:20 -05001184if [ -n "$cc_config" ] ; then
1185 if [ "$cc_config" -eq 1 ] && assert_can_git_clone "cc_root"; then
1186 # Copy code coverage repository
1187 echo "Cloning Code Coverage..."
1188 git clone -q $cc_src_repo_url cc_plugin --depth 1 -b $cc_src_repo_tag > /dev/null
1189 show_head "$cc_root"
1190 fi
1191fi
1192
Daniel Boulby25385ab2023-12-14 14:36:25 +00001193if [ "$spm_config" ] ; then
1194 if assert_can_git_clone "spm_root"; then
1195 # If the SPM repository has already been checked out, use
1196 # that location. Otherwise, clone one ourselves.
1197 echo "Cloning SPM..."
1198 clone_url="${SPM_CHECKOUT_LOC:-$spm_src_repo_url}" \
1199 where="$spm_root" refspec="$SPM_REFSPEC" \
1200 clone_repo &>>"$build_log"
1201 fi
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001202
1203 # Query git submodules
1204 pushd "$spm_root"
Daniel Boulby25385ab2023-12-14 14:36:25 +00001205 # Check if submodules need initialising
Paul Sokolovskyad274422024-09-01 10:27:56 +03001206
1207 # This handling is needed to reliably fetch submodules
1208 # in CI environment.
1209 for subm in $(git submodule status | awk '/^-/ {print $2}'); do
1210 for i in $(seq 1 7); do
1211 git submodule init $subm
1212 if git submodule update $subm; then
1213 break
1214 fi
1215 git submodule deinit --force $subm
1216 echo "Retrying $subm"
1217 sleep $((RANDOM % 10 + 5))
1218 done
1219 done
1220
1221 git submodule status
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001222 popd
1223
1224 show_head "$spm_root"
1225fi
1226
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +00001227if [ "$rmm_config" ] && assert_can_git_clone "rmm_root"; then
Manish V Badarkhe41909452025-04-11 12:06:45 +01001228 # If the RMM repository has already been checked out,
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +00001229 # use that location. Otherwise, clone one ourselves.
1230 echo "Cloning TF-RMM..."
1231 clone_url="${RMM_CHECKOUT_LOC:-$rmm_src_repo_url}" where="$rmm_root" \
1232 refspec="$RMM_REFSPEC" clone_repo &>>"$build_log"
1233 show_head "$rmm_root"
1234fi
1235
Juan Pablo Conde3feb7f12023-10-21 13:14:47 -05001236if [ "$tfut_config" ] && assert_can_git_clone "tfut_root"; then
1237 # If the Trusted Firmware UT repository has already been checked out,
1238 # use that location. Otherwise, clone one ourselves.
1239 echo "Cloning Trusted Firmware UT..."
1240 clone_url="${TFUT_CHECKOUT_LOC:-$tfut_src_repo_url}" where="$tfut_root" \
1241 refspec="$TFUT_GERRIT_REFSPEC" clone_repo &>>"$build_log"
1242 show_head "$tfut_root"
1243fi
1244
Fathi Boudra422bf772019-12-02 11:10:16 +02001245if [ "$run_config" ]; then
1246 # Get candidates for run config
Nicola Mazzucato7fc5abd2024-02-23 21:32:48 +00001247 run_config_candidates="$("$ci_root/script/gen_run_config_candidates.py" \
Fathi Boudra422bf772019-12-02 11:10:16 +02001248 "$run_config")"
Nicola Mazzucato7fc5abd2024-02-23 21:32:48 +00001249 if [ -z "$run_config_candidates" ]; then
Fathi Boudra422bf772019-12-02 11:10:16 +02001250 die "No run config candidates!"
1251 else
1252 echo
1253 echo "Chosen fragments:"
1254 echo
Nicola Mazzucato7fc5abd2024-02-23 21:32:48 +00001255 echo "$run_config_candidates" | sed 's/^\|\n/\t/g'
Fathi Boudra422bf772019-12-02 11:10:16 +02001256 echo
Harrison Mutai4dfe1192024-07-03 12:35:38 +00001257
1258 if [ ! -n "$bin_mode" ]; then
1259 if echo $run_config_candidates | grep -wq "debug"; then
1260 bin_mode="debug"
1261 else
1262 bin_mode="release"
1263 fi
1264 fi
Fathi Boudra422bf772019-12-02 11:10:16 +02001265 fi
1266fi
1267
1268call_hook "test_setup"
1269echo
1270
1271if upon "$local_ci"; then
1272 # For local runs, since each config is tried in sequence, it's
1273 # advantageous to run jobs in parallel
1274 if [ "$make_j" ]; then
1275 make_j_opts="-j $make_j"
1276 else
1277 n_cores="$(getconf _NPROCESSORS_ONLN)" 2>/dev/null || true
1278 if [ "$n_cores" ]; then
1279 make_j_opts="-j $n_cores"
1280 fi
1281 fi
1282fi
1283
Harrison Mutai07043e92023-07-06 09:41:12 +01001284# Install python build dependencies
1285if is_arm_jenkins_env; then
1286 source "$ci_root/script/install_python_deps.sh"
1287fi
1288
Juan Pablo Conde3feb7f12023-10-21 13:14:47 -05001289# Install c-picker dependency
1290if config_valid "$tfut_config"; then
1291 echo "started building"
1292 python3 -m venv .venv
1293 source .venv/bin/activate
1294
1295 if ! python3 -m pip show c-picker &> /dev/null; then
1296 echo "Installing c-picker"
1297 pip install git+https://git.trustedfirmware.org/TS/trusted-services.git@topics/c-picker || {
1298 echo "c-picker was not installed!"
1299 exit 1
1300 }
1301 echo "c-picker was installed"
1302 else
1303 echo "c-picker is already installed"
1304 fi
1305fi
1306
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +00001307# Print CMake version
1308cmake_ver=$(echo `cmake --version | sed -n '1p'`)
1309echo "Using $cmake_ver"
1310
1311# Check for Ninja
1312if [ -x "$(command -v ninja)" ]; then
1313 # Print Ninja version
1314 ninja_ver=$(echo `ninja --version | sed -n '1p'`)
1315 echo "Using ninja $ninja_ver"
1316 export cmake_gen="-G Ninja"
1317else
1318 echo 'Ninja is not installed'
1319 export cmake_gen=""
1320fi
1321
1322undo_rmm_patches() {
1323 pushd "$rmm_root"
1324 patch_record="$rmm_patch_record" undo_patch_record
1325 popd
1326}
1327
Fathi Boudra422bf772019-12-02 11:10:16 +02001328modes="${bin_mode:-debug release}"
1329for mode in $modes; do
Paul Sokolovskye9962cd2021-12-17 18:39:40 +03001330 echo "===== Building package in mode: $mode ====="
Fathi Boudra422bf772019-12-02 11:10:16 +02001331 # Build with a temporary archive
1332 build_archive="$archive/$mode"
1333 mkdir "$build_archive"
1334
1335 if [ "$mode" = "debug" ]; then
Zelalem219df412020-05-17 19:21:20 -05001336 export bin_mode="debug"
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +00001337 cmake_build_type="Debug"
Fathi Boudra422bf772019-12-02 11:10:16 +02001338 DEBUG=1
1339 else
Zelalem219df412020-05-17 19:21:20 -05001340 export bin_mode="release"
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +00001341 cmake_build_type="Release"
Fathi Boudra422bf772019-12-02 11:10:16 +02001342 DEBUG=0
1343 fi
1344
1345 # Perform builds in a subshell so as not to pollute the current and
1346 # subsequent builds' environment
1347
Zelalem219df412020-05-17 19:21:20 -05001348 if config_valid "$cc_config"; then
1349 # Build code coverage plugin
1350 build_cc
1351 fi
1352
Fathi Boudra422bf772019-12-02 11:10:16 +02001353 # TFTF build
1354 if config_valid "$tftf_config"; then
1355 (
1356 echo "##########"
1357
Manish V Badarkhe3bd3fea2020-11-08 15:17:00 +00001358 plat_utils="$(get_tf_opt PLAT_UTILS)"
1359 if [ -z ${plat_utils} ]; then
1360 # Source platform-specific utilities.
1361 plat="$(get_tftf_opt PLAT)"
1362 plat_utils="$ci_root/${plat}_utils.sh"
1363 else
1364 # Source platform-specific utilities by
1365 # using plat_utils name.
1366 plat_utils="$ci_root/${plat_utils}.sh"
1367 fi
1368
Fathi Boudra422bf772019-12-02 11:10:16 +02001369 if [ -f "$plat_utils" ]; then
1370 source "$plat_utils"
1371 fi
1372
1373 archive="$build_archive"
Boyan Karatotev97de8d82025-03-06 15:22:21 +00001374 tftf_build_root="$archive/build/tftf"
1375 mkdir -p ${tftf_build_root}
Fathi Boudra422bf772019-12-02 11:10:16 +02001376
1377 echo "Building Trusted Firmware TF ($mode) ..." |& log_separator
1378
1379 # Call pre-build hook
1380 call_hook pre_tftf_build
1381
1382 build_tftf
1383
1384 from="$tftf_build_root" to="$archive" collect_build_artefacts
1385
1386 # Clear any local changes made by applied patches
1387 undo_tftf_patches
1388
1389 echo "##########"
1390 echo
1391 )
1392 fi
1393
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001394 # SPM build
1395 if config_valid "$spm_config"; then
1396 (
1397 echo "##########"
1398
1399 # Get platform name from spm_config file
1400 plat="$(echo "$spm_config" | awk -F- '{print $1}')"
1401 plat_utils="$ci_root/${plat}_utils.sh"
1402 if [ -f "$plat_utils" ]; then
1403 source "$plat_utils"
1404 fi
1405
Daniel Boulbyb8d2a462022-03-07 13:55:25 +00001406 # Call pre-build hook
1407 call_hook pre_spm_build
1408
Manish Pandey1e7be852020-11-09 16:04:48 +00001409 # SPM build generates two sets of binaries, one for normal and other
1410 # for Secure world. We need both set of binaries for CI.
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001411 archive="$build_archive"
Boyan Karatotev27057342025-07-28 09:56:23 +01001412 spm_build_root="$archive/build/spm"
1413
1414 spm_secure_build_root="$spm_build_root/$spm_secure_out_dir"
1415 spm_ns_build_root="$spm_build_root/$spm_non_secure_out_dir"
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001416
Daniel Boulbyb8d2a462022-03-07 13:55:25 +00001417 echo "spm_build_root is $spm_build_root"
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001418 echo "Building SPM ($mode) ..." |& log_separator
1419
1420 # NOTE: mode has no effect on SPM build (for now), hence debug
1421 # mode is built but subsequent build using release mode just
1422 # goes through with "nothing to do".
1423 build_spm
1424
1425 # Show SPM/Hafnium binary details
Boyan Karatotev27057342025-07-28 09:56:23 +01001426 cksum $spm_secure_build_root/hafnium.bin
Madhukar Pappireddyc683cf62021-11-01 14:38:32 -05001427
1428 # Some platforms only have secure configuration enabled. Hence,
1429 # non secure hanfnium binary might not be built.
Boyan Karatotev27057342025-07-28 09:56:23 +01001430 if [ -f $spm_ns_build_root/hafnium.bin ]; then
1431 cksum $spm_ns_build_root/hafnium.bin
Madhukar Pappireddyc683cf62021-11-01 14:38:32 -05001432 fi
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001433
Boyan Karatotev27057342025-07-28 09:56:23 +01001434 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 +01001435
1436 echo "##########"
1437 echo
1438 )
1439 fi
1440
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +00001441 # TF RMM build
1442 if config_valid "$rmm_config"; then
1443 (
1444 echo "##########"
1445
1446 plat_utils="$(get_rmm_opt PLAT_UTILS)"
1447 if [ -z ${plat_utils} ]; then
1448 # Source platform-specific utilities.
1449 plat="$(get_rmm_opt PLAT)"
Manish V Badarkhea3505272025-04-17 14:20:42 +01001450 extra_options="$(get_rmm_opt EXTRA_OPTIONS)"
1451 extra_targets="$(get_rmm_opt EXTRA_TARGETS "")"
1452 rmm_toolchain="$(get_rmm_opt TOOLCHAIN gnu)"
1453 rmm_fpu_use_at_rel2="$(get_rmm_opt RMM_FPU_USE_AT_REL2 OFF)"
1454 rmm_attest_el3_token_sign="$(get_rmm_opt ATTEST_EL3_TOKEN_SIGN OFF)"
1455 rmm_v1_1="$(get_rmm_opt RMM_V1_1 ON)"
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +00001456 plat_utils="$ci_root/${plat}_utils.sh"
1457 else
1458 # Source platform-specific utilities by
1459 # using plat_utils name.
1460 plat_utils="$ci_root/${plat_utils}.sh"
1461 fi
1462
1463 if [ -f "$plat_utils" ]; then
1464 source "$plat_utils"
1465 fi
1466
1467 archive="$build_archive"
1468 rmm_build_root="$rmm_root/build"
1469
1470 echo "Building Trusted Firmware RMM ($mode) ..." |& log_separator
1471
1472 #call_hook pre_rmm_build
1473 build_rmm
1474
1475 # Collect all rmm.* files: rmm.img, rmm.elf, rmm.dump, rmm.map
1476 from="$rmm_build_root" to="$archive" collect_build_artefacts
1477
1478 # Clear any local changes made by applied patches
1479 undo_rmm_patches
1480
1481 echo "##########"
1482 )
1483 fi
1484
Fathi Boudra422bf772019-12-02 11:10:16 +02001485 # TF build
1486 if config_valid "$tf_config"; then
1487 (
1488 echo "##########"
1489
Manish V Badarkhe3bd3fea2020-11-08 15:17:00 +00001490 plat_utils="$(get_tf_opt PLAT_UTILS)"
Madhukar Pappireddy2f284e12021-08-30 16:06:14 -05001491 export plat_variant="$(get_tf_opt TARGET_PLATFORM)"
1492
Manish V Badarkhe3bd3fea2020-11-08 15:17:00 +00001493 if [ -z ${plat_utils} ]; then
1494 # Source platform-specific utilities.
1495 plat="$(get_tf_opt PLAT)"
1496 plat_utils="$ci_root/${plat}_utils.sh"
1497 else
1498 # Source platform-specific utilities by
1499 # using plat_utils name.
1500 plat_utils="$ci_root/${plat_utils}.sh"
1501 fi
1502
Fathi Boudra422bf772019-12-02 11:10:16 +02001503 if [ -f "$plat_utils" ]; then
1504 source "$plat_utils"
1505 fi
1506
Chris Kaye5a486b2023-08-04 11:50:31 +00001507 fvp_tsram_size="$(get_tf_opt FVP_TRUSTED_SRAM_SIZE)"
1508 fvp_tsram_size="${fvp_tsram_size:-256}"
1509
Harrison Mutaidc703402024-08-02 14:40:16 +00001510 poetry -C "$tf_root" install --without docs
Chris Kayd0837902021-11-17 10:17:52 +00001511
Fathi Boudra422bf772019-12-02 11:10:16 +02001512 archive="$build_archive"
Boyan Karatotev97de8d82025-03-06 15:22:21 +00001513 tf_build_root="$archive/build/tfa"
1514 mkdir -p ${tf_build_root}
Fathi Boudra422bf772019-12-02 11:10:16 +02001515
1516 echo "Building Trusted Firmware ($mode) ..." |& log_separator
1517
1518 # Call pre-build hook
1519 call_hook pre_tf_build
1520
1521 build_tf
1522
1523 # Call post-build hook
1524 call_hook post_tf_build
1525
1526 # Pre-archive hook
1527 call_hook pre_tf_archive
1528
1529 from="$tf_build_root" to="$archive" collect_build_artefacts
1530
1531 # Post-archive hook
1532 call_hook post_tf_archive
1533
1534 call_hook fetch_tf_resource
1535 call_hook post_fetch_tf_resource
1536
Chris Kay4e8aaf12022-09-01 15:21:55 +01001537 # Generate LAVA job files if necessary
1538 call_hook generate_lava_job_template
1539 call_hook generate_lava_job
1540
Fathi Boudra422bf772019-12-02 11:10:16 +02001541 # Clear any local changes made by applied patches
1542 undo_tf_patches
1543
1544 echo "##########"
1545 )
1546 fi
1547
Juan Pablo Conde3feb7f12023-10-21 13:14:47 -05001548 # TFUT build
1549 if config_valid "$tfut_config"; then
1550 (
1551 echo "##########"
1552
1553 archive="$build_archive"
1554 tfut_build_root="$tfut_root/build"
1555
1556 echo "Building Trusted Firmware UT ($mode) ..." |& log_separator
1557
1558 # Call pre-build hook
1559 call_hook pre_tfut_build
1560
1561 build_tfut
1562
1563 from="$tfut_build_root" to="$archive" collect_tfut_artefacts
1564
1565 echo "##########"
1566 echo
1567 )
1568 fi
Fathi Boudra422bf772019-12-02 11:10:16 +02001569 echo
1570 echo
1571done
1572
Juan Pablo Conde3feb7f12023-10-21 13:14:47 -05001573if config_valid "$tfut_config"; then
1574 deactivate
1575fi
1576
Fathi Boudra422bf772019-12-02 11:10:16 +02001577call_hook pre_package
1578
1579call_hook post_package
1580
1581if upon "$jenkins_run" && upon "$artefacts_receiver" && [ -d "artefacts" ]; then
Zelalem219df412020-05-17 19:21:20 -05001582 source "$CI_ROOT/script/send_artefacts.sh" "artefacts"
Fathi Boudra422bf772019-12-02 11:10:16 +02001583fi
1584
1585echo
1586echo "Done"