Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | /*
* Copyright (c) 2021 Carlo Caione <ccaione@baylibre.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <openamp/virtio_ring.h>
#include <openamp/rpmsg_virtio.h>
#include <ipc/ipc_static_vrings.h>
/*
* Endpoint registration flow:
*
* >>> Case #1: Endpoint registered on HOST first <<<
*
* [B] backend
* [O] OpenAMP
*
* REMOTE HOST
* -----------------------------------------------------------------
* [B] register_ept **
* [B] register_ept **
* [B] ipc_rpmsg_register_ept
* [B] rpmsg_create_ept
* [O] rpmsg_send_ns_message
* [O] virtqueue_kick
* [O] virtio_notify_cb
* [B] mbox_send
* [B] mbox_callback
* [B] mbox_callback_process
* [B] virtqueue_notification
* [O] rpmsg_virtio_rx_callback
* [B] ns_bind_cb
* [B] rpmsg_create_ept
* [B] bound_cb
* [B] rpmsg_send
* [B] virtio_notify_cb
* [B] mbox_send
* [B] mbox_callback
* [B] mbox_callback_process
* [B] virtqueue_notification
* [O] rpmsg_virtio_rx_callback
* [O] ept_cb
* [B] bound_cb
*
* >>> Case #2: Endpoint registered on REMOTE first <<<
*
* [B] backend
* [O] OpenAMP
*
* REMOTE HOST
* -----------------------------------------------------------------
* [B] register_ept **
* [B] ipc_rpmsg_register_ept
* [B] rpmsg_create_ept
* [O] rpmsg_send_ns_message
* [O] virtqueue_kick
* [O] virtio_notify_cb
* [O] mbox_send
* [B] mbox_callback
* [B] mbox_callback_process
* [B] virtqueue_notification
* [O] rpmsg_virtio_rx_callback
* [B] ns_bind_cb
*
* [B] register_ept **
* [B] rpmsg_create_ept
* [B] bound_cb
* [B] rpmsg_send
* [B] virtio_notify_cb
* [B] mbox_send
* [B] mbox_callback
* [B] mbox_callback_process
* [B] virtqueue_notification
* [O] rpmsg_virtio_rx_callback
* [O] ept_cb
* [B] bound_cb
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* Endpoint registration flow (with focus on backend):
*
* >>> Case #1: Endpoint registered on HOST first <<<
*
* REMOTE HOST
* -----------------------------------------------------------------
* register_ept()
* register_ept_on_host()
* get_ept() returns NULL
* name is cached in rpmsg_ept->name
* register_ept()
* register_ept_on_remote()
* ipc_rpmsg_register_ept()
* ns_bind_cb()
* get_ept() returns endpoint with cached name
* advertise_ept()
* rpmsg_create_ept()
* bound_cb()
* rpmsg_send()
* mbox_callback()
* mbox_callback_process()
* virtqueue_notification()
* ept_cb()
* bound_cb()
*
* >>> Case #2: Endpoint registered on REMOTE first <<<
*
* REMOTE HOST
* -----------------------------------------------------------------
* register_ept()
* register_ept_on_remote()
* ipc_rpmsg_register_ept()
* ns_bind_cb()
* get_ept() return NULL
* name is cached in rpmsg_ept->name
* ...
* register_ept()
* register_ept_on_host()
* get_ept() returns endpoint with cached name
* advertise_ept()
* rpmsg_create_ept()
* bound_cb()
* rpmsg-send()
* mbox_callback()
* mbox_callback_process()
* virtqueue_notification()
* ept_cb()
* bound_cb()
*
*/
#define VDEV_STATUS_SIZE (4) /* Size of status region */
#define VIRTQUEUE_ID_HOST (0)
#define VIRTQUEUE_ID_REMOTE (1)
#define ROLE_HOST VIRTIO_DEV_MASTER
#define ROLE_REMOTE VIRTIO_DEV_SLAVE
static inline size_t vq_ring_size(unsigned int num)
{
return (RPMSG_BUFFER_SIZE * num);
}
static inline size_t shm_size(unsigned int num)
{
return (VDEV_STATUS_SIZE + (VRING_COUNT * vq_ring_size(num)) +
(VRING_COUNT * vring_size(num, VRING_ALIGNMENT)));
}
static inline unsigned int optimal_num_desc(size_t shm_size)
{
size_t available, single_alloc;
unsigned int num_desc;
available = shm_size - VDEV_STATUS_SIZE;
single_alloc = VRING_COUNT * (vq_ring_size(1) + vring_size(1, VRING_ALIGNMENT));
num_desc = (unsigned int) (available / single_alloc);
return (1 << (find_msb_set(num_desc) - 1));
}
|