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