Annotation of nono/vm/virtio_def.h, revision 1.1.1.3

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.1.3 ! root       58:        static const uint32 DEVICE_ID_BALLOON   = 5;
        !            59:        static const uint32 DEVICE_ID_SCSI              = 8;
1.1       root       60:        static std::string DeviceIDStr(uint32);
                     61: 
                     62:        // STATUS
                     63:        static const uint32 STATUS_RESET                        = 0;
                     64:        static const uint32 STATUS_ACKNOWLEDGE          = (1U << 0);
                     65:        static const uint32 STATUS_DRIVER                       = (1U << 1);
                     66:        static const uint32 STATUS_OK                           = (1U << 2);
                     67:        static const uint32 STATUS_FEATURES_OK          = (1U << 3);
                     68:        static const uint32 STATUS_NEEDS_RESET          = (1U << 6);
                     69:        static const uint32 STATUS_FAILED                       = (1U << 7);
                     70:        static std::string StatusBits(uint32);
                     71: };
                     72: 
                     73: // FEATURES (共通)
                     74: static const uint VIRTIO_F_RING_INDIRECT_DESC  = 28;
                     75: static const uint VIRTIO_F_RING_EVENT_IDX              = 29;
                     76: static const uint VIRTIO_F_VERSION_1                   = 32;
                     77: static const uint VIRTIO_F_ACCESS_PLATFORM             = 33;
                     78: static const uint VIRTIO_F_RING_PACKED                 = 34;
                     79: static const uint VIRTIO_F_IN_ORDER                            = 35;
                     80: static const uint VIRTIO_F_ORDER_PLATFORM              = 36;
                     81: static const uint VIRTIO_F_SF_IOV                              = 37;
                     82: static const uint VIRTIO_F_NOTIFICATION_DATA   = 38;
                     83: // FEATURES (NetworkDevice)
                     84: static const uint VIRTIO_NET_F_CSUM                            = 0;
                     85: static const uint VIRTIO_NET_F_GUEST_CSUM              = 1;
                     86: static const uint VIRTIO_NET_F_CTRL_GUEST_OFFLOADS     = 2;
                     87: static const uint VIRTIO_NET_F_MTU                             = 3;
                     88: static const uint VIRTIO_NET_F_MAC                             = 5;
                     89: static const uint VIRTIO_NET_F_GUEST_TSO4              = 7;
                     90: static const uint VIRTIO_NET_F_GUEST_TSO6              = 8;
                     91: static const uint VIRTIO_NET_F_GUEST_ECN               = 9;
                     92: static const uint VIRTIO_NET_F_GUEST_UFO               = 10;
                     93: static const uint VIRTIO_NET_F_HOST_TSO4               = 11;
                     94: static const uint VIRTIO_NET_F_HOST_TSO6               = 12;
                     95: static const uint VIRTIO_NET_F_HOST_ECN                        = 13;
                     96: static const uint VIRTIO_NET_F_HOST_UFO                        = 14;
                     97: static const uint VIRTIO_NET_F_MRG_RXBUF               = 15;
                     98: static const uint VIRTIO_NET_F_STATUS                  = 16;
                     99: static const uint VIRTIO_NET_F_CTRL_VQ                 = 17;
                    100: static const uint VIRTIO_NET_F_CTRL_RX                 = 18;
                    101: static const uint VIRTIO_NET_F_CTRL_VLAN               = 19;
                    102: static const uint VIRTIO_NET_F_GUEST_ANNOUNCE  = 21;
                    103: static const uint VIRTIO_NET_F_MQ                              = 22;
                    104: static const uint VIRTIO_NET_F_CTRL_MAC_ADDR   = 23;
                    105: static const uint VIRTIO_NET_F_RSC_EXT                 = 61;
                    106: static const uint VIRTIO_NET_F_STANDBY                 = 62;
                    107: // FEATURES (BlockDevice)
                    108: static const uint VIRTIO_BLK_F_SIZE_MAX                        = 1;
                    109: static const uint VIRTIO_BLK_F_SEG_MAX                 = 2;
                    110: static const uint VIRTIO_BLK_F_GEOMETRY                        = 4;
                    111: static const uint VIRTIO_BLK_F_RO                              = 5;
                    112: static const uint VIRTIO_BLK_F_BLK_SIZE                        = 6;
                    113: static const uint VIRTIO_BLK_F_FLUSH                   = 9;
                    114: static const uint VIRTIO_BLK_F_TOPOLOGY                        = 10;
                    115: static const uint VIRTIO_BLK_F_CONFIG_WCE              = 11;
                    116: static const uint VIRTIO_BLK_F_DISCARD                 = 13;
                    117: static const uint VIRTIO_BLK_F_WRITE_ZEROES            = 14;
