|
|
1.1 root 1: //
2: // VirtIO 定義
3: // https://docs.oasis-open.org/virtio/virtio/v1.1/virtio-v1.1.html
4: //
5:
6: #pragma once
7:
8: #include "header.h"
9:
10: // 元仕様をそのまま記述するために用意しておく。
11: using u8 = uint8;
12: using le16 = uint16;
13: using le32 = uint32;
14: using le64 = uint64;
15: #define QUEUE_SIZE_ (0)
16:
17: // レジスタ名とかのプレフィックスを持たない名前。
18: class VirtIO
19: {
20: public:
21: // レジスタ (仕様は LE だがゲストエンディアンで動作させる)
22: static const uint32 MAGIC_VALUE = 0x000; // R-
23: static const uint32 VERSION = 0x004; // R-
24: static const uint32 DEVICE_ID = 0x008; // R-
25: static const uint32 VENDOR_ID = 0x00c; // R-
26: static const uint32 DEVICE_FEATURES = 0x010; // R-
27: static const uint32 DEVICE_FEATURES_SEL = 0x014; // -W
28: static const uint32 DRIVER_FEATURES = 0x020; // -W
29: static const uint32 DRIVER_FEATURES_SEL = 0x024; // -W
30: static const uint32 QUEUE_SEL = 0x030; // -W
31: static const uint32 QUEUE_NUM_MAX = 0x034; // R-
32: static const uint32 QUEUE_NUM = 0x038; // -W
33: static const uint32 QUEUE_READY = 0x044; // RW
34: static const uint32 QUEUE_NOTIFY = 0x050; // -W
35: static const uint32 INTERRUPT_STATUS = 0x060; // R-
36: static const uint32 INTERRUPT_ACK = 0x064; // -W
37: static const uint32 STATUS = 0x070; // RW
38: static const uint32 QUEUE_DESC_LOW = 0x080; // -W
39: static const uint32 QUEUE_DESC_HIGH = 0x084; // -W
40: static const uint32 QUEUE_DRIVER_LOW = 0x090; // -W
41: static const uint32 QUEUE_DRIVER_HIGH = 0x094; // -W
42: static const uint32 QUEUE_DEVICE_LOW = 0x0a0; // -W
43: static const uint32 QUEUE_DEVICE_HIGH = 0x0a4; // -W
44: static const uint32 CONFIG_GENERATION = 0x0fc; // R-
45:
46: // マジック
47: static const uint32 MAGIC_STRING = 0x74726976; // 'virt'
48:
49: // バージョン
50: static const uint32 DEVICE_VERSION = 2;
51:
52: // DEVICE_ID
53: static const uint32 DEVICE_ID_INVALID = 0;
1.1.1.2 ! root 54: static const uint32 DEVICE_ID_NETWORK = 1;
1.1 root 55: static const uint32 DEVICE_ID_BLOCK = 2;
1.1.1.2 ! root 56: static const uint32 DEVICE_ID_CONSOLE = 3;
! 57: static const uint32 DEVICE_ID_ENTROPY = 4;
1.1 root 58: static std::string DeviceIDStr(uint32);
59:
60: // STATUS
61: static const uint32 STATUS_RESET = 0;
62: static const uint32 STATUS_ACKNOWLEDGE = (1U << 0);
63: static const uint32 STATUS_DRIVER = (1U << 1);
64: static const uint32 STATUS_OK = (1U << 2);
65: static const uint32 STATUS_FEATURES_OK = (1U << 3);
66: static const uint32 STATUS_NEEDS_RESET = (1U << 6);
67: static const uint32 STATUS_FAILED = (1U << 7);
68: static std::string StatusBits(uint32);
69: };
70:
71: // FEATURES (共通)
72: static const uint VIRTIO_F_RING_INDIRECT_DESC = 28;
73: static const uint VIRTIO_F_RING_EVENT_IDX = 29;
74: static const uint VIRTIO_F_VERSION_1 = 32;
75: static const uint VIRTIO_F_ACCESS_PLATFORM = 33;
76: static const uint VIRTIO_F_RING_PACKED = 34;
77: static const uint VIRTIO_F_IN_ORDER = 35;
78: static const uint VIRTIO_F_ORDER_PLATFORM = 36;
79: static const uint VIRTIO_F_SF_IOV = 37;
80: static const uint VIRTIO_F_NOTIFICATION_DATA = 38;
81: // FEATURES (NetworkDevice)
82: static const uint VIRTIO_NET_F_CSUM = 0;
83: static const uint VIRTIO_NET_F_GUEST_CSUM = 1;
84: static const uint VIRTIO_NET_F_CTRL_GUEST_OFFLOADS = 2;
85: static const uint VIRTIO_NET_F_MTU = 3;
86: static const uint VIRTIO_NET_F_MAC = 5;
87: static const uint VIRTIO_NET_F_GUEST_TSO4 = 7;
88: static const uint VIRTIO_NET_F_GUEST_TSO6 = 8;
89: static const uint VIRTIO_NET_F_GUEST_ECN = 9;
90: static const uint VIRTIO_NET_F_GUEST_UFO = 10;
91: static const uint VIRTIO_NET_F_HOST_TSO4 = 11;
92: static const uint VIRTIO_NET_F_HOST_TSO6 = 12;
93: static const uint VIRTIO_NET_F_HOST_ECN = 13;
94: static const uint VIRTIO_NET_F_HOST_UFO = 14;
95: static const uint VIRTIO_NET_F_MRG_RXBUF = 15;
96: static const uint VIRTIO_NET_F_STATUS = 16;
97: static const uint VIRTIO_NET_F_CTRL_VQ = 17;
98: static const uint VIRTIO_NET_F_CTRL_RX = 18;
99: static const uint VIRTIO_NET_F_CTRL_VLAN = 19;
100: static const uint VIRTIO_NET_F_GUEST_ANNOUNCE = 21;
101: static const uint VIRTIO_NET_F_MQ = 22;
102: static const uint VIRTIO_NET_F_CTRL_MAC_ADDR = 23;
103: static const uint VIRTIO_NET_F_RSC_EXT = 61;
104: static const uint VIRTIO_NET_F_STANDBY = 62;
105: // FEATURES (BlockDevice)
106: static const uint VIRTIO_BLK_F_SIZE_MAX = 1;
107: static const uint VIRTIO_BLK_F_SEG_MAX = 2;
108: static const uint VIRTIO_BLK_F_GEOMETRY = 4;
109: static const uint VIRTIO_BLK_F_RO = 5;
110: static const uint VIRTIO_BLK_F_BLK_SIZE = 6;
111: static const uint VIRTIO_BLK_F_FLUSH = 9;
112: static const uint VIRTIO_BLK_F_TOPOLOGY = 10;
113: static const uint VIRTIO_BLK_F_CONFIG_WCE = 11;
114: static const uint VIRTIO_BLK_F_DISCARD = 13;
115: static const uint VIRTIO_BLK_F_WRITE_ZEROES = 14;
116:
117:
118: // こっちは仕様上の構造体定義。クラスのほうを使うこと。
119: struct virtq_desc {
120: le64 addr; // Guest physical address
121: le32 len; // Length
122: le16 flags; // The flags as indicated above
123: le16 next; // Next field if flags & NEXT
124: };
125: static const uint16 VIRTQ_DESC_F_NEXT = 1;
126: static const uint16 VIRTQ_DESC_F_WRITE = 2;
127: static const uint16 VIRTQ_DESC_F_INDIRECT = 4;
128:
129: class VirtQDesc
130: {
131: public:
132: uint32 addr {};
133: uint32 len {};
134: uint32 flag {};
135: uint32 next {};
136: public:
137: bool IsWrite() const { return (flag & VIRTQ_DESC_F_WRITE); }
138: bool IsRead() const { return !IsWrite(); }
139: bool IsNext() const { return (flag & VIRTQ_DESC_F_NEXT); }
140: std::string ToStr() const;
141: };
142:
143: struct virtq_avail {
144: le16 flags;
145: le16 idx;
146: le16 ring[QUEUE_SIZE_];
147: le16 used_event; // Only if F_EVENT_IDX
148: };
149: static const uint16 VIRTQ_AVAIL_F_NO_INTERRUPT = 1;
150:
151: struct virtq_used {
152: le16 flags;
153: le16 idx;
154: struct virtq_used_elem {
155: le32 id; // Index of start of used descriptor chan
156: le32 len; // Total length of the descriptor chain which was used
157: } ring[QUEUE_SIZE_];
158: le16 avail_count; // Only if F_EVENT_IDX
159: };
160: static const uint16 VIRTQ_USED_F_NO_NOTIFY = 1;
161:
162:
163: // NetworkCard
164:
165: struct virtio_net_hdr {
166: u8 flags;
167: u8 gso_type;
168: le16 hdr_len;
169: le16 gso_size;
170: le16 csum_start;
171: le16 csum_offset;
172: le16 num_buffers;
173: } __packed;
174:
175: static const uint8 VIRTIO_NET_HDR_F_NEED_CSUM = 1;
176: static const uint8 VIRTIO_NET_HDR_F_DATA_VALID = 2;
177: static const uint8 VIRTIO_NET_HDR_F_RSC_INFO = 4;
178:
179: static const uint8 VIRTIO_NET_HDR_GSO_NONE = 0;
180: static const uint8 VIRTIO_NET_HDR_GSO_TCPV4 = 1;
181: static const uint8 VIRTIO_NET_HDR_GSO_UDP = 3;
182: static const uint8 VIRTIO_NET_HDR_GSO_TCPV6 = 4;
183: static const uint8 VIRTIO_NET_HDR_GSO_ECN = 0x80;
184:
185: // BlockDevice
186:
187: struct virtio_blk_req {
188: le32 type;
189: le32 reserved;
190: le64 sector;
191: u8 data[0]; // u8 data[][512]
192: u8 status;
193: };
194:
195: static const uint32 VIRTIO_BLK_T_IN = 0;
196: static const uint32 VIRTIO_BLK_T_OUT = 1;
197: static const uint32 VIRTIO_BLK_T_FLUSH = 4;
198: static const uint32 VIRTIO_BLK_T_DISCARD = 11;
199: static const uint32 VIRTIO_BLK_T_WRITE_ZEROES = 13;
200:
201: static const uint8 VIRTIO_BLK_S_OK = 0;
202: static const uint8 VIRTIO_BLK_S_IOERR = 1;
203: static const uint8 VIRTIO_BLK_S_UNSUPP = 2;
204:
205: struct virtio_blk_discard_write_zeroes {
206: le64 sector;
207: le32 num_sectors;
208: //struct {
209: // le32 unmap:1;
210: // le32 reserved:31;
211: //} flags;
212: le32 flags;
213: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.