|
|
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; ! 54: static const uint32 DEVICE_ID_NET = 1; ! 55: static const uint32 DEVICE_ID_BLOCK = 2; ! 56: static std::string DeviceIDStr(uint32); ! 57: ! 58: // STATUS ! 59: static const uint32 STATUS_RESET = 0; ! 60: static const uint32 STATUS_ACKNOWLEDGE = (1U << 0); ! 61: static const uint32 STATUS_DRIVER = (1U << 1); ! 62: static const uint32 STATUS_OK = (1U << 2); ! 63: static const uint32 STATUS_FEATURES_OK = (1U << 3); ! 64: static const uint32 STATUS_NEEDS_RESET = (1U << 6); ! 65: static const uint32 STATUS_FAILED = (1U << 7); ! 66: static std::string StatusBits(uint32); ! 67: }; ! 68: ! 69: // FEATURES (共通) ! 70: static const uint VIRTIO_F_RING_INDIRECT_DESC = 28; ! 71: static const uint VIRTIO_F_RING_EVENT_IDX = 29; ! 72: static const uint VIRTIO_F_VERSION_1 = 32; ! 73: static const uint VIRTIO_F_ACCESS_PLATFORM = 33; ! 74: static const uint VIRTIO_F_RING_PACKED = 34; ! 75: static const uint VIRTIO_F_IN_ORDER = 35; ! 76: static const uint VIRTIO_F_ORDER_PLATFORM = 36; ! 77: static const uint VIRTIO_F_SF_IOV = 37; ! 78: static const uint VIRTIO_F_NOTIFICATION_DATA = 38; ! 79: // FEATURES (NetworkDevice) ! 80: static const uint VIRTIO_NET_F_CSUM = 0; ! 81: static const uint VIRTIO_NET_F_GUEST_CSUM = 1; ! 82: static const uint VIRTIO_NET_F_CTRL_GUEST_OFFLOADS = 2; ! 83: static const uint VIRTIO_NET_F_MTU = 3; ! 84: static const uint VIRTIO_NET_F_MAC = 5; ! 85: static const uint VIRTIO_NET_F_GUEST_TSO4 = 7; ! 86: static const uint VIRTIO_NET_F_GUEST_TSO6 = 8; ! 87: static const uint VIRTIO_NET_F_GUEST_ECN = 9; ! 88: static const uint VIRTIO_NET_F_GUEST_UFO = 10; ! 89: static const uint VIRTIO_NET_F_HOST_TSO4 = 11; ! 90: static const uint VIRTIO_NET_F_HOST_TSO6 = 12; ! 91: static const uint VIRTIO_NET_F_HOST_ECN = 13; ! 92: static const uint VIRTIO_NET_F_HOST_UFO = 14; ! 93: static const uint VIRTIO_NET_F_MRG_RXBUF = 15; ! 94: static const uint VIRTIO_NET_F_STATUS = 16; ! 95: static const uint VIRTIO_NET_F_CTRL_VQ = 17; ! 96: static const uint VIRTIO_NET_F_CTRL_RX = 18; ! 97: static const uint VIRTIO_NET_F_CTRL_VLAN = 19; ! 98: static const uint VIRTIO_NET_F_GUEST_ANNOUNCE = 21; ! 99: static const uint VIRTIO_NET_F_MQ = 22; ! 100: static const uint VIRTIO_NET_F_CTRL_MAC_ADDR = 23; ! 101: static const uint VIRTIO_NET_F_RSC_EXT = 61; ! 102: static const uint VIRTIO_NET_F_STANDBY = 62; ! 103: // FEATURES (BlockDevice) ! 104: static const uint VIRTIO_BLK_F_SIZE_MAX = 1; ! 105: static const uint VIRTIO_BLK_F_SEG_MAX = 2; ! 106: static const uint VIRTIO_BLK_F_GEOMETRY = 4; ! 107: static const uint VIRTIO_BLK_F_RO = 5; ! 108: static const uint VIRTIO_BLK_F_BLK_SIZE = 6; ! 109: static const uint VIRTIO_BLK_F_FLUSH = 9; ! 110: static const uint VIRTIO_BLK_F_TOPOLOGY = 10; ! 111: static const uint VIRTIO_BLK_F_CONFIG_WCE = 11; ! 112: static const uint VIRTIO_BLK_F_DISCARD = 13; ! 113: static const uint VIRTIO_BLK_F_WRITE_ZEROES = 14; ! 114: ! 115: ! 116: // こっちは仕様上の構造体定義。クラスのほうを使うこと。 ! 117: struct virtq_desc { ! 118: le64 addr; // Guest physical address ! 119: le32 len; // Length ! 120: le16 flags; // The flags as indicated above ! 121: le16 next; // Next field if flags & NEXT ! 122: }; ! 123: static const uint16 VIRTQ_DESC_F_NEXT = 1; ! 124: static const uint16 VIRTQ_DESC_F_WRITE = 2; ! 125: static const uint16 VIRTQ_DESC_F_INDIRECT = 4; ! 126: ! 127: class VirtQDesc ! 128: { ! 129: public: ! 130: uint32 addr {}; ! 131: uint32 len {}; ! 132: uint32 flag {}; ! 133: uint32 next {}; ! 134: public: ! 135: bool IsWrite() const { return (flag & VIRTQ_DESC_F_WRITE); } ! 136: bool IsRead() const { return !IsWrite(); } ! 137: bool IsNext() const { return (flag & VIRTQ_DESC_F_NEXT); } ! 138: std::string ToStr() const; ! 139: }; ! 140: ! 141: struct virtq_avail { ! 142: le16 flags; ! 143: le16 idx; ! 144: le16 ring[QUEUE_SIZE_]; ! 145: le16 used_event; // Only if F_EVENT_IDX ! 146: }; ! 147: static const uint16 VIRTQ_AVAIL_F_NO_INTERRUPT = 1; ! 148: ! 149: struct virtq_used { ! 150: le16 flags; ! 151: le16 idx; ! 152: struct virtq_used_elem { ! 153: le32 id; // Index of start of used descriptor chan ! 154: le32 len; // Total length of the descriptor chain which was used ! 155: } ring[QUEUE_SIZE_]; ! 156: le16 avail_count; // Only if F_EVENT_IDX ! 157: }; ! 158: static const uint16 VIRTQ_USED_F_NO_NOTIFY = 1; ! 159: ! 160: ! 161: // NetworkCard ! 162: ! 163: struct virtio_net_hdr { ! 164: u8 flags; ! 165: u8 gso_type; ! 166: le16 hdr_len; ! 167: le16 gso_size; ! 168: le16 csum_start; ! 169: le16 csum_offset; ! 170: le16 num_buffers; ! 171: } __packed; ! 172: ! 173: static const uint8 VIRTIO_NET_HDR_F_NEED_CSUM = 1; ! 174: static const uint8 VIRTIO_NET_HDR_F_DATA_VALID = 2; ! 175: static const uint8 VIRTIO_NET_HDR_F_RSC_INFO = 4; ! 176: ! 177: static const uint8 VIRTIO_NET_HDR_GSO_NONE = 0; ! 178: static const uint8 VIRTIO_NET_HDR_GSO_TCPV4 = 1; ! 179: static const uint8 VIRTIO_NET_HDR_GSO_UDP = 3; ! 180: static const uint8 VIRTIO_NET_HDR_GSO_TCPV6 = 4; ! 181: static const uint8 VIRTIO_NET_HDR_GSO_ECN = 0x80; ! 182: ! 183: // BlockDevice ! 184: ! 185: struct virtio_blk_req { ! 186: le32 type; ! 187: le32 reserved; ! 188: le64 sector; ! 189: u8 data[0]; // u8 data[][512] ! 190: u8 status; ! 191: }; ! 192: ! 193: static const uint32 VIRTIO_BLK_T_IN = 0; ! 194: static const uint32 VIRTIO_BLK_T_OUT = 1; ! 195: static const uint32 VIRTIO_BLK_T_FLUSH = 4; ! 196: static const uint32 VIRTIO_BLK_T_DISCARD = 11; ! 197: static const uint32 VIRTIO_BLK_T_WRITE_ZEROES = 13; ! 198: ! 199: static const uint8 VIRTIO_BLK_S_OK = 0; ! 200: static const uint8 VIRTIO_BLK_S_IOERR = 1; ! 201: static const uint8 VIRTIO_BLK_S_UNSUPP = 2; ! 202: ! 203: struct virtio_blk_discard_write_zeroes { ! 204: le64 sector; ! 205: le32 num_sectors; ! 206: //struct { ! 207: // le32 unmap:1; ! 208: // le32 reserved:31; ! 209: //} flags; ! 210: le32 flags; ! 211: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.