fix: track primary UART instead of using timeouts

Signed-off-by: Chris Kay <chris.kay@arm.com>
Change-Id: I0c3e265020e757f41a4dba6dac242ea5f2139b40
diff --git a/expect-lava/crash_rng_trap_unhandled_exception_at_el3.exp b/expect-lava/crash_rng_trap_unhandled_exception_at_el3.exp
new file mode 100644
index 0000000..5bff8ce
--- /dev/null
+++ b/expect-lava/crash_rng_trap_unhandled_exception_at_el3.exp
@@ -0,0 +1,87 @@
+#
+# Copyright (c) 2022, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+expect_string+=('i;Unhandled Exception in EL3.')
+expect_string+=('i;x30')
+expect_string+=('i;x0')
+expect_string+=('i;x1')
+expect_string+=('i;x2')
+expect_string+=('i;x3')
+expect_string+=('i;x4')
+expect_string+=('i;x5')
+expect_string+=('i;x6')
+expect_string+=('i;x7')
+expect_string+=('i;x8')
+expect_string+=('i;x9')
+expect_string+=('i;x10')
+expect_string+=('i;x11')
+expect_string+=('i;x12')
+expect_string+=('i;x13')
+expect_string+=('i;x14')
+expect_string+=('i;x15')
+expect_string+=('i;x16')
+expect_string+=('i;x17')
+expect_string+=('i;x18')
+expect_string+=('i;x19')
+expect_string+=('i;x20')
+expect_string+=('i;x21')
+expect_string+=('i;x22')
+expect_string+=('i;x23')
+expect_string+=('i;x24')
+expect_string+=('i;x25')
+expect_string+=('i;x26')
+expect_string+=('i;x27')
+expect_string+=('i;x28')
+expect_string+=('i;x29')
+expect_string+=('i;scr_el3')
+expect_string+=('i;sctlr_el3')
+expect_string+=('i;cptr_el3')
+expect_string+=('i;tcr_el3')
+expect_string+=('i;daif')
+expect_string+=('i;mair_el3')
+expect_string+=('i;spsr_el3')
+expect_string+=('i;elr_el3')
+expect_string+=('i;ttbr0_el3')
+expect_string+=('i;esr_el3')
+expect_string+=('i;far_el3')
+expect_string+=('i;spsr_el1')
+expect_string+=('i;elr_el1')
+expect_string+=('i;spsr_abt')
+expect_string+=('i;spsr_und')
+expect_string+=('i;spsr_irq')
+expect_string+=('i;spsr_fiq')
+expect_string+=('i;sctlr_el1')
+expect_string+=('i;actlr_el1')
+expect_string+=('i;cpacr_el1')
+expect_string+=('i;csselr_el1')
+expect_string+=('i;sp_el1')
+expect_string+=('i;esr_el1')
+expect_string+=('i;ttbr0_el1')
+expect_string+=('i;ttbr1_el1')
+expect_string+=('i;mair_el1')
+expect_string+=('i;amair_el1')
+expect_string+=('i;tcr_el1')
+expect_string+=('i;tpidr_el1')
+expect_string+=('i;tpidr_el0')
+expect_string+=('i;tpidrro_el0')
+expect_string+=('i;par_el1')
+expect_string+=('i;mpidr_el1')
+expect_string+=('i;afsr0_el1')
+expect_string+=('i;afsr1_el1')
+expect_string+=('i;contextidr_el1')
+expect_string+=('i;vbar_el1')
+expect_string+=('i;cntp_ctl_el0')
+expect_string+=('i;cntp_cval_el0')
+expect_string+=('i;cntv_ctl_el0')
+expect_string+=('i;cntv_cval_el0')
+expect_string+=('i;cntkctl_el1')
+expect_string+=('i;sp_el0')
+expect_string+=('i;isr_el1')
+expect_string+=('i;dacr32_el2')
+expect_string+=('i;ifsr32_el2')
+expect_string+=('i;icc_hppir0_el1')
+expect_string+=('i;icc_hppir1_el1')
+expect_string+=('i;icc_ctlr_el3')
diff --git a/fvp_utils.sh b/fvp_utils.sh
index c3e601f..e2bc450 100644
--- a/fvp_utils.sh
+++ b/fvp_utils.sh
@@ -507,6 +507,69 @@
     # iterate over them.
     readarray -t boot_arguments < "${lava_model_params}"
 
