iPXE
virtio-pci.c File Reference
#include "errno.h"
#include "byteswap.h"
#include "etherboot.h"
#include "ipxe/io.h"
#include "ipxe/iomap.h"
#include "ipxe/pci.h"
#include "ipxe/dma.h"
#include "ipxe/reboot.h"
#include "ipxe/virtio-pci.h"
#include "ipxe/virtio-ring.h"

Go to the source code of this file.

Macros

#define CFG_POS(vdev, field)

Functions

static int vp_alloc_vq (struct vring_virtqueue *vq, u16 num, size_t header_size)
void vp_free_vq (struct vring_virtqueue *vq)
int vp_find_vq (unsigned int ioaddr, int queue_index, struct vring_virtqueue *vq, struct dma_device *dma_dev, size_t header_size)
static void prep_pci_cfg_cap (struct virtio_pci_modern_device *vdev, struct virtio_pci_region *region, size_t offset, u32 length)
void vpm_iowrite8 (struct virtio_pci_modern_device *vdev, struct virtio_pci_region *region, u8 data, size_t offset)
void vpm_iowrite16 (struct virtio_pci_modern_device *vdev, struct virtio_pci_region *region, u16 data, size_t offset)
void vpm_iowrite32 (struct virtio_pci_modern_device *vdev, struct virtio_pci_region *region, u32 data, size_t offset)
u8 vpm_ioread8 (struct virtio_pci_modern_device *vdev, struct virtio_pci_region *region, size_t offset)
u16 vpm_ioread16 (struct virtio_pci_modern_device *vdev, struct virtio_pci_region *region, size_t offset)
u32 vpm_ioread32 (struct virtio_pci_modern_device *vdev, struct virtio_pci_region *region, size_t offset)
int virtio_pci_find_capability (struct pci_device *pci, uint8_t cfg_type)
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)
void virtio_pci_unmap_capability (struct virtio_pci_region *region)
void vpm_notify (struct virtio_pci_modern_device *vdev, struct vring_virtqueue *vq)
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)

Macro Definition Documentation

◆ CFG_POS

#define CFG_POS ( vdev,
field )
Value:
(vdev->cfg_cap_pos + offsetof(struct virtio_pci_cfg_cap, field))
#define offsetof(type, field)
Get offset of a field within a structure.
Definition stddef.h:25

Definition at line 106 of file virtio-pci.c.

106#define CFG_POS(vdev, field) \
107 (vdev->cfg_cap_pos + offsetof(struct virtio_pci_cfg_cap, field))

Referenced by prep_pci_cfg_cap(), vpm_ioread16(), vpm_ioread32(), vpm_ioread8(), vpm_iowrite16(), vpm_iowrite32(), and vpm_iowrite8().

Function Documentation

◆ vp_alloc_vq()

int vp_alloc_vq ( struct vring_virtqueue * vq,
u16 num,
size_t header_size )
static

Definition at line 25 of file virtio-pci.c.

26{
27 size_t ring_size = PAGE_MASK + vring_size(num);
28 size_t vdata_size = num * sizeof(void *);
29 size_t queue_size = ring_size + vdata_size + header_size;
30
31 vq->queue = dma_alloc(vq->dma, &vq->map, queue_size, queue_size);
32 if (!vq->queue) {
33 return -ENOMEM;
34 }
35
36 memset ( vq->queue, 0, queue_size );
37 vq->queue_size = queue_size;
38
39 /* vdata immediately follows the ring */
40 vq->vdata = (void **)(vq->queue + ring_size);
41
42 /* empty header immediately follows vdata */
43 vq->empty_header = (struct virtio_net_hdr_modern *)(vq->queue + ring_size + vdata_size);
44
45 return 0;
46}
#define ENOMEM
Not enough space.
Definition errno.h:535
#define PAGE_MASK
Page mask.
Definition io.h:31
void * memset(void *dest, int character, size_t len) __nonnull
void * dma_alloc(struct dma_device *dma, struct dma_mapping *map, size_t len, size_t align)
Allocate and map DMA-coherent buffer.
uint32_t num
Definition multiboot.h:0
struct virtio_net_hdr_modern * empty_header
Definition virtio-ring.h:85
unsigned char * queue
Definition virtio-ring.h:77
struct dma_mapping map
Definition virtio-ring.h:79
struct dma_device * dma
Definition virtio-ring.h:80
#define vring_size(num)
Definition virtio-ring.h:70

