blob: 325758e3cfe2c7bae8b160f84e29f49266313b69 [file] [log] [blame]
J-Alvese3e7c622024-11-13 10:42:32 +00001/*
2 * Copyright 2024 The Hafnium Authors.
3 *
4 * Use of this source code is governed by a BSD-style
5 * license that can be found in the LICENSE file or at
6 * https://opensource.org/licenses/BSD-3-Clause.
7 */
8
9/*
10 * Copyright (c) 2023-2024, Linaro Limited and Contributors. All rights
11 * reserved.
12 *
13 * SPDX-License-Identifier: BSD-3-Clause
14 */
15
16#pragma once
17
J-Alvese3e7c622024-11-13 10:42:32 +000018#include <stdint.h>
19
20#include "hf/arch/types.h"
21
J-Alvese3e7c622024-11-13 10:42:32 +000022#define TRANSFER_LIST_SIGNATURE 0x4a0fb10bU
23#define TRANSFER_LIST_VERSION 0x0001U
24
25/*
26 * Init value of maximum alignment required by any TE data in the TL
27 * specified as a power of two
28 */
29#define TRANSFER_LIST_INIT_MAX_ALIGN 3U
30
31/* Alignment required by TE header start address, in bytes */
32#define TRANSFER_LIST_GRANULE 8UL
33
34/*
35 * Version of the register convention used.
36 * Set to 1 for both AArch64 and AArch32 according to fw handoff spec v0.9
37 */
38#define REGISTER_CONVENTION_VERSION_SHIFT_64 32UL
39#define REGISTER_CONVENTION_VERSION_SHIFT_32 24UL
40#define REGISTER_CONVENTION_VERSION_MASK 0xffUL
41#define REGISTER_CONVENTION_VERSION 1UL
42
43#define TRANSFER_LIST_HANDOFF_X1_VALUE(__version) \
44 ((TRANSFER_LIST_SIGNATURE & \
45 ((1UL << REGISTER_CONVENTION_VERSION_SHIFT_64) - 1)) | \
46 (((__version) & REGISTER_CONVENTION_VERSION_MASK) \
47 << REGISTER_CONVENTION_VERSION_SHIFT_64))
48
49#define TRANSFER_LIST_HANDOFF_R1_VALUE(__version) \
50 ((TRANSFER_LIST_SIGNATURE & \
51 ((1UL << REGISTER_CONVENTION_VERSION_SHIFT_32) - 1)) | \
52 (((__version) & REGISTER_CONVENTION_VERSION_MASK) \
53 << REGISTER_CONVENTION_VERSION_SHIFT_32))
54
55#define TL_FLAGS_HAS_CHECKSUM (1U << 0)
56
57enum transfer_list_tag_id {
58 TL_TAG_EMPTY = 0,
59 TL_TAG_FDT = 1,
60 TL_TAG_HOB_BLOCK = 2,
61 TL_TAG_HOB_LIST = 3,
62 TL_TAG_ACPI_TABLE_AGGREGATE = 4,
63 TL_TAG_OPTEE_PAGABLE_PART = 0x100,
64 TL_TAG_DT_SPMC_MANIFEST = 0x101,
65 TL_TAG_EXEC_EP_INFO64 = 0x102,
J-Alves58bdd862024-12-09 14:49:02 +000066 TL_TAG_FFA_SP_BINARY = 0x103,
J-Alvese3e7c622024-11-13 10:42:32 +000067 TL_TAG_SRAM_LAYOUT64 = 0x104,
J-Alves58bdd862024-12-09 14:49:02 +000068 TL_TAG_DT_FFA_MANIFEST = 0x106,
J-Alvese3e7c622024-11-13 10:42:32 +000069};
70
71enum transfer_list_ops {
72 TL_OPS_NON, /* invalid for any operation */
73 TL_OPS_ALL, /* valid for all operations */
74 TL_OPS_RO, /* valid for read only */
75 TL_OPS_CUS, /* abort or switch to special code to interpret */
76};
77
78struct transfer_list_header {
79 uint32_t signature;
80 uint8_t checksum;
81 uint8_t version;
82 uint8_t hdr_size;
83
84 /* max alignment of TE data */
85 uint8_t alignment;
86
87 /* TL header + all TEs */
88 uint32_t size;
89 uint32_t max_size;
90 uint32_t flags;
91
92 /* Spare bytes */
93 uint32_t reserved;
94
95 /*
96 * Commented out element used to visualize dynamic part of the
97 * data structure.
98 *
99 * Note that struct transfer_list_entry also is dynamic in size
100 * so the elements can't be indexed directly but instead must be
101 * traversed in order
102 *
103 * struct transfer_list_entry entries[];
104 */
105};
106
107struct transfer_list_entry {
108 uint32_t tag_id : 24;
109 uint8_t hdr_size;
110 uint32_t data_size;
111 /*
112 * Commented out element used to visualize dynamic part of the
113 * data structure.
114 *
115 * Note that padding is added at the end of @data to make to reach
116 * a 8-byte boundary.
117 *
118 * uint8_t data[ROUNDUP(data_size, 8)];
119 */
120};
121
122static_assert(sizeof(struct transfer_list_entry) == 0x8U,
123 "transfer_list_entry size expected to be 0x8.");
124
125void transfer_list_dump(struct transfer_list_header *tl);
126
127enum transfer_list_ops transfer_list_check_header(
128 const struct transfer_list_header *tl);
129
130void transfer_list_update_checksum(struct transfer_list_header *tl);
131bool transfer_list_verify_checksum(const struct transfer_list_header *tl);
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_next(
138 struct transfer_list_header *tl, struct transfer_list_entry *last);
139
140struct transfer_list_entry *transfer_list_find(struct transfer_list_header *tl,
141 uint32_t tag_id);