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.5KB

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