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