Skip to content

Commit

Permalink
rpmsg_virtio: configuration option to set buffer sizes per instance
Browse files Browse the repository at this point in the history
Enable user of rpmsg_virtio to set sizes of TX and RX buffers per
created rpmsg_virtio instance. Each instance can use other buffer sizes.

Signed-off-by: Hubert Miś <hubert.mis@nordicsemi.no>
  • Loading branch information
hubertmis authored and arnopo committed Jan 4, 2022
1 parent 9ef58af commit 6cb75b8
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 7 deletions.
56 changes: 56 additions & 0 deletions lib/include/openamp/rpmsg_virtio.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,31 @@ struct rpmsg_virtio_shm_pool {
size_t size;
};

/**
* struct rpmsg_virtio_config - configuration of rpmsg device based on virtio
*
* This structure is used by the rpmsg virtio host to configure the virtiio
* layer.
*
* @h2r_buf_size: the size of the buffer used to send data from host to remote
* @r2h_buf_size: the size of the buffer used to send data from remote to host
*/
struct rpmsg_virtio_config {
uint32_t h2r_buf_size;
uint32_t r2h_buf_size;
};

/* Default configuration */
#define RPMSG_VIRTIO_DEFAULT_CONFIG \
((const struct rpmsg_virtio_config) { \
.h2r_buf_size = RPMSG_BUFFER_SIZE, \
.r2h_buf_size = RPMSG_BUFFER_SIZE, \
})

/**
* struct rpmsg_virtio_device - representation of a rpmsg device based on virtio
* @rdev: rpmsg device, first property in the struct
* @config: structure containing virtio configuration
* @vdev: pointer to the virtio device
* @rvq: pointer to receive virtqueue
* @svq: pointer to send virtqueue
Expand All @@ -52,6 +74,7 @@ struct rpmsg_virtio_shm_pool {
*/
struct rpmsg_virtio_device {
struct rpmsg_device rdev;
struct rpmsg_virtio_config config;
struct virtio_device *vdev;
struct virtqueue *rvq;
struct virtqueue *svq;
Expand Down Expand Up @@ -145,6 +168,39 @@ int rpmsg_init_vdev(struct rpmsg_virtio_device *rvdev,
struct metal_io_region *shm_io,
struct rpmsg_virtio_shm_pool *shpool);

/**
* rpmsg_init_vdev_with_config - initialize rpmsg virtio device with config
* Host side:
* Initialize RPMsg virtio queues and shared buffers, the address of shm can be
* ANY. In this case, function will get shared memory from system shared memory
* pools. If the vdev has the RPMsg name service feature, this API will create a
* name service endpoint.
* Sizes of virtio data buffers used by the initialized RPMsg instance are set
* to values read from the passed configuration structure.
*
* Remote side:
* This API will not return until the driver ready is set by the host side.
* Sizes of virtio data buffers are set by the host side. Values passed in the
* configuration structure have no effect.
*
* @param rvdev - pointer to the rpmsg virtio device
* @param vdev - pointer to the virtio device
* @param ns_bind_cb - callback handler for name service announcement without
* local endpoints waiting to bind.
* @param shm_io - pointer to the share memory I/O region.
* @param shpool - pointer to shared memory pool. rpmsg_virtio_init_shm_pool has
* to be called first to fill this structure.
* @param config - pointer to configuration structure
*
* @return - status of function execution
*/
int rpmsg_init_vdev_with_config(struct rpmsg_virtio_device *rvdev,
struct virtio_device *vdev,
rpmsg_ns_bind_cb ns_bind_cb,
struct metal_io_region *shm_io,
struct rpmsg_virtio_shm_pool *shpool,
const struct rpmsg_virtio_config *config);

/**
* rpmsg_deinit_vdev - deinitialize rpmsg virtio device
*
Expand Down
43 changes: 36 additions & 7 deletions lib/rpmsg/rpmsg_virtio.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* All rights reserved.
* Copyright (c) 2016 Freescale Semiconductor, Inc. All rights reserved.
* Copyright (c) 2018 Linaro, Inc. All rights reserved.
* Copyright (c) 2021 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: BSD-3-Clause
*/
Expand Down Expand Up @@ -151,8 +152,8 @@ static void *rpmsg_virtio_get_tx_buffer(struct rpmsg_virtio_device *rvdev,
data = virtqueue_get_buffer(rvdev->svq, len, idx);
if (!data && rvdev->svq->vq_free_cnt) {
data = rpmsg_virtio_shm_pool_get_buffer(rvdev->shpool,
RPMSG_BUFFER_SIZE);
*len = RPMSG_BUFFER_SIZE;
rvdev->config.h2r_buf_size);
*len = rvdev->config.h2r_buf_size;
*idx = 0;
}
}
Expand Down Expand Up @@ -250,7 +251,7 @@ static int _rpmsg_virtio_get_buffer_size(struct rpmsg_virtio_device *rvdev)
* If device role is Master then buffers are provided by us,
* so just provide the macro.
*/
length = RPMSG_BUFFER_SIZE - sizeof(struct rpmsg_hdr);
length = rvdev->config.h2r_buf_size - sizeof(struct rpmsg_hdr);
}
#endif /*!VIRTIO_SLAVE_ONLY*/

