1 /*
2  * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
3  * Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company)
4  * or an affiliate of Cypress Semiconductor Corporation. All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  *
8  */
9 
10 #include "current.h"
11 #include "fih.h"
12 #include "internal_status_code.h"
13 #include "spm.h"
14 #include "tfm_hal_isolation.h"
15 #include "tfm_multi_core.h"
16 #include "ffm/mailbox_agent_api.h"
17 #include "ffm/backend.h"
18 #include "ffm/psa_api.h"
19 #include "psa/error.h"
20 
tfm_spm_agent_psa_call(psa_handle_t handle,uint32_t control,const struct client_params_t * params,const void * client_data_stateless)21 psa_status_t tfm_spm_agent_psa_call(psa_handle_t handle,
22                                     uint32_t control,
23                                     const struct client_params_t *params,
24                                     const void *client_data_stateless)
25 {
26     struct connection_t *p_connection;
27     const struct partition_t *curr_partition = GET_CURRENT_COMPONENT();
28     fih_int fih_rc = FIH_FAILURE;
29     psa_status_t status;
30 
31     FIH_CALL(tfm_hal_memory_check, fih_rc,
32              curr_partition->boundary, (uintptr_t)params,
33              sizeof(struct client_params_t),
34              TFM_HAL_ACCESS_READABLE);
35     if (fih_not_eq(fih_rc, fih_int_encode(PSA_SUCCESS))) {
36         return PSA_ERROR_PROGRAMMER_ERROR;
37     }
38 
39     status = spm_get_idle_connection(&p_connection, handle, params->ns_client_id_stateless);
40     if (status != PSA_SUCCESS) {
41         return status;
42     }
43 
44     status = spm_associate_call_params(p_connection, control, params->p_invecs, params->p_outvecs);
45     if (status != PSA_SUCCESS) {
46         if (IS_STATIC_HANDLE(handle)) {
47             spm_free_connection(p_connection);
48         }
49         return status;
50     }
51 
52     /* Set Mailbox client data in connection handle for message reply. */
53     p_connection->client_data = client_data_stateless;
54 
55     status = backend_messaging(p_connection);
56 
57     p_connection->status = TFM_HANDLE_STATUS_ACTIVE;
58     return status;
59 }
60 
61 #if CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1
62 
tfm_spm_agent_psa_connect(uint32_t sid,uint32_t version,int32_t ns_client_id,const void * client_data)63 psa_status_t tfm_spm_agent_psa_connect(uint32_t sid, uint32_t version,
64                                        int32_t ns_client_id,
65                                        const void *client_data)
66 {
67     const struct partition_t *curr_partition = GET_CURRENT_COMPONENT();
68     struct connection_t *p_connection;
69     psa_status_t status;
70 
71     if (!IS_NS_AGENT_MAILBOX(curr_partition->p_ldinf)) {
72         tfm_core_panic();
73     }
74     if (ns_client_id >= 0) {
75         tfm_core_panic();
76     }
77 
78     status = spm_psa_connect_client_id_associated(&p_connection, sid, version, ns_client_id);
79     if (status != PSA_SUCCESS) {
80         return status;
81     }
82 
83     /* Set Mailbox client data in connection handle for message reply. */
84     p_connection->client_data = client_data;
85 
86     status = backend_messaging(p_connection);
87 
88     p_connection->status = TFM_HANDLE_STATUS_ACTIVE;
89     return status;
90 }
91 
tfm_spm_agent_psa_close(psa_handle_t handle,int32_t ns_client_id)92 psa_status_t tfm_spm_agent_psa_close(psa_handle_t handle,
93                                      int32_t ns_client_id)
94 {
95     const struct partition_t *curr_partition = GET_CURRENT_COMPONENT();
96 
97     if ((!IS_NS_AGENT_MAILBOX(curr_partition->p_ldinf)) || (ns_client_id >= 0)) {
98         tfm_core_panic();
99     }
100 
101     return spm_psa_close_client_id_associated(handle, ns_client_id);
102 }
103 #endif /* CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1 */
104