From: Ruslan Ruslichenko <[email protected]>

This patch adds functional tests for the new `arm-generic-fdt` machine type.
It introduces two new test suites:

1. test_arm_generic_fdt.py: Validates the firmware boot chain (TF-A and
   EDK2). It checks the console output for specific patterns indicating
   successful execution of BL1, BL2, BL31, and UEFI stages.

2. test_arm_generic_fdt_alpine.py: Validates a full OS boot by launching
   an Alpine Linux ISO and waiting for the welcome message.

To support these tests, two pre-compiled Device Tree Blob (DTB) files are
added to `tests/data`.

The tests reuse the existing firmware assets and Alpine ISO infrastructure
from the sbsa-ref tests.

Signed-off-by: Ruslan Ruslichenko <[email protected]>
---
 .../arm-generic-fdt/arm64-sbsa-guest.dtb      | Bin 0 -> 673 bytes
 .../aarch64/arm-generic-fdt/arm64-sbsa-hw.dtb | Bin 0 -> 5414 bytes
 tests/functional/aarch64/meson.build          |   2 +
 .../aarch64/test_arm_generic_fdt.py           | 114 ++++++++++++++++++
 .../aarch64/test_arm_generic_fdt_alpine.py    |  61 ++++++++++
 5 files changed, 177 insertions(+)
 create mode 100644 tests/data/dtb/aarch64/arm-generic-fdt/arm64-sbsa-guest.dtb
 create mode 100644 tests/data/dtb/aarch64/arm-generic-fdt/arm64-sbsa-hw.dtb
 create mode 100755 tests/functional/aarch64/test_arm_generic_fdt.py
 create mode 100755 tests/functional/aarch64/test_arm_generic_fdt_alpine.py

diff --git a/tests/data/dtb/aarch64/arm-generic-fdt/arm64-sbsa-guest.dtb 
b/tests/data/dtb/aarch64/arm-generic-fdt/arm64-sbsa-guest.dtb
new file mode 100644
index 
0000000000000000000000000000000000000000..5f2a1e9b2826eec45ed97e6dd704649a05d0af4c
GIT binary patch
literal 673
zcmZuuJx|0i40R8LjsXD+Gtw;#SBZ~>u>%r210zx{4c9=LRB?)cf5SiGkFYT#>@=y4
za+VVN*)R69@_F#{1u**nfNSzg@@I68=^W8v>j8@IA^dX}3GI;IO)>k7PbPKlJ=>_$
zyb&K#d~3ArUzfN-QF`@A85%4bhsws7-xk^i8PPE3l;S(a)gIquNmVr;U=mj7fSh1$
zyjOg4GfyjW=Rr%HA-g`3DVKL)?Q9um?L}~%Gj9Dhl*jr#VOEm)4-;HZaGP+RU!7Be
zjNkJnQ7<RRM$W~6ryQO;axS-XxIS{OwsW{|=CR*zg>1A{<%{yDoh@5!orix}@kH4L
u>UUL2WembX)U{WL2};*?BIuP-;ME#J<CUlpq$3VU(_^6ifKEOu`m|p^QBCmx

literal 0
HcmV?d00001