References vring_virtqueue::dma, dma_alloc(), vring_virtqueue::empty_header, ENOMEM, vring_virtqueue::map, memset(), num, PAGE_MASK, vring_virtqueue::queue, vring_virtqueue::queue_size, u16, vring_virtqueue::vdata, and vring_size.

Referenced by vp_find_vq(), and vpm_find_vqs().

◆ vp_free_vq()

void vp_free_vq ( struct vring_virtqueue * vq)

Definition at line 48 of file virtio-pci.c.

49{
50 if (vq->queue && vq->queue_size) {
51 dma_free(&vq->map, vq->queue, vq->queue_size);
52 vq->queue = NULL;
53 vq->vdata = NULL;
54 vq->queue_size = 0;
55 }
56}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
void dma_free(struct dma_mapping *map, void *addr, size_t len)
Unmap and free DMA-coherent buffer.

References dma_free(), vring_virtqueue::map, NULL, vring_virtqueue::queue, vring_virtqueue::queue_size, and vring_virtqueue::vdata.

Referenced by virtnet_free_virtqueues().

◆ vp_find_vq()

int vp_find_vq ( unsigned int ioaddr,
int queue_index,
struct vring_virtqueue * vq,
struct dma_device * dma_dev,
size_t header_size )

Definition at line 58 of file virtio-pci.c.

61{
62 struct vring * vr = &vq->vring;
63 u16 num;
64 int rc;
65
66 /* select the queue */
67
68 outw(queue_index, ioaddr + VIRTIO_PCI_QUEUE_SEL);
69
70 /* check if the queue is available */
71
73 if (!num) {
74 DBG("VIRTIO-PCI ERROR: queue size is 0\n");
75 return -1;
76 }
77
78 /* check if the queue is already active */
79
81 DBG("VIRTIO-PCI ERROR: queue already active\n");
82 return -1;
83 }
84
85 vq->queue_index = queue_index;
86 vq->dma = dma_dev;
87
88 /* initialize the queue */
89 rc = vp_alloc_vq(vq, num, header_size);
90 if (rc) {
91 DBG("VIRTIO-PCI ERROR: failed to allocate queue memory\n");
92 return rc;
93 }
94 vring_init(vr, num, vq->queue);
95
96 /* activate the queue
97 *
98 * NOTE: vr->desc is initialized by vring_init()
99 */
100
102
103 return num;
104}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
#define PAGE_SHIFT
Page shift.
Definition io.h:14
static unsigned long ioaddr
Definition davicom.c:129
#define DBG(...)
Print a debugging message.
Definition compiler.h:498
#define inw(io_addr)
Definition io.h:292
#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
physaddr_t dma(struct dma_mapping *map, void *addr)
Get DMA address from virtual address.
struct vring vring
Definition virtio-ring.h:81
struct vring_desc * desc
Definition virtio-ring.h:65
#define u16
Definition vga.h:20
static int vp_alloc_vq(struct vring_virtqueue *vq, u16 num, size_t header_size)
Definition virtio-pci.c:25
#define VIRTIO_PCI_QUEUE_NUM
Definition virtio-pci.h:16
#define VIRTIO_PCI_QUEUE_SEL
Definition virtio-pci.h:19
#define VIRTIO_PCI_QUEUE_PFN
Definition virtio-pci.h:13
static void vring_init(struct vring *vr, unsigned int num, unsigned char *queue)
Definition virtio-ring.h:96

References DBG, vring::desc, dma(), vring_virtqueue::dma, inl, inw, ioaddr, vring_virtqueue::map, num, outl, outw, PAGE_SHIFT, vring_virtqueue::queue, vring_virtqueue::queue_index, rc, u16, VIRTIO_PCI_QUEUE_NUM, VIRTIO_PCI_QUEUE_PFN, VIRTIO_PCI_QUEUE_SEL, vp_alloc_vq(), vring_virtqueue::vring, and vring_init().

Referenced by virtnet_open_legacy().

◆ prep_pci_cfg_cap()

void prep_pci_cfg_cap ( struct virtio_pci_modern_device * vdev,
struct virtio_pci_region * region,
size_t offset,
u32 length )
static

Definition at line 109 of file virtio-pci.c.

