diff options
author | Yang Zhang <yang.z.zhang@intel.com> | 2015-08-28 09:58:54 +0800 |
---|---|---|
committer | Yang Zhang <yang.z.zhang@intel.com> | 2015-09-01 12:44:00 +0800 |
commit | e44e3482bdb4d0ebde2d8b41830ac2cdb07948fb (patch) | |
tree | 66b09f592c55df2878107a468a91d21506104d3f /qemu/roms/seabios/src/hw/virtio-ring.h | |
parent | 9ca8dbcc65cfc63d6f5ef3312a33184e1d726e00 (diff) |
Add qemu 2.4.0
Change-Id: Ic99cbad4b61f8b127b7dc74d04576c0bcbaaf4f5
Signed-off-by: Yang Zhang <yang.z.zhang@intel.com>
Diffstat (limited to 'qemu/roms/seabios/src/hw/virtio-ring.h')
-rw-r--r-- | qemu/roms/seabios/src/hw/virtio-ring.h | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/qemu/roms/seabios/src/hw/virtio-ring.h b/qemu/roms/seabios/src/hw/virtio-ring.h new file mode 100644 index 000000000..b7a7aafb2 --- /dev/null +++ b/qemu/roms/seabios/src/hw/virtio-ring.h @@ -0,0 +1,131 @@ +#ifndef _VIRTIO_RING_H +#define _VIRTIO_RING_H + +#include "types.h" // u64 +#include "memmap.h" // PAGE_SIZE + +#define PAGE_SHIFT 12 +#define PAGE_MASK (PAGE_SIZE-1) + +#define virt_to_phys(v) (unsigned long)(v) +#define phys_to_virt(p) (void*)(p) +/* Compiler barrier is enough as an x86 CPU does not reorder reads or writes */ +#define smp_rmb() barrier() +#define smp_wmb() barrier() + +/* Status byte for guest to report progress, and synchronize features. */ +/* We have seen device and processed generic fields (VIRTIO_CONFIG_F_VIRTIO) */ +#define VIRTIO_CONFIG_S_ACKNOWLEDGE 1 +/* We have found a driver for the device. */ +#define VIRTIO_CONFIG_S_DRIVER 2 +/* Driver has used its parts of the config, and is happy */ +#define VIRTIO_CONFIG_S_DRIVER_OK 4 +/* We've given up on this device. */ +#define VIRTIO_CONFIG_S_FAILED 0x80 + +#define MAX_QUEUE_NUM (128) + +#define VRING_DESC_F_NEXT 1 +#define VRING_DESC_F_WRITE 2 + +#define VRING_AVAIL_F_NO_INTERRUPT 1 + +#define VRING_USED_F_NO_NOTIFY 1 + +struct vring_desc +{ + u64 addr; + u32 len; + u16 flags; + u16 next; +}; + +struct vring_avail +{ + u16 flags; + u16 idx; + u16 ring[0]; +}; + +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; +}; + +#define vring_size(num) \ + (((((sizeof(struct vring_desc) * num) + \ + (sizeof(struct vring_avail) + sizeof(u16) * num)) \ + + PAGE_MASK) & ~PAGE_MASK) + \ + (sizeof(struct vring_used) + sizeof(struct vring_used_elem) * num)) + +typedef unsigned char virtio_queue_t[vring_size(MAX_QUEUE_NUM)]; + +struct vring_virtqueue { + virtio_queue_t queue; + struct vring vring; + u16 free_head; + u16 last_used_idx; + u16 vdata[MAX_QUEUE_NUM]; + /* PCI */ + int queue_index; +}; + +struct vring_list { + char *addr; + unsigned int length; +}; + +static inline void vring_init(struct vring *vr, + unsigned int num, unsigned char *queue) +{ + unsigned int i; + unsigned long pa; + + ASSERT32FLAT(); + vr->num = num; + + /* physical address of desc must be page aligned */ + + pa = virt_to_phys(queue); + pa = (pa + PAGE_MASK) & ~PAGE_MASK; + vr->desc = phys_to_virt(pa); + + vr->avail = (struct vring_avail *)&vr->desc[num]; + /* disable interrupts */ + vr->avail->flags |= VRING_AVAIL_F_NO_INTERRUPT; + + /* physical address of used must be page aligned */ + + pa = virt_to_phys(&vr->avail->ring[num]); + pa = (pa + PAGE_MASK) & ~PAGE_MASK; + vr->used = phys_to_virt(pa); + + for (i = 0; i < num - 1; i++) + vr->desc[i].next = i + 1; + vr->desc[i].next = 0; +} + +int vring_more_used(struct vring_virtqueue *vq); +void vring_detach(struct vring_virtqueue *vq, unsigned int head); +int vring_get_buf(struct vring_virtqueue *vq, unsigned int *len); +void vring_add_buf(struct vring_virtqueue *vq, struct vring_list list[], + unsigned int out, unsigned int in, + int index, int num_added); +void vring_kick(unsigned int ioaddr, struct vring_virtqueue *vq, int num_added); + +#endif /* _VIRTIO_RING_H_ */ |