1 /*
2  * Copyright (c) 2021, L&T Technology Services Ltd.
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #ifndef RPMSG_RPC_CLIENT_SERVER_H
9 #define RPMSG_RPC_CLIENT_SERVER_H
10 
11 #include <openamp/open_amp.h>
12 #include <metal/compiler.h>
13 
14 #if defined __cplusplus
15 extern "C" {
16 #endif
17 
18 #define RPMSG_RPC_OK		0
19 #define RPMSG_RPC_INVALID_ID	(-1L)
20 #define RPMSG_RPC_SERVICE_NAME "rpmsg-rpc"
21 
22 /* RPMSG_BUFFER_SIZE = 512
23  * sizeof(struct rpmsg_hdr) = 16
24  * RPMSG_BUFFER_SIZE - sizeof(struct rpmsg_hdr) - 1 = 495
25  * Aligning to 64 bits -> 488UL
26  */
27 #define MAX_BUF_LEN	488UL
28 #define MAX_FUNC_ID_LEN sizeof(uint32_t)
29 
30 struct rpmsg_rpc_clt;
31 struct rpmsg_rpc_svr;
32 
33 typedef void (*rpmsg_rpc_shutdown_cb)(struct rpmsg_rpc_clt *rpc);
34 typedef void (*app_cb)(struct rpmsg_rpc_clt *rpc, int status, void *data,
35 		       size_t len);
36 typedef int (*rpmsg_rpc_syscall_cb)(void *data, struct rpmsg_rpc_svr *rpcs);
37 
38 /**
39  * struct rpmsg_rpc_request - rpc request message
40  *
41  * @param id		service id
42  * @param params	request params
43  *
44  */
45 struct rpmsg_rpc_request {
46 	uint32_t id;
47 	unsigned char params[MAX_BUF_LEN];
48 };
49 
50 /** @brief RPC request message */
51 METAL_PACKED_BEGIN
52 struct rpmsg_rpc_answer {
53 	/** Service ID */
54 	uint32_t id;
55 
56 	/** Status of RPC */
57 	int32_t status;
58 
59 	/** Answer params */
60 	unsigned char params[MAX_BUF_LEN];
61 } METAL_PACKED_END;
62 
63 /** @brief Table for services */
64 struct rpmsg_rpc_services {
65 	/** Service ID */
66 	uint32_t id;
67 
68 	/** ID callback */
69 	rpmsg_rpc_syscall_cb cb_function;
70 };
71 
72 /** @brief Table for client services */
73 struct rpmsg_rpc_client_services {
74 	/** Service ID */
75 	uint32_t id;
76 
77 	/** ID callback */
78 	app_cb cb;
79 };
80 
81 /**
82  * @brief Server remote procedure call data
83  *
84  * RPMsg RPC will send request to endpoint
85  */
86 struct rpmsg_rpc_svr {
87 	/** RPMsg destination endpoint structure */
88 	struct rpmsg_endpoint ept;
89 
90 	/** Service table */
91 	const struct rpmsg_rpc_services *services;
92 
93 	/** Number of services */
94 	unsigned int n_services;
95 };
96 
97 /**
98  * @brief Client remote procedure call data
99  *
100  * RPMsg RPC will send request to remote and
101  * wait for callback.
102  */
103 struct rpmsg_rpc_clt {
104 	/** RPMsg endpoint associated with the call */
105 	struct rpmsg_endpoint ept;
106 
107 	/** Shutdown callback function */
108 	rpmsg_rpc_shutdown_cb shutdown_cb;
109 
110 	/** Service table */
111 	const struct rpmsg_rpc_client_services *services;
112 
113 	/** Number of services */
114 	unsigned int n_services;
115 };
116 
117 /**
118  * @internal
119  *
120  * @brief Release RPMsg remote procedure call
121  *
122  * This function is to release remoteproc procedure call service
123  *
124  * @param rpc	Pointer to the client remote procedure call data
125  */
126 void rpmsg_rpc_client_release(struct rpmsg_rpc_clt *rpc);
127 
128 /**
129  * @internal
130  *
131  * @brief Initialize RPMsg remote procedure call
132  *
133  * This function is to initialize the remote procedure call
134  * client data. RPMsg RPC will send request to remote and
135  * wait for callback and load services to table
136  *
137  * @param rpc		Pointer to the client remote procedure call data
138  * @param rdev		Pointer to the rpmsg device
139  * @param shutdown_cb	Shutdown callback function
140  * @param services	Pointer to service table
141  * @param len		Length of table
142  *
143  * @return 0 for success, and negative value for failure
144  */
145 int rpmsg_rpc_client_init(struct rpmsg_rpc_clt *rpc,
146 			  struct rpmsg_device *rdev,
147 			  rpmsg_rpc_shutdown_cb shutdown_cb,
148 			  const struct rpmsg_rpc_client_services *services,
149 			  int len);
150 
151 /**
152  * @internal
153  *
154  * @brief Initialize RPMsg rpc for server
155  *
156  * This function create endpoint and loads services into table
157  *
158  * @param rpcs				Pointer to the server rpc
159  * @param rdev				Pointer to the rpmsg device
160  * @param services			Pointer to service table
161  * @param len				Length of table
162  * @param rpmsg_service_server_unbind	Unbind function callback
163  *
164  * @return 0 for success, and negative value for failure
165  */
166 int rpmsg_rpc_server_init(struct rpmsg_rpc_svr *rpcs, struct rpmsg_device *rdev,
167 			  const struct rpmsg_rpc_services *services, int len,
168 			  rpmsg_ns_unbind_cb rpmsg_service_server_unbind);
169 
170 /**
171  * @internal
172  *
173  * @brief Request RPMsg RPC call
174  *
175  * @param rpc			Pointer to client remoteproc procedure call
176  *				data
177  * @param rpc_id		Function id
178  * @param request_param		Pointer to request buffer
179  * @param req_param_size	Length of the request data
180  *
181  * @return Length of the received response, negative value for failure.
182  */
183 int rpmsg_rpc_client_send(struct rpmsg_rpc_clt *rpc,
184 			  uint32_t rpc_id, void *request_param,
185 			  size_t req_param_size);
186 
187 /**
188  * @internal
189  *
190  * @brief Request RPMsg RPC call
191  *
192  * This function sends RPC request
193  *
194  * @param rpcs		Pointer to server rpc data
195  * @param rpc_id	Function id
196  * @param status	Status of rpc
197  * @param request_param	Pointer to request buffer
198  * @param param_size	Length of the request data
199  *
200  * @return Length of the received response, negative value for failure.
201  */
202 int rpmsg_rpc_server_send(struct rpmsg_rpc_svr *rpcs, uint32_t rpc_id,
203 			  int status, void *request_param,
204 			  size_t param_size);
205 
206 #if defined __cplusplus
207 }
208 #endif
209 
210 #endif /* RPMSG_RPC_CLIENT_SERVER_H */
211