blob: b3b1b1e680fa45937278de8b58b584a4c983f771 [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}"
Zelalem219df412020-05-17 19:21:20 -050023cc_root="${cc_root:-$ccpathspec}"
Olivier Deprez0a9a3482019-12-16 14:10:31 +010024spm_root="${spm_root:-$workspace/spm}"
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +000025rmm_root="${rmm_root:-$workspace/tf-rmm}"
Zelalem219df412020-05-17 19:21:20 -050026
Fathi Boudra422bf772019-12-02 11:10:16 +020027# Refspecs
28tf_refspec="$TF_REFSPEC"
29tftf_refspec="$TFTF_REFSPEC"
Olivier Deprez0a9a3482019-12-16 14:10:31 +010030spm_refspec="$SPM_REFSPEC"
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +000031rmm_refspec="$RMM_REFSPEC"
Fathi Boudra422bf772019-12-02 11:10:16 +020032
33test_config="${TEST_CONFIG:?}"
34test_group="${TEST_GROUP:?}"
35build_configs="${BUILD_CONFIG:?}"
36run_config="${RUN_CONFIG:?}"
Zelalem219df412020-05-17 19:21:20 -050037cc_config="${CC_ENABLE:-}"
Fathi Boudra422bf772019-12-02 11:10:16 +020038
Boyan Karatotev97de8d82025-03-06 15:22:21 +000039export archive="$artefacts"
Fathi Boudra422bf772019-12-02 11:10:16 +020040build_log="$artefacts/build.log"
Boyan Karatotevde2cd442025-07-28 09:50:29 +010041
42fiptool_path() {
43 echo $tf_build_root/$(get_tf_opt PLAT)/${bin_mode}/tools/fiptool/fiptool
44}
45
46cert_create_path() {
47 echo $tf_build_root/$(get_tf_opt PLAT)/${bin_mode}/tools/cert_create/cert_create
48}
Fathi Boudra422bf772019-12-02 11:10:16 +020049
50# Validate $bin_mode
51case "$bin_mode" in
52 "" | debug | release)
53 ;;
54 *)
55 die "Invalid value for bin_mode: $bin_mode"
56 ;;
57esac
58
59# File to save any environem
60hook_env_file="$(mktempfile)"
61
62# Check if a config is valid
63config_valid() {
64 local config="${1?}"
65 if [ -z "$config" ] || [ "$(basename "$config")" = "nil" ]; then
66 return 1
67 fi
68
69 return 0
70}
71
72# Echo from a build wrapper. Print to descriptor 3 that's opened by the build
73# function.
74echo_w() {
75 echo $echo_flags "$@" >&3
76}
77
78# Print a separator to the log file. Intended to be used at the tail end of a pipe
79log_separator() {
80 {
81 echo
82 echo "----------"
83 } >> "$build_log"
84
85 tee -a "$build_log"
86
87 {
88 echo "----------"
89 echo
90 } >> "$build_log"
91}
92
93# Call function $1 if it's defined
94call_func() {
95 if type "${1:?}" &>/dev/null; then
96 echo
97 echo "> ${2:?}:$1()"
98 eval "$1"
99 echo "< $2:$1()"
100 fi
101}
102
Paul Sokolovskybe6510c2024-08-15 21:54:00 +0300103# Retry a command a number of times if it fails. Intended for I/O commands
104# in a CI environment which may be flaky.
105function retry() {
106 for i in $(seq 1 3); do
107 if "$@"; then
108 return 0
109 fi
110 sleep $(( i * 5 ))
111 done
112 return 1
113}
114
Fathi Boudra422bf772019-12-02 11:10:16 +0200115# Call hook $1 in all chosen fragments if it's defined. Hooks are invoked from
116# within a subshell, so any variables set within a hook are lost. Should a
117# variable needs to be set from within a hook, the function 'set_hook_var'
118# should be used
119call_hook() {
120 local func="$1"
121 local config_fragment
122
123 [ -z "$func" ] && return 0
124
Paul Sokolovskye9962cd2021-12-17 18:39:40 +0300125 echo "=== Calling hooks: $1 ==="
126
Fathi Boudra422bf772019-12-02 11:10:16 +0200127 : >"$hook_env_file"
128
Nicola Mazzucato7fc5abd2024-02-23 21:32:48 +0000129 if [ "$run_config_candidates" ]; then
130 for config_fragment in $run_config_candidates; do
Fathi Boudra422bf772019-12-02 11:10:16 +0200131 (
132 source "$ci_root/run_config/$config_fragment"
133 call_func "$func" "$config_fragment"
134 )
135 done
136 fi
137
138 # Also source test config file
139 (
140 unset "$func"
141 source "$test_config_file"
142 call_func "$func" "$(basename $test_config_file)"
143 )
144
145 # Have any variables set take effect
146 source "$hook_env_file"
Paul Sokolovskye9962cd2021-12-17 18:39:40 +0300147
148 echo "=== End calling hooks: $1 ==="
Fathi Boudra422bf772019-12-02 11:10:16 +0200149}
150
151# Set a variable from within a hook
152set_hook_var() {
153 echo "export $1=\"${2?}\"" >> "$hook_env_file"
154}
155
156# Append to an array from within a hook
157append_hook_var() {
158 echo "export $1+=\"${2?}\"" >> "$hook_env_file"
159}
160
161# Have the main build script source a file
162source_later() {
163 echo "source ${1?}" >> "$hook_env_file"
164}
165
166# Setup TF build wrapper function by pointing to a script containing a function
167# that will be called with the TF build commands.
168setup_tf_build_wrapper() {
169 source_later "$ci_root/script/${wrapper?}_wrapper.sh"
170 set_hook_var "tf_build_wrapper" "${wrapper}_wrapper"
171 echo "Setup $wrapper build wrapper."
172}
173
174# Collect .bin files for archiving
175collect_build_artefacts() {
176 if [ ! -d "${from:?}" ]; then
177 return
178 fi
179
Manish V Badarkhe84c3a482025-04-16 08:15:38 +0100180 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 +0200181 echo "You probably are running local CI on local repositories."
182 echo "Did you set 'dont_clean' but forgot to run 'distclean'?"
183 die
184 fi
185}
186
Manish Pandey1e7be852020-11-09 16:04:48 +0000187# Collect SPM/hafnium artefacts with "secure_" appended to the files
188# generated for SPM(secure hafnium).
189collect_spm_artefacts() {
Madhukar Pappireddyc683cf62021-11-01 14:38:32 -0500190 if [ -d "${non_secure_from:?}" ]; then
191 find "$non_secure_from" \( -name "*.bin" -o -name '*.elf' \) -exec cp -t "${to:?}" '{}' +
Manish Pandey1e7be852020-11-09 16:04:48 +0000192 fi
193
Madhukar Pappireddyc683cf62021-11-01 14:38:32 -0500194 if [ -d "${secure_from:?}" ]; then
195 for f in $(find "$secure_from" \( -name "*.bin" -o -name '*.elf' \)); do cp -- "$f" "${to:?}"/secure_$(basename $f); done
196 fi
Manish Pandey1e7be852020-11-09 16:04:48 +0000197}
198
Javier Almansa Sobrino412d3612020-05-22 17:53:12 +0100199# Map the UART ID used for expect with the UART descriptor and port
200# used by the FPGA automation tools.
201map_uart() {
202 local port="${port:?}"
203 local descriptor="${descriptor:?}"
204 local baudrate="${baudrate:?}"
205 local run_root="${archive:?}/run"
206
207 local uart_dir="$run_root/uart${uart:?}"
208 mkdir -p "$uart_dir"
209
210 echo "$port" > "$uart_dir/port"
211 echo "$descriptor" > "$uart_dir/descriptor"
212 echo "$baudrate" > "$uart_dir/baudrate"
213
214 echo "UART${uart} mapped to port ${port} with descriptor ${descriptor} and baudrate ${baudrate}"
215}
216
Fathi Boudra422bf772019-12-02 11:10:16 +0200217# Arrange environment varibles to be set when expect scripts are launched
218set_expect_variable() {
219 local var="${1:?}"
220 local val="${2?}"
221
222 local run_root="${archive:?}/run"
223 local uart_dir="$run_root/uart${uart:?}"
224 mkdir -p "$uart_dir"
225
226 env_file="$uart_dir/env" quote="1" emit_env "$var" "$val"
227 echo "UART$uart: env has $@"
228}
229
230# Place the binary package a pointer to expect script, and its parameters
231track_expect() {
232 local file="${file:?}"
233 local timeout="${timeout-600}"
234 local run_root="${archive:?}/run"
235
236 local uart_dir="$run_root/uart${uart:?}"
237 mkdir -p "$uart_dir"
238
239 echo "$file" > "$uart_dir/expect"
240 echo "$timeout" > "$uart_dir/timeout"
Paul Sokolovskybfa8bab2023-01-25 19:34:51 +0700241 if [ -n "$lava_timeout" ]; then
242 set_run_env "lava_timeout" "$lava_timeout"
243 fi
Fathi Boudra422bf772019-12-02 11:10:16 +0200244
Paul Sokolovskybfa8bab2023-01-25 19:34:51 +0700245 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 +0200246
Chris Kayfab6edc2022-11-17 19:18:32 +0000247 if [ ! -z "${port}" ]; then
248 echo "${port}" > "$uart_dir/port"
249 fi
250
Fathi Boudra422bf772019-12-02 11:10:16 +0200251 # The run script assumes UART0 to be primary. If we're asked to set any
252 # other UART to be primary, set a run environment variable to signal
253 # that to the run script
254 if upon "$set_primary"; then
255 echo "Primary UART set to UART$uart."
256 set_run_env "primary_uart" "$uart"
257 fi
Madhukar Pappireddy1e953722021-11-08 15:23:02 -0600258
259 # UART used by payload(such as tftf, Linux) may not be the same as the
260 # primary UART. Set a run environment variable to track the payload
261 # UART which is tracked to check if the test has finished sucessfully.
262 if upon "$set_payload_uart"; then
263 echo "Payload uses UART$uart."
264 set_run_env "payload_uart" "$uart"
265 fi
Fathi Boudra422bf772019-12-02 11:10:16 +0200266}
267
268# Extract a FIP in $1 using fiptool
269extract_fip() {
270 local fip="$1"
271
272 if is_url "$1"; then
273 url="$1" fetch_file
274 fip="$(basename "$1")"
275 fi
276
Boyan Karatotevde2cd442025-07-28 09:50:29 +0100277 fiptool=$(fiptool_path)
Fathi Boudra422bf772019-12-02 11:10:16 +0200278 "$fiptool" unpack "$fip"
279 echo "Extracted FIP: $fip"
280}
281
282# Report build failure by printing a the tail end of build log. Archive the
283# build log for later inspection
284fail_build() {
285 local log_path
286
287 if upon "$jenkins_run"; then
288 log_path="$BUILD_URL/artifact/artefacts/build.log"
289 else
290 log_path="$build_log"
291 fi
292
293 echo
Leonardo Sandovalae97eda2020-11-12 10:07:03 -0600294 echo "Build failed! Full build log below:"
Fathi Boudra422bf772019-12-02 11:10:16 +0200295 echo "[...]"
296 echo
Leonardo Sandovalae97eda2020-11-12 10:07:03 -0600297 cat "$build_log"
Fathi Boudra422bf772019-12-02 11:10:16 +0200298 echo
299 echo "See $log_path for full output"
300 echo
301 cp -t "$archive" "$build_log"
302 exit 1;
303}
304
305# Build a FIP with supplied arguments
306build_fip() {
307 (
308 echo "Building FIP with arguments: $@"
309 local tf_env="$workspace/tf.env"
310
311 if [ -f "$tf_env" ]; then
312 set -a
313 source "$tf_env"
314 set +a
315 fi
316
Slava Andrianov192ee172025-06-11 15:40:43 -0500317 if [ "$(get_tf_opt MEASURED_BOOT)" = 1 ]; then
318 # These are needed for accurate hash verification
319 local build_args_path="${workspace}/fip_build_args"
320 echo $@ > $build_args_path
321 archive_file $build_args_path
322 fi
323
Boyan Karatotev99e12312025-05-02 15:00:24 +0100324 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 +0200325 ${fip_targets:-fip} &>>"$build_log" || fail_build
326 )
327}
328
Sandrine Bailleux189fdb32023-10-20 13:41:22 +0200329# Build any extra rule from TF-A makefile with supplied arguments.
330#
331# This is useful in case you need to build something else than firmware binaries
332# or the FIP.
333build_tf_extra() {
334 (
335 tf_extra_rules=${tf_extra_rules:?}
336 echo "Building extra TF rule(s): $tf_extra_rules"
337 echo " Arguments: $@"
338
339 local tf_env="$workspace/tf.env"
340
341 if [ -f "$tf_env" ]; then
342 set -a
343 source "$tf_env"
344 set +a
345 fi
346
Boyan Karatotev99e12312025-05-02 15:00:24 +0100347 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 +0200348 ${tf_extra_rules} &>>"$build_log" || fail_build
349 )
350}
351
Fathi Boudra422bf772019-12-02 11:10:16 +0200352fip_update() {
Boyan Karatotevde2cd442025-07-28 09:50:29 +0100353 fiptool=$(fiptool_path)
Fathi Boudra422bf772019-12-02 11:10:16 +0200354 # Before the update process, check if the given image is supported by
355 # the fiptool. It's assumed that both fiptool and cert_create move in
Chris Kay197b1022023-08-16 21:31:41 +0100356 # tandem, and therefore, if one has support, the other has it too.
357 if ! ("$fiptool" update 2>&1 || true) | grep -qe "\s\+--${bin_name:?}"; then
Fathi Boudra422bf772019-12-02 11:10:16 +0200358 return 1
359 fi
360
361 if not_upon "$(get_tf_opt TRUSTED_BOARD_BOOT)"; then
362 echo "Updating FIP image: $bin_name"
363 # Update HW config. Without TBBR, it's only a matter of using
364 # the update sub-command of fiptool
365 "$fiptool" update "--$bin_name" "${src:-}" \
366 "$archive/fip.bin"
367 else
368 echo "Updating FIP image (TBBR): $bin_name"
369 # With TBBR, we need to unpack, re-create certificates, and then
370 # recreate the FIP.
371 local fip_dir="$(mktempdir)"
372 local bin common_args stem
373 local rot_key="$(get_tf_opt ROT_KEY)"
374
375 rot_key="${rot_key:?}"
376 if ! is_abs "$rot_key"; then
377 rot_key="$tf_root/$rot_key"
378 fi
379
380 # Arguments only for cert_create
381 local cert_args="-n"
382 cert_args+=" --tfw-nvctr ${nvctr:-31}"
383 cert_args+=" --ntfw-nvctr ${nvctr:-223}"
384 cert_args+=" --key-alg ${KEY_ALG:-rsa}"
385 cert_args+=" --rot-key $rot_key"
386
387 local dyn_config_opts=(
Zelalem1af7a7b2020-08-04 17:34:32 -0500388 "fw-config"
Fathi Boudra422bf772019-12-02 11:10:16 +0200389 "hw-config"
390 "tb-fw-config"
391 "nt-fw-config"
392 "soc-fw-config"
393 "tos-fw-config"
394 )
395
396 # Binaries without key certificates
397 declare -A has_no_key_cert
398 for bin in "tb-fw" "${dyn_config_opts[@]}"; do
399 has_no_key_cert["$bin"]="1"
400 done
401
402 # Binaries without certificates
403 declare -A has_no_cert
404 for bin in "hw-config" "${dyn_config_opts[@]}"; do
405 has_no_cert["$bin"]="1"
406 done
407
408 pushd "$fip_dir"
409
410 # Unpack FIP
411 "$fiptool" unpack "$archive/fip.bin" &>>"$build_log"
412
413 # Remove all existing certificates
414 rm -f *-cert.bin
415
416 # Copy the binary to be updated
417 cp -f "$src" "${bin_name}.bin"
418
419 # FIP unpack dumps binaries with the same name as the option
420 # used to pack it; likewise for certificates. Reverse-engineer
421 # the command line from the binary output.
422 common_args="--trusted-key-cert trusted_key.crt"
423 for bin in *.bin; do
424 stem="${bin%%.bin}"
425 common_args+=" --$stem $bin"
426 if not_upon "${has_no_cert[$stem]}"; then
427 common_args+=" --$stem-cert $stem.crt"
428 fi
429 if not_upon "${has_no_key_cert[$stem]}"; then
430 common_args+=" --$stem-key-cert $stem-key.crt"
431 fi
432 done
433
434 # Create certificates
Boyan Karatotevde2cd442025-07-28 09:50:29 +0100435 cert_create=$(cert_create_path)
Fathi Boudra422bf772019-12-02 11:10:16 +0200436 "$cert_create" $cert_args $common_args &>>"$build_log"
437
438 # Recreate and archive FIP
439 "$fiptool" create $common_args "fip.bin" &>>"$build_log"
440 archive_file "fip.bin"
441
442 popd
443 fi
444}
445
446# Update hw-config in FIP, and remove the original DTB afterwards.
447update_fip_hw_config() {
448 # The DTB needs to be loaded by the model (and not updated in the FIP)
Madhukar Pappireddy9062ebf2021-03-02 17:07:06 -0600449 # in configs:
450 # 1. Where BL2 isn't present
451 # 2. Where we boot to Linux directly as BL33
Fathi Boudra422bf772019-12-02 11:10:16 +0200452 case "1" in
453 "$(get_tf_opt RESET_TO_BL31)" | \
Madhukar Pappireddy9062ebf2021-03-02 17:07:06 -0600454 "$(get_tf_opt ARM_LINUX_KERNEL_AS_BL33)" | \
Fathi Boudra422bf772019-12-02 11:10:16 +0200455 "$(get_tf_opt RESET_TO_SP_MIN)" | \
Maksims Svecovs7a0da522023-03-06 16:28:27 +0000456 "$(get_tf_opt RESET_TO_BL2)")
Fathi Boudra422bf772019-12-02 11:10:16 +0200457 return 0;;
458 esac
459
460 if bin_name="hw-config" src="$archive/dtb.bin" fip_update; then
461 # Remove the DTB so that model won't load it
462 rm -f "$archive/dtb.bin"
463 fi
464}
465
Fathi Boudra422bf772019-12-02 11:10:16 +0200466get_tftf_opt() {
467 (
468 name="${1:?}"
469 if config_valid "$tftf_config_file"; then
470 source "$tftf_config_file"
471 echo "${!name}"
472 fi
473 )
474}
475
476get_tf_opt() {
477 (
478 name="${1:?}"
479 if config_valid "$tf_config_file"; then
480 source "$tf_config_file"
481 echo "${!name}"
482 fi
483 )
484}
485
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +0000486get_rmm_opt() {
487 (
488 name="${1:?}"
Manish V Badarkhea3505272025-04-17 14:20:42 +0100489 default="$2"
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +0000490 if config_valid "$rmm_config_file"; then
491 source "$rmm_config_file"
Manish V Badarkhea3505272025-04-17 14:20:42 +0100492 # If !name is not defined, go with the default
493 # value (if defined)
494 if [ -z "${!name}" ]; then
495 echo "$default"
496 else
497 echo "${!name}"
498 fi
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +0000499 fi
500 )
501}
502
Fathi Boudra422bf772019-12-02 11:10:16 +0200503build_tf() {
504 (
505 env_file="$workspace/tf.env"
506 config_file="${tf_build_config:-$tf_config_file}"
507
508 # Build fiptool and all targets by default
Harrison Mutai32de9d02023-06-12 14:23:37 +0100509 build_targets="${tf_build_targets:-fiptool all}"
Fathi Boudra422bf772019-12-02 11:10:16 +0200510
511 source "$config_file"
512
513 # If it is a TBBR build, extract the MBED TLS library from archive
Manish V Badarkhe8f125012021-12-21 05:47:52 +0000514 if [ "$(get_tf_opt TRUSTED_BOARD_BOOT)" = 1 ] ||
Manish V Badarkhef43e3f52022-06-21 20:37:25 +0100515 [ "$(get_tf_opt MEASURED_BOOT)" = 1 ] ||
516 [ "$(get_tf_opt DRTM_SUPPORT)" = 1 ]; then
Fathi Boudra422bf772019-12-02 11:10:16 +0200517 mbedtls_dir="$workspace/mbedtls"
518 if [ ! -d "$mbedtls_dir" ]; then
519 mbedtls_ar="$workspace/mbedtls.tar.gz"
520
521 url="$mbedtls_archive" saveas="$mbedtls_ar" fetch_file
522 mkdir "$mbedtls_dir"
Leonardo Sandovalec9e16c2020-09-09 14:32:40 -0500523 extract_tarball $mbedtls_ar $mbedtls_dir --strip-components=1
Fathi Boudra422bf772019-12-02 11:10:16 +0200524 fi
525
526 emit_env "MBEDTLS_DIR" "$mbedtls_dir"
527 fi
Jimmy Brisson0d5e12c2023-05-16 14:51:51 -0500528 if [ "$(get_tf_opt PLATFORM_TEST)" = "tfm-testsuite" ] &&
529 not_upon "${TF_M_TESTS_PATH}"; then
530 emit_env "TF_M_TESTS_PATH" "$WORKSPACE/tf-m-tests"
531 fi
532 if [ "$(get_tf_opt PLATFORM_TEST)" = "tfm-testsuite" ] &&
533 not_upon "${TF_M_EXTRAS_PATH}"; then
534 emit_env "TF_M_EXTRAS_PATH" "$WORKSPACE/tf-m-extras"
535 fi
David Vincze82db6932024-02-21 12:05:50 +0100536 if [ "$(get_tf_opt DICE_PROTECTION_ENVIRONMENT)" = 1 ] &&
537 not_upon "${QCBOR_DIR}"; then
538 emit_env "QCBOR_DIR" "$WORKSPACE/qcbor"
539 fi
Slava Andrianov192ee172025-06-11 15:40:43 -0500540
541 # Hash verification only occurs if there is a sufficient amount of
542 # information in the event log, which is as long as EVENT_LOG_LEVEL
543 # is set to at least 20 or if it is a debug build
544 if [[ ("$(get_tf_opt MEASURED_BOOT)" -eq 1) &&
545 (($bin_mode == "debug") || ("$(get_tf_opt EVENT_LOG_LEVEL)" -ge 20)) ]]; then
546 # This variable is later exported to the expect scripts so
547 # the hashes in the TF-A event log can be verified
548 set_run_env "verify_hashes" "1"
549 fi
Fathi Boudra422bf772019-12-02 11:10:16 +0200550 if [ -f "$env_file" ]; then
551 set -a
552 source "$env_file"
553 set +a
554 fi
555
Harrison Mutai013f6332022-02-16 16:06:33 +0000556 if is_arm_jenkins_env || upon "$local_ci"; then
557 path_list=(
558 "$llvm_dir/bin"
559 )
560 extend_path "PATH" "path_list"
561 fi
562
Boyan Karatotev97de8d82025-03-06 15:22:21 +0000563 pushd "$tf_root"
Fathi Boudra422bf772019-12-02 11:10:16 +0200564
565 # Always distclean when running on Jenkins. Skip distclean when running
566 # locally and explicitly requested.
567 if upon "$jenkins_run" || not_upon "$dont_clean"; then
Boyan Karatotev97de8d82025-03-06 15:22:21 +0000568 make distclean BUILD_BASE=$tf_build_root &>>"$build_log" || fail_build
Fathi Boudra422bf772019-12-02 11:10:16 +0200569 fi
570
571 # Log build command line. It is left unfolded on purpose to assist
572 # copying to clipboard.
573 cat <<EOF | log_separator >/dev/null
574
575Build command line:
Boyan Karatotev97de8d82025-03-06 15:22:21 +0000576 $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 +0200577
Paul Sokolovsky7f71b072023-10-16 12:59:09 +0300578CC version:
579$(${CC-${CROSS_COMPILE}gcc} -v 2>&1)
Fathi Boudra422bf772019-12-02 11:10:16 +0200580EOF
581
Javier Almansa Sobrinoe8363182020-11-10 16:40:53 +0000582 if not_upon "$local_ci"; then
583 connect_debugger=0
584 fi
585
Fathi Boudra422bf772019-12-02 11:10:16 +0200586 # Build TF. Since build output is being directed to the build log, have
587 # descriptor 3 point to the current terminal for build wrappers to vent.
Harrison Mutai6361dbe2023-02-16 14:12:40 +0000588 $tf_build_wrapper poetry run make $make_j_opts $(cat "$config_file") \
Boyan Karatotev97de8d82025-03-06 15:22:21 +0000589 DEBUG="$DEBUG" V=1 BUILD_BASE="$tf_build_root" SPIN_ON_BL1_EXIT="$connect_debugger" \
Fathi Boudra422bf772019-12-02 11:10:16 +0200590 $build_targets 3>&1 &>>"$build_log" || fail_build
Harrison Mutai32de9d02023-06-12 14:23:37 +0100591
Harrison Mutai6dafb5f2023-07-18 15:21:48 +0100592 if [ "$build_targets" != "doc" ]; then
Chris Kay9ab2d952025-05-29 13:46:24 +0100593 (poetry run memory --root "$tf_build_root" symbols 2>&1 || true) | tee -a "${build_log}"
594
595 for map in $(find "${tf_build_root}" -name '*.map'); do
596 (poetry run memory --root "${tf_build_root}" summary "${map}" 2>&1 || true) | tee -a "${build_log}"
597 done
Harrison Mutai6dafb5f2023-07-18 15:21:48 +0100598 fi
Boyan Karatotev97de8d82025-03-06 15:22:21 +0000599 popd
Fathi Boudra422bf772019-12-02 11:10:16 +0200600 )
601}
602
603build_tftf() {
604 (
605 config_file="${tftf_build_config:-$tftf_config_file}"
606
607 # Build tftf target by default
608 build_targets="${tftf_build_targets:-all}"
609
610 source "$config_file"
611
612 cd "$tftf_root"
613
614 # Always distclean when running on Jenkins. Skip distclean when running
615 # locally and explicitly requested.
616 if upon "$jenkins_run" || not_upon "$dont_clean"; then
Boyan Karatotev97de8d82025-03-06 15:22:21 +0000617 make distclean BUILD_BASE="$tftf_build_root" &>>"$build_log" || fail_build
Fathi Boudra422bf772019-12-02 11:10:16 +0200618 fi
619
620 # TFTF build system cannot reliably deal with -j option, so we avoid
621 # using that.
622
623 # Log build command line
624 cat <<EOF | log_separator >/dev/null
625
626Build command line:
Boyan Karatotev97de8d82025-03-06 15:22:21 +0000627 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 +0200628
629EOF
630
Boyan Karatotev97de8d82025-03-06 15:22:21 +0000631 make $make_j_opts $(cat "$config_file") DEBUG="$DEBUG" V=1 BUILD_BASE="$tftf_build_root" \
Fathi Boudra422bf772019-12-02 11:10:16 +0200632 $build_targets &>>"$build_log" || fail_build
633 )
634}
635
Zelalem219df412020-05-17 19:21:20 -0500636build_cc() {
637# Building code coverage plugin
638 ARM_DIR=/arm
639 pvlibversion=$(/arm/devsys-tools/abs/detag "SysGen:PVModelLib:$model_version::trunk")
640 PVLIB_HOME=$warehouse/SysGen/PVModelLib/$model_version/${pvlibversion}/external
641 if [ -n "$(find "$ARM_DIR" -maxdepth 0 -type d -empty 2>/dev/null)" ]; then
642 echo "Error: Arm warehouse not mounted. Please mount the Arm warehouse to your /arm local folder"
643 exit -1
644 fi # Error if arm warehouse not found
645 cd "$ccpathspec/scripts/tools/code_coverage/fastmodel_baremetal/bmcov"
646
647 make -C model-plugin PVLIB_HOME=$PVLIB_HOME &>>"$build_log"
648}
649
Olivier Deprez0a9a3482019-12-16 14:10:31 +0100650build_spm() {
651 (
652 env_file="$workspace/spm.env"
653 config_file="${spm_build_config:-$spm_config_file}"
654
655 source "$config_file"
656
657 if [ -f "$env_file" ]; then
658 set -a
659 source "$env_file"
660 set +a
661 fi
662
663 cd "$spm_root"
664
665 # Always clean when running on Jenkins. Skip clean when running
666 # locally and explicitly requested.
667 if upon "$jenkins_run" || not_upon "$dont_clean"; then
668 # make clean fails on a fresh repo where the project has not
669 # yet been built. Hence only clean if out/reference directory
670 # already exists.
671 if [ -d "out/reference" ]; then
672 make clean &>>"$build_log" || fail_build
673 fi
674 fi
675
676 # Log build command line. It is left unfolded on purpose to assist
677 # copying to clipboard.
678 cat <<EOF | log_separator >/dev/null
679
680Build command line:
Boyan Karatotev27057342025-07-28 09:56:23 +0100681 make $make_j_opts OUT=$spm_build_root $(cat "$config_file" | tr '\n' ' ')
Olivier Deprez0a9a3482019-12-16 14:10:31 +0100682
683EOF
684
685 # Build SPM. Since build output is being directed to the build log, have
686 # descriptor 3 point to the current terminal for build wrappers to vent.
Boyan Karatotev27057342025-07-28 09:56:23 +0100687 make $make_j_opts OUT=$spm_build_root $(cat "$config_file") 3>&1 &>>"$build_log" \
Olivier Deprez0a9a3482019-12-16 14:10:31 +0100688 || fail_build
689 )
690}
Zelalem219df412020-05-17 19:21:20 -0500691
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +0000692build_rmm() {
693 (
694 env_file="$workspace/rmm.env"
695 config_file="${rmm_build_config:-$rmm_config_file}"
696
697 # Build fiptool and all targets by default
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +0000698 export CROSS_COMPILE="${aarch64_none_elf_prefix}"
699
700 source "$config_file"
701
702 if [ -f "$env_file" ]; then
703 set -a
704 source "$env_file"
705 set +a
706 fi
707
708 cd "$rmm_root"
709
710 if [ -f "$rmm_root/requirements.txt" ]; then
711 export PATH="$HOME/.local/bin:$PATH"
712 python3 -m pip install --upgrade pip
713 python3 -m pip install -r "$rmm_root/requirements.txt"
714 fi
715
716 # Always distclean when running on Jenkins. Skip distclean when running
717 # locally and explicitly requested.
718 if upon "$jenkins_run" || not_upon "$dont_clean"; then
719 # Remove 'rmm\build' folder
720 echo "Removing $rmm_build_root..."
721 rm -rf $rmm_build_root
722 fi
723
Manish V Badarkhea3505272025-04-17 14:20:42 +0100724 if not_upon "$local_ci"; then
725 connect_debugger=0
726 fi
727
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +0000728 # Log build command line. It is left unfolded on purpose to assist
729 # copying to clipboard.
730 cat <<EOF | log_separator >/dev/null
731
732Build command line:
Manish V Badarkhea3505272025-04-17 14:20:42 +0100733 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}
734 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 +0000735
Manish V Badarkhea3505272025-04-17 14:20:42 +0100736EOF
737 cmake \
738 -DRMM_CONFIG=${plat}_defcfg $cmake_gen \
739 -S $rmm_root -B $rmm_build_root \
740 -DRMM_TOOLCHAIN=$rmm_toolchain \
741 -DRMM_FPU_USE_AT_REL2=$rmm_fpu_use_at_rel2 \
742 -DATTEST_EL3_TOKEN_SIGN=$rmm_attest_el3_token_sign \
743 -DRMM_V1_1=$rmm_v1_1 \
744 ${extra_options}
745 cmake --build $rmm_build_root --config $cmake_build_type $make_j_opts -v ${extra_targets+-- $extra_targets} 3>&1 &>>"$build_log" || fail_build
746 )
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +0000747}
748
Fathi Boudra422bf772019-12-02 11:10:16 +0200749# Set metadata for the whole package so that it can be used by both Jenkins and
750# shell
751set_package_var() {
752 env_file="$artefacts/env" emit_env "$@"
753}
754
755set_tf_build_targets() {
756 echo "Set build target to '${targets:?}'"
757 set_hook_var "tf_build_targets" "$targets"
758}
759
760set_tftf_build_targets() {
761 echo "Set build target to '${targets:?}'"
762 set_hook_var "tftf_build_targets" "$targets"
763}
764
Olivier Deprez0a9a3482019-12-16 14:10:31 +0100765set_spm_build_targets() {
766 echo "Set build target to '${targets:?}'"
767 set_hook_var "spm_build_targets" "$targets"
768}
769
Daniel Boulbyb8d2a462022-03-07 13:55:25 +0000770set_spm_out_dir() {
771 echo "Set SPMC binary build to '${out_dir:?}'"
772 set_hook_var "spm_secure_out_dir" "$out_dir"
773}
Fathi Boudra422bf772019-12-02 11:10:16 +0200774# Look under $archive directory for known files such as blX images, kernel, DTB,
775# initrd etc. For each known file foo, if foo.bin exists, then set variable
776# foo_bin to the path of the file. Make the path relative to the workspace so as
777# to remove any @ characters, which Jenkins inserts for parallel runs. If the
778# file doesn't exist, unset its path.
779set_default_bin_paths() {
780 local image image_name image_path path
781 local archive="${archive:?}"
782 local set_vars
783 local var
784
785 pushd "$archive"
786
787 for file in *.bin; do
788 # Get a shell variable from the file's stem
789 var_name="${file%%.*}_bin"
790 var_name="$(echo "$var_name" | sed -r 's/[^[:alnum:]]/_/g')"
791
792 # Skip setting the variable if it's already
793 if [ "${!var_name}" ]; then
794 echo "Note: not setting $var_name; already set to ${!var_name}"
795 continue
796 else
797 set_vars+="$var_name "
798 fi
799
800 eval "$var_name=$file"
801 done
802
803 echo "Binary paths set for: "
804 {
805 for var in $set_vars; do
806 echo -n "\$$var "
807 done
808 } | fmt -80 | sed 's/^/ /'
809 echo
810
811 popd
812}
813
814gen_model_params() {
815 local model_param_file="$archive/model_params"
Javier Almansa Sobrinoe8363182020-11-10 16:40:53 +0000816 [ "$connect_debugger" ] && [ "$connect_debugger" -eq 1 ] && wait_debugger=1
Fathi Boudra422bf772019-12-02 11:10:16 +0200817
818 set_default_bin_paths
819 echo "Generating model parameter for $model..."
820 source "$ci_root/model/${model:?}.sh"
821 archive_file "$model_param_file"
822}
823
824set_model_path() {
825 set_run_env "model_path" "${1:?}"
826}
827
Zelalem1af7a7b2020-08-04 17:34:32 -0500828set_model_env() {
829 local var="${1:?}"
830 local val="${2?}"
831 local run_root="${archive:?}/run"
832
833 mkdir -p "$run_root"
834 echo "export $var=$val" >> "$run_root/model_env"
835}
Fathi Boudra422bf772019-12-02 11:10:16 +0200836set_run_env() {
837 local var="${1:?}"
838 local val="${2?}"
839 local run_root="${archive:?}/run"
840
841 mkdir -p "$run_root"
842 env_file="$run_root/env" quote="1" emit_env "$var" "$val"
843}
844
845show_head() {
846 # Display HEAD descripton
847 pushd "$1"
848 git show --quiet --no-color | sed 's/^/ > /g'
849 echo
850 popd
851}
852
853# Choose debug binaries to run; by default, release binaries are chosen to run
854use_debug_bins() {
855 local run_root="${archive:?}/run"
856
857 echo "Choosing debug binaries for execution"
858 set_package_var "BIN_MODE" "debug"
859}
860
861assert_can_git_clone() {
862 local name="${1:?}"
863 local dir="${!name}"
864
865 # If it doesn't exist, it can be cloned into
866 if [ ! -e "$dir" ]; then
867 return 0
868 fi
869
870 # If it's a directory, it must be a Git clone already
871 if [ -d "$dir" ] && [ -d "$dir/.git" ]; then
872 # No need to clone again
873 echo "Using existing git clone for $name: $dir"
874 return 1
875 fi
876
877 die "Path $dir exists but is not a git clone"
878}
879
880clone_repo() {
881 if ! is_url "${clone_url?}"; then
882 # For --depth to take effect on local paths, it needs to use the
883 # file:// scheme.
884 clone_url="file://$clone_url"
885 fi
886
887 git clone -q --depth 1 "$clone_url" "${where?}"
888 if [ "$refspec" ]; then
889 pushd "$where"
890 git fetch -q --depth 1 origin "$refspec"
891 git checkout -q FETCH_HEAD
892 popd
893 fi
894}
895
896build_unstable() {
897 echo "--BUILD UNSTABLE--" | tee -a "$build_log"
898}
899
900undo_patch_record() {
901 if [ ! -f "${patch_record:?}" ]; then
902 return
903 fi
904
905 # Undo patches in reverse
906 echo
907 for patch_name in $(tac "$patch_record"); do
908 echo "Undoing $patch_name..."
909 if ! git apply -R "$ci_root/patch/$patch_name"; then
910 if upon "$local_ci"; then
911 echo
912 echo "Your local directory may have been dirtied."
913 echo
914 fi
915 fail_build
916 fi
917 done
918
919 rm -f "$patch_record"
920}
921
922undo_local_patches() {
923 pushd "$tf_root"
924 patch_record="$tf_patch_record" undo_patch_record
925 popd
926
927 if [ -d "$tftf_root" ]; then
928 pushd "$tftf_root"
929 patch_record="$tftf_patch_record" undo_patch_record
930 popd
931 fi
932}
933
934undo_tftf_patches() {
935 pushd "$tftf_root"
936 patch_record="$tftf_patch_record" undo_patch_record
937 popd
938}
939
940undo_tf_patches() {
941 pushd "$tf_root"
942 patch_record="$tf_patch_record" undo_patch_record
943 popd
944}
945
946apply_patch() {
947 # If skip_patches is set, the developer has applied required patches
948 # manually. They probably want to keep them applied for debugging
949 # purposes too. This means we don't have to apply/revert them as part of
950 # build process.
951 if upon "$skip_patches"; then
952 echo "Skipped applying ${1:?}..."
953 return 0
954 else
955 echo "Applying ${1:?}..."
956 fi
957
Sandrine Bailleux4cb8c222023-09-13 13:48:15 +0200958 if git apply --reverse --check < "$ci_root/patch/$1" 2> /dev/null; then
Jimmy Brissonf134e4c2023-03-22 13:20:20 -0500959 echo "Skipping already applied ${1:?}"
960 return 0
961 fi
962
Fathi Boudra422bf772019-12-02 11:10:16 +0200963 if git apply < "$ci_root/patch/$1"; then
964 echo "$1" >> "${patch_record:?}"
965 else
966 if upon "$local_ci"; then
967 undo_local_patches
968 fi
969 fail_build
970 fi
971}
972
Fathi Boudra422bf772019-12-02 11:10:16 +0200973apply_tf_patch() {
Boyan Karatotevfaf9a9d2025-07-28 09:52:05 +0100974 root="$tf_root"
975 new_root="$archive/tfa_mirror"
976
977 # paralell builds are only used locally. Don't do for CI since this will
978 # have a speed penalty. Also skip if this was already done as a single
979 # job may apply many patches.
980 if upon "$local_ci" && [[ ! -d $new_root ]]; then
981 root=$new_root
982 diff=$(mktempfile)
983
984 # get anything still uncommitted
985 pushd $tf_root
986 git diff HEAD > $diff
987 popd
988
989 # git will hard link when cloning locally, no need for --depth=1
990 git clone "$tf_root" $root --shallow-submodules
991
992 tf_root=$root # next apply_tf_patch will run in the same hook
993 set_hook_var "tf_root" "$root" # for anyone outside the hook
994
995 # apply uncommited changes so they are picked up in the build
996 pushd $tf_root
997 git apply $diff &> /dev/null || true
998 popd
999
1000 fi
1001
1002 pushd "$root"
Fathi Boudra422bf772019-12-02 11:10:16 +02001003 patch_record="$tf_patch_record" apply_patch "$1"
1004 popd
1005}
1006
Fathi Boudra422bf772019-12-02 11:10:16 +02001007mkdir -p "$workspace"
1008mkdir -p "$archive"
1009set_package_var "TEST_CONFIG" "$test_config"
1010
1011{
1012echo
1013echo "CONFIGURATION: $test_group/$test_config"
1014echo
1015} |& log_separator
1016
1017tf_config="$(echo "$build_configs" | awk -F, '{print $1}')"
1018tftf_config="$(echo "$build_configs" | awk -F, '{print $2}')"
Chris Kay4f7846a2025-08-04 19:56:35 +01001019spm_config="$(echo "$build_configs" | awk -F, '{print $3}')"
1020rmm_config="$(echo "$build_configs" | awk -F, '{print $4}')"
Fathi Boudra422bf772019-12-02 11:10:16 +02001021
1022test_config_file="$ci_root/group/$test_group/$test_config"
1023
1024tf_config_file="$ci_root/tf_config/$tf_config"
1025tftf_config_file="$ci_root/tftf_config/$tftf_config"
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001026spm_config_file="$ci_root/spm_config/$spm_config"
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +00001027rmm_config_file="$ci_root/rmm_config/$rmm_config"
Fathi Boudra422bf772019-12-02 11:10:16 +02001028
1029# File that keeps track of applied patches
1030tf_patch_record="$workspace/tf_patches"
1031tftf_patch_record="$workspace/tftf_patches"
1032
1033pushd "$workspace"
1034
1035if ! config_valid "$tf_config"; then
1036 tf_config=
1037else
1038 echo "Trusted Firmware config:"
1039 echo
1040 sort "$tf_config_file" | sed '/^\s*$/d;s/^/\t/'
1041 echo
1042fi
1043
1044if ! config_valid "$tftf_config"; then
1045 tftf_config=
1046else
1047 echo "Trusted Firmware TF config:"
1048 echo
1049 sort "$tftf_config_file" | sed '/^\s*$/d;s/^/\t/'
1050 echo
1051fi
1052
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001053if ! config_valid "$spm_config"; then
1054 spm_config=
1055else
1056 echo "SPM config:"
1057 echo
1058 sort "$spm_config_file" | sed '/^\s*$/d;s/^/\t/'
Zelalem219df412020-05-17 19:21:20 -05001059 echo
1060fi
1061
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +00001062# File that keeps track of applied patches
1063rmm_patch_record="$workspace/rmm_patches"
1064
1065if ! config_valid "$rmm_config"; then
1066 rmm_config=
1067else
1068 echo "Trusted Firmware RMM config:"
1069 echo
1070 sort "$rmm_config_file" | sed '/^\s*$/d;s/^/\t/'
1071 echo
1072fi
1073
Fathi Boudra422bf772019-12-02 11:10:16 +02001074if ! config_valid "$run_config"; then
1075 run_config=
1076fi
1077
1078if [ "$tf_config" ] && assert_can_git_clone "tf_root"; then
1079 # If the Trusted Firmware repository has already been checked out, use
1080 # that location. Otherwise, clone one ourselves.
1081 echo "Cloning Trusted Firmware..."
1082 clone_url="${TF_CHECKOUT_LOC:-$tf_src_repo_url}" where="$tf_root" \
1083 refspec="$TF_REFSPEC" clone_repo &>>"$build_log"
1084 show_head "$tf_root"
1085fi
1086
1087if [ "$tftf_config" ] && assert_can_git_clone "tftf_root"; then
1088 # If the Trusted Firmware TF repository has already been checked out,
1089 # use that location. Otherwise, clone one ourselves.
1090 echo "Cloning Trusted Firmware TF..."
1091 clone_url="${TFTF_CHECKOUT_LOC:-$tftf_src_repo_url}" where="$tftf_root" \
1092 refspec="$TFTF_REFSPEC" clone_repo &>>"$build_log"
1093 show_head "$tftf_root"
1094fi
1095
Zelalem219df412020-05-17 19:21:20 -05001096if [ -n "$cc_config" ] ; then
1097 if [ "$cc_config" -eq 1 ] && assert_can_git_clone "cc_root"; then
1098 # Copy code coverage repository
1099 echo "Cloning Code Coverage..."
1100 git clone -q $cc_src_repo_url cc_plugin --depth 1 -b $cc_src_repo_tag > /dev/null
1101 show_head "$cc_root"
1102 fi
1103fi
1104
Daniel Boulby25385ab2023-12-14 14:36:25 +00001105if [ "$spm_config" ] ; then
1106 if assert_can_git_clone "spm_root"; then
1107 # If the SPM repository has already been checked out, use
1108 # that location. Otherwise, clone one ourselves.
1109 echo "Cloning SPM..."
1110 clone_url="${SPM_CHECKOUT_LOC:-$spm_src_repo_url}" \
1111 where="$spm_root" refspec="$SPM_REFSPEC" \
1112 clone_repo &>>"$build_log"
1113 fi
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001114
1115 # Query git submodules
1116 pushd "$spm_root"
Daniel Boulby25385ab2023-12-14 14:36:25 +00001117 # Check if submodules need initialising
Paul Sokolovskyad274422024-09-01 10:27:56 +03001118
1119 # This handling is needed to reliably fetch submodules
1120 # in CI environment.
1121 for subm in $(git submodule status | awk '/^-/ {print $2}'); do
1122 for i in $(seq 1 7); do
1123 git submodule init $subm
1124 if git submodule update $subm; then
1125 break
1126 fi
1127 git submodule deinit --force $subm
1128 echo "Retrying $subm"
1129 sleep $((RANDOM % 10 + 5))
1130 done
1131 done
1132
1133 git submodule status
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001134 popd
1135
1136 show_head "$spm_root"
1137fi
1138
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +00001139if [ "$rmm_config" ] && assert_can_git_clone "rmm_root"; then
Manish V Badarkhe41909452025-04-11 12:06:45 +01001140 # If the RMM repository has already been checked out,
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +00001141 # use that location. Otherwise, clone one ourselves.
1142 echo "Cloning TF-RMM..."
1143 clone_url="${RMM_CHECKOUT_LOC:-$rmm_src_repo_url}" where="$rmm_root" \
1144 refspec="$RMM_REFSPEC" clone_repo &>>"$build_log"
1145 show_head "$rmm_root"
1146fi
1147
Fathi Boudra422bf772019-12-02 11:10:16 +02001148if [ "$run_config" ]; then
1149 # Get candidates for run config
Nicola Mazzucato7fc5abd2024-02-23 21:32:48 +00001150 run_config_candidates="$("$ci_root/script/gen_run_config_candidates.py" \
Fathi Boudra422bf772019-12-02 11:10:16 +02001151 "$run_config")"
Nicola Mazzucato7fc5abd2024-02-23 21:32:48 +00001152 if [ -z "$run_config_candidates" ]; then
Fathi Boudra422bf772019-12-02 11:10:16 +02001153 die "No run config candidates!"
1154 else
1155 echo
1156 echo "Chosen fragments:"
1157 echo
Nicola Mazzucato7fc5abd2024-02-23 21:32:48 +00001158 echo "$run_config_candidates" | sed 's/^\|\n/\t/g'
Fathi Boudra422bf772019-12-02 11:10:16 +02001159 echo
Harrison Mutai4dfe1192024-07-03 12:35:38 +00001160
1161 if [ ! -n "$bin_mode" ]; then
1162 if echo $run_config_candidates | grep -wq "debug"; then
1163 bin_mode="debug"
1164 else
1165 bin_mode="release"
1166 fi
1167 fi
Fathi Boudra422bf772019-12-02 11:10:16 +02001168 fi
1169fi
1170
1171call_hook "test_setup"
1172echo
1173
1174if upon "$local_ci"; then
1175 # For local runs, since each config is tried in sequence, it's
1176 # advantageous to run jobs in parallel
1177 if [ "$make_j" ]; then
1178 make_j_opts="-j $make_j"
1179 else
1180 n_cores="$(getconf _NPROCESSORS_ONLN)" 2>/dev/null || true
1181 if [ "$n_cores" ]; then
1182 make_j_opts="-j $n_cores"
1183 fi
1184 fi
1185fi
1186
Harrison Mutai07043e92023-07-06 09:41:12 +01001187# Install python build dependencies
1188if is_arm_jenkins_env; then
1189 source "$ci_root/script/install_python_deps.sh"
1190fi
1191
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +00001192# Print CMake version
1193cmake_ver=$(echo `cmake --version | sed -n '1p'`)
1194echo "Using $cmake_ver"
1195
1196# Check for Ninja
1197if [ -x "$(command -v ninja)" ]; then
1198 # Print Ninja version
1199 ninja_ver=$(echo `ninja --version | sed -n '1p'`)
1200 echo "Using ninja $ninja_ver"
1201 export cmake_gen="-G Ninja"
1202else
1203 echo 'Ninja is not installed'
1204 export cmake_gen=""
1205fi
1206
1207undo_rmm_patches() {
1208 pushd "$rmm_root"
1209 patch_record="$rmm_patch_record" undo_patch_record
1210 popd
1211}
1212
Fathi Boudra422bf772019-12-02 11:10:16 +02001213modes="${bin_mode:-debug release}"
1214for mode in $modes; do
Paul Sokolovskye9962cd2021-12-17 18:39:40 +03001215 echo "===== Building package in mode: $mode ====="
Fathi Boudra422bf772019-12-02 11:10:16 +02001216 # Build with a temporary archive
1217 build_archive="$archive/$mode"
1218 mkdir "$build_archive"
1219
1220 if [ "$mode" = "debug" ]; then
Zelalem219df412020-05-17 19:21:20 -05001221 export bin_mode="debug"
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +00001222 cmake_build_type="Debug"
Fathi Boudra422bf772019-12-02 11:10:16 +02001223 DEBUG=1
1224 else
Zelalem219df412020-05-17 19:21:20 -05001225 export bin_mode="release"
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +00001226 cmake_build_type="Release"
Fathi Boudra422bf772019-12-02 11:10:16 +02001227 DEBUG=0
1228 fi
1229
1230 # Perform builds in a subshell so as not to pollute the current and
1231 # subsequent builds' environment
1232
Zelalem219df412020-05-17 19:21:20 -05001233 if config_valid "$cc_config"; then
1234 # Build code coverage plugin
1235 build_cc
1236 fi
1237
Fathi Boudra422bf772019-12-02 11:10:16 +02001238 # TFTF build
1239 if config_valid "$tftf_config"; then
1240 (
1241 echo "##########"
1242
Manish V Badarkhe3bd3fea2020-11-08 15:17:00 +00001243 plat_utils="$(get_tf_opt PLAT_UTILS)"
1244 if [ -z ${plat_utils} ]; then
1245 # Source platform-specific utilities.
1246 plat="$(get_tftf_opt PLAT)"
1247 plat_utils="$ci_root/${plat}_utils.sh"
1248 else
1249 # Source platform-specific utilities by
1250 # using plat_utils name.
1251 plat_utils="$ci_root/${plat_utils}.sh"
1252 fi
1253
Fathi Boudra422bf772019-12-02 11:10:16 +02001254 if [ -f "$plat_utils" ]; then
1255 source "$plat_utils"
1256 fi
1257
1258 archive="$build_archive"
Boyan Karatotev97de8d82025-03-06 15:22:21 +00001259 tftf_build_root="$archive/build/tftf"
1260 mkdir -p ${tftf_build_root}
Fathi Boudra422bf772019-12-02 11:10:16 +02001261
1262 echo "Building Trusted Firmware TF ($mode) ..." |& log_separator
1263
1264 # Call pre-build hook
1265 call_hook pre_tftf_build
1266
1267 build_tftf
1268
1269 from="$tftf_build_root" to="$archive" collect_build_artefacts
1270
1271 # Clear any local changes made by applied patches
1272 undo_tftf_patches
1273
1274 echo "##########"
1275 echo
1276 )
1277 fi
1278
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001279 # SPM build
1280 if config_valid "$spm_config"; then
1281 (
1282 echo "##########"
1283
1284 # Get platform name from spm_config file
1285 plat="$(echo "$spm_config" | awk -F- '{print $1}')"
1286 plat_utils="$ci_root/${plat}_utils.sh"
1287 if [ -f "$plat_utils" ]; then
1288 source "$plat_utils"
1289 fi
1290
Daniel Boulbyb8d2a462022-03-07 13:55:25 +00001291 # Call pre-build hook
1292 call_hook pre_spm_build
1293
Manish Pandey1e7be852020-11-09 16:04:48 +00001294 # SPM build generates two sets of binaries, one for normal and other
1295 # for Secure world. We need both set of binaries for CI.
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001296 archive="$build_archive"
Boyan Karatotev27057342025-07-28 09:56:23 +01001297 spm_build_root="$archive/build/spm"
1298
1299 spm_secure_build_root="$spm_build_root/$spm_secure_out_dir"
1300 spm_ns_build_root="$spm_build_root/$spm_non_secure_out_dir"
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001301
Daniel Boulbyb8d2a462022-03-07 13:55:25 +00001302 echo "spm_build_root is $spm_build_root"
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001303 echo "Building SPM ($mode) ..." |& log_separator
1304
1305 # NOTE: mode has no effect on SPM build (for now), hence debug
1306 # mode is built but subsequent build using release mode just
1307 # goes through with "nothing to do".
1308 build_spm
1309
1310 # Show SPM/Hafnium binary details
Boyan Karatotev27057342025-07-28 09:56:23 +01001311 cksum $spm_secure_build_root/hafnium.bin
Madhukar Pappireddyc683cf62021-11-01 14:38:32 -05001312
1313 # Some platforms only have secure configuration enabled. Hence,
1314 # non secure hanfnium binary might not be built.
Boyan Karatotev27057342025-07-28 09:56:23 +01001315 if [ -f $spm_ns_build_root/hafnium.bin ]; then
1316 cksum $spm_ns_build_root/hafnium.bin
Madhukar Pappireddyc683cf62021-11-01 14:38:32 -05001317 fi
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001318
Boyan Karatotev27057342025-07-28 09:56:23 +01001319 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 +01001320
1321 echo "##########"
1322 echo
1323 )
1324 fi
1325
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +00001326 # TF RMM build
1327 if config_valid "$rmm_config"; then
1328 (
1329 echo "##########"
1330
1331 plat_utils="$(get_rmm_opt PLAT_UTILS)"
1332 if [ -z ${plat_utils} ]; then
1333 # Source platform-specific utilities.
1334 plat="$(get_rmm_opt PLAT)"
Manish V Badarkhea3505272025-04-17 14:20:42 +01001335 extra_options="$(get_rmm_opt EXTRA_OPTIONS)"
1336 extra_targets="$(get_rmm_opt EXTRA_TARGETS "")"
1337 rmm_toolchain="$(get_rmm_opt TOOLCHAIN gnu)"
1338 rmm_fpu_use_at_rel2="$(get_rmm_opt RMM_FPU_USE_AT_REL2 OFF)"
1339 rmm_attest_el3_token_sign="$(get_rmm_opt ATTEST_EL3_TOKEN_SIGN OFF)"
1340 rmm_v1_1="$(get_rmm_opt RMM_V1_1 ON)"
Manish V Badarkhed62aa5f2025-03-18 21:18:14 +00001341 plat_utils="$ci_root/${plat}_utils.sh"
1342 else
1343 # Source platform-specific utilities by
1344 # using plat_utils name.
1345 plat_utils="$ci_root/${plat_utils}.sh"
1346 fi
1347
1348 if [ -f "$plat_utils" ]; then
1349 source "$plat_utils"
1350 fi
1351
1352 archive="$build_archive"
1353 rmm_build_root="$rmm_root/build"
1354
1355 echo "Building Trusted Firmware RMM ($mode) ..." |& log_separator
1356
1357 #call_hook pre_rmm_build
1358 build_rmm
1359
1360 # Collect all rmm.* files: rmm.img, rmm.elf, rmm.dump, rmm.map
1361 from="$rmm_build_root" to="$archive" collect_build_artefacts
1362
1363 # Clear any local changes made by applied patches
1364 undo_rmm_patches
1365
1366 echo "##########"
1367 )
1368 fi
1369
Fathi Boudra422bf772019-12-02 11:10:16 +02001370 # TF build
1371 if config_valid "$tf_config"; then
1372 (
1373 echo "##########"
1374
Manish V Badarkhe3bd3fea2020-11-08 15:17:00 +00001375 plat_utils="$(get_tf_opt PLAT_UTILS)"
Madhukar Pappireddy2f284e12021-08-30 16:06:14 -05001376 export plat_variant="$(get_tf_opt TARGET_PLATFORM)"
1377
Manish V Badarkhe3bd3fea2020-11-08 15:17:00 +00001378 if [ -z ${plat_utils} ]; then
1379 # Source platform-specific utilities.
1380 plat="$(get_tf_opt PLAT)"
1381 plat_utils="$ci_root/${plat}_utils.sh"
1382 else
1383 # Source platform-specific utilities by
1384 # using plat_utils name.
1385 plat_utils="$ci_root/${plat_utils}.sh"
1386 fi
1387
Fathi Boudra422bf772019-12-02 11:10:16 +02001388 if [ -f "$plat_utils" ]; then
1389 source "$plat_utils"
1390 fi
1391
Chris Kaye5a486b2023-08-04 11:50:31 +00001392 fvp_tsram_size="$(get_tf_opt FVP_TRUSTED_SRAM_SIZE)"
1393 fvp_tsram_size="${fvp_tsram_size:-256}"
1394
Harrison Mutaidc703402024-08-02 14:40:16 +00001395 poetry -C "$tf_root" install --without docs
Chris Kayd0837902021-11-17 10:17:52 +00001396
Fathi Boudra422bf772019-12-02 11:10:16 +02001397 archive="$build_archive"
Boyan Karatotev97de8d82025-03-06 15:22:21 +00001398 tf_build_root="$archive/build/tfa"
1399 mkdir -p ${tf_build_root}
Fathi Boudra422bf772019-12-02 11:10:16 +02001400
1401 echo "Building Trusted Firmware ($mode) ..." |& log_separator
1402
1403 # Call pre-build hook
1404 call_hook pre_tf_build
1405
1406 build_tf
1407
1408 # Call post-build hook
1409 call_hook post_tf_build
1410
1411 # Pre-archive hook
1412 call_hook pre_tf_archive
1413
1414 from="$tf_build_root" to="$archive" collect_build_artefacts
1415
1416 # Post-archive hook
1417 call_hook post_tf_archive
1418
1419 call_hook fetch_tf_resource
1420 call_hook post_fetch_tf_resource
1421
Chris Kay4e8aaf12022-09-01 15:21:55 +01001422 # Generate LAVA job files if necessary
1423 call_hook generate_lava_job_template
1424 call_hook generate_lava_job
1425
Fathi Boudra422bf772019-12-02 11:10:16 +02001426 # Clear any local changes made by applied patches
1427 undo_tf_patches
1428
1429 echo "##########"
1430 )
1431 fi
1432
1433 echo
1434 echo
1435done
1436
1437call_hook pre_package
1438
1439call_hook post_package
1440
1441if upon "$jenkins_run" && upon "$artefacts_receiver" && [ -d "artefacts" ]; then
Zelalem219df412020-05-17 19:21:20 -05001442 source "$CI_ROOT/script/send_artefacts.sh" "artefacts"
Fathi Boudra422bf772019-12-02 11:10:16 +02001443fi
1444
1445echo
1446echo "Done"