blob: c864526f16c355f01b3f9794ae8929e45df00aef [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 Mao1fccc722024-12-27 07:17:14 -080059 TL_TAG_TPM_EVLOG = 5,
Raymond Mao60c3c972023-10-04 09:19:16 -070060 TL_TAG_OPTEE_PAGABLE_PART = 0x100,
Harrison Mutai60438ee2023-12-01 14:57:57 +000061 TL_TAG_DT_SPMC_MANIFEST = 0x101,
62 TL_TAG_EXEC_EP_INFO64 = 0x102,
Harrison Mutai803d22b2024-01-04 16:25:47 +000063 TL_TAG_SRAM_LAYOUT64 = 0x104,
Harrison Mutai61aaf272024-11-06 14:21:00 +000064 TL_TAG_MBEDTLS_HEAP_INFO = 0x105,
Harrison Mutai802dc9e2024-12-16 12:52:29 +000065 TL_TAG_EXEC_EP_INFO32 = 0x106,
Raymond Mao98983392023-07-25 07:53:35 -070066};
67
68enum transfer_list_ops {
Raymond Mao60c3c972023-10-04 09:19:16 -070069 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 */
Raymond Mao98983392023-07-25 07:53:35 -070073};
74
75struct transfer_list_header {
Raymond Mao60c3c972023-10-04 09:19:16 -070076 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 */
Raymond Mao98983392023-07-25 07:53:35 -070085 /*
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
Harrison Mutai4490cd02024-03-20 14:37:51 +000097struct __attribute__((packed)) transfer_list_entry {
98 uint32_t tag_id : 24;
Raymond Mao60c3c972023-10-04 09:19:16 -070099 uint8_t hdr_size;
100 uint32_t data_size;
Raymond Mao98983392023-07-25 07:53:35 -0700101 /*
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
Harrison Mutai4490cd02024-03-20 14:37:51 +0000112CASSERT(sizeof(struct transfer_list_entry) == U(0x8), assert_transfer_list_entry_size);
113
Harrison Mutaicebad0e2024-12-13 09:14:59 +0000114void transfer_entry_dump(struct transfer_list_entry *te);
Raymond Mao98983392023-07-25 07:53:35 -0700115void transfer_list_dump(struct transfer_list_header *tl);
Harrison Mutaiae1f7802024-11-06 10:03:51 +0000116struct transfer_list_header *transfer_list_ensure(void *addr, size_t size);
Raymond Mao60c3c972023-10-04 09:19:16 -0700117entry_point_info_t *
118transfer_list_set_handoff_args(struct transfer_list_header *tl,
119 entry_point_info_t *ep_info);
Raymond Mao98983392023-07-25 07:53:35 -0700120struct transfer_list_header *transfer_list_init(void *addr, size_t max_size);
121
Raymond Mao60c3c972023-10-04 09:19:16 -0700122struct transfer_list_header *
123transfer_list_relocate(struct transfer_list_header *tl, void *addr,
124 size_t max_size);
125enum transfer_list_ops
126transfer_list_check_header(const struct transfer_list_header *tl);
Raymond Mao98983392023-07-25 07:53:35 -0700127
128void transfer_list_update_checksum(struct transfer_list_header *tl);
129bool transfer_list_verify_checksum(const struct transfer_list_header *tl);
130
131bool transfer_list_set_data_size(struct transfer_list_header *tl,
132 struct transfer_list_entry *entry,
133 uint32_t new_data_size);
134
135void *transfer_list_entry_data(struct transfer_list_entry *entry);
Raymond Mao60c3c972023-10-04 09:19:16 -0700136bool transfer_list_rem(struct transfer_list_header *tl,
137 struct transfer_list_entry *entry);
Raymond Mao98983392023-07-25 07:53:35 -0700138
139struct transfer_list_entry *transfer_list_add(struct transfer_list_header *tl,
Harrison Mutai4490cd02024-03-20 14:37:51 +0000140 uint32_t tag_id,
Raymond Mao60c3c972023-10-04 09:19:16 -0700141 uint32_t data_size,
Raymond Mao98983392023-07-25 07:53:35 -0700142 const void *data);
143
Raymond Mao60c3c972023-10-04 09:19:16 -0700144struct transfer_list_entry *
Harrison Mutai4490cd02024-03-20 14:37:51 +0000145transfer_list_add_with_align(struct transfer_list_header *tl, uint32_t tag_id,
Raymond Mao60c3c972023-10-04 09:19:16 -0700146 uint32_t data_size, const void *data,
147 uint8_t alignment);
Raymond Mao98983392023-07-25 07:53:35 -0700148
Raymond Mao60c3c972023-10-04 09:19:16 -0700149struct transfer_list_entry *
150transfer_list_next(struct transfer_list_header *tl,
151 struct transfer_list_entry *last);
Raymond Mao98983392023-07-25 07:53:35 -0700152
153struct transfer_list_entry *transfer_list_find(struct transfer_list_header *tl,
Harrison Mutai4490cd02024-03-20 14:37:51 +0000154 uint32_t tag_id);
Raymond Mao98983392023-07-25 07:53:35 -0700155
156#endif /*__ASSEMBLER__*/
157#endif /*__TRANSFER_LIST_H*/