1 /*
2  * Remote processor messaging
3  *
4  * Copyright (C) 2011 Texas Instruments, Inc.
5  * Copyright (C) 2011 Google, Inc.
6  * All rights reserved.
7  * Copyright (c) 2016 Freescale Semiconductor, Inc. All rights reserved.
8  *
9  * SPDX-License-Identifier: BSD-3-Clause
10  */
11 
12 #ifndef _RPMSG_H_
13 #define _RPMSG_H_
14 
15 #include <openamp/compiler.h>
16 #include <metal/mutex.h>
17 #include <metal/list.h>
18 #include <metal/utilities.h>
19 #include <string.h>
20 #include <stdbool.h>
21 #include <stdint.h>
22 
23 #if defined __cplusplus
24 extern "C" {
25 #endif
26 
27 /* Configurable parameters */
28 #define RPMSG_NAME_SIZE		(32)
29 #define RPMSG_ADDR_BMP_SIZE	(128)
30 
31 #define RPMSG_NS_EPT_ADDR	(0x35)
32 #define RPMSG_ADDR_ANY		0xFFFFFFFF
33 
34 /* Error macros. */
35 #define RPMSG_SUCCESS		0
36 #define RPMSG_ERROR_BASE	-2000
37 #define RPMSG_ERR_NO_MEM	(RPMSG_ERROR_BASE - 1)
38 #define RPMSG_ERR_NO_BUFF	(RPMSG_ERROR_BASE - 2)
39 #define RPMSG_ERR_PARAM		(RPMSG_ERROR_BASE - 3)
40 #define RPMSG_ERR_DEV_STATE	(RPMSG_ERROR_BASE - 4)
41 #define RPMSG_ERR_BUFF_SIZE	(RPMSG_ERROR_BASE - 5)
42 #define RPMSG_ERR_INIT		(RPMSG_ERROR_BASE - 6)
43 #define RPMSG_ERR_ADDR		(RPMSG_ERROR_BASE - 7)
44 
45 struct rpmsg_endpoint;
46 struct rpmsg_device;
47 
48 typedef int (*rpmsg_ept_cb)(struct rpmsg_endpoint *ept, void *data,
49 			    size_t len, uint32_t src, void *priv);
50 typedef void (*rpmsg_ns_unbind_cb)(struct rpmsg_endpoint *ept);
51 typedef void (*rpmsg_ns_bind_cb)(struct rpmsg_device *rdev,
52 				 const char *name, uint32_t dest);
53 
54 /**
55  * struct rpmsg_endpoint - binds a local rpmsg address to its user
56  * @name:name of the service supported
57  * @rdev: pointer to the rpmsg device
58  * @addr: local address of the endpoint
59  * @dest_addr: address of the default remote endpoint binded.
60  * @cb: user rx callback, return value of this callback is reserved
61  *      for future use, for now, only allow RPMSG_SUCCESS as return value.
62  * @ns_unbind_cb: end point service service unbind callback, called when remote
63  *                ept is destroyed.
64  * @node: end point node.
65  * @addr: local rpmsg address
66  * @priv: private data for the driver's use
67  *
68  * In essence, an rpmsg endpoint represents a listener on the rpmsg bus, as
69  * it binds an rpmsg address with an rx callback handler.
70  */
71 struct rpmsg_endpoint {
72 	char name[RPMSG_NAME_SIZE];
73 	struct rpmsg_device *rdev;
74 	uint32_t addr;
75 	uint32_t dest_addr;
76 	rpmsg_ept_cb cb;
77 	rpmsg_ns_unbind_cb ns_unbind_cb;
78 	struct metal_list node;
79 	void *priv;
80 };
81 
82 /**
83  * struct rpmsg_device_ops - RPMsg device operations
84  * @send_offchannel_raw: send RPMsg data
85  */
86 struct rpmsg_device_ops {
87 	int (*send_offchannel_raw)(struct rpmsg_device *rdev,
88 				   uint32_t src, uint32_t dst,
89 				   const void *data, int size, int wait);
90 };
91 
92 /**
93  * struct rpmsg_device - representation of a RPMsg device
94  * @endpoints: list of endpoints
95  * @ns_ept: name service endpoint
96  * @bitmap: table endpoin address allocation.
97  * @lock: mutex lock for rpmsg management
98  * @ns_bind_cb: callback handler for name service announcement without local
99  *              endpoints waiting to bind.
100  * @ops: RPMsg device operations
101  */
102 struct rpmsg_device {
103 	struct metal_list endpoints;
104 	struct rpmsg_endpoint ns_ept;
105 	unsigned long bitmap[metal_bitmap_longs(RPMSG_ADDR_BMP_SIZE)];
106 	metal_mutex_t lock;
107 	rpmsg_ns_bind_cb ns_bind_cb;
108 	struct rpmsg_device_ops ops;
109 };
110 
111 /**
112  * rpmsg_send_offchannel_raw() - send a message across to the remote processor,
113  * specifying source and destination address.
114  * @ept: the rpmsg endpoint
115  * @data: payload of the message
116  * @len: length of the payload
117  *
118  * This function sends @data of length @len to the remote @dst address from
119  * the source @src address.
120  * The message will be sent to the remote processor which the channel belongs
121  * to.
122  * In case there are no TX buffers available, the function will block until
123  * one becomes available, or a timeout of 15 seconds elapses. When the latter
124  * happens, -ERESTARTSYS is returned.
125  *
126  * Returns number of bytes it has sent or negative error value on failure.
127  */
128 int rpmsg_send_offchannel_raw(struct rpmsg_endpoint *ept, uint32_t src,
129 			      uint32_t dst, const void *data, int size,
130 			      int wait);
131 
132 /**
133  * rpmsg_send() - send a message across to the remote processor
134  * @ept: the rpmsg endpoint
135  * @data: payload of the message
136  * @len: length of the payload
137  *
138  * This function sends @data of length @len based on the @ept.
139  * The message will be sent to the remote processor which the channel belongs
140  * to, using @ept's source and destination addresses.
141  * In case there are no TX buffers available, the function will block until
142  * one becomes available, or a timeout of 15 seconds elapses. When the latter
143  * happens, -ERESTARTSYS is returned.
144  *
145  * Returns number of bytes it has sent or negative error value on failure.
146  */
rpmsg_send(struct rpmsg_endpoint * ept,const void * data,int len)147 static inline int rpmsg_send(struct rpmsg_endpoint *ept, const void *data,
148 			     int len)
149 {
150 	if (ept->dest_addr == RPMSG_ADDR_ANY)
151 		return RPMSG_ERR_ADDR;
152 	return rpmsg_send_offchannel_raw(ept, ept->addr, ept->dest_addr, data,
153 					 len, true);
154 }
155 
156 /**
157  * rpmsg_sendto() - send a message across to the remote processor, specify dst
158  * @ept: the rpmsg endpoint
159  * @data: payload of message
160  * @len: length of payload
161  * @dst: destination address
162  *
163  * This function sends @data of length @len to the remote @dst address.
164  * The message will be sent to the remote processor which the @ept
165  * channel belongs to, using @ept's source address.
166  * In case there are no TX buffers available, the function will block until
167  * one becomes available, or a timeout of 15 seconds elapses. When the latter
168  * happens, -ERESTARTSYS is returned.
169  *
170  * Returns number of bytes it has sent or negative error value on failure.
171  */
rpmsg_sendto(struct rpmsg_endpoint * ept,const void * data,int len,uint32_t dst)172 static inline int rpmsg_sendto(struct rpmsg_endpoint *ept, const void *data,
173 			       int len, uint32_t dst)
174 {
175 	return rpmsg_send_offchannel_raw(ept, ept->addr, dst, data, len, true);
176 }
177 
178 /**
179  * rpmsg_send_offchannel() - send a message using explicit src/dst addresses
180  * @ept: the rpmsg endpoint
181  * @src: source address
182  * @dst: destination address
183  * @data: payload of message
184  * @len: length of payload
185  *
186  * This function sends @data of length @len to the remote @dst address,
187  * and uses @src as the source address.
188  * The message will be sent to the remote processor which the @ept
189  * channel belongs to.
190  * In case there are no TX buffers available, the function will block until
191  * one becomes available, or a timeout of 15 seconds elapses. When the latter
192  * happens, -ERESTARTSYS is returned.
193  *
194  * Returns number of bytes it has sent or negative error value on failure.
195  */
rpmsg_send_offchannel(struct rpmsg_endpoint * ept,uint32_t src,uint32_t dst,const void * data,int len)196 static inline int rpmsg_send_offchannel(struct rpmsg_endpoint *ept,
197 					uint32_t src, uint32_t dst,
198 					const void *data, int len)
199 {
200 	return rpmsg_send_offchannel_raw(ept, src, dst, data, len, true);
201 }
202 
203 /**
204  * rpmsg_trysend() - send a message across to the remote processor
205  * @ept: the rpmsg endpoint
206  * @data: payload of message
207  * @len: length of payload
208  *
209  * This function sends @data of length @len on the @ept channel.
210  * The message will be sent to the remote processor which the @ept
211  * channel belongs to, using @ept's source and destination addresses.
212  * In case there are no TX buffers available, the function will immediately
213  * return -ENOMEM without waiting until one becomes available.
214  *
215  * Returns number of bytes it has sent or negative error value on failure.
216  */
rpmsg_trysend(struct rpmsg_endpoint * ept,const void * data,int len)217 static inline int rpmsg_trysend(struct rpmsg_endpoint *ept, const void *data,
218 				int len)
219 {
220 	if (ept->dest_addr == RPMSG_ADDR_ANY)
221 		return RPMSG_ERR_ADDR;
222 	return rpmsg_send_offchannel_raw(ept, ept->addr, ept->dest_addr, data,
223 					 len, false);
224 }
225 
226 /**
227  * rpmsg_trysendto() - send a message across to the remote processor,
228  * specify dst
229  * @ept: the rpmsg endpoint
230  * @data: payload of message
231  * @len: length of payload
232  * @dst: destination address
233  *
234  * This function sends @data of length @len to the remote @dst address.
235  * The message will be sent to the remote processor which the @ept
236  * channel belongs to, using @ept's source address.
237  * In case there are no TX buffers available, the function will immediately
238  * return -ENOMEM without waiting until one becomes available.
239  *
240  * Returns number of bytes it has sent or negative error value on failure.
241  */
rpmsg_trysendto(struct rpmsg_endpoint * ept,const void * data,int len,uint32_t dst)242 static inline int rpmsg_trysendto(struct rpmsg_endpoint *ept, const void *data,
243 				  int len, uint32_t dst)
244 {
245 	return rpmsg_send_offchannel_raw(ept, ept->addr, dst, data, len, false);
246 }
247 
248 /**
249  * rpmsg_trysend_offchannel() - send a message using explicit src/dst addresses
250  * @ept: the rpmsg endpoint
251  * @src: source address
252  * @dst: destination address
253  * @data: payload of message
254  * @len: length of payload
255  *
256  * This function sends @data of length @len to the remote @dst address,
257  * and uses @src as the source address.
258  * The message will be sent to the remote processor which the @ept
259  * channel belongs to.
260  * In case there are no TX buffers available, the function will immediately
261  * return -ENOMEM without waiting until one becomes available.
262  *
263  * Returns number of bytes it has sent or negative error value on failure.
264  */
rpmsg_trysend_offchannel(struct rpmsg_endpoint * ept,uint32_t src,uint32_t dst,const void * data,int len)265 static inline int rpmsg_trysend_offchannel(struct rpmsg_endpoint *ept,
266 					   uint32_t src, uint32_t dst,
267 					   const void *data, int len)
268 {
269 	return rpmsg_send_offchannel_raw(ept, src, dst, data, len, false);
270 }
271 
272 /**
273  * rpmsg_init_ept - initialize rpmsg endpoint
274  *
275  * Initialize an RPMsg endpoint with a name, source address,
276  * remoteproc address, endpoitn callback, and destroy endpoint callback.
277  *
278  * @ept: pointer to rpmsg endpoint
279  * @name: service name associated to the endpoint
280  * @src: local address of the endpoint
281  * @dest: target address of the endpoint
282  * @cb: endpoint callback
283  * @ns_unbind_cb: end point service unbind callback, called when remote ept is
284  *                destroyed.
285  */
rpmsg_init_ept(struct rpmsg_endpoint * ept,const char * name,uint32_t src,uint32_t dest,rpmsg_ept_cb cb,rpmsg_ns_unbind_cb ns_unbind_cb)286 static inline void rpmsg_init_ept(struct rpmsg_endpoint *ept,
287 				  const char *name,
288 				  uint32_t src, uint32_t dest,
289 				  rpmsg_ept_cb cb,
290 				  rpmsg_ns_unbind_cb ns_unbind_cb)
291 {
292 	strncpy(ept->name, name, sizeof(ept->name));
293 	ept->addr = src;
294 	ept->dest_addr = dest;
295 	ept->cb = cb;
296 	ept->ns_unbind_cb = ns_unbind_cb;
297 }
298 
299 /**
300  * rpmsg_create_ept - create rpmsg endpoint and register it to rpmsg device
301  *
302  * Create a RPMsg endpoint, initialize it with a name, source address,
303  * remoteproc address, endpoitn callback, and destroy endpoint callback,
304  * and register it to the RPMsg device.
305  *
306  * @ept: pointer to rpmsg endpoint
307  * @name: service name associated to the endpoint
308  * @src: local address of the endpoint
309  * @dest: target address of the endpoint
310  * @cb: endpoint callback
311  * @ns_unbind_cb: end point service unbind callback, called when remote ept is
312  *                destroyed.
313  *
314  * In essence, an rpmsg endpoint represents a listener on the rpmsg bus, as
315  * it binds an rpmsg address with an rx callback handler.
316  *
317  * Rpmsg client should create an endpoint to discuss with remote. rpmsg client
318  * provide at least a channel name, a callback for message notification and by
319  * default endpoint source address should be set to RPMSG_ADDR_ANY.
320  *
321  * As an option Some rpmsg clients can specify an endpoint with a specific
322  * source address.
323  */
324 
325 int rpmsg_create_ept(struct rpmsg_endpoint *ept, struct rpmsg_device *rdev,
326 		     const char *name, uint32_t src, uint32_t dest,
327 		     rpmsg_ept_cb cb, rpmsg_ns_unbind_cb ns_unbind_cb);
328 
329 /**
330  * rpmsg_destroy_ept - destroy rpmsg endpoint and unregister it from rpmsg
331  *                     device
332  *
333  * @ept: pointer to the rpmsg endpoint
334  *
335  * It unregisters the rpmsg endpoint from the rpmsg device and calls the
336  * destroy endpoint callback if it is provided.
337  */
338 void rpmsg_destroy_ept(struct rpmsg_endpoint *ept);
339 
340 /**
341  * is_rpmsg_ept_ready - check if the rpmsg endpoint ready to send
342  *
343  * @ept: pointer to rpmsg endpoint
344  *
345  * Returns 1 if the rpmsg endpoint has both local addr and destination
346  * addr set, 0 otherwise
347  */
is_rpmsg_ept_ready(struct rpmsg_endpoint * ept)348 static inline unsigned int is_rpmsg_ept_ready(struct rpmsg_endpoint *ept)
349 {
350 	return (ept->dest_addr != RPMSG_ADDR_ANY &&
351 		ept->addr != RPMSG_ADDR_ANY);
352 }
353 
354 #if defined __cplusplus
355 }
356 #endif
357 
358 #endif				/* _RPMSG_H_ */
359