Marc Bonnici | 9f23c8d | 2021-10-01 16:06:04 +0100 | [diff] [blame] | 1 | /* |
Demi Marie Obenour | 2b2e652 | 2022-12-30 19:13:15 -0500 | [diff] [blame] | 2 | * Copyright (c) 2022-2023, ARM Limited and Contributors. All rights reserved. |
Marc Bonnici | 9f23c8d | 2021-10-01 16:06:04 +0100 | [diff] [blame] | 3 | * |
| 4 | * SPDX-License-Identifier: BSD-3-Clause |
| 5 | */ |
| 6 | |
| 7 | #ifndef EL3_SPMC_FFA_MEM_H |
| 8 | #define EL3_SPMC_FFA_MEM_H |
| 9 | |
| 10 | #include <assert.h> |
| 11 | |
| 12 | /* |
| 13 | * Subset of Arm Firmware Framework for Armv8-A |
| 14 | * (https://developer.arm.com/docs/den0077/a) needed for shared memory. |
| 15 | */ |
| 16 | |
| 17 | /** |
| 18 | * typedef ffa_endpoint_id16_t - Endpoint ID |
| 19 | * |
| 20 | * Current implementation only supports VM IDs. FF-A spec also support stream |
| 21 | * endpoint ids. |
| 22 | */ |
| 23 | typedef uint16_t ffa_endpoint_id16_t; |
| 24 | |
| 25 | /** |
| 26 | * struct ffa_cons_mrd - Constituent memory region descriptor |
| 27 | * @address: |
| 28 | * Start address of contiguous memory region. Must be 4K page aligned. |
| 29 | * @page_count: |
| 30 | * Number of 4K pages in region. |
| 31 | * @reserved_12_15: |
| 32 | * Reserve bytes 12-15 to pad struct size to 16 bytes. |
| 33 | */ |
| 34 | struct ffa_cons_mrd { |
| 35 | uint64_t address; |
| 36 | uint32_t page_count; |
| 37 | uint32_t reserved_12_15; |
| 38 | }; |
| 39 | CASSERT(sizeof(struct ffa_cons_mrd) == 16, assert_ffa_cons_mrd_size_mismatch); |
| 40 | |
| 41 | /** |
| 42 | * struct ffa_comp_mrd - Composite memory region descriptor |
| 43 | * @total_page_count: |
| 44 | * Number of 4k pages in memory region. Must match sum of |
| 45 | * @address_range_array[].page_count. |
| 46 | * @address_range_count: |
| 47 | * Number of entries in @address_range_array. |
| 48 | * @reserved_8_15: |
| 49 | * Reserve bytes 8-15 to pad struct size to 16 byte alignment and |
| 50 | * make @address_range_array 16 byte aligned. |
| 51 | * @address_range_array: |
| 52 | * Array of &struct ffa_cons_mrd entries. |
| 53 | */ |
| 54 | struct ffa_comp_mrd { |
| 55 | uint32_t total_page_count; |
| 56 | uint32_t address_range_count; |
| 57 | uint64_t reserved_8_15; |
| 58 | struct ffa_cons_mrd address_range_array[]; |
| 59 | }; |
| 60 | CASSERT(sizeof(struct ffa_comp_mrd) == 16, assert_ffa_comp_mrd_size_mismatch); |
| 61 | |
| 62 | /** |
Marc Bonnici | d1907f0 | 2022-04-19 17:42:53 +0100 | [diff] [blame] | 63 | * typedef ffa_mem_attr8_t - Memory region attributes v1.0. |
| 64 | * typedef ffa_mem_attr16_t - Memory region attributes v1.1. |
Marc Bonnici | 9f23c8d | 2021-10-01 16:06:04 +0100 | [diff] [blame] | 65 | * |
Marc Bonnici | 08f28ef | 2022-04-19 16:52:59 +0100 | [diff] [blame] | 66 | * * @FFA_MEM_ATTR_NS_BIT: |
| 67 | * Memory security state. |
Marc Bonnici | 9f23c8d | 2021-10-01 16:06:04 +0100 | [diff] [blame] | 68 | * * @FFA_MEM_ATTR_DEVICE_NGNRNE: |
| 69 | * Device-nGnRnE. |
| 70 | * * @FFA_MEM_ATTR_DEVICE_NGNRE: |
| 71 | * Device-nGnRE. |
| 72 | * * @FFA_MEM_ATTR_DEVICE_NGRE: |
| 73 | * Device-nGRE. |
| 74 | * * @FFA_MEM_ATTR_DEVICE_GRE: |
| 75 | * Device-GRE. |
| 76 | * * @FFA_MEM_ATTR_NORMAL_MEMORY_UNCACHED |
| 77 | * Normal memory. Non-cacheable. |
| 78 | * * @FFA_MEM_ATTR_NORMAL_MEMORY_CACHED_WB |
| 79 | * Normal memory. Write-back cached. |
| 80 | * * @FFA_MEM_ATTR_NON_SHAREABLE |
| 81 | * Non-shareable. Combine with FFA_MEM_ATTR_NORMAL_MEMORY_*. |
| 82 | * * @FFA_MEM_ATTR_OUTER_SHAREABLE |
| 83 | * Outer Shareable. Combine with FFA_MEM_ATTR_NORMAL_MEMORY_*. |
| 84 | * * @FFA_MEM_ATTR_INNER_SHAREABLE |
| 85 | * Inner Shareable. Combine with FFA_MEM_ATTR_NORMAL_MEMORY_*. |
| 86 | */ |
| 87 | typedef uint8_t ffa_mem_attr8_t; |
Marc Bonnici | d1907f0 | 2022-04-19 17:42:53 +0100 | [diff] [blame] | 88 | typedef uint16_t ffa_mem_attr16_t; |
Marc Bonnici | 08f28ef | 2022-04-19 16:52:59 +0100 | [diff] [blame] | 89 | #define FFA_MEM_ATTR_NS_BIT (0x1U << 6) |
Marc Bonnici | 9f23c8d | 2021-10-01 16:06:04 +0100 | [diff] [blame] | 90 | #define FFA_MEM_ATTR_DEVICE_NGNRNE ((1U << 4) | (0x0U << 2)) |
| 91 | #define FFA_MEM_ATTR_DEVICE_NGNRE ((1U << 4) | (0x1U << 2)) |
| 92 | #define FFA_MEM_ATTR_DEVICE_NGRE ((1U << 4) | (0x2U << 2)) |
| 93 | #define FFA_MEM_ATTR_DEVICE_GRE ((1U << 4) | (0x3U << 2)) |
| 94 | #define FFA_MEM_ATTR_NORMAL_MEMORY_UNCACHED ((2U << 4) | (0x1U << 2)) |
| 95 | #define FFA_MEM_ATTR_NORMAL_MEMORY_CACHED_WB ((2U << 4) | (0x3U << 2)) |
| 96 | #define FFA_MEM_ATTR_NON_SHAREABLE (0x0U << 0) |
| 97 | #define FFA_MEM_ATTR_OUTER_SHAREABLE (0x2U << 0) |
| 98 | #define FFA_MEM_ATTR_INNER_SHAREABLE (0x3U << 0) |
| 99 | |
| 100 | /** |
| 101 | * typedef ffa_mem_perm8_t - Memory access permissions |
| 102 | * |
| 103 | * * @FFA_MEM_ATTR_RO |
| 104 | * Request or specify read-only mapping. |
| 105 | * * @FFA_MEM_ATTR_RW |
| 106 | * Request or allow read-write mapping. |
| 107 | * * @FFA_MEM_PERM_NX |
| 108 | * Deny executable mapping. |
| 109 | * * @FFA_MEM_PERM_X |
| 110 | * Request executable mapping. |
| 111 | */ |
| 112 | typedef uint8_t ffa_mem_perm8_t; |
| 113 | #define FFA_MEM_PERM_RO (1U << 0) |
| 114 | #define FFA_MEM_PERM_RW (1U << 1) |
| 115 | #define FFA_MEM_PERM_NX (1U << 2) |
| 116 | #define FFA_MEM_PERM_X (1U << 3) |
| 117 | |
| 118 | /** |
| 119 | * typedef ffa_mem_flag8_t - Endpoint memory flags |
| 120 | * |
| 121 | * * @FFA_MEM_FLAG_NON_RETRIEVAL_BORROWER |
| 122 | * Non-retrieval Borrower. Memory region must not be or was not retrieved on |
| 123 | * behalf of this endpoint. |
| 124 | */ |
| 125 | typedef uint8_t ffa_mem_flag8_t; |
| 126 | #define FFA_MEM_FLAG_NON_RETRIEVAL_BORROWER (1U << 0) |
| 127 | |
| 128 | /** |
| 129 | * typedef ffa_mtd_flag32_t - Memory transaction descriptor flags |
| 130 | * |
| 131 | * * @FFA_MTD_FLAG_ZERO_MEMORY |
| 132 | * Zero memory after unmapping from sender (must be 0 for share). |
| 133 | * * @FFA_MTD_FLAG_TIME_SLICING |
| 134 | * Not supported by this implementation. |
| 135 | * * @FFA_MTD_FLAG_ZERO_MEMORY_AFTER_RELINQUISH |
| 136 | * Zero memory after unmapping from borrowers (must be 0 for share). |
| 137 | * * @FFA_MTD_FLAG_TYPE_MASK |
| 138 | * Bit-mask to extract memory management transaction type from flags. |
| 139 | * * @FFA_MTD_FLAG_TYPE_SHARE_MEMORY |
| 140 | * Share memory transaction flag. |
| 141 | * Used by @SMC_FC_FFA_MEM_RETRIEVE_RESP to indicate that memory came from |
| 142 | * @SMC_FC_FFA_MEM_SHARE and by @SMC_FC_FFA_MEM_RETRIEVE_REQ to specify that |
| 143 | * it must have. |
| 144 | * * @FFA_MTD_FLAG_ADDRESS_RANGE_ALIGNMENT_HINT_MASK |
| 145 | * Not supported by this implementation. |
| 146 | */ |
| 147 | typedef uint32_t ffa_mtd_flag32_t; |
| 148 | #define FFA_MTD_FLAG_ZERO_MEMORY (1U << 0) |
| 149 | #define FFA_MTD_FLAG_TIME_SLICING (1U << 1) |
| 150 | #define FFA_MTD_FLAG_ZERO_MEMORY_AFTER_RELINQUISH (1U << 2) |
| 151 | #define FFA_MTD_FLAG_TYPE_MASK (3U << 3) |
| 152 | #define FFA_MTD_FLAG_TYPE_SHARE_MEMORY (1U << 3) |
| 153 | #define FFA_MTD_FLAG_TYPE_LEND_MEMORY (1U << 4) |
| 154 | #define FFA_MTD_FLAG_ADDRESS_RANGE_ALIGNMENT_HINT_MASK (0x1FU << 5) |
| 155 | |
| 156 | /** |
| 157 | * struct ffa_mapd - Memory access permissions descriptor |
| 158 | * @endpoint_id: |
| 159 | * Endpoint id that @memory_access_permissions and @flags apply to. |
| 160 | * (&typedef ffa_endpoint_id16_t). |
| 161 | * @memory_access_permissions: |
| 162 | * FFA_MEM_PERM_* values or'ed together (&typedef ffa_mem_perm8_t). |
| 163 | * @flags: |
| 164 | * FFA_MEM_FLAG_* values or'ed together (&typedef ffa_mem_flag8_t). |
| 165 | */ |
| 166 | struct ffa_mapd { |
| 167 | ffa_endpoint_id16_t endpoint_id; |
| 168 | ffa_mem_perm8_t memory_access_permissions; |
| 169 | ffa_mem_flag8_t flags; |
| 170 | }; |
| 171 | CASSERT(sizeof(struct ffa_mapd) == 4, assert_ffa_mapd_size_mismatch); |
| 172 | |
| 173 | /** |
| 174 | * struct ffa_emad_v1_0 - Endpoint memory access descriptor. |
| 175 | * @mapd: &struct ffa_mapd. |
| 176 | * @comp_mrd_offset: |
| 177 | * Offset of &struct ffa_comp_mrd from start of &struct ffa_mtd_v1_0. |
| 178 | * @reserved_8_15: |
| 179 | * Reserved bytes 8-15. Must be 0. |
| 180 | */ |
| 181 | struct ffa_emad_v1_0 { |
| 182 | struct ffa_mapd mapd; |
| 183 | uint32_t comp_mrd_offset; |
| 184 | uint64_t reserved_8_15; |
| 185 | }; |
| 186 | CASSERT(sizeof(struct ffa_emad_v1_0) == 16, assert_ffa_emad_v1_0_size_mismatch); |
| 187 | |
| 188 | /** |
| 189 | * struct ffa_mtd_v1_0 - Memory transaction descriptor. |
| 190 | * @sender_id: |
| 191 | * Sender endpoint id. |
| 192 | * @memory_region_attributes: |
| 193 | * FFA_MEM_ATTR_* values or'ed together (&typedef ffa_mem_attr8_t). |
| 194 | * @reserved_3: |
| 195 | * Reserved bytes 3. Must be 0. |
| 196 | * @flags: |
| 197 | * FFA_MTD_FLAG_* values or'ed together (&typedef ffa_mtd_flag32_t). |
| 198 | * @handle: |
| 199 | * Id of shared memory object. Must be 0 for MEM_SHARE or MEM_LEND. |
| 200 | * @tag: Client allocated tag. Must match original value. |
| 201 | * @reserved_24_27: |
| 202 | * Reserved bytes 24-27. Must be 0. |
| 203 | * @emad_count: |
Marc Bonnici | 336630f | 2022-01-13 11:39:10 +0000 | [diff] [blame] | 204 | * Number of entries in @emad. |
Marc Bonnici | 9f23c8d | 2021-10-01 16:06:04 +0100 | [diff] [blame] | 205 | * @emad: |
| 206 | * Endpoint memory access descriptor array (see @struct ffa_emad_v1_0). |
| 207 | */ |
| 208 | struct ffa_mtd_v1_0 { |
| 209 | ffa_endpoint_id16_t sender_id; |
| 210 | ffa_mem_attr8_t memory_region_attributes; |
| 211 | uint8_t reserved_3; |
| 212 | ffa_mtd_flag32_t flags; |
| 213 | uint64_t handle; |
| 214 | uint64_t tag; |
| 215 | uint32_t reserved_24_27; |
| 216 | uint32_t emad_count; |
| 217 | struct ffa_emad_v1_0 emad[]; |
| 218 | }; |
| 219 | CASSERT(sizeof(struct ffa_mtd_v1_0) == 32, assert_ffa_mtd_size_v1_0_mismatch); |
Demi Marie Obenour | 4ed9df4 | 2022-12-30 19:30:58 -0500 | [diff] [blame] | 220 | CASSERT(offsetof(struct ffa_mtd_v1_0, emad) == 32, |
| 221 | assert_ffa_mtd_size_v1_0_mismatch_2); |
Marc Bonnici | 9f23c8d | 2021-10-01 16:06:04 +0100 | [diff] [blame] | 222 | |
Marc Bonnici | d1907f0 | 2022-04-19 17:42:53 +0100 | [diff] [blame] | 223 | /** |
| 224 | * struct ffa_mtd - Memory transaction descriptor for FF-A v1.1. |
| 225 | * @sender_id: |
| 226 | * Sender endpoint id. |
| 227 | * @memory_region_attributes: |
| 228 | * FFA_MEM_ATTR_* values or'ed together (&typedef ffa_mem_attr16_t). |
| 229 | * @flags: |
| 230 | * FFA_MTD_FLAG_* values or'ed together (&typedef ffa_mtd_flag32_t). |
| 231 | * @handle: |
| 232 | * Id of shared memory object. Must be 0 for MEM_SHARE or MEM_LEND. |
| 233 | * @tag: Client allocated tag. Must match original value. |
| 234 | * @emad_size: |
| 235 | * Size of the emad descriptor. |
| 236 | * @emad_count: |
| 237 | * Number of entries in the emad array. |
| 238 | * @emad_offset: |
| 239 | * Offset from the beginning of the descriptor to the location of the |
| 240 | * memory access descriptor array (see @struct ffa_emad_v1_0). |
| 241 | * @reserved_36_39: |
| 242 | * Reserved bytes 36-39. Must be 0. |
| 243 | * @reserved_40_47: |
| 244 | * Reserved bytes 44-47. Must be 0. |
| 245 | */ |
| 246 | struct ffa_mtd { |
| 247 | ffa_endpoint_id16_t sender_id; |
| 248 | ffa_mem_attr16_t memory_region_attributes; |
| 249 | ffa_mtd_flag32_t flags; |
| 250 | uint64_t handle; |
| 251 | uint64_t tag; |
| 252 | uint32_t emad_size; |
| 253 | uint32_t emad_count; |
| 254 | uint32_t emad_offset; |
| 255 | uint32_t reserved_36_39; |
| 256 | uint64_t reserved_40_47; |
| 257 | }; |
| 258 | CASSERT(sizeof(struct ffa_mtd) == 48, assert_ffa_mtd_size_mismatch); |
Demi Marie Obenour | 2b2e652 | 2022-12-30 19:13:15 -0500 | [diff] [blame] | 259 | CASSERT(offsetof(struct ffa_mtd, emad_count) == |
| 260 | offsetof(struct ffa_mtd_v1_0, emad_count), |
| 261 | assert_ffa_mtd_emad_count_offset_mismatch); |
Marc Bonnici | d1907f0 | 2022-04-19 17:42:53 +0100 | [diff] [blame] | 262 | |
Marc Bonnici | 9f23c8d | 2021-10-01 16:06:04 +0100 | [diff] [blame] | 263 | #endif /* EL3_SPMC_FFA_MEM_H */ |