blob: 1b5ec2d63b24a998ae6c4a6a7e89f2998a8f65e7 [file] [log] [blame]
Raymond Mao98983392023-07-25 07:53:35 -07001/*
Harrison Mutai60438ee2023-12-01 14:57:57 +00002 * Copyright (c) 2023-2024, Linaro Limited and Contributors. All rights reserved.
Raymond Mao98983392023-07-25 07:53:35 -07003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef __TRANSFER_LIST_H
8#define __TRANSFER_LIST_H
9
10#include <stdbool.h>
11#include <stdint.h>
12
Raymond Mao60c3c972023-10-04 09:19:16 -070013#include <common/ep_info.h>
Raymond Mao98983392023-07-25 07:53:35 -070014#include <lib/utils_def.h>
15
Raymond Mao60c3c972023-10-04 09:19:16 -070016#define TRANSFER_LIST_SIGNATURE U(0x4a0fb10b)
17#define TRANSFER_LIST_VERSION U(0x0001)
Raymond Mao98983392023-07-25 07:53:35 -070018
Raymond Mao60c3c972023-10-04 09:19:16 -070019/*
20 * Init value of maximum alignment required by any TE data in the TL
21 * specified as a power of two
22 */
23#define TRANSFER_LIST_INIT_MAX_ALIGN U(3)
Raymond Mao98983392023-07-25 07:53:35 -070024
Raymond Mao60c3c972023-10-04 09:19:16 -070025/* Alignment required by TE header start address, in bytes */
26#define TRANSFER_LIST_GRANULE U(8)
Raymond Mao98983392023-07-25 07:53:35 -070027
Raymond Mao60c3c972023-10-04 09:19:16 -070028/*
29 * Version of the register convention used.
30 * Set to 1 for both AArch64 and AArch32 according to fw handoff spec v0.9
31 */
levi.yun010d2ae2024-05-13 10:27:17 +010032#define REGISTER_CONVENTION_VERSION_SHIFT_64 UL(32)
33#define REGISTER_CONVENTION_VERSION_SHIFT_32 UL(24)
34#define REGISTER_CONVENTION_VERSION_MASK UL(0xff)
35#define REGISTER_CONVENTION_VERSION UL(1)
36
37#define TRANSFER_LIST_HANDOFF_X1_VALUE(__version) \
38 ((TRANSFER_LIST_SIGNATURE & \
39 ((1UL << REGISTER_CONVENTION_VERSION_SHIFT_64) - 1)) | \
40 (((__version) & REGISTER_CONVENTION_VERSION_MASK) << \
41 REGISTER_CONVENTION_VERSION_SHIFT_64))
42
43#define TRANSFER_LIST_HANDOFF_R1_VALUE(__version) \
44 ((TRANSFER_LIST_SIGNATURE & \
45 ((1UL << REGISTER_CONVENTION_VERSION_SHIFT_32) - 1)) | \
46 (((__version) & REGISTER_CONVENTION_VERSION_MASK) << \
47 REGISTER_CONVENTION_VERSION_SHIFT_32))
Raymond Mao98983392023-07-25 07:53:35 -070048
49#ifndef __ASSEMBLER__
50
Raymond Mao60c3c972023-10-04 09:19:16 -070051#define TL_FLAGS_HAS_CHECKSUM BIT(0)
52
Raymond Mao98983392023-07-25 07:53:35 -070053enum transfer_list_tag_id {
54 TL_TAG_EMPTY = 0,
55 TL_TAG_FDT = 1,
56 TL_TAG_HOB_BLOCK = 2,
57 TL_TAG_HOB_LIST = 3,
58 TL_TAG_ACPI_TABLE_AGGREGATE = 4,
Raymond Mao60c3c972023-10-04 09:19:16 -070059 TL_TAG_OPTEE_PAGABLE_PART = 0x100,
Harrison Mutai60438ee2023-12-01 14:57:57 +000060 TL_TAG_DT_SPMC_MANIFEST = 0x101,
61 TL_TAG_EXEC_EP_INFO64 = 0x102,
Harrison Mutai803d22b2024-01-04 16:25:47 +000062 TL_TAG_TB_FW_CONFIG = 0x103,
63 TL_TAG_SRAM_LAYOUT64 = 0x104,
Raymond Mao98983392023-07-25 07:53:35 -070064};
65
66enum transfer_list_ops {
Raymond Mao60c3c972023-10-04 09:19:16 -070067 TL_OPS_NON, /* invalid for any operation */
68 TL_OPS_ALL, /* valid for all operations */
69 TL_OPS_RO, /* valid for read only */
70 TL_OPS_CUS, /* abort or switch to special code to interpret */
Raymond Mao98983392023-07-25 07:53:35 -070071};
72
73struct transfer_list_header {
Raymond Mao60c3c972023-10-04 09:19:16 -070074 uint32_t signature;
75 uint8_t checksum;
76 uint8_t version;
77 uint8_t hdr_size;
78 uint8_t alignment; /* max alignment of TE data */
79 uint32_t size; /* TL header + all TEs */
80 uint32_t max_size;
81 uint32_t flags;
82 uint32_t reserved; /* spare bytes */
Raymond Mao98983392023-07-25 07:53:35 -070083 /*
84 * Commented out element used to visualize dynamic part of the
85 * data structure.
86 *
87 * Note that struct transfer_list_entry also is dynamic in size
88 * so the elements can't be indexed directly but instead must be
89 * traversed in order
90 *
91 * struct transfer_list_entry entries[];
92 */
93};
94
Harrison Mutai4490cd02024-03-20 14:37:51 +000095struct __attribute__((packed)) transfer_list_entry {
96 uint32_t tag_id : 24;
Raymond Mao60c3c972023-10-04 09:19:16 -070097 uint8_t hdr_size;
98 uint32_t data_size;
Raymond Mao98983392023-07-25 07:53:35 -070099 /*
100 * Commented out element used to visualize dynamic part of the
101 * data structure.
102 *
103 * Note that padding is added at the end of @data to make to reach
104 * a 8-byte boundary.
105 *
106 * uint8_t data[ROUNDUP(data_size, 8)];
107 */
108};
109
Harrison Mutai4490cd02024-03-20 14:37:51 +0000110CASSERT(sizeof(struct transfer_list_entry) == U(0x8), assert_transfer_list_entry_size);
111
Raymond Mao98983392023-07-25 07:53:35 -0700112void transfer_list_dump(struct transfer_list_header *tl);
Raymond Mao60c3c972023-10-04 09:19:16 -0700113entry_point_info_t *
114transfer_list_set_handoff_args(struct transfer_list_header *tl,
115 entry_point_info_t *ep_info);
Raymond Mao98983392023-07-25 07:53:35 -0700116struct transfer_list_header *transfer_list_init(void *addr, size_t max_size);
117
Raymond Mao60c3c972023-10-04 09:19:16 -0700118struct transfer_list_header *
119transfer_list_relocate(struct transfer_list_header *tl, void *addr,
120 size_t max_size);
121enum transfer_list_ops
122transfer_list_check_header(const struct transfer_list_header *tl);
Raymond Mao98983392023-07-25 07:53:35 -0700123
124void transfer_list_update_checksum(struct transfer_list_header *tl);
125bool transfer_list_verify_checksum(const struct transfer_list_header *tl);
126
127bool transfer_list_set_data_size(struct transfer_list_header *tl,
128 struct transfer_list_entry *entry,
129 uint32_t new_data_size);
130
131void *transfer_list_entry_data(struct transfer_list_entry *entry);
Raymond Mao60c3c972023-10-04 09:19:16 -0700132bool transfer_list_rem(struct transfer_list_header *tl,
133 struct transfer_list_entry *entry);
Raymond Mao98983392023-07-25 07:53:35 -0700134
135struct transfer_list_entry *transfer_list_add(struct transfer_list_header *tl,
Harrison Mutai4490cd02024-03-20 14:37:51 +0000136 uint32_t tag_id,
Raymond Mao60c3c972023-10-04 09:19:16 -0700137 uint32_t data_size,
Raymond Mao98983392023-07-25 07:53:35 -0700138 const void *data);
139
Raymond Mao60c3c972023-10-04 09:19:16 -0700140struct transfer_list_entry *
Harrison Mutai4490cd02024-03-20 14:37:51 +0000141transfer_list_add_with_align(struct transfer_list_header *tl, uint32_t tag_id,
Raymond Mao60c3c972023-10-04 09:19:16 -0700142 uint32_t data_size, const void *data,
143 uint8_t alignment);
Raymond Mao98983392023-07-25 07:53:35 -0700144
Raymond Mao60c3c972023-10-04 09:19:16 -0700145struct transfer_list_entry *
146transfer_list_next(struct transfer_list_header *tl,
147 struct transfer_list_entry *last);
Raymond Mao98983392023-07-25 07:53:35 -0700148
149struct transfer_list_entry *transfer_list_find(struct transfer_list_header *tl,
Harrison Mutai4490cd02024-03-20 14:37:51 +0000150 uint32_t tag_id);
Raymond Mao98983392023-07-25 07:53:35 -0700151
152#endif /*__ASSEMBLER__*/
153#endif /*__TRANSFER_LIST_H*/