diff --git a/tests/data/dtb/aarch64/arm-generic-fdt/arm64-sbsa-hw.dtb 
b/tests/data/dtb/aarch64/arm-generic-fdt/arm64-sbsa-hw.dtb
new file mode 100644
index 
0000000000000000000000000000000000000000..0f12655f9c4b4f12556dd0c55c3bc552ff3f8a5e
GIT binary patch
literal 5414
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
E4{LL%!~g&Q

literal 0
HcmV?d00001

diff --git a/tests/functional/aarch64/meson.build 
b/tests/functional/aarch64/meson.build
index 49eca12058..3ec20f5bb2 100644
--- a/tests/functional/aarch64/meson.build
+++ b/tests/functional/aarch64/meson.build
@@ -41,6 +41,8 @@ tests_aarch64_system_thorough = [
   'sbsaref',
   'sbsaref_alpine',
   'sbsaref_freebsd',
+  'arm_generic_fdt',
+  'arm_generic_fdt_alpine',
   'smmu',
   'tcg_plugins',
   'tuxrun',
diff --git a/tests/functional/aarch64/test_arm_generic_fdt.py 
b/tests/functional/aarch64/test_arm_generic_fdt.py
new file mode 100755
index 0000000000..7b0d81196e
--- /dev/null
+++ b/tests/functional/aarch64/test_arm_generic_fdt.py
@@ -0,0 +1,114 @@
+#!/usr/bin/env python3
+#
+# Functional test that boots a kernel and checks the console
+#
+# Based on test_arm_generic_fdt.py
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from qemu_test import QemuSystemTest, Asset
+from qemu_test import wait_for_console_pattern
+from qemu_test import interrupt_interactive_console_until_pattern
+
+from pathlib import Path
+
+def fetch_firmware(test):
+    """
+    Flash volumes generated using:
+
+    Toolchain from Debian:
+    aarch64-linux-gnu-gcc (Debian 12.2.0-14) 12.2.0
+
+    Used components:
+
+    - Trusted Firmware         v2.12.0
+    - Tianocore EDK2           edk2-stable202411
+    - Tianocore EDK2-platforms 4b3530d
+
+    """
+
+    # Secure BootRom (TF-A code)
+    fs0_path = test.uncompress(Aarch64ArmGenericFdtMachine.ASSET_FLASH0,
+                                format="xz")
+
+    # Non-secure rom (UEFI and EFI variables)
+    fs1_path = test.uncompress(Aarch64ArmGenericFdtMachine.ASSET_FLASH1,
+                                format="xz")
+
+    for path in [fs0_path, fs1_path]:
+        with open(path, "ab+") as fd:
+            fd.truncate(256 << 20)  # Expand volumes to 256MiB
+
+    test.vm.add_args(
+        "-blockdev", f"driver=file,filename={fs0_path},node-name=pflash0",
+        "-blockdev", f"driver=file,filename={fs1_path},node-name=pflash1",
+    )
+
+
+class Aarch64ArmGenericFdtMachine(QemuSystemTest):
+    """
+    As firmware runs at a higher privilege level than the hypervisor we
+    can only run these tests under TCG emulation.
+    """
+
+    timeout = 180
+
+    # SBSA_FLASH0.fd.xz
+    ASSET_FLASH0 = Asset(
+            'https://share.linaro.org/downloadFile?id=kyoMLGC9zXa4oA7',
+            '76eb89d42eebe324e4395329f47447cda9ac920aabcf99aca85424609c3384a5')
+
+    # SBSA_FLASH1.fd.xz
+    ASSET_FLASH1 = Asset(
+        'https://share.linaro.org/downloadFile?id=Dj1HRXnDnKtU6Nj',
+        'f850f243bd8dbd49c51e061e0f79f1697546938f454aeb59ab7d93e5f0d412fc')
+
+    current_dir = Path(__file__).resolve().parent
+
+    hw_dtb_path = current_dir.parent.parent/ "data" / "dtb" / "aarch64" / \
+                    "arm-generic-fdt" / "arm64-sbsa-hw.dtb"
+
+    dtb_path = current_dir.parent.parent/ "data" / "dtb" / "aarch64" / \
+                    "arm-generic-fdt" / "arm64-sbsa-guest.dtb"
+
+    def test_edk2_firmware(self):
+
+        self.set_machine('arm-generic-fdt')
+
+        fetch_firmware(self)
+
+        self.vm.add_args('-hw-dtb', str(self.hw_dtb_path))
+        self.vm.add_args('-dtb', str(self.dtb_path))
+
+        self.vm.add_args('-device', "bochs-display")
+        self.vm.add_args('-device', "bochs-display")
+
+        self.vm.add_args('-d', 'guest_errors,unimp')
+        self.vm.set_console()
+        self.vm.launch()
+
+        # TF-A boot sequence:
+        #
+        # https://github.com/ARM-software/arm-trusted-firmware/blob/v2.8.0/\
+        #     docs/design/trusted-board-boot.rst#trusted-board-boot-sequence
+        # https://trustedfirmware-a.readthedocs.io/en/v2.8/\
+        #     design/firmware-design.html#cold-boot
+
+        # AP Trusted ROM
+        wait_for_console_pattern(self, "Booting Trusted Firmware")
+        wait_for_console_pattern(self, "BL1: v2.12.0(release):")
+        wait_for_console_pattern(self, "BL1: Booting BL2")
+
+        # Trusted Boot Firmware
+        wait_for_console_pattern(self, "BL2: v2.12.0(release)")
+        wait_for_console_pattern(self, "Booting BL31")
+
+        # EL3 Runtime Software
+        wait_for_console_pattern(self, "BL31: v2.12.0(release)")
+
+        # Non-trusted Firmware
+        wait_for_console_pattern(self, "UEFI firmware (version 1.0")
+        interrupt_interactive_console_until_pattern(self, "QEMU SBSA-REF 
Machine")
+
+if __name__ == '__main__':
+    QemuSystemTest.main()
diff --git a/tests/functional/aarch64/test_arm_generic_fdt_alpine.py 
b/tests/functional/aarch64/test_arm_generic_fdt_alpine.py
new file mode 100755
index 0000000000..10429d21a3
--- /dev/null
+++ b/tests/functional/aarch64/test_arm_generic_fdt_alpine.py
@@ -0,0 +1,61 @@
+#!/usr/bin/env python3
+#
+# Functional test that boots a kernel and checks the console
+#
+# Based on test_arm_generic_fdt_alpine.py
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from qemu_test import QemuSystemTest, Asset, skipSlowTest
+from qemu_test import wait_for_console_pattern
+from test_arm_generic_fdt import fetch_firmware
+
+from pathlib import Path
+
+class Aarch64ArmGenericFdtAlpine(QemuSystemTest):
+
+    ASSET_ALPINE_ISO = Asset(
+        ('https://dl-cdn.alpinelinux.org/'
+         'alpine/v3.17/releases/aarch64/alpine-standard-3.17.2-aarch64.iso'),
+        '5a36304ecf039292082d92b48152a9ec21009d3a62f459de623e19c4bd9dc027')
+
+    current_dir = Path(__file__).resolve().parent
+
+    hw_dtb_path = current_dir.parent.parent/ "data" / "dtb" / "aarch64" / \
+        "arm-generic-fdt" / "arm64-sbsa-hw.dtb"
+
+    dtb_path = current_dir.parent.parent/ "data" / "dtb" / "aarch64" / \
+        "arm-generic-fdt" / "arm64-sbsa-guest.dtb"
+
+
+    # This tests the whole boot chain from EFI to Userspace
+    # We only boot a whole OS for the current top level CPU and GIC
+    # Other test profiles should use more minimal boots
+    def boot_alpine_linux(self):
+        self.set_machine('arm-generic-fdt')
+
+        fetch_firmware(self)
+        iso_path = self.ASSET_ALPINE_ISO.fetch()
+
+        self.vm.set_console()
+        self.vm.add_args('-hw-dtb', str(self.hw_dtb_path))
+        self.vm.add_args('-dtb', str(self.dtb_path))
+        self.vm.add_args(
+            "-device", f"ide-cd,bus=ahci.0,unit=0,drive=cdrom0",
+        )
+        self.vm.add_args(
+            "-drive", f"file={iso_path},if=none,id=cdrom0",
+        )
+        self.vm.add_args('-device', "bochs-display")
+        self.vm.add_args('-netdev', "user,id=net0")
+        self.vm.add_args('-device', "e1000e,netdev=net0")
+
+        self.vm.launch()
+        wait_for_console_pattern(self, "Welcome to Alpine Linux 3.17")
+
+    def test_alpine_linux(self):
+        self.boot_alpine_linux()
+
+
+if __name__ == '__main__':
+    QemuSystemTest.main()
-- 
2.43.0


Reply via email to