112{
113 pci_write_config_byte(vdev->pci, CFG_POS(vdev, cap.bar), region->bar);
114 pci_write_config_dword(vdev->pci, CFG_POS(vdev, cap.length), length);
115 pci_write_config_dword(vdev->pci, CFG_POS(vdev, cap.offset),
116 (intptr_t)(region->base + offset));
117}
unsigned long intptr_t
Definition stdint.h:21
uint16_t offset
Offset to command line.
Definition bzimage.h:3
int pci_write_config_byte(struct pci_device *pci, unsigned int where, uint8_t value)
Write byte to PCI configuration space.
int pci_write_config_dword(struct pci_device *pci, unsigned int where, uint32_t value)
Write 32-bit dword to PCI configuration space.
u16 length
Definition sky2.h:1
struct pci_device * pci
Definition virtio-pci.h:122
#define CFG_POS(vdev, field)
Definition virtio-pci.c:106

References virtio_pci_region::bar, virtio_pci_region::base, CFG_POS, length, offset, virtio_pci_modern_device::pci, pci_write_config_byte(), pci_write_config_dword(), and u32.

Referenced by vpm_ioread16(), vpm_ioread32(), vpm_ioread8(), vpm_iowrite16(), vpm_iowrite32(), and vpm_iowrite8().

◆ vpm_iowrite8()

void vpm_iowrite8 ( struct virtio_pci_modern_device * vdev,
struct virtio_pci_region * region,
u8 data,
size_t offset )

Definition at line 119 of file virtio-pci.c.

121{
122 switch (region->flags & VIRTIO_PCI_REGION_TYPE_MASK) {
124 writeb(data, region->base + offset);
125 break;
127 outb(data, region->base + offset);
128 break;
130 prep_pci_cfg_cap(vdev, region, offset, 1);
131 pci_write_config_byte(vdev->pci, CFG_POS(vdev, pci_cfg_data), data);
132 break;
133 default:
134 assert(0);
135 break;
136 }
137}
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
uint8_t data[48]
Additional event data.
Definition ena.h:11
#define outb(data, io_addr)
Definition io.h:310
static void prep_pci_cfg_cap(struct virtio_pci_modern_device *vdev, struct virtio_pci_region *region, size_t offset, u32 length)
Definition virtio-pci.c:109
#define VIRTIO_PCI_REGION_TYPE_MASK
Definition virtio-pci.h:110
#define VIRTIO_PCI_REGION_MEMORY
Definition virtio-pci.h:112
#define VIRTIO_PCI_REGION_PCI_CONFIG
Definition virtio-pci.h:116
#define VIRTIO_PCI_REGION_PORT
Definition virtio-pci.h:114
#define writeb
Definition w89c840.c:158

References assert, virtio_pci_region::base, CFG_POS, data, virtio_pci_region::flags, offset, outb, virtio_pci_modern_device::pci, pci_write_config_byte(), prep_pci_cfg_cap(), u8, VIRTIO_PCI_REGION_MEMORY, VIRTIO_PCI_REGION_PCI_CONFIG, VIRTIO_PCI_REGION_PORT, VIRTIO_PCI_REGION_TYPE_MASK, and writeb.

Referenced by vpm_add_status(), and vpm_reset().

◆ vpm_iowrite16()

void vpm_iowrite16 ( struct virtio_pci_modern_device * vdev,
struct virtio_pci_region * region,
u16 data,
size_t offset )

Definition at line 139 of file virtio-pci.c.

141{
143 switch (region->flags & VIRTIO_PCI_REGION_TYPE_MASK) {
145 writew(data, region->base + offset);
146 break;
148 outw(data, region->base + offset);
149 break;
151 prep_pci_cfg_cap(vdev, region, offset, 2);
152 pci_write_config_word(vdev->pci, CFG_POS(vdev, pci_cfg_data), data);
153 break;
154 default:
155 assert(0);
156 break;
157 }
158}
#define cpu_to_le16(value)
Definition byteswap.h:107
int pci_write_config_word(struct pci_device *pci, unsigned int where, uint16_t value)
Write 16-bit word to PCI configuration space.
#define writew
Definition w89c840.c:159

References assert, virtio_pci_region::base, CFG_POS, cpu_to_le16, data, virtio_pci_region::flags, offset, outw, virtio_pci_modern_device::pci, pci_write_config_word(), prep_pci_cfg_cap(), u16, VIRTIO_PCI_REGION_MEMORY, VIRTIO_PCI_REGION_PCI_CONFIG, VIRTIO_PCI_REGION_PORT, VIRTIO_PCI_REGION_TYPE_MASK, and writew.

