blob: e165da63080f3b160db098d4f1ac41ac22f6930b [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
Paul Sokolovskybe6510c2024-08-15 21:54:00 +0300101# Retry a command a number of times if it fails. Intended for I/O commands
102# in a CI environment which may be flaky.
103function retry() {
104 for i in $(seq 1 3); do
105 if "$@"; then
106 return 0
107 fi
108 sleep $(( i * 5 ))
109 done
110 return 1
111}
112
Fathi Boudra422bf772019-12-02 11:10:16 +0200113# Call hook $1 in all chosen fragments if it's defined. Hooks are invoked from
114# within a subshell, so any variables set within a hook are lost. Should a
115# variable needs to be set from within a hook, the function 'set_hook_var'
116# should be used
117call_hook() {
118 local func="$1"
119 local config_fragment
120
121 [ -z "$func" ] && return 0
122
Paul Sokolovskye9962cd2021-12-17 18:39:40 +0300123 echo "=== Calling hooks: $1 ==="
124
Fathi Boudra422bf772019-12-02 11:10:16 +0200125 : >"$hook_env_file"
126
Nicola Mazzucato7fc5abd2024-02-23 21:32:48 +0000127 if [ "$run_config_candidates" ]; then
128 for config_fragment in $run_config_candidates; do
Fathi Boudra422bf772019-12-02 11:10:16 +0200129 (
130 source "$ci_root/run_config/$config_fragment"
131 call_func "$func" "$config_fragment"
132 )
133 done
134 fi
135
136 # Also source test config file
137 (
138 unset "$func"
139 source "$test_config_file"
140 call_func "$func" "$(basename $test_config_file)"
141 )
142
143 # Have any variables set take effect
144 source "$hook_env_file"
Paul Sokolovskye9962cd2021-12-17 18:39:40 +0300145
146 echo "=== End calling hooks: $1 ==="
Fathi Boudra422bf772019-12-02 11:10:16 +0200147}
148
149# Set a variable from within a hook
150set_hook_var() {
151 echo "export $1=\"${2?}\"" >> "$hook_env_file"
152}
153
154# Append to an array from within a hook
155append_hook_var() {
156 echo "export $1+=\"${2?}\"" >> "$hook_env_file"
157}
158
159# Have the main build script source a file
160source_later() {
161 echo "source ${1?}" >> "$hook_env_file"
162}
163
164# Setup TF build wrapper function by pointing to a script containing a function
165# that will be called with the TF build commands.
166setup_tf_build_wrapper() {
167 source_later "$ci_root/script/${wrapper?}_wrapper.sh"
168 set_hook_var "tf_build_wrapper" "${wrapper}_wrapper"
169 echo "Setup $wrapper build wrapper."
170}
171
172# Collect .bin files for archiving
173collect_build_artefacts() {
174 if [ ! -d "${from:?}" ]; then
175 return
176 fi
177
Yann Gautier7e9d6cf2023-03-08 14:24:38 +0100178 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 +0200179 echo "You probably are running local CI on local repositories."
180 echo "Did you set 'dont_clean' but forgot to run 'distclean'?"
181 die
182 fi
183}
184
185# SCP and MCP binaries are named firmware.{bin,elf}, and are placed under
186# scp/mcp_ramfw and scp/mcp_romfw directories, so can't be collected by
187# collect_build_artefacts function.
188collect_scp_artefacts() {
189 to="${to:?}" \
Joel Goddard9bdfe3c2021-02-25 10:15:14 +0000190 find "$scp_root" \( \( -name "*.bin" -o -name '*.elf' \) -and ! -name 'CMake*' \) -exec bash -c '
Fathi Boudra422bf772019-12-02 11:10:16 +0200191 for file; do
192 ext="$(echo $file | awk -F. "{print \$NF}")"
193 case $file in
Anurag Koulbaedf932021-12-09 12:49:56 +0000194 */firmware-scp_ramfw/bin/*|*/firmware-scp_ramfw_fvp/bin/*)
Fathi Boudra422bf772019-12-02 11:10:16 +0200195 cp $file $to/scp_ram.$ext
196 ;;
Joel Goddard9bdfe3c2021-02-25 10:15:14 +0000197 */firmware-scp_romfw/bin/*)
Fathi Boudra422bf772019-12-02 11:10:16 +0200198 cp $file $to/scp_rom.$ext
199 ;;
Anurag Koulbaedf932021-12-09 12:49:56 +0000200 */firmware-mcp_ramfw/bin/*|*/firmware-mcp_ramfw_fvp/bin/*)
Fathi Boudra422bf772019-12-02 11:10:16 +0200201 cp $file $to/mcp_ram.$ext
202 ;;
Joel Goddard9bdfe3c2021-02-25 10:15:14 +0000203 */firmware-mcp_romfw/bin/*)
Fathi Boudra422bf772019-12-02 11:10:16 +0200204 cp $file $to/mcp_rom.$ext
205 ;;
Joel Goddard9bdfe3c2021-02-25 10:15:14 +0000206 */firmware-scp_romfw_bypass/bin/*)
Zelalem219df412020-05-17 19:21:20 -0500207 cp $file $to/scp_rom_bypass.$ext
208 ;;
Fathi Boudra422bf772019-12-02 11:10:16 +0200209 *)
210 echo "Unknown SCP binary: $file" >&2
211 ;;
212 esac
213 done
214 ' bash '{}' +
215}
216
Manish Pandey1e7be852020-11-09 16:04:48 +0000217# Collect SPM/hafnium artefacts with "secure_" appended to the files
218# generated for SPM(secure hafnium).
219collect_spm_artefacts() {
Madhukar Pappireddyc683cf62021-11-01 14:38:32 -0500220 if [ -d "${non_secure_from:?}" ]; then
221 find "$non_secure_from" \( -name "*.bin" -o -name '*.elf' \) -exec cp -t "${to:?}" '{}' +
Manish Pandey1e7be852020-11-09 16:04:48 +0000222 fi
223
Madhukar Pappireddyc683cf62021-11-01 14:38:32 -0500224 if [ -d "${secure_from:?}" ]; then
225 for f in $(find "$secure_from" \( -name "*.bin" -o -name '*.elf' \)); do cp -- "$f" "${to:?}"/secure_$(basename $f); done
226 fi
Manish Pandey1e7be852020-11-09 16:04:48 +0000227}
228
Javier Almansa Sobrino412d3612020-05-22 17:53:12 +0100229# Map the UART ID used for expect with the UART descriptor and port
230# used by the FPGA automation tools.
231map_uart() {
232 local port="${port:?}"
233 local descriptor="${descriptor:?}"
234 local baudrate="${baudrate:?}"
235 local run_root="${archive:?}/run"
236
237 local uart_dir="$run_root/uart${uart:?}"
238 mkdir -p "$uart_dir"
239
240 echo "$port" > "$uart_dir/port"
241 echo "$descriptor" > "$uart_dir/descriptor"
242 echo "$baudrate" > "$uart_dir/baudrate"
243
244 echo "UART${uart} mapped to port ${port} with descriptor ${descriptor} and baudrate ${baudrate}"
245}
246
Fathi Boudra422bf772019-12-02 11:10:16 +0200247# Arrange environment varibles to be set when expect scripts are launched
248set_expect_variable() {
249 local var="${1:?}"
250 local val="${2?}"
251
252 local run_root="${archive:?}/run"
253 local uart_dir="$run_root/uart${uart:?}"
254 mkdir -p "$uart_dir"
255
256 env_file="$uart_dir/env" quote="1" emit_env "$var" "$val"
257 echo "UART$uart: env has $@"
258}
259
260# Place the binary package a pointer to expect script, and its parameters
261track_expect() {
262 local file="${file:?}"
263 local timeout="${timeout-600}"
264 local run_root="${archive:?}/run"
265
266 local uart_dir="$run_root/uart${uart:?}"
267 mkdir -p "$uart_dir"
268
269 echo "$file" > "$uart_dir/expect"
270 echo "$timeout" > "$uart_dir/timeout"
Paul Sokolovskybfa8bab2023-01-25 19:34:51 +0700271 if [ -n "$lava_timeout" ]; then
272 set_run_env "lava_timeout" "$lava_timeout"
273 fi
Fathi Boudra422bf772019-12-02 11:10:16 +0200274
Paul Sokolovskybfa8bab2023-01-25 19:34:51 +0700275 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 +0200276
Chris Kayfab6edc2022-11-17 19:18:32 +0000277 if [ ! -z "${port}" ]; then
278 echo "${port}" > "$uart_dir/port"
279 fi
280
Fathi Boudra422bf772019-12-02 11:10:16 +0200281 # The run script assumes UART0 to be primary. If we're asked to set any
282 # other UART to be primary, set a run environment variable to signal
283 # that to the run script
284 if upon "$set_primary"; then
285 echo "Primary UART set to UART$uart."
286 set_run_env "primary_uart" "$uart"
287 fi
Madhukar Pappireddy1e953722021-11-08 15:23:02 -0600288
289 # UART used by payload(such as tftf, Linux) may not be the same as the
290 # primary UART. Set a run environment variable to track the payload
291 # UART which is tracked to check if the test has finished sucessfully.
292 if upon "$set_payload_uart"; then
293 echo "Payload uses UART$uart."
294 set_run_env "payload_uart" "$uart"
295 fi
Fathi Boudra422bf772019-12-02 11:10:16 +0200296}
297
298# Extract a FIP in $1 using fiptool
299extract_fip() {
300 local fip="$1"
301
302 if is_url "$1"; then
303 url="$1" fetch_file
304 fip="$(basename "$1")"
305 fi
306
307 "$fiptool" unpack "$fip"
308 echo "Extracted FIP: $fip"
309}
310
311# Report build failure by printing a the tail end of build log. Archive the
312# build log for later inspection
313fail_build() {
314 local log_path
315
316 if upon "$jenkins_run"; then
317 log_path="$BUILD_URL/artifact/artefacts/build.log"
318 else
319 log_path="$build_log"
320 fi
321
322 echo
Leonardo Sandovalae97eda2020-11-12 10:07:03 -0600323 echo "Build failed! Full build log below:"
Fathi Boudra422bf772019-12-02 11:10:16 +0200324 echo "[...]"
325 echo
Leonardo Sandovalae97eda2020-11-12 10:07:03 -0600326 cat "$build_log"
Fathi Boudra422bf772019-12-02 11:10:16 +0200327 echo
328 echo "See $log_path for full output"
329 echo
330 cp -t "$archive" "$build_log"
331 exit 1;
332}
333
334# Build a FIP with supplied arguments
335build_fip() {
336 (
337 echo "Building FIP with arguments: $@"
338 local tf_env="$workspace/tf.env"
339
340 if [ -f "$tf_env" ]; then
341 set -a
342 source "$tf_env"
343 set +a
344 fi
345
346 make -C "$tf_root" $(cat "$tf_config_file") DEBUG="$DEBUG" V=1 "$@" \
347 ${fip_targets:-fip} &>>"$build_log" || fail_build
348 )
349}
350
Sandrine Bailleux189fdb32023-10-20 13:41:22 +0200351# Build any extra rule from TF-A makefile with supplied arguments.
352#
353# This is useful in case you need to build something else than firmware binaries
354# or the FIP.
355build_tf_extra() {
356 (
357 tf_extra_rules=${tf_extra_rules:?}
358 echo "Building extra TF rule(s): $tf_extra_rules"
359 echo " Arguments: $@"
360
361 local tf_env="$workspace/tf.env"
362
363 if [ -f "$tf_env" ]; then
364 set -a
365 source "$tf_env"
366 set +a
367 fi
368
369 make -C "$tf_root" $(cat "$tf_config_file") DEBUG="$DEBUG" V=1 "$@" \
370 ${tf_extra_rules} &>>"$build_log" || fail_build
371 )
372}
373
Fathi Boudra422bf772019-12-02 11:10:16 +0200374fip_update() {
375 # Before the update process, check if the given image is supported by
376 # the fiptool. It's assumed that both fiptool and cert_create move in
Chris Kay197b1022023-08-16 21:31:41 +0100377 # tandem, and therefore, if one has support, the other has it too.
378 if ! ("$fiptool" update 2>&1 || true) | grep -qe "\s\+--${bin_name:?}"; then
Fathi Boudra422bf772019-12-02 11:10:16 +0200379 return 1
380 fi
381
382 if not_upon "$(get_tf_opt TRUSTED_BOARD_BOOT)"; then
383 echo "Updating FIP image: $bin_name"
384 # Update HW config. Without TBBR, it's only a matter of using
385 # the update sub-command of fiptool
386 "$fiptool" update "--$bin_name" "${src:-}" \
387 "$archive/fip.bin"
388 else
389 echo "Updating FIP image (TBBR): $bin_name"
390 # With TBBR, we need to unpack, re-create certificates, and then
391 # recreate the FIP.
392 local fip_dir="$(mktempdir)"
393 local bin common_args stem
394 local rot_key="$(get_tf_opt ROT_KEY)"
395
396 rot_key="${rot_key:?}"
397 if ! is_abs "$rot_key"; then
398 rot_key="$tf_root/$rot_key"
399 fi
400
401 # Arguments only for cert_create
402 local cert_args="-n"
403 cert_args+=" --tfw-nvctr ${nvctr:-31}"
404 cert_args+=" --ntfw-nvctr ${nvctr:-223}"
405 cert_args+=" --key-alg ${KEY_ALG:-rsa}"
406 cert_args+=" --rot-key $rot_key"
407
408 local dyn_config_opts=(
Zelalem1af7a7b2020-08-04 17:34:32 -0500409 "fw-config"
Fathi Boudra422bf772019-12-02 11:10:16 +0200410 "hw-config"
411 "tb-fw-config"
412 "nt-fw-config"
413 "soc-fw-config"
414 "tos-fw-config"
415 )
416
417 # Binaries without key certificates
418 declare -A has_no_key_cert
419 for bin in "tb-fw" "${dyn_config_opts[@]}"; do
420 has_no_key_cert["$bin"]="1"
421 done
422
423 # Binaries without certificates
424 declare -A has_no_cert
425 for bin in "hw-config" "${dyn_config_opts[@]}"; do
426 has_no_cert["$bin"]="1"
427 done
428
429 pushd "$fip_dir"
430
431 # Unpack FIP
432 "$fiptool" unpack "$archive/fip.bin" &>>"$build_log"
433
434 # Remove all existing certificates
435 rm -f *-cert.bin
436
437 # Copy the binary to be updated
438 cp -f "$src" "${bin_name}.bin"
439
440 # FIP unpack dumps binaries with the same name as the option
441 # used to pack it; likewise for certificates. Reverse-engineer
442 # the command line from the binary output.
443 common_args="--trusted-key-cert trusted_key.crt"
444 for bin in *.bin; do
445 stem="${bin%%.bin}"
446 common_args+=" --$stem $bin"
447 if not_upon "${has_no_cert[$stem]}"; then
448 common_args+=" --$stem-cert $stem.crt"
449 fi
450 if not_upon "${has_no_key_cert[$stem]}"; then
451 common_args+=" --$stem-key-cert $stem-key.crt"
452 fi
453 done
454
455 # Create certificates
456 "$cert_create" $cert_args $common_args &>>"$build_log"
457
458 # Recreate and archive FIP
459 "$fiptool" create $common_args "fip.bin" &>>"$build_log"
460 archive_file "fip.bin"
461
462 popd
463 fi
464}
465
466# Update hw-config in FIP, and remove the original DTB afterwards.
467update_fip_hw_config() {
468 # The DTB needs to be loaded by the model (and not updated in the FIP)
Madhukar Pappireddy9062ebf2021-03-02 17:07:06 -0600469 # in configs:
470 # 1. Where BL2 isn't present
471 # 2. Where we boot to Linux directly as BL33
Fathi Boudra422bf772019-12-02 11:10:16 +0200472 case "1" in
473 "$(get_tf_opt RESET_TO_BL31)" | \
Madhukar Pappireddy9062ebf2021-03-02 17:07:06 -0600474 "$(get_tf_opt ARM_LINUX_KERNEL_AS_BL33)" | \
Fathi Boudra422bf772019-12-02 11:10:16 +0200475 "$(get_tf_opt RESET_TO_SP_MIN)" | \
Maksims Svecovs7a0da522023-03-06 16:28:27 +0000476 "$(get_tf_opt RESET_TO_BL2)")
Fathi Boudra422bf772019-12-02 11:10:16 +0200477 return 0;;
478 esac
479
480 if bin_name="hw-config" src="$archive/dtb.bin" fip_update; then
481 # Remove the DTB so that model won't load it
482 rm -f "$archive/dtb.bin"
483 fi
484}
485
486get_scp_opt() {
487 (
488 name="${1:?}"
489 if config_valid "$scp_config_file"; then
490 source "$scp_config_file"
491 echo "${!name}"
492 fi
493 )
494}
495
496get_tftf_opt() {
497 (
498 name="${1:?}"
499 if config_valid "$tftf_config_file"; then
500 source "$tftf_config_file"
501 echo "${!name}"
502 fi
503 )
504}
505
506get_tf_opt() {
507 (
508 name="${1:?}"
509 if config_valid "$tf_config_file"; then
510 source "$tf_config_file"
511 echo "${!name}"
512 fi
513 )
514}
515
516build_tf() {
517 (
518 env_file="$workspace/tf.env"
519 config_file="${tf_build_config:-$tf_config_file}"
520
521 # Build fiptool and all targets by default
Harrison Mutai32de9d02023-06-12 14:23:37 +0100522 build_targets="${tf_build_targets:-fiptool all}"
Fathi Boudra422bf772019-12-02 11:10:16 +0200523
524 source "$config_file"
525
526 # If it is a TBBR build, extract the MBED TLS library from archive
Manish V Badarkhe8f125012021-12-21 05:47:52 +0000527 if [ "$(get_tf_opt TRUSTED_BOARD_BOOT)" = 1 ] ||
Manish V Badarkhef43e3f52022-06-21 20:37:25 +0100528 [ "$(get_tf_opt MEASURED_BOOT)" = 1 ] ||
529 [ "$(get_tf_opt DRTM_SUPPORT)" = 1 ]; then
Fathi Boudra422bf772019-12-02 11:10:16 +0200530 mbedtls_dir="$workspace/mbedtls"
531 if [ ! -d "$mbedtls_dir" ]; then
532 mbedtls_ar="$workspace/mbedtls.tar.gz"
533
534 url="$mbedtls_archive" saveas="$mbedtls_ar" fetch_file
535 mkdir "$mbedtls_dir"
Leonardo Sandovalec9e16c2020-09-09 14:32:40 -0500536 extract_tarball $mbedtls_ar $mbedtls_dir --strip-components=1
Fathi Boudra422bf772019-12-02 11:10:16 +0200537 fi
538
539 emit_env "MBEDTLS_DIR" "$mbedtls_dir"
540 fi
Jimmy Brisson0d5e12c2023-05-16 14:51:51 -0500541 if [ "$(get_tf_opt PLATFORM_TEST)" = "tfm-testsuite" ] &&
542 not_upon "${TF_M_TESTS_PATH}"; then
543 emit_env "TF_M_TESTS_PATH" "$WORKSPACE/tf-m-tests"
544 fi
545 if [ "$(get_tf_opt PLATFORM_TEST)" = "tfm-testsuite" ] &&
546 not_upon "${TF_M_EXTRAS_PATH}"; then
547 emit_env "TF_M_EXTRAS_PATH" "$WORKSPACE/tf-m-extras"
548 fi
David Vincze82db6932024-02-21 12:05:50 +0100549 if [ "$(get_tf_opt DICE_PROTECTION_ENVIRONMENT)" = 1 ] &&
550 not_upon "${QCBOR_DIR}"; then
551 emit_env "QCBOR_DIR" "$WORKSPACE/qcbor"
552 fi
Fathi Boudra422bf772019-12-02 11:10:16 +0200553 if [ -f "$env_file" ]; then
554 set -a
555 source "$env_file"
556 set +a
557 fi
558
Harrison Mutai013f6332022-02-16 16:06:33 +0000559 if is_arm_jenkins_env || upon "$local_ci"; then
560 path_list=(
561 "$llvm_dir/bin"
562 )
563 extend_path "PATH" "path_list"
564 fi
565
Fathi Boudra422bf772019-12-02 11:10:16 +0200566 cd "$tf_root"
567
568 # Always distclean when running on Jenkins. Skip distclean when running
569 # locally and explicitly requested.
570 if upon "$jenkins_run" || not_upon "$dont_clean"; then
571 make distclean &>>"$build_log" || fail_build
572 fi
573
574 # Log build command line. It is left unfolded on purpose to assist
575 # copying to clipboard.
576 cat <<EOF | log_separator >/dev/null
577
578Build command line:
579 $tf_build_wrapper make $make_j_opts $(cat "$config_file" | tr '\n' ' ') DEBUG=$DEBUG V=1 $build_targets
580
Paul Sokolovsky7f71b072023-10-16 12:59:09 +0300581CC version:
582$(${CC-${CROSS_COMPILE}gcc} -v 2>&1)
Fathi Boudra422bf772019-12-02 11:10:16 +0200583EOF
584
Javier Almansa Sobrinoe8363182020-11-10 16:40:53 +0000585 if not_upon "$local_ci"; then
586 connect_debugger=0
587 fi
588
Fathi Boudra422bf772019-12-02 11:10:16 +0200589 # Build TF. Since build output is being directed to the build log, have
590 # descriptor 3 point to the current terminal for build wrappers to vent.
Harrison Mutai6361dbe2023-02-16 14:12:40 +0000591 $tf_build_wrapper poetry run make $make_j_opts $(cat "$config_file") \
Javier Almansa Sobrinoe8363182020-11-10 16:40:53 +0000592 DEBUG="$DEBUG" V=1 SPIN_ON_BL1_EXIT="$connect_debugger" \
Fathi Boudra422bf772019-12-02 11:10:16 +0200593 $build_targets 3>&1 &>>"$build_log" || fail_build
Harrison Mutai32de9d02023-06-12 14:23:37 +0100594
Harrison Mutai6dafb5f2023-07-18 15:21:48 +0100595 if [ "$build_targets" != "doc" ]; then
Harrison Mutai2c2c9172024-04-12 11:24:27 +0000596 (poetry run memory -sr "$tf_build_root" 2>&1 || true) | tee -a "$build_log"
Harrison Mutai6dafb5f2023-07-18 15:21:48 +0100597 fi
Fathi Boudra422bf772019-12-02 11:10:16 +0200598 )
599}
600
601build_tftf() {
602 (
603 config_file="${tftf_build_config:-$tftf_config_file}"
604
605 # Build tftf target by default
606 build_targets="${tftf_build_targets:-all}"
607
608 source "$config_file"
609
610 cd "$tftf_root"
611
612 # Always distclean when running on Jenkins. Skip distclean when running
613 # locally and explicitly requested.
614 if upon "$jenkins_run" || not_upon "$dont_clean"; then
615 make distclean &>>"$build_log" || fail_build
616 fi
617
618 # TFTF build system cannot reliably deal with -j option, so we avoid
619 # using that.
620
621 # Log build command line
622 cat <<EOF | log_separator >/dev/null
623
624Build command line:
625 make $(cat "$config_file" | tr '\n' ' ') DEBUG=$DEBUG V=1 $build_targets
626
627EOF
628
629 make $(cat "$config_file") DEBUG="$DEBUG" V=1 \
630 $build_targets &>>"$build_log" || fail_build
631 )
632}
633
634build_scp() {
635 (
636 config_file="${scp_build_config:-$scp_config_file}"
637
638 source "$config_file"
639
640 cd "$scp_root"
641
642 # Always distclean when running on Jenkins. Skip distclean when running
643 # locally and explicitly requested.
644 if upon "$jenkins_run" || not_upon "$dont_clean"; then
Leandro Belli99e20b22022-12-29 13:50:47 +0000645 make -f Makefile.cmake clean &>>"$build_log" || fail_build
Fathi Boudra422bf772019-12-02 11:10:16 +0200646 fi
647
Joel Goddard9bdfe3c2021-02-25 10:15:14 +0000648 python3 -m venv .venv
649 . .venv/bin/activate
650
651 # Install extra tools used by CMake build system
652 pip install -r requirements.txt --timeout 30 --retries 15
653
Fathi Boudra422bf772019-12-02 11:10:16 +0200654 # Log build command line. It is left unfolded on purpose to assist
655 # copying to clipboard.
656 cat <<EOF | log_separator >/dev/null
657
658SCP build command line:
Joel Goddard9bdfe3c2021-02-25 10:15:14 +0000659 make -f Makefile.cmake $(cat "$config_file" | tr '\n' ' ') \
660 TOOLCHAIN=GNU \
661 MODE="$mode" \
Nicola Mazzucato506b5802021-12-24 14:23:25 +0000662 EXTRA_CONFIG_ARGS+=-DDISABLE_CPPCHECK=true \
Joel Goddard9bdfe3c2021-02-25 10:15:14 +0000663 V=1 &>>"$build_log"
Fathi Boudra422bf772019-12-02 11:10:16 +0200664
665EOF
666
667 # Build SCP
Joel Goddard9bdfe3c2021-02-25 10:15:14 +0000668 make -f Makefile.cmake $(cat "$config_file" | tr '\n' ' ') \
669 TOOLCHAIN=GNU \
670 MODE="$mode" \
Nicola Mazzucato506b5802021-12-24 14:23:25 +0000671 EXTRA_CONFIG_ARGS+=-DDISABLE_CPPCHECK=true \
Joel Goddard9bdfe3c2021-02-25 10:15:14 +0000672 V=1 &>>"$build_log" \
Fathi Boudra422bf772019-12-02 11:10:16 +0200673 || fail_build
674 )
675}
676
Zelalem219df412020-05-17 19:21:20 -0500677clone_scp_tools() {
678
679 if [ ! -d "$scp_tools_root" ]; then
680 echo "Cloning SCP-tools ... $scp_tools_commit" |& log_separator
681
682 clone_url="${SCP_TOOLS_CHECKOUT_LOC:-$scp_tools_src_repo_url}" \
683 where="$scp_tools_root" \
684 refspec="${scp_tools_commit}"
685 clone_repo &>>"$build_log"
686 else
687 echo "Already cloned SCP-tools ..." |& log_separator
688 fi
689
690 show_head "$scp_tools_root"
691
692 cd "$scp_tools_root"
693
694 echo "Updating submodules"
695
696 git submodule init
697
698 git submodule update
699
Nicola Mazzucato9b171422023-08-29 15:50:49 +0100700 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 +0000701
Zelalem219df412020-05-17 19:21:20 -0500702 cd "scmi"
Nicola Mazzucato7302cd32021-12-14 13:36:57 +0000703 git checkout $lib_commit
Zelalem219df412020-05-17 19:21:20 -0500704
705 git show --quiet --no-color | sed 's/^/ > /g'
706}
707
708clone_tf_for_scp_tools() {
709 scp_tools_arm_tf="$scp_tools_root/arm-tf"
710
711 if [ ! -d "$scp_tools_arm_tf" ]; then
712 echo "Cloning TF-4-SCP-tools ..." |& log_separator
713
714 clone_url="$tf_for_scp_tools_src_repo_url"
715 where="$scp_tools_arm_tf"
716
717 git clone "$clone_url" "$where"
718
719 cd "$scp_tools_arm_tf"
720
Joel Goddard3ad03062021-03-16 16:47:42 +0000721 git checkout --track origin/juno-v4.3
Zelalem219df412020-05-17 19:21:20 -0500722
723 git show --quiet --no-color | sed 's/^/ > /g'
724
725 else
726 echo "Already cloned TF-4-SCP-tools ..." |& log_separator
727 fi
728}
729
730build_scmi_lib_scp_tools() {
731 (
732 cd "$scp_tools_root"
733
734 cd "scmi"
735
736 scp_tools_arm_tf="$scp_tools_root/arm-tf"
737
Leonardo Sandovalfeae3a22020-11-17 16:53:59 -0600738 cross_compile="$(set_cross_compile_gcc_linaro_toolchain)"
Zelalem219df412020-05-17 19:21:20 -0500739
740 std_libs="-I$scp_tools_arm_tf/include/common"
741 std_libs="$std_libs -I$scp_tools_arm_tf/include/common/tbbr"
742 std_libs="$std_libs -I$scp_tools_arm_tf/include/drivers/arm"
743 std_libs="$std_libs -I$scp_tools_arm_tf/include/lib"
744 std_libs="$std_libs -I$scp_tools_arm_tf/include/lib/aarch64"
745 std_libs="$std_libs -I$scp_tools_arm_tf/include/lib/stdlib"
746 std_libs="$std_libs -I$scp_tools_arm_tf/include/lib/stdlib/sys"
747 std_libs="$std_libs -I$scp_tools_arm_tf/include/lib/xlat_tables"
748 std_libs="$std_libs -I$scp_tools_arm_tf/include/plat/common"
749 std_libs="$std_libs -I$scp_tools_arm_tf/include/plat/arm/common"
750 std_libs="$std_libs -I$scp_tools_arm_tf/include/plat/arm/css/common"
751 std_libs="$std_libs -I$scp_tools_arm_tf/include/plat/arm/board/common"
752 std_libs="$std_libs -I$scp_tools_arm_tf/include/plat/arm/soc/common"
753 std_libs="$std_libs -I$scp_tools_arm_tf/plat/arm/board/juno/include"
754
755 cflags="-Og -g"
756 cflags="$cflags -mgeneral-regs-only"
757 cflags="$cflags -mstrict-align"
758 cflags="$cflags -nostdinc"
759 cflags="$cflags -fno-inline"
760 cflags="$cflags -ffreestanding"
761 cflags="$cflags -ffunction-sections"
762 cflags="$cflags -fdata-sections"
763 cflags="$cflags -DAARCH64"
764 cflags="$cflags -DPRId32=\"ld\""
Joel Goddard3ad03062021-03-16 16:47:42 +0000765 cflags="$cflags -DVERBOSE_LEVEL=3"
Zelalem219df412020-05-17 19:21:20 -0500766
767 cflags="$cflags $std_libs"
768
Joel Goddard3ad03062021-03-16 16:47:42 +0000769 protocols="performance,power_domain,system_power,reset"
Zelalem219df412020-05-17 19:21:20 -0500770
771 echo "Building SCMI library (SCP-tools) ..."
772
773 make "CROSS_COMPILE=$cross_compile" \
774 "CFLAGS=$cflags" \
Joel Goddard3ad03062021-03-16 16:47:42 +0000775 "PLAT=baremetal" \
Zelalem219df412020-05-17 19:21:20 -0500776 "PROTOCOLS=$protocols" \
777 "clean" \
778 "all"
779 )
780}
781
782build_tf_for_scp_tools() {
783
784 cd "$scp_tools_root/arm-tf"
785
Leonardo Sandovalfeae3a22020-11-17 16:53:59 -0600786 cross_compile="$(set_cross_compile_gcc_linaro_toolchain)"
Zelalem219df412020-05-17 19:21:20 -0500787
788 if [ "$1" = "release" ]; then
789 echo "Build TF-4-SCP-Tools rls..."
790 else
791 echo "Build TF-4-SCP-Tools dbg..."
792
793 make realclean
794
795 make "BM_TEST=scmi" \
796 "ARM_BOARD_OPTIMISE_MEM=1" \
797 "BM_CSS=juno" \
798 "CSS_USE_SCMI_SDS_DRIVER=1" \
799 "PLAT=juno" \
800 "DEBUG=1" \
801 "PLATFORM=juno" \
802 "CROSS_COMPILE=$cross_compile" \
803 "BM_WORKSPACE=$scp_tools_root/baremetal"
804
805 archive_file "build/juno/debug/bl1.bin"
806
807 archive_file "build/juno/debug/bl2.bin"
808
809 archive_file "build/juno/debug/bl31.bin"
810 fi
811}
812
813build_fip_for_scp_tools() {
814
815 cd "$scp_tools_root/arm-tf"
816
Leonardo Sandovalfeae3a22020-11-17 16:53:59 -0600817 cross_compile="$(set_cross_compile_gcc_linaro_toolchain)"
Zelalem219df412020-05-17 19:21:20 -0500818
Joel Goddard9bdfe3c2021-02-25 10:15:14 +0000819 if [ ! -d "$scp_root/build/juno/GNU/debug/firmware-scp_ramfw" ]; then
Zelalem219df412020-05-17 19:21:20 -0500820 make fiptool
821 echo "Make FIP 4 SCP-Tools rls..."
822
823 else
824 make fiptool
825 echo "Make FIP 4 SCP-Tools dbg..."
826
827 make "PLAT=juno" \
828 "all" \
829 "fip" \
830 "DEBUG=1" \
831 "CROSS_COMPILE=$cross_compile" \
832 "BL31=$scp_tools_root/arm-tf/build/juno/debug/bl31.bin" \
833 "BL33=$scp_tools_root/baremetal/dummy_bl33" \
Joel Goddard9bdfe3c2021-02-25 10:15:14 +0000834 "SCP_BL2=$scp_root/build/juno/GNU/$mode/firmware-scp_ramfw/bin/juno-bl2.bin"
Zelalem219df412020-05-17 19:21:20 -0500835
836 archive_file "$scp_tools_root/arm-tf/build/juno/debug/fip.bin"
837 fi
838}
839
840build_cc() {
841# Building code coverage plugin
842 ARM_DIR=/arm
843 pvlibversion=$(/arm/devsys-tools/abs/detag "SysGen:PVModelLib:$model_version::trunk")
844 PVLIB_HOME=$warehouse/SysGen/PVModelLib/$model_version/${pvlibversion}/external
845 if [ -n "$(find "$ARM_DIR" -maxdepth 0 -type d -empty 2>/dev/null)" ]; then
846 echo "Error: Arm warehouse not mounted. Please mount the Arm warehouse to your /arm local folder"
847 exit -1
848 fi # Error if arm warehouse not found
849 cd "$ccpathspec/scripts/tools/code_coverage/fastmodel_baremetal/bmcov"
850
851 make -C model-plugin PVLIB_HOME=$PVLIB_HOME &>>"$build_log"
852}
853
Olivier Deprez0a9a3482019-12-16 14:10:31 +0100854build_spm() {
855 (
856 env_file="$workspace/spm.env"
857 config_file="${spm_build_config:-$spm_config_file}"
858
859 source "$config_file"
860
861 if [ -f "$env_file" ]; then
862 set -a
863 source "$env_file"
864 set +a
865 fi
866
867 cd "$spm_root"
868
869 # Always clean when running on Jenkins. Skip clean when running
870 # locally and explicitly requested.
871 if upon "$jenkins_run" || not_upon "$dont_clean"; then
872 # make clean fails on a fresh repo where the project has not
873 # yet been built. Hence only clean if out/reference directory
874 # already exists.
875 if [ -d "out/reference" ]; then
876 make clean &>>"$build_log" || fail_build
877 fi
878 fi
879
880 # Log build command line. It is left unfolded on purpose to assist
881 # copying to clipboard.
882 cat <<EOF | log_separator >/dev/null
883
884Build command line:
885 make $make_j_opts $(cat "$config_file" | tr '\n' ' ')
886
887EOF
888
889 # Build SPM. Since build output is being directed to the build log, have
890 # descriptor 3 point to the current terminal for build wrappers to vent.
891 make $make_j_opts $(cat "$config_file") 3>&1 &>>"$build_log" \
892 || fail_build
893 )
894}
Zelalem219df412020-05-17 19:21:20 -0500895
Fathi Boudra422bf772019-12-02 11:10:16 +0200896# Set metadata for the whole package so that it can be used by both Jenkins and
897# shell
898set_package_var() {
899 env_file="$artefacts/env" emit_env "$@"
900}
901
902set_tf_build_targets() {
903 echo "Set build target to '${targets:?}'"
904 set_hook_var "tf_build_targets" "$targets"
905}
906
907set_tftf_build_targets() {
908 echo "Set build target to '${targets:?}'"
909 set_hook_var "tftf_build_targets" "$targets"
910}
911
912set_scp_build_targets() {
913 echo "Set build target to '${targets:?}'"
914 set_hook_var "scp_build_targets" "$targets"
915}
916
Olivier Deprez0a9a3482019-12-16 14:10:31 +0100917set_spm_build_targets() {
918 echo "Set build target to '${targets:?}'"
919 set_hook_var "spm_build_targets" "$targets"
920}
921
Daniel Boulbyb8d2a462022-03-07 13:55:25 +0000922set_spm_out_dir() {
923 echo "Set SPMC binary build to '${out_dir:?}'"
924 set_hook_var "spm_secure_out_dir" "$out_dir"
925}
Fathi Boudra422bf772019-12-02 11:10:16 +0200926# Look under $archive directory for known files such as blX images, kernel, DTB,
927# initrd etc. For each known file foo, if foo.bin exists, then set variable
928# foo_bin to the path of the file. Make the path relative to the workspace so as
929# to remove any @ characters, which Jenkins inserts for parallel runs. If the
930# file doesn't exist, unset its path.
931set_default_bin_paths() {
932 local image image_name image_path path
933 local archive="${archive:?}"
934 local set_vars
935 local var
936
937 pushd "$archive"
938
939 for file in *.bin; do
940 # Get a shell variable from the file's stem
941 var_name="${file%%.*}_bin"
942 var_name="$(echo "$var_name" | sed -r 's/[^[:alnum:]]/_/g')"
943
944 # Skip setting the variable if it's already
945 if [ "${!var_name}" ]; then
946 echo "Note: not setting $var_name; already set to ${!var_name}"
947 continue
948 else
949 set_vars+="$var_name "
950 fi
951
952 eval "$var_name=$file"
953 done
954
955 echo "Binary paths set for: "
956 {
957 for var in $set_vars; do
958 echo -n "\$$var "
959 done
960 } | fmt -80 | sed 's/^/ /'
961 echo
962
963 popd
964}
965
966gen_model_params() {
967 local model_param_file="$archive/model_params"
Javier Almansa Sobrinoe8363182020-11-10 16:40:53 +0000968 [ "$connect_debugger" ] && [ "$connect_debugger" -eq 1 ] && wait_debugger=1
Fathi Boudra422bf772019-12-02 11:10:16 +0200969
970 set_default_bin_paths
971 echo "Generating model parameter for $model..."
972 source "$ci_root/model/${model:?}.sh"
973 archive_file "$model_param_file"
974}
975
976set_model_path() {
977 set_run_env "model_path" "${1:?}"
978}
979
Zelalem1af7a7b2020-08-04 17:34:32 -0500980set_model_env() {
981 local var="${1:?}"
982 local val="${2?}"
983 local run_root="${archive:?}/run"
984
985 mkdir -p "$run_root"
986 echo "export $var=$val" >> "$run_root/model_env"
987}
Fathi Boudra422bf772019-12-02 11:10:16 +0200988set_run_env() {
989 local var="${1:?}"
990 local val="${2?}"
991 local run_root="${archive:?}/run"
992
993 mkdir -p "$run_root"
994 env_file="$run_root/env" quote="1" emit_env "$var" "$val"
995}
996
997show_head() {
998 # Display HEAD descripton
999 pushd "$1"
1000 git show --quiet --no-color | sed 's/^/ > /g'
1001 echo
1002 popd
1003}
1004
1005# Choose debug binaries to run; by default, release binaries are chosen to run
1006use_debug_bins() {
1007 local run_root="${archive:?}/run"
1008
1009 echo "Choosing debug binaries for execution"
1010 set_package_var "BIN_MODE" "debug"
1011}
1012
1013assert_can_git_clone() {
1014 local name="${1:?}"
1015 local dir="${!name}"
1016
1017 # If it doesn't exist, it can be cloned into
1018 if [ ! -e "$dir" ]; then
1019 return 0
1020 fi
1021
1022 # If it's a directory, it must be a Git clone already
1023 if [ -d "$dir" ] && [ -d "$dir/.git" ]; then
1024 # No need to clone again
1025 echo "Using existing git clone for $name: $dir"
1026 return 1
1027 fi
1028
1029 die "Path $dir exists but is not a git clone"
1030}
1031
1032clone_repo() {
1033 if ! is_url "${clone_url?}"; then
1034 # For --depth to take effect on local paths, it needs to use the
1035 # file:// scheme.
1036 clone_url="file://$clone_url"
1037 fi
1038
1039 git clone -q --depth 1 "$clone_url" "${where?}"
1040 if [ "$refspec" ]; then
1041 pushd "$where"
1042 git fetch -q --depth 1 origin "$refspec"
1043 git checkout -q FETCH_HEAD
1044 popd
1045 fi
1046}
1047
1048build_unstable() {
1049 echo "--BUILD UNSTABLE--" | tee -a "$build_log"
1050}
1051
1052undo_patch_record() {
1053 if [ ! -f "${patch_record:?}" ]; then
1054 return
1055 fi
1056
1057 # Undo patches in reverse
1058 echo
1059 for patch_name in $(tac "$patch_record"); do
1060 echo "Undoing $patch_name..."
1061 if ! git apply -R "$ci_root/patch/$patch_name"; then
1062 if upon "$local_ci"; then
1063 echo
1064 echo "Your local directory may have been dirtied."
1065 echo
1066 fi
1067 fail_build
1068 fi
1069 done
1070
1071 rm -f "$patch_record"
1072}
1073
1074undo_local_patches() {
1075 pushd "$tf_root"
1076 patch_record="$tf_patch_record" undo_patch_record
1077 popd
1078
1079 if [ -d "$tftf_root" ]; then
1080 pushd "$tftf_root"
1081 patch_record="$tftf_patch_record" undo_patch_record
1082 popd
1083 fi
1084}
1085
1086undo_tftf_patches() {
1087 pushd "$tftf_root"
1088 patch_record="$tftf_patch_record" undo_patch_record
1089 popd
1090}
1091
1092undo_tf_patches() {
1093 pushd "$tf_root"
1094 patch_record="$tf_patch_record" undo_patch_record
1095 popd
1096}
1097
1098apply_patch() {
1099 # If skip_patches is set, the developer has applied required patches
1100 # manually. They probably want to keep them applied for debugging
1101 # purposes too. This means we don't have to apply/revert them as part of
1102 # build process.
1103 if upon "$skip_patches"; then
1104 echo "Skipped applying ${1:?}..."
1105 return 0
1106 else
1107 echo "Applying ${1:?}..."
1108 fi
1109
Sandrine Bailleux4cb8c222023-09-13 13:48:15 +02001110 if git apply --reverse --check < "$ci_root/patch/$1" 2> /dev/null; then
Jimmy Brissonf134e4c2023-03-22 13:20:20 -05001111 echo "Skipping already applied ${1:?}"
1112 return 0
1113 fi
1114
Fathi Boudra422bf772019-12-02 11:10:16 +02001115 if git apply < "$ci_root/patch/$1"; then
1116 echo "$1" >> "${patch_record:?}"
1117 else
1118 if upon "$local_ci"; then
1119 undo_local_patches
1120 fi
1121 fail_build
1122 fi
1123}
1124
1125apply_tftf_patch() {
1126 pushd "$tftf_root"
1127 patch_record="$tftf_patch_record" apply_patch "$1"
1128 popd
1129}
1130
1131apply_tf_patch() {
1132 pushd "$tf_root"
1133 patch_record="$tf_patch_record" apply_patch "$1"
1134 popd
1135}
1136
1137# Clear workspace for a local run
Leandro Bellibe7b8fa2024-07-18 10:14:22 +01001138if not_upon "$jenkins_run" && not_upon "$dont_clean"; then
Fathi Boudra422bf772019-12-02 11:10:16 +02001139 rm -rf "$workspace"
1140
1141 # Clear residue from previous runs
1142 rm -rf "$archive"
1143fi
1144
1145mkdir -p "$workspace"
1146mkdir -p "$archive"
1147set_package_var "TEST_CONFIG" "$test_config"
1148
1149{
1150echo
1151echo "CONFIGURATION: $test_group/$test_config"
1152echo
1153} |& log_separator
1154
1155tf_config="$(echo "$build_configs" | awk -F, '{print $1}')"
1156tftf_config="$(echo "$build_configs" | awk -F, '{print $2}')"
1157scp_config="$(echo "$build_configs" | awk -F, '{print $3}')"
Zelalem219df412020-05-17 19:21:20 -05001158scp_tools_config="$(echo "$build_configs" | awk -F, '{print $4}')"
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001159spm_config="$(echo "$build_configs" | awk -F, '{print $5}')"
Fathi Boudra422bf772019-12-02 11:10:16 +02001160
1161test_config_file="$ci_root/group/$test_group/$test_config"
1162
1163tf_config_file="$ci_root/tf_config/$tf_config"
1164tftf_config_file="$ci_root/tftf_config/$tftf_config"
1165scp_config_file="$ci_root/scp_config/$scp_config"
Zelalem219df412020-05-17 19:21:20 -05001166scp_tools_config_file="$ci_root/scp_tools_config/$scp_tools_config"
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001167spm_config_file="$ci_root/spm_config/$spm_config"
Fathi Boudra422bf772019-12-02 11:10:16 +02001168
1169# File that keeps track of applied patches
1170tf_patch_record="$workspace/tf_patches"
1171tftf_patch_record="$workspace/tftf_patches"
1172
1173pushd "$workspace"
1174
1175if ! config_valid "$tf_config"; then
1176 tf_config=
1177else
1178 echo "Trusted Firmware config:"
1179 echo
1180 sort "$tf_config_file" | sed '/^\s*$/d;s/^/\t/'
1181 echo
1182fi
1183
1184if ! config_valid "$tftf_config"; then
1185 tftf_config=
1186else
1187 echo "Trusted Firmware TF config:"
1188 echo
1189 sort "$tftf_config_file" | sed '/^\s*$/d;s/^/\t/'
1190 echo
1191fi
1192
1193if ! config_valid "$scp_config"; then
1194 scp_config=
1195else
1196 echo "SCP firmware config:"
1197 echo
1198 sort "$scp_config_file" | sed '/^\s*$/d;s/^/\t/'
1199 echo
1200fi
1201
Zelalem219df412020-05-17 19:21:20 -05001202if ! config_valid "$scp_tools_config"; then
1203 scp_tools_config=
1204else
1205 echo "SCP Tools config:"
1206 echo
1207 sort "$scp_tools_config_file" | sed '/^\s*$/d;s/^/\t/'
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001208fi
1209
1210if ! config_valid "$spm_config"; then
1211 spm_config=
1212else
1213 echo "SPM config:"
1214 echo
1215 sort "$spm_config_file" | sed '/^\s*$/d;s/^/\t/'
Zelalem219df412020-05-17 19:21:20 -05001216 echo
1217fi
1218
Fathi Boudra422bf772019-12-02 11:10:16 +02001219if ! config_valid "$run_config"; then
1220 run_config=
1221fi
1222
1223if [ "$tf_config" ] && assert_can_git_clone "tf_root"; then
1224 # If the Trusted Firmware repository has already been checked out, use
1225 # that location. Otherwise, clone one ourselves.
1226 echo "Cloning Trusted Firmware..."
1227 clone_url="${TF_CHECKOUT_LOC:-$tf_src_repo_url}" where="$tf_root" \
1228 refspec="$TF_REFSPEC" clone_repo &>>"$build_log"
1229 show_head "$tf_root"
1230fi
1231
1232if [ "$tftf_config" ] && assert_can_git_clone "tftf_root"; then
1233 # If the Trusted Firmware TF repository has already been checked out,
1234 # use that location. Otherwise, clone one ourselves.
1235 echo "Cloning Trusted Firmware TF..."
1236 clone_url="${TFTF_CHECKOUT_LOC:-$tftf_src_repo_url}" where="$tftf_root" \
1237 refspec="$TFTF_REFSPEC" clone_repo &>>"$build_log"
1238 show_head "$tftf_root"
1239fi
1240
1241if [ "$scp_config" ] && assert_can_git_clone "scp_root"; then
1242 # If the SCP firmware repository has already been checked out,
1243 # use that location. Otherwise, clone one ourselves.
1244 echo "Cloning SCP Firmware..."
1245 clone_url="${SCP_CHECKOUT_LOC:-$scp_src_repo_url}" where="$scp_root" \
1246 refspec="${SCP_REFSPEC-master-upstream}" clone_repo &>>"$build_log"
1247
1248 pushd "$scp_root"
1249
1250 # Use filer submodule as a reference if it exists
Girish Pathak31b824e2021-03-03 20:58:21 +00001251 if [ -d "$SCP_CHECKOUT_LOC/cmsis" ]; then
Fathi Boudra422bf772019-12-02 11:10:16 +02001252 cmsis_reference="--reference $SCP_CHECKOUT_LOC/cmsis"
1253 fi
1254
1255 # If we don't have a reference yet, fall back to $cmsis_root if set, or
1256 # then to project filer if accessible.
1257 if [ -z "$cmsis_reference" ]; then
1258 cmsis_ref_repo="${cmsis_root:-$project_filer/ref-repos/cmsis}"
1259 if [ -d "$cmsis_ref_repo" ]; then
1260 cmsis_reference="--reference $cmsis_ref_repo"
1261 fi
1262 fi
1263
1264 git submodule -q update $cmsis_reference --init
1265
1266 popd
1267
1268 show_head "$scp_root"
1269fi
1270
Zelalem219df412020-05-17 19:21:20 -05001271if [ -n "$cc_config" ] ; then
1272 if [ "$cc_config" -eq 1 ] && assert_can_git_clone "cc_root"; then
1273 # Copy code coverage repository
1274 echo "Cloning Code Coverage..."
1275 git clone -q $cc_src_repo_url cc_plugin --depth 1 -b $cc_src_repo_tag > /dev/null
1276 show_head "$cc_root"
1277 fi
1278fi
1279
Daniel Boulby25385ab2023-12-14 14:36:25 +00001280if [ "$spm_config" ] ; then
1281 if assert_can_git_clone "spm_root"; then
1282 # If the SPM repository has already been checked out, use
1283 # that location. Otherwise, clone one ourselves.
1284 echo "Cloning SPM..."
1285 clone_url="${SPM_CHECKOUT_LOC:-$spm_src_repo_url}" \
1286 where="$spm_root" refspec="$SPM_REFSPEC" \
1287 clone_repo &>>"$build_log"
1288 fi
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001289
1290 # Query git submodules
1291 pushd "$spm_root"
Daniel Boulby25385ab2023-12-14 14:36:25 +00001292 # Check if submodules need initialising
Paul Sokolovskyad274422024-09-01 10:27:56 +03001293
1294 # This handling is needed to reliably fetch submodules
1295 # in CI environment.
1296 for subm in $(git submodule status | awk '/^-/ {print $2}'); do
1297 for i in $(seq 1 7); do
1298 git submodule init $subm
1299 if git submodule update $subm; then
1300 break
1301 fi
1302 git submodule deinit --force $subm
1303 echo "Retrying $subm"
1304 sleep $((RANDOM % 10 + 5))
1305 done
1306 done
1307
1308 git submodule status
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001309 popd
1310
1311 show_head "$spm_root"
1312fi
1313
Fathi Boudra422bf772019-12-02 11:10:16 +02001314if [ "$run_config" ]; then
1315 # Get candidates for run config
Nicola Mazzucato7fc5abd2024-02-23 21:32:48 +00001316 run_config_candidates="$("$ci_root/script/gen_run_config_candidates.py" \
Fathi Boudra422bf772019-12-02 11:10:16 +02001317 "$run_config")"
Nicola Mazzucato7fc5abd2024-02-23 21:32:48 +00001318 if [ -z "$run_config_candidates" ]; then
Fathi Boudra422bf772019-12-02 11:10:16 +02001319 die "No run config candidates!"
1320 else
1321 echo
1322 echo "Chosen fragments:"
1323 echo
Nicola Mazzucato7fc5abd2024-02-23 21:32:48 +00001324 echo "$run_config_candidates" | sed 's/^\|\n/\t/g'
Fathi Boudra422bf772019-12-02 11:10:16 +02001325 echo
1326 fi
1327fi
1328
1329call_hook "test_setup"
1330echo
1331
1332if upon "$local_ci"; then
1333 # For local runs, since each config is tried in sequence, it's
1334 # advantageous to run jobs in parallel
1335 if [ "$make_j" ]; then
1336 make_j_opts="-j $make_j"
1337 else
1338 n_cores="$(getconf _NPROCESSORS_ONLN)" 2>/dev/null || true
1339 if [ "$n_cores" ]; then
1340 make_j_opts="-j $n_cores"
1341 fi
1342 fi
1343fi
1344
Harrison Mutai07043e92023-07-06 09:41:12 +01001345# Install python build dependencies
1346if is_arm_jenkins_env; then
1347 source "$ci_root/script/install_python_deps.sh"
1348fi
1349
Fathi Boudra422bf772019-12-02 11:10:16 +02001350modes="${bin_mode:-debug release}"
1351for mode in $modes; do
Paul Sokolovskye9962cd2021-12-17 18:39:40 +03001352 echo "===== Building package in mode: $mode ====="
Fathi Boudra422bf772019-12-02 11:10:16 +02001353 # Build with a temporary archive
1354 build_archive="$archive/$mode"
1355 mkdir "$build_archive"
1356
1357 if [ "$mode" = "debug" ]; then
Zelalem219df412020-05-17 19:21:20 -05001358 export bin_mode="debug"
Fathi Boudra422bf772019-12-02 11:10:16 +02001359 DEBUG=1
1360 else
Zelalem219df412020-05-17 19:21:20 -05001361 export bin_mode="release"
Fathi Boudra422bf772019-12-02 11:10:16 +02001362 DEBUG=0
1363 fi
1364
1365 # Perform builds in a subshell so as not to pollute the current and
1366 # subsequent builds' environment
1367
Zelalem219df412020-05-17 19:21:20 -05001368 if config_valid "$cc_config"; then
1369 # Build code coverage plugin
1370 build_cc
1371 fi
1372
Fathi Boudra422bf772019-12-02 11:10:16 +02001373 # SCP build
1374 if config_valid "$scp_config"; then
1375 (
1376 echo "##########"
1377
1378 # Source platform-specific utilities
1379 plat="$(get_scp_opt PRODUCT)"
1380 plat_utils="$ci_root/${plat}_utils.sh"
1381 if [ -f "$plat_utils" ]; then
1382 source "$plat_utils"
1383 fi
1384
1385 archive="$build_archive"
1386 scp_build_root="$scp_root/build"
1387
1388 echo "Building SCP Firmware ($mode) ..." |& log_separator
1389
1390 build_scp
Fathi Boudra422bf772019-12-02 11:10:16 +02001391 to="$archive" collect_scp_artefacts
1392
1393 echo "##########"
1394 echo
1395 )
1396 fi
1397
Zelalem219df412020-05-17 19:21:20 -05001398 # SCP-tools build
1399 if config_valid "$scp_tools_config"; then
1400 (
1401 echo "##########"
1402
1403 archive="$build_archive"
1404 scp_tools_build_root="$scp_tools_root/build"
1405
1406 clone_scp_tools
1407
1408 echo "##########"
1409 echo
1410
1411 echo "##########"
1412 clone_tf_for_scp_tools
1413 echo "##########"
1414 echo
1415 )
1416 fi
1417
Fathi Boudra422bf772019-12-02 11:10:16 +02001418 # TFTF build
1419 if config_valid "$tftf_config"; then
1420 (
1421 echo "##########"
1422
Manish V Badarkhe3bd3fea2020-11-08 15:17:00 +00001423 plat_utils="$(get_tf_opt PLAT_UTILS)"
1424 if [ -z ${plat_utils} ]; then
1425 # Source platform-specific utilities.
1426 plat="$(get_tftf_opt PLAT)"
1427 plat_utils="$ci_root/${plat}_utils.sh"
1428 else
1429 # Source platform-specific utilities by
1430 # using plat_utils name.
1431 plat_utils="$ci_root/${plat_utils}.sh"
1432 fi
1433
Fathi Boudra422bf772019-12-02 11:10:16 +02001434 if [ -f "$plat_utils" ]; then
1435 source "$plat_utils"
1436 fi
1437
1438 archive="$build_archive"
1439 tftf_build_root="$tftf_root/build"
1440
1441 echo "Building Trusted Firmware TF ($mode) ..." |& log_separator
1442
1443 # Call pre-build hook
1444 call_hook pre_tftf_build
1445
1446 build_tftf
1447
1448 from="$tftf_build_root" to="$archive" collect_build_artefacts
1449
1450 # Clear any local changes made by applied patches
1451 undo_tftf_patches
1452
1453 echo "##########"
1454 echo
1455 )
1456 fi
1457
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001458 # SPM build
1459 if config_valid "$spm_config"; then
1460 (
1461 echo "##########"
1462
1463 # Get platform name from spm_config file
1464 plat="$(echo "$spm_config" | awk -F- '{print $1}')"
1465 plat_utils="$ci_root/${plat}_utils.sh"
1466 if [ -f "$plat_utils" ]; then
1467 source "$plat_utils"
1468 fi
1469
Daniel Boulbyb8d2a462022-03-07 13:55:25 +00001470 # Call pre-build hook
1471 call_hook pre_spm_build
1472
Manish Pandey1e7be852020-11-09 16:04:48 +00001473 # SPM build generates two sets of binaries, one for normal and other
1474 # for Secure world. We need both set of binaries for CI.
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001475 archive="$build_archive"
Manish Pandey1e7be852020-11-09 16:04:48 +00001476 spm_build_root="$spm_root/out/reference/$spm_secure_out_dir"
1477 hafnium_build_root="$spm_root/out/reference/$spm_non_secure_out_dir"
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001478
Daniel Boulbyb8d2a462022-03-07 13:55:25 +00001479 echo "spm_build_root is $spm_build_root"
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001480 echo "Building SPM ($mode) ..." |& log_separator
1481
1482 # NOTE: mode has no effect on SPM build (for now), hence debug
1483 # mode is built but subsequent build using release mode just
1484 # goes through with "nothing to do".
1485 build_spm
1486
1487 # Show SPM/Hafnium binary details
Madhukar Pappireddyc683cf62021-11-01 14:38:32 -05001488 cksum $spm_build_root/hafnium.bin
1489
1490 # Some platforms only have secure configuration enabled. Hence,
1491 # non secure hanfnium binary might not be built.
1492 if [ -f $hafnium_build_root/hafnium.bin ]; then
1493 cksum $hafnium_build_root/hafnium.bin
1494 fi
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001495
Manish Pandey1e7be852020-11-09 16:04:48 +00001496 secure_from="$spm_build_root" non_secure_from="$hafnium_build_root" to="$archive" collect_spm_artefacts
Olivier Deprez0a9a3482019-12-16 14:10:31 +01001497
1498 echo "##########"
1499 echo
1500 )
1501 fi
1502
Fathi Boudra422bf772019-12-02 11:10:16 +02001503 # TF build
1504 if config_valid "$tf_config"; then
1505 (
1506 echo "##########"
1507
Manish V Badarkhe3bd3fea2020-11-08 15:17:00 +00001508 plat_utils="$(get_tf_opt PLAT_UTILS)"
Madhukar Pappireddy2f284e12021-08-30 16:06:14 -05001509 export plat_variant="$(get_tf_opt TARGET_PLATFORM)"
1510
Manish V Badarkhe3bd3fea2020-11-08 15:17:00 +00001511 if [ -z ${plat_utils} ]; then
1512 # Source platform-specific utilities.
1513 plat="$(get_tf_opt PLAT)"
1514 plat_utils="$ci_root/${plat}_utils.sh"
1515 else
1516 # Source platform-specific utilities by
1517 # using plat_utils name.
1518 plat_utils="$ci_root/${plat_utils}.sh"
1519 fi
1520
Fathi Boudra422bf772019-12-02 11:10:16 +02001521 if [ -f "$plat_utils" ]; then
1522 source "$plat_utils"
1523 fi
1524
Chris Kaye5a486b2023-08-04 11:50:31 +00001525 fvp_tsram_size="$(get_tf_opt FVP_TRUSTED_SRAM_SIZE)"
1526 fvp_tsram_size="${fvp_tsram_size:-256}"
1527
Harrison Mutaidc703402024-08-02 14:40:16 +00001528 poetry -C "$tf_root" install --without docs
Chris Kayd0837902021-11-17 10:17:52 +00001529
Fathi Boudra422bf772019-12-02 11:10:16 +02001530 archive="$build_archive"
1531 tf_build_root="$tf_root/build"
1532
1533 echo "Building Trusted Firmware ($mode) ..." |& log_separator
1534
1535 # Call pre-build hook
1536 call_hook pre_tf_build
1537
1538 build_tf
1539
1540 # Call post-build hook
1541 call_hook post_tf_build
1542
1543 # Pre-archive hook
1544 call_hook pre_tf_archive
1545
1546 from="$tf_build_root" to="$archive" collect_build_artefacts
1547
1548 # Post-archive hook
1549 call_hook post_tf_archive
1550
1551 call_hook fetch_tf_resource
1552 call_hook post_fetch_tf_resource
1553
Chris Kay4e8aaf12022-09-01 15:21:55 +01001554 # Generate LAVA job files if necessary
1555 call_hook generate_lava_job_template
1556 call_hook generate_lava_job
1557
Fathi Boudra422bf772019-12-02 11:10:16 +02001558 # Clear any local changes made by applied patches
1559 undo_tf_patches
1560
1561 echo "##########"
1562 )
1563 fi
1564
1565 echo
1566 echo
1567done
1568
1569call_hook pre_package
1570
1571call_hook post_package
1572
1573if upon "$jenkins_run" && upon "$artefacts_receiver" && [ -d "artefacts" ]; then
Zelalem219df412020-05-17 19:21:20 -05001574 source "$CI_ROOT/script/send_artefacts.sh" "artefacts"
Fathi Boudra422bf772019-12-02 11:10:16 +02001575fi
1576
1577echo
1578echo "Done"