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