Libmetal helper data struct
struct metal_io_region {
char name[64]; /**< I/O region name */
void *virt; /**< base virtual address */
const metal_phys_addr_t *physmap; /**< table of base physical address
of each of the pages in the I/O
region */
size_t size; /**< size of the I/O region */
unsigned long page_shift; /**< page shift of I/O region */
metal_phys_addr_t page_mask; /**< page mask of I/O region */
unsigned int mem_flags; /**< memory attribute of the
I/O region */
struct metal_io_ops ops; /**< I/O region operations */
};
/** Libmetal device structure. */
struct metal_device {
const char *name; /**< Device name */
struct metal_bus *bus; /**< Bus that contains device */
unsigned num_regions; /**< Number of I/O regions in
device */
struct metal_io_region regions[METAL_MAX_DEVICE_REGIONS]; /**< Array of
I/O regions in device*/
struct metal_list node; /**< Node on bus' list of devices */
int irq_num; /**< Number of IRQs per device */
void *irq_info; /**< IRQ ID */
};
Remoteproc data struct
struct remoteproc {
struct metal_device dev; /**< Each remoteproc has a device, each device knows its memories regions */
metal_mutex_t lock; /**< mutex lock */
void *rsc_table; /**< pointer to resource table */
size_t rsc_len; /**< length of the resoruce table */
struct remoteproc_ops *ops; /**< pointer to remoteproc operation */
metal_phys_addr_t bootaddr; /**< boot address */
struct loader_ops *loader_ops; /**< image loader operation */
unsigned int state; /**< remoteproc state */
struct metal_list vdevs; /**< list of vdevs (can we limited to one for code size but linux and resource table supports multiple */
void *priv; /**< remoteproc private data */
};
struct remoteproc_vdev {
struct metal_list node; /**< node */
struct remoteproc *rproc; /**< pointer to the remoteproc instance */
struct virtio_dev; /**< virtio device */
uint32_t notify_id; /**< virtio device notification ID */
void *vdev_rsc; /**< pointer to the vdev space in resource table */
struct metal_io_region *vdev_io; /**< pointer to the vdev space I/O region */
int vrings_num; /**< number of vrings */
struct rproc_vrings[1]; /**< vrings array */
};
struct remoteproc_vring {
struct remoteproc_vdev *rpvdev; /**< pointer to the remoteproc vdev */
uint32_t notify_id; /**< vring notify id */
size_t len; /**< vring length */
uint32_t alignment; /**< vring alignment */
void *va; /**< vring start virtual address */
struct metal_io_region *io; /**< pointer to the vring I/O region */
};
Virtio Data struct
struct virtio_dev {
int index; /**< unique position on the virtio bus */
struct virtio_device_id id; /**< the device type identification (used to match it with a driver). */
struct metal_device *dev; /**< do we need this in virtio device ? */
metal_spinlock lock; /**< spin lock */
uint64_t features; /**< the features supported by both ends. */
unsigned int role; /**< if it is virtio backend or front end. */
void (*rst_cb)(struct virtio_dev *vdev); /**< user registered virtio device callback */
void *priv; /**< pointer to virtio_dev private data */
int vrings_num; /**< number of vrings */
struct virtqueue vqs[1]; /**< array of virtqueues */
};
struct virtqueue {
char vq_name[VIRTQUEUE_MAX_NAME_SZ]; /**< virtqueue name */
struct virtio_device *vdev; /**< pointer to virtio device */
uint16_t vq_queue_index;
uint16_t vq_nentries;
uint32_t vq_flags;
int vq_alignment;
int vq_ring_size;
boolean vq_inuse;
void *vq_ring_mem;
void (*callback) (struct virtqueue * vq); /**< virtqueue callback */
void (*notify) (struct virtqueue * vq); /**< virtqueue notify remote function */
int vq_max_indirect_size;
int vq_indirect_mem_size;
struct vring vq_ring;
uint16_t vq_free_cnt;
uint16_t vq_queued_cnt;
struct metal_io_region *buffers_io; /**< buffers shared memory */
/*
* Head of the free chain in the descriptor table. If
* there are no free descriptors, this will be set to
* VQ_RING_DESC_CHAIN_END.
*/
uint16_t vq_desc_head_idx;
/*
* Last consumed descriptor in the used table,
* trails vq_ring.used->idx.
*/
uint16_t vq_used_cons_idx;
/*
* Last consumed descriptor in the available table -
* used by the consumer side.
*/
uint16_t vq_available_idx;
uint8_t padd;
/*
* Used by the host side during callback. Cookie
* holds the address of buffer received from other side.
* Other fields in this structure are not used currently.
* Do we needed??/
struct vq_desc_extra {
void *cookie;
struct vring_desc *indirect;
uint32_t indirect_paddr;
uint16_t ndescs;
} vq_descx[0];
};
struct vring {
unsigned int num; /**< number of buffers of the vring */
struct vring_desc *desc;
struct vring_avail *avail;
struct vring_used *used;
};
RPMsg Data struct
struct rpmsg_virtio_device {
struct virtio_dev *vdev; /**< pointer to the virtio device */
struct virtqueue *rvq; /**< pointer to receive virtqueue */
struct virtqueue *svq; /**< pointer to send virtqueue */
int buffers_number; /**< number of shared buffers */
struct metal_io_region *shbuf_io; /**< pointer to the shared buffer I/O region */
void *shbuf;
int (*new_endpoint_cb)(const char *name, uint32_t addr); /**< name service announcement user designed callback which is used for when there is a name service announcement, there is no local endpoints waiting to bind */
struct metal_list endpoints; /**< list of endpoints */
};
struct rpmsg_endpoint {
char name[SERVICE_NAME_SIZE];
struct rpmsg_virtio_dev *rvdev; /**< pointer to the RPMsg virtio device */
uint32_t addr; /**< endpoint local address */
uint32_t dest_addr; /**< endpoint default target address */
int (*cb)(struct rpmsg_endpoint *ept, void *data, struct metal_io_region *io, size_t len, uint32_t addr); /**< endpoint callback */
void (*destroy)(struct rpmsg_endpoint *ept); /**< user registerd endpoint destory callback */
/* Whether we need another callback for ack ns announcement? */
};