cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

rpmsg.rst (13389B)


      1============================================
      2Remote Processor Messaging (rpmsg) Framework
      3============================================
      4
      5.. note::
      6
      7  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============
     13
     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
     66User API
     67========
     68
     69::
     70
     71  int rpmsg_send(struct rpmsg_channel *rpdev, void *data, int len);
     72
     73sends 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::
     89
     90  int rpmsg_sendto(struct rpmsg_channel *rpdev, void *data, int len, u32 dst);
     91
     92sends 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::
    112
    113  int rpmsg_send_offchannel(struct rpmsg_channel *rpdev, u32 src, u32 dst,
    114							void *data, int len);
    115
    116
    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::
    136
    137  int rpmsg_trysend(struct rpmsg_channel *rpdev, void *data, int len);
    138
    139sends 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::
    152
    153  int rpmsg_trysendto(struct rpmsg_channel *rpdev, void *data, int len, u32 dst)
    154
    155
    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::
    173
    174  int rpmsg_trysend_offchannel(struct rpmsg_channel *rpdev, u32 src, u32 dst,
    175							void *data, int len);
    176
    177
    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::
    194
    195  struct rpmsg_endpoint *rpmsg_create_ept(struct rpmsg_device *rpdev,
    196					  rpmsg_rx_cb_t cb, void *priv,
    197					  struct rpmsg_channel_info chinfo);
    198
    199every 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.
    202
    203This 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).
    207
    208Simple 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).
    211
    212So 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.
    217
    218That 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::
    232
    233  void rpmsg_destroy_ept(struct rpmsg_endpoint *ept);
    234
    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::
    240
    241  int register_rpmsg_driver(struct rpmsg_driver *rpdrv);
    242
    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::
    251
    252  void unregister_rpmsg_driver(struct rpmsg_driver *rpdrv);
    253
    254
    255unregisters 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=============
    262
    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
    267::
    268
    269  #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,
    274						void *priv, u32 src)
    275  {
    276	print_hex_dump(KERN_INFO, "incoming message:", DUMP_PREFIX_NONE,
    277						16, 1, data, len, true);
    278  }
    279
    280  static int rpmsg_sample_probe(struct rpmsg_channel *rpdev)
    281  {
    282	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;
    294  }
    295
    296  static void rpmsg_sample_remove(struct rpmsg_channel *rpdev)
    297  {
    298	dev_info(&rpdev->dev, "rpmsg sample client driver is removed\n");
    299  }
    300
    301  static struct rpmsg_device_id rpmsg_driver_sample_id_table[] = {
    302	{ .name	= "rpmsg-client-sample" },
    303	{ },
    304  };
    305  MODULE_DEVICE_TABLE(rpmsg, rpmsg_driver_sample_id_table);
    306
    307  static struct rpmsg_driver rpmsg_sample_client = {
    308	.drv.name	= KBUILD_MODNAME,
    309	.id_table	= rpmsg_driver_sample_id_table,
    310	.probe		= rpmsg_sample_probe,
    311	.callback	= rpmsg_sample_cb,
    312	.remove		= rpmsg_sample_remove,
    313  };
    314  module_rpmsg_driver(rpmsg_sample_client);
    315
    316.. note::
    317
    318   a similar sample which can be built and loaded can be found
    319   in samples/rpmsg/.
    320
    321Allocations of rpmsg channels
    322=============================
    323
    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.