1 /*
2  * Copyright (c) 2019-2021, Arm Limited. All rights reserved.
3  * Copyright (c) 2022-2024 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 /*
11  * This is header file of common mailbox objects shared by NSPE and SPE.
12  * Please refer to tfm_ns_mailbox.h for the definitions only used in NSPE
13  * mailbox library.
14  * Please refer to tfm_spe_mailbox.h for the SPE specific definitions and APIs.
15  */
16 
17 #ifndef __TFM_MAILBOX_H__
18 #define __TFM_MAILBOX_H__
19 
20 #include <stdbool.h>
21 #include <stdint.h>
22 #include <stddef.h>
23 
24 #include "psa/client.h"
25 #include "tfm_mailbox_config.h"
26 
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30 
31 /* PSA client call type value */
32 #define MAILBOX_PSA_FRAMEWORK_VERSION       (0x1)
33 #define MAILBOX_PSA_VERSION                 (0x2)
34 #define MAILBOX_PSA_CONNECT                 (0x3)
35 #define MAILBOX_PSA_CALL                    (0x4)
36 #define MAILBOX_PSA_CLOSE                   (0x5)
37 
38 /* Return code of mailbox APIs */
39 #define MAILBOX_SUCCESS                     (0)
40 #define MAILBOX_QUEUE_FULL                  (INT32_MIN + 1)
41 #define MAILBOX_INVAL_PARAMS                (INT32_MIN + 2)
42 #define MAILBOX_NO_PERMS                    (INT32_MIN + 3)
43 #define MAILBOX_NO_PEND_EVENT               (INT32_MIN + 4)
44 #define MAILBOX_CHAN_BUSY                   (INT32_MIN + 5)
45 #define MAILBOX_CALLBACK_REG_ERROR          (INT32_MIN + 6)
46 #define MAILBOX_INIT_ERROR                  (INT32_MIN + 7)
47 #define MAILBOX_GENERIC_ERROR               (INT32_MIN + 8)
48 
49 /*
50  * This structure holds the parameters used in a PSA client call.
51  */
52 struct psa_client_params_t {
53     union {
54         struct {
55             uint32_t        sid;
56         } psa_version_params;
57 
58         struct {
59             uint32_t        sid;
60             uint32_t        version;
61         } psa_connect_params;
62 
63         struct {
64             psa_handle_t    handle;
65             int32_t         type;
66             const psa_invec *in_vec;
67             size_t          in_len;
68             psa_outvec      *out_vec;
69             size_t          out_len;
70         } psa_call_params;
71 
72         struct {
73             psa_handle_t    handle;
74         } psa_close_params;
75     };
76 };
77 
78 /* Mailbox message passed from NSPE to SPE to deliver a PSA client call */
79 struct mailbox_msg_t {
80     uint32_t                    call_type; /* PSA client call type */
81     struct psa_client_params_t  params;    /* Contain parameters used in PSA
82                                             * client call
83                                             */
84 
85     int32_t                     client_id; /* Optional client ID of the
86                                             * non-secure caller.
87                                             * It is required to identify the
88                                             * non-secure task when NSPE OS
89                                             * enforces non-secure task isolation
90                                             */
91 };
92 
93 /*
94  * Mailbox reply structure in non-secure memory
95  * to hold the PSA client call return result from SPE
96  */
97 struct mailbox_reply_t {
98     int32_t    return_val;
99 };
100 
101 /*
102  * A single slot structure in NSPE mailbox queue.
103  * This structure is an ABI between SPE and NSPE mailbox instances.
104  * So, it must not include data that are not used by SPE like information about NS threads
105  * or that depends on NSPE build settings.
106  * TODO: It's good to align each slot structure according to the cache row,
107  * so it will be easier to clean and invalidate slot during transfer between cores.
108  */
109 struct mailbox_slot_t {
110     struct mailbox_msg_t   msg;
111     struct mailbox_reply_t reply;
112 };
113 
114 typedef uint32_t   mailbox_queue_status_t;
115 
116 /*
117  * NSPE mailbox status shared between TF-M and mailbox client.
118  * This structure is separated from slots to allow flexible allocation of slots.
119  * So, it's safe to change number of slots on non-secure side without rebuild of TF-M.
120  * TODO: It's good to align structure according to the cache row,
121  * so it will be easier to clean and invalidate slot during transfer between cores.
122  */
123 struct mailbox_status_t {
124     mailbox_queue_status_t   pend_slots;        /* Bitmask of slots pending
125                                                  * for SPE handling
126                                                  */
127     mailbox_queue_status_t   replied_slots;     /* Bitmask of active slots
128                                                  * containing PSA client call
129                                                  * return result
130                                                  */
131 };
132 
133 /* Data used to send information to mailbox partition about mailbox queue allocated by non-secure image */
134 struct mailbox_init_t {
135     /* Shared data with fixed size */
136     struct mailbox_status_t *status;
137 
138     /* Number of slots allocated by NS. */
139     uint32_t slot_count;
140 
141     /* Pointer to struct mailbox_slot_t[slot_count] allocated by NS */
142     struct mailbox_slot_t *slots;
143 };
144 
145 #ifdef __cplusplus
146 }
147 #endif
148 
149 #endif /* __TFM_MAILBOX_H__ */
150