1 /* 2 * Copyright (c) 2022 Wind River Systems, Inc. 3 * Based on Virtio PCI driver by Anthony Liguori, copyright IBM Corp. 2007 4 * 5 * SPDX-License-Identifier: BSD-3-Clause 6 */ 7 8 #ifndef OPENAMP_VIRTIO_MMIO_H 9 #define OPENAMP_VIRTIO_MMIO_H 10 11 #include <metal/device.h> 12 #include <openamp/virtio.h> 13 #include <openamp/virtqueue.h> 14 15 #ifdef __cplusplus 16 extern "C" { 17 #endif 18 19 /* Enable support for legacy devices */ 20 #define VIRTIO_MMIO_LEGACY 21 22 /* Control registers */ 23 24 /* Magic value ("virt" string) - Read Only */ 25 #define VIRTIO_MMIO_MAGIC_VALUE 0x000 26 27 #define VIRTIO_MMIO_MAGIC_VALUE_STRING ('v' | ('i' << 8) | ('r' << 16) | ('t' << 24)) 28 29 /* Virtio device version - Read Only */ 30 #define VIRTIO_MMIO_VERSION 0x004 31 32 /* Virtio device ID - Read Only */ 33 #define VIRTIO_MMIO_DEVICE_ID 0x008 34 35 /* Virtio vendor ID - Read Only */ 36 #define VIRTIO_MMIO_VENDOR_ID 0x00c 37 38 /* 39 * Bitmask of the features supported by the device (host) 40 * (32 bits per set) - Read Only 41 */ 42 #define VIRTIO_MMIO_DEVICE_FEATURES 0x010 43 44 /* Device (host) features set selector - Write Only */ 45 #define VIRTIO_MMIO_DEVICE_FEATURES_SEL 0x014 46 47 /* 48 * Bitmask of features activated by the driver (guest) 49 * (32 bits per set) - Write Only 50 */ 51 #define VIRTIO_MMIO_DRIVER_FEATURES 0x020 52 53 /* Activated features set selector - Write Only */ 54 #define VIRTIO_MMIO_DRIVER_FEATURES_SEL 0x024 55 56 #ifndef VIRTIO_MMIO_NO_LEGACY /* LEGACY DEVICES ONLY! */ 57 /* Guest's memory page size in bytes - Write Only */ 58 #define VIRTIO_MMIO_GUEST_PAGE_SIZE 0x028 59 #endif 60 61 /* Queue selector - Write Only */ 62 #define VIRTIO_MMIO_QUEUE_SEL 0x030 63 64 /* Maximum size of the currently selected queue - Read Only */ 65 #define VIRTIO_MMIO_QUEUE_NUM_MAX 0x034 66 67 /* Queue size for the currently selected queue - Write Only */ 68 #define VIRTIO_MMIO_QUEUE_NUM 0x038 69 70 #ifdef VIRTIO_MMIO_LEGACY 71 /* Used Ring alignment for the currently selected queue - Write Only */ 72 #define VIRTIO_MMIO_QUEUE_ALIGN 0x03c 73 /* Guest's PFN for the currently selected queue - Read Write */ 74 #define VIRTIO_MMIO_QUEUE_PFN 0x040 75 #endif 76 77 /* Ready bit for the currently selected queue - Read Write */ 78 #define VIRTIO_MMIO_QUEUE_READY 0x044 79 80 /* Queue notifier - Write Only */ 81 #define VIRTIO_MMIO_QUEUE_NOTIFY 0x050 82 83 /* Interrupt status - Read Only */ 84 #define VIRTIO_MMIO_INTERRUPT_STATUS 0x060 85 86 /* Interrupt acknowledge - Write Only */ 87 #define VIRTIO_MMIO_INTERRUPT_ACK 0x064 88 89 /* Device status register - Read Write */ 90 #define VIRTIO_MMIO_STATUS 0x070 91 92 /* Selected queue's Descriptor Table address, 64 bits in two halves */ 93 #define VIRTIO_MMIO_QUEUE_DESC_LOW 0x080 94 #define VIRTIO_MMIO_QUEUE_DESC_HIGH 0x084 95 96 /* Selected queue's Available Ring address, 64 bits in two halves */ 97 #define VIRTIO_MMIO_QUEUE_AVAIL_LOW 0x090 98 #define VIRTIO_MMIO_QUEUE_AVAIL_HIGH 0x094 99 100 /* Selected queue's Used Ring address, 64 bits in two halves */ 101 #define VIRTIO_MMIO_QUEUE_USED_LOW 0x0a0 102 #define VIRTIO_MMIO_QUEUE_USED_HIGH 0x0a4 103 104 /* Shared memory region id */ 105 #define VIRTIO_MMIO_SHM_SEL 0x0ac 106 107 /* Shared memory region length, 64 bits in two halves */ 108 #define VIRTIO_MMIO_SHM_LEN_LOW 0x0b0 109 #define VIRTIO_MMIO_SHM_LEN_HIGH 0x0b4 110 111 /* Shared memory region base address, 64 bits in two halves */ 112 #define VIRTIO_MMIO_SHM_BASE_LOW 0x0b8 113 #define VIRTIO_MMIO_SHM_BASE_HIGH 0x0bc 114 115 /* Configuration atomicity value */ 116 #define VIRTIO_MMIO_CONFIG_GENERATION 0x0fc 117 118 /* 119 * The config space is defined by each driver as 120 * the per-driver configuration space - Read Write 121 */ 122 #define VIRTIO_MMIO_CONFIG 0x100 123 124 /* Interrupt flags (re: interrupt status & acknowledge registers) */ 125 #define VIRTIO_MMIO_INT_VRING (1 << 0) 126 #define VIRTIO_MMIO_INT_CONFIG (1 << 1) 127 128 /* Data buffer size for preallocated buffers before vring */ 129 #define VIRTIO_MMIO_MAX_DATA_SIZE 128 130 131 /** @brief VIRTIO MMIO memory area */ 132 struct virtio_mmio_dev_mem { 133 /** Memory region physical address */ 134 void *base; 135 136 /** Memory region size */ 137 size_t size; 138 }; 139 140 /** @brief A VIRTIO MMIO device */ 141 struct virtio_mmio_device { 142 /** Base virtio device structure */ 143 struct virtio_device vdev; 144 145 /** Device configuration space metal_io_region */ 146 struct metal_io_region cfg_io; 147 148 /** Pre-shared memory space metal_io_region */ 149 struct metal_io_region shm_io; 150 151 /** VIRTIO device configuration space */ 152 struct virtio_mmio_dev_mem cfg_mem; 153 154 /** VIRTIO device pre-shared memory */ 155 struct virtio_mmio_dev_mem shm_mem; 156 157 /** VIRTIO_DEV_DRIVER or VIRTIO_DEV_DEVICE */ 158 unsigned int device_mode; 159 160 /** Interrupt number */ 161 unsigned int irq; 162 163 /** Custom user data */ 164 void *user_data; 165 }; 166 167 /** 168 * @brief Register a VIRTIO device with the VIRTIO stack. 169 * 170 * @param vdev Pointer to device structure. 171 * @param vq_num Number of virtqueues the device uses. 172 * @param vqs Array of pointers to vthe virtqueues used by the device. 173 */ 174 void virtio_mmio_register_device(struct virtio_device *vdev, int vq_num, struct virtqueue **vqs); 175 176 /** 177 * @brief Setup a virtqueue structure. 178 * 179 * @param vdev Pointer to device structure. 180 * @param idx Index of the virtqueue. 181 * @param vq Pointer to virtqueue structure. 182 * @param cb Pointer to virtqueue callback. Can be NULL. 183 * @param cb_arg Argument for the virtqueue callback. 184 * @param vq_name Name of the virtqueue. 185 * 186 * @return pointer to virtqueue structure. 187 */ 188 struct virtqueue *virtio_mmio_setup_virtqueue(struct virtio_device *vdev, 189 unsigned int idx, 190 struct virtqueue *vq, 191 void (*cb)(void *), 192 void *cb_arg, 193 const char *vq_name); 194 195 /** 196 * @brief VIRTIO MMIO device initialization. 197 * 198 * @param vmdev Pointer to virtio_mmio_device structure. 199 * @param virt_mem_ptr Guest virtio (shared) memory base address (virtual). 200 * @param cfg_mem_ptr Virtio device configuration memory base address (virtual). 201 * @param user_data Pointer to custom user data. 202 * 203 * @return int 0 for success. 204 */ 205 int virtio_mmio_device_init(struct virtio_mmio_device *vmdev, uintptr_t virt_mem_ptr, 206 uintptr_t cfg_mem_ptr, void *user_data); 207 208 /** 209 * @brief VIRTIO MMIO interrupt service routine. 210 * 211 * @param vdev Pointer to virtio_device structure. 212 */ 213 void virtio_mmio_isr(struct virtio_device *vdev); 214 215 #ifdef __cplusplus 216 } 217 #endif 218 219 #endif /* OPENAMP_VIRTIO_MMIO_H */ 220