1 /*
2  * Copyright (c) 2022-2023, Intel Corporation.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef ZEPHYR_INCLUDE_SIP_SVC_H_
8 #define ZEPHYR_INCLUDE_SIP_SVC_H_
9 
10 /**
11  * @file
12  * @brief Public API for ARM SiP services
13  *
14  * ARM SiP service provides the capability to send the
15  * SMC/HVC call from kernel running at EL1 to hypervisor/secure
16  * monitor firmware running at EL2/EL3.
17  *
18  * Only allow one SMC and one HVC per system.
19  *
20  * The service support multiple clients.
21  *
22  * The client must open a channel before sending any request and
23  * close the channel immediately after complete. The service only
24  * allow one channel at one time.
25  *
26  * The service will return the SMC/HVC return value to the client
27  * via callback function.
28  *
29  * The client state machine
30  * - INVALID: Invalid state before registration.
31  * - IDLE   : Initial state.
32  * - OPEN   : The client will switch from IDLE to OPEN once it
33  *            successfully open the channel. On the other hand, it
34  *            will switch from OPEN to IDLE state once it successfully
35  *            close the channel.
36  * - ABORT  : The client has closed the channel, however, there are
37  *            incomplete transactions being left over. The service
38  *            will only move the client back to IDLE state once all
39  *            transactions completed. The client is not allowed to
40  *            re-open the channel when in ABORT state/
41  */
42 
43 #include <zephyr/kernel.h>
44 #include <zephyr/arch/arm64/arm-smccc.h>
45 #include <zephyr/drivers/sip_svc/sip_svc_proto.h>
46 
47 #define SIP_SVC_CLIENT_ST_INVALID 0
48 #define SIP_SVC_CLIENT_ST_IDLE	  1
49 #define SIP_SVC_CLIENT_ST_OPEN	  2
50 #define SIP_SVC_CLIENT_ST_ABORT	  3
51 
52 /** @brief ARM sip service callback function prototype for response after completion
53  *
54  * On success , response is returned via a callback to the user.
55  *
56  * @param c_token Client's token
57  * @param res pointer to struct sip_svc_response
58  */
59 typedef void (*sip_svc_cb_fn)(uint32_t c_token, struct sip_svc_response *res);
60 
61 /**
62  * @brief Register a client on ARM SiP service
63  *
64  * On success, the client will be at IDLE state in the service and
65  * the service will return a token to the client. The client can then
66  * use the token to open the channel on the service and communicate
67  * with hypervisor/secure monitor firmware running at EL2/EL3.
68  *
69  * @param ctrl Pointer to controller instance whose service provides ARM SMC/HVC
70  *            SiP services.
71  * @param priv_data Pointer to client private data.
72  *
73  * @retval token_id on success.
74  * @retval SIP_SVC_ID_INVALID invalid arguments, failure to allocate a client id and failure to get
75  * a lock.
76  */
77 uint32_t sip_svc_register(void *ctrl, void *priv_data);
78 
79 /**
80  * @brief Unregister a client on ARM SiP service
81  *
82  * On success, detach the client from the service. Unregistration
83  * is only allowed when all transactions belong to the client are closed.
84  *
85  * @param ctrl Pointer to controller instance which provides ARM SiP services.
86  * @param c_token Client's token
87  *
88  * @retval 0 on success.
89  * @retval -EINVALinvalid arguments.
90  * @retval -ENODATA if client is not registered correctly.
91  * @retval -EBUSY if client has pending transactions.
92  * @retval -ECANCELED if client is not in IDLE state.
93  * @retval -ENOLCK if failure in acquiring mutex.
94  */
95 int sip_svc_unregister(void *ctrl, uint32_t c_token);
96 
97 /**
98  * @brief Client requests to open a channel on ARM SiP service.
99  *
100  * Client must open a channel before sending any request via
101  * SMC/HVC to hypervisor/secure monitor firmware running at EL2/EL3.
102  *
103  * The service only allows one opened channel at one time and it is protected
104  * by mutex.
105  *
106  * @param ctrl Pointer to controller instance which provides ARM SiP services.
107  * @param c_token Client's token
108  * @param k_timeout Waiting time if the mutex have been locked.
109  *                   When the mutex have been locked:
110  *                   - returns non-zero error code immediately if value is K_NO_WAIT
111  *                   - wait forever if the value is K_FOREVER
112  *                   - otherwise, for the given time
113  *
114  * @retval 0 on success.
115  * @retval -EINVAL invalid arguments.
116  * @retval -ETIMEDOUT timeout expiry.
117  * @retval -EALREADY client state is already open.
118  */
119 int sip_svc_open(void *ctrl, uint32_t c_token, k_timeout_t k_timeout);
120 
121 /**
122  * @brief Client requests to close the channel on ARM SiP services.
123  *
124  * Client must close the channel immediately once complete.
125  *
126  * @param ctrl Pointer to controller instance which provides ARM SiP services.
127  * @param c_token Client's token
128  * @param pre_close_req pre close request sent to lower layer on channel close.
129  *
130  * @retval 0 on success, negative errno on failure.
131  * @retval -EINVAL invalid arguments.
132  * @retval -ENOTSUP error on sending pre_close_request.
133  * @retval -EPROTO client is not in OPEN state.
134  */
135 int sip_svc_close(void *ctrl, uint32_t c_token, struct sip_svc_request *pre_close_req);
136 
137 /**
138  * @brief Client requests to send a SMC/HVC call to EL3/EL2
139  *
140  * Client must open a channel on the device before using this function.
141  * This function is non-blocking and can be called from any context. The
142  * service will return a Transaction ID to the client if the request
143  * is being accepted. Client callback is called when the transaction is
144  * completed.
145  *
146  * @param ctrl Pointer to controller instance which provides ARM SiP services.
147  * @param c_token Client's token
148  * @param req Address to the user input in struct sip_svc_request format.
149  * @param cb Callback. SMC/SVC return value will be passed to client via
150  *           context in struct sip_svc_response format in callback.
151  *
152  * @retval transaction id on success.
153  * @retval -EINVAL invalid arguments.
154  * @retval -EOPNOTSUPP invalid command id or function id.
155  * @retval -ESRCH invalid client state.
156  * @retval -ENOMEM failure to allocate memory.
157  * @retval -ENOMSG failure to insert into database.
158  * @retval -ENOBUF failure to insert into msgq.
159  * @retval -ENOLCK failure to get lock.
160  * @retval -EHOSTDOWN sip_svc thread not present.
161  * @retval -ENOTSUP check for unsupported condition.
162  */
163 int sip_svc_send(void *ctrl, uint32_t c_token, struct sip_svc_request *req, sip_svc_cb_fn cb);
164 
165 /**
166  * @brief Get the address pointer to the client private data.
167  *
168  * The pointer is provided by client during registration.
169  *
170  * @param ctrl Pointer to controller instance which provides ARM SiP service.
171  * @param c_token Client's token
172  *
173  * @retval Address pointer to the client private data.
174  * @retval NULL invalid arguments and failure to get lock.
175  */
176 void *sip_svc_get_priv_data(void *ctrl, uint32_t c_token);
177 
178 /**
179  * @brief get the ARM SiP service handle
180  *
181  * @param method Pointer to controller instance which provides ARM SiP service.
182  *
183  * @retval Valid pointer.
184  * @retval NULL invalid arguments and on providing unsupported method name.
185  */
186 void *sip_svc_get_controller(char *method);
187 
188 #endif /* ZEPHYR_INCLUDE_SIP_SVC_H_ */
189