fix(tlc): add void entries to align data
Add void entries to ensure proper alignment of data in the TL,
addressing runtime errors caused by previously unaccounted padding bytes
between TE's.
Change-Id: Id2acee8f4df0dcc52eedc4372b962a51acb9d8ce
Signed-off-by: J-Alves <joao.alves@arm.com>
Co-authored-by:: Harrison Mutai <harrison.mutai@arm.com>
diff --git a/tools/tlc/tests/conftest.py b/tools/tlc/tests/conftest.py
index 155746a..93e44a9 100644
--- a/tools/tlc/tests/conftest.py
+++ b/tools/tlc/tests/conftest.py
@@ -69,7 +69,7 @@
def tlcrunner(tmptlstr):
runner = CliRunner()
with runner.isolated_filesystem():
- runner.invoke(cli, ["create", tmptlstr])
+ runner.invoke(cli, ["create", "--size", 0x1F000, tmptlstr])
return runner
diff --git a/tools/tlc/tests/test_transfer_list.py b/tools/tlc/tests/test_transfer_list.py
index e00280b..54d93ec 100644
--- a/tools/tlc/tests/test_transfer_list.py
+++ b/tools/tlc/tests/test_transfer_list.py
@@ -9,6 +9,7 @@
"""Contains unit tests for the types TransferEntry and TransferList."""
import math
+from random import randint
import pytest
@@ -49,16 +50,40 @@
assert tl.checksum == csum
-@pytest.mark.parametrize(("tag_id", "data"), test_entries)
-def test_add_transfer_entry(tag_id, data):
+def test_add_transfer_entry(random_entries):
tl = TransferList(0x1000)
- te = TransferEntry(tag_id, len(data), data)
-
- tl.add_transfer_entry(tag_id, data)
+ # Add a single entry and check it's in the list of entries
+ te = tl.add_transfer_entry(1, bytes(100))
assert te in tl.entries
- assert tl.size == TransferList.hdr_size + te.size
+ assert tl.size % 8 == 0
+
+ # Add a range of tag id's
+ for id, data in random_entries(50, 1):
+ te = tl.add_transfer_entry(id, data)
+ assert te in tl.entries
+ assert tl.size % 8 == 0
+
+
+@pytest.mark.parametrize("align", [4, 6, 12, 13])
+def test_add_transfer_entry_with_align(align, random_entries, random_entry):
+ tl = TransferList(0xF00000)
+ id, data = random_entry(4)
+
+ tl.add_transfer_entry(id, data)
+ # Add an entry with a larger alignment requirement
+ _, data = random_entry(4)
+ te = tl.add_transfer_entry(1, data, data_align=align)
+ assert (te.offset + te.hdr_size) % (1 << align) == 0
+ assert tl.alignment == align
+
+ # Add some more entries and ensure the alignment is preserved
+ for id, data in random_entries(5, 0x200):
+ te = tl.add_transfer_entry(id, data, data_align=align)
+ assert (te.offset + te.hdr_size) % (1 << align) == 0
+ assert tl.alignment == align
+
@pytest.mark.parametrize(
("tag_id", "data"),
@@ -155,6 +180,10 @@
data_size = int.from_bytes(f.read(4), "little")
assert f.read(data_size) == data
+ # padding is added to align TE's, make sure padding is added to the size of
+ # the TL by checking we don't overflow.
+ assert f.tell() <= tl.size
+
def test_read_empty_transfer_list_from_file(tmpdir):
test_file = tmpdir.join("test_tl_blob.bin")
@@ -203,20 +232,18 @@
assert tl.sum_of_bytes() == 0
-
-@pytest.mark.parametrize("tag", [tag for tag, _ in test_entries])
-def test_remove_tag_from_file(tag):
- tl = TransferList(0x1000)
- for tag_id, data in test_entries:
- tl.add_transfer_entry(tag_id, data)
+def test_remove_tag(random_entry):
+ """Adds a transfer entry and remove it, size == transfer list header."""
+ tl = TransferList(0x100)
+ id, data = random_entry(tl.total_size // 2)
- removed_entries = list(filter(lambda te: te.id == tag, tl.entries))
- original_size = tl.size
- tl.remove_tag(tag)
+ te = tl.add_transfer_entry(id, data)
+ assert te in tl.entries
- assert not any(tag == te.id for te in tl.entries)
- assert tl.size == original_size - sum(map(lambda te: te.size, removed_entries))
+ tl.remove_tag(id)
+ assert not tl.get_entry(id) and te not in tl.entries
+ assert tl.size == tl.hdr_size
def test_get_fdt_offset(tmpdir):