virtio-ring.h

Go to the documentation of this file.
00001 #ifndef _VIRTIO_RING_H_
00002 # define _VIRTIO_RING_H_
00003 #define PAGE_SHIFT (12)
00004 #define PAGE_SIZE  (1<<PAGE_SHIFT)
00005 #define PAGE_MASK  (PAGE_SIZE-1)
00006 
00007 /* Status byte for guest to report progress, and synchronize features. */
00008 /* We have seen device and processed generic fields (VIRTIO_CONFIG_F_VIRTIO) */
00009 #define VIRTIO_CONFIG_S_ACKNOWLEDGE     1
00010 /* We have found a driver for the device. */
00011 #define VIRTIO_CONFIG_S_DRIVER          2
00012 /* Driver has used its parts of the config, and is happy */
00013 #define VIRTIO_CONFIG_S_DRIVER_OK       4
00014 /* We've given up on this device. */
00015 #define VIRTIO_CONFIG_S_FAILED          0x80
00016 
00017 #define MAX_QUEUE_NUM      (512)
00018 
00019 #define VRING_DESC_F_NEXT  1
00020 #define VRING_DESC_F_WRITE 2
00021 
00022 #define VRING_AVAIL_F_NO_INTERRUPT 1
00023 
00024 #define VRING_USED_F_NO_NOTIFY     1
00025 
00026 struct vring_desc
00027 {
00028    u64 addr;
00029    u32 len;
00030    u16 flags;
00031    u16 next;
00032 };
00033 
00034 struct vring_avail
00035 {
00036    u16 flags;
00037    u16 idx;
00038    u16 ring[0];
00039 };
00040 
00041 struct vring_used_elem
00042 {
00043    u32 id;
00044    u32 len;
00045 };
00046 
00047 struct vring_used
00048 {
00049    u16 flags;
00050    u16 idx;
00051    struct vring_used_elem ring[];
00052 };
00053 
00054 struct vring {
00055    unsigned int num;
00056    struct vring_desc *desc;
00057    struct vring_avail *avail;
00058    struct vring_used *used;
00059 };
00060 
00061 #define vring_size(num) \
00062    (((((sizeof(struct vring_desc) * num) + \
00063       (sizeof(struct vring_avail) + sizeof(u16) * num)) \
00064          + PAGE_MASK) & ~PAGE_MASK) + \
00065          (sizeof(struct vring_used) + sizeof(struct vring_used_elem) * num))
00066 
00067 typedef unsigned char virtio_queue_t[PAGE_MASK + vring_size(MAX_QUEUE_NUM)];
00068 
00069 struct vring_virtqueue {
00070    virtio_queue_t queue;
00071    struct vring vring;
00072    u16 free_head;
00073    u16 last_used_idx;
00074    u16 vdata[MAX_QUEUE_NUM];
00075    /* PCI */
00076    int queue_index;
00077 };
00078 
00079 struct vring_list {
00080   char *addr;
00081   unsigned int length;
00082 };
00083 
00084 static inline void vring_init(struct vring *vr,
00085                          unsigned int num, unsigned char *queue)
00086 {
00087    unsigned int i;
00088    unsigned long pa;
00089 
00090         vr->num = num;
00091 
00092    /* physical address of desc must be page aligned */
00093 
00094    pa = virt_to_phys(queue);
00095    pa = (pa + PAGE_MASK) & ~PAGE_MASK;
00096    vr->desc = phys_to_virt(pa);
00097 
00098         vr->avail = (struct vring_avail *)&vr->desc[num];
00099 
00100    /* physical address of used must be page aligned */
00101 
00102    pa = virt_to_phys(&vr->avail->ring[num]);
00103    pa = (pa + PAGE_MASK) & ~PAGE_MASK;
00104         vr->used = phys_to_virt(pa);
00105 
00106    for (i = 0; i < num - 1; i++)
00107            vr->desc[i].next = i + 1;
00108    vr->desc[i].next = 0;
00109 }
00110 
00111 static inline void vring_enable_cb(struct vring_virtqueue *vq)
00112 {
00113    vq->vring.avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT;
00114 }
00115 
00116 static inline void vring_disable_cb(struct vring_virtqueue *vq)
00117 {
00118    vq->vring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;
00119 }
00120 
00121 
00122 /*
00123  * vring_more_used
00124  *
00125  * is there some used buffers ?
00126  *
00127  */
00128 
00129 static inline int vring_more_used(struct vring_virtqueue *vq)
00130 {
00131    wmb();
00132    return vq->last_used_idx != vq->vring.used->idx;
00133 }
00134 
00135 void vring_detach(struct vring_virtqueue *vq, unsigned int head);
00136 int vring_get_buf(struct vring_virtqueue *vq, unsigned int *len);
00137 void vring_add_buf(struct vring_virtqueue *vq, struct vring_list list[],
00138                    unsigned int out, unsigned int in,
00139                    int index, int num_added);
00140 void vring_kick(unsigned int ioaddr, struct vring_virtqueue *vq, int num_added);
00141 
00142 #endif /* _VIRTIO_RING_H_ */

Generated on Tue Apr 6 20:01:09 2010 for gPXE by  doxygen 1.5.7.1