blob: 7ae57bce5e33376293a5e29d29548aba252bc953 [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,
57 TL_TAG_OPTEE_PAGABLE_PART = 0x100,
58 TL_TAG_DT_SPMC_MANIFEST = 0x101,
59 TL_TAG_EXEC_EP_INFO64 = 0x102,
60 TL_TAG_TB_FW_CONFIG = 0x103,
61 TL_TAG_SRAM_LAYOUT64 = 0x104,
62 TL_TAG_MBEDTLS_HEAP_INFO = 0x105,
63};
64
65enum transfer_list_ops {
66 TL_OPS_NON, /* invalid for any operation */
67 TL_OPS_ALL, /* valid for all operations */
68 TL_OPS_RO, /* valid for read only */
69 TL_OPS_CUS, /* abort or switch to special code to interpret */
70};
71
72struct transfer_list_header {
73 uint32_t signature;
74 uint8_t checksum;
75 uint8_t version;
76 uint8_t hdr_size;
77 uint8_t alignment; /* max alignment of TE data */
78 uint32_t size; /* TL header + all TEs */
79 uint32_t max_size;
80 uint32_t flags;
81 uint32_t reserved; /* spare bytes */
82 /*
83 * Commented out element used to visualize dynamic part of the
84 * data structure.
85 *
86 * Note that struct transfer_list_entry also is dynamic in size
87 * so the elements can't be indexed directly but instead must be
88 * traversed in order
89 *
90 * struct transfer_list_entry entries[];
91 */
92};
93
94struct __attribute__((packed)) transfer_list_entry {
95 uint32_t tag_id : 24;
96 uint8_t hdr_size;
97 uint32_t data_size;
98 /*
99 * Commented out element used to visualize dynamic part of the
100 * data structure.
101 *
102 * Note that padding is added at the end of @data to make to reach
103 * a 8-byte boundary.
104 *
105 * uint8_t data[ROUNDUP(data_size, 8)];
106 */
107};
108
109static_assert(sizeof(struct transfer_list_entry) == 0x8U,
110 "assert_transfer_list_entry_size");
111
112void transfer_list_dump(struct transfer_list_header *tl);
113struct transfer_list_header *transfer_list_init(void *addr, size_t max_size);
114
115struct transfer_list_header *
116transfer_list_relocate(struct transfer_list_header *tl, void *addr,
117 size_t max_size);
118enum transfer_list_ops
119transfer_list_check_header(const struct transfer_list_header *tl);
120
121void transfer_list_update_checksum(struct transfer_list_header *tl);
122bool transfer_list_verify_checksum(const struct transfer_list_header *tl);
123
124bool transfer_list_set_data_size(struct transfer_list_header *tl,
125 struct transfer_list_entry *entry,
126 uint32_t new_data_size);
127
128void *transfer_list_entry_data(struct transfer_list_entry *entry);
129bool transfer_list_rem(struct transfer_list_header *tl,
130 struct transfer_list_entry *entry);
131
132struct transfer_list_entry *transfer_list_add(struct transfer_list_header *tl,
133 uint32_t tag_id,
134 uint32_t data_size,
135 const void *data);
136
137struct transfer_list_entry *
138transfer_list_add_with_align(struct transfer_list_header *tl, uint32_t tag_id,
139 uint32_t data_size, const void *data,
140 uint8_t alignment);
141
142struct transfer_list_entry *
143transfer_list_next(struct transfer_list_header *tl,
144 struct transfer_list_entry *last);
145
146struct transfer_list_entry *transfer_list_find(struct transfer_list_header *tl,
147 uint32_t tag_id);
148
149#endif /* __ASSEMBLER__ */
150#endif /* TRANSFER_LIST_H */