1 /* 2 * Copyright (c) 2018-2023, Arm Limited. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 * 6 */ 7 8 #include "compiler_ext_defs.h" 9 #include "internal_status_code.h" 10 #include "spm.h" 11 #include "tfm_arch.h" 12 13 #ifdef CONFIG_TFM_CONN_HANDLE_MAX_NUM 14 #pragma message("CONFIG_TFM_CONN_HANDLE_MAX_NUM is not used in SFN model without connection-based services.") 15 #endif 16 17 /* 18 * Bits [2:0] of PSPLIM are reserved in v8m, 19 * so PSPLIM has to be 8 bytes aligned when allocating space for connection. 20 */ 21 #define CONNECTION_SIZE ((sizeof(struct connection_t) + 7) & ~0x7) 22 #define FIXED_STATIC_HANDLE ((psa_handle_t)0x1000) 23 alloc_conn_from_stack_top(void)24static inline struct connection_t *alloc_conn_from_stack_top(void) 25 { 26 uint32_t stack_top = tfm_arch_get_psplim(); 27 28 tfm_arch_set_psplim(stack_top + CONNECTION_SIZE); 29 30 return (struct connection_t *)stack_top; 31 } 32 free_conn_from_stack_top(void)33static inline void free_conn_from_stack_top(void) 34 { 35 uint32_t stack_top = tfm_arch_get_psplim(); 36 37 tfm_arch_set_psplim(stack_top - CONNECTION_SIZE); 38 } 39 40 /*********************** Connection handle conversion APIs *******************/ 41 42 /* 43 * A connection instance connection_t allocated inside SPM is actually a memory 44 * address in PSP stack. Return this connection to the client directly 45 * exposes information of secure memory address. In this case, converting the 46 * connection into another handle value does not represent the memory address 47 * to avoid exposing secure memory directly to clients. 48 * Since the current connection can always be calculated from the address of 49 * PSP stack top, it is good enough to return a fixed static handle value to client. 50 */ connection_to_handle(struct connection_t * p_connection)51psa_handle_t connection_to_handle(struct connection_t *p_connection) 52 { 53 (void)p_connection; 54 55 return FIXED_STATIC_HANDLE; 56 } 57 handle_to_connection(psa_handle_t handle)58struct connection_t *handle_to_connection(psa_handle_t handle) 59 { 60 struct connection_t *p_connection; 61 62 if (handle != FIXED_STATIC_HANDLE) { 63 return NULL; 64 } 65 66 p_connection = (struct connection_t *) 67 (tfm_arch_get_psplim() - CONNECTION_SIZE); 68 69 return p_connection; 70 } 71 72 /* Service handle management functions */ spm_init_connection_space(void)73void spm_init_connection_space(void) 74 { 75 /* 76 * No initialization is required for local handle, 77 * because space for connection will be directly allocated 78 * from stack when calling spm_allocate_connection. 79 */ 80 } 81 spm_allocate_connection(void)82struct connection_t *spm_allocate_connection(void) 83 { 84 return alloc_conn_from_stack_top(); 85 } 86 spm_validate_connection(const struct connection_t * p_connection)87psa_status_t spm_validate_connection(const struct connection_t *p_connection) 88 { 89 /* Connection address is always calculated from PSPLIM. No need to validate here. */ 90 return PSA_SUCCESS; 91 } 92 spm_free_connection(struct connection_t * p_connection)93void spm_free_connection(struct connection_t *p_connection) 94 { 95 (void)p_connection; 96 97 free_conn_from_stack_top(); 98 } 99