/* * Copyright (c) 2022-2023, Intel Corporation. * * SPDX-License-Identifier: Apache-2.0 */ #ifndef ZEPHYR_INCLUDE_SIP_SVC_H_ #define ZEPHYR_INCLUDE_SIP_SVC_H_ /** * @file * @brief Public API for ARM SiP services * * ARM SiP service provides the capability to send the * SMC/HVC call from kernel running at EL1 to hypervisor/secure * monitor firmware running at EL2/EL3. * * Only allow one SMC and one HVC per system. * * The service support multiple clients. * * The client must open a channel before sending any request and * close the channel immediately after complete. The service only * allow one channel at one time. * * The service will return the SMC/HVC return value to the client * via callback function. * * The client state machine * - INVALID: Invalid state before registration. * - IDLE : Initial state. * - OPEN : The client will switch from IDLE to OPEN once it * successfully open the channel. On the other hand, it * will switch from OPEN to IDLE state once it successfully * close the channel. * - ABORT : The client has closed the channel, however, there are * incomplete transactions being left over. The service * will only move the client back to IDLE state once all * transactions completed. The client is not allowed to * re-open the channel when in ABORT state/ */ #include #include #include #define SIP_SVC_CLIENT_ST_INVALID 0 #define SIP_SVC_CLIENT_ST_IDLE 1 #define SIP_SVC_CLIENT_ST_OPEN 2 #define SIP_SVC_CLIENT_ST_ABORT 3 /** @brief ARM sip service callback function prototype for response after completion * * On success , response is returned via a callback to the user. * * @param c_token Client's token * @param res pointer to struct sip_svc_response */ typedef void (*sip_svc_cb_fn)(uint32_t c_token, struct sip_svc_response *res); /** * @brief Register a client on ARM SiP service * * On success, the client will be at IDLE state in the service and * the service will return a token to the client. The client can then * use the token to open the channel on the service and communicate * with hypervisor/secure monitor firmware running at EL2/EL3. * * @param ctrl Pointer to controller instance whose service provides ARM SMC/HVC * SiP services. * @param priv_data Pointer to client private data. * * @retval token_id on success. * @retval SIP_SVC_ID_INVALID invalid arguments, failure to allocate a client id and failure to get * a lock. */ uint32_t sip_svc_register(void *ctrl, void *priv_data); /** * @brief Unregister a client on ARM SiP service * * On success, detach the client from the service. Unregistration * is only allowed when all transactions belong to the client are closed. * * @param ctrl Pointer to controller instance which provides ARM SiP services. * @param c_token Client's token * * @retval 0 on success. * @retval -EINVALinvalid arguments. * @retval -ENODATA if client is not registered correctly. * @retval -EBUSY if client has pending transactions. * @retval -ECANCELED if client is not in IDLE state. * @retval -ENOLCK if failure in acquiring mutex. */ int sip_svc_unregister(void *ctrl, uint32_t c_token); /** * @brief Client requests to open a channel on ARM SiP service. * * Client must open a channel before sending any request via * SMC/HVC to hypervisor/secure monitor firmware running at EL2/EL3. * * The service only allows one opened channel at one time and it is protected * by mutex. * * @param ctrl Pointer to controller instance which provides ARM SiP services. * @param c_token Client's token * @param k_timeout Waiting time if the mutex have been locked. * When the mutex have been locked: * - returns non-zero error code immediately if value is K_NO_WAIT * - wait forever if the value is K_FOREVER * - otherwise, for the given time * * @retval 0 on success. * @retval -EINVAL invalid arguments. * @retval -ETIMEDOUT timeout expiry. * @retval -EALREADY client state is already open. */ int sip_svc_open(void *ctrl, uint32_t c_token, k_timeout_t k_timeout); /** * @brief Client requests to close the channel on ARM SiP services. * * Client must close the channel immediately once complete. * * @param ctrl Pointer to controller instance which provides ARM SiP services. * @param c_token Client's token * @param pre_close_req pre close request sent to lower layer on channel close. * * @retval 0 on success, negative errno on failure. * @retval -EINVAL invalid arguments. * @retval -ENOTSUP error on sending pre_close_request. * @retval -EPROTO client is not in OPEN state. */ int sip_svc_close(void *ctrl, uint32_t c_token, struct sip_svc_request *pre_close_req); /** * @brief Client requests to send a SMC/HVC call to EL3/EL2 * * Client must open a channel on the device before using this function. * This function is non-blocking and can be called from any context. The * service will return a Transaction ID to the client if the request * is being accepted. Client callback is called when the transaction is * completed. * * @param ctrl Pointer to controller instance which provides ARM SiP services. * @param c_token Client's token * @param req Address to the user input in struct sip_svc_request format. * @param cb Callback. SMC/SVC return value will be passed to client via * context in struct sip_svc_response format in callback. * * @retval transaction id on success. * @retval -EINVAL invalid arguments. * @retval -EOPNOTSUPP invalid command id or function id. * @retval -ESRCH invalid client state. * @retval -ENOMEM failure to allocate memory. * @retval -ENOMSG failure to insert into database. * @retval -ENOBUF failure to insert into msgq. * @retval -ENOLCK failure to get lock. * @retval -EHOSTDOWN sip_svc thread not present. * @retval -ENOTSUP check for unsupported condition. */ int sip_svc_send(void *ctrl, uint32_t c_token, struct sip_svc_request *req, sip_svc_cb_fn cb); /** * @brief Get the address pointer to the client private data. * * The pointer is provided by client during registration. * * @param ctrl Pointer to controller instance which provides ARM SiP service. * @param c_token Client's token * * @retval Address pointer to the client private data. * @retval NULL invalid arguments and failure to get lock. */ void *sip_svc_get_priv_data(void *ctrl, uint32_t c_token); /** * @brief get the ARM SiP service handle * * @param method Pointer to controller instance which provides ARM SiP service. * * @retval Valid pointer. * @retval NULL invalid arguments and on providing unsupported method name. */ void *sip_svc_get_controller(char *method); #endif /* ZEPHYR_INCLUDE_SIP_SVC_H_ */