1/* 2 * Copyright (c) 2014, ETH Zurich. All rights reserved. 3 * 4 * This file is distributed under the terms in the attached LICENSE file. 5 * If you do not find this file, copies can be found by writing to: 6 * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group. 7 */ 8 9/* 10 * virtio_mmio.dev 11 * 12 * Virtio over Memory Mapped IO 13 * 14 * From the Virtio Specification, Section 4.2 15 * 16 */ 17 18device virtio_mmio lsbfirst ( addr base ) "Virtio MMIO Transport Specification" { 19 20 constants virtio_magic width(4) "Little Endian equivalent of the 'virt' string" { 21 magic_value = 0x74726976 "Little Endian equivalent of the 'virt' string"; 22 }; 23 24 register magic_value addr(base, 0x000) "Magic value for identifying the Virtio device" { 25 val 32 "Has to be 0x74726976"; 26 }; 27 28 constants virtio_version width(32) "Virtio MMIO Device Versions" { 29 version_invalid = 0x0 "Invalid Version."; 30 version_legacy = 0x1 "The legacy interface is used."; 31 version_virtio10 = 0x2 "Virtio Version 1.0"; 32 }; 33 34 register version addr(base, 0x004) "Device Version Number" { 35 version 8 "Virtio device interface version"; 36 _ 24 "Reserved"; 37 }; 38 39 constants virtio_deviceid width(32) "Virtio Device IDs" { 40 reserved = 0x0 "Invalid Device ID"; 41 network_card = 0x1 "Network Interface Device"; 42 block_device = 0x2 "Block Device"; 43 console = 0x3 "Serial Console Device"; 44 entropy_source = 0x4 "Entorpy Source Device (Randomness)"; 45 legacy_balloon = 0x5 "Memory Ballooning Device (legacy)"; 46 io_memory = 0x6 "IO Memory Device"; 47 rpmsg = 0x7 "RPMSG Device"; 48 scsi_host = 0x8 "SCSI Host Device"; 49 transport_9p = 0x9 "9P Transport Device"; 50 mac80211_wlan = 0xA "MAC 802.11 WLAN Device"; 51 rproc_serial = 0xB "RPROC Serial Device"; 52 virtio_caif = 0xC "Virtio CAIF Device"; 53 memory_balloon = 0xD "Memory Ballooning Device"; 54 gpu_device = 0xE "GPU Device"; 55 timer_device = 0xF "Clock / Timer Device"; 56 }; 57 58 /* 59 * See 5 Device Types for possible values. Value zero (0x0) is used to de- 60 * fine a system memory map with placeholder devices at static, well known 61 * addresses, assigning functions to them depending on user's needs. 62 */ 63 register deviceid addr(base, 0x008) "Virtio Subsystem Device ID" { 64 id 8 "Device ID"; 65 _ 24 "Reserved"; 66 }; 67 68 register vendorid addr(base, 0x00C) "Virtio Subsystem Vendor ID" { 69 id 32 "Vendor ID"; 70 }; 71 72 73 /* 74 * Reading from this register returns 32 consecutive flag bits, first bit 75 * depending on the last value written to DeviceFeaturesSel. Access to this 76 * register returns bits DeviceFeaturesSel * 32 to 77 * (DeviceFeaturesSel * 32) + 31, eg. feature bits 0 to 31 if 78 * DeviceFeaturesSel is set to 0 and features bits 32 to 63 if 79 * DeviceFeaturesSel is set to 1. Also see 2.2 Feature Bits. 80 * 81 * Note: The representation of the actual feature bits depend on the device 82 */ 83 register dev_features addr(base, 0x010) "Flags representing features the device supports" { 84 features 32 "Virtio Features Bits"; 85 }; 86 87 /* 88 * Writing to this register selects a set of 32 device feature bits accessible 89 * by reading from DeviceFeatures. 90 */ 91 register dev_features_sel addr(base, 0x014) "Device (host) features word selection." { 92 ready 1 "The host has loaded the dev_features register"; 93 _ 30 "Reserved"; 94 selector 1 "Virtio Feature Selector"; 95 }; 96 97 /* 98 * Writing to this register sets 32 consecutive flag bits, first bit depending 99 * on the last value written to DriverFeaturesSel. Access to this register sets 100 * bits DriverFeaturesSel * 32 to (DriverFeaturesSel * 32) + 31, eg. feature 101 * bits 0 to 31 if DriverFeaturesSel is set to 0 and features bits 32 to 63 102 * if DriverFeaturesSel is set to 1. Also see 2.2 Feature Bits. 103 * 104 * Note: The representation of the actual feature bits depend on the device 105 */ 106 register driv_features addr(base, 0x020) "Flags representing device features understood and activated by the driver" { 107 features 32 "Virtio Features Bits"; 108 }; 109 110 register driv_features_sel addr(base, 0x024) "Activated (guest) features word selection" { 111 selector 1 "Virtio Feature Selector"; 112 _ 29 "Reserved"; 113 ready 1 "signal the host that the values are ready"; 114 ack 1 "the host has stored the values"; 115 }; 116 117 /* 118 * Writing to this register selects the virtual queue that the following 119 * operations on QueueNumMax, QueueNum, QueueReady, QueueDescLow, 120 * QueueDescHigh, QueueAvailLow, QueueAvailHigh, QueueUsedLow and 121 * QueueUsedHigh apply to. The index number of the first queue is zero (0x0). 122 */ 123 register queue_sel addr(base, 0x030) "Virtual queue index" { 124 selector 31 "Virtio Queue Selector"; 125 ready 1 "the host has loaded the registers witht the values"; 126 }; 127 128 /* 129 * Reading from the register returns the maximum size (number of elements) 130 * of the queue the device is ready to process or zero (0x0) if the queue is 131 * not available. This applies to the queue selected by writing to QueueSel. 132 */ 133 register queue_max addr(base, 0x34) "Maximum virtual queue size" { 134 size 16 "Number ready to process"; 135 }; 136 137 /* 138 * Queue size is the number of elements in the queue, therefore size of the 139 * Descriptor Table and both Available and Used rings. Writing to this 140 * register notifies the device what size of the queue the driver will use. 141 * This applies to the queue selected by writing to QueueSel. 142 */ 143 register queue_num addr(base, 0x038) "Virtual queue size" { 144 size 16 "Number of elements in queue"; 145 }; 146 147 148 /* 149 * Writing one (0x1) to this register notifies the device that the virtual 150 * queue is ready to be used. Reading from this register returns the last 151 * value written to it. Both read and write accesses apply to the queue 152 * selected by writing to QueueSel. 153 */ 154 register queue_ready addr(base, 0x044) "Virtual queue ready bit" { 155 ready 1 "Queue ready bit"; 156 _ 30 "Reserved"; 157 signal 1 "signal the host that something has changed"; 158 }; 159 160 constants queue width(1) "Queue Ready Bit Values" { 161 ready = 0x1 "The queue is ready to use"; 162 notready = 0x0 "The queue is not ready"; 163 }; 164 165 /* 166 * Writing a queue index to this register notifies the device that there are 167 * new buffers to process in the queue. 168 */ 169 register queue_notify addr(base, 0x050) "Queue notifier" { 170 index 32 "The queue index with new buffers"; 171 }; 172 173 /* 174 * Reading from this register returns a bit mask of events that caused the 175 * device interrupt to be asserted. The following events are possible: 176 * 177 * Used Ring Update - bit 0 - the interrupt was asserted because the device 178 * has updated the Used Ring in at least one of the active virtual queues. 179 * 180 * Configuration Change - bit 1 - the interrupt was asserted because the 181 * configuration of the device has changed. 182 */ 183 register interrupt_status addr(base, 0x060) "Interrupt status" { 184 ring_update 1 "The device has updated the used ring"; 185 config_change 1 "The configuration of the device has changed"; 186 _ 30 ""; 187 }; 188 189 /* 190 * Writing to this register notifies the device that the interrupt has been 191 * handled, as per values for InterruptStatus. 192 * 193 */ 194 register interrupt_ack addr(base, 0x064) "Interrupt acknowledge" { 195 ring_update 1 "The device has updated the used ring"; 196 config_change 1 "The configuration of the device has changed"; 197 _ 30 ""; 198 }; 199 200 constants device_status width(8) "Reset value" { 201 device_reset = 0x0 "Reset the device"; 202 }; 203 204 /* 205 * Reading from this register returns the current device status flags. 206 * Writing non-zero values to this register sets the status flags, indicating 207 * the driver progress. Writing zero (0x0) to this register triggers a 208 * device reset. 209 */ 210 register status addr(base, 0x70) { 211 acknowledge 1 "Guest has found the device"; 212 driver 1 "Guest knows how to drive the device"; 213 driver_ok 1 "Driver setup and ready to drive the device"; 214 features_ok 1 "Driver has acknowledged all the features it understands"; 215 _ 3 "Reserved"; 216 failed 1 "Something went wrong"; 217 _ 24 "Reserved"; 218 }; 219 220 register reset also addr(base, 0x70) { 221 reset 8 "Reset the device"; 222 _ 24 "Reserved"; 223 }; 224 225 /* 226 * Writing to these two registers (lower 32 bits of the address to QueueDescLow, 227 * higher 32 bits to QueueDescHigh) notifies the device about location of 228 * the Descriptor Table of the queue selected by writing to QueueSel register. 229 */ 230 register queue_desc_lo addr(base, 0x080) "Virtual queue Descriptor Table 64 bit long physical address" { 231 addr 32 "Address of Queue Descriptor Table"; 232 }; 233 register queue_desc_hi addr(base, 0x084) "Virtual queue Descriptor Table 64 bit long physical address" { 234 addr 32 "Address of Queue Descriptor Table"; 235 }; 236 237 /* 238 * Writing to these two registers (lower 32 bits of the address to 239 * QueueAvailLow, higher 32 bits to QueueAvailHigh) notifies the device 240 * about location of the Available Ring of the queue selected by writing to QueueSel. 241 */ 242 register queue_avail_lo addr(base, 0x090) "Virtual queue Available Ring 64 bit long physical address" { 243 addr 32 "Address of available ring"; 244 }; 245 register queue_avail_hi addr(base, 0x094) "Virtual queue Available Ring 64 bit long physical address" { 246 addr 32 "Address of available ring"; 247 }; 248 249 /* 250 * Writing to these two registers (lower 32 bits of the address to 251 * QueueUsedLow, higher 32 bits to QueueUsedHigh) notifies the device about 252 * locationof the Used Ring of the queue selected by writing to QueueSel. 253 */ 254 register queue_used_lo addr(base, 0x0a0) "Virtual queue Used Ring 64 bit long physical address" { 255 addr 32 "Address of used ring"; 256 }; 257 register queue_used_hi addr(base, 0x0a4) "Virtual queue Used Ring 64 bit long physical address" { 258 addr 32 "Address of used ring"; 259 }; 260 261 /* 262 * Changes every time the configuration noticeably changes 263 */ 264 register config_gen addr(base, 0x0fc) "Configuration atomicity value" { 265 value 32 "Value"; 266 }; 267 268 constants config_offset width(8) "Reset value" { 269 config_offset = 0x100 "Offset of the configuration space"; 270 }; 271 272}; 273