1.1.1.3 ! root      118: // FEATURES (SCSIDevice)
        !           119: static const uint VIRTIO_SCSI_F_INOUT                  = 0;
        !           120: static const uint VIRTIO_SCSI_F_HOTPLUG                        = 1;
        !           121: static const uint VIRTIO_SCSI_F_CHANGE                 = 2;
        !           122: static const uint VIRTIO_SCSI_F_T10_PI                 = 4;
1.1       root      123: 
                    124: 
                    125: // こっちは仕様上の構造体定義。クラスのほうを使うこと。
                    126: struct virtq_desc {
                    127:        le64 addr;      // Guest physical address
                    128:        le32 len;       // Length
                    129:        le16 flags;     // The flags as indicated above
                    130:        le16 next;      // Next field if flags & NEXT
                    131: };
                    132: static const uint16 VIRTQ_DESC_F_NEXT                  = 1;
                    133: static const uint16 VIRTQ_DESC_F_WRITE                 = 2;
                    134: static const uint16 VIRTQ_DESC_F_INDIRECT              = 4;
                    135: 
                    136: class VirtQDesc
                    137: {
                    138:  public:
                    139:        uint32 addr {};
                    140:        uint32 len {};
                    141:        uint32 flag {};
                    142:        uint32 next {};
                    143:  public:
                    144:        bool IsWrite() const    { return (flag & VIRTQ_DESC_F_WRITE); }
                    145:        bool IsRead() const             { return !IsWrite(); }
                    146:        bool IsNext() const             { return (flag & VIRTQ_DESC_F_NEXT); }
                    147:        std::string ToStr() const;
                    148: };
                    149: 
                    150: struct virtq_avail {
                    151:        le16 flags;
                    152:        le16 idx;
                    153:        le16 ring[QUEUE_SIZE_];
                    154:        le16 used_event;        // Only if F_EVENT_IDX
                    155: };
                    156: static const uint16 VIRTQ_AVAIL_F_NO_INTERRUPT = 1;
                    157: 
                    158: struct virtq_used {
                    159:        le16 flags;
                    160:        le16 idx;
                    161:        struct virtq_used_elem {
                    162:                le32 id;        // Index of start of used descriptor chan
                    163:                le32 len;       // Total length of the descriptor chain which was used
                    164:        } ring[QUEUE_SIZE_];
                    165:        le16 avail_count;       // Only if F_EVENT_IDX
                    166: };
                    167: static const uint16 VIRTQ_USED_F_NO_NOTIFY             = 1;
                    168: 
                    169: 
