# SPDX-License-Identifier: GPL-2.0+ # # Copyright (c) 2025 Linaro Limited # Author: Raymond Mao # # Validate Firmware Handoff from TF-A and OP-TEE """ Note: This test relies on boardenv_* containing configuration values to define whether Firmware Handoff is enabled for testing. Without this, this test will be automatically skipped. For example: .. code-block:: python # Boolean indicating whether Firmware Handoff is enabled on this board. # This variable may be omitted if its value is False. env__firmware_handoff_enabled = True """ import pytest import re def _norm_ws(s: str) -> str: """Normalize whitespace for robust comparisons.""" return re.sub(r"\s+", " ", s).strip() @pytest.mark.buildconfigspec("bloblist") @pytest.mark.buildconfigspec("cmd_bloblist") @pytest.mark.buildconfigspec("of_control") @pytest.mark.buildconfigspec("cmd_fdt") def test_fw_handoff_dt(ubman): """Validate FDT handoff via bloblist.""" fh_en = ubman.config.env.get('env__firmware_handoff_enabled', False) if not fh_en: pytest.skip('Firmware Handoff is disabled') bloblist = ubman.run_command("bloblist list") blob_fdt = re.search(r"^([0-9a-fA-F]+)\s+[0-9a-fA-F]+\s+1\s+Control FDT\s*$", bloblist, re.MULTILINE) assert blob_fdt, "Control FDT entry not found in bloblist" blob_fdt_addr = int(blob_fdt.group(1), 16) ubman.run_command(f"fdt addr {blob_fdt_addr:x}") reserved_a = ubman.run_command("fdt print /reserved-memory") firmware_a = ubman.run_command("fdt print /firmware") fdt_addr_out = ubman.run_command("echo $fdt_addr") fdt_addr_match = re.search(r"(?:0x)?([0-9a-fA-F]+)", fdt_addr_out) assert fdt_addr_match, "Could not parse $fdt_addr" fdt_addr = int(fdt_addr_match.group(1), 16) ubman.run_command(f"fdt addr {fdt_addr:x}") reserved_b = ubman.run_command("fdt print /reserved-memory") firmware_b = ubman.run_command("fdt print /firmware") # Normalize whitespace & compare assert _norm_ws(reserved_a) == _norm_ws(reserved_b), \ "reserved-memory blocks differ between Control FDT and $fdt_addr FDT" assert _norm_ws(firmware_a) == _norm_ws(firmware_b), \ "firmware blocks differ between Control FDT and $fdt_addr FDT" @pytest.mark.buildconfigspec("bloblist") @pytest.mark.buildconfigspec("cmd_bloblist") @pytest.mark.buildconfigspec("cmd_memory") def test_fw_handoff_eventlog(ubman): """Validate TPM event log handoff via bloblist.""" fh_en = ubman.config.env.get('env__firmware_handoff_enabled', False) if not fh_en: pytest.skip('Firmware Handoff is disabled') # Get the address and size of eventlog from the bloblist bloblist_output = ubman.run_command("bloblist list") evt_addr = None evt_size = None for line in bloblist_output.splitlines(): if "TPM event log" in line: parts = line.strip().split() evt_addr = int(parts[0], 16) evt_size = int(parts[1], 16) break assert evt_addr is not None and evt_size is not None, \ "TPM event log not found in bloblist" # Read byte from memory and extract printable ASCII from each line md_output = ubman.run_command(f"md.b {evt_addr:x} {evt_size}") ascii_log = "" for line in md_output.splitlines(): match = re.search(r'([0-9a-f]+:.*?)((?:\s[0-9a-f]{2}){1,16})\s+(.*)', line) if match: ascii_part = match.group(3).strip() ascii_log += ascii_part # The events created by TF-A are expected expected_keywords = [ "SECURE_RT_EL3", "SECURE_RT_EL1_OPTEE", "SECURE_RT_EL1_OPTEE_EXTRA1" ] for keyword in expected_keywords: assert keyword in ascii_log, f"Missing expected event: {keyword}"