blob: 9b8e0004f056d47290cdaca0e370844e685abc15 [file] [log] [blame]
Leonardo Sandoval9dfdd1b2020-08-06 17:08:11 -05001#!/usr/bin/env bash
Fathi Boudra422bf772019-12-02 11:10:16 +02002#
Leonardo Sandoval579c7372020-10-23 15:23:32 -05003# Copyright (c) 2019-2020 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}"
26
27scp_tf_tools_root="$scp_tools_root/scp_tf_tools"
Fathi Boudra422bf772019-12-02 11:10:16 +020028
29# Refspecs
30tf_refspec="$TF_REFSPEC"
31tftf_refspec="$TFTF_REFSPEC"
32scp_refspec="$SCP_REFSPEC"
Zelalem219df412020-05-17 19:21:20 -050033scp_tools_commit="${SCP_TOOLS_COMMIT:-master}"
Fathi Boudra422bf772019-12-02 11:10:16 +020034
35test_config="${TEST_CONFIG:?}"
36test_group="${TEST_GROUP:?}"
37build_configs="${BUILD_CONFIG:?}"
38run_config="${RUN_CONFIG:?}"
Zelalem219df412020-05-17 19:21:20 -050039cc_config="${CC_ENABLE:-}"
Fathi Boudra422bf772019-12-02 11:10:16 +020040
41archive="$artefacts"
42build_log="$artefacts/build.log"
43fiptool="$tf_root/tools/fiptool/fiptool"
44cert_create="$tf_root/tools/cert_create/cert_create"
45
46# Validate $bin_mode
47case "$bin_mode" in
48 "" | debug | release)
49 ;;
50 *)
51 die "Invalid value for bin_mode: $bin_mode"
52 ;;
53esac
54
55# File to save any environem
56hook_env_file="$(mktempfile)"
57
58# Check if a config is valid
59config_valid() {
60 local config="${1?}"
61 if [ -z "$config" ] || [ "$(basename "$config")" = "nil" ]; then
62 return 1
63 fi
64
65 return 0
66}
67
68# Echo from a build wrapper. Print to descriptor 3 that's opened by the build
69# function.
70echo_w() {
71 echo $echo_flags "$@" >&3
72}
73
74# Print a separator to the log file. Intended to be used at the tail end of a pipe
75log_separator() {
76 {
77 echo
78 echo "----------"
79 } >> "$build_log"
80
81 tee -a "$build_log"
82
83 {
84 echo "----------"
85 echo
86 } >> "$build_log"
87}
88
89# Call function $1 if it's defined
90call_func() {
91 if type "${1:?}" &>/dev/null; then
92 echo
93 echo "> ${2:?}:$1()"
94 eval "$1"
95 echo "< $2:$1()"
96 fi
97}
98
99# Call hook $1 in all chosen fragments if it's defined. Hooks are invoked from
100# within a subshell, so any variables set within a hook are lost. Should a
101# variable needs to be set from within a hook, the function 'set_hook_var'
102# should be used
103call_hook() {
104 local func="$1"
105 local config_fragment
106
107 [ -z "$func" ] && return 0
108
109 : >"$hook_env_file"
110
111 if [ "$run_config_candiates" ]; then
112 for config_fragment in $run_config_candiates; do
113 (
114 source "$ci_root/run_config/$config_fragment"
115 call_func "$func" "$config_fragment"
116 )
117 done
118 fi
119
120 # Also source test config file
121 (
122 unset "$func"
123 source "$test_config_file"
124 call_func "$func" "$(basename $test_config_file)"
125 )
126
127 # Have any variables set take effect
128 source "$hook_env_file"
129}
130
131# Set a variable from within a hook
132set_hook_var() {
133 echo "export $1=\"${2?}\"" >> "$hook_env_file"
134}
135
136# Append to an array from within a hook
137append_hook_var() {
138 echo "export $1+=\"${2?}\"" >> "$hook_env_file"
139}
140
141# Have the main build script source a file
142source_later() {
143 echo "source ${1?}" >> "$hook_env_file"
144}
145
146# Setup TF build wrapper function by pointing to a script containing a function
147# that will be called with the TF build commands.
148setup_tf_build_wrapper() {
149 source_later "$ci_root/script/${wrapper?}_wrapper.sh"
150 set_hook_var "tf_build_wrapper" "${wrapper}_wrapper"
151 echo "Setup $wrapper build wrapper."
152}
153
154# Collect .bin files for archiving
155collect_build_artefacts() {
156 if [ ! -d "${from:?}" ]; then
157 return
158 fi
159
Javier Almansa Sobrinof98dbd82020-09-30 19:29:27 +0100160 if ! find "$from" \( -name "*.bin" -o -name '*.elf' -o -name '*.dtb' -o -name '*.axf' \) -exec cp -t "${to:?}" '{}' +; then
Fathi Boudra422bf772019-12-02 11:10:16 +0200161 echo "You probably are running local CI on local repositories."
162 echo "Did you set 'dont_clean' but forgot to run 'distclean'?"
163 die
164 fi
165}
166
167# SCP and MCP binaries are named firmware.{bin,elf}, and are placed under
168# scp/mcp_ramfw and scp/mcp_romfw directories, so can't be collected by
169# collect_build_artefacts function.
170collect_scp_artefacts() {
171 to="${to:?}" \
172 find "$scp_root" \( -name "*.bin" -o -name '*.elf' \) -exec bash -c '
173 for file; do
174 ext="$(echo $file | awk -F. "{print \$NF}")"
175 case $file in
176 */scp_ramfw/*)
177 cp $file $to/scp_ram.$ext
178 ;;
179 */scp_romfw/*)
180 cp $file $to/scp_rom.$ext
181 ;;
182 */mcp_ramfw/*)
183 cp $file $to/mcp_ram.$ext
184 ;;
185 */mcp_romfw/*)
186 cp $file $to/mcp_rom.$ext
187 ;;
Zelalem219df412020-05-17 19:21:20 -0500188 */scp_romfw_bypass/*)
189 cp $file $to/scp_rom_bypass.$ext
190 ;;
Fathi Boudra422bf772019-12-02 11:10:16 +0200191 *)
192 echo "Unknown SCP binary: $file" >&2
193 ;;
194 esac
195 done
196 ' bash '{}' +
197}
198
Javier Almansa Sobrino412d3612020-05-22 17:53:12 +0100199# Map the UART ID used for expect with the UART descriptor and port
200# used by the FPGA automation tools.
201map_uart() {
202 local port="${port:?}"
203 local descriptor="${descriptor:?}"
204 local baudrate="${baudrate:?}"
205 local run_root="${archive:?}/run"
206
207 local uart_dir="$run_root/uart${uart:?}"
208 mkdir -p "$uart_dir"
209
210 echo "$port" > "$uart_dir/port"
211 echo "$descriptor" > "$uart_dir/descriptor"
212 echo "$baudrate" > "$uart_dir/baudrate"
213
214 echo "UART${uart} mapped to port ${port} with descriptor ${descriptor} and baudrate ${baudrate}"
215}
216
Fathi Boudra422bf772019-12-02 11:10:16 +0200217# Arrange environment varibles to be set when expect scripts are launched
218set_expect_variable() {
219 local var="${1:?}"
220 local val="${2?}"
221
222 local run_root="${archive:?}/run"
223 local uart_dir="$run_root/uart${uart:?}"
224 mkdir -p "$uart_dir"
225
226 env_file="$uart_dir/env" quote="1" emit_env "$var" "$val"
227 echo "UART$uart: env has $@"
228}
229
230# Place the binary package a pointer to expect script, and its parameters
231track_expect() {
232 local file="${file:?}"
233 local timeout="${timeout-600}"
234 local run_root="${archive:?}/run"
235
236 local uart_dir="$run_root/uart${uart:?}"
237 mkdir -p "$uart_dir"
238
239 echo "$file" > "$uart_dir/expect"
240 echo "$timeout" > "$uart_dir/timeout"
241
242 echo "UART$uart to be tracked with $file; timeout ${timeout}s"
243
244 # The run script assumes UART0 to be primary. If we're asked to set any
245 # other UART to be primary, set a run environment variable to signal
246 # that to the run script
247 if upon "$set_primary"; then
248 echo "Primary UART set to UART$uart."
249 set_run_env "primary_uart" "$uart"
250 fi
251}
252
253# Extract a FIP in $1 using fiptool
254extract_fip() {
255 local fip="$1"
256
257 if is_url "$1"; then
258 url="$1" fetch_file
259 fip="$(basename "$1")"
260 fi
261
262 "$fiptool" unpack "$fip"
263 echo "Extracted FIP: $fip"
264}
265
266# Report build failure by printing a the tail end of build log. Archive the
267# build log for later inspection
268fail_build() {
269 local log_path
270
271 if upon "$jenkins_run"; then
272 log_path="$BUILD_URL/artifact/artefacts/build.log"
273 else
274 log_path="$build_log"
275 fi
276
277 echo
Leonardo Sandovalae97eda2020-11-12 10:07:03 -0600278 echo "Build failed! Full build log below:"
Fathi Boudra422bf772019-12-02 11:10:16 +0200279 echo "[...]"
280 echo
Leonardo Sandovalae97eda2020-11-12 10:07:03 -0600281 cat "$build_log"
Fathi Boudra422bf772019-12-02 11:10:16 +0200282 echo
283 echo "See $log_path for full output"
284 echo
285 cp -t "$archive" "$build_log"
286 exit 1;
287}
288
289# Build a FIP with supplied arguments
290build_fip() {
291 (
292 echo "Building FIP with arguments: $@"
293 local tf_env="$workspace/tf.env"
294
295 if [ -f "$tf_env" ]; then
296 set -a
297 source "$tf_env"
298 set +a
299 fi
300
301 make -C "$tf_root" $(cat "$tf_config_file") DEBUG="$DEBUG" V=1 "$@" \
302 ${fip_targets:-fip} &>>"$build_log" || fail_build
303 )
304}
305
306fip_update() {
307 # Before the update process, check if the given image is supported by
308 # the fiptool. It's assumed that both fiptool and cert_create move in
309 # tandem, and therfore, if one has support, the other has it too.
310 if ! "$fiptool" update 2>&1 | grep -qe "\s\+--${bin_name:?}"; then
311 return 1
312 fi
313
314 if not_upon "$(get_tf_opt TRUSTED_BOARD_BOOT)"; then
315 echo "Updating FIP image: $bin_name"
316 # Update HW config. Without TBBR, it's only a matter of using
317 # the update sub-command of fiptool
318 "$fiptool" update "--$bin_name" "${src:-}" \
319 "$archive/fip.bin"
320 else
321 echo "Updating FIP image (TBBR): $bin_name"
322 # With TBBR, we need to unpack, re-create certificates, and then
323 # recreate the FIP.
324 local fip_dir="$(mktempdir)"
325 local bin common_args stem
326 local rot_key="$(get_tf_opt ROT_KEY)"
327
328 rot_key="${rot_key:?}"
329 if ! is_abs "$rot_key"; then
330 rot_key="$tf_root/$rot_key"
331 fi
332
333 # Arguments only for cert_create
334 local cert_args="-n"
335 cert_args+=" --tfw-nvctr ${nvctr:-31}"
336 cert_args+=" --ntfw-nvctr ${nvctr:-223}"
337 cert_args+=" --key-alg ${KEY_ALG:-rsa}"
338 cert_args+=" --rot-key $rot_key"
339
340 local dyn_config_opts=(
Zelalem1af7a7b2020-08-04 17:34:32 -0500341 "fw-config"
Fathi Boudra422bf772019-12-02 11:10:16 +0200342 "hw-config"
343 "tb-fw-config"
344 "nt-fw-config"
345 "soc-fw-config"
346 "tos-fw-config"
347 )
348
349 # Binaries without key certificates
350 declare -A has_no_key_cert
351 for bin in "tb-fw" "${dyn_config_opts[@]}"; do
352 has_no_key_cert["$bin"]="1"
353 done
354
355 # Binaries without certificates
356 declare -A has_no_cert
357 for bin in "hw-config" "${dyn_config_opts[@]}"; do
358 has_no_cert["$bin"]="1"
359 done
360
361 pushd "$fip_dir"
362
363 # Unpack FIP
364 "$fiptool" unpack "$archive/fip.bin" &>>"$build_log"
365
366 # Remove all existing certificates
367 rm -f *-cert.bin
368
369 # Copy the binary to be updated
370 cp -f "$src" "${bin_name}.bin"
371
372 # FIP unpack dumps binaries with the same name as the option
373 # used to pack it; likewise for certificates. Reverse-engineer
374 # the command line from the binary output.
375 common_args="--trusted-key-cert trusted_key.crt"
376 for bin in *.bin; do
377 stem="${bin%%.bin}"
378 common_args+=" --$stem $bin"
379 if not_upon "${has_no_cert[$stem]}"; then
380 common_args+=" --$stem-cert $stem.crt"
381 fi
382 if not_upon "${has_no_key_cert[$stem]}"; then
383 common_args+=" --$stem-key-cert $stem-key.crt"
384 fi
385 done
386
387 # Create certificates
388 "$cert_create" $cert_args $common_args &>>"$build_log"
389
390 # Recreate and archive FIP
391 "$fiptool" create $common_args "fip.bin" &>>"$build_log"
392 archive_file "fip.bin"
393
394 popd
395 fi
396}
397
398# Update hw-config in FIP, and remove the original DTB afterwards.
399update_fip_hw_config() {
400 # The DTB needs to be loaded by the model (and not updated in the FIP)
401 # in configs where BL2 isn't present
402 case "1" in
403 "$(get_tf_opt RESET_TO_BL31)" | \
404 "$(get_tf_opt RESET_TO_SP_MIN)" | \
405 "$(get_tf_opt BL2_AT_EL3)")
406 return 0;;
407 esac
408
409 if bin_name="hw-config" src="$archive/dtb.bin" fip_update; then
410 # Remove the DTB so that model won't load it
411 rm -f "$archive/dtb.bin"
412 fi
413}
414
415get_scp_opt() {
416 (
417 name="${1:?}"
418 if config_valid "$scp_config_file"; then
419 source "$scp_config_file"
420 echo "${!name}"
421 fi
422 )
423}
424
425get_tftf_opt() {
426 (
427 name="${1:?}"
428 if config_valid "$tftf_config_file"; then
429 source "$tftf_config_file"
430 echo "${!name}"
431 fi
432 )
433}
434
435get_tf_opt() {
436 (
437 name="${1:?}"
438 if config_valid "$tf_config_file"; then
439 source "$tf_config_file"
440 echo "${!name}"
441 fi
442 )
443}
444
445build_tf() {
446 (
447 env_file="$workspace/tf.env"
448 config_file="${tf_build_config:-$tf_config_file}"
449
450 # Build fiptool and all targets by default
451 build_targets="${tf_build_targets:-fiptool all}"
452
453 source "$config_file"
454
455 # If it is a TBBR build, extract the MBED TLS library from archive
456 if [ "$(get_tf_opt TRUSTED_BOARD_BOOT)" = 1 ]; then
457 mbedtls_dir="$workspace/mbedtls"
458 if [ ! -d "$mbedtls_dir" ]; then
459 mbedtls_ar="$workspace/mbedtls.tar.gz"
460
461 url="$mbedtls_archive" saveas="$mbedtls_ar" fetch_file
462 mkdir "$mbedtls_dir"
Leonardo Sandovalec9e16c2020-09-09 14:32:40 -0500463 extract_tarball $mbedtls_ar $mbedtls_dir --strip-components=1
Fathi Boudra422bf772019-12-02 11:10:16 +0200464 fi
465
466 emit_env "MBEDTLS_DIR" "$mbedtls_dir"
467 fi
468
469 if [ -f "$env_file" ]; then
470 set -a
471 source "$env_file"
472 set +a
473 fi
474
475 cd "$tf_root"
476
477 # Always distclean when running on Jenkins. Skip distclean when running
478 # locally and explicitly requested.
479 if upon "$jenkins_run" || not_upon "$dont_clean"; then
480 make distclean &>>"$build_log" || fail_build
481 fi
482
483 # Log build command line. It is left unfolded on purpose to assist
484 # copying to clipboard.
485 cat <<EOF | log_separator >/dev/null
486
487Build command line:
488 $tf_build_wrapper make $make_j_opts $(cat "$config_file" | tr '\n' ' ') DEBUG=$DEBUG V=1 $build_targets
489
490EOF
491
Javier Almansa Sobrinoe8363182020-11-10 16:40:53 +0000492 if not_upon "$local_ci"; then
493 connect_debugger=0
494 fi
495
Fathi Boudra422bf772019-12-02 11:10:16 +0200496 # Build TF. Since build output is being directed to the build log, have
497 # descriptor 3 point to the current terminal for build wrappers to vent.
498 $tf_build_wrapper make $make_j_opts $(cat "$config_file") \
Javier Almansa Sobrinoe8363182020-11-10 16:40:53 +0000499 DEBUG="$DEBUG" V=1 SPIN_ON_BL1_EXIT="$connect_debugger" \
Fathi Boudra422bf772019-12-02 11:10:16 +0200500 $build_targets 3>&1 &>>"$build_log" || fail_build
501 )
502}
503
504build_tftf() {
505 (
506 config_file="${tftf_build_config:-$tftf_config_file}"
507
508 # Build tftf target by default
509 build_targets="${tftf_build_targets:-all}"
510
511 source "$config_file"
512
513 cd "$tftf_root"
514
515 # Always distclean when running on Jenkins. Skip distclean when running
516 # locally and explicitly requested.
517 if upon "$jenkins_run" || not_upon "$dont_clean"; then
518 make distclean &>>"$build_log" || fail_build
519 fi
520
521 # TFTF build system cannot reliably deal with -j option, so we avoid
522 # using that.
523
524 # Log build command line
525 cat <<EOF | log_separator >/dev/null
526
527Build command line:
528 make $(cat "$config_file" | tr '\n' ' ') DEBUG=$DEBUG V=1 $build_targets
529
530EOF
531
532 make $(cat "$config_file") DEBUG="$DEBUG" V=1 \
533 $build_targets &>>"$build_log" || fail_build
534 )
535}
536
537build_scp() {
538 (
539 config_file="${scp_build_config:-$scp_config_file}"
540
541 source "$config_file"
542
543 cd "$scp_root"
544
545 # Always distclean when running on Jenkins. Skip distclean when running
546 # locally and explicitly requested.
547 if upon "$jenkins_run" || not_upon "$dont_clean"; then
548 make clean &>>"$build_log" || fail_build
549 fi
550
551 # Log build command line. It is left unfolded on purpose to assist
552 # copying to clipboard.
553 cat <<EOF | log_separator >/dev/null
554
555SCP build command line:
556 make $(cat "$config_file" | tr '\n' ' ') MODE=$mode V=1
557
558EOF
559
560 # Build SCP
561 make $(cat "$config_file") MODE="$mode" V=1 &>>"$build_log" \
562 || fail_build
563 )
564}
565
Zelalem219df412020-05-17 19:21:20 -0500566clone_scp_tools() {
567
568 if [ ! -d "$scp_tools_root" ]; then
569 echo "Cloning SCP-tools ... $scp_tools_commit" |& log_separator
570
571 clone_url="${SCP_TOOLS_CHECKOUT_LOC:-$scp_tools_src_repo_url}" \
572 where="$scp_tools_root" \
573 refspec="${scp_tools_commit}"
574 clone_repo &>>"$build_log"
575 else
576 echo "Already cloned SCP-tools ..." |& log_separator
577 fi
578
579 show_head "$scp_tools_root"
580
581 cd "$scp_tools_root"
582
583 echo "Updating submodules"
584
585 git submodule init
586
587 git submodule update
588
589 cd "scmi"
590
591 git show --quiet --no-color | sed 's/^/ > /g'
592}
593
594clone_tf_for_scp_tools() {
595 scp_tools_arm_tf="$scp_tools_root/arm-tf"
596
597 if [ ! -d "$scp_tools_arm_tf" ]; then
598 echo "Cloning TF-4-SCP-tools ..." |& log_separator
599
600 clone_url="$tf_for_scp_tools_src_repo_url"
601 where="$scp_tools_arm_tf"
602
603 git clone "$clone_url" "$where"
604
605 cd "$scp_tools_arm_tf"
606
607 git checkout --track origin/dev/pedro/juno
608
609 git show --quiet --no-color | sed 's/^/ > /g'
610
611 else
612 echo "Already cloned TF-4-SCP-tools ..." |& log_separator
613 fi
614}
615
616build_scmi_lib_scp_tools() {
617 (
618 cd "$scp_tools_root"
619
620 cd "scmi"
621
622 scp_tools_arm_tf="$scp_tools_root/arm-tf"
623
Leonardo Sandovalfeae3a22020-11-17 16:53:59 -0600624 cross_compile="$(set_cross_compile_gcc_linaro_toolchain)"
Zelalem219df412020-05-17 19:21:20 -0500625
626 std_libs="-I$scp_tools_arm_tf/include/common"
627 std_libs="$std_libs -I$scp_tools_arm_tf/include/common/tbbr"
628 std_libs="$std_libs -I$scp_tools_arm_tf/include/drivers/arm"
629 std_libs="$std_libs -I$scp_tools_arm_tf/include/lib"
630 std_libs="$std_libs -I$scp_tools_arm_tf/include/lib/aarch64"
631 std_libs="$std_libs -I$scp_tools_arm_tf/include/lib/stdlib"
632 std_libs="$std_libs -I$scp_tools_arm_tf/include/lib/stdlib/sys"
633 std_libs="$std_libs -I$scp_tools_arm_tf/include/lib/xlat_tables"
634 std_libs="$std_libs -I$scp_tools_arm_tf/include/plat/common"
635 std_libs="$std_libs -I$scp_tools_arm_tf/include/plat/arm/common"
636 std_libs="$std_libs -I$scp_tools_arm_tf/include/plat/arm/css/common"
637 std_libs="$std_libs -I$scp_tools_arm_tf/include/plat/arm/board/common"
638 std_libs="$std_libs -I$scp_tools_arm_tf/include/plat/arm/soc/common"
639 std_libs="$std_libs -I$scp_tools_arm_tf/plat/arm/board/juno/include"
640
641 cflags="-Og -g"
642 cflags="$cflags -mgeneral-regs-only"
643 cflags="$cflags -mstrict-align"
644 cflags="$cflags -nostdinc"
645 cflags="$cflags -fno-inline"
646 cflags="$cflags -ffreestanding"
647 cflags="$cflags -ffunction-sections"
648 cflags="$cflags -fdata-sections"
649 cflags="$cflags -DAARCH64"
650 cflags="$cflags -DPRId32=\"ld\""
651
652 cflags="$cflags $std_libs"
653
654 protocols="power,system_power,performance,sensor"
655
656 echo "Building SCMI library (SCP-tools) ..."
657
658 make "CROSS_COMPILE=$cross_compile" \
659 "CFLAGS=$cflags" \
660 "PROTOCOLS=$protocols" \
661 "clean" \
662 "all"
663 )
664}
665
666build_tf_for_scp_tools() {
667
668 cd "$scp_tools_root/arm-tf"
669
Leonardo Sandovalfeae3a22020-11-17 16:53:59 -0600670 cross_compile="$(set_cross_compile_gcc_linaro_toolchain)"
Zelalem219df412020-05-17 19:21:20 -0500671
672 if [ "$1" = "release" ]; then
673 echo "Build TF-4-SCP-Tools rls..."
674 else
675 echo "Build TF-4-SCP-Tools dbg..."
676
677 make realclean
678
679 make "BM_TEST=scmi" \
680 "ARM_BOARD_OPTIMISE_MEM=1" \
681 "BM_CSS=juno" \
682 "CSS_USE_SCMI_SDS_DRIVER=1" \
683 "PLAT=juno" \
684 "DEBUG=1" \
685 "PLATFORM=juno" \
686 "CROSS_COMPILE=$cross_compile" \
687 "BM_WORKSPACE=$scp_tools_root/baremetal"
688
689 archive_file "build/juno/debug/bl1.bin"
690
691 archive_file "build/juno/debug/bl2.bin"
692
693 archive_file "build/juno/debug/bl31.bin"
694 fi
695}
696
697build_fip_for_scp_tools() {
698
699 cd "$scp_tools_root/arm-tf"
700
Leonardo Sandovalfeae3a22020-11-17 16:53:59 -0600701 cross_compile="$(set_cross_compile_gcc_linaro_toolchain)"
Zelalem219df412020-05-17 19:21:20 -0500702
703 if [ ! -d "$scp_root/build/product/juno/scp_ramfw/debug" ]; then
704 make fiptool
705 echo "Make FIP 4 SCP-Tools rls..."
706
707 else
708 make fiptool
709 echo "Make FIP 4 SCP-Tools dbg..."
710
711 make "PLAT=juno" \
712 "all" \
713 "fip" \
714 "DEBUG=1" \
715 "CROSS_COMPILE=$cross_compile" \
716 "BL31=$scp_tools_root/arm-tf/build/juno/debug/bl31.bin" \
717 "BL33=$scp_tools_root/baremetal/dummy_bl33" \
718 "SCP_BL2=$scp_root/build/product/juno/scp_ramfw/debug/bin/firmware.bin"
719
720 archive_file "$scp_tools_root/arm-tf/build/juno/debug/fip.bin"
721 fi
722}
723
724build_cc() {
725# Building code coverage plugin
726 ARM_DIR=/arm
727 pvlibversion=$(/arm/devsys-tools/abs/detag "SysGen:PVModelLib:$model_version::trunk")
728 PVLIB_HOME=$warehouse/SysGen/PVModelLib/$model_version/${pvlibversion}/external
729 if [ -n "$(find "$ARM_DIR" -maxdepth 0 -type d -empty 2>/dev/null)" ]; then
730 echo "Error: Arm warehouse not mounted. Please mount the Arm warehouse to your /arm local folder"
731 exit -1
732 fi # Error if arm warehouse not found
733 cd "$ccpathspec/scripts/tools/code_coverage/fastmodel_baremetal/bmcov"
734
735 make -C model-plugin PVLIB_HOME=$PVLIB_HOME &>>"$build_log"
736}
737
738
Fathi Boudra422bf772019-12-02 11:10:16 +0200739# Set metadata for the whole package so that it can be used by both Jenkins and
740# shell
741set_package_var() {
742 env_file="$artefacts/env" emit_env "$@"
743}
744
745set_tf_build_targets() {
746 echo "Set build target to '${targets:?}'"
747 set_hook_var "tf_build_targets" "$targets"
748}
749
750set_tftf_build_targets() {
751 echo "Set build target to '${targets:?}'"
752 set_hook_var "tftf_build_targets" "$targets"
753}
754
755set_scp_build_targets() {
756 echo "Set build target to '${targets:?}'"
757 set_hook_var "scp_build_targets" "$targets"
758}
759
760# Look under $archive directory for known files such as blX images, kernel, DTB,
761# initrd etc. For each known file foo, if foo.bin exists, then set variable
762# foo_bin to the path of the file. Make the path relative to the workspace so as
763# to remove any @ characters, which Jenkins inserts for parallel runs. If the
764# file doesn't exist, unset its path.
765set_default_bin_paths() {
766 local image image_name image_path path
767 local archive="${archive:?}"
768 local set_vars
769 local var
770
771 pushd "$archive"
772
773 for file in *.bin; do
774 # Get a shell variable from the file's stem
775 var_name="${file%%.*}_bin"
776 var_name="$(echo "$var_name" | sed -r 's/[^[:alnum:]]/_/g')"
777
778 # Skip setting the variable if it's already
779 if [ "${!var_name}" ]; then
780 echo "Note: not setting $var_name; already set to ${!var_name}"
781 continue
782 else
783 set_vars+="$var_name "
784 fi
785
786 eval "$var_name=$file"
787 done
788
789 echo "Binary paths set for: "
790 {
791 for var in $set_vars; do
792 echo -n "\$$var "
793 done
794 } | fmt -80 | sed 's/^/ /'
795 echo
796
797 popd
798}
799
800gen_model_params() {
801 local model_param_file="$archive/model_params"
Javier Almansa Sobrinoe8363182020-11-10 16:40:53 +0000802 [ "$connect_debugger" ] && [ "$connect_debugger" -eq 1 ] && wait_debugger=1
Fathi Boudra422bf772019-12-02 11:10:16 +0200803
804 set_default_bin_paths
805 echo "Generating model parameter for $model..."
806 source "$ci_root/model/${model:?}.sh"
807 archive_file "$model_param_file"
808}
809
810set_model_path() {
811 set_run_env "model_path" "${1:?}"
812}
813
Zelalem1af7a7b2020-08-04 17:34:32 -0500814set_model_env() {
815 local var="${1:?}"
816 local val="${2?}"
817 local run_root="${archive:?}/run"
818
819 mkdir -p "$run_root"
820 echo "export $var=$val" >> "$run_root/model_env"
821}
Fathi Boudra422bf772019-12-02 11:10:16 +0200822set_run_env() {
823 local var="${1:?}"
824 local val="${2?}"
825 local run_root="${archive:?}/run"
826
827 mkdir -p "$run_root"
828 env_file="$run_root/env" quote="1" emit_env "$var" "$val"
829}
830
831show_head() {
832 # Display HEAD descripton
833 pushd "$1"
834 git show --quiet --no-color | sed 's/^/ > /g'
835 echo
836 popd
837}
838
839# Choose debug binaries to run; by default, release binaries are chosen to run
840use_debug_bins() {
841 local run_root="${archive:?}/run"
842
843 echo "Choosing debug binaries for execution"
844 set_package_var "BIN_MODE" "debug"
845}
846
847assert_can_git_clone() {
848 local name="${1:?}"
849 local dir="${!name}"
850
851 # If it doesn't exist, it can be cloned into
852 if [ ! -e "$dir" ]; then
853 return 0
854 fi
855
856 # If it's a directory, it must be a Git clone already
857 if [ -d "$dir" ] && [ -d "$dir/.git" ]; then
858 # No need to clone again
859 echo "Using existing git clone for $name: $dir"
860 return 1
861 fi
862
863 die "Path $dir exists but is not a git clone"
864}
865
866clone_repo() {
867 if ! is_url "${clone_url?}"; then
868 # For --depth to take effect on local paths, it needs to use the
869 # file:// scheme.
870 clone_url="file://$clone_url"
871 fi
872
873 git clone -q --depth 1 "$clone_url" "${where?}"
874 if [ "$refspec" ]; then
875 pushd "$where"
876 git fetch -q --depth 1 origin "$refspec"
877 git checkout -q FETCH_HEAD
878 popd
879 fi
880}
881
882build_unstable() {
883 echo "--BUILD UNSTABLE--" | tee -a "$build_log"
884}
885
886undo_patch_record() {
887 if [ ! -f "${patch_record:?}" ]; then
888 return
889 fi
890
891 # Undo patches in reverse
892 echo
893 for patch_name in $(tac "$patch_record"); do
894 echo "Undoing $patch_name..."
895 if ! git apply -R "$ci_root/patch/$patch_name"; then
896 if upon "$local_ci"; then
897 echo
898 echo "Your local directory may have been dirtied."
899 echo
900 fi
901 fail_build
902 fi
903 done
904
905 rm -f "$patch_record"
906}
907
908undo_local_patches() {
909 pushd "$tf_root"
910 patch_record="$tf_patch_record" undo_patch_record
911 popd
912
913 if [ -d "$tftf_root" ]; then
914 pushd "$tftf_root"
915 patch_record="$tftf_patch_record" undo_patch_record
916 popd
917 fi
918}
919
920undo_tftf_patches() {
921 pushd "$tftf_root"
922 patch_record="$tftf_patch_record" undo_patch_record
923 popd
924}
925
926undo_tf_patches() {
927 pushd "$tf_root"
928 patch_record="$tf_patch_record" undo_patch_record
929 popd
930}
931
932apply_patch() {
933 # If skip_patches is set, the developer has applied required patches
934 # manually. They probably want to keep them applied for debugging
935 # purposes too. This means we don't have to apply/revert them as part of
936 # build process.
937 if upon "$skip_patches"; then
938 echo "Skipped applying ${1:?}..."
939 return 0
940 else
941 echo "Applying ${1:?}..."
942 fi
943
944 if git apply < "$ci_root/patch/$1"; then
945 echo "$1" >> "${patch_record:?}"
946 else
947 if upon "$local_ci"; then
948 undo_local_patches
949 fi
950 fail_build
951 fi
952}
953
954apply_tftf_patch() {
955 pushd "$tftf_root"
956 patch_record="$tftf_patch_record" apply_patch "$1"
957 popd
958}
959
960apply_tf_patch() {
961 pushd "$tf_root"
962 patch_record="$tf_patch_record" apply_patch "$1"
963 popd
964}
965
966# Clear workspace for a local run
967if not_upon "$jenkins_run"; then
968 rm -rf "$workspace"
969
970 # Clear residue from previous runs
971 rm -rf "$archive"
972fi
973
974mkdir -p "$workspace"
975mkdir -p "$archive"
976set_package_var "TEST_CONFIG" "$test_config"
977
978{
979echo
980echo "CONFIGURATION: $test_group/$test_config"
981echo
982} |& log_separator
983
984tf_config="$(echo "$build_configs" | awk -F, '{print $1}')"
985tftf_config="$(echo "$build_configs" | awk -F, '{print $2}')"
986scp_config="$(echo "$build_configs" | awk -F, '{print $3}')"
Zelalem219df412020-05-17 19:21:20 -0500987scp_tools_config="$(echo "$build_configs" | awk -F, '{print $4}')"
Fathi Boudra422bf772019-12-02 11:10:16 +0200988
989test_config_file="$ci_root/group/$test_group/$test_config"
990
991tf_config_file="$ci_root/tf_config/$tf_config"
992tftf_config_file="$ci_root/tftf_config/$tftf_config"
993scp_config_file="$ci_root/scp_config/$scp_config"
Zelalem219df412020-05-17 19:21:20 -0500994scp_tools_config_file="$ci_root/scp_tools_config/$scp_tools_config"
Fathi Boudra422bf772019-12-02 11:10:16 +0200995
996# File that keeps track of applied patches
997tf_patch_record="$workspace/tf_patches"
998tftf_patch_record="$workspace/tftf_patches"
999
1000pushd "$workspace"
1001
1002if ! config_valid "$tf_config"; then
1003 tf_config=
1004else
1005 echo "Trusted Firmware config:"
1006 echo
1007 sort "$tf_config_file" | sed '/^\s*$/d;s/^/\t/'
1008 echo
1009fi
1010
1011if ! config_valid "$tftf_config"; then
1012 tftf_config=
1013else
1014 echo "Trusted Firmware TF config:"
1015 echo
1016 sort "$tftf_config_file" | sed '/^\s*$/d;s/^/\t/'
1017 echo
1018fi
1019
1020if ! config_valid "$scp_config"; then
1021 scp_config=
1022else
1023 echo "SCP firmware config:"
1024 echo
1025 sort "$scp_config_file" | sed '/^\s*$/d;s/^/\t/'
1026 echo
1027fi
1028
Zelalem219df412020-05-17 19:21:20 -05001029if ! config_valid "$scp_tools_config"; then
1030 scp_tools_config=
1031else
1032 echo "SCP Tools config:"
1033 echo
1034 sort "$scp_tools_config_file" | sed '/^\s*$/d;s/^/\t/'
1035 echo
1036fi
1037
Fathi Boudra422bf772019-12-02 11:10:16 +02001038if ! config_valid "$run_config"; then
1039 run_config=
1040fi
1041
1042if [ "$tf_config" ] && assert_can_git_clone "tf_root"; then
1043 # If the Trusted Firmware repository has already been checked out, use
1044 # that location. Otherwise, clone one ourselves.
1045 echo "Cloning Trusted Firmware..."
1046 clone_url="${TF_CHECKOUT_LOC:-$tf_src_repo_url}" where="$tf_root" \
1047 refspec="$TF_REFSPEC" clone_repo &>>"$build_log"
1048 show_head "$tf_root"
1049fi
1050
1051if [ "$tftf_config" ] && assert_can_git_clone "tftf_root"; then
1052 # If the Trusted Firmware TF repository has already been checked out,
1053 # use that location. Otherwise, clone one ourselves.
1054 echo "Cloning Trusted Firmware TF..."
1055 clone_url="${TFTF_CHECKOUT_LOC:-$tftf_src_repo_url}" where="$tftf_root" \
1056 refspec="$TFTF_REFSPEC" clone_repo &>>"$build_log"
1057 show_head "$tftf_root"
1058fi
1059
1060if [ "$scp_config" ] && assert_can_git_clone "scp_root"; then
1061 # If the SCP firmware repository has already been checked out,
1062 # use that location. Otherwise, clone one ourselves.
1063 echo "Cloning SCP Firmware..."
1064 clone_url="${SCP_CHECKOUT_LOC:-$scp_src_repo_url}" where="$scp_root" \
1065 refspec="${SCP_REFSPEC-master-upstream}" clone_repo &>>"$build_log"
1066
1067 pushd "$scp_root"
1068
1069 # Use filer submodule as a reference if it exists
1070 if [ -d "$SCP_CHECKOUT_LOC/cmsis" ]; then
1071 cmsis_reference="--reference $SCP_CHECKOUT_LOC/cmsis"
1072 fi
1073
1074 # If we don't have a reference yet, fall back to $cmsis_root if set, or
1075 # then to project filer if accessible.
1076 if [ -z "$cmsis_reference" ]; then
1077 cmsis_ref_repo="${cmsis_root:-$project_filer/ref-repos/cmsis}"
1078 if [ -d "$cmsis_ref_repo" ]; then
1079 cmsis_reference="--reference $cmsis_ref_repo"
1080 fi
1081 fi
1082
1083 git submodule -q update $cmsis_reference --init
1084
1085 popd
1086
1087 show_head "$scp_root"
1088fi
1089
Zelalem219df412020-05-17 19:21:20 -05001090if [ -n "$cc_config" ] ; then
1091 if [ "$cc_config" -eq 1 ] && assert_can_git_clone "cc_root"; then
1092 # Copy code coverage repository
1093 echo "Cloning Code Coverage..."
1094 git clone -q $cc_src_repo_url cc_plugin --depth 1 -b $cc_src_repo_tag > /dev/null
1095 show_head "$cc_root"
1096 fi
1097fi
1098
Fathi Boudra422bf772019-12-02 11:10:16 +02001099if [ "$run_config" ]; then
1100 # Get candidates for run config
1101 run_config_candiates="$("$ci_root/script/gen_run_config_candidates.py" \
1102 "$run_config")"
1103 if [ -z "$run_config_candiates" ]; then
1104 die "No run config candidates!"
1105 else
1106 echo
1107 echo "Chosen fragments:"
1108 echo
1109 echo "$run_config_candiates" | sed 's/^\|\n/\t/g'
1110 echo
1111 fi
1112fi
1113
1114call_hook "test_setup"
1115echo
1116
1117if upon "$local_ci"; then
1118 # For local runs, since each config is tried in sequence, it's
1119 # advantageous to run jobs in parallel
1120 if [ "$make_j" ]; then
1121 make_j_opts="-j $make_j"
1122 else
1123 n_cores="$(getconf _NPROCESSORS_ONLN)" 2>/dev/null || true
1124 if [ "$n_cores" ]; then
1125 make_j_opts="-j $n_cores"
1126 fi
1127 fi
1128fi
1129
1130modes="${bin_mode:-debug release}"
1131for mode in $modes; do
1132 # Build with a temporary archive
1133 build_archive="$archive/$mode"
1134 mkdir "$build_archive"
1135
1136 if [ "$mode" = "debug" ]; then
Zelalem219df412020-05-17 19:21:20 -05001137 export bin_mode="debug"
Fathi Boudra422bf772019-12-02 11:10:16 +02001138 DEBUG=1
1139 else
Zelalem219df412020-05-17 19:21:20 -05001140 export bin_mode="release"
Fathi Boudra422bf772019-12-02 11:10:16 +02001141 DEBUG=0
1142 fi
1143
1144 # Perform builds in a subshell so as not to pollute the current and
1145 # subsequent builds' environment
1146
Zelalem219df412020-05-17 19:21:20 -05001147 if config_valid "$cc_config"; then
1148 # Build code coverage plugin
1149 build_cc
1150 fi
1151
Fathi Boudra422bf772019-12-02 11:10:16 +02001152 # SCP build
1153 if config_valid "$scp_config"; then
1154 (
1155 echo "##########"
1156
1157 # Source platform-specific utilities
1158 plat="$(get_scp_opt PRODUCT)"
1159 plat_utils="$ci_root/${plat}_utils.sh"
1160 if [ -f "$plat_utils" ]; then
1161 source "$plat_utils"
1162 fi
1163
1164 archive="$build_archive"
1165 scp_build_root="$scp_root/build"
1166
1167 echo "Building SCP Firmware ($mode) ..." |& log_separator
1168
1169 build_scp
Fathi Boudra422bf772019-12-02 11:10:16 +02001170 to="$archive" collect_scp_artefacts
1171
1172 echo "##########"
1173 echo
1174 )
1175 fi
1176
Zelalem219df412020-05-17 19:21:20 -05001177 # SCP-tools build
1178 if config_valid "$scp_tools_config"; then
1179 (
1180 echo "##########"
1181
1182 archive="$build_archive"
1183 scp_tools_build_root="$scp_tools_root/build"
1184
1185 clone_scp_tools
1186
1187 echo "##########"
1188 echo
1189
1190 echo "##########"
1191 clone_tf_for_scp_tools
1192 echo "##########"
1193 echo
1194 )
1195 fi
1196
Fathi Boudra422bf772019-12-02 11:10:16 +02001197 # TFTF build
1198 if config_valid "$tftf_config"; then
1199 (
1200 echo "##########"
1201
Manish V Badarkhe3bd3fea2020-11-08 15:17:00 +00001202 plat_utils="$(get_tf_opt PLAT_UTILS)"
1203 if [ -z ${plat_utils} ]; then
1204 # Source platform-specific utilities.
1205 plat="$(get_tftf_opt PLAT)"
1206 plat_utils="$ci_root/${plat}_utils.sh"
1207 else
1208 # Source platform-specific utilities by
1209 # using plat_utils name.
1210 plat_utils="$ci_root/${plat_utils}.sh"
1211 fi
1212
Fathi Boudra422bf772019-12-02 11:10:16 +02001213 if [ -f "$plat_utils" ]; then
1214 source "$plat_utils"
1215 fi
1216
1217 archive="$build_archive"
1218 tftf_build_root="$tftf_root/build"
1219
1220 echo "Building Trusted Firmware TF ($mode) ..." |& log_separator
1221
1222 # Call pre-build hook
1223 call_hook pre_tftf_build
1224
1225 build_tftf
1226
1227 from="$tftf_build_root" to="$archive" collect_build_artefacts
1228
1229 # Clear any local changes made by applied patches
1230 undo_tftf_patches
1231
1232 echo "##########"
1233 echo
1234 )
1235 fi
1236
1237 # TF build
1238 if config_valid "$tf_config"; then
1239 (
1240 echo "##########"
1241
Manish V Badarkhe3bd3fea2020-11-08 15:17:00 +00001242 plat_utils="$(get_tf_opt PLAT_UTILS)"
1243 if [ -z ${plat_utils} ]; then
1244 # Source platform-specific utilities.
1245 plat="$(get_tf_opt PLAT)"
1246 plat_utils="$ci_root/${plat}_utils.sh"
1247 else
1248 # Source platform-specific utilities by
1249 # using plat_utils name.
1250 plat_utils="$ci_root/${plat_utils}.sh"
1251 fi
1252
Fathi Boudra422bf772019-12-02 11:10:16 +02001253 if [ -f "$plat_utils" ]; then
1254 source "$plat_utils"
1255 fi
1256
1257 archive="$build_archive"
1258 tf_build_root="$tf_root/build"
1259
1260 echo "Building Trusted Firmware ($mode) ..." |& log_separator
1261
1262 # Call pre-build hook
1263 call_hook pre_tf_build
1264
1265 build_tf
1266
1267 # Call post-build hook
1268 call_hook post_tf_build
1269
1270 # Pre-archive hook
1271 call_hook pre_tf_archive
1272
1273 from="$tf_build_root" to="$archive" collect_build_artefacts
1274
1275 # Post-archive hook
1276 call_hook post_tf_archive
1277
1278 call_hook fetch_tf_resource
1279 call_hook post_fetch_tf_resource
1280
1281 # Clear any local changes made by applied patches
1282 undo_tf_patches
1283
1284 echo "##########"
1285 )
1286 fi
1287
1288 echo
1289 echo
1290done
1291
1292call_hook pre_package
1293
1294call_hook post_package
1295
1296if upon "$jenkins_run" && upon "$artefacts_receiver" && [ -d "artefacts" ]; then
Zelalem219df412020-05-17 19:21:20 -05001297 source "$CI_ROOT/script/send_artefacts.sh" "artefacts"
Fathi Boudra422bf772019-12-02 11:10:16 +02001298fi
1299
1300echo
1301echo "Done"