1 /*
2  * Copyright (c) 2019-2024, 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 "cmsis_compiler.h"
25 #include "psa/client.h"
26 #include "tfm_mailbox_config.h"
27 
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31 
32 
33 /*
34  * If the mailbox itself can be cached (in either the SPE or NSPE, or both),
35  * we want to add some padding to avoid any cache line conflicts.
36  * Platforms can set both MAILBOX_IS_UNCACHED_S and MAILBOX_IS_UNCACHED_NS to 1
37  * to shrink the mailbox struct a bit if it cannot be cached.
38  */
39 #if (MAILBOX_IS_UNCACHED_S == 1) && (MAILBOX_IS_UNCACHED_NS == 1)
40 /* Let the compiler pick the alignment */
41 #define MAILBOX_ALIGN
42 #else
43 #if !defined(MAILBOX_CACHE_LINE_SIZE)
44 /* 32 bytes is a common dcache line size on Armv8-M */
45 #define MAILBOX_CACHE_LINE_SIZE 32
46 #endif
47 #define MAILBOX_ALIGN  __ALIGNED(MAILBOX_CACHE_LINE_SIZE)
48 #endif
49 
50 
51 /* PSA client call type value */
52 #define MAILBOX_PSA_FRAMEWORK_VERSION       (0x1)
53 #define MAILBOX_PSA_VERSION                 (0x2)
54 #define MAILBOX_PSA_CONNECT                 (0x3)
55 #define MAILBOX_PSA_CALL                    (0x4)
56 #define MAILBOX_PSA_CLOSE                   (0x5)
57 
58 /* Return code of mailbox APIs */
59 #define MAILBOX_SUCCESS                     (0)
60 #define MAILBOX_QUEUE_FULL                  (INT32_MIN + 1)
61 #define MAILBOX_INVAL_PARAMS                (INT32_MIN + 2)
62 #define MAILBOX_NO_PERMS                    (INT32_MIN + 3)
63 #define MAILBOX_NO_PEND_EVENT               (INT32_MIN + 4)
64 #define MAILBOX_CHAN_BUSY                   (INT32_MIN + 5)
65 #define MAILBOX_CALLBACK_REG_ERROR          (INT32_MIN + 6)
66 #define MAILBOX_INIT_ERROR                  (INT32_MIN + 7)
67 #define MAILBOX_GENERIC_ERROR               (INT32_MIN + 8)
68 
69 /*
70  * This structure holds the parameters used in a PSA client call.
71  */
72 struct psa_client_params_t {
73     union {
74         struct {
75             uint32_t        sid;
76         } psa_version_params;
77 
78         struct {
79             uint32_t        sid;
80             uint32_t        version;
81         } psa_connect_params;
82 
83         struct {
84             psa_handle_t    handle;
85             int32_t         type;
86             const psa_invec *in_vec;
87             size_t          in_len;
88             psa_outvec      *out_vec;
89             size_t          out_len;
90         } psa_call_params;
91 
92         struct {
93             psa_handle_t    handle;
94         } psa_close_params;
95     };
96 };
97 
98 /* Mailbox message passed from NSPE to SPE to deliver a PSA client call */
99 struct mailbox_msg_t {
100     uint32_t                    call_type; /* PSA client call type */
101     struct psa_client_params_t  params;    /* Contain parameters used in PSA
102                                             * client call
103                                             */
104 
105     int32_t                     client_id; /* Optional client ID of the
106                                             * non-secure caller.
107                                             * It is required to identify the
108                                             * non-secure task when NSPE OS
109                                             * enforces non-secure task isolation
110                                             */
111 };
112 
113 /*
114  * Mailbox reply structure in non-secure memory
115  * to hold the PSA client call return result from SPE
116  */
117 struct mailbox_reply_t {
118     int32_t    return_val;
119 };
120 
121 /*
122  * A single slot structure in NSPE mailbox queue.
123  * This structure is an ABI between SPE and NSPE mailbox instances.
124  * So, it must not include data that are not used by SPE like information about NS threads
125  * or that depends on NSPE build settings.
126  */
127 struct mailbox_slot_t {
128     /* In the array, msg must not share a cache line with the preceding reply */
129     struct mailbox_msg_t   msg    MAILBOX_ALIGN;
130     /* reply.return_val must not share a cache line with msg */
131     struct mailbox_reply_t reply  MAILBOX_ALIGN;
132 } MAILBOX_ALIGN;
133 
134 typedef uint32_t   mailbox_queue_status_t;
135 
136 /*
137  * NSPE mailbox status shared between TF-M and mailbox client.
138  * This structure is separated from slots to allow flexible allocation of slots.
139  * So, it's safe to change number of slots on non-secure side without rebuild of TF-M.
140  * Access to mailbox status should be guarded by critical section between cores.
141  * Thus there is no need to allocate a separate cache line for each flag.
142  */
143 struct mailbox_status_t {
144     mailbox_queue_status_t   pend_slots;        /* Bitmask of slots pending
145                                                  * for SPE handling
146                                                  */
147     mailbox_queue_status_t   replied_slots;     /* Bitmask of active slots
148                                                  * containing PSA client call
149                                                  * return result
150                                                  */
151 } MAILBOX_ALIGN;
152 
153 /*
154  * Data used to send information to mailbox partition about mailbox queue
155  * allocated by non-secure image. It's expected that data in this structure
156  * is not modified by the secure side.
157  */
158 struct mailbox_init_t {
159     /* Shared data with fixed size */
160     struct mailbox_status_t *status;
161 
162     /* Number of slots allocated by NS. */
163     uint32_t slot_count;
164 
165     /* Pointer to struct mailbox_slot_t[slot_count] allocated by NS */
166     struct mailbox_slot_t *slots;
167 };
168 
169 #ifdef __cplusplus
170 }
171 #endif
172 
173 #endif /* __TFM_MAILBOX_H__ */
174