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