Referenced by vpm_find_vqs(), and vpm_notify().

◆ vpm_iowrite32()

void vpm_iowrite32 ( struct virtio_pci_modern_device * vdev,
struct virtio_pci_region * region,
u32 data,
size_t offset )

Definition at line 160 of file virtio-pci.c.

162{
164 switch (region->flags & VIRTIO_PCI_REGION_TYPE_MASK) {
166 writel(data, region->base + offset);
167 break;
169 outl(data, region->base + offset);
170 break;
172 prep_pci_cfg_cap(vdev, region, offset, 4);
173 pci_write_config_dword(vdev->pci, CFG_POS(vdev, pci_cfg_data), data);
174 break;
175 default:
176 assert(0);
177 break;
178 }
179}
#define cpu_to_le32(value)
Definition byteswap.h:108
#define writel
Definition w89c840.c:160

References assert, virtio_pci_region::base, CFG_POS, cpu_to_le32, data, virtio_pci_region::flags, offset, outl, virtio_pci_modern_device::pci, pci_write_config_dword(), prep_pci_cfg_cap(), u32, VIRTIO_PCI_REGION_MEMORY, VIRTIO_PCI_REGION_PCI_CONFIG, VIRTIO_PCI_REGION_PORT, VIRTIO_PCI_REGION_TYPE_MASK, and writel.

Referenced by vpm_get_features(), vpm_iowrite64(), and vpm_set_features().

◆ vpm_ioread8()

u8 vpm_ioread8 ( struct virtio_pci_modern_device * vdev,
struct virtio_pci_region * region,
size_t offset )

Definition at line 181 of file virtio-pci.c.

183{
185 switch (region->flags & VIRTIO_PCI_REGION_TYPE_MASK) {
187 data = readb(region->base + offset);
188 break;
190 data = inb(region->base + offset);
191 break;
193 prep_pci_cfg_cap(vdev, region, offset, 1);
194 pci_read_config_byte(vdev->pci, CFG_POS(vdev, pci_cfg_data), &data);
195 break;
196 default:
197 assert(0);
198 data = 0;
199 break;
200 }
201 return data;
202}
unsigned char uint8_t
Definition stdint.h:10
#define inb(io_addr)
Definition io.h:283
int pci_read_config_byte(struct pci_device *pci, unsigned int where, uint8_t *value)
Read byte from PCI configuration space.
#define readb
Definition w89c840.c:155

References assert, virtio_pci_region::base, CFG_POS, data, virtio_pci_region::flags, inb, offset, virtio_pci_modern_device::pci, pci_read_config_byte(), prep_pci_cfg_cap(), readb, u8, VIRTIO_PCI_REGION_MEMORY, VIRTIO_PCI_REGION_PCI_CONFIG, VIRTIO_PCI_REGION_PORT, and VIRTIO_PCI_REGION_TYPE_MASK.

Referenced by vpm_add_status(), vpm_get(), vpm_get_isr(), vpm_get_status(), and vpm_reset().

◆ vpm_ioread16()

u16 vpm_ioread16 ( struct virtio_pci_modern_device * vdev,
struct virtio_pci_region * region,
size_t offset )

Definition at line 204 of file virtio-pci.c.

206{
208 switch (region->flags & VIRTIO_PCI_REGION_TYPE_MASK) {
210 data = readw(region->base + offset);
211 break;
213 data = inw(region->base + offset);
214 break;
216 prep_pci_cfg_cap(vdev, region, offset, 2);
217 pci_read_config_word(vdev->pci, CFG_POS(vdev, pci_cfg_data), &data);
218 break;
219 default:
220 assert(0);
221 data = 0;
222 break;
223 }
224 return le16_to_cpu(data);
225}
unsigned short uint16_t
Definition stdint.h:11
#define le16_to_cpu(value)
Definition byteswap.h:113
int pci_read_config_word(struct pci_device *pci, unsigned int where, uint16_t *value)
Read 16-bit word from PCI configuration space.
#define readw
Definition w89c840.c:156

References assert, virtio_pci_region::base, CFG_POS, data, virtio_pci_region::flags, inw, le16_to_cpu, offset, virtio_pci_modern_device::pci, pci_read_config_word(), prep_pci_cfg_cap(), readw, u16, VIRTIO_PCI_REGION_MEMORY, VIRTIO_PCI_REGION_PCI_CONFIG, VIRTIO_PCI_REGION_PORT, and VIRTIO_PCI_REGION_TYPE_MASK.

