Appearance
virtio.h
TIP
virtio 设备接口定义。 本文件包含了 virtio MMIO (Memory-Mapped I/O) 接口的寄存器定义 以及 virtio 描述符表的结构,这些都是 virtio 设备通信的核心。 这些定义主要基于 QEMU 的实现,并遵循 virtio v1.1 规范。 virtio 规范 v1.1: https://docs.oasis-open.org/virtio/virtio/v1.1/virtio-v1.1.pdf
TIP
virtio MMIO 控制寄存器,映射到物理地址 0x10001000 开始的内存区域。 寄存器偏移量定义,源自 QEMU (hw/virtio/virtio-mmio.h)。
#define VIRTIO_MMIO_MAGIC_VALUE 0x000
#define VIRTIO_MMIO_VERSION 0x004
#define VIRTIO_MMIO_DEVICE_ID 0x008
#define VIRTIO_MMIO_VENDOR_ID 0x00c
#define VIRTIO_MMIO_DEVICE_FEATURES 0x010
#define VIRTIO_MMIO_DRIVER_FEATURES 0x020
#define VIRTIO_MMIO_QUEUE_SEL 0x030
#define VIRTIO_MMIO_QUEUE_NUM_MAX 0x034
#define VIRTIO_MMIO_QUEUE_NUM 0x038
#define VIRTIO_MMIO_QUEUE_READY 0x044
#define VIRTIO_MMIO_QUEUE_NOTIFY 0x050
#define VIRTIO_MMIO_INTERRUPT_STATUS 0x060
#define VIRTIO_MMIO_INTERRUPT_ACK 0x064
#define VIRTIO_MMIO_STATUS 0x070
#define VIRTIO_MMIO_QUEUE_DESC_LOW 0x080
#define VIRTIO_MMIO_QUEUE_DESC_HIGH 0x084
#define VIRTIO_MMIO_DRIVER_DESC_LOW 0x090
#define VIRTIO_MMIO_DRIVER_DESC_HIGH 0x094
#define VIRTIO_MMIO_DEVICE_DESC_LOW 0x0a0
#define VIRTIO_MMIO_DEVICE_DESC_HIGH 0x0a4
TIP
设备状态寄存器 (VIRTIO_MMIO_STATUS) 的位定义。 这些位用于驱动与设备之间的初始化握手过程。
#define VIRTIO_CONFIG_S_ACKNOWLEDGE 1
#define VIRTIO_CONFIG_S_DRIVER 2
#define VIRTIO_CONFIG_S_DRIVER_OK 4
#define VIRTIO_CONFIG_S_FEATURES_OK 8
TIP
设备特性位 (VIRTIO_MMIO_DEVICE_FEATURES)。
#define VIRTIO_BLK_F_RO 5 /* 磁盘为只读设备 */
#define VIRTIO_BLK_F_SCSI 7 /* 支持 SCSI 命令透传 */
#define VIRTIO_BLK_F_CONFIG_WCE 11 /* 支持配置写缓存 */
#define VIRTIO_BLK_F_MQ 12 /* 支持多队列 */
#define VIRTIO_F_ANY_LAYOUT 27 /* 驱动接受任意内存布局 */
#define VIRTIO_RING_F_INDIRECT_DESC 28 /* 支持间接描述符 */
#define VIRTIO_RING_F_EVENT_IDX 29 /* 支持事件索引,用于抑制中断 */
TIP
每个虚拟队列的描述符数量。 该值必须是 2 的幂。
#define NUM 8
TIP
单个 virtio 描述符结构。 描述符用于定义一个供设备访问的内存缓冲区。
struct virtq_desc {
uint64 addr;
uint32 len;
uint16 flags;
uint16 next;
};
#define VRING_DESC_F_NEXT 1
#define VRING_DESC_F_WRITE 2
TIP
可用环 (Available Ring),由驱动程序填充,用于向设备提供新的缓冲区。
struct virtq_avail {
uint16 flags;
uint16 idx;
uint16 ring[NUM];
uint16 used_event;
};
TIP
已用环 (Used Ring) 中的一个条目,由设备填充, 用于通知驱动程序已经处理完一个缓冲区。
struct virtq_used_elem {
uint32 id;
uint32 len;
};
TIP
已用环 (Used Ring) 结构,设备用它来通知驱动程序已完成的请求。
struct virtq_used {
uint16 flags;
uint16 idx;
struct virtq_used_elem ring[NUM];
uint16 avail_event;
};
TIP
以下定义特定于 virtio 块设备 (如 virtio-blk 磁盘)。 详见 virtio 规范的 5.2 节。
#define VIRTIO_BLK_T_IN 0
#define VIRTIO_BLK_T_OUT 1
TIP
virtio 块设备请求的头部结构。 一个典型的块设备请求由三个描述符组成: 1. 请求头 (本结构) 2. 数据缓冲区 (读或写) 3. 一个单字节的状态,由设备写回
struct virtio_blk_req {
uint32 type;
uint32 reserved;
uint64 sector;
};