1 /** @file
2 
3   Generic type and macro definitions corresponding to the virtio-0.9.5
4   specification.
5 
6   Copyright (C) 2012, Red Hat, Inc.
7   Portion of Copyright (C) 2013, ARM Ltd.
8 
9   This program and the accompanying materials are licensed and made available
10   under the terms and conditions of the BSD License which accompanies this
11   distribution. The full text of the license may be found at
12   http://opensource.org/licenses/bsd-license.php
13 
14   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
15   WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 
17 **/
18 
19 #ifndef _VIRTIO_H_
20 #define _VIRTIO_H_
21 
22 #include <Base.h>
23 
24 //
25 // VirtIo Subsystem Device IDs
26 //
27 #define VIRTIO_SUBSYSTEM_NETWORK_CARD       1
28 #define VIRTIO_SUBSYSTEM_BLOCK_DEVICE       2
29 #define VIRTIO_SUBSYSTEM_CONSOLE            3
30 #define VIRTIO_SUBSYSTEM_ENTROPY_SOURCE     4
31 #define VIRTIO_SUBSYSTEM_MEMORY_BALLOONING  5
32 #define VIRTIO_SUBSYSTEM_IO_MEMORY          6
33 #define VIRTIO_SUBSYSTEM_RPMSG              7
34 #define VIRTIO_SUBSYSTEM_SCSI_HOST          8
35 #define VIRTIO_SUBSYSTEM_9P_TRANSPORT       9
36 #define VIRTIO_SUBSYSTEM_MAC80211_WLAN      10
37 
38 //
39 // Virtio IDs
40 //
41 #define VIRTIO_VENDOR_ID                    0x1AF4
42 #define VIRTIO_MMIO_MAGIC                   0x74726976 // "virt"
43 
44 
45 //
46 // VirtIo Device Specific Configuration Offsets
47 //
48 #define VIRTIO_DEVICE_SPECIFIC_CONFIGURATION_OFFSET_PCI             20
49 #define VIRTIO_DEVICE_SPECIFIC_CONFIGURATION_OFFSET_PCI_WITH_MSI_X  24
50 #define VIRTIO_DEVICE_SPECIFIC_CONFIGURATION_OFFSET_MMIO            0x100
51 
52 //
53 // PCI VirtIo Header Offsets
54 //
55 #define VIRTIO_PCI_OFFSET_DEVICE_FEATURES           0x00
56 #define VIRTIO_PCI_OFFSET_GUEST_FEATURES            0x04
57 #define VIRTIO_PCI_OFFSET_QUEUE_ADDRESS             0x08
58 #define VIRTIO_PCI_OFFSET_QUEUE_SIZE                0x0C
59 #define VIRTIO_PCI_OFFSET_QUEUE_SELECT              0x0E
60 #define VIRTIO_PCI_OFFSET_QUEUE_NOTIFY              0x10
61 #define VIRTIO_PCI_OFFSET_QUEUE_DEVICE_STATUS       0x12
62 #define VIRTIO_PCI_OFFSET_QUEUE_DEVICE_ISR          0x13
63 
64 //
65 // MMIO VirtIo Header Offsets
66 //
67 #define VIRTIO_MMIO_OFFSET_MAGIC                    0x00
68 #define VIRTIO_MMIO_OFFSET_VERSION                  0x04
69 #define VIRTIO_MMIO_OFFSET_DEVICE_ID                0x08
70 #define VIRTIO_MMIO_OFFSET_VENDOR_ID                0x0C
71 #define VIRTIO_MMIO_OFFSET_HOST_FEATURES            0x10
72 #define VIRTIO_MMIO_OFFSET_HOST_FEATURES_SEL        0x14
73 #define VIRTIO_MMIO_OFFSET_GUEST_FEATURES           0x20
74 #define VIRTIO_MMIO_OFFSET_GUEST_FEATURES_SEL       0x24
75 #define VIRTIO_MMIO_OFFSET_GUEST_PAGE_SIZE          0x28
76 #define VIRTIO_MMIO_OFFSET_QUEUE_SEL                0x30
77 #define VIRTIO_MMIO_OFFSET_QUEUE_NUM_MAX            0x34
78 #define VIRTIO_MMIO_OFFSET_QUEUE_NUM                0x38
79 #define VIRTIO_MMIO_OFFSET_QUEUE_ALIGN              0x3C
80 #define VIRTIO_MMIO_OFFSET_QUEUE_PFN                0x40
81 #define VIRTIO_MMIO_OFFSET_QUEUE_NOTIFY             0x50
82 #define VIRTIO_MMIO_OFFSET_INTERRUPT_STATUS         0x60
83 #define VIRTIO_MMIO_OFFSET_INTERRUPT_ACK            0x64
84 #define VIRTIO_MMIO_OFFSET_STATUS                   0x70
85 
86 //
87 // Data in the communication area is defined as packed and accessed as
88 // volatile.
89 //
90 // Some structures contain arrays with dynamically determined size. In such
91 // cases the array and its sibling fields are replaced with pointers.
92 //
93 // All indices (variables and fields named *Idx) are free-running and wrap
94 // around after 0xFFFF. The queue size reported by the host is always an
95 // integral power of 2, not greater than 32768. Actual array indices are
96 // consistently calculated by taking the remainder of a given Idx object modulo
97 // QueueSize. Since 0x10000 is an integral multiple of the QueueSize, UINT16
98 // wraparound is a correct wraparound modulo QueueSize too (it doesn't offset
99 // the remainder class).
100 //
101 // virtio-0.9.5, 2.3.4 Available Ring
102 //
103 #define VRING_AVAIL_F_NO_INTERRUPT BIT0
104 
105 typedef struct {
106   volatile UINT16 *Flags;
107   volatile UINT16 *Idx;
108 
109   volatile UINT16 *Ring;      // QueueSize elements
110   volatile UINT16 *UsedEvent; // unused as per negotiation
111 } VRING_AVAIL;
112 
113 
114 //
115 // virtio-0.9.5, 2.3.5 Used Ring
116 //
117 #define VRING_USED_F_NO_NOTIFY BIT0
118 
119 #pragma pack(1)
120 typedef struct {
121   UINT32 Id;
122   UINT32 Len;
123 } VRING_USED_ELEM;
124 #pragma pack()
125 
126 typedef struct {
127   volatile UINT16          *Flags;
128   volatile UINT16          *Idx;
129   volatile VRING_USED_ELEM *UsedElem;   // QueueSize elements
130   volatile UINT16          *AvailEvent; // unused as per negotiation
131 } VRING_USED;
132 
133 
134 //
135 // virtio-0.9.5, 2.3.2 Descriptor Table
136 //
137 #define VRING_DESC_F_NEXT     BIT0 // more descriptors in this request
138 #define VRING_DESC_F_WRITE    BIT1 // buffer to be written *by the host*
139 #define VRING_DESC_F_INDIRECT BIT2 // unused
140 
141 #pragma pack(1)
142 typedef struct {
143   UINT64 Addr;
144   UINT32 Len;
145   UINT16 Flags;
146   UINT16 Next;
147 } VRING_DESC;
148 #pragma pack()
149 
150 typedef struct {
151   UINTN               NumPages;
152   VOID                *Base;     // deallocate only this field
153   volatile VRING_DESC *Desc;     // QueueSize elements
154   VRING_AVAIL         Avail;
155   VRING_USED          Used;
156   UINT16              QueueSize;
157 } VRING;
158 
159 //
160 // virtio-0.9.5, 2.2.2.1 Device Status
161 //
162 #define VSTAT_ACK       BIT0
163 #define VSTAT_DRIVER    BIT1
164 #define VSTAT_DRIVER_OK BIT2
165 #define VSTAT_FAILED    BIT7
166 
167 //
168 // virtio-0.9.5, Appendix B: Reserved (Device-Independent) Feature Bits
169 //
170 #define VIRTIO_F_NOTIFY_ON_EMPTY    BIT24
171 #define VIRTIO_F_RING_INDIRECT_DESC BIT28
172 #define VIRTIO_F_RING_EVENT_IDX     BIT29
173 
174 
175 #endif // _VIRTIO_H_
176