Skip to content

Commit e9a44f6

Browse files
author
Hubert Miś
committed
rpmsg_virtio: configuration option to set buffer sizes per instance
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>
1 parent f7640de commit e9a44f6

2 files changed

Lines changed: 90 additions & 8 deletions

File tree

lib/include/openamp/rpmsg_virtio.h

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,31 @@ struct rpmsg_virtio_shm_pool {
4141
size_t size;
4242
};
4343

44+
/**
45+
* struct rpmsg_virtio_config - configuration of rpmsg device based on virtio
46+
*
47+
* This structure is used by the rpmsg virtio host to configure the virtiio
48+
* layer.
49+
*
50+
* @h2r_buf_size: the size of the buffer used to send data from host to remote
51+
* @r2h_buf_size: the size of the buffer used to send data from remote to host
52+
*/
53+
struct rpmsg_virtio_config {
54+
uint32_t h2r_buf_size;
55+
uint32_t r2h_buf_size;
56+
};
57+
58+
/* Default configuration */
59+
#define RPMSG_VIRTIO_DEFAULT_CONFIG \
60+
((const struct rpmsg_virtio_config) { \
61+
.h2r_buf_size = RPMSG_BUFFER_SIZE, \
62+
.r2h_buf_size = RPMSG_BUFFER_SIZE, \
63+
})
64+
4465
/**
4566
* struct rpmsg_virtio_device - representation of a rpmsg device based on virtio
4667
* @rdev: rpmsg device, first property in the struct
68+
* @config: structure containing virtio configuration
4769
* @vdev: pointer to the virtio device
4870
* @rvq: pointer to receive virtqueue
4971
* @svq: pointer to send virtqueue
@@ -52,6 +74,7 @@ struct rpmsg_virtio_shm_pool {
5274
*/
5375
struct rpmsg_virtio_device {
5476
struct rpmsg_device rdev;
77+
struct rpmsg_virtio_config config;
5578
struct virtio_device *vdev;
5679
struct virtqueue *rvq;
5780
struct virtqueue *svq;
@@ -145,6 +168,39 @@ int rpmsg_init_vdev(struct rpmsg_virtio_device *rvdev,
145168
struct metal_io_region *shm_io,
146169
struct rpmsg_virtio_shm_pool *shpool);
147170

171+
/**
172+
* rpmsg_init_vdev_with_config - initialize rpmsg virtio device with config
173+
* Host side:
174+
* Initialize RPMsg virtio queues and shared buffers, the address of shm can be
175+
* ANY. In this case, function will get shared memory from system shared memory
176+
* pools. If the vdev has the RPMsg name service feature, this API will create a
177+
* name service endpoint.
178+
* Sizes of virtio data buffers used by the initialized RPMsg instance are set
179+
* to values read from the passed configuration structure.
180+
*
181+
* Remote side:
182+
* This API will not return until the driver ready is set by the host side.
183+
* Sizes of virtio data buffers are set by the host side. Values passed in the
184+
* configuration structure have no effect.
185+
*
186+
* @param rvdev - pointer to the rpmsg virtio device
187+
* @param vdev - pointer to the virtio device
188+
* @param ns_bind_cb - callback handler for name service announcement without
189+
* local endpoints waiting to bind.
190+
* @param shm_io - pointer to the share memory I/O region.
191+
* @param shpool - pointer to shared memory pool. rpmsg_virtio_init_shm_pool has
192+
* to be called first to fill this structure.
193+
* @param config - pointer to configuration structure
194+
*
195+
* @return - status of function execution
196+
*/
197+
int rpmsg_init_vdev_with_config(struct rpmsg_virtio_device *rvdev,
198+
struct virtio_device *vdev,
199+
rpmsg_ns_bind_cb ns_bind_cb,
200+
struct metal_io_region *shm_io,
201+
struct rpmsg_virtio_shm_pool *shpool,
202+
const struct rpmsg_virtio_config *config);
203+
148204
/**
149205
* rpmsg_deinit_vdev - deinitialize rpmsg virtio device
150206
*

lib/rpmsg/rpmsg_virtio.c

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* All rights reserved.
44
* Copyright (c) 2016 Freescale Semiconductor, Inc. All rights reserved.
55
* Copyright (c) 2018 Linaro, Inc. All rights reserved.
6+
* Copyright (c) 2021 Nordic Semiconductor ASA
67
*
78
* SPDX-License-Identifier: BSD-3-Clause
89
*/
@@ -151,8 +152,8 @@ static void *rpmsg_virtio_get_tx_buffer(struct rpmsg_virtio_device *rvdev,
151152
data = virtqueue_get_buffer(rvdev->svq, len, idx);
152153
if (!data && rvdev->svq->vq_free_cnt) {
153154
data = rpmsg_virtio_shm_pool_get_buffer(rvdev->shpool,
154-
RPMSG_BUFFER_SIZE);
155-
*len = RPMSG_BUFFER_SIZE;
155+
rvdev->config.h2r_buf_size);
156+
*len = rvdev->config.h2r_buf_size;
156157
*idx = 0;
157158
}
158159
}
@@ -250,7 +251,7 @@ static int _rpmsg_virtio_get_buffer_size(struct rpmsg_virtio_device *rvdev)
250251
* If device role is Master then buffers are provided by us,
251252
* so just provide the macro.
252253
*/
253-
length = RPMSG_BUFFER_SIZE - sizeof(struct rpmsg_hdr);
254+
length = rvdev->config.h2r_buf_size - sizeof(struct rpmsg_hdr);
254255
}
255256
#endif /*!VIRTIO_SLAVE_ONLY*/
256257

