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 <metal/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_RESERVED_ADDRESSES	(1024)
33 #define RPMSG_ADDR_ANY			0xFFFFFFFF
34 
35 /* Error macros. */
36 #define RPMSG_SUCCESS			0
37 #define RPMSG_ERROR_BASE		-2000
38 #define RPMSG_ERR_NO_MEM		(RPMSG_ERROR_BASE - 1)
39 #define RPMSG_ERR_NO_BUFF		(RPMSG_ERROR_BASE - 2)
40 #define RPMSG_ERR_PARAM			(RPMSG_ERROR_BASE - 3)
41 #define RPMSG_ERR_DEV_STATE		(RPMSG_ERROR_BASE - 4)
42 #define RPMSG_ERR_BUFF_SIZE		(RPMSG_ERROR_BASE - 5)
43 #define RPMSG_ERR_INIT			(RPMSG_ERROR_BASE - 6)
44 #define RPMSG_ERR_ADDR			(RPMSG_ERROR_BASE - 7)
45 
46 struct rpmsg_endpoint;
47 struct rpmsg_device;
48 
49 /* Returns positive value on success or negative error value on failure */
50 typedef int (*rpmsg_ept_cb)(struct rpmsg_endpoint *ept, void *data,
51 			    size_t len, uint32_t src, void *priv);
52 typedef void (*rpmsg_ns_unbind_cb)(struct rpmsg_endpoint *ept);
53 typedef void (*rpmsg_ns_bind_cb)(struct rpmsg_device *rdev,
54 				 const char *name, uint32_t dest);
55 
56 /**
57  * struct rpmsg_endpoint - binds a local rpmsg address to its user
58  * @name: name of the service supported
59  * @rdev: pointer to the rpmsg device
60  * @addr: local address of the endpoint
61  * @dest_addr: address of the default remote endpoint binded.
62  * @cb: user rx callback, return value of this callback is reserved
63  *      for future use, for now, only allow RPMSG_SUCCESS as return value.
64  * @ns_unbind_cb: end point service unbind callback, called when remote
65  *                ept is destroyed.
66  * @node: end point node.
67  * @priv: private data for the driver's use
68  *
69  * In essence, an rpmsg endpoint represents a listener on the rpmsg bus, as
70  * it binds an rpmsg address with an rx callback handler.
71  */
72 struct rpmsg_endpoint {
73 	char name[RPMSG_NAME_SIZE];
74 	struct rpmsg_device *rdev;
75 	uint32_t addr;
76 	uint32_t dest_addr;
77 	rpmsg_ept_cb cb;
78 	rpmsg_ns_unbind_cb ns_unbind_cb;
79 	struct metal_list node;
80 	void *priv;
81 };
82 
83 /**
84  * struct rpmsg_device_ops - RPMsg device operations
85  * @send_offchannel_raw: send RPMsg data
86  * @hold_rx_buffer: hold RPMsg RX buffer
87  * @release_rx_buffer: release RPMsg RX buffer
88  * @get_tx_payload_buffer: get RPMsg TX buffer
89  * @send_offchannel_nocopy: send RPMsg data without copy
90  */
91 struct rpmsg_device_ops {
92 	int (*send_offchannel_raw)(struct rpmsg_device *rdev,
93 				   uint32_t src, uint32_t dst,
94 				   const void *data, int len, int wait);
95 	void (*hold_rx_buffer)(struct rpmsg_device *rdev, void *rxbuf);
96 	void (*release_rx_buffer)(struct rpmsg_device *rdev, void *rxbuf);
97 	void *(*get_tx_payload_buffer)(struct rpmsg_device *rdev,
98 				       uint32_t *len, int wait);
99 	int (*send_offchannel_nocopy)(struct rpmsg_device *rdev,
100 				      uint32_t src, uint32_t dst,
101 				       const void *data, int len);
102 };
103 
104 /**
105  * struct rpmsg_device - representation of a RPMsg device
106  * @endpoints: list of endpoints
107  * @ns_ept: name service endpoint
108  * @bitmap: table endpoint address allocation.
109  * @lock: mutex lock for rpmsg management
110  * @ns_bind_cb: callback handler for name service announcement without local
111  *              endpoints waiting to bind.
112  * @ops: RPMsg device operations
113  * @support_ns: create/destroy namespace message
114  */
115 struct rpmsg_device {
116 	struct metal_list endpoints;
117 	struct rpmsg_endpoint ns_ept;
118 	unsigned long bitmap[metal_bitmap_longs(RPMSG_ADDR_BMP_SIZE)];
119 	metal_mutex_t lock;
120 	rpmsg_ns_bind_cb ns_bind_cb;
121 	struct rpmsg_device_ops ops;
122 	bool support_ns;
123 };
124 
125 /**
126  * rpmsg_send_offchannel_raw() - send a message across to the remote processor,
127  * specifying source and destination address.
128  * @ept: the rpmsg endpoint
129  * @data: payload of the message
130  * @len: length of the payload
131  *
132  * This function sends @data of length @len to the remote @dst address from
133  * the source @src address.
134  * The message will be sent to the remote processor which the channel belongs
135  * to.
136  *
137  * Returns number of bytes it has sent or negative error value on failure.
138  */
139 int rpmsg_send_offchannel_raw(struct rpmsg_endpoint *ept, uint32_t src,
140 			      uint32_t dst, const void *data, int len,
141 			      int wait);
142 
143 /**
144  * rpmsg_send() - send a message across to the remote processor
145  * @ept: the rpmsg endpoint
146  * @data: payload of the message
147  * @len: length of the payload
148  *
149  * This function sends @data of length @len based on the @ept.
150  * The message will be sent to the remote processor which the channel belongs
151  * to, using @ept's source and destination addresses.
152  * In case there are no TX buffers available, the function will block until
153  * one becomes available, or a timeout of 15 seconds elapses. When the latter
154  * happens, -ERESTARTSYS is returned.
155  *
156  * Returns number of bytes it has sent or negative error value on failure.
157  */
rpmsg_send(struct rpmsg_endpoint * ept,const void * data,int len)158 static inline int rpmsg_send(struct rpmsg_endpoint *ept, const void *data,
159 			     int len)
160 {
161 	return rpmsg_send_offchannel_raw(ept, ept->addr, ept->dest_addr, data,
162 					 len, true);
163 }
164 
165 /**
166  * rpmsg_sendto() - send a message across to the remote processor, specify dst
167  * @ept: the rpmsg endpoint
168  * @data: payload of message
169  * @len: length of payload
170  * @dst: destination address
171  *
172  * This function sends @data of length @len to the remote @dst address.
173  * The message will be sent to the remote processor which the @ept
174  * channel belongs to, using @ept's source address.
175  * In case there are no TX buffers available, the function will block until
176  * one becomes available, or a timeout of 15 seconds elapses. When the latter
177  * happens, -ERESTARTSYS is returned.
178  *
179  * Returns number of bytes it has sent or negative error value on failure.
180  */
rpmsg_sendto(struct rpmsg_endpoint * ept,const void * data,int len,uint32_t dst)181 static inline int rpmsg_sendto(struct rpmsg_endpoint *ept, const void *data,
182 			       int len, uint32_t dst)
183 {
184 	return rpmsg_send_offchannel_raw(ept, ept->addr, dst, data, len, true);
185 }
186 
187 /**
188  * rpmsg_send_offchannel() - send a message using explicit src/dst addresses
189  * @ept: the rpmsg endpoint
190  * @src: source address
191  * @dst: destination address
192  * @data: payload of message
193  * @len: length of payload
194  *
195  * This function sends @data of length @len to the remote @dst address,
196  * and uses @src as the source address.
197  * The message will be sent to the remote processor which the @ept
198  * channel belongs to.
199  * In case there are no TX buffers available, the function will block until
200  * one becomes available, or a timeout of 15 seconds elapses. When the latter
201  * happens, -ERESTARTSYS is returned.
202  *
203  * Returns number of bytes it has sent or negative error value on failure.
204  */
rpmsg_send_offchannel(struct rpmsg_endpoint * ept,uint32_t src,uint32_t dst,const void * data,int len)205 static inline int rpmsg_send_offchannel(struct rpmsg_endpoint *ept,
206 					uint32_t src, uint32_t dst,
207 					const void *data, int len)
208 {
209 	return rpmsg_send_offchannel_raw(ept, src, dst, data, len, true);
210 }
211 
212 /**
213  * rpmsg_trysend() - send a message across to the remote processor
214  * @ept: the rpmsg endpoint
215  * @data: payload of message
216  * @len: length of payload
217  *
218  * This function sends @data of length @len on the @ept channel.
219  * The message will be sent to the remote processor which the @ept
220  * channel belongs to, using @ept's source and destination addresses.
221  * In case there are no TX buffers available, the function will immediately
222  * return -ENOMEM without waiting until one becomes available.
223  *
224  * Returns number of bytes it has sent or negative error value on failure.
225  */
rpmsg_trysend(struct rpmsg_endpoint * ept,const void * data,int len)226 static inline int rpmsg_trysend(struct rpmsg_endpoint *ept, const void *data,
227 				int len)
228 {
229 	return rpmsg_send_offchannel_raw(ept, ept->addr, ept->dest_addr, data,
230 					 len, false);
231 }
232 
233 /**
234  * rpmsg_trysendto() - send a message across to the remote processor,
235  * specify dst
236  * @ept: the rpmsg endpoint
237  * @data: payload of message
238  * @len: length of payload
239  * @dst: destination address
240  *
241  * This function sends @data of length @len to the remote @dst address.
242  * The message will be sent to the remote processor which the @ept
243  * channel belongs to, using @ept's source address.
244  * In case there are no TX buffers available, the function will immediately
245  * return -ENOMEM without waiting until one becomes available.
246  *
247  * Returns number of bytes it has sent or negative error value on failure.
248  */
rpmsg_trysendto(struct rpmsg_endpoint * ept,const void * data,int len,uint32_t dst)249 static inline int rpmsg_trysendto(struct rpmsg_endpoint *ept, const void *data,
250 				  int len, uint32_t dst)
251 {
252 	return rpmsg_send_offchannel_raw(ept, ept->addr, dst, data, len, false);
253 }
254 
255 /**
256  * rpmsg_trysend_offchannel() - send a message using explicit src/dst addresses
257  * @ept: the rpmsg endpoint
258  * @src: source address
259  * @dst: destination address
260  * @data: payload of message
261  * @len: length of payload
262  *
263  * This function sends @data of length @len to the remote @dst address,
264  * and uses @src as the source address.
265  * The message will be sent to the remote processor which the @ept
266  * channel belongs to.
267  * In case there are no TX buffers available, the function will immediately
268  * return -ENOMEM without waiting until one becomes available.
269  *
270  * Returns number of bytes it has sent or negative error value on failure.
271  */
rpmsg_trysend_offchannel(struct rpmsg_endpoint * ept,uint32_t src,uint32_t dst,const void * data,int len)272 static inline int rpmsg_trysend_offchannel(struct rpmsg_endpoint *ept,
273 					   uint32_t src, uint32_t dst,
274 					   const void *data, int len)
275 {
276 	return rpmsg_send_offchannel_raw(ept, src, dst, data, len, false);
277 }
278 
279 /**
280  * @brief Holds the rx buffer for usage outside the receive callback.
281  *
282  * Calling this function prevents the RPMsg receive buffer from being released
283  * back to the pool of shmem buffers. This API can only be called at rx
284  * callback context (rpmsg_rx_cb_t). With this API, the application doesn't
285  * need to copy the message in rx callback. Instead, the rx buffer base address
286  * is saved in application context and further processed in application
287  * process. After the message is processed, the application can release the rx
288  * buffer for future reuse in vring by calling the rpmsg_release_rx_buffer()
289  * function.
290  *
291  * @param: ept The rpmsg endpoint
292  * @param: rxbuf RX buffer with message payload
293  *
294  * @see rpmsg_release_rx_buffer
295  */
296 void rpmsg_hold_rx_buffer(struct rpmsg_endpoint *ept, void *rxbuf);
297 
298 /**
299  * @brief Releases the rx buffer for future reuse in vring.
300  *
301  * This API can be called at process context when the message in rx buffer is
302  * processed.
303  *
304  * @ept: the rpmsg endpoint
305  * @rxbuf: rx buffer with message payload
306  *
307  * @see rpmsg_hold_rx_buffer
308  */
309 void rpmsg_release_rx_buffer(struct rpmsg_endpoint *ept, void *rxbuf);
310 
311 /**
312  * @brief Gets the tx buffer for message payload.
313  *
314  * This API can only be called at process context to get the tx buffer in vring.
315  * By this way, the application can directly put its message into the vring tx
316  * buffer without copy from an application buffer.
317  * It is the application responsibility to correctly fill the allocated tx
318  * buffer by data and passing correct parameters to the rpmsg_send_nocopy() or
319  * rpmsg_sendto_nocopy() function to perform data no-copy-send mechanism.
320  *
321  * @ept:  Pointer to rpmsg endpoint
322  * @len:  Pointer to store tx buffer size
323  * @wait: Boolean, wait or not for buffer to become available
324  *
325  * @return The tx buffer address on success and NULL on failure
326  *
327  * @see rpmsg_send_offchannel_nocopy
328  * @see rpmsg_sendto_nocopy
329  * @see rpmsg_send_nocopy
330  */
331 void *rpmsg_get_tx_payload_buffer(struct rpmsg_endpoint *ept,
332 				  uint32_t *len, int wait);
333 
334 /**
335  * rpmsg_send_offchannel_nocopy() - send a message in tx buffer reserved by
336  * rpmsg_get_tx_payload_buffer() across to the remote processor.
337  *
338  * This function sends buf of length len to the remote dst address,
339  * and uses src as the source address.
340  * The message will be sent to the remote processor which the ept
341  * endpoint belongs to.
342  * The application has to take the responsibility for:
343  *  1. tx buffer reserved (rpmsg_get_tx_payload_buffer() )
344  *  2. filling the data to be sent into the pre-allocated tx buffer
345  *  3. not exceeding the buffer size when filling the data
346  *  4. data cache coherency
347  *
348  * After the rpmsg_send_offchannel_nocopy() function is issued the tx buffer is
349  * no more owned by the sending task and must not be touched anymore unless the
350  * rpmsg_send_offchannel_nocopy() function fails and returns an error. In that
351  * case application should try to re-issue the rpmsg_send_offchannel_nocopy()
352  * again.
353  *
354  * @ept:  The rpmsg endpoint
355  * @src:  The rpmsg endpoint local address
356  * @dst:  The rpmsg endpoint remote address
357  * @data: TX buffer with message filled
358  * @len:  Length of payload
359  *
360  * @return number of bytes it has sent or negative error value on failure.
361  *
362  * @see rpmsg_get_tx_payload_buffer
363  * @see rpmsg_sendto_nocopy
364  * @see rpmsg_send_nocopy
365  */
366 int rpmsg_send_offchannel_nocopy(struct rpmsg_endpoint *ept, uint32_t src,
367 				 uint32_t dst, const void *data, int len);
368 
369 /**
370  * @brief rpmsg_sendto_nocopy() - sends a message in tx buffer allocated by
371  * rpmsg_get_tx_payload_buffer() across to the remote processor, specify dst.
372  *
373  * This function sends buf of length len to the remote dst address.
374  * The message will be sent to the remote processor which the ept
375  * endpoint belongs to, using ept's source address.
376  * The application has to take the responsibility for:
377  *  1. tx buffer allocation (rpmsg_get_tx_payload_buffer() )
378  *  2. filling the data to be sent into the pre-allocated tx buffer
379  *  3. not exceeding the buffer size when filling the data
380  *  4. data cache coherency
381  *
382  * After the rpmsg_sendto_nocopy() function is issued the tx buffer is no more
383  * owned by the sending task and must not be touched anymore unless the
384  * rpmsg_sendto_nocopy() function fails and returns an error. In that case the
385  * application should try to re-issue the rpmsg_sendto_nocopy() again.
386  *
387  * @ept:  The rpmsg endpoint
388  * @data: TX buffer with message filled
389  * @len:  Length of payload
390  * @dst:  Destination address
391  *
392  * @return number of bytes it has sent or negative error value on failure.
393  *
394  * @see rpmsg_get_tx_payload_buffer
395  * @see rpmsg_send_offchannel_nocopy
396  * @see rpmsg_send_nocopy
397  */
rpmsg_sendto_nocopy(struct rpmsg_endpoint * ept,const void * data,int len,uint32_t dst)398 static inline int rpmsg_sendto_nocopy(struct rpmsg_endpoint *ept,
399 				      const void *data, int len, uint32_t dst)
400 {
401 	return rpmsg_send_offchannel_nocopy(ept, ept->addr, dst, data, len);
402 }
403 
404 /**
405  * rpmsg_send_nocopy() - send a message in tx buffer reserved by
406  * rpmsg_get_tx_payload_buffer() across to the remote processor.
407  *
408  * This function sends buf of length len on the ept endpoint.
409  * The message will be sent to the remote processor which the ept
410  * endpoint belongs to, using ept's source and destination addresses.
411  * The application has to take the responsibility for:
412  *  1. tx buffer reserved (rpmsg_get_tx_payload_buffer() )
413  *  2. filling the data to be sent into the pre-allocated tx buffer
414  *  3. not exceeding the buffer size when filling the data
415  *  4. data cache coherency
416  *
417  * After the rpmsg_send_nocopy() function is issued the tx buffer is no more
418  * owned by the sending task and must not be touched anymore unless the
419  * rpmsg_send_nocopy() function fails and returns an error. In that case the
420  * application should try to re-issue the rpmsg_send_nocopy() again.
421  *
422  * @ept:  The rpmsg endpoint
423  * @data: TX buffer with message filled
424  * @len:  Length of payload
425  *
426  * @return number of bytes it has sent or negative error value on failure.
427  *
428  * @see rpmsg_get_tx_payload_buffer
429  * @see rpmsg_send_offchannel_nocopy
430  * @see rpmsg_sendto_nocopy
431  */
rpmsg_send_nocopy(struct rpmsg_endpoint * ept,const void * data,int len)432 static inline int rpmsg_send_nocopy(struct rpmsg_endpoint *ept,
433 				    const void *data, int len)
434 {
435 	return rpmsg_send_offchannel_nocopy(ept, ept->addr,
436 					    ept->dest_addr, data, len);
437 }
438 
439 /**
440  * rpmsg_init_ept - initialize rpmsg endpoint
441  *
442  * Initialize an RPMsg endpoint with a name, source address,
443  * remoteproc address, endpoint callback, and destroy endpoint callback.
444  *
445  * API deprecated since release v2020.10
446  *
447  * @ept: pointer to rpmsg endpoint
448  * @name: service name associated to the endpoint
449  * @src: local address of the endpoint
450  * @dest: target address of the endpoint
451  * @cb: endpoint callback
452  * @ns_unbind_cb: end point service unbind callback, called when remote ept is
453  *                destroyed.
454  */
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)455 __deprecated static inline void rpmsg_init_ept(struct rpmsg_endpoint *ept,
456 					       const char *name,
457 					       uint32_t src, uint32_t dest,
458 					       rpmsg_ept_cb cb,
459 					       rpmsg_ns_unbind_cb ns_unbind_cb)
460 {
461 	strncpy(ept->name, name ? name : "", sizeof(ept->name));
462 	ept->addr = src;
463 	ept->dest_addr = dest;
464 	ept->cb = cb;
465 	ept->ns_unbind_cb = ns_unbind_cb;
466 }
467 
468 /**
469  * rpmsg_create_ept - create rpmsg endpoint and register it to rpmsg device
470  *
471  * Create a RPMsg endpoint, initialize it with a name, source address,
472  * remoteproc address, endpoint callback, and destroy endpoint callback,
473  * and register it to the RPMsg device.
474  *
475  * @ept: pointer to rpmsg endpoint
476  * @name: service name associated to the endpoint
477  * @src: local address of the endpoint
478  * @dest: target address of the endpoint
479  * @cb: endpoint callback
480  * @ns_unbind_cb: end point service unbind callback, called when remote ept is
481  *                destroyed.
482  *
483  * In essence, an rpmsg endpoint represents a listener on the rpmsg bus, as
484  * it binds an rpmsg address with an rx callback handler.
485  *
486  * Rpmsg client should create an endpoint to discuss with remote. rpmsg client
487  * provide at least a channel name, a callback for message notification and by
488  * default endpoint source address should be set to RPMSG_ADDR_ANY.
489  *
490  * As an option Some rpmsg clients can specify an endpoint with a specific
491  * source address.
492  */
493 
494 int rpmsg_create_ept(struct rpmsg_endpoint *ept, struct rpmsg_device *rdev,
495 		     const char *name, uint32_t src, uint32_t dest,
496 		     rpmsg_ept_cb cb, rpmsg_ns_unbind_cb ns_unbind_cb);
497 
498 /**
499  * rpmsg_destroy_ept - destroy rpmsg endpoint and unregister it from rpmsg
500  *                     device
501  *
502  * @ept: pointer to the rpmsg endpoint
503  *
504  * It unregisters the rpmsg endpoint from the rpmsg device and calls the
505  * destroy endpoint callback if it is provided.
506  */
507 void rpmsg_destroy_ept(struct rpmsg_endpoint *ept);
508 
509 /**
510  * is_rpmsg_ept_ready - check if the rpmsg endpoint ready to send
511  *
512  * @ept: pointer to rpmsg endpoint
513  *
514  * Returns 1 if the rpmsg endpoint has both local addr and destination
515  * addr set, 0 otherwise
516  */
is_rpmsg_ept_ready(struct rpmsg_endpoint * ept)517 static inline unsigned int is_rpmsg_ept_ready(struct rpmsg_endpoint *ept)
518 {
519 	return ept && ept->rdev && ept->dest_addr != RPMSG_ADDR_ANY;
520 }
521 
522 #if defined __cplusplus
523 }
524 #endif
525 
526 #endif				/* _RPMSG_H_ */
527