| Transfer List Compiler |
| ====================== |
| |
| The Transfer List Compiler (tlc) is a host tool used by TF-A to generate transfer |
| lists compliant with the v0.9 of the `Firmware Handoff specification`_. It enables |
| developers to statically generate transfer list blobs containing any number of |
| transfer entries. |
| |
| Getting Started |
| ~~~~~~~~~~~~~~~ |
| |
| ``tlc`` is installed by default with TF-A's poetry environment. All of it's |
| dependencies are listed in `tools/tlc/pyproject.toml`_. |
| |
| To install ``tlc`` seperately, run the following command: |
| |
| .. code:: |
| |
| make -C tools/tlc install |
| |
| Creating a Transfer List |
| ~~~~~~~~~~~~~~~~~~~~~~~~ |
| |
| To create an empty TL, you can use the ``create`` command. |
| |
| .. code:: |
| |
| tlc create tl.bin |
| |
| This commands generates a binary blob representing an empty TL, shown in the |
| hexdump below. |
| |
| .. code:: |
| |
| $ hexdump tl.bin | head |
| 0000000 b10b 4a0f 01a6 0318 0018 0000 1000 0000 |
| 0000010 0001 0000 0000 0000 |
| |
| A common use-case this tool supports is the addition of TE's via the option |
| ``--entry``. This takes as input the tag ID and path to a binary blob to be |
| included in the transfer list. The snippet below shows how to include an FDT in |
| the TL. |
| |
| .. code:: |
| |
| tlc create --entry 1 fdt.dtb tl.bin |
| |
| Alternatively, addition of a device tree is supported through the option |
| ``--fdt``. This has the same effect as passing the device tree and it's tag ID |
| through the ``--entry`` option. |
| |
| .. code:: |
| |
| tlc create --fdt fdt.dtb tl.bin |
| |
| .. note:: |
| |
| ``tlc`` makes no effort to verify the contents of a binary blob against the |
| provided tag ID. It only checks that the tags provided as input are within |
| range and that there is sufficient memory to include their TE's. |
| |
| You can also create a TL from a YAML config file. |
| |
| .. code :: |
| |
| tlc create --from-yaml config.yaml tl.bin |
| |
| Printing the contents of a TL |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| |
| Support is provided for dumping the contents of a TL via the ``info`` command. |
| This prints the header of the TL and all included TE's. |
| |
| .. code:: |
| |
| $ tlc info tl.bin |
| signature 0x4a0fb10b |
| checksum 0xe1 |
| version 0x1 |
| hdr_size 0x18 |
| alignment 0x3 |
| size 0x2a6f |
| total_size 0x4e20 |
| flags 0x1 |
| ---- |
| id 0x1 |
| data_size 0x2a47 |
| hdr_size 0x8 |
| offset 0x18 |
| ---- |
| id 0x0 |
| data_size 0x0 |
| hdr_size 0x8 |
| offset 0x2a68 |
| |
| The example above shows the dump produced by ``tlc`` for a 20Kb TL containing a |
| device tree (tag_id=1) and a NULL entry (tag_id=0). |
| |
| Modifying the contents of an existing TL |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| |
| `tlc` supports removal of one or more entries from a TL through the ``remove`` |
| command. It takes as argument the filename, and one or more tag ID's, passed |
| through the ``--tags`` option. It produces a valid TL blob without those |
| entries. |
| |
| |
| For example, using the same blob as in the section above, we can remove the FDT |
| TE with the command. |
| |
| .. code:: |
| |
| $ tlc remove --tags 1 tl.bin |
| |
| Using the ``info`` command, shows the the TE has been remove: |
| |
| .. code:: |
| |
| $ tlc info tl.bin |
| |
| signature 0x4a0fb10b |
| checksum 0x38 |
| version 0x1 |
| hdr_size 0x18 |
| alignment 0x3 |
| size 0x20 |
| total_size 0x4e20 |
| flags 0x1 |
| ---- |
| id 0x0 |
| data_size 0x0 |
| hdr_size 0x8 |
| offset 0x18 |
| |
| Note that more than one entry can be removed at a time. The ``--tags`` option |
| accepts multiple tag ID's. |
| |
| Conversely, TE's can be added to an existing TL. This is achieved through the |
| `add` command. |
| |
| .. code:: |
| |
| $ tlc add --entry 1 fdt.dtb tl.bin |
| |
| |
| The result of this modification is shown below: |
| |
| .. code:: |
| |
| $ tlc info tl.bin |
| |
| signature 0x4a0fb10b |
| checksum 0xe1 |
| version 0x1 |
| hdr_size 0x18 |
| alignment 0x3 |
| size 0x2a6f |
| total_size 0x4e20 |
| flags 0x1 |
| ---- |
| id 0x0 |
| data_size 0x0 |
| hdr_size 0x8 |
| offset 0x18 |
| ---- |
| id 0x1 |
| data_size 0x2a47 |
| hdr_size 0x8 |
| offset 0x20 |
| |
| Unpacking a Transfer List |
| ~~~~~~~~~~~~~~~~~~~~~~~~~ |
| |
| Given a transfer list, ``tlc`` also provides a mechanism for extracting TE data. |
| Running the command ``unpack``, yields binary files containing data from all the TE's. |
| |
| .. code:: |
| |
| $ tlc create --size 20000 --fdt build/fvp/debug/fdts/fvp-base-gicv3-psci.dtb tl.bin |
| $ tlc unpack tl.bin |
| $ file te_1.bin |
| te_1.bin: Device Tree Blob version 17, size=10823, boot CPU=0, string block size=851, DT structure block size=9900 |
| |
| Validate a Transfer List |
| ~~~~~~~~~~~~~~~~~~~~~~~~ |
| |
| ``tlc validate`` provides a quick and simple mechanism for checking wether the TL |
| is compliant with version of the specification supported by the tool. It |
| performs the following checks: |
| |
| #. Validates the signature. |
| #. Ensures that the specified version is greater than or equal to the tool’s current version. |
| #. Verifies alignment criteria for all TE’s. |
| |
| YAML Config File Format |
| ~~~~~~~~~~~~~~~~~~~~~~~ |
| |
| Example YAML config file: |
| |
| .. code:: |
| |
| execution_state: aarch32 |
| has_checksum: true |
| max_size: 4096 |
| entries: |
| - tag_id: 258 # entry point info |
| ep_info: |
| args: |
| - 67112968 |
| - 67112960 |
| - 0 |
| - 0 |
| - 0 |
| - 0 |
| - 0 |
| - 0 |
| h: |
| attr: 8 |
| type: 1 |
| version: 2 |
| pc: 67239936 |
| spsr: 467 |
| - tag_id: 3 # memory layout |
| addr: 8 |
| size: 8 |
| - tag_id: 1, # fdt |
| blob_file_path: "fdt.bin", |
| |
| `max_size` defaults to `0x1000`, `execution_state` defaults to `aarch64`, and `has_checksum` |
| defaults to `true`. |
| |
| The fields of the YAML file should match the fields in the specification for the transfer list. You |
| don't need to give the hdr_size or data_size fields. For example, a memory layout entry would have |
| an entry like: |
| |
| .. code:: |
| |
| tag_id: 3 |
| addr: 8 |
| size: 8 |
| |
| You can input blob files by giving paths to the current working directory. You can do this for any |
| TE type. For example, an FDT layout would have an entry like: |
| |
| .. code:: |
| |
| tag_id: 1, |
| blob_file_path: "fdt.bin", |
| |
| You can input C-types by giving its fields. For example, an entry point |
| info entry would have an entry like: |
| |
| .. code:: |
| |
| tag_id: 258 |
| ep_info: |
| args: |
| - 67112968 |
| - 67112960 |
| - 0 |
| - 0 |
| h: |
| attr: 8 |
| type: 1 |
| version: 2 |
| lr_svc: 0 |
| pc: 67239936 |
| spsr: 467 |
| |
| You can give the name of the tag instead of the tag id number. The valid tag names are in the |
| `transfer_entry_formats` dict in `tools/tlc/tlc/tl.py`_. Some examples are: |
| |
| * empty |
| * fdt |
| * hob_block |
| * hob_list |
| |
| You can input the attr field of entry_point_info as a string of flag |
| names separated by `|`. The names are taken from ep_info_exp.h in TF-A. |
| For example: |
| |
| .. code:: |
| |
| has_checksum: true |
| max_size: 4096 |
| entries: |
| - tag_id: 0x102 |
| ep_info: |
| args: |
| - 67112976 |
| - 67112960 |
| - 0 |
| - 0 |
| - 0 |
| - 0 |
| - 0 |
| - 0 |
| h: |
| attr: EP_NON_SECURE | EP_ST_ENABLE |
| type: 1 |
| version: 2 |
| pc: 67239936 |
| spsr: 965 |
| |
| -------------- |
| |
| *Copyright (c) 2024, Arm Limited. All rights reserved.* |
| |
| .. _Firmware Handoff specification: https://github.com/FirmwareHandoff/firmware_handoff/ |
| .. _tools/tlc/pyproject.toml: https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/refs/heads/master/tools/tlc/pyproject.toml |
| .. _tools/tlc/tlc/tl.py: https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/refs/heads/master/tools/tlc/tlc/tl.py |