xref: /qemu/tests/functional/test_aarch64_sbsaref.py (revision 8f16cd80fcc2e3f502080ea72de55c9f9bc21f58)
1*8f16cd80SPhilippe Mathieu-Daudé#!/usr/bin/env python3
2*8f16cd80SPhilippe Mathieu-Daudé#
3*8f16cd80SPhilippe Mathieu-Daudé# Functional test that boots a Linux kernel and checks the console
4*8f16cd80SPhilippe Mathieu-Daudé#
5*8f16cd80SPhilippe Mathieu-Daudé# SPDX-FileCopyrightText: 2023-2024 Linaro Ltd.
6*8f16cd80SPhilippe Mathieu-Daudé# SPDX-FileContributor: Philippe Mathieu-Daudé <philmd@linaro.org>
7*8f16cd80SPhilippe Mathieu-Daudé# SPDX-FileContributor: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
8*8f16cd80SPhilippe Mathieu-Daudé#
9*8f16cd80SPhilippe Mathieu-Daudé# SPDX-License-Identifier: GPL-2.0-or-later
10*8f16cd80SPhilippe Mathieu-Daudé
11*8f16cd80SPhilippe Mathieu-Daudéimport os
12*8f16cd80SPhilippe Mathieu-Daudé
13*8f16cd80SPhilippe Mathieu-Daudéfrom qemu_test import QemuSystemTest, Asset
14*8f16cd80SPhilippe Mathieu-Daudéfrom qemu_test import wait_for_console_pattern
15*8f16cd80SPhilippe Mathieu-Daudéfrom qemu_test import interrupt_interactive_console_until_pattern
16*8f16cd80SPhilippe Mathieu-Daudéfrom qemu_test.utils import lzma_uncompress
17*8f16cd80SPhilippe Mathieu-Daudéfrom unittest import skipUnless
18*8f16cd80SPhilippe Mathieu-Daudé
19*8f16cd80SPhilippe Mathieu-Daudé
20*8f16cd80SPhilippe Mathieu-Daudéclass Aarch64SbsarefMachine(QemuSystemTest):
21*8f16cd80SPhilippe Mathieu-Daudé    """
22*8f16cd80SPhilippe Mathieu-Daudé    As firmware runs at a higher privilege level than the hypervisor we
23*8f16cd80SPhilippe Mathieu-Daudé    can only run these tests under TCG emulation.
24*8f16cd80SPhilippe Mathieu-Daudé    """
25*8f16cd80SPhilippe Mathieu-Daudé
26*8f16cd80SPhilippe Mathieu-Daudé    timeout = 180
27*8f16cd80SPhilippe Mathieu-Daudé
28*8f16cd80SPhilippe Mathieu-Daudé    ASSET_FLASH0 = Asset(
29*8f16cd80SPhilippe Mathieu-Daudé        ('https://artifacts.codelinaro.org/artifactory/linaro-419-sbsa-ref/'
30*8f16cd80SPhilippe Mathieu-Daudé         '20240619-148232/edk2/SBSA_FLASH0.fd.xz'),
31*8f16cd80SPhilippe Mathieu-Daudé        '0c954842a590988f526984de22e21ae0ab9cb351a0c99a8a58e928f0c7359cf7')
32*8f16cd80SPhilippe Mathieu-Daudé
33*8f16cd80SPhilippe Mathieu-Daudé    ASSET_FLASH1 = Asset(
34*8f16cd80SPhilippe Mathieu-Daudé        ('https://artifacts.codelinaro.org/artifactory/linaro-419-sbsa-ref/'
35*8f16cd80SPhilippe Mathieu-Daudé         '20240619-148232/edk2/SBSA_FLASH1.fd.xz'),
36*8f16cd80SPhilippe Mathieu-Daudé        'c6ec39374c4d79bb9e9cdeeb6db44732d90bb4a334cec92002b3f4b9cac4b5ee')
37*8f16cd80SPhilippe Mathieu-Daudé
38*8f16cd80SPhilippe Mathieu-Daudé    def fetch_firmware(self):
39*8f16cd80SPhilippe Mathieu-Daudé        """
40*8f16cd80SPhilippe Mathieu-Daudé        Flash volumes generated using:
41*8f16cd80SPhilippe Mathieu-Daudé
42*8f16cd80SPhilippe Mathieu-Daudé        Toolchain from Debian:
43*8f16cd80SPhilippe Mathieu-Daudé        aarch64-linux-gnu-gcc (Debian 12.2.0-14) 12.2.0
44*8f16cd80SPhilippe Mathieu-Daudé
45*8f16cd80SPhilippe Mathieu-Daudé        Used components:
46*8f16cd80SPhilippe Mathieu-Daudé
47*8f16cd80SPhilippe Mathieu-Daudé        - Trusted Firmware         v2.11.0
48*8f16cd80SPhilippe Mathieu-Daudé        - Tianocore EDK2           4d4f569924
49*8f16cd80SPhilippe Mathieu-Daudé        - Tianocore EDK2-platforms 3f08401
50*8f16cd80SPhilippe Mathieu-Daudé
51*8f16cd80SPhilippe Mathieu-Daudé        """
52*8f16cd80SPhilippe Mathieu-Daudé
53*8f16cd80SPhilippe Mathieu-Daudé        # Secure BootRom (TF-A code)
54*8f16cd80SPhilippe Mathieu-Daudé        fs0_xz_path = self.ASSET_FLASH0.fetch()
55*8f16cd80SPhilippe Mathieu-Daudé        fs0_path = os.path.join(self.workdir, "SBSA_FLASH0.fd")
56*8f16cd80SPhilippe Mathieu-Daudé        lzma_uncompress(fs0_xz_path, fs0_path)
57*8f16cd80SPhilippe Mathieu-Daudé
58*8f16cd80SPhilippe Mathieu-Daudé        # Non-secure rom (UEFI and EFI variables)
59*8f16cd80SPhilippe Mathieu-Daudé        fs1_xz_path = self.ASSET_FLASH1.fetch()
60*8f16cd80SPhilippe Mathieu-Daudé        fs1_path = os.path.join(self.workdir, "SBSA_FLASH1.fd")
61*8f16cd80SPhilippe Mathieu-Daudé        lzma_uncompress(fs1_xz_path, fs1_path)
62*8f16cd80SPhilippe Mathieu-Daudé
63*8f16cd80SPhilippe Mathieu-Daudé        for path in [fs0_path, fs1_path]:
64*8f16cd80SPhilippe Mathieu-Daudé            with open(path, "ab+") as fd:
65*8f16cd80SPhilippe Mathieu-Daudé                fd.truncate(256 << 20)  # Expand volumes to 256MiB
66*8f16cd80SPhilippe Mathieu-Daudé
67*8f16cd80SPhilippe Mathieu-Daudé        self.set_machine('sbsa-ref')
68*8f16cd80SPhilippe Mathieu-Daudé        self.vm.set_console()
69*8f16cd80SPhilippe Mathieu-Daudé        self.vm.add_args(
70*8f16cd80SPhilippe Mathieu-Daudé            "-drive", f"if=pflash,file={fs0_path},format=raw",
71*8f16cd80SPhilippe Mathieu-Daudé            "-drive", f"if=pflash,file={fs1_path},format=raw",
72*8f16cd80SPhilippe Mathieu-Daudé        )
73*8f16cd80SPhilippe Mathieu-Daudé
74*8f16cd80SPhilippe Mathieu-Daudé    def test_sbsaref_edk2_firmware(self):
75*8f16cd80SPhilippe Mathieu-Daudé
76*8f16cd80SPhilippe Mathieu-Daudé        self.fetch_firmware()
77*8f16cd80SPhilippe Mathieu-Daudé
78*8f16cd80SPhilippe Mathieu-Daudé        self.vm.add_args('-cpu', 'cortex-a57')
79*8f16cd80SPhilippe Mathieu-Daudé        self.vm.launch()
80*8f16cd80SPhilippe Mathieu-Daudé
81*8f16cd80SPhilippe Mathieu-Daudé        # TF-A boot sequence:
82*8f16cd80SPhilippe Mathieu-Daudé        #
83*8f16cd80SPhilippe Mathieu-Daudé        # https://github.com/ARM-software/arm-trusted-firmware/blob/v2.8.0/\
84*8f16cd80SPhilippe Mathieu-Daudé        #     docs/design/trusted-board-boot.rst#trusted-board-boot-sequence
85*8f16cd80SPhilippe Mathieu-Daudé        # https://trustedfirmware-a.readthedocs.io/en/v2.8/\
86*8f16cd80SPhilippe Mathieu-Daudé        #     design/firmware-design.html#cold-boot
87*8f16cd80SPhilippe Mathieu-Daudé
88*8f16cd80SPhilippe Mathieu-Daudé        # AP Trusted ROM
89*8f16cd80SPhilippe Mathieu-Daudé        wait_for_console_pattern(self, "Booting Trusted Firmware")
90*8f16cd80SPhilippe Mathieu-Daudé        wait_for_console_pattern(self, "BL1: v2.11.0(release):")
91*8f16cd80SPhilippe Mathieu-Daudé        wait_for_console_pattern(self, "BL1: Booting BL2")
92*8f16cd80SPhilippe Mathieu-Daudé
93*8f16cd80SPhilippe Mathieu-Daudé        # Trusted Boot Firmware
94*8f16cd80SPhilippe Mathieu-Daudé        wait_for_console_pattern(self, "BL2: v2.11.0(release)")
95*8f16cd80SPhilippe Mathieu-Daudé        wait_for_console_pattern(self, "Booting BL31")
96*8f16cd80SPhilippe Mathieu-Daudé
97*8f16cd80SPhilippe Mathieu-Daudé        # EL3 Runtime Software
98*8f16cd80SPhilippe Mathieu-Daudé        wait_for_console_pattern(self, "BL31: v2.11.0(release)")
99*8f16cd80SPhilippe Mathieu-Daudé
100*8f16cd80SPhilippe Mathieu-Daudé        # Non-trusted Firmware
101*8f16cd80SPhilippe Mathieu-Daudé        wait_for_console_pattern(self, "UEFI firmware (version 1.0")
102*8f16cd80SPhilippe Mathieu-Daudé        interrupt_interactive_console_until_pattern(self, "QEMU SBSA-REF Machine")
103*8f16cd80SPhilippe Mathieu-Daudé
104*8f16cd80SPhilippe Mathieu-Daudé
105*8f16cd80SPhilippe Mathieu-Daudé    ASSET_ALPINE_ISO = Asset(
106*8f16cd80SPhilippe Mathieu-Daudé        ('https://dl-cdn.alpinelinux.org/'
107*8f16cd80SPhilippe Mathieu-Daudé         'alpine/v3.17/releases/aarch64/alpine-standard-3.17.2-aarch64.iso'),
108*8f16cd80SPhilippe Mathieu-Daudé        '5a36304ecf039292082d92b48152a9ec21009d3a62f459de623e19c4bd9dc027')
109*8f16cd80SPhilippe Mathieu-Daudé
110*8f16cd80SPhilippe Mathieu-Daudé    # This tests the whole boot chain from EFI to Userspace
111*8f16cd80SPhilippe Mathieu-Daudé    # We only boot a whole OS for the current top level CPU and GIC
112*8f16cd80SPhilippe Mathieu-Daudé    # Other test profiles should use more minimal boots
113*8f16cd80SPhilippe Mathieu-Daudé    def boot_alpine_linux(self, cpu):
114*8f16cd80SPhilippe Mathieu-Daudé        self.fetch_firmware()
115*8f16cd80SPhilippe Mathieu-Daudé
116*8f16cd80SPhilippe Mathieu-Daudé        iso_path = self.ASSET_ALPINE_ISO.fetch()
117*8f16cd80SPhilippe Mathieu-Daudé
118*8f16cd80SPhilippe Mathieu-Daudé        self.vm.set_console()
119*8f16cd80SPhilippe Mathieu-Daudé        self.vm.add_args(
120*8f16cd80SPhilippe Mathieu-Daudé            "-cpu", cpu,
121*8f16cd80SPhilippe Mathieu-Daudé            "-drive", f"file={iso_path},media=cdrom,format=raw",
122*8f16cd80SPhilippe Mathieu-Daudé        )
123*8f16cd80SPhilippe Mathieu-Daudé
124*8f16cd80SPhilippe Mathieu-Daudé        self.vm.launch()
125*8f16cd80SPhilippe Mathieu-Daudé        wait_for_console_pattern(self, "Welcome to Alpine Linux 3.17")
126*8f16cd80SPhilippe Mathieu-Daudé
127*8f16cd80SPhilippe Mathieu-Daudé    def test_sbsaref_alpine_linux_cortex_a57(self):
128*8f16cd80SPhilippe Mathieu-Daudé        self.boot_alpine_linux("cortex-a57")
129*8f16cd80SPhilippe Mathieu-Daudé
130*8f16cd80SPhilippe Mathieu-Daudé    def test_sbsaref_alpine_linux_neoverse_n1(self):
131*8f16cd80SPhilippe Mathieu-Daudé        self.boot_alpine_linux("neoverse-n1")
132*8f16cd80SPhilippe Mathieu-Daudé
133*8f16cd80SPhilippe Mathieu-Daudé    def test_sbsaref_alpine_linux_max_pauth_off(self):
134*8f16cd80SPhilippe Mathieu-Daudé        self.boot_alpine_linux("max,pauth=off")
135*8f16cd80SPhilippe Mathieu-Daudé
136*8f16cd80SPhilippe Mathieu-Daudé    def test_sbsaref_alpine_linux_max_pauth_impdef(self):
137*8f16cd80SPhilippe Mathieu-Daudé        self.boot_alpine_linux("max,pauth-impdef=on")
138*8f16cd80SPhilippe Mathieu-Daudé
139*8f16cd80SPhilippe Mathieu-Daudé    @skipUnless(os.getenv('QEMU_TEST_TIMEOUT_EXPECTED'), 'Test might timeout')
140*8f16cd80SPhilippe Mathieu-Daudé    def test_sbsaref_alpine_linux_max(self):
141*8f16cd80SPhilippe Mathieu-Daudé        self.boot_alpine_linux("max")
142*8f16cd80SPhilippe Mathieu-Daudé
143*8f16cd80SPhilippe Mathieu-Daudé
144*8f16cd80SPhilippe Mathieu-Daudé    ASSET_OPENBSD_ISO = Asset(
145*8f16cd80SPhilippe Mathieu-Daudé        ('https://cdn.openbsd.org/pub/OpenBSD/7.3/arm64/miniroot73.img'),
146*8f16cd80SPhilippe Mathieu-Daudé        '7fc2c75401d6f01fbfa25f4953f72ad7d7c18650056d30755c44b9c129b707e5')
147*8f16cd80SPhilippe Mathieu-Daudé
148*8f16cd80SPhilippe Mathieu-Daudé    # This tests the whole boot chain from EFI to Userspace
149*8f16cd80SPhilippe Mathieu-Daudé    # We only boot a whole OS for the current top level CPU and GIC
150*8f16cd80SPhilippe Mathieu-Daudé    # Other test profiles should use more minimal boots
151*8f16cd80SPhilippe Mathieu-Daudé    def boot_openbsd73(self, cpu):
152*8f16cd80SPhilippe Mathieu-Daudé        self.fetch_firmware()
153*8f16cd80SPhilippe Mathieu-Daudé
154*8f16cd80SPhilippe Mathieu-Daudé        img_path = self.ASSET_OPENBSD_ISO.fetch()
155*8f16cd80SPhilippe Mathieu-Daudé
156*8f16cd80SPhilippe Mathieu-Daudé        self.vm.set_console()
157*8f16cd80SPhilippe Mathieu-Daudé        self.vm.add_args(
158*8f16cd80SPhilippe Mathieu-Daudé            "-cpu", cpu,
159*8f16cd80SPhilippe Mathieu-Daudé            "-drive", f"file={img_path},format=raw,snapshot=on",
160*8f16cd80SPhilippe Mathieu-Daudé        )
161*8f16cd80SPhilippe Mathieu-Daudé
162*8f16cd80SPhilippe Mathieu-Daudé        self.vm.launch()
163*8f16cd80SPhilippe Mathieu-Daudé        wait_for_console_pattern(self,
164*8f16cd80SPhilippe Mathieu-Daudé                                 "Welcome to the OpenBSD/arm64"
165*8f16cd80SPhilippe Mathieu-Daudé                                 " 7.3 installation program.")
166*8f16cd80SPhilippe Mathieu-Daudé
167*8f16cd80SPhilippe Mathieu-Daudé    def test_sbsaref_openbsd73_cortex_a57(self):
168*8f16cd80SPhilippe Mathieu-Daudé        self.boot_openbsd73("cortex-a57")
169*8f16cd80SPhilippe Mathieu-Daudé
170*8f16cd80SPhilippe Mathieu-Daudé    def test_sbsaref_openbsd73_neoverse_n1(self):
171*8f16cd80SPhilippe Mathieu-Daudé        self.boot_openbsd73("neoverse-n1")
172*8f16cd80SPhilippe Mathieu-Daudé
173*8f16cd80SPhilippe Mathieu-Daudé    def test_sbsaref_openbsd73_max_pauth_off(self):
174*8f16cd80SPhilippe Mathieu-Daudé        self.boot_openbsd73("max,pauth=off")
175*8f16cd80SPhilippe Mathieu-Daudé
176*8f16cd80SPhilippe Mathieu-Daudé    @skipUnless(os.getenv('QEMU_TEST_TIMEOUT_EXPECTED'), 'Test might timeout')
177*8f16cd80SPhilippe Mathieu-Daudé    def test_sbsaref_openbsd73_max_pauth_impdef(self):
178*8f16cd80SPhilippe Mathieu-Daudé        self.boot_openbsd73("max,pauth-impdef=on")
179*8f16cd80SPhilippe Mathieu-Daudé
180*8f16cd80SPhilippe Mathieu-Daudé    @skipUnless(os.getenv('QEMU_TEST_TIMEOUT_EXPECTED'), 'Test might timeout')
181*8f16cd80SPhilippe Mathieu-Daudé    def test_sbsaref_openbsd73_max(self):
182*8f16cd80SPhilippe Mathieu-Daudé        self.boot_openbsd73("max")
183*8f16cd80SPhilippe Mathieu-Daudé
184*8f16cd80SPhilippe Mathieu-Daudé
185*8f16cd80SPhilippe Mathieu-Daudéif __name__ == '__main__':
186*8f16cd80SPhilippe Mathieu-Daudé    QemuSystemTest.main()
187