+    # Source runtime environment variables now so that they are accessible from
+    # the LAVA job template.
+    local run_root="${archive}/run"
+    local run_env="${run_root}/env"
+
+    if [ -f "${run_env}" ]; then
+        source "${run_env}"
+    fi
+
+    # The following defaults are based on those used by `run_package.sh`!
+
+    local num_uarts="${num_uarts:-4}"
+
+    # The payload UART for most FVPs is the primary UART, and the primary UART
+    # for most FVPs is UART0, but there are some tests and platforms where that
+    # isn't the case.
+    local primary_uart="${primary_uart:-0}"
+    local payload_uart="${payload_uart:-${primary_uart}}"
+
+    # TODO: Introduce a mechanism for mapping terminal names to UART indices.
+    #
+    # In the on-premises CI, the scripts figure out the FVP terminal names by
+    # first booting up the FVP, running an AWK script over it (the "ports
+    # script") which populates a Bash array with the real terminal names for
+    # each UART index, and then killing the FVP.
+    #
+    # In LAVA, we're supposed to know the terminal names beforehand to populate
+    # the console string and feedback regular expressions, which means we need
+    # to effectively run this process in reverse.
+    #
+    # To avoid having to introduce a whole new scheme for mapping the UARTs to
+    # their FVP terminal names, we're instead going to run the ports script over
+    # a list of all of the terminal names we have ever known, then use that to
+    # update the template file with the proper terminal names.
+    declare -a ports
+
+    if [ "${ports_script}" = "" ]; then
+        for ((i=0; i<${num_uarts}; i++)); do
+            ports[$i]="terminal_${i}"
+        done
+    else
+        local ports_input=$(mktempfile)
+        local ports_output=$(mktempfile)
+
+        cat > "${ports_input}" <<-EOF
+			terminal_0
+			terminal_1
+			terminal_2
+			terminal_3
+			terminal_s0
+			terminal_s1
+			terminal_uart_aon
+			terminal_uart_ap
+			terminal_uart0
+			terminal_uart1_ap
+		EOF
+
+        awk -v "num_uarts=${num_uarts}" -f "${ports_script:?}" \
+            "${ports_input}" > "${ports_output}"
+
+        source "${ports_output}"
+    fi
+
     # Generate the LAVA job definition, minus the test expectations
     expand_template "${yaml_template_file}" > "${yaml_file}"
 
@@ -522,21 +585,15 @@
 }
 
 gen_fvp_yaml_expect() {
-
-    run_root="$archive/run"
-
     # Loop through all uarts expect files
     for expect_file in $(find $run_root -name expect); do
+        local uart_number=$(basename "$(dirname ${expect_file})")
 
-        # TODO: currently, only handle UART 0
-        case $expect_file in
-            *uart0* )
-                uart_number=uart0
-                ;;
-            *)
-                continue
-                ;;
-        esac
+        # Only handle the primary UART through LAVA. The remaining UARTs are
+        # validated after LAVA returns by the post-expect script.
+        if [ "${uart_number:?}" != "uart${primary_uart}" ]; then
+            continue
+        fi
 
         # Array containing "interactive" or "monitor" expect strings and populated during run config execution.
         # Interactive expect scripts are converted into LAVA Interactive Test Actions (see
diff --git a/script/lava-templates/fvp-linux.yaml b/script/lava-templates/fvp-linux.yaml
index a0acc6e..2203d1b 100644
--- a/script/lava-templates/fvp-linux.yaml
+++ b/script/lava-templates/fvp-linux.yaml
@@ -62,11 +62,19 @@
       local: true
     image: ${model_dir}/${model_bin}
     version_string: ${version_string}
-    console_string: 'terminal_0: Listening for serial connection on port (?P<PORT>\d+)'
+    console_string: '${ports[${payload_uart:?}]:?}: Listening for serial connection on port (?P<PORT>\d+)'
     feedbacks:
-      - '(?P<NAME>terminal_1): Listening for serial connection on port (?P<PORT>\d+)'
-      - '(?P<NAME>terminal_2): Listening for serial connection on port (?P<PORT>\d+)'
-      - '(?P<NAME>terminal_3): Listening for serial connection on port (?P<PORT>\d+)'
+
+$(for port in "${ports[@]}"; do
+	if [ "${port}" = "${ports[${payload_uart}]}" ]; then
+		continue
+	fi
+
+	cat <<-YAML
+      - '(?P<NAME>${port}): Listening for serial connection on port (?P<PORT>\d+)'
+	YAML
+done)
+
     timeout:
       minutes: 30
     arguments:
diff --git a/script/lava-templates/fvp-tftf.yaml b/script/lava-templates/fvp-tftf.yaml
index bde3f60..8f41e9e 100644
--- a/script/lava-templates/fvp-tftf.yaml
+++ b/script/lava-templates/fvp-tftf.yaml
@@ -75,11 +75,19 @@
       local: true
     image: ${model_dir}/${model_bin}
     version_string: ${version_string}
-    console_string: 'terminal_0: Listening for serial connection on port (?P<PORT>\d+)'
+    console_string: '${ports[${payload_uart:?}]:?}: Listening for serial connection on port (?P<PORT>\d+)'
     feedbacks:
-      - '(?P<NAME>terminal_1): Listening for serial connection on port (?P<PORT>\d+)'
-      - '(?P<NAME>terminal_2): Listening for serial connection on port (?P<PORT>\d+)'
-      - '(?P<NAME>terminal_3): Listening for serial connection on port (?P<PORT>\d+)'
+
+$(for port in "${ports[@]}"; do
+	if [ "${port}" = "${ports[${payload_uart}]}" ]; then
+		continue
+	fi
+
+	cat <<-YAML
+      - '(?P<NAME>${port}): Listening for serial connection on port (?P<PORT>\d+)'
+	YAML
+done)
+
     arguments:
 
 $(for boot_argument in "${boot_arguments[@]:?}"; do