blob: fdbf70e595e9f313ef90f364aa621f948e2a6f0c [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,
69 TL_TAG_TB_FW_CONFIG = 0x103,
70 TL_TAG_SRAM_LAYOUT64 = 0x104,
71};
72
73enum transfer_list_ops {
74 TL_OPS_NON, /* invalid for any operation */
75 TL_OPS_ALL, /* valid for all operations */
76 TL_OPS_RO, /* valid for read only */
77 TL_OPS_CUS, /* abort or switch to special code to interpret */
78};
79
80struct transfer_list_header {
81 uint32_t signature;
82 uint8_t checksum;
83 uint8_t version;
84 uint8_t hdr_size;
85
86 /* max alignment of TE data */
87 uint8_t alignment;
88
89 /* TL header + all TEs */
90 uint32_t size;
91 uint32_t max_size;
92 uint32_t flags;
93
94 /* Spare bytes */
95 uint32_t reserved;
96
97 /*
98 * Commented out element used to visualize dynamic part of the
99 * data structure.
100 *
101 * Note that struct transfer_list_entry also is dynamic in size
102 * so the elements can't be indexed directly but instead must be
103 * traversed in order
104 *
105 * struct transfer_list_entry entries[];
106 */
107};
108
109struct transfer_list_entry {
110 uint32_t tag_id : 24;
111 uint8_t hdr_size;
112 uint32_t data_size;
113 /*
114 * Commented out element used to visualize dynamic part of the
115 * data structure.
116 *
117 * Note that padding is added at the end of @data to make to reach
118 * a 8-byte boundary.
119 *
120 * uint8_t data[ROUNDUP(data_size, 8)];
121 */
122};
123
124static_assert(sizeof(struct transfer_list_entry) == 0x8U,
125 "transfer_list_entry size expected to be 0x8.");
126
127void transfer_list_dump(struct transfer_list_header *tl);
128
129enum transfer_list_ops transfer_list_check_header(
130 const struct transfer_list_header *tl);
131
132void transfer_list_update_checksum(struct transfer_list_header *tl);
133bool transfer_list_verify_checksum(const struct transfer_list_header *tl);
134
135void *transfer_list_entry_data(struct transfer_list_entry *entry);
136bool transfer_list_rem(struct transfer_list_header *tl,
137 struct transfer_list_entry *entry);
138
139struct transfer_list_entry *transfer_list_next(
140 struct transfer_list_header *tl, struct transfer_list_entry *last);
141
142struct transfer_list_entry *transfer_list_find(struct transfer_list_header *tl,
143 uint32_t tag_id);