1 /* 2 * Copyright (c) 2023, Linaro Limited and Contributors. All rights reserved. 3 * 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 13 #include <lib/utils_def.h> 14 15 #define TRANSFER_LIST_SIGNATURE U(0x006ed0ff) 16 #define TRANSFER_LIST_VERSION U(0x0001) 17 18 // Init value of maximum alignment required by any TE data in the TL 19 // specified as a power of two 20 #define TRANSFER_LIST_INIT_MAX_ALIGN U(3) 21 22 // alignment required by TE header start address, in bytes 23 #define TRANSFER_LIST_GRANULE U(8) 24 25 // version of the register convention used. 26 // Set to 1 for both AArch64 and AArch32 according to fw handoff spec v0.9 27 #define REGISTER_CONVENTION_VERSION_MASK (1 << 24) 28 29 #ifndef __ASSEMBLER__ 30 31 enum transfer_list_tag_id { 32 TL_TAG_EMPTY = 0, 33 TL_TAG_FDT = 1, 34 TL_TAG_HOB_BLOCK = 2, 35 TL_TAG_HOB_LIST = 3, 36 TL_TAG_ACPI_TABLE_AGGREGATE = 4, 37 }; 38 39 enum transfer_list_ops { 40 TL_OPS_NON, // invalid for any operation 41 TL_OPS_ALL, // valid for all operations 42 TL_OPS_RO, // valid for read only 43 TL_OPS_CUS, // either abort or switch to special code to interpret 44 }; 45 46 struct transfer_list_header { 47 uint32_t signature; 48 uint8_t checksum; 49 uint8_t version; 50 uint8_t hdr_size; 51 uint8_t alignment; // max alignment of TE data 52 uint32_t size; // TL header + all TEs 53 uint32_t max_size; 54 /* 55 * Commented out element used to visualize dynamic part of the 56 * data structure. 57 * 58 * Note that struct transfer_list_entry also is dynamic in size 59 * so the elements can't be indexed directly but instead must be 60 * traversed in order 61 * 62 * struct transfer_list_entry entries[]; 63 */ 64 }; 65 66 struct transfer_list_entry { 67 uint16_t tag_id; 68 uint8_t reserved0; // place holder 69 uint8_t hdr_size; 70 uint32_t data_size; 71 /* 72 * Commented out element used to visualize dynamic part of the 73 * data structure. 74 * 75 * Note that padding is added at the end of @data to make to reach 76 * a 8-byte boundary. 77 * 78 * uint8_t data[ROUNDUP(data_size, 8)]; 79 */ 80 }; 81 82 void transfer_list_dump(struct transfer_list_header *tl); 83 struct transfer_list_header *transfer_list_init(void *addr, size_t max_size); 84 85 struct transfer_list_header *transfer_list_relocate(struct transfer_list_header *tl, 86 void *addr, size_t max_size); 87 enum transfer_list_ops transfer_list_check_header(const struct transfer_list_header *tl); 88 89 void transfer_list_update_checksum(struct transfer_list_header *tl); 90 bool transfer_list_verify_checksum(const struct transfer_list_header *tl); 91 92 bool transfer_list_set_data_size(struct transfer_list_header *tl, 93 struct transfer_list_entry *entry, 94 uint32_t new_data_size); 95 96 void *transfer_list_entry_data(struct transfer_list_entry *entry); 97 bool transfer_list_rem(struct transfer_list_header *tl, struct transfer_list_entry *entry); 98 99 struct transfer_list_entry *transfer_list_add(struct transfer_list_header *tl, 100 uint16_t tag_id, uint32_t data_size, 101 const void *data); 102 103 struct transfer_list_entry *transfer_list_add_with_align(struct transfer_list_header *tl, 104 uint16_t tag_id, uint32_t data_size, 105 const void *data, uint8_t alignment); 106 107 struct transfer_list_entry *transfer_list_next(struct transfer_list_header *tl, 108 struct transfer_list_entry *last); 109 110 struct transfer_list_entry *transfer_list_find(struct transfer_list_header *tl, 111 uint16_t tag_id); 112 113 #endif /*__ASSEMBLER__*/ 114 #endif /*__TRANSFER_LIST_H*/ 115