Expand Down Expand Up @@ -384,7 +385,7 @@ static int rpmsg_virtio_send_offchannel_nocopy(struct rpmsg_device *rdev,

#ifndef VIRTIO_SLAVE_ONLY
if (rpmsg_virtio_get_role(rvdev) == RPMSG_MASTER)
buff_len = RPMSG_BUFFER_SIZE;
buff_len = rvdev->config.h2r_buf_size;
else
#endif /*!VIRTIO_SLAVE_ONLY*/
buff_len = virtqueue_get_buffer_length(rvdev->svq, idx);
Expand Down Expand Up @@ -610,6 +611,17 @@ int rpmsg_init_vdev(struct rpmsg_virtio_device *rvdev,
rpmsg_ns_bind_cb ns_bind_cb,
struct metal_io_region *shm_io,
struct rpmsg_virtio_shm_pool *shpool)
{
return rpmsg_init_vdev_with_config(rvdev, vdev, ns_bind_cb, shm_io,
shpool, &RPMSG_VIRTIO_DEFAULT_CONFIG);
}

int rpmsg_init_vdev_with_config(struct rpmsg_virtio_device *rvdev,
struct virtio_device *vdev,
rpmsg_ns_bind_cb ns_bind_cb,
struct metal_io_region *shm_io,
struct rpmsg_virtio_shm_pool *shpool,
const struct rpmsg_virtio_config *config)
{
struct rpmsg_device *rdev;
const char *vq_names[RPMSG_NUM_VRINGS];
Expand All @@ -630,6 +642,23 @@ int rpmsg_init_vdev(struct rpmsg_virtio_device *rvdev,
rdev->ops.send_offchannel_nocopy = rpmsg_virtio_send_offchannel_nocopy;
role = rpmsg_virtio_get_role(rvdev);

#ifndef VIRTIO_SLAVE_ONLY
if (role == RPMSG_MASTER) {
/*
* The virtio configuration contains only options applicable to
* a virtio driver, implying rpmsg host role.
*/
if (config == NULL) {
return RPMSG_ERR_PARAM;
}
rvdev->config = *config;
}
#else /*!VIRTIO_SLAVE_ONLY*/
/* Ignore passed config in the virtio-device-only configuration. */
(void)config;
#endif /*!VIRTIO_SLAVE_ONLY*/


#ifndef VIRTIO_MASTER_ONLY
if (role == RPMSG_REMOTE) {
/* wait synchro with the master */
Expand Down Expand Up @@ -699,11 +728,11 @@ int rpmsg_init_vdev(struct rpmsg_virtio_device *rvdev,
unsigned int idx;
void *buffer;

vqbuf.len = RPMSG_BUFFER_SIZE;
vqbuf.len = rvdev->config.r2h_buf_size;
for (idx = 0; idx < rvdev->rvq->vq_nentries; idx++) {
/* Initialize TX virtqueue buffers for remote device */
buffer = rpmsg_virtio_shm_pool_get_buffer(shpool,
RPMSG_BUFFER_SIZE);
rvdev->config.r2h_buf_size);

if (!buffer) {
return RPMSG_ERR_NO_BUFF;
Expand All @@ -714,7 +743,7 @@ int rpmsg_init_vdev(struct rpmsg_virtio_device *rvdev,
metal_io_block_set(shm_io,
metal_io_virt_to_offset(shm_io,
buffer),
0x00, RPMSG_BUFFER_SIZE);
0x00, rvdev->config.r2h_buf_size);
status =
virtqueue_add_buffer(rvdev->rvq, &vqbuf, 0, 1,
buffer);
Expand Down

0 comments on commit 6cb75b8

Please sign in to comment.