1 /* 2 * Copyright (c) 2006-2023, RT-Thread Development Team 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 * 6 * Change Logs: 7 * Date Author Notes 8 * 2021-11-11 GuEe-GUI the first version 9 */ 10 11 #ifndef __VIRTIO_QUEUE_H__ 12 #define __VIRTIO_QUEUE_H__ 13 14 #include <rtdef.h> 15 16 #define VIRTQ_DESC_F_NEXT 1 /* This marks a buffer as continuing via the next field. */ 17 #define VIRTQ_DESC_F_WRITE 2 /* This marks a buffer as write-only (otherwise read-only). */ 18 #define VIRTQ_DESC_F_INDIRECT 4 /* This means the buffer contains a list of buffer descriptors. */ 19 20 /* 21 * The device uses this in used->flags to advise the driver: don't kick me 22 * when you add a buffer. It's unreliable, so it's simply an optimization. 23 */ 24 #define VIRTQ_USED_F_NO_NOTIFY 1 25 26 /* 27 * The driver uses this in avail->flags to advise the device: don't 28 * interrupt me when you consume a buffer. It's unreliable, so it's 29 * simply an optimization. 30 */ 31 #define VIRTQ_AVAIL_F_NO_INTERRUPT 1 32 33 /* Virtqueue descriptors: 16 bytes. These can chain together via "next". */ 34 struct virtq_desc 35 { 36 rt_uint64_t addr; /* Address (guest-physical). */ 37 rt_uint32_t len; /* Length. */ 38 rt_uint16_t flags; /* The flags as indicated above. */ 39 rt_uint16_t next; /* We chain unused descriptors via this, too */ 40 }; 41 42 struct virtq_avail 43 { 44 rt_uint16_t flags; /* Notifications */ 45 rt_uint16_t idx; /* Where the driver would put the next descriptor entry in the ring (modulo the queue size) */ 46 rt_uint16_t ring[]; 47 48 /* 49 * Only if VIRTIO_F_RING_EVENT_IDX 50 * rt_uint16_t used_event; 51 */ 52 }; 53 54 struct virtq_used_elem 55 { 56 rt_uint32_t id; /* Index of start of used descriptor chain. */ 57 rt_uint32_t len; /* Total length of the descriptor chain which was written to. */ 58 }; 59 60 struct virtq_used 61 { 62 rt_uint16_t flags; 63 rt_uint16_t idx; 64 struct virtq_used_elem ring[]; 65 66 /* 67 * Only if VIRTIO_F_RING_EVENT_IDX 68 * rt_uint16_t avail_event; 69 */ 70 }; 71 72 struct virtq 73 { 74 rt_uint32_t num; 75 76 struct virtq_desc *desc; 77 struct virtq_avail *avail; 78 struct virtq_used *used; 79 80 /* Helper of driver */ 81 rt_uint16_t used_idx; 82 rt_bool_t *free; 83 rt_size_t free_count; 84 }; 85 86 #define VIRTQ_DESC_TOTAL_SIZE(ring_size) (sizeof(struct virtq_desc) * (ring_size)) 87 /* flags, idx, used_event + ring * ring_size */ 88 #define VIRTQ_AVAIL_TOTAL_SIZE(ring_size) (sizeof(rt_uint16_t) * 3 + sizeof(rt_uint16_t) * (ring_size)) 89 /* flags, idx, avail_event + ring * ring_size */ 90 #define VIRTQ_USED_TOTAL_SIZE(ring_size) (sizeof(rt_uint16_t) * 3 + sizeof(struct virtq_used_elem) * (ring_size)) 91 92 #define VIRTQ_AVAIL_RES_SIZE (sizeof(rt_uint16_t)) /* used_event */ 93 #define VIRTQ_USED_RES_SIZE (sizeof(rt_uint16_t)) /* avail_event */ 94 95 #define VIRTQ_INVALID_DESC_ID RT_UINT16_MAX 96 97 #endif /* __VIRTIO_QUEUE_H__ */ 98