1# Copyright (c) 2024, TOKITA Hiroshi <tokita.hiroshi@gmail.com>
2# SPDX-License-Identifier: Apache-2.0
3
4import os
5import sys
6import logging
7import re
8from twister_harness import DeviceAdapter
9
10ZEPHYR_BASE = os.getenv("ZEPHYR_BASE")
11sys.path.insert(
12    0, os.path.join(ZEPHYR_BASE, "scripts", "dts", "python-devicetree", "src")
13)
14from devicetree import edtlib
15
16logger = logging.getLogger(__name__)
17
18
19def smart_int(numstr):
20    if numstr.startswith("0x"):
21        return int(numstr[2:], 16)
22    else:
23        return int(numstr)
24
25
26def verify_memory_region_flags(build_dir, label, expect):
27    logger.info(label)
28
29    linkercmd = os.path.join(build_dir, "zephyr", "linker.cmd")
30    logger.info(linkercmd)
31
32    edt = edtlib.EDT(
33        os.path.join(build_dir, "zephyr", "zephyr.dts"),
34        [os.path.join(ZEPHYR_BASE, "dts", "bindings")],
35    )
36
37    node = edt.label2node[label]
38    logger.info(node)
39
40    region = node.props["zephyr,memory-region"].val
41    logger.info(region)
42
43    origin = node.props["reg"].val[0]
44    length = node.props["reg"].val[1]
45    pattern = (
46        region + r"\s*" + expect +
47        r"\s*:\s*ORIGIN\s*=\s*\(?([0-9A-Fa-fx]*)\)?,\s*LENGTH\s*=\s*\(?([0-9A-Fa-fx]*)\)?"
48    )
49
50    logger.info(pattern)
51
52    found = False
53
54    with open(linkercmd) as f:
55        for line in f:
56            m = re.search(pattern, line)
57            if m and smart_int(m[1]) == origin and smart_int(m[2]) == length:
58                found = True
59
60    assert found
61
62
63def test_region_r(dut: DeviceAdapter):
64    verify_memory_region_flags(dut.device_config.build_dir, "test_region_r", r"\(\s*r\s*\)")
65
66def test_region_nrwxail(dut: DeviceAdapter):
67    verify_memory_region_flags(dut.device_config.build_dir, "test_region_nrwxail", r"\(\s*!rwxail\s*\)")
68
69def test_region_no_flags(dut: DeviceAdapter):
70    verify_memory_region_flags(dut.device_config.build_dir, "test_region_no_flags", r"\(\s*rw\s*\)")
71
72def test_region_none(dut: DeviceAdapter):
73    verify_memory_region_flags(dut.device_config.build_dir, "test_region_none", r"")
74