@@ -384,7 +385,7 @@ static int rpmsg_virtio_send_offchannel_nocopy(struct rpmsg_device *rdev,
384385

385386
#ifndef VIRTIO_SLAVE_ONLY
386387
if (rpmsg_virtio_get_role(rvdev) == RPMSG_MASTER)
387-
buff_len = RPMSG_BUFFER_SIZE;
388+
buff_len = rvdev->config.h2r_buf_size;
388389
else
389390
#endif /*!VIRTIO_SLAVE_ONLY*/
390391
buff_len = virtqueue_get_buffer_length(rvdev->svq, idx);
@@ -610,13 +611,39 @@ int rpmsg_init_vdev(struct rpmsg_virtio_device *rvdev,
610611
rpmsg_ns_bind_cb ns_bind_cb,
611612
struct metal_io_region *shm_io,
612613
struct rpmsg_virtio_shm_pool *shpool)
614+
{
615+
return rpmsg_init_vdev_with_config(rvdev, vdev, ns_bind_cb, shm_io,
616+
shpool, &RPMSG_VIRTIO_DEFAULT_CONFIG);
617+
}
618+
619+
int rpmsg_init_vdev_with_config(struct rpmsg_virtio_device *rvdev,
620+
struct virtio_device *vdev,
621+
rpmsg_ns_bind_cb ns_bind_cb,
622+
struct metal_io_region *shm_io,
623+
struct rpmsg_virtio_shm_pool *shpool,
624+
const struct rpmsg_virtio_config *config)
613625
{
614626
struct rpmsg_device *rdev;
615627
const char *vq_names[RPMSG_NUM_VRINGS];
616628
vq_callback callback[RPMSG_NUM_VRINGS];
617629
int status;
618630
unsigned int i, role;
619631

632+
role = rpmsg_virtio_get_role(rvdev);
633+
634+
#ifndef VIRTIO_SLAVE_ONLY
635+
if (role == RPMSG_MASTER) {
636+
/*
637+
* The virtio configuration contains only options applicable to
638+
* a virtio driver, implying rpmsg host role.
639+
*/
640+
if (config == NULL) {
641+
return RPMSG_ERR_PARAM;
642+
}
643+
rvdev->config = *config;
644+
}
645+
#endif /*!VIRTIO_SLAVE_ONLY*/
646+
620647
rdev = &rvdev->rdev;
621648
memset(rdev, 0, sizeof(*rdev));
622649
metal_mutex_init(&rdev->lock);
@@ -628,7 +655,6 @@ int rpmsg_init_vdev(struct rpmsg_virtio_device *rvdev,
628655
rdev->ops.release_rx_buffer = rpmsg_virtio_release_rx_buffer;
629656
rdev->ops.get_tx_payload_buffer = rpmsg_virtio_get_tx_payload_buffer;
630657
rdev->ops.send_offchannel_nocopy = rpmsg_virtio_send_offchannel_nocopy;
631-
role = rpmsg_virtio_get_role(rvdev);
632658

633659
#ifndef VIRTIO_MASTER_ONLY
634660
if (role == RPMSG_REMOTE) {
@@ -699,11 +725,11 @@ int rpmsg_init_vdev(struct rpmsg_virtio_device *rvdev,
699725
unsigned int idx;
700726
void *buffer;
701727

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

708734
if (!buffer) {
709735
return RPMSG_ERR_NO_BUFF;
@@ -714,7 +740,7 @@ int rpmsg_init_vdev(struct rpmsg_virtio_device *rvdev,
714740
metal_io_block_set(shm_io,
715741
metal_io_virt_to_offset(shm_io,
716742
buffer),
717-
0x00, RPMSG_BUFFER_SIZE);
743+
0x00, rvdev->config.r2h_buf_size);
718744
status =
719745
virtqueue_add_buffer(rvdev->rvq, &vqbuf, 0, 1,
720746
buffer);

0 commit comments

Comments
 (0)