/* * rpmsg based on virtio * * Copyright (C) 2018 Linaro, Inc. * * All rights reserved. * Copyright (c) 2016 Freescale Semiconductor, Inc. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #ifndef _RPMSG_VIRTIO_H_ #define _RPMSG_VIRTIO_H_ #include #include #include #include #if defined __cplusplus extern "C" { #endif /* Configurable parameters */ #ifndef RPMSG_BUFFER_SIZE #define RPMSG_BUFFER_SIZE (512) #endif /* The feature bitmap for virtio rpmsg */ #define VIRTIO_RPMSG_F_NS 0 /* RP supports name service notifications */ /** * struct rpmsg_virtio_shm_pool - shared memory pool used for rpmsg buffers * @base: base address of the memory pool * @avail: available memory size * @size: total pool size */ struct rpmsg_virtio_shm_pool { void *base; size_t avail; size_t size; }; /** * struct rpmsg_virtio_device - representation of a rpmsg device based on virtio * @rdev: rpmsg device, first property in the struct * @vdev: pointer to the virtio device * @rvq: pointer to receive virtqueue * @svq: pointer to send virtqueue * @shbuf_io: pointer to the shared buffer I/O region * @shpool: pointer to the shared buffers pool */ struct rpmsg_virtio_device { struct rpmsg_device rdev; struct virtio_device *vdev; struct virtqueue *rvq; struct virtqueue *svq; struct metal_io_region *shbuf_io; struct rpmsg_virtio_shm_pool *shpool; }; #define RPMSG_REMOTE VIRTIO_DEV_SLAVE #define RPMSG_MASTER VIRTIO_DEV_MASTER static inline unsigned int rpmsg_virtio_get_role(struct rpmsg_virtio_device *rvdev) { return rvdev->vdev->role; } static inline void rpmsg_virtio_set_status(struct rpmsg_virtio_device *rvdev, uint8_t status) { rvdev->vdev->func->set_status(rvdev->vdev, status); } static inline uint8_t rpmsg_virtio_get_status(struct rpmsg_virtio_device *rvdev) { return rvdev->vdev->func->get_status(rvdev->vdev); } static inline uint32_t rpmsg_virtio_get_features(struct rpmsg_virtio_device *rvdev) { return rvdev->vdev->func->get_features(rvdev->vdev); } static inline void rpmsg_virtio_read_config(struct rpmsg_virtio_device *rvdev, uint32_t offset, void *dst, int length) { rvdev->vdev->func->read_config(rvdev->vdev, offset, dst, length); } static inline void rpmsg_virtio_write_config(struct rpmsg_virtio_device *rvdev, uint32_t offset, void *dst, int length) { rvdev->vdev->func->write_config(rvdev->vdev, offset, dst, length); } static inline int rpmsg_virtio_create_virtqueues(struct rpmsg_virtio_device *rvdev, int flags, unsigned int nvqs, const char *names[], vq_callback *callbacks) { return virtio_create_virtqueues(rvdev->vdev, flags, nvqs, names, callbacks); } /** * rpmsg_virtio_get_buffer_size - get rpmsg virtio buffer size * * @rdev - pointer to the rpmsg device * * @return - next available buffer size for text, negative value for failure */ int rpmsg_virtio_get_buffer_size(struct rpmsg_device *rdev); /** * rpmsg_init_vdev - initialize rpmsg virtio device * Master 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 RPMsg name service feature, this API will create an * name service endpoint. * * Slave side: * This API will not return until the driver ready is set by the master side. * * @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. * * @return - status of function execution */ int rpmsg_init_vdev(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); /** * rpmsg_deinit_vdev - deinitialize rpmsg virtio device * * @param rvdev - pointer to the rpmsg virtio device */ void rpmsg_deinit_vdev(struct rpmsg_virtio_device *rvdev); /** * rpmsg_virtio_init_shm_pool - initialize default shared buffers pool * * RPMsg virtio has default shared buffers pool implementation. * The memory assigned to this pool will be dedicated to the RPMsg * virtio. This function has to be called before calling rpmsg_init_vdev, * to initialize the rpmsg_virtio_shm_pool structure. * * @param shpool - pointer to the shared buffers pool structure * @param shbuf - pointer to the beginning of shared buffers * @param size - shared buffers total size */ void rpmsg_virtio_init_shm_pool(struct rpmsg_virtio_shm_pool *shpool, void *shbuf, size_t size); /** * rpmsg_virtio_get_rpmsg_device - get RPMsg device from RPMsg virtio device * * @param rvdev - pointer to RPMsg virtio device * @return - RPMsg device pointed by RPMsg virtio device */ static inline struct rpmsg_device * rpmsg_virtio_get_rpmsg_device(struct rpmsg_virtio_device *rvdev) { return &rvdev->rdev; } /** * rpmsg_virtio_shm_pool_get_buffer - get buffer in the shared memory pool * * RPMsg virtio has default shared buffers pool implementation. * The memory assigned to this pool will be dedicated to the RPMsg * virtio. If you prefer to have other shared buffers allocation, * you can implement your rpmsg_virtio_shm_pool_get_buffer function. * * @param shpool - pointer to the shared buffers pool * @param size - shared buffers total size * @return - buffer pointer if free buffer is available, NULL otherwise. */ metal_weak void * rpmsg_virtio_shm_pool_get_buffer(struct rpmsg_virtio_shm_pool *shpool, size_t size); #if defined __cplusplus } #endif #endif /* _RPMSG_VIRTIO_H_ */