1 /*
2  * Copyright (c) 2023, Intel Corporation.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef ZEPHYR_SIP_SVC_CONTROLLER_H_
8 #define ZEPHYR_SIP_SVC_CONTROLLER_H_
9 
10 /**
11  * @note This file should only be included by sip_svc driver.
12  */
13 
14 #ifdef CONFIG_ARM_SIP_SVC_SUBSYS
15 
16 #include <zephyr/sys/atomic.h>
17 
18 /**
19  * @brief Length of SVC conduit name in sip svc subsystem.
20  *
21  */
22 #define SIP_SVC_SUBSYS_CONDUIT_NAME_LENGTH (4U)
23 
24 /**
25  * @brief Open lock states in sip_svc atomic variable
26  */
27 enum open_state {
28 	SIP_SVC_OPEN_UNLOCKED = 0,
29 	SIP_SVC_OPEN_LOCKED
30 };
31 
32 /**
33  *  @brief Arm SiP Service client data.
34  *
35  */
36 struct sip_svc_client {
37 
38 	/* Client id internal to sip_svc*/
39 	uint32_t id;
40 	/* Client's token id provided back to client during sip_svc_register() */
41 	uint32_t token;
42 	/* Client's state */
43 	uint32_t state;
44 	/* Total Number of on-going transaction  of the client */
45 	uint32_t active_trans_cnt;
46 	/* Private data of each client , Provided during sip_svc_register() */
47 	void *priv_data;
48 	/* Transaction id pool for each client */
49 	struct sip_svc_id_pool *trans_idx_pool;
50 };
51 
52 /**
53  * @brief Arm SiP Services controller data.
54  *
55  */
56 struct sip_svc_controller {
57 
58 	/* Initialization status*/
59 	bool init;
60 	/* Total number of clients*/
61 	const uint32_t num_clients;
62 	/* Maximum allowable transactions in the system per controller*/
63 	const uint32_t max_transactions;
64 	/* Response size of buffer used for ASYNC transaction*/
65 	const uint32_t resp_size;
66 	/* Total Number of active transactions */
67 	uint32_t active_job_cnt;
68 	/* Active ASYNC transactions */
69 	uint32_t active_async_job_cnt;
70 	/* Supervisory call name , got from dts entry */
71 	char method[SIP_SVC_SUBSYS_CONDUIT_NAME_LENGTH];
72 	/* Pointer to driver instance */
73 	const struct device *dev;
74 	/* Pointer to client id pool */
75 	struct sip_svc_id_pool *client_id_pool;
76 	/* Pointer to database for storing arguments from sip_svc_send() */
77 	struct sip_svc_id_map *trans_id_map;
78 	/* Pointer to client array */
79 	struct sip_svc_client *clients;
80 	/* Pointer to Buffer used for storing response from lower layers */
81 	uint8_t *async_resp_data;
82 	/* Thread id of sip_svc thread */
83 	k_tid_t tid;
84 
85 #if CONFIG_ARM_SIP_SVC_SUBSYS_SINGLY_OPEN
86 	/* Atomic variable to restrict one client access */
87 	atomic_t open_lock;
88 #endif
89 	/* Mutex for protecting database access */
90 	struct k_mutex data_mutex;
91 	/* msgq for sending sip_svc_request to sip_svc thread */
92 	struct k_msgq req_msgq;
93 	/* sip_svc thread object */
94 	struct k_thread thread;
95 	/* Stack object of sip_svc thread */
96 	K_KERNEL_STACK_MEMBER(stack, CONFIG_ARM_SIP_SVC_SUBSYS_THREAD_STACK_SIZE);
97 };
98 
99 /**
100  * @brief Controller define used by sip_svc driver to instantiate each controller.
101  * Each sip_svc driver will use this API to instantiate a controller for sip_svc
102  * subsystem to consume, for more details check @ref ITERABLE_SECTION_RAM()
103  */
104 #define SIP_SVC_CONTROLLER_DEFINE(inst, conduit_name, sip_dev, sip_num_clients,                    \
105 				  sip_max_transactions, sip_resp_size)                             \
106 	BUILD_ASSERT(                                                                              \
107 		((sip_num_clients <= CONFIG_ARM_SIP_SVC_SUBSYS_MAX_CLIENT_COUNT) &&                \
108 		 (sip_num_clients > 0)),                                                           \
109 		"Number of client should be within 1 and ARM_SIP_SVC_SUBSYS_MAX_CLIENT_COUNT");    \
110 	static STRUCT_SECTION_ITERABLE(sip_svc_controller, sip_svc_##inst) = {                     \
111 		.method = conduit_name,                                                            \
112 		.dev = sip_dev,                                                                    \
113 		.num_clients = sip_num_clients,                                                    \
114 		.max_transactions = sip_max_transactions,                                          \
115 		.resp_size = sip_resp_size,                                                        \
116 	}
117 
118 #else
119 #define SIP_SVC_CONTROLLER_DEFINE(inst, conduit_name, sip_dev, sip_num_clients,                    \
120 				  sip_max_transactions, sip_resp_size)
121 #endif
122 
123 #endif /* ZEPHYR_SIP_SVC_CONTROLLER_H_ */
124