Line data Source code
1 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 0 : #define SIP_SVC_CLIENT_ST_INVALID 0
48 0 : #define SIP_SVC_CLIENT_ST_IDLE 1
49 0 : #define SIP_SVC_CLIENT_ST_OPEN 2
50 0 : #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 1 : 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 1 : 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 1 : 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 1 : 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 1 : 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 1 : 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 1 : 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 1 : void *sip_svc_get_controller(char *method);
187 :
188 : #endif /* ZEPHYR_INCLUDE_SIP_SVC_H_ */
|