1f8296c60SJoshua M. Clulow /* 2f8296c60SJoshua M. Clulow * This file and its contents are supplied under the terms of the 3f8296c60SJoshua M. Clulow * Common Development and Distribution License ("CDDL"), version 1.0. 4f8296c60SJoshua M. Clulow * You may only use this file in accordance with the terms of version 5f8296c60SJoshua M. Clulow * 1.0 of the CDDL. 6f8296c60SJoshua M. Clulow * 7f8296c60SJoshua M. Clulow * A full copy of the text of the CDDL should have accompanied this 8f8296c60SJoshua M. Clulow * source. A copy of the CDDL is also available via the Internet at 9f8296c60SJoshua M. Clulow * http://www.illumos.org/license/CDDL. 10f8296c60SJoshua M. Clulow */ 11f8296c60SJoshua M. Clulow 12f8296c60SJoshua M. Clulow /* 13f8296c60SJoshua M. Clulow * Copyright 2019 Joyent, Inc. 14*501bc5c0SAndy Fiddaman * Copyright 2022 OmniOS Community Edition (OmniOSce) Association. 15f8296c60SJoshua M. Clulow */ 16f8296c60SJoshua M. Clulow 17f8296c60SJoshua M. Clulow #ifndef _VIRTIO_IMPL_H 18f8296c60SJoshua M. Clulow #define _VIRTIO_IMPL_H 19f8296c60SJoshua M. Clulow 20f8296c60SJoshua M. Clulow /* 21f8296c60SJoshua M. Clulow * VIRTIO FRAMEWORK: FRAMEWORK-PRIVATE DEFINITIONS 22f8296c60SJoshua M. Clulow * 23f8296c60SJoshua M. Clulow * For design and usage documentation, see the comments in "virtio.h". 24f8296c60SJoshua M. Clulow * 25f8296c60SJoshua M. Clulow * NOTE: Client drivers should not use definitions from this file. 26f8296c60SJoshua M. Clulow */ 27f8296c60SJoshua M. Clulow 28f8296c60SJoshua M. Clulow #include <sys/types.h> 29f8296c60SJoshua M. Clulow #include <sys/dditypes.h> 30f8296c60SJoshua M. Clulow #include <sys/list.h> 31f8296c60SJoshua M. Clulow #include <sys/ccompile.h> 32f8296c60SJoshua M. Clulow 33f8296c60SJoshua M. Clulow #include "virtio.h" 34f8296c60SJoshua M. Clulow 35f8296c60SJoshua M. Clulow #ifdef __cplusplus 36f8296c60SJoshua M. Clulow extern "C" { 37f8296c60SJoshua M. Clulow #endif 38f8296c60SJoshua M. Clulow 39f8296c60SJoshua M. Clulow extern ddi_device_acc_attr_t virtio_acc_attr; 40f8296c60SJoshua M. Clulow extern ddi_dma_attr_t virtio_dma_attr; 41f8296c60SJoshua M. Clulow 42f8296c60SJoshua M. Clulow typedef struct virtio_vq_desc virtio_vq_desc_t; 43f8296c60SJoshua M. Clulow typedef struct virtio_vq_driver virtio_vq_driver_t; 44f8296c60SJoshua M. Clulow typedef struct virtio_vq_device virtio_vq_device_t; 45f8296c60SJoshua M. Clulow typedef struct virtio_vq_elem virtio_vq_elem_t; 46f8296c60SJoshua M. Clulow 47f8296c60SJoshua M. Clulow int virtio_dma_init(virtio_t *, virtio_dma_t *, size_t, const ddi_dma_attr_t *, 48f8296c60SJoshua M. Clulow int, int); 49f8296c60SJoshua M. Clulow void virtio_dma_fini(virtio_dma_t *); 50f8296c60SJoshua M. Clulow 51f8296c60SJoshua M. Clulow 52f8296c60SJoshua M. Clulow 53f8296c60SJoshua M. Clulow typedef enum virtio_dma_level { 54f8296c60SJoshua M. Clulow VIRTIO_DMALEVEL_HANDLE_ALLOC = (1ULL << 0), 55f8296c60SJoshua M. Clulow VIRTIO_DMALEVEL_MEMORY_ALLOC = (1ULL << 1), 56f8296c60SJoshua M. Clulow VIRTIO_DMALEVEL_HANDLE_BOUND = (1ULL << 2), 57f8296c60SJoshua M. Clulow VIRTIO_DMALEVEL_COOKIE_ARRAY = (1ULL << 3), 58f8296c60SJoshua M. Clulow } virtio_dma_level_t; 59f8296c60SJoshua M. Clulow 60f8296c60SJoshua M. Clulow struct virtio_dma { 61f8296c60SJoshua M. Clulow virtio_dma_level_t vidma_level; 62f8296c60SJoshua M. Clulow virtio_t *vidma_virtio; 63f8296c60SJoshua M. Clulow caddr_t vidma_va; 64f8296c60SJoshua M. Clulow size_t vidma_size; 65f8296c60SJoshua M. Clulow size_t vidma_real_size; 66f8296c60SJoshua M. Clulow ddi_dma_handle_t vidma_dma_handle; 67f8296c60SJoshua M. Clulow ddi_acc_handle_t vidma_acc_handle; 68f8296c60SJoshua M. Clulow uint_t vidma_dma_ncookies; 69f8296c60SJoshua M. Clulow ddi_dma_cookie_t *vidma_dma_cookies; 70f8296c60SJoshua M. Clulow }; 71f8296c60SJoshua M. Clulow 72f8296c60SJoshua M. Clulow typedef enum virtio_initlevel { 73f8296c60SJoshua M. Clulow VIRTIO_INITLEVEL_REGS = (1ULL << 0), 74f8296c60SJoshua M. Clulow VIRTIO_INITLEVEL_PROVIDER = (1ULL << 1), 75f8296c60SJoshua M. Clulow VIRTIO_INITLEVEL_INT_ALLOC = (1ULL << 2), 76f8296c60SJoshua M. Clulow VIRTIO_INITLEVEL_INT_ADDED = (1ULL << 3), 77f8296c60SJoshua M. Clulow VIRTIO_INITLEVEL_INT_ENABLED = (1ULL << 4), 78f8296c60SJoshua M. Clulow VIRTIO_INITLEVEL_SHUTDOWN = (1ULL << 5), 79f8296c60SJoshua M. Clulow } virtio_initlevel_t; 80f8296c60SJoshua M. Clulow 81f8296c60SJoshua M. Clulow struct virtio { 82f8296c60SJoshua M. Clulow dev_info_t *vio_dip; 83f8296c60SJoshua M. Clulow 84f8296c60SJoshua M. Clulow kmutex_t vio_mutex; 85f8296c60SJoshua M. Clulow 86f8296c60SJoshua M. Clulow virtio_initlevel_t vio_initlevel; 87f8296c60SJoshua M. Clulow 88f8296c60SJoshua M. Clulow list_t vio_queues; 89f8296c60SJoshua M. Clulow 90f8296c60SJoshua M. Clulow ddi_acc_handle_t vio_barh; 91f8296c60SJoshua M. Clulow caddr_t vio_bar; 92f8296c60SJoshua M. Clulow uint_t vio_config_offset; 93f8296c60SJoshua M. Clulow 94f8296c60SJoshua M. Clulow uint32_t vio_features; 95f8296c60SJoshua M. Clulow uint32_t vio_features_device; 96f8296c60SJoshua M. Clulow 97f8296c60SJoshua M. Clulow ddi_intr_handle_t *vio_interrupts; 98f8296c60SJoshua M. Clulow int vio_ninterrupts; 99f8296c60SJoshua M. Clulow int vio_interrupt_type; 100f8296c60SJoshua M. Clulow int vio_interrupt_cap; 101f8296c60SJoshua M. Clulow uint_t vio_interrupt_priority; 102*501bc5c0SAndy Fiddaman 103*501bc5c0SAndy Fiddaman ddi_intr_handler_t *vio_cfgchange_handler; 104*501bc5c0SAndy Fiddaman void *vio_cfgchange_handlerarg; 105*501bc5c0SAndy Fiddaman boolean_t vio_cfgchange_handler_added; 106*501bc5c0SAndy Fiddaman uint_t vio_cfgchange_handler_index; 107f8296c60SJoshua M. Clulow }; 108f8296c60SJoshua M. Clulow 109f8296c60SJoshua M. Clulow struct virtio_queue { 110f8296c60SJoshua M. Clulow virtio_t *viq_virtio; 111f8296c60SJoshua M. Clulow kmutex_t viq_mutex; 112f8296c60SJoshua M. Clulow const char *viq_name; 113f8296c60SJoshua M. Clulow list_node_t viq_link; 114f8296c60SJoshua M. Clulow 115f8296c60SJoshua M. Clulow boolean_t viq_shutdown; 116f8296c60SJoshua M. Clulow boolean_t viq_indirect; 117f8296c60SJoshua M. Clulow uint_t viq_max_segs; 118f8296c60SJoshua M. Clulow 119f8296c60SJoshua M. Clulow /* 120f8296c60SJoshua M. Clulow * Each Virtio device type has some set of queues for data transfer to 121f8296c60SJoshua M. Clulow * and from the host. This index is described in the specification for 122f8296c60SJoshua M. Clulow * the particular device and queue type, and written to QUEUE_SELECT to 123f8296c60SJoshua M. Clulow * allow interaction with the queue. For example, a network device has 124f8296c60SJoshua M. Clulow * at least a receive queue with index 0, and a transmit queue with 125f8296c60SJoshua M. Clulow * index 1. 126f8296c60SJoshua M. Clulow */ 127f8296c60SJoshua M. Clulow uint16_t viq_index; 128f8296c60SJoshua M. Clulow 129f8296c60SJoshua M. Clulow /* 130f8296c60SJoshua M. Clulow * For legacy Virtio devices, the size and shape of the queue is 131f8296c60SJoshua M. Clulow * determined entirely by the number of queue entries. 132f8296c60SJoshua M. Clulow */ 133f8296c60SJoshua M. Clulow uint16_t viq_size; 134f8296c60SJoshua M. Clulow id_space_t *viq_descmap; 135f8296c60SJoshua M. Clulow 136f8296c60SJoshua M. Clulow /* 137f8296c60SJoshua M. Clulow * The memory shared between the device and the driver is allocated as 138f8296c60SJoshua M. Clulow * a large phyisically contiguous chunk. Access to this area is 139f8296c60SJoshua M. Clulow * through three pointers to packed structures. 140f8296c60SJoshua M. Clulow */ 141f8296c60SJoshua M. Clulow virtio_dma_t viq_dma; 142f8296c60SJoshua M. Clulow virtio_vq_desc_t *viq_dma_descs; 143f8296c60SJoshua M. Clulow virtio_vq_driver_t *viq_dma_driver; 144f8296c60SJoshua M. Clulow virtio_vq_device_t *viq_dma_device; 145f8296c60SJoshua M. Clulow 146f8296c60SJoshua M. Clulow uint16_t viq_device_index; 147f8296c60SJoshua M. Clulow uint16_t viq_driver_index; 148f8296c60SJoshua M. Clulow 149f8296c60SJoshua M. Clulow /* 150f8296c60SJoshua M. Clulow * Interrupt handler function, or NULL if not provided. 151f8296c60SJoshua M. Clulow */ 152f8296c60SJoshua M. Clulow ddi_intr_handler_t *viq_func; 153f8296c60SJoshua M. Clulow void *viq_funcarg; 154f8296c60SJoshua M. Clulow boolean_t viq_handler_added; 155f8296c60SJoshua M. Clulow uint_t viq_handler_index; 156f8296c60SJoshua M. Clulow 157f8296c60SJoshua M. Clulow /* 158f8296c60SJoshua M. Clulow * When a chain is submitted to the queue, it is also stored in this 159f8296c60SJoshua M. Clulow * AVL tree keyed by the index of the first descriptor in the chain. 160f8296c60SJoshua M. Clulow */ 161f8296c60SJoshua M. Clulow avl_tree_t viq_inflight; 162f8296c60SJoshua M. Clulow }; 163f8296c60SJoshua M. Clulow 164f8296c60SJoshua M. Clulow struct virtio_chain { 165f8296c60SJoshua M. Clulow virtio_queue_t *vic_vq; 166f8296c60SJoshua M. Clulow avl_node_t vic_node; 167f8296c60SJoshua M. Clulow 168f8296c60SJoshua M. Clulow void *vic_data; 169f8296c60SJoshua M. Clulow 170f8296c60SJoshua M. Clulow uint16_t vic_head; 171f8296c60SJoshua M. Clulow uint32_t vic_received_length; 172f8296c60SJoshua M. Clulow 173f8296c60SJoshua M. Clulow virtio_dma_t vic_indirect_dma; 174f8296c60SJoshua M. Clulow uint_t vic_indirect_capacity; 175f8296c60SJoshua M. Clulow uint_t vic_indirect_used; 176f8296c60SJoshua M. Clulow 177f8296c60SJoshua M. Clulow uint_t vic_direct_capacity; 178f8296c60SJoshua M. Clulow uint_t vic_direct_used; 179f8296c60SJoshua M. Clulow uint16_t vic_direct[]; 180f8296c60SJoshua M. Clulow }; 181f8296c60SJoshua M. Clulow 182f8296c60SJoshua M. Clulow /* 183f8296c60SJoshua M. Clulow * PACKED STRUCTS FOR DEVICE ACCESS 184f8296c60SJoshua M. Clulow */ 185f8296c60SJoshua M. Clulow 186f8296c60SJoshua M. Clulow struct virtio_vq_desc { 187f8296c60SJoshua M. Clulow /* 188f8296c60SJoshua M. Clulow * Buffer physical address and length. 189f8296c60SJoshua M. Clulow */ 190f8296c60SJoshua M. Clulow uint64_t vqd_addr; 191f8296c60SJoshua M. Clulow uint32_t vqd_len; 192f8296c60SJoshua M. Clulow 193f8296c60SJoshua M. Clulow /* 194f8296c60SJoshua M. Clulow * Flags. Use with the VIRTQ_DESC_F_* family of constants. See below. 195f8296c60SJoshua M. Clulow */ 196f8296c60SJoshua M. Clulow uint16_t vqd_flags; 197f8296c60SJoshua M. Clulow 198f8296c60SJoshua M. Clulow /* 199f8296c60SJoshua M. Clulow * If VIRTQ_DESC_F_NEXT is set in flags, this refers to the next 200f8296c60SJoshua M. Clulow * descriptor in the chain by table index. 201f8296c60SJoshua M. Clulow */ 202f8296c60SJoshua M. Clulow uint16_t vqd_next; 203f8296c60SJoshua M. Clulow } __packed; 204f8296c60SJoshua M. Clulow 205f8296c60SJoshua M. Clulow /* 206f8296c60SJoshua M. Clulow * VIRTIO DESCRIPTOR FLAGS (vqd_flags) 207f8296c60SJoshua M. Clulow */ 208f8296c60SJoshua M. Clulow 209f8296c60SJoshua M. Clulow /* 210f8296c60SJoshua M. Clulow * NEXT: 211f8296c60SJoshua M. Clulow * Signals that this descriptor (direct or indirect) is part of a chain. 212f8296c60SJoshua M. Clulow * If populated, "vqd_next" names the next descriptor in the chain by its 213f8296c60SJoshua M. Clulow * table index. 214f8296c60SJoshua M. Clulow */ 215f8296c60SJoshua M. Clulow #define VIRTQ_DESC_F_NEXT (1 << 0) 216f8296c60SJoshua M. Clulow 217f8296c60SJoshua M. Clulow /* 218f8296c60SJoshua M. Clulow * WRITE: 219f8296c60SJoshua M. Clulow * Determines whether this buffer is to be written by the device (WRITE is 220f8296c60SJoshua M. Clulow * set) or by the driver (WRITE is not set). 221f8296c60SJoshua M. Clulow */ 222f8296c60SJoshua M. Clulow #define VIRTQ_DESC_F_WRITE (1 << 1) 223f8296c60SJoshua M. Clulow 224f8296c60SJoshua M. Clulow /* 225f8296c60SJoshua M. Clulow * INDIRECT: 226f8296c60SJoshua M. Clulow * This bit signals that a direct descriptor refers to an indirect 227f8296c60SJoshua M. Clulow * descriptor list, rather than directly to a buffer. This bit may only 228f8296c60SJoshua M. Clulow * be used in a direct descriptor; indirect descriptors are not allowed to 229f8296c60SJoshua M. Clulow * refer to additional layers of indirect tables. If this bit is set, 230f8296c60SJoshua M. Clulow * NEXT must be clear; indirect descriptors may not be chained. 231f8296c60SJoshua M. Clulow */ 232f8296c60SJoshua M. Clulow #define VIRTQ_DESC_F_INDIRECT (1 << 2) 233f8296c60SJoshua M. Clulow 234f8296c60SJoshua M. Clulow /* 235f8296c60SJoshua M. Clulow * This structure is variously known as the "available" or "avail" ring, or the 236f8296c60SJoshua M. Clulow * driver-owned portion of the queue structure. It is used by the driver to 237f8296c60SJoshua M. Clulow * submit descriptor chains to the device. 238f8296c60SJoshua M. Clulow */ 239f8296c60SJoshua M. Clulow struct virtio_vq_driver { 240f8296c60SJoshua M. Clulow uint16_t vqdr_flags; 241f8296c60SJoshua M. Clulow uint16_t vqdr_index; 242f8296c60SJoshua M. Clulow uint16_t vqdr_ring[]; 243f8296c60SJoshua M. Clulow } __packed; 244f8296c60SJoshua M. Clulow 245f8296c60SJoshua M. Clulow #define VIRTQ_AVAIL_F_NO_INTERRUPT (1 << 0) 246f8296c60SJoshua M. Clulow 247f8296c60SJoshua M. Clulow /* 248f8296c60SJoshua M. Clulow * We use the sizeof operator on this packed struct to calculate the offset of 249f8296c60SJoshua M. Clulow * subsequent structs. Ensure the compiler is not adding any padding to the 250f8296c60SJoshua M. Clulow * end of the struct. 251f8296c60SJoshua M. Clulow */ 252f8296c60SJoshua M. Clulow CTASSERT(sizeof (virtio_vq_driver_t) == 253f8296c60SJoshua M. Clulow offsetof(virtio_vq_driver_t, vqdr_ring)); 254f8296c60SJoshua M. Clulow 255f8296c60SJoshua M. Clulow struct virtio_vq_elem { 256f8296c60SJoshua M. Clulow /* 257f8296c60SJoshua M. Clulow * The device returns chains of descriptors by specifying the table 258f8296c60SJoshua M. Clulow * index of the first descriptor in the chain. 259f8296c60SJoshua M. Clulow */ 260f8296c60SJoshua M. Clulow uint32_t vqe_start; 261f8296c60SJoshua M. Clulow uint32_t vqe_len; 262f8296c60SJoshua M. Clulow } __packed; 263f8296c60SJoshua M. Clulow 264f8296c60SJoshua M. Clulow /* 265f8296c60SJoshua M. Clulow * This structure is variously known as the "used" ring, or the device-owned 266f8296c60SJoshua M. Clulow * portion of the queue structure. It is used by the device to return 267c00b0288SJoshua M. Clulow * completed descriptor chains to the driver. 268f8296c60SJoshua M. Clulow */ 269f8296c60SJoshua M. Clulow struct virtio_vq_device { 270f8296c60SJoshua M. Clulow uint16_t vqde_flags; 271f8296c60SJoshua M. Clulow uint16_t vqde_index; 272f8296c60SJoshua M. Clulow virtio_vq_elem_t vqde_ring[]; 273f8296c60SJoshua M. Clulow } __packed; 274f8296c60SJoshua M. Clulow 275f8296c60SJoshua M. Clulow #define VIRTQ_USED_F_NO_NOTIFY (1 << 0) 276f8296c60SJoshua M. Clulow 277f8296c60SJoshua M. Clulow /* 278f8296c60SJoshua M. Clulow * BASIC CONFIGURATION 279f8296c60SJoshua M. Clulow * 280f8296c60SJoshua M. Clulow * Legacy devices expose both their generic and their device-specific 281f8296c60SJoshua M. Clulow * configuration through PCI BAR0. This is the second entry in the register 282f8296c60SJoshua M. Clulow * address space set for these devices. 283f8296c60SJoshua M. Clulow */ 284f8296c60SJoshua M. Clulow #define VIRTIO_LEGACY_PCI_BAR0 1 285f8296c60SJoshua M. Clulow 286f8296c60SJoshua M. Clulow /* 287f8296c60SJoshua M. Clulow * These are offsets into the base configuration space available through the 288f8296c60SJoshua M. Clulow * virtio_get*() and virtio_put*() family of functions. These offsets are for 289f8296c60SJoshua M. Clulow * what the specification describes as the "legacy" mode of device operation. 290f8296c60SJoshua M. Clulow */ 291f8296c60SJoshua M. Clulow #define VIRTIO_LEGACY_FEATURES_DEVICE 0x00 /* 32 R */ 292f8296c60SJoshua M. Clulow #define VIRTIO_LEGACY_FEATURES_DRIVER 0x04 /* 32 R/W */ 293f8296c60SJoshua M. Clulow #define VIRTIO_LEGACY_QUEUE_ADDRESS 0x08 /* 32 R/W */ 294f8296c60SJoshua M. Clulow #define VIRTIO_LEGACY_QUEUE_SIZE 0x0C /* 16 R */ 295f8296c60SJoshua M. Clulow #define VIRTIO_LEGACY_QUEUE_SELECT 0x0E /* 16 R/W */ 296f8296c60SJoshua M. Clulow #define VIRTIO_LEGACY_QUEUE_NOTIFY 0x10 /* 16 R/W */ 297f8296c60SJoshua M. Clulow #define VIRTIO_LEGACY_DEVICE_STATUS 0x12 /* 8 R/W */ 298f8296c60SJoshua M. Clulow #define VIRTIO_LEGACY_ISR_STATUS 0x13 /* 8 R */ 299f8296c60SJoshua M. Clulow 300f8296c60SJoshua M. Clulow #define VIRTIO_LEGACY_MSIX_CONFIG 0x14 /* 16 R/W */ 301f8296c60SJoshua M. Clulow #define VIRTIO_LEGACY_MSIX_QUEUE 0x16 /* 16 R/W */ 302f8296c60SJoshua M. Clulow 303f8296c60SJoshua M. Clulow #define VIRTIO_LEGACY_CFG_OFFSET (VIRTIO_LEGACY_ISR_STATUS + 1) 304f8296c60SJoshua M. Clulow #define VIRTIO_LEGACY_CFG_OFFSET_MSIX (VIRTIO_LEGACY_MSIX_QUEUE + 2) 305f8296c60SJoshua M. Clulow 306f8296c60SJoshua M. Clulow #define VIRTIO_LEGACY_MSI_NO_VECTOR 0xFFFF 307f8296c60SJoshua M. Clulow 308f8296c60SJoshua M. Clulow /* 309f8296c60SJoshua M. Clulow * Bits in the Device Status byte (VIRTIO_LEGACY_DEVICE_STATUS): 310f8296c60SJoshua M. Clulow */ 311f8296c60SJoshua M. Clulow #define VIRTIO_STATUS_RESET 0 312f8296c60SJoshua M. Clulow #define VIRTIO_STATUS_ACKNOWLEDGE (1 << 0) 313f8296c60SJoshua M. Clulow #define VIRTIO_STATUS_DRIVER (1 << 1) 314f8296c60SJoshua M. Clulow #define VIRTIO_STATUS_DRIVER_OK (1 << 2) 315f8296c60SJoshua M. Clulow #define VIRTIO_STATUS_FAILED (1 << 7) 316f8296c60SJoshua M. Clulow 317f8296c60SJoshua M. Clulow /* 318f8296c60SJoshua M. Clulow * Bits in the Interrupt Service Routine Status byte 319f8296c60SJoshua M. Clulow * (VIRTIO_LEGACY_ISR_STATUS): 320f8296c60SJoshua M. Clulow */ 321f8296c60SJoshua M. Clulow #define VIRTIO_ISR_CHECK_QUEUES (1 << 0) 322f8296c60SJoshua M. Clulow #define VIRTIO_ISR_CHECK_CONFIG (1 << 1) 323f8296c60SJoshua M. Clulow 324f8296c60SJoshua M. Clulow /* 325f8296c60SJoshua M. Clulow * Bits in the Features fields (VIRTIO_LEGACY_FEATURES_DEVICE, 326f8296c60SJoshua M. Clulow * VIRTIO_LEGACY_FEATURES_DRIVER): 327f8296c60SJoshua M. Clulow */ 328f8296c60SJoshua M. Clulow #define VIRTIO_F_RING_INDIRECT_DESC (1ULL << 28) 329f8296c60SJoshua M. Clulow 330f8296c60SJoshua M. Clulow /* 331f8296c60SJoshua M. Clulow * For devices operating in the legacy mode, virtqueues must be aligned on a 332f8296c60SJoshua M. Clulow * "page size" of 4096 bytes; this is also called the "Queue Align" value in 333f8296c60SJoshua M. Clulow * newer versions of the specification. 334f8296c60SJoshua M. Clulow */ 335f8296c60SJoshua M. Clulow #define VIRTIO_PAGE_SHIFT 12 336f8296c60SJoshua M. Clulow #define VIRTIO_PAGE_SIZE (1 << VIRTIO_PAGE_SHIFT) 337f8296c60SJoshua M. Clulow CTASSERT(VIRTIO_PAGE_SIZE == 4096); 338f8296c60SJoshua M. Clulow CTASSERT(ISP2(VIRTIO_PAGE_SIZE)); 339f8296c60SJoshua M. Clulow 340f8296c60SJoshua M. Clulow /* 341f8296c60SJoshua M. Clulow * DMA SYNCHRONISATION WRAPPERS 342f8296c60SJoshua M. Clulow */ 343f8296c60SJoshua M. Clulow 344f8296c60SJoshua M. Clulow /* 345f8296c60SJoshua M. Clulow * Synchronise the driver-owned portion of the queue so that the device can see 346f8296c60SJoshua M. Clulow * our writes. This covers the memory accessed via the "viq_dma_descs" and 347f8296c60SJoshua M. Clulow * "viq_dma_device" members. 348f8296c60SJoshua M. Clulow */ 349f8296c60SJoshua M. Clulow #define VIRTQ_DMA_SYNC_FORDEV(viq) VERIFY0(ddi_dma_sync( \ 350f8296c60SJoshua M. Clulow (viq)->viq_dma.vidma_dma_handle, \ 351f8296c60SJoshua M. Clulow 0, \ 352f8296c60SJoshua M. Clulow (uintptr_t)(viq)->viq_dma_device - \ 353f8296c60SJoshua M. Clulow (uintptr_t)(viq)->viq_dma_descs, \ 354f8296c60SJoshua M. Clulow DDI_DMA_SYNC_FORDEV)) 355f8296c60SJoshua M. Clulow 356f8296c60SJoshua M. Clulow /* 357f8296c60SJoshua M. Clulow * Synchronise the device-owned portion of the queue so that we can see any 358f8296c60SJoshua M. Clulow * writes from the device. This covers the memory accessed via the 359f8296c60SJoshua M. Clulow * "viq_dma_device" member. 360f8296c60SJoshua M. Clulow */ 361f8296c60SJoshua M. Clulow #define VIRTQ_DMA_SYNC_FORKERNEL(viq) VERIFY0(ddi_dma_sync( \ 362f8296c60SJoshua M. Clulow (viq)->viq_dma.vidma_dma_handle, \ 363f8296c60SJoshua M. Clulow (uintptr_t)(viq)->viq_dma_device - \ 364f8296c60SJoshua M. Clulow (uintptr_t)(viq)->viq_dma_descs, \ 365f8296c60SJoshua M. Clulow (viq)->viq_dma.vidma_size - \ 366f8296c60SJoshua M. Clulow (uintptr_t)(viq)->viq_dma_device - \ 367f8296c60SJoshua M. Clulow (uintptr_t)(viq)->viq_dma_descs, \ 368f8296c60SJoshua M. Clulow DDI_DMA_SYNC_FORKERNEL)) 369f8296c60SJoshua M. Clulow 370f8296c60SJoshua M. Clulow #ifdef __cplusplus 371f8296c60SJoshua M. Clulow } 372f8296c60SJoshua M. Clulow #endif 373f8296c60SJoshua M. Clulow 374f8296c60SJoshua M. Clulow #endif /* _VIRTIO_IMPL_H */ 375