Referenced by vpm_find_vqs().

◆ vpm_ioread32()

u32 vpm_ioread32 ( struct virtio_pci_modern_device * vdev,
struct virtio_pci_region * region,
size_t offset )

Definition at line 227 of file virtio-pci.c.

229{
231 switch (region->flags & VIRTIO_PCI_REGION_TYPE_MASK) {
233 data = readl(region->base + offset);
234 break;
236 data = inl(region->base + offset);
237 break;
239 prep_pci_cfg_cap(vdev, region, offset, 4);
240 pci_read_config_dword(vdev->pci, CFG_POS(vdev, pci_cfg_data), &data);
241 break;
242 default:
243 assert(0);
244 data = 0;
245 break;
246 }
247 return le32_to_cpu(data);
248}
unsigned int uint32_t
Definition stdint.h:12
#define le32_to_cpu(value)
Definition byteswap.h:114
int pci_read_config_dword(struct pci_device *pci, unsigned int where, uint32_t *value)
Read 32-bit dword from PCI configuration space.
#define readl
Definition w89c840.c:157

References assert, virtio_pci_region::base, CFG_POS, data, virtio_pci_region::flags, inl, le32_to_cpu, offset, virtio_pci_modern_device::pci, pci_read_config_dword(), prep_pci_cfg_cap(), readl, u32, VIRTIO_PCI_REGION_MEMORY, VIRTIO_PCI_REGION_PCI_CONFIG, VIRTIO_PCI_REGION_PORT, and VIRTIO_PCI_REGION_TYPE_MASK.

Referenced by vpm_get_features().

◆ virtio_pci_find_capability()

int virtio_pci_find_capability ( struct pci_device * pci,
uint8_t cfg_type )

Definition at line 250 of file virtio-pci.c.

251{
252 int pos;
253 uint8_t type, bar;
254
255 for (pos = pci_find_capability(pci, PCI_CAP_ID_VNDR);
256 pos > 0;
257 pos = pci_find_next_capability(pci, pos, PCI_CAP_ID_VNDR)) {
258
260 cfg_type), &type);
262 bar), &bar);
263
264 /* Ignore structures with reserved BAR values */
265 if (bar > 0x5) {
266 continue;
267 }
268
269 if (type == cfg_type) {
270 return pos;
271 }
272 }
273 return 0;
274}
uint32_t type
Operating system type.
Definition ena.h:1
#define PCI_CAP_ID_VNDR
Vendor-specific.
Definition pci.h:97
int pci_find_next_capability(struct pci_device *pci, int pos, int cap)
Look for another PCI capability.
Definition pciextra.c:76
int pci_find_capability(struct pci_device *pci, int cap)
Look for a PCI capability.
Definition pciextra.c:39

References offsetof, PCI_CAP_ID_VNDR, pci_find_capability(), pci_find_next_capability(), pci_read_config_byte(), and type.

Referenced by virtnet_probe_modern().

◆ virtio_pci_map_capability()

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 at line 276 of file virtio-pci.c.

