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