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