blob: 333a6b2ff5bb74a88af34132f1027d4500778bd8 [file] [log] [blame]
Manish Pandey65fe3642025-03-21 12:44:42 +00001/*
2 * Copyright The Transfer List Library Contributors
3 *
4 * SPDX-License-Identifier: MIT OR GPL-2.0-or-later
5 */
6
7#ifndef TRANSFER_LIST_H
8#define TRANSFER_LIST_H
9
10#include <assert.h>
11#include <stdbool.h>
12#include <stdint.h>
13
14#define TRANSFER_LIST_SIGNATURE 0x4a0fb10b
15#define TRANSFER_LIST_VERSION 0x0001
16
17/*
18 * Init value of maximum alignment required by any TE data in the TL
19 * specified as a power of two
20 */
21#define TRANSFER_LIST_INIT_MAX_ALIGN 3U
22
23/* Alignment required by TE header start address, in bytes */
24#define TRANSFER_LIST_GRANULE 8U
25
26/*
27 * Version of the register convention used.
28 * Set to 1 for both AArch64 and AArch32 according to fw handoff spec v0.9
29 */
30#define REGISTER_CONVENTION_VERSION_SHIFT_64 32UL
31#define REGISTER_CONVENTION_VERSION_SHIFT_32 24UL
32#define REGISTER_CONVENTION_VERSION_MASK 0xffUL
33#define REGISTER_CONVENTION_VERSION 1UL
34
35#define TRANSFER_LIST_HANDOFF_X1_VALUE(__version) \
36 ((TRANSFER_LIST_SIGNATURE & \
37 ((1UL << REGISTER_CONVENTION_VERSION_SHIFT_64) - 1)) | \
38 (((__version)&REGISTER_CONVENTION_VERSION_MASK) \
39 << REGISTER_CONVENTION_VERSION_SHIFT_64))
40
41#define TRANSFER_LIST_HANDOFF_R1_VALUE(__version) \
42 ((TRANSFER_LIST_SIGNATURE & \
43 ((1UL << REGISTER_CONVENTION_VERSION_SHIFT_32) - 1)) | \
44 (((__version)&REGISTER_CONVENTION_VERSION_MASK) \
45 << REGISTER_CONVENTION_VERSION_SHIFT_32))
46
47#ifndef __ASSEMBLER__
48
49#define TL_FLAGS_HAS_CHECKSUM (1U << 0U)
50
51enum transfer_list_tag_id {
52 TL_TAG_EMPTY = 0,
53 TL_TAG_FDT = 1,
54 TL_TAG_HOB_BLOCK = 2,
55 TL_TAG_HOB_LIST = 3,
56 TL_TAG_ACPI_TABLE_AGGREGATE = 4,
Harrison Mutai1171f832025-03-21 15:33:17 +000057 TL_TAG_TPM_EVLOG = 5,
Manish Pandey65fe3642025-03-21 12:44:42 +000058 TL_TAG_OPTEE_PAGABLE_PART = 0x100,
59 TL_TAG_DT_SPMC_MANIFEST = 0x101,
60 TL_TAG_EXEC_EP_INFO64 = 0x102,
Manish Pandey65fe3642025-03-21 12:44:42 +000061 TL_TAG_SRAM_LAYOUT64 = 0x104,
62 TL_TAG_MBEDTLS_HEAP_INFO = 0x105,
Yeoreum Yune25480f2025-06-02 20:40:23 +010063 TL_TAG_DT_FFA_MANIFEST = 0x106,
Harrison Mutai1171f832025-03-21 15:33:17 +000064 TL_TAG_SRAM_LAYOUT32 = 0x107,
Yeoreum Yune25480f2025-06-02 20:40:23 +010065 TL_TAG_EXEC_EP_INFO32 = 0x108,
Manish Pandey65fe3642025-03-21 12:44:42 +000066};
67
68enum transfer_list_ops {
69 TL_OPS_NON, /* invalid for any operation */
70 TL_OPS_ALL, /* valid for all operations */
71 TL_OPS_RO, /* valid for read only */
72 TL_OPS_CUS, /* abort or switch to special code to interpret */
73};
74
75struct transfer_list_header {
76 uint32_t signature;
77 uint8_t checksum;
78 uint8_t version;
79 uint8_t hdr_size;
80 uint8_t alignment; /* max alignment of TE data */
81 uint32_t size; /* TL header + all TEs */
82 uint32_t max_size;
83 uint32_t flags;
84 uint32_t reserved; /* spare bytes */
85 /*
86 * Commented out element used to visualize dynamic part of the
87 * data structure.
88 *
89 * Note that struct transfer_list_entry also is dynamic in size
90 * so the elements can't be indexed directly but instead must be
91 * traversed in order
92 *
93 * struct transfer_list_entry entries[];
94 */
95};
96
97struct __attribute__((packed)) transfer_list_entry {
98 uint32_t tag_id : 24;
99 uint8_t hdr_size;
100 uint32_t data_size;
101 /*
102 * Commented out element used to visualize dynamic part of the
103 * data structure.
104 *
105 * Note that padding is added at the end of @data to make to reach
106 * a 8-byte boundary.
107 *
108 * uint8_t data[ROUNDUP(data_size, 8)];
109 */
110};
111
112static_assert(sizeof(struct transfer_list_entry) == 0x8U,
113 "assert_transfer_list_entry_size");
114
115void transfer_list_dump(struct transfer_list_header *tl);
Harrison Mutaidb83bfa2025-03-21 15:24:55 +0000116void transfer_entry_dump(struct transfer_list_entry *te);
117struct transfer_list_header *transfer_list_ensure(void *addr, size_t size);
Manish Pandey65fe3642025-03-21 12:44:42 +0000118struct transfer_list_header *transfer_list_init(void *addr, size_t max_size);
119
120struct transfer_list_header *
121transfer_list_relocate(struct transfer_list_header *tl, void *addr,
122 size_t max_size);
123enum transfer_list_ops
124transfer_list_check_header(const struct transfer_list_header *tl);
125
126void transfer_list_update_checksum(struct transfer_list_header *tl);
127bool transfer_list_verify_checksum(const struct transfer_list_header *tl);
128
129bool transfer_list_set_data_size(struct transfer_list_header *tl,
130 struct transfer_list_entry *entry,
131 uint32_t new_data_size);
132
133void *transfer_list_entry_data(struct transfer_list_entry *entry);
134bool transfer_list_rem(struct transfer_list_header *tl,
135 struct transfer_list_entry *entry);
136
137struct transfer_list_entry *transfer_list_add(struct transfer_list_header *tl,
138 uint32_t tag_id,
139 uint32_t data_size,
140 const void *data);
141
142struct transfer_list_entry *
143transfer_list_add_with_align(struct transfer_list_header *tl, uint32_t tag_id,
144 uint32_t data_size, const void *data,
145 uint8_t alignment);
146
147struct transfer_list_entry *
148transfer_list_next(struct transfer_list_header *tl,
149 struct transfer_list_entry *last);
150
151struct transfer_list_entry *transfer_list_find(struct transfer_list_header *tl,
152 uint32_t tag_id);
153
154#endif /* __ASSEMBLER__ */
155#endif /* TRANSFER_LIST_H */