blob: d91ef1d9be4ca9e54b7082d1d4fc183b8f740c7e [file] [log] [blame]
Leonardo Sandoval9dfdd1b2020-08-06 17:08:11 -05001#!/usr/bin/env bash
Fathi Boudra422bf772019-12-02 11:10:16 +02002#
David Vincze82db6932024-02-21 12:05:50 +01003# Copyright (c) 2019-2024 Arm Limited. All rights reserved.
Fathi Boudra422bf772019-12-02 11:10:16 +02004#
5# SPDX-License-Identifier: BSD-3-Clause
6#
7
8# Builds a package with Trusted Firwmare and other payload binaries. The package
9# is meant to be executed by run_package.sh
10
11set -e
12
13ci_root="$(readlink -f "$(dirname "$0")/..")"
14source "$ci_root/utils.sh"
15
16if [ ! -d "$workspace" ]; then
17 die "Directory $workspace doesn't exist"
18fi
19
20# Directory to where the source code e.g. for Trusted Firmware is checked out.
Zelalem219df412020-05-17 19:21:20 -050021export tf_root="${tf_root:-$workspace/trusted_firmware}"
22export tftf_root="${tftf_root:-$workspace/trusted_firmware_tf}"
23export scp_root="${scp_root:-$workspace/scp}"
24scp_tools_root="${scp_tools_root:-$workspace/scp_tools}"
25cc_root="${cc_root:-$ccpathspec}"
Olivier Deprez0a9a3482019-12-16 14:10:31 +010026spm_root="${spm_root:-$workspace/spm}"
Zelalem219df412020-05-17 19:21:20 -050027
28scp_tf_tools_root="$scp_tools_root/scp_tf_tools"
Fathi Boudra422bf772019-12-02 11:10:16 +020029
30# Refspecs
31tf_refspec="$TF_REFSPEC"
32tftf_refspec="$TFTF_REFSPEC"
33scp_refspec="$SCP_REFSPEC"
Zelalem219df412020-05-17 19:21:20 -050034scp_tools_commit="${SCP_TOOLS_COMMIT:-master}"
Olivier Deprez0a9a3482019-12-16 14:10:31 +010035spm_refspec="$SPM_REFSPEC"
Fathi Boudra422bf772019-12-02 11:10:16 +020036
37test_config="${TEST_CONFIG:?}"
38test_group="${TEST_GROUP:?}"
39build_configs="${BUILD_CONFIG:?}"
40run_config="${RUN_CONFIG:?}"
Zelalem219df412020-05-17 19:21:20 -050041cc_config="${CC_ENABLE:-}"
Fathi Boudra422bf772019-12-02 11:10:16 +020042
43archive="$artefacts"
44build_log="$artefacts/build.log"
45fiptool="$tf_root/tools/fiptool/fiptool"
46cert_create="$tf_root/tools/cert_create/cert_create"
47
48# Validate $bin_mode
49case "$bin_mode" in
50 "" | debug | release)
51 ;;
52 *)
53 die "Invalid value for bin_mode: $bin_mode"
54 ;;
55esac
56
57# File to save any environem
58hook_env_file="$(mktempfile)"
59
60# Check if a config is valid
61config_valid() {
62 local config="${1?}"
63 if [ -z "$config" ] || [ "$(basename "$config")" = "nil" ]; then
64 return 1
65 fi
66
67 return 0
68}
69
70# Echo from a build wrapper. Print to descriptor 3 that's opened by the build
71# function.
72echo_w() {
73 echo $echo_flags "$@" >&3
74}
75
76# Print a separator to the log file. Intended to be used at the tail end of a pipe
77log_separator() {
78 {
79 echo
80 echo "----------"
81 } >> "$build_log"
82
83 tee -a "$build_log"
84
85 {
86 echo "----------"
87 echo
88 } >> "$build_log"
89}
90
91# Call function $1 if it's defined
92call_func() {
93 if type "${1:?}" &>/dev/null; then
94 echo
95 echo "> ${2:?}:$1()"
96 eval "$1"
97 echo "< $2:$1()"
98 fi
99}
100
101# Call hook $1 in all chosen fragments if it's defined. Hooks are invoked from
102# within a subshell, so any variables set within a hook are lost. Should a
103# variable needs to be set from within a hook, the function 'set_hook_var'
104# should be used
105call_hook() {
106 local func="$1"
107 local config_fragment
108
109 [ -z "$func" ] && return 0
110
Paul Sokolovskye9962cd2021-12-17 18:39:40 +0300111 echo "=== Calling hooks: $1 ==="
112
Fathi Boudra422bf772019-12-02 11:10:16 +0200113 : >"$hook_env_file"
114
Nicola Mazzucato7fc5abd2024-02-23 21:32:48 +0000115 if [ "$run_config_candidates" ]; then
116 for config_fragment in $run_config_candidates; do
Fathi Boudra422bf772019-12-02 11:10:16 +0200117 (
118 source "$ci_root/run_config/$config_fragment"
119 call_func "$func" "$config_fragment"
120 )
121 done
122 fi
123
124 # Also source test config file
125 (
126 unset "$func"
127 source "$test_config_file"
128 call_func "$func" "$(basename $test_config_file)"
129 )
130
131 # Have any variables set take effect
132 source "$hook_env_file"
Paul Sokolovskye9962cd2021-12-17 18:39:40 +0300133
134 echo "=== End calling hooks: $1 ==="
Fathi Boudra422bf772019-12-02 11:10:16 +0200135}
136
137# Set a variable from within a hook
138set_hook_var() {
139 echo "export $1=\"${2?}\"" >> "$hook_env_file"
140}
141
142# Append to an array from within a hook
143append_hook_var() {
144 echo "export $1+=\"${2?}\"" >> "$hook_env_file"
145}
146
147# Have the main build script source a file
148source_later() {
149 echo "source ${1?}" >> "$hook_env_file"
150}
151
152# Setup TF build wrapper function by pointing to a script containing a function
153# that will be called with the TF build commands.
154setup_tf_build_wrapper() {
155 source_later "$ci_root/script/${wrapper?}_wrapper.sh"
156 set_hook_var "tf_build_wrapper" "${wrapper}_wrapper"
157 echo "Setup $wrapper build wrapper."
158}
159
160# Collect .bin files for archiving
161collect_build_artefacts() {
162 if [ ! -d "${from:?}" ]; then
163 return
164 fi
165
Yann Gautier7e9d6cf2023-03-08 14:24:38 +0100166 if ! find "$from" \( -name "*.bin" -o -name '*.elf' -o -name '*.dtb' -o -name '*.axf' -o -name '*.stm32' \) -exec cp -t "${to:?}" '{}' +; then
Fathi Boudra422bf772019-12-02 11:10:16 +0200167 echo "You probably are running local CI on local repositories."
168 echo "Did you set 'dont_clean' but forgot to run 'distclean'?"
169 die
170 fi
171}
172
173# SCP and MCP binaries are named firmware.{bin,elf}, and are placed under
174# scp/mcp_ramfw and scp/mcp_romfw directories, so can't be collected by
175# collect_build_artefacts function.
176collect_scp_artefacts() {
177 to="${to:?}" \
Joel Goddard9bdfe3c2021-02-25 10:15:14 +0000178 find "$scp_root" \( \( -name "*.bin" -o -name '*.elf' \) -and ! -name 'CMake*' \) -exec bash -c '
Fathi Boudra422bf772019-12-02 11:10:16 +0200179 for file; do
180 ext="$(echo $file | awk -F. "{print \$NF}")"
181 case $file in
Anurag Koulbaedf932021-12-09 12:49:56 +0000182 */firmware-scp_ramfw/bin/*|*/firmware-scp_ramfw_fvp/bin/*)
Fathi Boudra422bf772019-12-02 11:10:16 +0200183 cp $file $to/scp_ram.$ext
184 ;;
Joel Goddard9bdfe3c2021-02-25 10:15:14 +0000185 */firmware-scp_romfw/bin/*)
Fathi Boudra422bf772019-12-02 11:10:16 +0200186 cp $file $to/scp_rom.$ext
187 ;;
Anurag Koulbaedf932021-12-09 12:49:56 +0000188 */firmware-mcp_ramfw/bin/*|*/firmware-mcp_ramfw_fvp/bin/*)
Fathi Boudra422bf772019-12-02 11:10:16 +0200189 cp $file $to/mcp_ram.$ext
190 ;;
Joel Goddard9bdfe3c2021-02-25 10:15:14 +0000191 */firmware-mcp_romfw/bin/*)
Fathi Boudra422bf772019-12-02 11:10:16 +0200192 cp $file $to/mcp_rom.$ext
193 ;;
Joel Goddard9bdfe3c2021-02-25 10:15:14 +0000194 */firmware-scp_romfw_bypass/bin/*)
Zelalem219df412020-05-17 19:21:20 -0500195 cp $file $to/scp_rom_bypass.$ext
196 ;;
Fathi Boudra422bf772019-12-02 11:10:16 +0200197 *)
198 echo "Unknown SCP binary: $file" >&2
199 ;;
200 esac
201 done
202 ' bash '{}' +
203}
204
Manish Pandey1e7be852020-11-09 16:04:48 +0000205# Collect SPM/hafnium artefacts with "secure_" appended to the files
206# generated for SPM(secure hafnium).
207collect_spm_artefacts() {
Madhukar Pappireddyc683cf62021-11-01 14:38:32 -0500208 if [ -d "${non_secure_from:?}" ]; then
209 find "$non_secure_from" \( -name "*.bin" -o -name '*.elf' \) -exec cp -t "${to:?}" '{}' +
Manish Pandey1e7be852020-11-09 16:04:48 +0000210 fi
211
Madhukar Pappireddyc683cf62021-11-01 14:38:32 -0500212 if [ -d "${secure_from:?}" ]; then
213 for f in $(find "$secure_from" \( -name "*.bin" -o -name '*.elf' \)); do cp -- "$f" "${to:?}"/secure_$(basename $f); done
214 fi
Manish Pandey1e7be852020-11-09 16:04:48 +0000215}
216
Javier Almansa Sobrino412d3612020-05-22 17:53:12 +0100217# Map the UART ID used for expect with the UART descriptor and port
218# used by the FPGA automation tools.
219map_uart() {
220 local port="${port:?}"
221 local descriptor="${descriptor:?}"
222 local baudrate="${baudrate:?}"
223 local run_root="${archive:?}/run"
224
225 local uart_dir="$run_root/uart${uart:?}"
226 mkdir -p "$uart_dir"
227
228 echo "$port" > "$uart_dir/port"
229 echo "$descriptor" > "$uart_dir/descriptor"
230 echo "$baudrate" > "$uart_dir/baudrate"
231
232 echo "UART${uart} mapped to port ${port} with descriptor ${descriptor} and baudrate ${baudrate}"
233}
234
Fathi Boudra422bf772019-12-02 11:10:16 +0200235# Arrange environment varibles to be set when expect scripts are launched
236set_expect_variable() {
237 local var="${1:?}"
238 local val="${2?}"
239
240 local run_root="${archive:?}/run"
241 local uart_dir="$run_root/uart${uart:?}"
242 mkdir -p "$uart_dir"
243
244 env_file="$uart_dir/env" quote="1" emit_env "$var" "$val"
245 echo "UART$uart: env has $@"
246}
247
248# Place the binary package a pointer to expect script, and its parameters
249track_expect() {
250 local file="${file:?}"
251 local timeout="${timeout-600}"
252 local run_root="${archive:?}/run"
253
254 local uart_dir="$run_root/uart${uart:?}"
255 mkdir -p "$uart_dir"
256
257 echo "$file" > "$uart_dir/expect"
258 echo "$timeout" > "$uart_dir/timeout"
Paul Sokolovskybfa8bab2023-01-25 19:34:51 +0700259 if [ -n "$lava_timeout" ]; then
260 set_run_env "lava_timeout" "$lava_timeout"
261 fi
Fathi Boudra422bf772019-12-02 11:10:16 +0200262
Paul Sokolovskybfa8bab2023-01-25 19:34:51 +0700263 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 +0200264
Chris Kayfab6edc2022-11-17 19:18:32 +0000265 if [ ! -z "${port}" ]; then
266 echo "${port}" > "$uart_dir/port"
267 fi
268
Fathi Boudra422bf772019-12-02 11:10:16 +0200269 # The run script assumes UART0 to be primary. If we're asked to set any
270 # other UART to be primary, set a run environment variable to signal
271 # that to the run script
272 if upon "$set_primary"; then
273 echo "Primary UART set to UART$uart."
274 set_run_env "primary_uart" "$uart"
275 fi
Madhukar Pappireddy1e953722021-11-08 15:23:02 -0600276
277 # UART used by payload(such as tftf, Linux) may not be the same as the
278 # primary UART. Set a run environment variable to track the payload
279 # UART which is tracked to check if the test has finished sucessfully.
280 if upon "$set_payload_uart"; then
281 echo "Payload uses UART$uart."
282 set_run_env "payload_uart" "$uart"
283 fi
Fathi Boudra422bf772019-12-02 11:10:16 +0200284}
285
286# Extract a FIP in $1 using fiptool
287extract_fip() {
288 local fip="$1"
289
290 if is_url "$1"; then
291 url="$1" fetch_file
292 fip="$(basename "$1")"
293 fi
294
295 "$fiptool" unpack "$fip"
296 echo "Extracted FIP: $fip"
297}
298
299# Report build failure by printing a the tail end of build log. Archive the
300# build log for later inspection
301fail_build() {
302 local log_path
303
304 if upon "$jenkins_run"; then
305 log_path="$BUILD_URL/artifact/artefacts/build.log"
306 else
307 log_path="$build_log"
308 fi
309
310 echo
Leonardo Sandovalae97eda2020-11-12 10:07:03 -0600311 echo "Build failed! Full build log below:"
Fathi Boudra422bf772019-12-02 11:10:16 +0200312 echo "[...]"
313 echo
Leonardo Sandovalae97eda2020-11-12 10:07:03 -0600314 cat "$build_log"
Fathi Boudra422bf772019-12-02 11:10:16 +0200315 echo
316 echo "See $log_path for full output"
317 echo
318 cp -t "$archive" "$build_log"
319 exit 1;
320}
321
322# Build a FIP with supplied arguments
323build_fip() {
324 (
325 echo "Building FIP with arguments: $@"
326 local tf_env="$workspace/tf.env"
327
328 if [ -f "$tf_env" ]; then
329 set -a
330 source "$tf_env"
331 set +a
332 fi
333
334 make -C "$tf_root" $(cat "$tf_config_file") DEBUG="$DEBUG" V=1 "$@" \
335 ${fip_targets:-fip} &>>"$build_log" || fail_build
336 )
337}
338
Sandrine Bailleux189fdb32023-10-20 13:41:22 +0200339# Build any extra rule from TF-A makefile with supplied arguments.
340#
341# This is useful in case you need to build something else than firmware binaries
342# or the FIP.
343build_tf_extra() {
344 (
345 tf_extra_rules=${tf_extra_rules:?}
346 echo "Building extra TF rule(s): $tf_extra_rules"
347 echo " Arguments: $@"
348
349 local tf_env="$workspace/tf.env"
350
351 if [ -f "$tf_env" ]; then
352 set -a
353 source "$tf_env"
354 set +a
355 fi
356
357 make -C "$tf_root" $(cat "$tf_config_file") DEBUG="$DEBUG" V=1 "$@" \
358 ${tf_extra_rules} &>>"$build_log" || fail_build
359 )
360}
361
Fathi Boudra422bf772019-12-02 11:10:16 +0200362fip_update() {
363 # Before the update process, check if the given image is supported by
364 # the fiptool. It's assumed that both fiptool and cert_create move in
Chris Kay197b1022023-08-16 21:31:41 +0100365 # tandem, and therefore, if one has support, the other has it too.
366 if ! ("$fiptool" update 2>&1 || true) | grep -qe "\s\+--${bin_name:?}"; then
Fathi Boudra422bf772019-12-02 11:10:16 +0200367 return 1
368 fi
369
370 if not_upon "$(get_tf_opt TRUSTED_BOARD_BOOT)"; then
371 echo "Updating FIP image: $bin_name"
372 # Update HW config. Without TBBR, it's only a matter of using
373 # the update sub-command of fiptool
374 "$fiptool" update "--$bin_name" "${src:-}" \
375 "$archive/fip.bin"
376 else
377 echo "Updating FIP image (TBBR): $bin_name"
378 # With TBBR, we need to unpack, re-create certificates, and then
379 # recreate the FIP.
380 local fip_dir="$(mktempdir)"
381 local bin common_args stem
382 local rot_key="$(get_tf_opt ROT_KEY)"
383
384 rot_key="${rot_key:?}"
385 if ! is_abs "$rot_key"; then
386 rot_key="$tf_root/$rot_key"
387 fi
388
389 # Arguments only for cert_create
390 local cert_args="-n"
391 cert_args+=" --tfw-nvctr ${nvctr:-31}"
392 cert_args+=" --ntfw-nvctr ${nvctr:-223}"
393 cert_args+=" --key-alg ${KEY_ALG:-rsa}"
394 cert_args+=" --rot-key $rot_key"
395
396 local dyn_config_opts=(
Zelalem1af7a7b2020-08-04 17:34:32 -0500397 "fw-config"
Fathi Boudra422bf772019-12-02 11:10:16 +0200398 "hw-config"
399 "tb-fw-config"
400 "nt-fw-config"
401 "soc-fw-config"
402 "tos-fw-config"
403 )
404
405 # Binaries without key certificates
406 declare -A has_no_key_cert
407 for bin in "tb-fw" "${dyn_config_opts[@]}"; do
408 has_no_key_cert["$bin"]="1"
409 done
410
411 # Binaries without certificates
412 declare -A has_no_cert
413 for bin in "hw-config" "${dyn_config_opts[@]}"; do
414 has_no_cert["$bin"]="1"
415 done
416
417 pushd "$fip_dir"
418
419 # Unpack FIP
420 "$fiptool" unpack "$archive/fip.bin" &>>"$build_log"
421
422 # Remove all existing certificates
423 rm -f *-cert.bin
424
425 # Copy the binary to be updated
426 cp -f "$src" "${bin_name}.bin"
427
428 # FIP unpack dumps binaries with the same name as the option
429 # used to pack it; likewise for certificates. Reverse-engineer
430 # the command line from the binary output.
431 common_args="--trusted-key-cert trusted_key.crt"
432 for bin in *.bin; do
433 stem="${bin%%.bin}"
434 common_args+=" --$stem $bin"
435 if not_upon "${has_no_cert[$stem]}"; then
436 common_args+=" --$stem-cert $stem.crt"
437 fi
438 if not_upon "${has_no_key_cert[$stem]}"; then
439 common_args+=" --$stem-key-cert $stem-key.crt"
440 fi
441 done
442
443 # Create certificates
444 "$cert_create" $cert_args $common_args &>>"$build_log"
445
446 # Recreate and archive FIP
447 "$fiptool" create $common_args "fip.bin" &>>"$build_log"
448 archive_file "fip.bin"
449
450 popd
451 fi
452}
453
454# Update hw-config in FIP, and remove the original DTB afterwards.
455update_fip_hw_config() {
456 # The DTB needs to be loaded by the model (and not updated in the FIP)
Madhukar Pappireddy9062ebf2021-03-02 17:07:06 -0600457 # in configs:
458 # 1. Where BL2 isn't present
459 # 2. Where we boot to Linux directly as BL33
Fathi Boudra422bf772019-12-02 11:10:16 +0200460 case "1" in
461 "$(get_tf_opt RESET_TO_BL31)" | \
Madhukar Pappireddy9062ebf2021-03-02 17:07:06 -0600462 "$(get_tf_opt ARM_LINUX_KERNEL_AS_BL33)" | \
Fathi Boudra422bf772019-12-02 11:10:16 +0200463 "$(get_tf_opt RESET_TO_SP_MIN)" | \
Maksims Svecovs7a0da522023-03-06 16:28:27 +0000464 "$(get_tf_opt RESET_TO_BL2)")
Fathi Boudra422bf772019-12-02 11:10:16 +0200465 return 0;;
466 esac
467
468 if bin_name="hw-config" src="$archive/dtb.bin" fip_update; then
469 # Remove the DTB so that model won't load it
470 rm -f "$archive/dtb.bin"
471 fi
472}
473
474get_scp_opt() {
475 (
476 name="${1:?}"
477 if config_valid "$scp_config_file"; then
478 source "$scp_config_file"
479 echo "${!name}"
480 fi
481 )
482}
483
484get_tftf_opt() {
485 (
486 name="${1:?}"
487 if config_valid "$tftf_config_file"; then
488 source "$tftf_config_file"
489 echo "${!name}"
490 fi
491 )
492}
493
494get_tf_opt() {
495 (
496 name="${1:?}"
497 if config_valid "$tf_config_file"; then
498 source "$tf_config_file"
499 echo "${!name}"
500 fi
501 )
502}
503
504build_tf() {
505 (
506 env_file="$workspace/tf.env"
507 config_file="${tf_build_config:-$tf_config_file}"
508
509 # Build fiptool and all targets by default
Harrison Mutai32de9d02023-06-12 14:23:37 +0100510 build_targets="${tf_build_targets:-fiptool all}"
Fathi Boudra422bf772019-12-02 11:10:16 +0200511
512 source "$config_file"
513
514 # If it is a TBBR build, extract the MBED TLS library from archive
Manish V Badarkhe8f125012021-12-21 05:47:52 +0000515 if [ "$(get_tf_opt TRUSTED_BOARD_BOOT)" = 1 ] ||
Manish V Badarkhef43e3f52022-06-21 20:37:25 +0100516 [ "$(get_tf_opt MEASURED_BOOT)" = 1 ] ||
517 [ "$(get_tf_opt DRTM_SUPPORT)" = 1 ]; then
Fathi Boudra422bf772019-12-02 11:10:16 +0200518 mbedtls_dir="$workspace/mbedtls"
519 if [ ! -d "$mbedtls_dir" ]; then
520 mbedtls_ar="$workspace/mbedtls.tar.gz"
521
522 url="$mbedtls_archive" saveas="$mbedtls_ar" fetch_file
523 mkdir "$mbedtls_dir"
Leonardo Sandovalec9e16c2020-09-09 14:32:40 -0500524 extract_tarball $mbedtls_ar $mbedtls_dir --strip-components=1
Fathi Boudra422bf772019-12-02 11:10:16 +0200525 fi
526
527 emit_env "MBEDTLS_DIR" "$mbedtls_dir"
528 fi
Jimmy Brisson0d5e12c2023-05-16 14:51:51 -0500529 if [ "$(get_tf_opt PLATFORM_TEST)" = "tfm-testsuite" ] &&
530 not_upon "${TF_M_TESTS_PATH}"; then
531 emit_env "TF_M_TESTS_PATH" "$WORKSPACE/tf-m-tests"
532 fi
533 if [ "$(get_tf_opt PLATFORM_TEST)" = "tfm-testsuite" ] &&
534 not_upon "${TF_M_EXTRAS_PATH}"; then
535 emit_env "TF_M_EXTRAS_PATH" "$WORKSPACE/tf-m-extras"
536 fi
David Vincze82db6932024-02-21 12:05:50 +0100537 if [ "$(get_tf_opt DICE_PROTECTION_ENVIRONMENT)" = 1 ] &&
538 not_upon "${QCBOR_DIR}"; then
539 emit_env "QCBOR_DIR" "$WORKSPACE/qcbor"
540 fi
Fathi Boudra422bf772019-12-02 11:10:16 +0200541 if [ -f "$env_file" ]; then
542 set -a
543 source "$env_file"
544 set +a
545 fi
546
Harrison Mutai013f6332022-02-16 16:06:33 +0000547 if is_arm_jenkins_env || upon "$local_ci"; then
548 path_list=(
549 "$llvm_dir/bin"
550 )
551 extend_path "PATH" "path_list"
552 fi
553
Fathi Boudra422bf772019-12-02 11:10:16 +0200554 cd "$tf_root"
555
556 # Always distclean when running on Jenkins. Skip distclean when running
557 # locally and explicitly requested.
558 if upon "$jenkins_run" || not_upon "$dont_clean"; then
559 make distclean &>>"$build_log" || fail_build
560 fi
561
562 # Log build command line. It is left unfolded on purpose to assist
563 # copying to clipboard.
564 cat <<EOF | log_separator >/dev/null
565
566Build command line:
567 $tf_build_wrapper make $make_j_opts $(cat "$config_file" | tr '\n' ' ') DEBUG=$DEBUG V=1 $build_targets
568
Paul Sokolovsky7f71b072023-10-16 12:59:09 +0300569CC version:
570$(${CC-${CROSS_COMPILE}gcc} -v 2>&1)
Fathi Boudra422bf772019-12-02 11:10:16 +0200571EOF
572
Javier Almansa Sobrinoe8363182020-11-10 16:40:53 +0000573 if not_upon "$local_ci"; then
574 connect_debugger=0
575 fi
576
Fathi Boudra422bf772019-12-02 11:10:16 +0200577 # Build TF. Since build output is being directed to the build log, have
578 # descriptor 3 point to the current terminal for build wrappers to vent.
Harrison Mutai6361dbe2023-02-16 14:12:40 +0000579 $tf_build_wrapper poetry run make $make_j_opts $(cat "$config_file") \
Javier Almansa Sobrinoe8363182020-11-10 16:40:53 +0000580 DEBUG="$DEBUG" V=1 SPIN_ON_BL1_EXIT="$connect_debugger" \
Fathi Boudra422bf772019-12-02 11:10:16 +0200581 $build_targets 3>&1 &>>"$build_log" || fail_build
Harrison Mutai32de9d02023-06-12 14:23:37 +0100582
Harrison Mutai6dafb5f2023-07-18 15:21:48 +0100583 if [ "$build_targets" != "doc" ]; then
Harrison Mutai2c2c9172024-04-12 11:24:27 +0000584 (poetry run memory -sr "$tf_build_root" 2>&1 || true) | tee -a "$build_log"
Harrison Mutai6dafb5f2023-07-18 15:21:48 +0100585 fi
Fathi Boudra422bf772019-12-02 11:10:16 +0200586 )
587}
588
589build_tftf() {
590 (
591 config_file="${tftf_build_config:-$tftf_config_file}"
592
593 # Build tftf target by default
594 build_targets="${tftf_build_targets:-all}"
595
596 source "$config_file"
597
598 cd "$tftf_root"
599
600 # Always distclean when running on Jenkins. Skip distclean when running
601 # locally and explicitly requested.
602 if upon "$jenkins_run" || not_upon "$dont_clean"; then
603 make distclean &>>"$build_log" || fail_build
604 fi
605
606 # TFTF build system cannot reliably deal with -j option, so we avoid
607 # using that.
608
609 # Log build command line
610 cat <<EOF | log_separator >/dev/null
611
612Build command line:
613 make $(cat "$config_file" | tr '\n' ' ') DEBUG=$DEBUG V=1 $build_targets
614
615EOF
616
617 make $(cat "$config_file") DEBUG="$DEBUG" V=1 \
618 $build_targets &>>"$build_log" || fail_build
619 )
620}
621
622build_scp() {
623 (
624 config_file="${scp_build_config:-$scp_config_file}"
625
626 source "$config_file"
627
628 cd "$scp_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
Leandro Belli99e20b22022-12-29 13:50:47 +0000633 make -f Makefile.cmake clean &>>"$build_log" || fail_build
Fathi Boudra422bf772019-12-02 11:10:16 +0200634 fi
635
Joel Goddard9bdfe3c2021-02-25 10:15:14 +0000636 python3 -m venv .venv
637 . .venv/bin/activate
638
639 # Install extra tools used by CMake build system
640 pip install -r requirements.txt --timeout 30 --retries 15
641
Fathi Boudra422bf772019-12-02 11:10:16 +0200642 # Log build command line. It is left unfolded on purpose to assist
643 # copying to clipboard.
644 cat <<EOF | log_separator >/dev/null
645
646SCP build command line:
Joel Goddard9bdfe3c2021-02-25 10:15:14 +0000647 make -f Makefile.cmake $(cat "$config_file" | tr '\n' ' ') \
648 TOOLCHAIN=GNU \
649 MODE="$mode" \
Nicola Mazzucato506b5802021-12-24 14:23:25 +0000650 EXTRA_CONFIG_ARGS+=-DDISABLE_CPPCHECK=true \
Joel Goddard9bdfe3c2021-02-25 10:15:14 +0000651 V=1 &>>"$build_log"
Fathi Boudra422bf772019-12-02 11:10:16 +0200652
653EOF
654
655 # Build SCP
Joel Goddard9bdfe3c2021-02-25 10:15:14 +0000656 make -f Makefile.cmake $(cat "$config_file" | tr '\n' ' ') \
657 TOOLCHAIN=GNU \
658 MODE="$mode" \
Nicola Mazzucato506b5802021-12-24 14:23:25 +0000659 EXTRA_CONFIG_ARGS+=-DDISABLE_CPPCHECK=true \
Joel Goddard9bdfe3c2021-02-25 10:15:14 +0000660 V=1 &>>"$build_log" \
Fathi Boudra422bf772019-12-02 11:10:16 +0200661 || fail_build
662 )
663}
664
Zelalem219df412020-05-17 19:21:20 -0500665clone_scp_tools() {
666
667 if [ ! -d "$scp_tools_root" ]; then
668 echo "Cloning SCP-tools ... $scp_tools_commit" |& log_separator
669
670 clone_url="${SCP_TOOLS_CHECKOUT_LOC:-$scp_tools_src_repo_url}" \
671 where="$scp_tools_root" \
672 refspec="${scp_tools_commit}"
673 clone_repo &>>"$build_log"
674 else
675 echo "Already cloned SCP-tools ..." |& log_separator
676 fi
677
678 show_head "$scp_tools_root"
679
680 cd "$scp_tools_root"
681
682 echo "Updating submodules"
683
684 git submodule init
685
686 git submodule update
687
Nicola Mazzucato9b171422023-08-29 15:50:49 +0100688 lib_commit=$(grep "'scmi_lib_commit'" run_tests/settings.py | cut -d':' -f 2 | tr -d "'" | tr -d ",")
Nicola Mazzucato7302cd32021-12-14 13:36:57 +0000689
Zelalem219df412020-05-17 19:21:20 -0500690 cd "scmi"
Nicola Mazzucato7302cd32021-12-14 13:36:57 +0000691 git checkout $lib_commit
Zelalem219df412020-05-17 19:21:20 -0500692
693 git show --quiet --no-color | sed 's/^/ > /g'
694}
695
696clone_tf_for_scp_tools() {
697 scp_tools_arm_tf="$scp_tools_root/arm-tf"
698
699 if [ ! -d "$scp_tools_arm_tf" ]; then
700 echo "Cloning TF-4-SCP-tools ..." |& log_separator
701
702 clone_url="$tf_for_scp_tools_src_repo_url"
703 where="$scp_tools_arm_tf"
704
705 git clone "$clone_url" "$where"
706
707 cd "$scp_tools_arm_tf"
708
Joel Goddard3ad03062021-03-16 16:47:42 +0000709 git checkout --track origin/juno-v4.3
Zelalem219df412020-05-17 19:21:20 -0500710
711 git show --quiet --no-color | sed 's/^/ > /g'
712
713 else
714 echo "Already cloned TF-4-SCP-tools ..." |& log_separator
715 fi
716}
717
718build_scmi_lib_scp_tools() {
719 (
720 cd "$scp_tools_root"
721
722 cd "scmi"
723
724 scp_tools_arm_tf="$scp_tools_root/arm-tf"
725
Leonardo Sandovalfeae3a22020-11-17 16:53:59 -0600726 cross_compile="$(set_cross_compile_gcc_linaro_toolchain)"
Zelalem219df412020-05-17 19:21:20 -0500727
728 std_libs="-I$scp_tools_arm_tf/include/common"
729 std_libs="$std_libs -I$scp_tools_arm_tf/include/common/tbbr"
730 std_libs="$std_libs -I$scp_tools_arm_tf/include/drivers/arm"
731 std_libs="$std_libs -I$scp_tools_arm_tf/include/lib"
732 std_libs="$std_libs -I$scp_tools_arm_tf/include/lib/aarch64"
733 std_libs="$std_libs -I$scp_tools_arm_tf/include/lib/stdlib"
734 std_libs="$std_libs -I$scp_tools_arm_tf/include/lib/stdlib/sys"
735 std_libs="$std_libs -I$scp_tools_arm_tf/include/lib/xlat_tables"
736 std_libs="$std_libs -I$scp_tools_arm_tf/include/plat/common"
737 std_libs="$std_libs -I$scp_tools_arm_tf/include/plat/arm/common"
738 std_libs="$std_libs -I$scp_tools_arm_tf/include/plat/arm/css/common"
739 std_libs="$std_libs -I$scp_tools_arm_tf/include/plat/arm/board/common"
740 std_libs="$std_libs -I$scp_tools_arm_tf/include/plat/arm/soc/common"
741 std_libs="$std_libs -I$scp_tools_arm_tf/plat/arm/board/juno/include"
742
743 cflags="-Og -g"
744 cflags="$cflags -mgeneral-regs-only"
745 cflags="$cflags -mstrict-align"
746 cflags="$cflags -nostdinc"
747 cflags="$cflags -fno-inline"
748 cflags="$cflags -ffreestanding"
749 cflags="$cflags -ffunction-sections"
750 cflags="$cflags -fdata-sections"
751 cflags="$cflags -DAARCH64"
752 cflags="$cflags -DPRId32=\"ld\""
Joel Goddard3ad03062021-03-16 16:47:42 +0000753 cflags="$cflags -DVERBOSE_LEVEL=3"
Zelalem219df412020-05-17 19:21:20 -0500754
755 cflags="$cflags $std_libs"
756
Joel Goddard3ad03062021-03-16 16:47:42 +0000757 protocols="performance,power_domain,system_power,reset"
Zelalem219df412020-05-17 19:21:20 -0500758
759 echo "Building SCMI library (SCP-tools) ..."
760
761 make "CROSS_COMPILE=$cross_compile" \
762 "CFLAGS=$cflags" \
Joel Goddard3ad03062021-03-16 16:47:42 +0000763 "PLAT=baremetal" \
Zelalem219df412020-05-17 19:21:20 -0500764 "PROTOCOLS=$protocols" \
765 "clean" \
766 "all"
767 )
768}
769
770build_tf_for_scp_tools() {
771
772 cd "$scp_tools_root/arm-tf"
773
Leonardo Sandovalfeae3a22020-11-17 16:53:59 -0600774 cross_compile="$(set_cross_compile_gcc_linaro_toolchain)"
Zelalem219df412020-05-17 19:21:20 -0500775
776 if [ "$1" = "release" ]; then
777 echo "Build TF-4-SCP-Tools rls..."
778 else
779 echo "Build TF-4-SCP-Tools dbg..."
780
781 make realclean
782
783 make "BM_TEST=scmi" \
784 "ARM_BOARD_OPTIMISE_MEM=1" \
785 "BM_CSS=juno" \
786 "CSS_USE_SCMI_SDS_DRIVER=1" \
787 "PLAT=juno" \
788 "DEBUG=1" \
789 "PLATFORM=juno" \
790 "CROSS_COMPILE=$cross_compile" \
791 "BM_WORKSPACE=$scp_tools_root/baremetal"
792
793 archive_file "build/juno/debug/bl1.bin"
794
795 archive_file "build/juno/debug/bl2.bin"
796
797 archive_file "build/juno/debug/bl31.bin"
798 fi
799}
800
801build_fip_for_scp_tools() {
802
803 cd "$scp_tools_root/arm-tf"
804
Leonardo Sandovalfeae3a22020-11-17 16:53:59 -0600805 cross_compile="$(set_cross_compile_gcc_linaro_toolchain)"
Zelalem219df412020-05-17 19:21:20 -0500806
Joel Goddard9bdfe3c2021-02-25 10:15:14 +0000807 if [ ! -d "$scp_root/build/juno/GNU/debug/firmware-scp_ramfw" ]; then
Zelalem219df412020-05-17 19:21:20 -0500808 make fiptool
809 echo "Make FIP 4 SCP-Tools rls..."
810
811 else
812 make fiptool
813 echo "Make FIP 4 SCP-Tools dbg..."
814
815 make "PLAT=juno" \
816 "all" \
817 "fip" \
818 "DEBUG=1" \
819 "CROSS_COMPILE=$cross_compile" \
820 "BL31=$scp_tools_root/arm-tf/build/juno/debug/bl31.bin" \
821 "BL33=$scp_tools_root/baremetal/dummy_bl33" \
Joel Goddard9bdfe3c2021-02-25 10:15:14 +0000822 "SCP_BL2=$scp_root/build/juno/GNU/$mode/firmware-scp_ramfw/bin/juno-bl2.bin"
Zelalem219df412020-05-17 19:21:20 -0500823
824 archive_file "$scp_tools_root/arm-tf/build/juno/debug/fip.bin"
825 fi
826}
827
828build_cc() {
829# Building code coverage plugin
830 ARM_DIR=/arm
831 pvlibversion=$(/arm/devsys-tools/abs/detag "SysGen:PVModelLib:$model_version::trunk")
832 PVLIB_HOME=$warehouse/SysGen/PVModelLib/$model_version/${pvlibversion}/external
833 if [ -n "$(find "$ARM_DIR" -maxdepth 0 -type d -empty 2>/dev/null)" ]; then
834 echo "Error: Arm warehouse not mounted. Please mount the Arm warehouse to your /arm local folder"
835 exit -1
836 fi # Error if arm warehouse not found
837 cd "$ccpathspec/scripts/tools/code_coverage/fastmodel_baremetal/bmcov"
838
839 make -C model-plugin PVLIB_HOME=$PVLIB_HOME &>>"$build_log"
840}
841
Olivier Deprez0a9a3482019-12-16 14:10:31 +0100842build_spm() {
843 (
844 env_file="$workspace/spm.env"
845 config_file="${spm_build_config:-$spm_config_file}"
846
847 source "$config_file"
848
849 if [ -f "$env_file" ]; then
850 set -a
851 source "$env_file"
852 set +a
853 fi
854
855 cd "$spm_root"
856
857 # Always clean when running on Jenkins. Skip clean when running
858 # locally and explicitly requested.
859 if upon "$jenkins_run" || not_upon "$dont_clean"; then
860 # make clean fails on a fresh repo where the project has not
861 # yet been built. Hence only clean if out/reference directory
862 # already exists.
863 if [ -d "out/reference" ]; then
864 make clean &>>"$build_log" || fail_build
865 fi
866 fi
867
868 # Log build command line. It is left unfolded on purpose to assist
869 # copying to clipboard.
870 cat <<EOF | log_separator >/dev/null
871
872Build command line:
873 make $make_j_opts $(cat "$config_file" | tr '\n' ' ')
874
875EOF
876
877 # Build SPM. Since build output is being directed to the build log, have
878 # descriptor 3 point to the current terminal for build wrappers to vent.
879 make $make_j_opts $(cat "$config_file") 3>&1 &>>"$build_log" \
880 || fail_build
881 )
882}
Zelalem219df412020-05-17 19:21:20 -0500883
Fathi Boudra422bf772019-12-02 11:10:16 +0200884# Set metadata for the whole package so that it can be used by both Jenkins and
885# shell
886set_package_var() {
887 env_file="$artefacts/env" emit_env "$@"
888}
889
890set_tf_build_targets() {
891 echo "Set build target to '${targets:?}'"
892 set_hook_var "tf_build_targets" "$targets"
893}
894
895set_tftf_build_targets() {
896 echo "Set build target to '${targets:?}'"
897 set_hook_var "tftf_build_targets" "$targets"
898}
899
900set_scp_build_targets() {
901 echo "Set build target to '${targets:?}'"
902 set_hook_var "scp_build_targets" "$targets"
903}
904
Olivier Deprez0a9a3482019-12-16 14:10:31 +0100905set_spm_build_targets() {
906 echo "Set build target to '${targets:?}'"
907 set_hook_var "spm_build_targets" "$targets"
908}
909
Daniel Boulbyb8d2a462022-03-07 13:55:25 +0000910set_spm_out_dir() {
911 echo "Set SPMC binary build to '${out_dir:?}'"
912 set_hook_var "spm_secure_out_dir" "$out_dir"
913}
Fathi Boudra422bf772019-12-02 11:10:16 +0200914# Look under $archive directory for known files such as blX images, kernel, DTB,
915# initrd etc. For each known file foo, if foo.bin exists, then set variable
916# foo_bin to the path of the file. Make the path relative to the workspace so as
917# to remove any @ characters, which Jenkins inserts for parallel runs. If the
918# file doesn't exist, unset its path.
919set_default_bin_paths() {
920 local image image_name image_path path
921 local archive="${archive:?}"
922 local set_vars
923 local var
924
925 pushd "$archive"
926
927 for file in *.bin; do
928 # Get a shell variable from the file's stem
929 var_name="${file%%.*}_bin"
930 var_name="$(echo "$var_name" | sed -r 's/[^[:alnum:]]/_/g')"
931
932 # Skip setting the variable if it's already
933 if [ "${!var_name}" ]; then
934 echo "Note: not setting $var_name; already set to ${!var_name}"
935 continue
936 else
937 set_vars+="$var_name "
938 fi
939
940 eval "$var_name=$file"
941 done
942
943 echo "Binary paths set for: "
944 {
945 for var in $set_vars; do
946 echo -n "\$$var "
947 done
948 } | fmt -80 | sed 's/^/ /'
949 echo
950
951 popd
952}
953
954gen_model_params() {
955 local model_param_file="$archive/model_params"
Javier Almansa Sobrinoe8363182020-11-10 16:40:53 +0000956 [ "$connect_debugger" ] && [ "$connect_debugger" -eq 1 ] && wait_debugger=1
Fathi Boudra422bf772019-12-02 11:10:16 +0200957
958 set_default_bin_paths
959 echo "Generating model parameter for $model..."
960 source "$ci_root/model/${model:?}.sh"
961 archive_file "$model_param_file"
962}
963
964set_model_path() {
965 set_run_env "model_path" "${1:?}"
966}
967
Zelalem1af7a7b2020-08-04 17:34:32 -0500968set_model_env() {
969 local var="${1:?}"
970 local val="${2?}"
971 local run_root="${archive:?}/run"
972
973 mkdir -p "$run_root"
974 echo "export $var=$val" >> "$run_root/model_env"
975}
Fathi Boudra422bf772019-12-02 11:10:16 +0200976set_run_env() {
977 local var="${1:?}"
978 local val="${2?}"
979 local run_root="${archive:?}/run"
980
981 mkdir -p "$run_root"
982 env_file="$run_root/env" quote="1" emit_env "$var" "$val"
983}
984
985show_head() {
986 # Display HEAD descripton
987 pushd "$1"
988 git show --quiet --no-color | sed 's/^/ > /g'
989 echo
990 popd
991}
992
993# Choose debug binaries to run; by default, release binaries are chosen to run
994use_debug_bins() {
995 local run_root="${archive:?}/run"
996
997 echo "Choosing debug binaries for execution"
998 set_package_var "BIN_MODE" "debug"
999}
1000
1001assert_can_git_clone() {
1002 local name="${1:?}"
1003 local dir="${!name}"
1004
1005 # If it doesn't exist, it can be cloned into
1006 if [ ! -e "$dir" ]; then
1007 return 0
1008 fi
1009
1010 # If it's a directory, it must be a Git clone already
1011 if [ -d "$dir" ] && [ -d "$dir/.git" ]; then
1012 # No need to clone again
1013 echo "Using existing git clone for $name: $dir"
1014 return 1
1015 fi
1016
1017 die "Path $dir exists but is not a git clone"
1018}
1019
1020clone_repo() {
1021 if ! is_url "${clone_url?}"; then
1022 # For --depth to take effect on local paths, it needs to use the
1023 # file:// scheme.
1024 clone_url="file://$clone_url"
1025 fi
1026
1027 git clone -q --depth 1 "$clone_url" "${where?}"
1028 if [ "$refspec" ]; then
1029 pushd "$where"
1030 git fetch -q --depth 1 origin "$refspec"
1031 git checkout -q FETCH_HEAD
1032 popd
1033 fi
1034}
1035
1036build_unstable() {
1037 echo "--BUILD UNSTABLE--" | tee -a "$build_log"
1038}
1039
1040undo_patch_record() {
1041 if [ ! -f "${patch_record:?}" ]; then
1042 return
1043 fi
1044
1045 # Undo patches in reverse
1046 echo
1047 for patch_name in $(tac "$patch_record"); do
1048 echo "Undoing $patch_name..."
1049 if ! git apply -R "$ci_root/patch/$patch_name"; then
1050 if upon "$local_ci"; then
1051 echo
1052 echo "Your local directory may have been dirtied."
1053 echo
1054 fi
1055 fail_build
1056 fi
1057 done
1058
1059 rm -f "$patch_record"
1060}
1061
1062undo_local_patches() {
1063 pushd "$tf_root"
1064 patch_record="$tf_patch_record" undo_patch_record
1065 popd
1066
1067 if [ -d "$tftf_root" ]; then
1068 pushd "$tftf_root"
1069 patch_record="$tftf_patch_record" undo_patch_record
1070 popd
1071 fi
1072}
1073
1074undo_tftf_patches() {
1075 pushd "$tftf_root"
1076 patch_record="$tftf_patch_record" undo_patch_record
1077 popd
1078}
1079
1080undo_tf_patches() {
1081 pushd "$tf_root"
1082 patch_record="$tf_patch_record" undo_patch_record
1083 popd
1084}
1085
1086apply_patch() {
1087 # If skip_patches is set, the developer has applied required patches
1088 # manually. They probably want to keep them applied for debugging
1089 # purposes too. This means we don't have to apply/revert them as part of
1090 # build process.
1091 if upon "$skip_patches"; then
1092 echo "Skipped applying ${1:?}..."
1093 return 0
1094 else
1095 echo "Applying ${1:?}..."
1096 fi
1097
Sandrine Bailleux4cb8c222023-09-13 13:48:15 +02001098 if git apply --reverse --check < "$ci_root/patch/$1" 2> /dev/null; then
Jimmy Brissonf134e4c2023-03-22 13:20:20 -05001099 echo "Skipping already applied ${1:?}"
1100 return 0
1101 fi
1102
Fathi Boudra422bf772019-12-02 11:10:16 +02001103 if git apply < "$ci_root/patch/$1"; then
1104 echo "$1" >> "${patch_record:?}"
1105 else
1106 if upon "$local_ci"; then
1107 undo_local_patches
1108 fi
1109 fail_build
1110 fi
1111}
1112
1113apply_tftf_patch() {
1114 pushd "$tftf_root"
1115 patch_record="$tftf_patch_record" apply_patch "$1"
1116 popd
1117}
1118
1119apply_tf_patch() {
1120 pushd "$tf_root"
1121 patch_record="$tf_patch_record" apply_patch "$1"
1122 popd
1123}
1124
1125# Clear workspace for a local run
1126if not_upon "$jenkins_run"; then
1127 rm -rf "$workspace"
1128
1129 # Clear residue from previous runs
1130 rm -rf "$archive"
1131fi
1132
1133mkdir -p "$workspace"
1134mkdir -p "$archive"
1135set_package_var "TEST_CONFIG" "$test_config"
1136
1137{
1138echo
1139echo "CONFIGURATION: $test_group/$test_config"
1140echo
1141} |& log_separator
1142
1143tf_config="$(echo "$build_configs" | awk -F, '{print $1}')"
1144tftf_config="$(echo "$build_configs" | awk -F, '{print $2}')"
1145scp_config="$(echo "$build_configs" | awk -F, '{print $3}')"
Zelalem219df412020-05-17 19:21:20 -05001146scp_tools_config="$(echo "$build_configs" | awk -F, '{print $4}')"
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001147spm_config="$(echo "$build_configs" | awk -F, '{print $5}')"
Fathi Boudra422bf772019-12-02 11:10:16 +02001148
1149test_config_file="$ci_root/group/$test_group/$test_config"
1150
1151tf_config_file="$ci_root/tf_config/$tf_config"
1152tftf_config_file="$ci_root/tftf_config/$tftf_config"
1153scp_config_file="$ci_root/scp_config/$scp_config"
Zelalem219df412020-05-17 19:21:20 -05001154scp_tools_config_file="$ci_root/scp_tools_config/$scp_tools_config"
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001155spm_config_file="$ci_root/spm_config/$spm_config"
Fathi Boudra422bf772019-12-02 11:10:16 +02001156
1157# File that keeps track of applied patches
1158tf_patch_record="$workspace/tf_patches"
1159tftf_patch_record="$workspace/tftf_patches"
1160
1161pushd "$workspace"
1162
1163if ! config_valid "$tf_config"; then
1164 tf_config=
1165else
1166 echo "Trusted Firmware config:"
1167 echo
1168 sort "$tf_config_file" | sed '/^\s*$/d;s/^/\t/'
1169 echo
1170fi
1171
1172if ! config_valid "$tftf_config"; then
1173 tftf_config=
1174else
1175 echo "Trusted Firmware TF config:"
1176 echo
1177 sort "$tftf_config_file" | sed '/^\s*$/d;s/^/\t/'
1178 echo
1179fi
1180
1181if ! config_valid "$scp_config"; then
1182 scp_config=
1183else
1184 echo "SCP firmware config:"
1185 echo
1186 sort "$scp_config_file" | sed '/^\s*$/d;s/^/\t/'
1187 echo
1188fi
1189
Zelalem219df412020-05-17 19:21:20 -05001190if ! config_valid "$scp_tools_config"; then
1191 scp_tools_config=
1192else
1193 echo "SCP Tools config:"
1194 echo
1195 sort "$scp_tools_config_file" | sed '/^\s*$/d;s/^/\t/'
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001196fi
1197
1198if ! config_valid "$spm_config"; then
1199 spm_config=
1200else
1201 echo "SPM config:"
1202 echo
1203 sort "$spm_config_file" | sed '/^\s*$/d;s/^/\t/'
Zelalem219df412020-05-17 19:21:20 -05001204 echo
1205fi
1206
Fathi Boudra422bf772019-12-02 11:10:16 +02001207if ! config_valid "$run_config"; then
1208 run_config=
1209fi
1210
1211if [ "$tf_config" ] && assert_can_git_clone "tf_root"; then
1212 # If the Trusted Firmware repository has already been checked out, use
1213 # that location. Otherwise, clone one ourselves.
1214 echo "Cloning Trusted Firmware..."
1215 clone_url="${TF_CHECKOUT_LOC:-$tf_src_repo_url}" where="$tf_root" \
1216 refspec="$TF_REFSPEC" clone_repo &>>"$build_log"
1217 show_head "$tf_root"
1218fi
1219
1220if [ "$tftf_config" ] && assert_can_git_clone "tftf_root"; then
1221 # If the Trusted Firmware TF repository has already been checked out,
1222 # use that location. Otherwise, clone one ourselves.
1223 echo "Cloning Trusted Firmware TF..."
1224 clone_url="${TFTF_CHECKOUT_LOC:-$tftf_src_repo_url}" where="$tftf_root" \
1225 refspec="$TFTF_REFSPEC" clone_repo &>>"$build_log"
1226 show_head "$tftf_root"
1227fi
1228
1229if [ "$scp_config" ] && assert_can_git_clone "scp_root"; then
1230 # If the SCP firmware repository has already been checked out,
1231 # use that location. Otherwise, clone one ourselves.
1232 echo "Cloning SCP Firmware..."
1233 clone_url="${SCP_CHECKOUT_LOC:-$scp_src_repo_url}" where="$scp_root" \
1234 refspec="${SCP_REFSPEC-master-upstream}" clone_repo &>>"$build_log"
1235
1236 pushd "$scp_root"
1237
1238 # Use filer submodule as a reference if it exists
Girish Pathak31b824e2021-03-03 20:58:21 +00001239 if [ -d "$SCP_CHECKOUT_LOC/cmsis" ]; then
Fathi Boudra422bf772019-12-02 11:10:16 +02001240 cmsis_reference="--reference $SCP_CHECKOUT_LOC/cmsis"
1241 fi
1242
1243 # If we don't have a reference yet, fall back to $cmsis_root if set, or
1244 # then to project filer if accessible.
1245 if [ -z "$cmsis_reference" ]; then
1246 cmsis_ref_repo="${cmsis_root:-$project_filer/ref-repos/cmsis}"
1247 if [ -d "$cmsis_ref_repo" ]; then
1248 cmsis_reference="--reference $cmsis_ref_repo"
1249 fi
1250 fi
1251
1252 git submodule -q update $cmsis_reference --init
1253
1254 popd
1255
1256 show_head "$scp_root"
1257fi
1258
Zelalem219df412020-05-17 19:21:20 -05001259if [ -n "$cc_config" ] ; then
1260 if [ "$cc_config" -eq 1 ] && assert_can_git_clone "cc_root"; then
1261 # Copy code coverage repository
1262 echo "Cloning Code Coverage..."
1263 git clone -q $cc_src_repo_url cc_plugin --depth 1 -b $cc_src_repo_tag > /dev/null
1264 show_head "$cc_root"
1265 fi
1266fi
1267
Daniel Boulby25385ab2023-12-14 14:36:25 +00001268if [ "$spm_config" ] ; then
1269 if assert_can_git_clone "spm_root"; then
1270 # If the SPM repository has already been checked out, use
1271 # that location. Otherwise, clone one ourselves.
1272 echo "Cloning SPM..."
1273 clone_url="${SPM_CHECKOUT_LOC:-$spm_src_repo_url}" \
1274 where="$spm_root" refspec="$SPM_REFSPEC" \
1275 clone_repo &>>"$build_log"
1276 fi
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001277
1278 # Query git submodules
1279 pushd "$spm_root"
Daniel Boulby25385ab2023-12-14 14:36:25 +00001280 # Check if submodules need initialising
1281 if git submodule status | grep '^-'; then
1282 git submodule update --init
1283 fi
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001284 popd
1285
1286 show_head "$spm_root"
1287fi
1288
Fathi Boudra422bf772019-12-02 11:10:16 +02001289if [ "$run_config" ]; then
1290 # Get candidates for run config
Nicola Mazzucato7fc5abd2024-02-23 21:32:48 +00001291 run_config_candidates="$("$ci_root/script/gen_run_config_candidates.py" \
Fathi Boudra422bf772019-12-02 11:10:16 +02001292 "$run_config")"
Nicola Mazzucato7fc5abd2024-02-23 21:32:48 +00001293 if [ -z "$run_config_candidates" ]; then
Fathi Boudra422bf772019-12-02 11:10:16 +02001294 die "No run config candidates!"
1295 else
1296 echo
1297 echo "Chosen fragments:"
1298 echo
Nicola Mazzucato7fc5abd2024-02-23 21:32:48 +00001299 echo "$run_config_candidates" | sed 's/^\|\n/\t/g'
Fathi Boudra422bf772019-12-02 11:10:16 +02001300 echo
1301 fi
1302fi
1303
1304call_hook "test_setup"
1305echo
1306
1307if upon "$local_ci"; then
1308 # For local runs, since each config is tried in sequence, it's
1309 # advantageous to run jobs in parallel
1310 if [ "$make_j" ]; then
1311 make_j_opts="-j $make_j"
1312 else
1313 n_cores="$(getconf _NPROCESSORS_ONLN)" 2>/dev/null || true
1314 if [ "$n_cores" ]; then
1315 make_j_opts="-j $n_cores"
1316 fi
1317 fi
1318fi
1319
Harrison Mutai07043e92023-07-06 09:41:12 +01001320# Install python build dependencies
1321if is_arm_jenkins_env; then
1322 source "$ci_root/script/install_python_deps.sh"
1323fi
1324
Fathi Boudra422bf772019-12-02 11:10:16 +02001325modes="${bin_mode:-debug release}"
1326for mode in $modes; do
Paul Sokolovskye9962cd2021-12-17 18:39:40 +03001327 echo "===== Building package in mode: $mode ====="
Fathi Boudra422bf772019-12-02 11:10:16 +02001328 # Build with a temporary archive
1329 build_archive="$archive/$mode"
1330 mkdir "$build_archive"
1331
1332 if [ "$mode" = "debug" ]; then
Zelalem219df412020-05-17 19:21:20 -05001333 export bin_mode="debug"
Fathi Boudra422bf772019-12-02 11:10:16 +02001334 DEBUG=1
1335 else
Zelalem219df412020-05-17 19:21:20 -05001336 export bin_mode="release"
Fathi Boudra422bf772019-12-02 11:10:16 +02001337 DEBUG=0
1338 fi
1339
1340 # Perform builds in a subshell so as not to pollute the current and
1341 # subsequent builds' environment
1342
Zelalem219df412020-05-17 19:21:20 -05001343 if config_valid "$cc_config"; then
1344 # Build code coverage plugin
1345 build_cc
1346 fi
1347
Fathi Boudra422bf772019-12-02 11:10:16 +02001348 # SCP build
1349 if config_valid "$scp_config"; then
1350 (
1351 echo "##########"
1352
1353 # Source platform-specific utilities
1354 plat="$(get_scp_opt PRODUCT)"
1355 plat_utils="$ci_root/${plat}_utils.sh"
1356 if [ -f "$plat_utils" ]; then
1357 source "$plat_utils"
1358 fi
1359
1360 archive="$build_archive"
1361 scp_build_root="$scp_root/build"
1362
1363 echo "Building SCP Firmware ($mode) ..." |& log_separator
1364
1365 build_scp
Fathi Boudra422bf772019-12-02 11:10:16 +02001366 to="$archive" collect_scp_artefacts
1367
1368 echo "##########"
1369 echo
1370 )
1371 fi
1372
Zelalem219df412020-05-17 19:21:20 -05001373 # SCP-tools build
1374 if config_valid "$scp_tools_config"; then
1375 (
1376 echo "##########"
1377
1378 archive="$build_archive"
1379 scp_tools_build_root="$scp_tools_root/build"
1380
1381 clone_scp_tools
1382
1383 echo "##########"
1384 echo
1385
1386 echo "##########"
1387 clone_tf_for_scp_tools
1388 echo "##########"
1389 echo
1390 )
1391 fi
1392
Fathi Boudra422bf772019-12-02 11:10:16 +02001393 # TFTF build
1394 if config_valid "$tftf_config"; then
1395 (
1396 echo "##########"
1397
Manish V Badarkhe3bd3fea2020-11-08 15:17:00 +00001398 plat_utils="$(get_tf_opt PLAT_UTILS)"
1399 if [ -z ${plat_utils} ]; then
1400 # Source platform-specific utilities.
1401 plat="$(get_tftf_opt PLAT)"
1402 plat_utils="$ci_root/${plat}_utils.sh"
1403 else
1404 # Source platform-specific utilities by
1405 # using plat_utils name.
1406 plat_utils="$ci_root/${plat_utils}.sh"
1407 fi
1408
Fathi Boudra422bf772019-12-02 11:10:16 +02001409 if [ -f "$plat_utils" ]; then
1410 source "$plat_utils"
1411 fi
1412
1413 archive="$build_archive"
1414 tftf_build_root="$tftf_root/build"
1415
1416 echo "Building Trusted Firmware TF ($mode) ..." |& log_separator
1417
1418 # Call pre-build hook
1419 call_hook pre_tftf_build
1420
1421 build_tftf
1422
1423 from="$tftf_build_root" to="$archive" collect_build_artefacts
1424
1425 # Clear any local changes made by applied patches
1426 undo_tftf_patches
1427
1428 echo "##########"
1429 echo
1430 )
1431 fi
1432
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001433 # SPM build
1434 if config_valid "$spm_config"; then
1435 (
1436 echo "##########"
1437
1438 # Get platform name from spm_config file
1439 plat="$(echo "$spm_config" | awk -F- '{print $1}')"
1440 plat_utils="$ci_root/${plat}_utils.sh"
1441 if [ -f "$plat_utils" ]; then
1442 source "$plat_utils"
1443 fi
1444
Daniel Boulbyb8d2a462022-03-07 13:55:25 +00001445 # Call pre-build hook
1446 call_hook pre_spm_build
1447
Manish Pandey1e7be852020-11-09 16:04:48 +00001448 # SPM build generates two sets of binaries, one for normal and other
1449 # for Secure world. We need both set of binaries for CI.
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001450 archive="$build_archive"
Manish Pandey1e7be852020-11-09 16:04:48 +00001451 spm_build_root="$spm_root/out/reference/$spm_secure_out_dir"
1452 hafnium_build_root="$spm_root/out/reference/$spm_non_secure_out_dir"
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001453
Daniel Boulbyb8d2a462022-03-07 13:55:25 +00001454 echo "spm_build_root is $spm_build_root"
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001455 echo "Building SPM ($mode) ..." |& log_separator
1456
1457 # NOTE: mode has no effect on SPM build (for now), hence debug
1458 # mode is built but subsequent build using release mode just
1459 # goes through with "nothing to do".
1460 build_spm
1461
1462 # Show SPM/Hafnium binary details
Madhukar Pappireddyc683cf62021-11-01 14:38:32 -05001463 cksum $spm_build_root/hafnium.bin
1464
1465 # Some platforms only have secure configuration enabled. Hence,
1466 # non secure hanfnium binary might not be built.
1467 if [ -f $hafnium_build_root/hafnium.bin ]; then
1468 cksum $hafnium_build_root/hafnium.bin
1469 fi
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001470
Manish Pandey1e7be852020-11-09 16:04:48 +00001471 secure_from="$spm_build_root" non_secure_from="$hafnium_build_root" to="$archive" collect_spm_artefacts
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001472
1473 echo "##########"
1474 echo
1475 )
1476 fi
1477
Fathi Boudra422bf772019-12-02 11:10:16 +02001478 # TF build
1479 if config_valid "$tf_config"; then
1480 (
1481 echo "##########"
1482
Manish V Badarkhe3bd3fea2020-11-08 15:17:00 +00001483 plat_utils="$(get_tf_opt PLAT_UTILS)"
Madhukar Pappireddy2f284e12021-08-30 16:06:14 -05001484 export plat_variant="$(get_tf_opt TARGET_PLATFORM)"
1485
Manish V Badarkhe3bd3fea2020-11-08 15:17:00 +00001486 if [ -z ${plat_utils} ]; then
1487 # Source platform-specific utilities.
1488 plat="$(get_tf_opt PLAT)"
1489 plat_utils="$ci_root/${plat}_utils.sh"
1490 else
1491 # Source platform-specific utilities by
1492 # using plat_utils name.
1493 plat_utils="$ci_root/${plat_utils}.sh"
1494 fi
1495
Fathi Boudra422bf772019-12-02 11:10:16 +02001496 if [ -f "$plat_utils" ]; then
1497 source "$plat_utils"
1498 fi
1499
Chris Kaye5a486b2023-08-04 11:50:31 +00001500 fvp_tsram_size="$(get_tf_opt FVP_TRUSTED_SRAM_SIZE)"
1501 fvp_tsram_size="${fvp_tsram_size:-256}"
1502
Harrison Mutai6361dbe2023-02-16 14:12:40 +00001503 poetry -C "$tf_root" install --without doc
Chris Kayd0837902021-11-17 10:17:52 +00001504
Fathi Boudra422bf772019-12-02 11:10:16 +02001505 archive="$build_archive"
1506 tf_build_root="$tf_root/build"
1507
1508 echo "Building Trusted Firmware ($mode) ..." |& log_separator
1509
1510 # Call pre-build hook
1511 call_hook pre_tf_build
1512
1513 build_tf
1514
1515 # Call post-build hook
1516 call_hook post_tf_build
1517
1518 # Pre-archive hook
1519 call_hook pre_tf_archive
1520
1521 from="$tf_build_root" to="$archive" collect_build_artefacts
1522
1523 # Post-archive hook
1524 call_hook post_tf_archive
1525
1526 call_hook fetch_tf_resource
1527 call_hook post_fetch_tf_resource
1528
Chris Kay4e8aaf12022-09-01 15:21:55 +01001529 # Generate LAVA job files if necessary
1530 call_hook generate_lava_job_template
1531 call_hook generate_lava_job
1532
Fathi Boudra422bf772019-12-02 11:10:16 +02001533 # Clear any local changes made by applied patches
1534 undo_tf_patches
1535
1536 echo "##########"
1537 )
1538 fi
1539
1540 echo
1541 echo
1542done
1543
1544call_hook pre_package
1545
1546call_hook post_package
1547
1548if upon "$jenkins_run" && upon "$artefacts_receiver" && [ -d "artefacts" ]; then
Zelalem219df412020-05-17 19:21:20 -05001549 source "$CI_ROOT/script/send_artefacts.sh" "artefacts"
Fathi Boudra422bf772019-12-02 11:10:16 +02001550fi
1551
1552echo
1553echo "Done"