1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (c) 2025 Linaro Limited
# Author: Raymond Mao <[email protected]>
#
# 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}"
|