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