15566a3e3SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
25566a3e3SBruce Richardson * Copyright(c) 2010-2014 Intel Corporation
36c3169a3SBruce Richardson */
46c3169a3SBruce Richardson
56c3169a3SBruce Richardson #ifndef _VIRTIO_RING_H_
66c3169a3SBruce Richardson #define _VIRTIO_RING_H_
76c3169a3SBruce Richardson
86c3169a3SBruce Richardson #include <stdint.h>
96c3169a3SBruce Richardson
106c3169a3SBruce Richardson #include <rte_common.h>
116c3169a3SBruce Richardson
126c3169a3SBruce Richardson /* This marks a buffer as continuing via the next field. */
136c3169a3SBruce Richardson #define VRING_DESC_F_NEXT 1
146c3169a3SBruce Richardson /* This marks a buffer as write-only (otherwise read-only). */
156c3169a3SBruce Richardson #define VRING_DESC_F_WRITE 2
166c3169a3SBruce Richardson /* This means the buffer contains a list of buffer descriptors. */
176c3169a3SBruce Richardson #define VRING_DESC_F_INDIRECT 4
1812e9e70cSTiwei Bie
194c3f5822SJens Freimann /* This flag means the descriptor was made available by the driver */
2012e9e70cSTiwei Bie #define VRING_PACKED_DESC_F_AVAIL (1 << 7)
214c3f5822SJens Freimann /* This flag means the descriptor was used by the device */
2212e9e70cSTiwei Bie #define VRING_PACKED_DESC_F_USED (1 << 15)
2312e9e70cSTiwei Bie
2412e9e70cSTiwei Bie /* Frequently used combinations */
2512e9e70cSTiwei Bie #define VRING_PACKED_DESC_F_AVAIL_USED (VRING_PACKED_DESC_F_AVAIL | \
2612e9e70cSTiwei Bie VRING_PACKED_DESC_F_USED)
276c3169a3SBruce Richardson
286c3169a3SBruce Richardson /* The Host uses this in used->flags to advise the Guest: don't kick me
296c3169a3SBruce Richardson * when you add a buffer. It's unreliable, so it's simply an
306c3169a3SBruce Richardson * optimization. Guest will still kick if it's out of buffers. */
316c3169a3SBruce Richardson #define VRING_USED_F_NO_NOTIFY 1
326c3169a3SBruce Richardson /* The Guest uses this in avail->flags to advise the Host: don't
336c3169a3SBruce Richardson * interrupt me when you consume a buffer. It's unreliable, so it's
346c3169a3SBruce Richardson * simply an optimization. */
356c3169a3SBruce Richardson #define VRING_AVAIL_F_NO_INTERRUPT 1
366c3169a3SBruce Richardson
376c3169a3SBruce Richardson /* VirtIO ring descriptors: 16 bytes.
386c3169a3SBruce Richardson * These can chain together via "next". */
396c3169a3SBruce Richardson struct vring_desc {
406c3169a3SBruce Richardson uint64_t addr; /* Address (guest-physical). */
416c3169a3SBruce Richardson uint32_t len; /* Length. */
426c3169a3SBruce Richardson uint16_t flags; /* The flags as indicated above. */
436c3169a3SBruce Richardson uint16_t next; /* We chain unused descriptors via this. */
446c3169a3SBruce Richardson };
456c3169a3SBruce Richardson
466c3169a3SBruce Richardson struct vring_avail {
476c3169a3SBruce Richardson uint16_t flags;
486c3169a3SBruce Richardson uint16_t idx;
49013b4c52SBruce Richardson uint16_t ring[];
506c3169a3SBruce Richardson };
516c3169a3SBruce Richardson
526c3169a3SBruce Richardson /* id is a 16bit index. uint32_t is used here for ids for padding reasons. */
536c3169a3SBruce Richardson struct vring_used_elem {
546c3169a3SBruce Richardson /* Index of start of used descriptor chain. */
556c3169a3SBruce Richardson uint32_t id;
566c3169a3SBruce Richardson /* Total length of the descriptor chain which was written to. */
576c3169a3SBruce Richardson uint32_t len;
586c3169a3SBruce Richardson };
596c3169a3SBruce Richardson
606c3169a3SBruce Richardson struct vring_used {
616c3169a3SBruce Richardson uint16_t flags;
62e12a0166STyler Retzlaff RTE_ATOMIC(uint16_t) idx;
63013b4c52SBruce Richardson struct vring_used_elem ring[];
646c3169a3SBruce Richardson };
656c3169a3SBruce Richardson
664c3f5822SJens Freimann /* For support of packed virtqueues in Virtio 1.1 the format of descriptors
674c3f5822SJens Freimann * looks like this.
684c3f5822SJens Freimann */
694c3f5822SJens Freimann struct vring_packed_desc {
704c3f5822SJens Freimann uint64_t addr;
714c3f5822SJens Freimann uint32_t len;
724c3f5822SJens Freimann uint16_t id;
73e12a0166STyler Retzlaff RTE_ATOMIC(uint16_t) flags;
744c3f5822SJens Freimann };
754c3f5822SJens Freimann
764c3f5822SJens Freimann #define RING_EVENT_FLAGS_ENABLE 0x0
774c3f5822SJens Freimann #define RING_EVENT_FLAGS_DISABLE 0x1
784c3f5822SJens Freimann #define RING_EVENT_FLAGS_DESC 0x2
794c3f5822SJens Freimann struct vring_packed_desc_event {
804c3f5822SJens Freimann uint16_t desc_event_off_wrap;
814c3f5822SJens Freimann uint16_t desc_event_flags;
824c3f5822SJens Freimann };
834c3f5822SJens Freimann
844c3f5822SJens Freimann struct vring_packed {
854c3f5822SJens Freimann unsigned int num;
86*802a0389SSrujana Challa rte_iova_t desc_iova;
874cdc4d98STiwei Bie struct vring_packed_desc *desc;
884cdc4d98STiwei Bie struct vring_packed_desc_event *driver;
894cdc4d98STiwei Bie struct vring_packed_desc_event *device;
904c3f5822SJens Freimann };
914c3f5822SJens Freimann
926c3169a3SBruce Richardson struct vring {
936c3169a3SBruce Richardson unsigned int num;
94*802a0389SSrujana Challa rte_iova_t desc_iova;
956c3169a3SBruce Richardson struct vring_desc *desc;
966c3169a3SBruce Richardson struct vring_avail *avail;
976c3169a3SBruce Richardson struct vring_used *used;
986c3169a3SBruce Richardson };
996c3169a3SBruce Richardson
1006c3169a3SBruce Richardson /* The standard layout for the ring is a continuous chunk of memory which
1016c3169a3SBruce Richardson * looks like this. We assume num is a power of 2.
1026c3169a3SBruce Richardson *
1036c3169a3SBruce Richardson * struct vring {
1046c3169a3SBruce Richardson * // The actual descriptors (16 bytes each)
1056c3169a3SBruce Richardson * struct vring_desc desc[num];
1066c3169a3SBruce Richardson *
1076c3169a3SBruce Richardson * // A ring of available descriptor heads with free-running index.
1086c3169a3SBruce Richardson * __u16 avail_flags;
1096c3169a3SBruce Richardson * __u16 avail_idx;
1106c3169a3SBruce Richardson * __u16 available[num];
1116c3169a3SBruce Richardson * __u16 used_event_idx;
1126c3169a3SBruce Richardson *
1136c3169a3SBruce Richardson * // Padding to the next align boundary.
1146c3169a3SBruce Richardson * char pad[];
1156c3169a3SBruce Richardson *
1166c3169a3SBruce Richardson * // A ring of used descriptor heads with free-running index.
1176c3169a3SBruce Richardson * __u16 used_flags;
1186c3169a3SBruce Richardson * __u16 used_idx;
1196c3169a3SBruce Richardson * struct vring_used_elem used[num];
1206c3169a3SBruce Richardson * __u16 avail_event_idx;
1216c3169a3SBruce Richardson * };
1226c3169a3SBruce Richardson *
1236c3169a3SBruce Richardson * NOTE: for VirtIO PCI, align is 4096.
1246c3169a3SBruce Richardson */
1256c3169a3SBruce Richardson
1266c3169a3SBruce Richardson /*
1276c3169a3SBruce Richardson * We publish the used event index at the end of the available ring, and vice
1286c3169a3SBruce Richardson * versa. They are at the end for backwards compatibility.
1296c3169a3SBruce Richardson */
1306c3169a3SBruce Richardson #define vring_used_event(vr) ((vr)->avail->ring[(vr)->num])
1316c3169a3SBruce Richardson #define vring_avail_event(vr) (*(uint16_t *)&(vr)->used->ring[(vr)->num])
1326c3169a3SBruce Richardson
1331e7bd238SStephen Hemminger static inline size_t
vring_size(struct virtio_hw * hw,unsigned int num,unsigned long align)134f803734bSJens Freimann vring_size(struct virtio_hw *hw, unsigned int num, unsigned long align)
1356c3169a3SBruce Richardson {
1361e7bd238SStephen Hemminger size_t size;
1376c3169a3SBruce Richardson
138b4f9a45aSMaxime Coquelin if (virtio_with_packed_queue(hw)) {
139f803734bSJens Freimann size = num * sizeof(struct vring_packed_desc);
140f803734bSJens Freimann size += sizeof(struct vring_packed_desc_event);
141f803734bSJens Freimann size = RTE_ALIGN_CEIL(size, align);
142f803734bSJens Freimann size += sizeof(struct vring_packed_desc_event);
143f803734bSJens Freimann return size;
144f803734bSJens Freimann }
145f803734bSJens Freimann
1466c3169a3SBruce Richardson size = num * sizeof(struct vring_desc);
1476c3169a3SBruce Richardson size += sizeof(struct vring_avail) + (num * sizeof(uint16_t));
1486c3169a3SBruce Richardson size = RTE_ALIGN_CEIL(size, align);
1496c3169a3SBruce Richardson size += sizeof(struct vring_used) +
1506c3169a3SBruce Richardson (num * sizeof(struct vring_used_elem));
1516c3169a3SBruce Richardson return size;
1526c3169a3SBruce Richardson }
1536c3169a3SBruce Richardson static inline void
vring_init_split(struct vring * vr,uint8_t * p,rte_iova_t iova,unsigned long align,unsigned int num)154*802a0389SSrujana Challa vring_init_split(struct vring *vr, uint8_t *p, rte_iova_t iova,
155*802a0389SSrujana Challa unsigned long align, unsigned int num)
1566c3169a3SBruce Richardson {
1576c3169a3SBruce Richardson vr->num = num;
1586c3169a3SBruce Richardson vr->desc = (struct vring_desc *) p;
159*802a0389SSrujana Challa vr->desc_iova = iova;
1606c3169a3SBruce Richardson vr->avail = (struct vring_avail *) (p +
1616c3169a3SBruce Richardson num * sizeof(struct vring_desc));
1626c3169a3SBruce Richardson vr->used = (void *)
1636c3169a3SBruce Richardson RTE_ALIGN_CEIL((uintptr_t)(&vr->avail->ring[num]), align);
1646c3169a3SBruce Richardson }
1656c3169a3SBruce Richardson
166f803734bSJens Freimann static inline void
vring_init_packed(struct vring_packed * vr,uint8_t * p,rte_iova_t iova,unsigned long align,unsigned int num)167*802a0389SSrujana Challa vring_init_packed(struct vring_packed *vr, uint8_t *p, rte_iova_t iova,
168*802a0389SSrujana Challa unsigned long align, unsigned int num)
169f803734bSJens Freimann {
170f803734bSJens Freimann vr->num = num;
1714cdc4d98STiwei Bie vr->desc = (struct vring_packed_desc *)p;
172*802a0389SSrujana Challa vr->desc_iova = iova;
1734cdc4d98STiwei Bie vr->driver = (struct vring_packed_desc_event *)(p +
174f803734bSJens Freimann vr->num * sizeof(struct vring_packed_desc));
1754cdc4d98STiwei Bie vr->device = (struct vring_packed_desc_event *)
1764cdc4d98STiwei Bie RTE_ALIGN_CEIL(((uintptr_t)vr->driver +
177f803734bSJens Freimann sizeof(struct vring_packed_desc_event)), align);
178f803734bSJens Freimann }
179f803734bSJens Freimann
1806c3169a3SBruce Richardson /*
1816c3169a3SBruce Richardson * The following is used with VIRTIO_RING_F_EVENT_IDX.
1826c3169a3SBruce Richardson * Assuming a given event_idx value from the other size, if we have
1836c3169a3SBruce Richardson * just incremented index from old to new_idx, should we trigger an
1846c3169a3SBruce Richardson * event?
1856c3169a3SBruce Richardson */
1866c3169a3SBruce Richardson static inline int
vring_need_event(uint16_t event_idx,uint16_t new_idx,uint16_t old)1876c3169a3SBruce Richardson vring_need_event(uint16_t event_idx, uint16_t new_idx, uint16_t old)
1886c3169a3SBruce Richardson {
1896c3169a3SBruce Richardson return (uint16_t)(new_idx - event_idx - 1) < (uint16_t)(new_idx - old);
1906c3169a3SBruce Richardson }
1916c3169a3SBruce Richardson
1926c3169a3SBruce Richardson #endif /* _VIRTIO_RING_H_ */
193