1.1.1.3 ! root      170: // NetworkDevice
1.1       root      171: 
                    172: struct virtio_net_hdr {
                    173:        u8 flags;
                    174:        u8 gso_type;
                    175:        le16 hdr_len;
                    176:        le16 gso_size;
                    177:        le16 csum_start;
                    178:        le16 csum_offset;
                    179:        le16 num_buffers;
                    180: } __packed;
                    181: 
                    182: static const uint8 VIRTIO_NET_HDR_F_NEED_CSUM  = 1;
                    183: static const uint8 VIRTIO_NET_HDR_F_DATA_VALID = 2;
                    184: static const uint8 VIRTIO_NET_HDR_F_RSC_INFO   = 4;
                    185: 
                    186: static const uint8 VIRTIO_NET_HDR_GSO_NONE             = 0;
                    187: static const uint8 VIRTIO_NET_HDR_GSO_TCPV4            = 1;
                    188: static const uint8 VIRTIO_NET_HDR_GSO_UDP              = 3;
                    189: static const uint8 VIRTIO_NET_HDR_GSO_TCPV6            = 4;
                    190: static const uint8 VIRTIO_NET_HDR_GSO_ECN              = 0x80;
                    191: 
                    192: // BlockDevice
                    193: 
                    194: struct virtio_blk_req {
                    195:        le32 type;
                    196:        le32 reserved;
                    197:        le64 sector;
                    198:        u8   data[0];   // u8 data[][512]
                    199:        u8   status;
                    200: };
                    201: 
                    202: static const uint32 VIRTIO_BLK_T_IN                            = 0;
                    203: static const uint32 VIRTIO_BLK_T_OUT                   = 1;
                    204: static const uint32 VIRTIO_BLK_T_FLUSH                 = 4;
                    205: static const uint32 VIRTIO_BLK_T_DISCARD               = 11;
                    206: static const uint32 VIRTIO_BLK_T_WRITE_ZEROES  = 13;
                    207: 
                    208: static const uint8 VIRTIO_BLK_S_OK                             = 0;
                    209: static const uint8 VIRTIO_BLK_S_IOERR                  = 1;
                    210: static const uint8 VIRTIO_BLK_S_UNSUPP                 = 2;
                    211: 
                    212: struct virtio_blk_discard_write_zeroes {
                    213:        le64 sector;
                    214:        le32 num_sectors;
                    215:        //struct {
                    216:        //      le32 unmap:1;
                    217:        //      le32 reserved:31;
                    218:        //} flags;
                    219:        le32 flags;
                    220: };
1.1.1.3 ! root      221: 
        !           222: // SCSIDevice
        !           223: 
        !           224: struct virtio_scsi_req_cmd {
        !           225:        // Device-readable part
        !           226:        u8 lun[8];
        !           227:        le64 id;
        !           228:        u8 task_attr;
        !           229:        u8 prio;
        !           230:        u8 crn;
        !           231:        u8 cdb[0];      // [cdb_size]
        !           232:        // The next three fields are only present if VIRTIO_SCSI_F_T10_PI
        !           233:        // is negotiated.
        !           234:        //le32 pi_bytesout;
        !           235:        //le32 pi_bytesin;
        !           236:        //u8 pi_out[pi_bytesout];
        !           237:        u8 dataout[0];
        !           238: 
        !           239:        // Device-writable part
        !           240:        le32 sense_len;
        !           241:        le32 residual;
        !           242:        le16 status_qualifier;
        !           243:        u8 status;
        !           244:        u8 response;
        !           245:        u8 sense[0];    // [sense_size]
        !           246:        // The next field is only present if VIRTIO_SCS_IF_T10_PI
        !           247:        // is negotiated.
        !           248:        //u8 pi_in[pi_bytesin];
        !           249:        u8 datain[0];
        !           250: };
        !           251: 
        !           252: struct virtio_scsi_ctrl {
        !           253:        le32 type;
        !           254:        //
        !           255:        u8 response;
        !           256: };
        !           257: 
        !           258: static const uint8 VIRTIO_SCSI_S_OK                                    = 0;
        !           259: static const uint8 VIRTIO_SCSI_S_OVERRUN                       = 1;
        !           260: static const uint8 VIRTIO_SCSI_S_ABORTED                       = 2;
        !           261: static const uint8 VIRTIO_SCSI_S_BAD_TARGET                    = 3;
        !           262: static const uint8 VIRTIO_SCSI_S_RESET                         = 4;
        !           263: static const uint8 VIRTIO_SCSI_S_BUSY                          = 5;
        !           264: static const uint8 VIRTIO_SCSI_S_TRANSPORT_FAILURE     = 6;
        !           265: static const uint8 VIRTIO_SCSI_S_TARGET_FAILURE                = 7;
        !           266: static const uint8 VIRTIO_SCSI_S_NEXUS_FAILURE         = 8;
        !           267: static const uint8 VIRTIO_SCSI_S_FAILURE                       = 9;
        !           268: static const uint8 VIRTIO_SCSI_S_INCORRECT_LUN         = 12;
        !           269: // task_attr
        !           270: static const uint8 VIRTIO_SCSI_S_SIMPLE                                = 0;
        !           271: static const uint8 VIRTIO_SCSI_S_ORDERED                       = 1;
        !           272: static const uint8 VIRTIO_SCSI_S_HEAD                          = 2;
        !           273: static const uint8 VIRTIO_SCSI_S_ACA                           = 3;

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.