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