You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

virtio-ring.h 3.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. #ifndef _VIRTIO_RING_H_
  2. # define _VIRTIO_RING_H_
  3. #define PAGE_SHIFT (12)
  4. #define PAGE_SIZE (1<<PAGE_SHIFT)
  5. #define PAGE_MASK (PAGE_SIZE-1)
  6. /* Status byte for guest to report progress, and synchronize features. */
  7. /* We have seen device and processed generic fields (VIRTIO_CONFIG_F_VIRTIO) */
  8. #define VIRTIO_CONFIG_S_ACKNOWLEDGE 1
  9. /* We have found a driver for the device. */
  10. #define VIRTIO_CONFIG_S_DRIVER 2
  11. /* Driver has used its parts of the config, and is happy */
  12. #define VIRTIO_CONFIG_S_DRIVER_OK 4
  13. /* We've given up on this device. */
  14. #define VIRTIO_CONFIG_S_FAILED 0x80
  15. #define MAX_QUEUE_NUM (512)
  16. #define VRING_DESC_F_NEXT 1
  17. #define VRING_DESC_F_WRITE 2
  18. #define VRING_AVAIL_F_NO_INTERRUPT 1
  19. #define VRING_USED_F_NO_NOTIFY 1
  20. struct vring_desc
  21. {
  22. u64 addr;
  23. u32 len;
  24. u16 flags;
  25. u16 next;
  26. };
  27. struct vring_avail
  28. {
  29. u16 flags;
  30. u16 idx;
  31. u16 ring[0];
  32. };
  33. struct vring_used_elem
  34. {
  35. u32 id;
  36. u32 len;
  37. };
  38. struct vring_used
  39. {
  40. u16 flags;
  41. u16 idx;
  42. struct vring_used_elem ring[];
  43. };
  44. struct vring {
  45. unsigned int num;
  46. struct vring_desc *desc;
  47. struct vring_avail *avail;
  48. struct vring_used *used;
  49. };
  50. #define vring_size(num) \
  51. (((((sizeof(struct vring_desc) * num) + \
  52. (sizeof(struct vring_avail) + sizeof(u16) * num)) \
  53. + PAGE_MASK) & ~PAGE_MASK) + \
  54. (sizeof(struct vring_used) + sizeof(struct vring_used_elem) * num))
  55. typedef unsigned char virtio_queue_t[PAGE_MASK + vring_size(MAX_QUEUE_NUM)];
  56. struct vring_virtqueue {
  57. virtio_queue_t queue;
  58. struct vring vring;
  59. u16 free_head;
  60. u16 last_used_idx;
  61. u16 vdata[MAX_QUEUE_NUM];
  62. /* PCI */
  63. int queue_index;
  64. };
  65. struct vring_list {
  66. char *addr;
  67. unsigned int length;
  68. };
  69. static inline void vring_init(struct vring *vr,
  70. unsigned int num, unsigned char *queue)
  71. {
  72. unsigned int i;
  73. unsigned long pa;
  74. vr->num = num;
  75. /* physical address of desc must be page aligned */
  76. pa = virt_to_phys(queue);
  77. pa = (pa + PAGE_MASK) & ~PAGE_MASK;
  78. vr->desc = phys_to_virt(pa);
  79. vr->avail = (struct vring_avail *)&vr->desc[num];
  80. /* physical address of used must be page aligned */
  81. pa = virt_to_phys(&vr->avail->ring[num]);
  82. pa = (pa + PAGE_MASK) & ~PAGE_MASK;
  83. vr->used = phys_to_virt(pa);
  84. for (i = 0; i < num - 1; i++)
  85. vr->desc[i].next = i + 1;
  86. vr->desc[i].next = 0;
  87. }
  88. static inline void vring_enable_cb(struct vring_virtqueue *vq)
  89. {
  90. vq->vring.avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT;
  91. }
  92. static inline void vring_disable_cb(struct vring_virtqueue *vq)
  93. {
  94. vq->vring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;
  95. }
  96. /*
  97. * vring_more_used
  98. *
  99. * is there some used buffers ?
  100. *
  101. */
  102. static inline int vring_more_used(struct vring_virtqueue *vq)
  103. {
  104. wmb();
  105. return vq->last_used_idx != vq->vring.used->idx;
  106. }
  107. void vring_detach(struct vring_virtqueue *vq, unsigned int head);
  108. int vring_get_buf(struct vring_virtqueue *vq, unsigned int *len);
  109. void vring_add_buf(struct vring_virtqueue *vq, struct vring_list list[],
  110. unsigned int out, unsigned int in,
  111. int index, int num_added);
  112. void vring_kick(unsigned int ioaddr, struct vring_virtqueue *vq, int num_added);
  113. #endif /* _VIRTIO_RING_H_ */