279{
280 u8 bar;
281 u32 offset, length, base_raw;
282 unsigned long base;
283
284 pci_read_config_byte(pci, cap + offsetof(struct virtio_pci_cap, bar), &bar);
286 &offset);
288 &length);
289
290 if (length <= start) {
291 DBG("VIRTIO-PCI bad capability len %d (>%d expected)\n", length, start);
292 return -EINVAL;
293 }
294 if (length - start < minlen) {
295 DBG("VIRTIO-PCI bad capability len %d (>=%zd expected)\n", length, minlen);
296 return -EINVAL;
297 }
298 length -= start;
299 if (start + offset < offset) {
300 DBG("VIRTIO-PCI map wrap-around %d+%d\n", start, offset);
301 return -EINVAL;
302 }
303 offset += start;
304 if (offset & (align - 1)) {
305 DBG("VIRTIO-PCI offset %d not aligned to %d\n", offset, align);
306 return -EINVAL;
307 }
308 if (length > size) {
309 length = size;
310 }
311
312 if (minlen + offset < minlen ||
313 minlen + offset > pci_bar_size(pci, PCI_BASE_ADDRESS(bar))) {
314 DBG("VIRTIO-PCI map virtio %zd@%d out of range on bar %i length %ld\n",
315 minlen, offset,
316 bar, pci_bar_size(pci, PCI_BASE_ADDRESS(bar)));
317 return -EINVAL;
318 }
319
320 region->base = NULL;
321 region->length = length;
322 region->bar = bar;
323
325 if (base) {
326 pci_read_config_dword(pci, PCI_BASE_ADDRESS(bar), &base_raw);
327
328 if (base_raw & PCI_BASE_ADDRESS_SPACE_IO) {
329 /* Region accessed using port I/O */
330 region->base = (void *)(base + offset);
332 } else {
333 /* Region mapped into memory space */
334 region->base = pci_ioremap(pci, base + offset, length);
336 }
337 }
338 if (!region->base) {
339 /* Region accessed via PCI config space window */
340 region->base = (void *)(intptr_t)offset;
342 }
343 return 0;
344}
uint32_t start
Starting offset.
Definition netvsc.h:1
uint16_t size
Buffer size.
Definition dwmac.h:3
#define EINVAL
Invalid argument.
Definition errno.h:429
#define u8
Definition igbvf_osdep.h:40
void * pci_ioremap(struct pci_device *pci, unsigned long bus_addr, size_t len)
Map PCI bus address as an I/O address.
uint32_t base
Base.
Definition librm.h:3
unsigned long pci_bar_size(struct pci_device *pci, unsigned int reg)
Get the size of a PCI BAR.
Definition pci.c:164
unsigned long pci_bar_start(struct pci_device *pci, unsigned int reg)
Find the start of a PCI BAR.
Definition pci.c:97
#define PCI_BASE_ADDRESS_SPACE_IO
I/O BAR.
Definition pci.h:69
#define PCI_BASE_ADDRESS(n)
PCI base address registers.
Definition pci.h:62
#define u32
Definition vga.h:21

References virtio_pci_region::bar, base, virtio_pci_region::base, DBG, EINVAL, virtio_pci_region::flags, length, virtio_pci_region::length, NULL, offset, offsetof, pci_bar_size(), pci_bar_start(), PCI_BASE_ADDRESS, PCI_BASE_ADDRESS_SPACE_IO, pci_ioremap(), pci_read_config_byte(), pci_read_config_dword(), size, start, u32, u8, VIRTIO_PCI_REGION_MEMORY, VIRTIO_PCI_REGION_PCI_CONFIG, and VIRTIO_PCI_REGION_PORT.

Referenced by virtnet_probe_modern(), and vpm_find_vqs().

◆ virtio_pci_unmap_capability()

void virtio_pci_unmap_capability ( struct virtio_pci_region * region)

Definition at line 346 of file virtio-pci.c.

347{
348 unsigned region_type = region->flags & VIRTIO_PCI_REGION_TYPE_MASK;
349 if (region_type == VIRTIO_PCI_REGION_MEMORY) {
350 iounmap(region->base);
351 }
352}
void iounmap(volatile const void *io_addr)
Unmap I/O address.

References virtio_pci_region::base, virtio_pci_region::flags, iounmap(), VIRTIO_PCI_REGION_MEMORY, and VIRTIO_PCI_REGION_TYPE_MASK.

Referenced by virtnet_free_virtqueues(), virtnet_probe_modern(), and virtnet_remove().

◆ vpm_notify()

void vpm_notify ( struct virtio_pci_modern_device * vdev,
struct vring_virtqueue * vq )

Definition at line 354 of file virtio-pci.c.

356{
357 vpm_iowrite16(vdev, &vq->notification, (u16)vq->queue_index, 0);
358}
struct virtio_pci_region notification
Definition virtio-ring.h:88
void vpm_iowrite16(struct virtio_pci_modern_device *vdev, struct virtio_pci_region *region, u16 data, size_t offset)
Definition virtio-pci.c:139

References vring_virtqueue::notification, vring_virtqueue::queue_index, u16, and vpm_iowrite16().

Referenced by vring_kick().

◆ vpm_find_vqs()

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 at line 360 of file virtio-pci.c.

