1 /* SPDX-License-Identifier: BSD-3-Clause */ 2 /* 3 * Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved. 4 */ 5 6 #ifndef LIBSP_INCLUDE_SP_MEMORY_MANAGEMENT_H_ 7 #define LIBSP_INCLUDE_SP_MEMORY_MANAGEMENT_H_ 8 9 /** 10 * @file sp_memory_management.h 11 * @brief The file contains wrapper functions around the FF-A interfaces 12 * described in section 8 of the specification. 13 */ 14 15 #include "ffa_memory_descriptors.h" 16 #include "sp_api_defines.h" 17 #include "sp_api_types.h" 18 #include <stdbool.h> 19 #include <stddef.h> 20 #include <stdint.h> 21 22 #ifdef __cplusplus 23 extern "C" { 24 #endif 25 26 #if CFG_FFA_VERSION >= FFA_VERSION_1_1 27 /** 28 * @brief Security state of the memory region 29 */ 30 enum sp_memory_security_state { 31 sp_memory_security_state_secure = 0x00, 32 sp_memory_security_state_non_secure = 0x01, 33 }; 34 #endif /* CFG_FFA_VERSION */ 35 36 /** 37 * @brief Memory type of the region 38 */ 39 enum sp_memory_type { 40 sp_memory_type_not_specified = 0x00, /**< Not specified */ 41 sp_memory_type_device_memory = 0x01, /**< Device memory */ 42 sp_memory_type_normal_memory = 0x02, /**< Normal memory */ 43 sp_memory_type_reserved = 0x03 /**< Reserved */ 44 }; 45 46 /** 47 * @brief Cacheability attribute of the memory region 48 */ 49 enum sp_cacheability_attribute { 50 sp_cacheability_reserved0 = 0x00, /**< Reserved */ 51 sp_cacheability_non_cacheable = 0x01, /**< Non-cacheable */ 52 sp_cacheability_reserved2 = 0x02, /**< Reserved */ 53 sp_cacheability_write_back = 0x03 /**< Write-back */ 54 }; 55 56 /** 57 * @brief Device memory attributes (Gathering, Reordering, Early Write 58 * Acknowledgment) of the memory region 59 */ 60 enum sp_device_memory_attributes { 61 sp_device_memory_nGnRnE = 0x00, /**< nGnRnE */ 62 sp_device_memory_nGnRE = 0x01, /**< nGnRE */ 63 sp_device_memory_nGRE = 0x02, /**< nGRE */ 64 sp_device_memory_GRE = 0x03 /**< GRE */ 65 }; 66 67 /** 68 * @brief Shareability attribute of the memory region 69 */ 70 enum sp_shareablity_attribute { 71 sp_shareability_non_shareable = 0x00, /**< Non-shareable */ 72 sp_shareability_reserved = 0x01, /**< Reserved */ 73 sp_shareability_outer_shareable = 0x02, /**< Outer shareable */ 74 sp_shareability_inner_shareable = 0x03 /**< Inner shareable */ 75 }; 76 77 /** 78 * @brief Instruction access permission of the memory region 79 */ 80 enum sp_instruction_access_permission { 81 sp_instruction_access_not_specified = 0x00, /**< Not specified*/ 82 sp_instruction_access_not_executable = 0x01, /**< Not executable */ 83 sp_instruction_access_executable = 0x02, /**< Executable */ 84 sp_instruction_access_reserved = 0x03 /**< Reserved */ 85 }; 86 87 /** 88 * @brief Data access permission of the memory region 89 */ 90 enum sp_data_access_permission { 91 sp_data_access_not_specified = 0x00, /**< Not specified */ 92 sp_data_access_read_only = 0x01, /**< Read-only */ 93 sp_data_access_read_write = 0x02, /**< Read-write */ 94 sp_data_access_reserved = 0x03 /**< Reserved */ 95 }; 96 97 /** 98 * @brief Memory management transaction type 99 */ 100 enum sp_memory_transaction_type { 101 /** Relayer specified */ 102 sp_memory_transaction_type_relayer_specified = 0x00, 103 sp_memory_transaction_type_share = 0x01, /**< Share */ 104 sp_memory_transaction_type_lend = 0x02, /**< Lend */ 105 sp_memory_transaction_type_donate = 0x03, /**< Donate */ 106 }; 107 108 /** 109 * @brief This union contains the memory attributes for normal and device 110 * memory areas. 111 */ 112 union sp_memory_attr { 113 /** Normal memory attributes */ 114 struct sp_normal_memory_attributes { 115 /** Cacheability attribute */ 116 enum sp_cacheability_attribute cacheability; 117 118 /** Shareability attribute */ 119 enum sp_shareablity_attribute shareability; 120 } normal_memory; 121 122 /** Device memory attributes */ 123 enum sp_device_memory_attributes device_memory; 124 125 #if CFG_FFA_VERSION >= FFA_VERSION_1_1 126 /* Memory security state (secure/non-secure) */ 127 enum sp_memory_security_state security_state; 128 #endif /* CFG_FFA_VERSION */ 129 }; 130 131 /** 132 * @brief Flags are used to govern the behavior of a memory management 133 * transaction. 134 */ 135 struct sp_memory_transaction_flags { 136 /** 137 * Zero memory on share, lend and donate call or zero memory before 138 * retrieval flag on a retrieve call or zero memory after relinquish on 139 * a relinquish call. 140 */ 141 bool zero_memory; 142 143 /** 144 * The flag specifies if the relayer can time slice this operation. 145 */ 146 bool operation_time_slicing; 147 148 /** 149 * The flag specified if the relayer must zero the memory region 150 * contents after unmapping it from the borrower's translation regime or 151 * if the borrower crashes. 152 * **This field can only be used at a retrieve call.** 153 */ 154 bool zero_memory_after_relinquish; 155 156 /** 157 * In an invocation of a retrieve call, this flag is used by the 158 * receiver to either specify the memory management transaction it is 159 * participating in or indicate that it will discover this information 160 * in the response structure. 161 * **This field can only be used at a retrieve call.** 162 */ 163 enum sp_memory_transaction_type transaction_type; 164 165 /** 166 * This flag is used by the receiver to specify the boundary. 167 * The valid range is 8K-120K in 8K steps. Zero means the relayer must 168 * choose the alignment boundary. The value of this field is multiplied 169 * by 8K. 170 * **This field can only be used at a retrieve call.** 171 */ 172 uint32_t alignment_hint; 173 }; 174 175 /** 176 * @brief This structure describes the details of a memory transaction. The 177 * type is used in donate, lend, share and retrieve calls but the 178 * mandatory and optional fields vary according to the description 179 * of the individual fields. 180 */ 181 struct sp_memory_descriptor { 182 uint16_t sender_id; /**< Sender FF-A ID, **must** be specified */ 183 184 /** 185 * The type of the memory region (device, normal, not specified) 186 * * Donate: The owner **must not** specify it 187 * * Lend: The owner **must not** specify it 188 * * Share: The owner **must** specify it 189 * * Retrieve: The receiver **should** specify same or less permissive 190 * as the owner. This field is filled with the value used by 191 * the relayer on retrieve. 192 */ 193 enum sp_memory_type memory_type; 194 195 /** 196 * Memory region attributes 197 * The field of the union which is matching with the memory type should 198 * be used. In case of non-specified memory type the contents of the 199 * union is ignored. 200 */ 201 union sp_memory_attr mem_region_attr; 202 203 /** 204 * Flags are used to govern the behavior of a memory management 205 * transaction. 206 * The allowed flags for each transaction type is describe in the type's 207 * comment. 208 */ 209 struct sp_memory_transaction_flags flags; 210 211 /** 212 * This 64-bit field must be used to specify an implementation defined 213 * value associated with the transaction and known to participating 214 * endpoints. 215 */ 216 uint64_t tag; 217 }; 218 219 /** 220 * @brief Structure for specifying access restrictions for 221 * receiver endpoints. 222 */ 223 struct sp_memory_access_descriptor { 224 uint16_t receiver_id; /**< Receiver FF-A ID, **must** be specified */ 225 226 /** 227 * Instruction access permission of the memory region 228 * * Donate: The owner **must not** specify it 229 * * Lend: The owner **must not** specify it 230 * * Share: The owner **must not** specify it 231 * * Retrieve: The receiver **must not** specify it on retrieving a 232 * **shared or lent** memory region. The receiver **should** 233 * specify it on retrieving a **donated** region. This field 234 * is filled with the value used by the relayer on retrieve. 235 */ 236 enum sp_instruction_access_permission instruction_access; 237 238 /** 239 * Data access permission of the memory region 240 * * Donate: The owner **must not** specify it 241 * * Lend: The owner **must** specify it 242 * * Share: The owner **must** specify it 243 * * Retrieve: The receiver **must** specify it on retrieving a 244 * **donated** memory region. The receiver **should** 245 * specify same or less permissive as the owner on 246 * retrieving **shared or lent** memory region.This field 247 * is filled with the value used by the relayer on retrieve. 248 */ 249 enum sp_data_access_permission data_access; 250 }; 251 252 /** 253 * @brief The structure describes a memory region by its base address 254 * and its page count. 255 */ 256 struct sp_memory_region { 257 void *address; /**< Base address of the memory region */ 258 uint32_t page_count; /**< Number of 4K pages in memory region */ 259 }; 260 261 /** 262 * @brief Enum for describing data access permissions in 263 * sp_memory_permission_get/set calls (FFA_MEM_PERM_GET/SET). 264 */ 265 enum sp_mem_perm_data_access_permission { 266 sp_mem_perm_data_perm_no_access = 0x00, 267 sp_mem_perm_data_perm_read_write = 0x01, 268 sp_mem_perm_data_perm_reserved = 0x02, 269 sp_mem_perm_data_perm_read_only = 0x03 270 }; 271 272 /** 273 * @brief Enum for describing instruction access permissions in 274 * sp_memory_permission_get/set calls (FFA_MEM_PERM_GET/SET). 275 */ 276 enum sp_mem_perm_instruction_access_permission { 277 sp_mem_perm_instruction_perm_executable = 0x00, 278 sp_mem_perm_instruction_perm_non_executable = 0x01 279 }; 280 281 /** 282 * @brief Struct for describing memory access setting in 283 * sp_memory_permission_get/set calls (FFA_MEM_PERM_GET/SET). 284 * 285 */ 286 struct sp_mem_perm { 287 enum sp_mem_perm_data_access_permission data_access; 288 enum sp_mem_perm_instruction_access_permission instruction_access; 289 }; 290 291 /** 292 * @brief Starts a transaction to transfer of ownership of a memory region 293 * from a Sender endpoint to a Receiver endpoint. 294 * 295 * @param[in] descriptor The memory descriptor 296 * @param[in] acc_desc Access descriptor 297 * @param[in] regions Memory region array 298 * @param[in] region_count Memory region count 299 * @param[out] handle The handle for identifying the memory transaction 300 * 301 * @return The SP API result 302 */ 303 sp_result sp_memory_donate(struct sp_memory_descriptor *descriptor, 304 struct sp_memory_access_descriptor *acc_desc, 305 struct sp_memory_region regions[], 306 uint32_t region_count, uint64_t *handle); 307 308 sp_result sp_memory_donate_dynamic(struct sp_memory_descriptor *descriptor, 309 struct sp_memory_access_descriptor *acc_desc, 310 struct sp_memory_region regions[], 311 uint32_t region_count, uint64_t *handle, 312 struct ffa_mem_transaction_buffer *buffer); 313 314 /** 315 * @brief Queries if sp_memory_donate_dynamic is supported by the SPM. 316 * 317 * @param[out] supported Flag indicating the support state 318 * 319 * @return The SP API result 320 */ 321 sp_result sp_memory_donate_dynamic_is_supported(bool *supported); 322 323 /** 324 * @brief Starts a transaction to transfer an Owner’s access to a memory 325 * region and grant access to it to one or more Borrowers. 326 * 327 * @param[in] descriptor The memory descriptor 328 * @param[in] acc_desc Access descriptor array 329 * @param[in] acc_desc_count Access descriptor count, must be greater than 0 330 * @param[in] regions Memory region array 331 * @param[in] region_count Memory region count 332 * @param[out] handle The handle for identifying the memory transaction 333 * 334 * @return The SP API result 335 */ 336 sp_result sp_memory_lend(struct sp_memory_descriptor *descriptor, 337 struct sp_memory_access_descriptor acc_desc[], 338 uint32_t acc_desc_count, 339 struct sp_memory_region regions[], 340 uint32_t region_count, uint64_t *handle); 341 342 sp_result sp_memory_lend_dynamic(struct sp_memory_descriptor *descriptor, 343 struct sp_memory_access_descriptor acc_desc[], 344 uint32_t acc_desc_count, 345 struct sp_memory_region regions[], 346 uint32_t region_count, uint64_t *handle, 347 struct ffa_mem_transaction_buffer *buffer); 348 349 /** 350 * @brief Queries if sp_memory_lend_dynamic is supported by the SPM. 351 * 352 * @param[out] supported Flag indicating the support state 353 * 354 * @return The SP API result 355 */ 356 sp_result sp_memory_lend_dynamic_is_supported(bool *supported); 357 358 /** 359 * @brief Starts a transaction to grant access to a memory region to one or 360 * more Borrowers. 361 * 362 * @param[in] descriptor The memory descriptor 363 * @param[in] acc_desc Access descriptor array 364 * @param[in] acc_desc_count Access descriptor count, must be greater than 0 365 * @param[in] regions Memory region array 366 * @param[in] region_count Memory region count 367 * @param[out] handle The handle for identifying the memory transaction 368 * 369 * @return The SP API result 370 */ 371 sp_result sp_memory_share(struct sp_memory_descriptor *descriptor, 372 struct sp_memory_access_descriptor acc_desc[], 373 uint32_t acc_desc_count, 374 struct sp_memory_region regions[], 375 uint32_t region_count, uint64_t *handle); 376 377 sp_result sp_memory_share_dynamic(struct sp_memory_descriptor *descriptor, 378 struct sp_memory_access_descriptor acc_desc[], 379 uint32_t acc_desc_count, 380 struct sp_memory_region regions[], 381 uint32_t region_count, uint64_t *handle, 382 struct ffa_mem_transaction_buffer *buffer); 383 384 /** 385 * @brief Queries if sp_memory_share_dynamic is supported by the SPM. 386 * 387 * @param[out] supported Flag indicating the support state 388 * 389 * @return The SP API result 390 */ 391 sp_result sp_memory_share_dynamic_is_supported(bool *supported); 392 393 /** 394 * @brief Requests completion of a donate, lend or share memory 395 * management transaction. 396 * 397 * @param[in] descriptor The memory descriptor 398 * @param[in,out] acc_desc Access descriptor 399 * @param[in,out] regions Memory region array 400 * @param[in] in_region_count Count of the specified regions, can be 0 401 * @param[in,out] out_region_count Count of the reserved space of in the 402 * regions buffer for retrieved regions. After 403 * call it will contain the exact count of the 404 * retrieved regions. 405 * @param[in] handle The handle for identifying the memory 406 * transaction 407 * 408 * @return The SP API result 409 */ 410 sp_result sp_memory_retrieve(struct sp_memory_descriptor *descriptor, 411 struct sp_memory_access_descriptor *acc_desc, 412 struct sp_memory_region regions[], 413 uint32_t in_region_count, 414 uint32_t *out_region_count, uint64_t handle); 415 416 sp_result 417 sp_memory_retrieve_dynamic(struct sp_memory_descriptor *descriptor, 418 struct sp_memory_access_descriptor *acc_desc, 419 struct sp_memory_region regions[], 420 uint32_t in_region_count, uint32_t *out_region_count, 421 uint64_t handle, 422 struct ffa_mem_transaction_buffer *buffer); 423 424 /** 425 * @brief Queries if sp_memory_retrieve_dynamic is supported by the SPM. 426 * 427 * @param[out] supported Flag indicating the support state 428 * 429 * @return The SP API result 430 */ 431 sp_result sp_memory_retrieve_dynamic_is_supported(bool *supported); 432 433 /** 434 * @brief Starts a transaction to transfer access to a shared or lent 435 * memory region from a Borrower back to its Owner. 436 * 437 * @param[in] handle The handle for identifying the memory transaction 438 * @param[in] endpoints The endpoints 439 * @param[in] endpoint_count The endpoint count 440 * 441 * @return The SP API result 442 */ 443 sp_result sp_memory_relinquish(uint64_t handle, const uint16_t endpoints[], 444 uint32_t endpoint_count, 445 struct sp_memory_transaction_flags *flags); 446 447 /** 448 * @brief Restores exclusive access to a memory region back to its Owner. 449 * 450 * @param[in] handle The handle for identifying the memory transaction 451 * @param[in] flags Flags for modifying the reclaim behavior 452 * 453 * @return The SP API result 454 */ 455 sp_result sp_memory_reclaim(uint64_t handle, uint32_t flags); 456 457 /** 458 * @brief Queries the memory attributes of a memory region. It can only 459 * access the regions of the SP's own translation regine. Moreover 460 * this function is only available in the boot phase, i.e. before 461 * calling sp_msg_wait. 462 * 463 * 464 * @param[in] base_address Base VA of a translation granule whose 465 * permission attributes must be returned. 466 * @param[out] mem_perm Permission attributes of the memory region 467 * @return The SP API result 468 */ 469 sp_result sp_memory_permission_get(const void *base_address, 470 struct sp_mem_perm *mem_perm); 471 472 /** 473 * @brief Sets the memory attributes of a memory regions. It can only 474 * access the regions of the SP's own translation regine. Moreover 475 * this function is only available in the boot phase, i.e. before 476 * calling sp_msg_wait. 477 * 478 * @param[in] base_address Base VA of a memory region whose permission 479 * attributes must be set. 480 * @param[in] region_size Memory regions size in bytes 481 * @param[in] mem_perm Permission attributes to be set for the memory 482 * region 483 * @return The SP API result 484 */ 485 sp_result sp_memory_permission_set(const void *base_address, size_t region_size, 486 const struct sp_mem_perm *mem_perm); 487 488 #ifdef __cplusplus 489 } 490 #endif 491 492 #endif /* LIBSP_INCLUDE_SP_MEMORY_MANAGEMENT_H_ */ 493