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 #define RPMSG_ERR_PERM (RPMSG_ERROR_BASE - 8)
46 #define RPMSG_EOPNOTSUPP (RPMSG_ERROR_BASE - 9)
47
48 struct rpmsg_endpoint;
49 struct rpmsg_device;
50
51 /* Returns positive value on success or negative error value on failure */
52 typedef int (*rpmsg_ept_cb)(struct rpmsg_endpoint *ept, void *data,
53 size_t len, uint32_t src, void *priv);
54 typedef void (*rpmsg_ept_release_cb)(struct rpmsg_endpoint *ept);
55 typedef void (*rpmsg_ns_unbind_cb)(struct rpmsg_endpoint *ept);
56 typedef void (*rpmsg_ns_bind_cb)(struct rpmsg_device *rdev,
57 const char *name, uint32_t dest);
58
59 /**
60 * @brief Structure that binds a local RPMsg address to its user
61 *
62 * In essence, an RPMsg endpoint represents a listener on the RPMsg bus, as
63 * it binds an RPMsg address with an rx callback handler.
64 */
65 struct rpmsg_endpoint {
66 /** Name of the service supported */
67 char name[RPMSG_NAME_SIZE];
68
69 /** Pointer to the RPMsg device */
70 struct rpmsg_device *rdev;
71
72 /** Local address of the endpoint */
73 uint32_t addr;
74
75 /** Address of the default remote endpoint binded */
76 uint32_t dest_addr;
77
78 /** Reference count for determining whether the endpoint can be deallocated */
79 uint32_t refcnt;
80
81 /** Callback to inform the user that the endpoint allocation can be safely removed */
82 rpmsg_ept_release_cb release_cb;
83
84 /**
85 * User rx callback, return value of this callback is reserved for future
86 * use, for now, only allow RPMSG_SUCCESS as return value
87 */
88 rpmsg_ept_cb cb;
89
90 /** Endpoint service unbind callback, called when remote ept is destroyed */
91 rpmsg_ns_unbind_cb ns_unbind_cb;
92
93 /** Endpoint node */
94 struct metal_list node;
95
96 /** Private data for the driver's use */
97 void *priv;
98 };
99
100 /** @brief RPMsg device operations */
101 struct rpmsg_device_ops {
102 /** Send RPMsg data */
103 int (*send_offchannel_raw)(struct rpmsg_device *rdev,
104 uint32_t src, uint32_t dst,
105 const void *data, int len, int wait);
106
107 /** Hold RPMsg RX buffer */
108 void (*hold_rx_buffer)(struct rpmsg_device *rdev, void *rxbuf);
109
110 /** Release RPMsg RX buffer */
111 void (*release_rx_buffer)(struct rpmsg_device *rdev, void *rxbuf);
112
113 /** Get RPMsg TX buffer */
114 void *(*get_tx_payload_buffer)(struct rpmsg_device *rdev,
115 uint32_t *len, int wait);
116
117 /** Send RPMsg data without copy */
118 int (*send_offchannel_nocopy)(struct rpmsg_device *rdev,
119 uint32_t src, uint32_t dst,
120 const void *data, int len);
121
122 /** Release RPMsg TX buffer */
123 int (*release_tx_buffer)(struct rpmsg_device *rdev, void *txbuf);
124
125 /** Get RPMsg RX buffer size */
126 int (*get_rx_buffer_size)(struct rpmsg_device *rdev);
127
128 /** Get RPMsg TX buffer size */
129 int (*get_tx_buffer_size)(struct rpmsg_device *rdev);
130 };
131
132 /** @brief Representation of a RPMsg device */
133 struct rpmsg_device {
134 /** List of endpoints */
135 struct metal_list endpoints;
136
137 /** Name service endpoint */
138 struct rpmsg_endpoint ns_ept;
139
140 /** Table endpoint address allocation */
141 unsigned long bitmap[metal_bitmap_longs(RPMSG_ADDR_BMP_SIZE)];
142 unsigned int bitnext;
143
144 /** Mutex lock for RPMsg management */
145 metal_mutex_t lock;
146
147 /** Callback handler for name service announcement without local epts waiting to bind */
148 rpmsg_ns_bind_cb ns_bind_cb;
149
150 /** Callback handler for name service announcement, called when remote ept is destroyed */
151 rpmsg_ns_bind_cb ns_unbind_cb;
152
153 /** RPMsg device operations */
154 struct rpmsg_device_ops ops;
155
156 /** Create/destroy namespace message */
157 bool support_ns;
158 };
159
160 /**
161 * @brief Send a message across to the remote processor,
162 * specifying source and destination address.
163 *
164 * This function sends `data` of length `len` to the remote `dst` address from
165 * the source `src` address.
166 * The message will be sent to the remote processor which the channel belongs
167 * to.
168 *
169 * @param ept The rpmsg endpoint
170 * @param src Source endpoint address of the message
171 * @param dst Destination endpoint address of the message
172 * @param data Payload of the message
173 * @param len Length of the payload
174 * @param wait Boolean value indicating whether to wait on buffers
175 *
176 * @return Number of bytes it has sent or negative error value on failure.
177 */
178 int rpmsg_send_offchannel_raw(struct rpmsg_endpoint *ept, uint32_t src,
179 uint32_t dst, const void *data, int len,
180 int wait);
181
182 /**
183 * @brief Send a message across to the remote processor
184 *
185 * This function sends `data` of length `len` based on the `ept`.
186 * The message will be sent to the remote processor which the channel belongs
187 * to, using `ept`'s source and destination addresses.
188 * In case there are no TX buffers available, the function will block until
189 * one becomes available, or a timeout of 15 seconds elapses. When the latter
190 * happens, -ERESTARTSYS is returned.
191 *
192 * @param ept The rpmsg endpoint
193 * @param data Payload of the message
194 * @param len Length of the payload
195 *
196 * @return Number of bytes it has sent or negative error value on failure.
197 */
rpmsg_send(struct rpmsg_endpoint * ept,const void * data,int len)198 static inline int rpmsg_send(struct rpmsg_endpoint *ept, const void *data,
199 int len)
200 {
201 if (!ept)
202 return RPMSG_ERR_PARAM;
203
204 return rpmsg_send_offchannel_raw(ept, ept->addr, ept->dest_addr, data,
205 len, true);
206 }
207
208 /**
209 * @brief Send a message across to the remote processor, specify dst
210 *
211 * This function sends `data` of length `len` to the remote `dst` address.
212 * The message will be sent to the remote processor which the `ept`
213 * channel belongs to, using `ept`'s source address.
214 * In case there are no TX buffers available, the function will block until
215 * one becomes available, or a timeout of 15 seconds elapses. When the latter
216 * happens, -ERESTARTSYS is returned.
217 *
218 * @param ept The rpmsg endpoint
219 * @param data Payload of message
220 * @param len Length of payload
221 * @param dst Destination address
222 *
223 * @return Number of bytes it has sent or negative error value on failure.
224 */
rpmsg_sendto(struct rpmsg_endpoint * ept,const void * data,int len,uint32_t dst)225 static inline int rpmsg_sendto(struct rpmsg_endpoint *ept, const void *data,
226 int len, uint32_t dst)
227 {
228 if (!ept)
229 return RPMSG_ERR_PARAM;
230
231 return rpmsg_send_offchannel_raw(ept, ept->addr, dst, data, len, true);
232 }
233
234 /**
235 * @brief Send a message using explicit src/dst addresses
236 *
237 * This function sends `data` of length `len` to the remote `dst` address,
238 * and uses `src` as the source address.
239 * The message will be sent to the remote processor which the `ept`
240 * channel belongs to.
241 * In case there are no TX buffers available, the function will block until
242 * one becomes available, or a timeout of 15 seconds elapses. When the latter
243 * happens, -ERESTARTSYS is returned.
244 *
245 * @param ept The rpmsg endpoint
246 * @param src Source address
247 * @param dst Destination address
248 * @param data Payload of message
249 * @param len Length of payload
250 *
251 * @return Number of bytes it has sent or negative error value on failure.
252 */
rpmsg_send_offchannel(struct rpmsg_endpoint * ept,uint32_t src,uint32_t dst,const void * data,int len)253 static inline int rpmsg_send_offchannel(struct rpmsg_endpoint *ept,
254 uint32_t src, uint32_t dst,
255 const void *data, int len)
256 {
257 return rpmsg_send_offchannel_raw(ept, src, dst, data, len, true);
258 }
259
260 /**
261 * @brief Send a message across to the remote processor
262 *
263 * This function sends `data` of length `len` on the `ept` channel.
264 * The message will be sent to the remote processor which the `ept`
265 * channel belongs to, using `ept`'s source and destination addresses.
266 * In case there are no TX buffers available, the function will immediately
267 * return -ENOMEM without waiting until one becomes available.
268 *
269 * @param ept The rpmsg endpoint
270 * @param data Payload of message
271 * @param len Length of payload
272 *
273 * @return Number of bytes it has sent or negative error value on failure.
274 */
rpmsg_trysend(struct rpmsg_endpoint * ept,const void * data,int len)275 static inline int rpmsg_trysend(struct rpmsg_endpoint *ept, const void *data,
276 int len)
277 {
278 if (!ept)
279 return RPMSG_ERR_PARAM;
280
281 return rpmsg_send_offchannel_raw(ept, ept->addr, ept->dest_addr, data,
282 len, false);
283 }
284
285 /**
286 * @brief Send a message across to the remote processor, specify dst
287 *
288 * This function sends `data` of length `len` to the remote `dst` address.
289 * The message will be sent to the remote processor which the `ept`
290 * channel belongs to, using `ept`'s source address.
291 * In case there are no TX buffers available, the function will immediately
292 * return -ENOMEM without waiting until one becomes available.
293 *
294 * @param ept The rpmsg endpoint
295 * @param data Payload of message
296 * @param len Length of payload
297 * @param dst Destination address
298 *
299 * @return Number of bytes it has sent or negative error value on failure.
300 */
rpmsg_trysendto(struct rpmsg_endpoint * ept,const void * data,int len,uint32_t dst)301 static inline int rpmsg_trysendto(struct rpmsg_endpoint *ept, const void *data,
302 int len, uint32_t dst)
303 {
304 if (!ept)
305 return RPMSG_ERR_PARAM;
306
307 return rpmsg_send_offchannel_raw(ept, ept->addr, dst, data, len, false);
308 }
309
310 /**
311 * @brief Send a message using explicit src/dst addresses
312 *
313 * This function sends `data` of length `len` to the remote `dst` address,
314 * and uses `src` as the source address.
315 * The message will be sent to the remote processor which the `ept`
316 * channel belongs to.
317 * In case there are no TX buffers available, the function will immediately
318 * return -ENOMEM without waiting until one becomes available.
319 *
320 * @param ept The rpmsg endpoint
321 * @param src Source address
322 * @param dst Destination address
323 * @param data Payload of message
324 * @param len Length of payload
325 *
326 * @return Number of bytes it has sent or negative error value on failure.
327 */
rpmsg_trysend_offchannel(struct rpmsg_endpoint * ept,uint32_t src,uint32_t dst,const void * data,int len)328 static inline int rpmsg_trysend_offchannel(struct rpmsg_endpoint *ept,
329 uint32_t src, uint32_t dst,
330 const void *data, int len)
331 {
332 return rpmsg_send_offchannel_raw(ept, src, dst, data, len, false);
333 }
334
335 /**
336 * @brief Holds the rx buffer for usage outside the receive callback.
337 *
338 * Calling this function prevents the RPMsg receive buffer from being released
339 * back to the pool of shmem buffers. This API can only be called at rx
340 * callback context (rpmsg_rx_cb_t). With this API, the application doesn't
341 * need to copy the message in rx callback. Instead, the rx buffer base address
342 * is saved in application context and further processed in application
343 * process. After the message is processed, the application can release the rx
344 * buffer for future reuse in vring by calling the rpmsg_release_rx_buffer()
345 * function.
346 *
347 * @param ept The rpmsg endpoint
348 * @param rxbuf RX buffer with message payload
349 *
350 * @see rpmsg_release_rx_buffer
351 */
352 void rpmsg_hold_rx_buffer(struct rpmsg_endpoint *ept, void *rxbuf);
353
354 /**
355 * @brief Releases the rx buffer for future reuse in vring.
356 *
357 * This API can be called at process context when the message in rx buffer is
358 * processed.
359 *
360 * @param ept The rpmsg endpoint
361 * @param rxbuf rx buffer with message payload
362 *
363 * @see rpmsg_hold_rx_buffer
364 */
365 void rpmsg_release_rx_buffer(struct rpmsg_endpoint *ept, void *rxbuf);
366
367 /**
368 * @brief Gets the tx buffer for message payload.
369 *
370 * This API can only be called at process context to get the tx buffer in vring.
371 * By this way, the application can directly put its message into the vring tx
372 * buffer without copy from an application buffer.
373 * It is the application responsibility to correctly fill the allocated tx
374 * buffer by data and passing correct parameters to the rpmsg_send_nocopy() or
375 * rpmsg_sendto_nocopy() function to perform data no-copy-send mechanism.
376 *
377 * @param ept Pointer to rpmsg endpoint
378 * @param len Pointer to store tx buffer size
379 * @param wait Boolean, wait or not for buffer to become available
380 *
381 * @return The tx buffer address on success and NULL on failure
382 *
383 * @see rpmsg_send_offchannel_nocopy
384 * @see rpmsg_sendto_nocopy
385 * @see rpmsg_send_nocopy
386 */
387 void *rpmsg_get_tx_payload_buffer(struct rpmsg_endpoint *ept,
388 uint32_t *len, int wait);
389
390 /**
391 * @brief Releases unused buffer.
392 *
393 * This API can be called when the Tx buffer reserved by
394 * rpmsg_get_tx_payload_buffer needs to be released without having been sent to
395 * the remote side.
396 *
397 * Note that the rpmsg virtio is not able to detect if a buffer has already
398 * been released. The user must prevent a double release (e.g. by resetting its
399 * buffer pointer to zero after the release).
400 *
401 * @param ept The rpmsg endpoint
402 * @param txbuf tx buffer with message payload
403 *
404 * @return
405 * - RPMSG_SUCCESS on success
406 * - RPMSG_ERR_PARAM on invalid parameter
407 * - RPMSG_ERR_PERM if service not implemented
408 *
409 * @see rpmsg_get_tx_payload_buffer
410 */
411 int rpmsg_release_tx_buffer(struct rpmsg_endpoint *ept, void *txbuf);
412
413 /**
414 * @brief Get RPMsg Tx buffer size
415 *
416 * @param ept The rpmsg endpoint
417 *
418 * @return
419 * - Next available Tx buffer size on success
420 * - RPMSG_ERR_PARAM on invalid parameter
421 * - RPMSG_ERR_PERM if service not implemented
422 */
423 int rpmsg_get_tx_buffer_size(struct rpmsg_endpoint *ept);
424
425 /**
426 * @brief Get RPMsg Rx buffer size
427 *
428 * @param ept The rpmsg endpoint
429 *
430 * @return
431 * - Next available Rx buffer size on success
432 * - RPMSG_ERR_PARAM on invalid parameter
433 * - RPMSG_ERR_PERM if service not implemented
434 */
435 int rpmsg_get_rx_buffer_size(struct rpmsg_endpoint *ept);
436
437 /**
438 * @brief Send a message in tx buffer reserved by
439 * rpmsg_get_tx_payload_buffer() across to the remote processor.
440 *
441 * This function sends buf of length len to the remote dst address,
442 * and uses src as the source address.
443 * The message will be sent to the remote processor which the ept
444 * endpoint belongs to.
445 * The application has to take the responsibility for:
446 * 1. tx buffer reserved (rpmsg_get_tx_payload_buffer() )
447 * 2. filling the data to be sent into the pre-allocated tx buffer
448 * 3. not exceeding the buffer size when filling the data
449 * 4. data cache coherency
450 *
451 * After the rpmsg_send_offchannel_nocopy() function is issued the tx buffer is
452 * no more owned by the sending task and must not be touched anymore unless the
453 * rpmsg_send_offchannel_nocopy() function fails and returns an error. In that
454 * case application should try to re-issue the rpmsg_send_offchannel_nocopy()
455 * again.
456 *
457 * @param ept The rpmsg endpoint
458 * @param src The rpmsg endpoint local address
459 * @param dst The rpmsg endpoint remote address
460 * @param data TX buffer with message filled
461 * @param len Length of payload
462 *
463 * @return Number of bytes it has sent or negative error value on failure.
464 *
465 * @see rpmsg_get_tx_payload_buffer
466 * @see rpmsg_sendto_nocopy
467 * @see rpmsg_send_nocopy
468 */
469 int rpmsg_send_offchannel_nocopy(struct rpmsg_endpoint *ept, uint32_t src,
470 uint32_t dst, const void *data, int len);
471
472 /**
473 * @brief Sends a message in tx buffer allocated by
474 * rpmsg_get_tx_payload_buffer() across to the remote processor, specify dst.
475 *
476 * This function sends buf of length len to the remote dst address.
477 * The message will be sent to the remote processor which the ept
478 * endpoint belongs to, using ept's source address.
479 * The application has to take the responsibility for:
480 * 1. tx buffer allocation (rpmsg_get_tx_payload_buffer() )
481 * 2. filling the data to be sent into the pre-allocated tx buffer
482 * 3. not exceeding the buffer size when filling the data
483 * 4. data cache coherency
484 *
485 * After the rpmsg_sendto_nocopy() function is issued the tx buffer is no more
486 * owned by the sending task and must not be touched anymore unless the
487 * rpmsg_sendto_nocopy() function fails and returns an error. In that case the
488 * application should try to re-issue the rpmsg_sendto_nocopy() again.
489 *
490 * @param ept The rpmsg endpoint
491 * @param data TX buffer with message filled
492 * @param len Length of payload
493 * @param dst Destination address
494 *
495 * @return Number of bytes it has sent or negative error value on failure.
496 *
497 * @see rpmsg_get_tx_payload_buffer
498 * @see rpmsg_send_offchannel_nocopy
499 * @see rpmsg_send_nocopy
500 */
rpmsg_sendto_nocopy(struct rpmsg_endpoint * ept,const void * data,int len,uint32_t dst)501 static inline int rpmsg_sendto_nocopy(struct rpmsg_endpoint *ept,
502 const void *data, int len, uint32_t dst)
503 {
504 if (!ept)
505 return RPMSG_ERR_PARAM;
506
507 return rpmsg_send_offchannel_nocopy(ept, ept->addr, dst, data, len);
508 }
509
510 /**
511 * @brief Send a message in tx buffer reserved by
512 * rpmsg_get_tx_payload_buffer() across to the remote processor.
513 *
514 * This function sends buf of length len on the ept endpoint.
515 * The message will be sent to the remote processor which the ept
516 * endpoint belongs to, using ept's source and destination addresses.
517 * The application has to take the responsibility for:
518 * 1. tx buffer reserved (rpmsg_get_tx_payload_buffer() )
519 * 2. filling the data to be sent into the pre-allocated tx buffer
520 * 3. not exceeding the buffer size when filling the data
521 * 4. data cache coherency
522 *
523 * After the rpmsg_send_nocopy() function is issued the tx buffer is no more
524 * owned by the sending task and must not be touched anymore unless the
525 * rpmsg_send_nocopy() function fails and returns an error. In that case the
526 * application should try to re-issue the rpmsg_send_nocopy() again.
527 *
528 * @param ept The rpmsg endpoint
529 * @param data TX buffer with message filled
530 * @param len Length of payload
531 *
532 * @return Number of bytes it has sent or negative error value on failure.
533 *
534 * @see rpmsg_get_tx_payload_buffer
535 * @see rpmsg_send_offchannel_nocopy
536 * @see rpmsg_sendto_nocopy
537 */
rpmsg_send_nocopy(struct rpmsg_endpoint * ept,const void * data,int len)538 static inline int rpmsg_send_nocopy(struct rpmsg_endpoint *ept,
539 const void *data, int len)
540 {
541 if (!ept)
542 return RPMSG_ERR_PARAM;
543
544 return rpmsg_send_offchannel_nocopy(ept, ept->addr,
545 ept->dest_addr, data, len);
546 }
547
548 /**
549 * @brief Create rpmsg endpoint and register it to rpmsg device
550 *
551 * Create a RPMsg endpoint, initialize it with a name, source address,
552 * remoteproc address, endpoint callback, and destroy endpoint callback,
553 * and register it to the RPMsg device.
554 *
555 * In essence, an rpmsg endpoint represents a listener on the rpmsg bus, as
556 * it binds an rpmsg address with an rx callback handler.
557 *
558 * Rpmsg client should create an endpoint to discuss with remote. rpmsg client
559 * provide at least a channel name, a callback for message notification and by
560 * default endpoint source address should be set to RPMSG_ADDR_ANY.
561 *
562 * As an option Some rpmsg clients can specify an endpoint with a specific
563 * source address.
564 *
565 * @param ept Pointer to rpmsg endpoint
566 * @param rdev RPMsg device associated with the endpoint
567 * @param name Service name associated to the endpoint (maximum size \ref RPMSG_NAME_SIZE)
568 * @param src Local address of the endpoint
569 * @param dest Target address of the endpoint
570 * @param cb Endpoint callback
571 * @param ns_unbind_cb Endpoint service unbind callback, called when remote
572 * ept is destroyed.
573 *
574 * @return 0 on success, or negative error value on failure.
575 */
576 int rpmsg_create_ept(struct rpmsg_endpoint *ept, struct rpmsg_device *rdev,
577 const char *name, uint32_t src, uint32_t dest,
578 rpmsg_ept_cb cb, rpmsg_ns_unbind_cb ns_unbind_cb);
579
580 /**
581 * @brief Destroy rpmsg endpoint and unregister it from rpmsg device
582 *
583 * It unregisters the rpmsg endpoint from the rpmsg device and calls the
584 * destroy endpoint callback if it is provided.
585 *
586 * @param ept Pointer to the rpmsg endpoint
587 */
588 void rpmsg_destroy_ept(struct rpmsg_endpoint *ept);
589
590 /**
591 * @brief Check if the rpmsg endpoint ready to send
592 *
593 * @param ept Pointer to rpmsg endpoint
594 *
595 * @return 1 if the rpmsg endpoint has both local addr and destination
596 * addr set, 0 otherwise
597 */
is_rpmsg_ept_ready(struct rpmsg_endpoint * ept)598 static inline unsigned int is_rpmsg_ept_ready(struct rpmsg_endpoint *ept)
599 {
600 return ept && ept->rdev && ept->dest_addr != RPMSG_ADDR_ANY;
601 }
602
603 #if defined __cplusplus
604 }
605 #endif
606
607 #endif /* _RPMSG_H_ */
608