123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- #ifndef _VIRTIO_H_
- #define _VIRTIO_H_
- /*
- * A minimal implementation of virtio.
- * Structures adapted from the Linux Kernel.
- *
- * Copyright (C) 2017, Red Hat Inc, Andrew Jones <drjones@redhat.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2.
- */
- #include "libcflat.h"
- #define VIRTIO_ID_CONSOLE 3
- struct virtio_device_id {
- u32 device;
- u32 vendor;
- };
- struct virtio_device {
- struct virtio_device_id id;
- const struct virtio_config_ops *config;
- };
- struct virtqueue {
- void (*callback)(struct virtqueue *vq);
- const char *name;
- struct virtio_device *vdev;
- unsigned int index;
- unsigned int num_free;
- void *priv;
- };
- typedef void vq_callback_t(struct virtqueue *);
- struct virtio_config_ops {
- void (*get)(struct virtio_device *vdev, unsigned offset,
- void *buf, unsigned len);
- void (*set)(struct virtio_device *vdev, unsigned offset,
- const void *buf, unsigned len);
- int (*find_vqs)(struct virtio_device *vdev, unsigned nvqs,
- struct virtqueue *vqs[],
- vq_callback_t *callbacks[],
- const char *names[]);
- };
- static inline u8
- virtio_config_readb(struct virtio_device *vdev, unsigned offset)
- {
- u8 val;
- vdev->config->get(vdev, offset, &val, 1);
- return val;
- }
- static inline u16
- virtio_config_readw(struct virtio_device *vdev, unsigned offset)
- {
- u16 val;
- vdev->config->get(vdev, offset, &val, 2);
- return val;
- }
- static inline u32
- virtio_config_readl(struct virtio_device *vdev, unsigned offset)
- {
- u32 val;
- vdev->config->get(vdev, offset, &val, 4);
- return val;
- }
- static inline void
- virtio_config_writeb(struct virtio_device *vdev, unsigned offset, u8 val)
- {
- vdev->config->set(vdev, offset, &val, 1);
- }
- static inline void
- virtio_config_writew(struct virtio_device *vdev, unsigned offset, u16 val)
- {
- vdev->config->set(vdev, offset, &val, 2);
- }
- static inline void
- virtio_config_writel(struct virtio_device *vdev, unsigned offset, u32 val)
- {
- vdev->config->set(vdev, offset, &val, 4);
- }
- #define VRING_DESC_F_NEXT 1
- #define VRING_DESC_F_WRITE 2
- struct vring_desc {
- u64 addr;
- u32 len;
- u16 flags;
- u16 next;
- };
- struct vring_avail {
- u16 flags;
- u16 idx;
- u16 ring[];
- };
- struct vring_used_elem {
- u32 id;
- u32 len;
- };
- struct vring_used {
- u16 flags;
- u16 idx;
- struct vring_used_elem ring[];
- };
- struct vring {
- unsigned int num;
- struct vring_desc *desc;
- struct vring_avail *avail;
- struct vring_used *used;
- };
- struct vring_virtqueue {
- struct virtqueue vq;
- struct vring vring;
- unsigned int free_head;
- unsigned int num_added;
- u16 last_used_idx;
- bool (*notify)(struct virtqueue *vq);
- void *data[];
- };
- #define to_vvq(_vq) container_of(_vq, struct vring_virtqueue, vq)
- extern void vring_init(struct vring *vr, unsigned int num, void *p,
- unsigned long align);
- extern void vring_init_virtqueue(struct vring_virtqueue *vq, unsigned index,
- unsigned num, unsigned vring_align,
- struct virtio_device *vdev, void *pages,
- bool (*notify)(struct virtqueue *),
- void (*callback)(struct virtqueue *),
- const char *name);
- extern int virtqueue_add_outbuf(struct virtqueue *vq, char *buf,
- unsigned int len);
- extern bool virtqueue_kick(struct virtqueue *vq);
- extern void detach_buf(struct vring_virtqueue *vq, unsigned head);
- extern void *virtqueue_get_buf(struct virtqueue *_vq, unsigned int *len);
- extern struct virtio_device *virtio_bind(u32 devid);
- #endif /* _VIRTIO_H_ */
|