blob: 24b7a9e1a5f99695e6f74d1f79694a999271f903 [file] [log] [blame]
Mauro Carvalho Chehabaf3137f2017-05-17 06:53:44 -03001============================================
Ohad Ben-Cohenbcabbcc2011-10-20 21:10:55 +02002Remote Processor Messaging (rpmsg) Framework
Mauro Carvalho Chehabaf3137f2017-05-17 06:53:44 -03003============================================
Ohad Ben-Cohenbcabbcc2011-10-20 21:10:55 +02004
Mauro Carvalho Chehabaf3137f2017-05-17 06:53:44 -03005.. note::
Ohad Ben-Cohenbcabbcc2011-10-20 21:10:55 +02006
Mauro Carvalho Chehabaf3137f2017-05-17 06:53:44 -03007 This document describes the rpmsg bus and how to write rpmsg drivers.
8 To learn how to add rpmsg support for new platforms, check out remoteproc.txt
9 (also a resident of Documentation/).
10
11Introduction
12============
Ohad Ben-Cohenbcabbcc2011-10-20 21:10:55 +020013
14Modern SoCs typically employ heterogeneous remote processor devices in
15asymmetric multiprocessing (AMP) configurations, which may be running
16different instances of operating system, whether it's Linux or any other
17flavor of real-time OS.
18
19OMAP4, for example, has dual Cortex-A9, dual Cortex-M3 and a C64x+ DSP.
20Typically, the dual cortex-A9 is running Linux in a SMP configuration,
21and each of the other three cores (two M3 cores and a DSP) is running
22its own instance of RTOS in an AMP configuration.
23
24Typically AMP remote processors employ dedicated DSP codecs and multimedia
25hardware accelerators, and therefore are often used to offload CPU-intensive
26multimedia tasks from the main application processor.
27
28These remote processors could also be used to control latency-sensitive
29sensors, drive random hardware blocks, or just perform background tasks
30while the main CPU is idling.
31
32Users of those remote processors can either be userland apps (e.g. multimedia
33frameworks talking with remote OMX components) or kernel drivers (controlling
34hardware accessible only by the remote processor, reserving kernel-controlled
35resources on behalf of the remote processor, etc..).
36
37Rpmsg is a virtio-based messaging bus that allows kernel drivers to communicate
38with remote processors available on the system. In turn, drivers could then
39expose appropriate user space interfaces, if needed.
40
41When writing a driver that exposes rpmsg communication to userland, please
42keep in mind that remote processors might have direct access to the
43system's physical memory and other sensitive hardware resources (e.g. on
44OMAP4, remote cores and hardware accelerators may have direct access to the
45physical memory, gpio banks, dma controllers, i2c bus, gptimers, mailbox
46devices, hwspinlocks, etc..). Moreover, those remote processors might be
47running RTOS where every task can access the entire memory/devices exposed
48to the processor. To minimize the risks of rogue (or buggy) userland code
49exploiting remote bugs, and by that taking over the system, it is often
50desired to limit userland to specific rpmsg channels (see definition below)
51it can send messages on, and if possible, minimize how much control
52it has over the content of the messages.
53
54Every rpmsg device is a communication channel with a remote processor (thus
55rpmsg devices are called channels). Channels are identified by a textual name
56and have a local ("source") rpmsg address, and remote ("destination") rpmsg
57address.
58
59When a driver starts listening on a channel, its rx callback is bound with
60a unique rpmsg local address (a 32-bit integer). This way when inbound messages
61arrive, the rpmsg core dispatches them to the appropriate driver according
62to their destination address (this is done by invoking the driver's rx handler
63with the payload of the inbound message).
64
65
Mauro Carvalho Chehabaf3137f2017-05-17 06:53:44 -030066User API
67========
68
69::
Ohad Ben-Cohenbcabbcc2011-10-20 21:10:55 +020070
71 int rpmsg_send(struct rpmsg_channel *rpdev, void *data, int len);
Ohad Ben-Cohenbcabbcc2011-10-20 21:10:55 +020072
Mauro Carvalho Chehabaf3137f2017-05-17 06:53:44 -030073sends a message across to the remote processor on a given channel.
74The caller should specify the channel, the data it wants to send,
75and its length (in bytes). The message will be sent on the specified
76channel, i.e. its source and destination address fields will be
77set to the channel's src and dst addresses.
78
79In case there are no TX buffers available, the function will block until
80one becomes available (i.e. until the remote processor consumes
81a tx buffer and puts it back on virtio's used descriptor ring),
82or a timeout of 15 seconds elapses. When the latter happens,
83-ERESTARTSYS is returned.
84
85The function can only be called from a process context (for now).
86Returns 0 on success and an appropriate error value on failure.
87
88::
Ohad Ben-Cohenbcabbcc2011-10-20 21:10:55 +020089
90 int rpmsg_sendto(struct rpmsg_channel *rpdev, void *data, int len, u32 dst);
Ohad Ben-Cohenbcabbcc2011-10-20 21:10:55 +020091
Mauro Carvalho Chehabaf3137f2017-05-17 06:53:44 -030092sends a message across to the remote processor on a given channel,
93to a destination address provided by the caller.
94
95The caller should specify the channel, the data it wants to send,
96its length (in bytes), and an explicit destination address.
97
98The message will then be sent to the remote processor to which the
99channel belongs, using the channel's src address, and the user-provided
100dst address (thus the channel's dst address will be ignored).
101
102In case there are no TX buffers available, the function will block until
103one becomes available (i.e. until the remote processor consumes
104a tx buffer and puts it back on virtio's used descriptor ring),
105or a timeout of 15 seconds elapses. When the latter happens,
106-ERESTARTSYS is returned.
107
108The function can only be called from a process context (for now).
109Returns 0 on success and an appropriate error value on failure.
110
111::
Ohad Ben-Cohenbcabbcc2011-10-20 21:10:55 +0200112
113 int rpmsg_send_offchannel(struct rpmsg_channel *rpdev, u32 src, u32 dst,
114 void *data, int len);
Ohad Ben-Cohenbcabbcc2011-10-20 21:10:55 +0200115
Mauro Carvalho Chehabaf3137f2017-05-17 06:53:44 -0300116
117sends a message across to the remote processor, using the src and dst
118addresses provided by the user.
119
120The caller should specify the channel, the data it wants to send,
121its length (in bytes), and explicit source and destination addresses.
122The message will then be sent to the remote processor to which the
123channel belongs, but the channel's src and dst addresses will be
124ignored (and the user-provided addresses will be used instead).
125
126In case there are no TX buffers available, the function will block until
127one becomes available (i.e. until the remote processor consumes
128a tx buffer and puts it back on virtio's used descriptor ring),
129or a timeout of 15 seconds elapses. When the latter happens,
130-ERESTARTSYS is returned.
131
132The function can only be called from a process context (for now).
133Returns 0 on success and an appropriate error value on failure.
134
135::
Ohad Ben-Cohenbcabbcc2011-10-20 21:10:55 +0200136
137 int rpmsg_trysend(struct rpmsg_channel *rpdev, void *data, int len);
Ohad Ben-Cohenbcabbcc2011-10-20 21:10:55 +0200138
Mauro Carvalho Chehabaf3137f2017-05-17 06:53:44 -0300139sends a message across to the remote processor on a given channel.
140The caller should specify the channel, the data it wants to send,
141and its length (in bytes). The message will be sent on the specified
142channel, i.e. its source and destination address fields will be
143set to the channel's src and dst addresses.
144
145In case there are no TX buffers available, the function will immediately
146return -ENOMEM without waiting until one becomes available.
147
148The function can only be called from a process context (for now).
149Returns 0 on success and an appropriate error value on failure.
150
151::
Ohad Ben-Cohenbcabbcc2011-10-20 21:10:55 +0200152
153 int rpmsg_trysendto(struct rpmsg_channel *rpdev, void *data, int len, u32 dst)
Ohad Ben-Cohenbcabbcc2011-10-20 21:10:55 +0200154
Mauro Carvalho Chehabaf3137f2017-05-17 06:53:44 -0300155
156sends a message across to the remote processor on a given channel,
157to a destination address provided by the user.
158
159The user should specify the channel, the data it wants to send,
160its length (in bytes), and an explicit destination address.
161
162The message will then be sent to the remote processor to which the
163channel belongs, using the channel's src address, and the user-provided
164dst address (thus the channel's dst address will be ignored).
165
166In case there are no TX buffers available, the function will immediately
167return -ENOMEM without waiting until one becomes available.
168
169The function can only be called from a process context (for now).
170Returns 0 on success and an appropriate error value on failure.
171
172::
Ohad Ben-Cohenbcabbcc2011-10-20 21:10:55 +0200173
174 int rpmsg_trysend_offchannel(struct rpmsg_channel *rpdev, u32 src, u32 dst,
175 void *data, int len);
Ohad Ben-Cohenbcabbcc2011-10-20 21:10:55 +0200176
Mauro Carvalho Chehabaf3137f2017-05-17 06:53:44 -0300177
178sends a message across to the remote processor, using source and
179destination addresses provided by the user.
180
181The user should specify the channel, the data it wants to send,
182its length (in bytes), and explicit source and destination addresses.
183The message will then be sent to the remote processor to which the
184channel belongs, but the channel's src and dst addresses will be
185ignored (and the user-provided addresses will be used instead).
186
187In case there are no TX buffers available, the function will immediately
188return -ENOMEM without waiting until one becomes available.
189
190The function can only be called from a process context (for now).
191Returns 0 on success and an appropriate error value on failure.
192
193::
Ohad Ben-Cohenbcabbcc2011-10-20 21:10:55 +0200194
195 struct rpmsg_endpoint *rpmsg_create_ept(struct rpmsg_channel *rpdev,
196 void (*cb)(struct rpmsg_channel *, void *, int, void *, u32),
197 void *priv, u32 addr);
Ohad Ben-Cohenbcabbcc2011-10-20 21:10:55 +0200198
Mauro Carvalho Chehabaf3137f2017-05-17 06:53:44 -0300199every rpmsg address in the system is bound to an rx callback (so when
200inbound messages arrive, they are dispatched by the rpmsg bus using the
201appropriate callback handler) by means of an rpmsg_endpoint struct.
Ohad Ben-Cohenbcabbcc2011-10-20 21:10:55 +0200202
Mauro Carvalho Chehabaf3137f2017-05-17 06:53:44 -0300203This function allows drivers to create such an endpoint, and by that,
204bind a callback, and possibly some private data too, to an rpmsg address
205(either one that is known in advance, or one that will be dynamically
206assigned for them).
Ohad Ben-Cohenbcabbcc2011-10-20 21:10:55 +0200207
Mauro Carvalho Chehabaf3137f2017-05-17 06:53:44 -0300208Simple rpmsg drivers need not call rpmsg_create_ept, because an endpoint
209is already created for them when they are probed by the rpmsg bus
210(using the rx callback they provide when they registered to the rpmsg bus).
Ohad Ben-Cohenbcabbcc2011-10-20 21:10:55 +0200211
Mauro Carvalho Chehabaf3137f2017-05-17 06:53:44 -0300212So things should just work for simple drivers: they already have an
213endpoint, their rx callback is bound to their rpmsg address, and when
214relevant inbound messages arrive (i.e. messages which their dst address
215equals to the src address of their rpmsg channel), the driver's handler
216is invoked to process it.
Ohad Ben-Cohenbcabbcc2011-10-20 21:10:55 +0200217
Mauro Carvalho Chehabaf3137f2017-05-17 06:53:44 -0300218That said, more complicated drivers might do need to allocate
219additional rpmsg addresses, and bind them to different rx callbacks.
220To accomplish that, those drivers need to call this function.
221Drivers should provide their channel (so the new endpoint would bind
222to the same remote processor their channel belongs to), an rx callback
223function, an optional private data (which is provided back when the
224rx callback is invoked), and an address they want to bind with the
225callback. If addr is RPMSG_ADDR_ANY, then rpmsg_create_ept will
226dynamically assign them an available rpmsg address (drivers should have
227a very good reason why not to always use RPMSG_ADDR_ANY here).
228
229Returns a pointer to the endpoint on success, or NULL on error.
230
231::
Ohad Ben-Cohenbcabbcc2011-10-20 21:10:55 +0200232
233 void rpmsg_destroy_ept(struct rpmsg_endpoint *ept);
Mauro Carvalho Chehabaf3137f2017-05-17 06:53:44 -0300234
235
236destroys an existing rpmsg endpoint. user should provide a pointer
237to an rpmsg endpoint that was previously created with rpmsg_create_ept().
238
239::
Ohad Ben-Cohenbcabbcc2011-10-20 21:10:55 +0200240
241 int register_rpmsg_driver(struct rpmsg_driver *rpdrv);
Mauro Carvalho Chehabaf3137f2017-05-17 06:53:44 -0300242
243
244registers an rpmsg driver with the rpmsg bus. user should provide
245a pointer to an rpmsg_driver struct, which contains the driver's
246->probe() and ->remove() functions, an rx callback, and an id_table
247specifying the names of the channels this driver is interested to
248be probed with.
249
250::
Ohad Ben-Cohenbcabbcc2011-10-20 21:10:55 +0200251
252 void unregister_rpmsg_driver(struct rpmsg_driver *rpdrv);
Ohad Ben-Cohenbcabbcc2011-10-20 21:10:55 +0200253
254
Mauro Carvalho Chehabaf3137f2017-05-17 06:53:44 -0300255unregisters an rpmsg driver from the rpmsg bus. user should provide
256a pointer to a previously-registered rpmsg_driver struct.
257Returns 0 on success, and an appropriate error value on failure.
258
259
260Typical usage
261=============
Ohad Ben-Cohenbcabbcc2011-10-20 21:10:55 +0200262
263The following is a simple rpmsg driver, that sends an "hello!" message
264on probe(), and whenever it receives an incoming message, it dumps its
265content to the console.
266
Mauro Carvalho Chehabaf3137f2017-05-17 06:53:44 -0300267::
Ohad Ben-Cohenbcabbcc2011-10-20 21:10:55 +0200268
Mauro Carvalho Chehabaf3137f2017-05-17 06:53:44 -0300269 #include <linux/kernel.h>
270 #include <linux/module.h>
271 #include <linux/rpmsg.h>
272
273 static void rpmsg_sample_cb(struct rpmsg_channel *rpdev, void *data, int len,
Ohad Ben-Cohenbcabbcc2011-10-20 21:10:55 +0200274 void *priv, u32 src)
Mauro Carvalho Chehabaf3137f2017-05-17 06:53:44 -0300275 {
Ohad Ben-Cohenbcabbcc2011-10-20 21:10:55 +0200276 print_hex_dump(KERN_INFO, "incoming message:", DUMP_PREFIX_NONE,
277 16, 1, data, len, true);
Mauro Carvalho Chehabaf3137f2017-05-17 06:53:44 -0300278 }
Ohad Ben-Cohenbcabbcc2011-10-20 21:10:55 +0200279
Mauro Carvalho Chehabaf3137f2017-05-17 06:53:44 -0300280 static int rpmsg_sample_probe(struct rpmsg_channel *rpdev)
281 {
Ohad Ben-Cohenbcabbcc2011-10-20 21:10:55 +0200282 int err;
283
284 dev_info(&rpdev->dev, "chnl: 0x%x -> 0x%x\n", rpdev->src, rpdev->dst);
285
286 /* send a message on our channel */
287 err = rpmsg_send(rpdev, "hello!", 6);
288 if (err) {
289 pr_err("rpmsg_send failed: %d\n", err);
290 return err;
291 }
292
293 return 0;
Mauro Carvalho Chehabaf3137f2017-05-17 06:53:44 -0300294 }
Ohad Ben-Cohenbcabbcc2011-10-20 21:10:55 +0200295
Mauro Carvalho Chehabaf3137f2017-05-17 06:53:44 -0300296 static void rpmsg_sample_remove(struct rpmsg_channel *rpdev)
297 {
Ohad Ben-Cohenbcabbcc2011-10-20 21:10:55 +0200298 dev_info(&rpdev->dev, "rpmsg sample client driver is removed\n");
Mauro Carvalho Chehabaf3137f2017-05-17 06:53:44 -0300299 }
Ohad Ben-Cohenbcabbcc2011-10-20 21:10:55 +0200300
Mauro Carvalho Chehabaf3137f2017-05-17 06:53:44 -0300301 static struct rpmsg_device_id rpmsg_driver_sample_id_table[] = {
Ohad Ben-Cohenbcabbcc2011-10-20 21:10:55 +0200302 { .name = "rpmsg-client-sample" },
303 { },
Mauro Carvalho Chehabaf3137f2017-05-17 06:53:44 -0300304 };
305 MODULE_DEVICE_TABLE(rpmsg, rpmsg_driver_sample_id_table);
Ohad Ben-Cohenbcabbcc2011-10-20 21:10:55 +0200306
Mauro Carvalho Chehabaf3137f2017-05-17 06:53:44 -0300307 static struct rpmsg_driver rpmsg_sample_client = {
Ohad Ben-Cohenbcabbcc2011-10-20 21:10:55 +0200308 .drv.name = KBUILD_MODNAME,
Ohad Ben-Cohenbcabbcc2011-10-20 21:10:55 +0200309 .id_table = rpmsg_driver_sample_id_table,
310 .probe = rpmsg_sample_probe,
311 .callback = rpmsg_sample_cb,
Greg Kroah-Hartman63a29f72012-12-21 15:15:02 -0800312 .remove = rpmsg_sample_remove,
Mauro Carvalho Chehabaf3137f2017-05-17 06:53:44 -0300313 };
314 module_rpmsg_driver(rpmsg_sample_client);
Ohad Ben-Cohenbcabbcc2011-10-20 21:10:55 +0200315
Mauro Carvalho Chehabaf3137f2017-05-17 06:53:44 -0300316.. note::
Ohad Ben-Cohenbcabbcc2011-10-20 21:10:55 +0200317
Mauro Carvalho Chehabaf3137f2017-05-17 06:53:44 -0300318 a similar sample which can be built and loaded can be found
319 in samples/rpmsg/.
320
321Allocations of rpmsg channels
322=============================
Ohad Ben-Cohenbcabbcc2011-10-20 21:10:55 +0200323
324At this point we only support dynamic allocations of rpmsg channels.
325
326This is possible only with remote processors that have the VIRTIO_RPMSG_F_NS
327virtio device feature set. This feature bit means that the remote
328processor supports dynamic name service announcement messages.
329
330When this feature is enabled, creation of rpmsg devices (i.e. channels)
331is completely dynamic: the remote processor announces the existence of a
332remote rpmsg service by sending a name service message (which contains
333the name and rpmsg addr of the remote service, see struct rpmsg_ns_msg).
334
335This message is then handled by the rpmsg bus, which in turn dynamically
336creates and registers an rpmsg channel (which represents the remote service).
337If/when a relevant rpmsg driver is registered, it will be immediately probed
338by the bus, and can then start sending messages to the remote service.
339
340The plan is also to add static creation of rpmsg channels via the virtio
341config space, but it's not implemented yet.