iPXE
virtio-pci.h
Go to the documentation of this file.
1#ifndef _VIRTIO_PCI_H_
2# define _VIRTIO_PCI_H_
3
4#include <ipxe/dma.h>
5
6/* A 32-bit r/o bitmask of the features supported by the host */
7#define VIRTIO_PCI_HOST_FEATURES 0
8
9/* A 32-bit r/w bitmask of features activated by the guest */
10#define VIRTIO_PCI_GUEST_FEATURES 4
11
12/* A 32-bit r/w PFN for the currently selected queue */
13#define VIRTIO_PCI_QUEUE_PFN 8
14
15/* A 16-bit r/o queue size for the currently selected queue */
16#define VIRTIO_PCI_QUEUE_NUM 12
17
18/* A 16-bit r/w queue selector */
19#define VIRTIO_PCI_QUEUE_SEL 14
20
21/* A 16-bit r/w queue notifier */
22#define VIRTIO_PCI_QUEUE_NOTIFY 16
23
24/* An 8-bit device status register. */
25#define VIRTIO_PCI_STATUS 18
26
27/* An 8-bit r/o interrupt status register. Reading the value will return the
28 * current contents of the ISR and will also clear it. This is effectively
29 * a read-and-acknowledge. */
30#define VIRTIO_PCI_ISR 19
31
32/* The bit of the ISR which indicates a device configuration change. */
33#define VIRTIO_PCI_ISR_CONFIG 0x2
34
35/* The remaining space is defined by each driver as the per-driver
36 * configuration space */
37#define VIRTIO_PCI_CONFIG 20
38
39/* Virtio ABI version, this must match exactly */
40#define VIRTIO_PCI_ABI_VERSION 0
41
42/* PCI capability types: */
43#define VIRTIO_PCI_CAP_COMMON_CFG 1 /* Common configuration */
44#define VIRTIO_PCI_CAP_NOTIFY_CFG 2 /* Notifications */
45#define VIRTIO_PCI_CAP_ISR_CFG 3 /* ISR access */
46#define VIRTIO_PCI_CAP_DEVICE_CFG 4 /* Device specific configuration */
47#define VIRTIO_PCI_CAP_PCI_CFG 5 /* PCI configuration access */
48
49#define __u8 uint8_t
50#define __le16 uint16_t
51#define __le32 uint32_t
52#define __le64 uint64_t
53
54/* This is the PCI capability header: */
56 __u8 cap_vndr; /* Generic PCI field: PCI_CAP_ID_VNDR */
57 __u8 cap_next; /* Generic PCI field: next ptr. */
58 __u8 cap_len; /* Generic PCI field: capability length */
59 __u8 cfg_type; /* Identifies the structure. */
60 __u8 bar; /* Where to find it. */
61 __u8 padding[3]; /* Pad to full dword. */
62 __le32 offset; /* Offset within bar. */
63 __le32 length; /* Length of the structure, in bytes. */
64};
65
68 __le32 notify_off_multiplier; /* Multiplier for queue_notify_off. */
69};
70
73 __u8 pci_cfg_data[4]; /* Data for BAR access. */
74};
75
76/* Fields in VIRTIO_PCI_CAP_COMMON_CFG: */
78 /* About the whole device. */
79 __le32 device_feature_select; /* read-write */
80 __le32 device_feature; /* read-only */
81 __le32 guest_feature_select; /* read-write */
82 __le32 guest_feature; /* read-write */
83 __le16 msix_config; /* read-write */
84 __le16 num_queues; /* read-only */
85 __u8 device_status; /* read-write */
86 __u8 config_generation; /* read-only */
87
88 /* About a specific virtqueue. */
89 __le16 queue_select; /* read-write */
90 __le16 queue_size; /* read-write, power of 2. */
91 __le16 queue_msix_vector; /* read-write */
92 __le16 queue_enable; /* read-write */
93 __le16 queue_notify_off; /* read-only */
94 __le32 queue_desc_lo; /* read-write */
95 __le32 queue_desc_hi; /* read-write */
96 __le32 queue_avail_lo; /* read-write */
97 __le32 queue_avail_hi; /* read-write */
98 __le32 queue_used_lo; /* read-write */
99 __le32 queue_used_hi; /* read-write */
100};
101
102/* Virtio 1.0 PCI region descriptor. We support memory mapped I/O, port I/O,
103 * and PCI config space access via the cfg PCI capability as a fallback. */
105 void *base;
106 size_t length;
108
109/* How to interpret the base field */
110#define VIRTIO_PCI_REGION_TYPE_MASK 0x00000003
111/* The base field is a memory address */
112#define VIRTIO_PCI_REGION_MEMORY 0x00000001
113/* The base field is a port address */
114#define VIRTIO_PCI_REGION_PORT 0x00000002
115/* The base field is an offset within the PCI bar */
116#define VIRTIO_PCI_REGION_PCI_CONFIG 0x00000003
117 unsigned flags;
118};
119
120/* Virtio 1.0 device state */
123
124 /* VIRTIO_PCI_CAP_PCI_CFG position */
126
127 /* VIRTIO_PCI_CAP_COMMON_CFG data */
129
130 /* VIRTIO_PCI_CAP_DEVICE_CFG data */
132
133 /* VIRTIO_PCI_CAP_ISR_CFG data */
135
136 /* VIRTIO_PCI_CAP_NOTIFY_CFG data */
138};
139
140static inline u32 vp_get_features(unsigned int ioaddr)
141{
143}
144
145static inline void vp_set_features(unsigned int ioaddr, u32 features)
146{
148}
149
150static inline void vp_get(unsigned int ioaddr, unsigned offset,
151 void *buf, unsigned len)
152{
153 u8 *ptr = buf;
154 unsigned i;
155
156 for (i = 0; i < len; i++)
157 ptr[i] = inb(ioaddr + VIRTIO_PCI_CONFIG + offset + i);
158}
159
160static inline u8 vp_get_status(unsigned int ioaddr)
161{
162 return inb(ioaddr + VIRTIO_PCI_STATUS);
163}
164
165static inline void vp_set_status(unsigned int ioaddr, u8 status)
166{
167 if (status == 0) /* reset */
168 return;
170}
171
172static inline u8 vp_get_isr(unsigned int ioaddr)
173{
174 return inb(ioaddr + VIRTIO_PCI_ISR);
175}
176
177static inline void vp_reset(unsigned int ioaddr)
178{
180 (void)inb(ioaddr + VIRTIO_PCI_ISR);
181}
182
183static inline void vp_notify(unsigned int ioaddr, int queue_index)
184{
185 outw(queue_index, ioaddr + VIRTIO_PCI_QUEUE_NOTIFY);
186}
187
188static inline void vp_del_vq(unsigned int ioaddr, int queue_index)
189{
190 /* select the queue */
191
192 outw(queue_index, ioaddr + VIRTIO_PCI_QUEUE_SEL);
193
194 /* deactivate the queue */
195
197}
198
199struct vring_virtqueue;
200
201void vp_free_vq(struct vring_virtqueue *vq);
202int vp_find_vq(unsigned int ioaddr, int queue_index,
203 struct vring_virtqueue *vq, struct dma_device *dma_dev,
204 size_t header_size);
205
206
207/* Virtio 1.0 I/O routines abstract away the three possible HW access
208 * mechanisms - memory, port I/O, and PCI cfg space access. Also built-in
209 * are endianness conversions - to LE on write and from LE on read. */
210
211void vpm_iowrite8(struct virtio_pci_modern_device *vdev,
212 struct virtio_pci_region *region, u8 data, size_t offset);
213
215 struct virtio_pci_region *region, u16 data, size_t offset);
216
218 struct virtio_pci_region *region, u32 data, size_t offset);
219
220static inline void vpm_iowrite64(struct virtio_pci_modern_device *vdev,
221 struct virtio_pci_region *region,
222 u64 data, size_t offset_lo, size_t offset_hi)
223{
224 vpm_iowrite32(vdev, region, (u32)data, offset_lo);
225 vpm_iowrite32(vdev, region, data >> 32, offset_hi);
226}
227
229 struct virtio_pci_region *region, size_t offset);
230
232 struct virtio_pci_region *region, size_t offset);
233
235 struct virtio_pci_region *region, size_t offset);
236
237/* Virtio 1.0 device manipulation routines */
238
239#define COMMON_OFFSET(field) offsetof(struct virtio_pci_common_cfg, field)
240
241static inline void vpm_reset(struct virtio_pci_modern_device *vdev)
242{
243 vpm_iowrite8(vdev, &vdev->common, 0, COMMON_OFFSET(device_status));
244 while (vpm_ioread8(vdev, &vdev->common, COMMON_OFFSET(device_status)))
245 mdelay(1);
246}
247
248static inline u8 vpm_get_status(struct virtio_pci_modern_device *vdev)
249{
250 return vpm_ioread8(vdev, &vdev->common, COMMON_OFFSET(device_status));
251}
252
253static inline void vpm_add_status(struct virtio_pci_modern_device *vdev,
254 u8 status)
255{
256 u8 curr_status = vpm_ioread8(vdev, &vdev->common, COMMON_OFFSET(device_status));
257 vpm_iowrite8(vdev, &vdev->common,
258 curr_status | status, COMMON_OFFSET(device_status));
259}
260
262{
263 u32 features_lo, features_hi;
264
265 vpm_iowrite32(vdev, &vdev->common, 0, COMMON_OFFSET(device_feature_select));
266 features_lo = vpm_ioread32(vdev, &vdev->common, COMMON_OFFSET(device_feature));
267 vpm_iowrite32(vdev, &vdev->common, 1, COMMON_OFFSET(device_feature_select));
268 features_hi = vpm_ioread32(vdev, &vdev->common, COMMON_OFFSET(device_feature));
269
270 return ((u64)features_hi << 32) | features_lo;
271}
272
273static inline void vpm_set_features(struct virtio_pci_modern_device *vdev,
275{
276 u32 features_lo = (u32)features;
277 u32 features_hi = features >> 32;
278
279 vpm_iowrite32(vdev, &vdev->common, 0, COMMON_OFFSET(guest_feature_select));
280 vpm_iowrite32(vdev, &vdev->common, features_lo, COMMON_OFFSET(guest_feature));
281 vpm_iowrite32(vdev, &vdev->common, 1, COMMON_OFFSET(guest_feature_select));
282 vpm_iowrite32(vdev, &vdev->common, features_hi, COMMON_OFFSET(guest_feature));
283}
284
285static inline void vpm_get(struct virtio_pci_modern_device *vdev,
286 unsigned offset, void *buf, unsigned len)
287{
288 u8 *ptr = buf;
289 unsigned i;
290
291 for (i = 0; i < len; i++)
292 ptr[i] = vpm_ioread8(vdev, &vdev->device, offset + i);
293}
294
295static inline u8 vpm_get_isr(struct virtio_pci_modern_device *vdev)
296{
297 return vpm_ioread8(vdev, &vdev->isr, 0);
298}
299
300void vpm_notify(struct virtio_pci_modern_device *vdev,
301 struct vring_virtqueue *vq);
302
304 unsigned nvqs, struct vring_virtqueue *vqs,
305 struct dma_device *dma_dev, size_t header_size);
306
307int virtio_pci_find_capability(struct pci_device *pci, uint8_t cfg_type);
308
309int virtio_pci_map_capability(struct pci_device *pci, int cap, size_t minlen,
310 u32 align, u32 start, u32 size,
311 struct virtio_pci_region *region);
312
314#endif /* _VIRTIO_PCI_H_ */
unsigned char uint8_t
Definition stdint.h:10
uint16_t offset
Offset to command line.
Definition bzimage.h:3
static unsigned long ioaddr
Definition davicom.c:129
ring len
Length.
Definition dwmac.h:226
uint32_t features
Supported features.
Definition ena.h:5
uint8_t data[48]
Additional event data.
Definition ena.h:11
uint8_t status
Status.
Definition ena.h:5
uint32_t start
Starting offset.
Definition netvsc.h:1
uint16_t size
Buffer size.
Definition dwmac.h:3
#define u8
Definition igbvf_osdep.h:40
#define outb(data, io_addr)
Definition io.h:310
#define outw(data, io_addr)
Definition io.h:320
#define inl(io_addr)
Definition io.h:301
#define outl(data, io_addr)
Definition io.h:330
#define inb(io_addr)
Definition io.h:283
uint64_t u64
Definition stdint.h:26
DMA mappings.
A DMA-capable device.
Definition dma.h:48
A PCI device.
Definition pci.h:211
__u8 padding[3]
Definition virtio-pci.h:61
struct virtio_pci_cap cap
Definition virtio-pci.h:72
struct virtio_pci_region isr
Definition virtio-pci.h:134
struct virtio_pci_region device
Definition virtio-pci.h:131
struct pci_device * pci
Definition virtio-pci.h:122
struct virtio_pci_region common
Definition virtio-pci.h:128
struct virtio_pci_cap cap
Definition virtio-pci.h:67
void mdelay(unsigned long msecs)
Delay for a fixed number of milliseconds.
Definition timer.c:79
#define u16
Definition vga.h:20
#define u32
Definition vga.h:21
u8 vpm_ioread8(struct virtio_pci_modern_device *vdev, struct virtio_pci_region *region, size_t offset)
Definition virtio-pci.c:181
static u8 vp_get_status(unsigned int ioaddr)
Definition virtio-pci.h:160
void vpm_iowrite32(struct virtio_pci_modern_device *vdev, struct virtio_pci_region *region, u32 data, size_t offset)
Definition virtio-pci.c:160
void vp_free_vq(struct vring_virtqueue *vq)
Definition virtio-pci.c:48
static u32 vp_get_features(unsigned int ioaddr)
Definition virtio-pci.h:140
#define VIRTIO_PCI_ISR
Definition virtio-pci.h:30
#define __le16
Definition virtio-pci.h:50
static void vpm_add_status(struct virtio_pci_modern_device *vdev, u8 status)
Definition virtio-pci.h:253
#define __le32
Definition virtio-pci.h:51
static void vp_set_features(unsigned int ioaddr, u32 features)
Definition virtio-pci.h:145
void vpm_iowrite16(struct virtio_pci_modern_device *vdev, struct virtio_pci_region *region, u16 data, size_t offset)
Definition virtio-pci.c:139
static void vpm_reset(struct virtio_pci_modern_device *vdev)
Definition virtio-pci.h:241
#define VIRTIO_PCI_CONFIG
Definition virtio-pci.h:37
static void vp_notify(unsigned int ioaddr, int queue_index)
Definition virtio-pci.h:183
static void vp_reset(unsigned int ioaddr)
Definition virtio-pci.h:177
int virtio_pci_map_capability(struct pci_device *pci, int cap, size_t minlen, u32 align, u32 start, u32 size, struct virtio_pci_region *region)
Definition virtio-pci.c:276
#define VIRTIO_PCI_HOST_FEATURES
Definition virtio-pci.h:7
#define VIRTIO_PCI_QUEUE_SEL
Definition virtio-pci.h:19
int vp_find_vq(unsigned int ioaddr, int queue_index, struct vring_virtqueue *vq, struct dma_device *dma_dev, size_t header_size)
Definition virtio-pci.c:58
static void vp_set_status(unsigned int ioaddr, u8 status)
Definition virtio-pci.h:165
#define VIRTIO_PCI_STATUS
Definition virtio-pci.h:25
static void vpm_set_features(struct virtio_pci_modern_device *vdev, u64 features)
Definition virtio-pci.h:273
static u64 vpm_get_features(struct virtio_pci_modern_device *vdev)
Definition virtio-pci.h:261
#define COMMON_OFFSET(field)
Definition virtio-pci.h:239
static u8 vpm_get_status(struct virtio_pci_modern_device *vdev)
Definition virtio-pci.h:248
void vpm_notify(struct virtio_pci_modern_device *vdev, struct vring_virtqueue *vq)
Definition virtio-pci.c:354
static void vpm_get(struct virtio_pci_modern_device *vdev, unsigned offset, void *buf, unsigned len)
Definition virtio-pci.h:285
#define VIRTIO_PCI_QUEUE_NOTIFY
Definition virtio-pci.h:22
u32 vpm_ioread32(struct virtio_pci_modern_device *vdev, struct virtio_pci_region *region, size_t offset)
Definition virtio-pci.c:227
static void vpm_iowrite64(struct virtio_pci_modern_device *vdev, struct virtio_pci_region *region, u64 data, size_t offset_lo, size_t offset_hi)
Definition virtio-pci.h:220
#define __u8
Definition virtio-pci.h:49
#define VIRTIO_PCI_GUEST_FEATURES
Definition virtio-pci.h:10
void virtio_pci_unmap_capability(struct virtio_pci_region *region)
Definition virtio-pci.c:346
u16 vpm_ioread16(struct virtio_pci_modern_device *vdev, struct virtio_pci_region *region, size_t offset)
Definition virtio-pci.c:204
static void vp_get(unsigned int ioaddr, unsigned offset, void *buf, unsigned len)
Definition virtio-pci.h:150
static void vp_del_vq(unsigned int ioaddr, int queue_index)
Definition virtio-pci.h:188
int virtio_pci_find_capability(struct pci_device *pci, uint8_t cfg_type)
Definition virtio-pci.c:250
int vpm_find_vqs(struct virtio_pci_modern_device *vdev, unsigned nvqs, struct vring_virtqueue *vqs, struct dma_device *dma_dev, size_t header_size)
Definition virtio-pci.c:360
#define VIRTIO_PCI_QUEUE_PFN
Definition virtio-pci.h:13
static u8 vp_get_isr(unsigned int ioaddr)
Definition virtio-pci.h:172
static u8 vpm_get_isr(struct virtio_pci_modern_device *vdev)
Definition virtio-pci.h:295
void vpm_iowrite8(struct virtio_pci_modern_device *vdev, struct virtio_pci_region *region, u8 data, size_t offset)
Definition virtio-pci.c:119