363{
364 unsigned i;
365 struct vring_virtqueue *vq;
366 u16 size, off;
367 u32 notify_offset_multiplier;
368 int err;
369
370 if (nvqs > vpm_ioread16(vdev, &vdev->common, COMMON_OFFSET(num_queues))) {
371 return -ENOENT;
372 }
373
374 /* Read notify_off_multiplier from config space. */
377 notify_off_multiplier),
378 &notify_offset_multiplier);
379
380 for (i = 0; i < nvqs; i++) {
381 /* Select the queue we're interested in */
382 vpm_iowrite16(vdev, &vdev->common, (u16)i, COMMON_OFFSET(queue_select));
383
384 /* Check if queue is either not available or already active. */
386 /* QEMU has a bug where queues don't revert to inactive on device
387 * reset. Skip checking the queue_enable field until it is fixed.
388 */
389 if (!size /*|| vpm_ioread16(vdev, &vdev->common.queue_enable)*/)
390 return -ENOENT;
391
392 if (size & (size - 1)) {
393 DBG("VIRTIO-PCI %p: bad queue size %d\n", vdev, size);
394 return -EINVAL;
395 }
396
397 if (size > MAX_QUEUE_NUM) {
398 /* iPXE networking tends to be not perf critical so there's no
399 * need to accept large queue sizes.
400 */
402 }
403
404 vq = &vqs[i];
405 vq->queue_index = i;
406 vq->dma = dma_dev;
407
408 /* get offset of notification word for this vq */
409 off = vpm_ioread16(vdev, &vdev->common, COMMON_OFFSET(queue_notify_off));
410
411 err = vp_alloc_vq(vq, size, header_size);
412 if (err) {
413 DBG("VIRTIO-PCI %p: failed to allocate queue memory\n", vdev);
414 return err;
415 }
416 vring_init(&vq->vring, size, vq->queue);
417
418 /* activate the queue */
420
421 vpm_iowrite64(vdev, &vdev->common,
422 dma(&vq->map, vq->vring.desc),
423 COMMON_OFFSET(queue_desc_lo),
424 COMMON_OFFSET(queue_desc_hi));
425 vpm_iowrite64(vdev, &vdev->common,
426 dma(&vq->map, vq->vring.avail),
427 COMMON_OFFSET(queue_avail_lo),
428 COMMON_OFFSET(queue_avail_hi));
429 vpm_iowrite64(vdev, &vdev->common,
430 dma(&vq->map, vq->vring.used),
431 COMMON_OFFSET(queue_used_lo),
432 COMMON_OFFSET(queue_used_hi));
433
434 err = virtio_pci_map_capability(vdev->pci,
435 vdev->notify_cap_pos, 2, 2,
436 off * notify_offset_multiplier, 2,
437 &vq->notification);
438 if (err) {
439 return err;
440 }
441 }
442
443 /* Select and activate all queues. Has to be done last: once we do
444 * this, there's no way to go back except reset.
445 */
446 for (i = 0; i < nvqs; i++) {
447 vq = &vqs[i];
448 vpm_iowrite16(vdev, &vdev->common, (u16)vq->queue_index,
449 COMMON_OFFSET(queue_select));
450 vpm_iowrite16(vdev, &vdev->common, 1, COMMON_OFFSET(queue_enable));
451 }
452 return 0;
453}
#define ENOENT
No such file or directory.
Definition errno.h:515
struct virtio_pci_region common
Definition virtio-pci.h:128
struct vring_avail * avail
Definition virtio-ring.h:66
struct vring_used * used
Definition virtio-ring.h:67
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
u16 vpm_ioread16(struct virtio_pci_modern_device *vdev, struct virtio_pci_region *region, size_t offset)
Definition virtio-pci.c:204
#define COMMON_OFFSET(field)
Definition virtio-pci.h:239
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 MAX_QUEUE_NUM
Definition virtio-ring.h:26

References vring::avail, virtio_pci_modern_device::common, COMMON_OFFSET, DBG, vring::desc, dma(), vring_virtqueue::dma, EINVAL, ENOENT, vring_virtqueue::map, MAX_QUEUE_NUM, vring_virtqueue::notification, virtio_pci_modern_device::notify_cap_pos, offsetof, virtio_pci_modern_device::pci, pci_read_config_dword(), vring_virtqueue::queue, vring_virtqueue::queue_index, vring_virtqueue::queue_size, size, u16, u32, vring::used, virtio_pci_map_capability(), vp_alloc_vq(), vpm_ioread16(), vpm_iowrite16(), vpm_iowrite64(), vring_virtqueue::vring, and vring_init().

Referenced by virtnet_open_modern().