iPXE
Macros | Functions
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/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)   (vdev->cfg_cap_pos + offsetof(struct virtio_pci_cfg_cap, field))
 

Functions

static int vp_alloc_vq (struct vring_virtqueue *vq, u16 num)
 
void vp_free_vq (struct vring_virtqueue *vq)
 
int vp_find_vq (unsigned int ioaddr, int queue_index, struct vring_virtqueue *vq)
 
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)
 

Macro Definition Documentation

◆ CFG_POS

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

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

Function Documentation

◆ vp_alloc_vq()

static int vp_alloc_vq ( struct vring_virtqueue vq,
u16  num 
)
static

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

25 {
26  size_t queue_size = PAGE_MASK + vring_size(num);
27  size_t vdata_size = num * sizeof(void *);
28 
29  vq->queue = zalloc(queue_size + vdata_size);
30  if (!vq->queue) {
31  return -ENOMEM;
32  }
33 
34  /* vdata immediately follows the ring */
35  vq->vdata = (void **)(vq->queue + queue_size);
36 
37  return 0;
38 }
unsigned char * queue
Definition: virtio-ring.h:76
#define PAGE_MASK
Page mask.
Definition: io.h:30
#define vring_size(num)
Definition: virtio-ring.h:69
#define ENOMEM
Not enough space.
Definition: errno.h:534
char unsigned long * num
Definition: xenstore.h:17
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624

References ENOMEM, num, PAGE_MASK, vring_virtqueue::queue, vring_virtqueue::vdata, vring_size, and zalloc().

Referenced by vp_find_vq(), and vpm_find_vqs().

◆ vp_free_vq()

void vp_free_vq ( struct vring_virtqueue vq)

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

41 {
42  if (vq->queue) {
43  free(vq->queue);
44  vq->queue = NULL;
45  vq->vdata = NULL;
46  }
47 }
unsigned char * queue
Definition: virtio-ring.h:76
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

References free, NULL, vring_virtqueue::queue, 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 
)

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

51 {
52  struct vring * vr = &vq->vring;
53  u16 num;
54  int rc;
55 
56  /* select the queue */
57 
58  outw(queue_index, ioaddr + VIRTIO_PCI_QUEUE_SEL);
59 
60  /* check if the queue is available */
61 
63  if (!num) {
64  DBG("VIRTIO-PCI ERROR: queue size is 0\n");
65  return -1;
66  }
67 
68  /* check if the queue is already active */
69 
71  DBG("VIRTIO-PCI ERROR: queue already active\n");
72  return -1;
73  }
74 
75  vq->queue_index = queue_index;
76 
77  /* initialize the queue */
78  rc = vp_alloc_vq(vq, num);
79  if (rc) {
80  DBG("VIRTIO-PCI ERROR: failed to allocate queue memory\n");
81  return rc;
82  }
83  vring_init(vr, num, vq->queue);
84 
85  /* activate the queue
86  *
87  * NOTE: vr->desc is initialized by vring_init()
88  */
89 
90  outl((unsigned long)virt_to_phys(vr->desc) >> PAGE_SHIFT,
92 
93  return num;
94 }
uint16_t u16
Definition: stdint.h:21
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
unsigned char * queue
Definition: virtio-ring.h:76
uint16_t inw(volatile uint16_t *io_addr)
Read 16-bit word from I/O-mapped device.
struct vring vring
Definition: virtio-ring.h:77
#define PAGE_SHIFT
Page shift.
Definition: x86_io.h:32
#define outw(data, io_addr)
Definition: io.h:319
static void vring_init(struct vring *vr, unsigned int num, unsigned char *queue)
Definition: virtio-ring.h:91
static __always_inline unsigned long virt_to_phys(volatile const void *addr)
Convert virtual address to a physical address.
Definition: uaccess.h:287
#define VIRTIO_PCI_QUEUE_PFN
Definition: virtio-pci.h:11
static unsigned long ioaddr
Definition: davicom.c:129
char unsigned long * num
Definition: xenstore.h:17
#define VIRTIO_PCI_QUEUE_SEL
Definition: virtio-pci.h:17
#define outl(data, io_addr)
Definition: io.h:329
static int vp_alloc_vq(struct vring_virtqueue *vq, u16 num)
Definition: virtio-pci.c:24
struct vring_desc * desc
Definition: virtio-ring.h:64
#define VIRTIO_PCI_QUEUE_NUM
Definition: virtio-pci.h:14
uint32_t inl(volatile uint32_t *io_addr)
Read 32-bit dword from I/O-mapped device.
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498

References DBG, vring::desc, inl(), inw(), ioaddr, num, outl, outw, PAGE_SHIFT, vring_virtqueue::queue, vring_virtqueue::queue_index, rc, virt_to_phys(), 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()

static 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 99 of file virtio-pci.c.

102 {
103  pci_write_config_byte(vdev->pci, CFG_POS(vdev, cap.bar), region->bar);
104  pci_write_config_dword(vdev->pci, CFG_POS(vdev, cap.length), length);
105  pci_write_config_dword(vdev->pci, CFG_POS(vdev, cap.offset),
106  (intptr_t)(region->base + offset));
107 }
uint16_t length
Length.
Definition: intel.h:14
struct pci_device * pci
Definition: virtio-pci.h:120
unsigned long intptr_t
Definition: stdint.h:21
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
#define CFG_POS(vdev, field)
Definition: virtio-pci.c:96
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.

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

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 109 of file virtio-pci.c.

111 {
112  switch (region->flags & VIRTIO_PCI_REGION_TYPE_MASK) {
114  writeb(data, region->base + offset);
115  break;
117  outb(data, region->base + offset);
118  break;
120  prep_pci_cfg_cap(vdev, region, offset, 1);
121  pci_write_config_byte(vdev->pci, CFG_POS(vdev, pci_cfg_data), data);
122  break;
123  default:
124  assert(0);
125  break;
126  }
127 }
struct pci_device * pci
Definition: virtio-pci.h:120
#define VIRTIO_PCI_REGION_PCI_CONFIG
Definition: virtio-pci.h:114
#define VIRTIO_PCI_REGION_MEMORY
Definition: virtio-pci.h:110
void writeb(uint8_t data, volatile uint8_t *io_addr)
Write byte to memory-mapped device.
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
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:99
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
#define CFG_POS(vdev, field)
Definition: virtio-pci.c:96
int pci_write_config_byte(struct pci_device *pci, unsigned int where, uint8_t value)
Write byte to PCI configuration space.
#define VIRTIO_PCI_REGION_TYPE_MASK
Definition: virtio-pci.h:108
#define outb(data, io_addr)
Definition: io.h:309
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
#define VIRTIO_PCI_REGION_PORT
Definition: virtio-pci.h:112

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(), 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 129 of file virtio-pci.c.

131 {
132  data = cpu_to_le16(data);
133  switch (region->flags & VIRTIO_PCI_REGION_TYPE_MASK) {
135  writew(data, region->base + offset);
136  break;
138  outw(data, region->base + offset);
139  break;
141  prep_pci_cfg_cap(vdev, region, offset, 2);
142  pci_write_config_word(vdev->pci, CFG_POS(vdev, pci_cfg_data), data);
143  break;
144  default:
145  assert(0);
146  break;
147  }
148 }
struct pci_device * pci
Definition: virtio-pci.h:120
#define VIRTIO_PCI_REGION_PCI_CONFIG
Definition: virtio-pci.h:114
#define VIRTIO_PCI_REGION_MEMORY
Definition: virtio-pci.h:110
#define outw(data, io_addr)
Definition: io.h:319
int pci_write_config_word(struct pci_device *pci, unsigned int where, uint16_t value)
Write 16-bit word to PCI configuration space.
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
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:99
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
#define CFG_POS(vdev, field)
Definition: virtio-pci.c:96
#define VIRTIO_PCI_REGION_TYPE_MASK
Definition: virtio-pci.h:108
#define writew
Definition: w89c840.c:159
#define cpu_to_le16(value)
Definition: byteswap.h:106
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
#define VIRTIO_PCI_REGION_PORT
Definition: virtio-pci.h:112

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(), 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 150 of file virtio-pci.c.

152 {
153  data = cpu_to_le32(data);
154  switch (region->flags & VIRTIO_PCI_REGION_TYPE_MASK) {
156  writel(data, region->base + offset);
157  break;
159  outl(data, region->base + offset);
160  break;
162  prep_pci_cfg_cap(vdev, region, offset, 4);
163  pci_write_config_dword(vdev->pci, CFG_POS(vdev, pci_cfg_data), data);
164  break;
165  default:
166  assert(0);
167  break;
168  }
169 }
struct pci_device * pci
Definition: virtio-pci.h:120
#define VIRTIO_PCI_REGION_PCI_CONFIG
Definition: virtio-pci.h:114
#define VIRTIO_PCI_REGION_MEMORY
Definition: virtio-pci.h:110
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
void writel(uint32_t data, volatile uint32_t *io_addr)
Write 32-bit dword to memory-mapped device.
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:99
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
#define cpu_to_le32(value)
Definition: byteswap.h:107
#define CFG_POS(vdev, field)
Definition: virtio-pci.c:96
#define outl(data, io_addr)
Definition: io.h:329
#define VIRTIO_PCI_REGION_TYPE_MASK
Definition: virtio-pci.h:108
int pci_write_config_dword(struct pci_device *pci, unsigned int where, uint32_t value)
Write 32-bit dword to PCI configuration space.
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
#define VIRTIO_PCI_REGION_PORT
Definition: virtio-pci.h:112

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(), 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 171 of file virtio-pci.c.

173 {
174  uint8_t data;
175  switch (region->flags & VIRTIO_PCI_REGION_TYPE_MASK) {
177  data = readb(region->base + offset);
178  break;
180  data = inb(region->base + offset);
181  break;
183  prep_pci_cfg_cap(vdev, region, offset, 1);
184  pci_read_config_byte(vdev->pci, CFG_POS(vdev, pci_cfg_data), &data);
185  break;
186  default:
187  assert(0);
188  data = 0;
189  break;
190  }
191  return data;
192 }
struct pci_device * pci
Definition: virtio-pci.h:120
uint8_t readb(volatile uint8_t *io_addr)
Read byte from memory-mapped device.
#define VIRTIO_PCI_REGION_PCI_CONFIG
Definition: virtio-pci.h:114
#define VIRTIO_PCI_REGION_MEMORY
Definition: virtio-pci.h:110
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
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:99
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
#define CFG_POS(vdev, field)
Definition: virtio-pci.c:96
#define VIRTIO_PCI_REGION_TYPE_MASK
Definition: virtio-pci.h:108
unsigned char uint8_t
Definition: stdint.h:10
uint8_t inb(volatile uint8_t *io_addr)
Read byte from I/O-mapped device.
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
#define VIRTIO_PCI_REGION_PORT
Definition: virtio-pci.h:112
int pci_read_config_byte(struct pci_device *pci, unsigned int where, uint8_t *value)
Read byte from PCI configuration space.

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(), 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 194 of file virtio-pci.c.

196 {
197  uint16_t data;
198  switch (region->flags & VIRTIO_PCI_REGION_TYPE_MASK) {
200  data = readw(region->base + offset);
201  break;
203  data = inw(region->base + offset);
204  break;
206  prep_pci_cfg_cap(vdev, region, offset, 2);
207  pci_read_config_word(vdev->pci, CFG_POS(vdev, pci_cfg_data), &data);
208  break;
209  default:
210  assert(0);
211  data = 0;
212  break;
213  }
214  return le16_to_cpu(data);
215 }
struct pci_device * pci
Definition: virtio-pci.h:120
unsigned short uint16_t
Definition: stdint.h:11
#define VIRTIO_PCI_REGION_PCI_CONFIG
Definition: virtio-pci.h:114
uint16_t inw(volatile uint16_t *io_addr)
Read 16-bit word from I/O-mapped device.
#define VIRTIO_PCI_REGION_MEMORY
Definition: virtio-pci.h:110
uint16_t readw(volatile uint16_t *io_addr)
Read 16-bit word from memory-mapped device.
int pci_read_config_word(struct pci_device *pci, unsigned int where, uint16_t *value)
Read 16-bit word from PCI configuration space.
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
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:99
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
#define CFG_POS(vdev, field)
Definition: virtio-pci.c:96
#define VIRTIO_PCI_REGION_TYPE_MASK
Definition: virtio-pci.h:108
#define le16_to_cpu(value)
Definition: byteswap.h:112
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
#define VIRTIO_PCI_REGION_PORT
Definition: virtio-pci.h:112

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(), 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 217 of file virtio-pci.c.

219 {
220  uint32_t data;
221  switch (region->flags & VIRTIO_PCI_REGION_TYPE_MASK) {
223  data = readw(region->base + offset);
224  break;
226  data = inw(region->base + offset);
227  break;
229  prep_pci_cfg_cap(vdev, region, offset, 4);
230  pci_read_config_dword(vdev->pci, CFG_POS(vdev, pci_cfg_data), &data);
231  break;
232  default:
233  assert(0);
234  data = 0;
235  break;
236  }
237  return le32_to_cpu(data);
238 }
struct pci_device * pci
Definition: virtio-pci.h:120
#define VIRTIO_PCI_REGION_PCI_CONFIG
Definition: virtio-pci.h:114
uint16_t inw(volatile uint16_t *io_addr)
Read 16-bit word from I/O-mapped device.
#define le32_to_cpu(value)
Definition: byteswap.h:113
#define VIRTIO_PCI_REGION_MEMORY
Definition: virtio-pci.h:110
uint16_t readw(volatile uint16_t *io_addr)
Read 16-bit word from memory-mapped device.
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
int pci_read_config_dword(struct pci_device *pci, unsigned int where, uint32_t *value)
Read 32-bit dword from PCI configuration space.
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:99
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
#define CFG_POS(vdev, field)
Definition: virtio-pci.c:96
#define VIRTIO_PCI_REGION_TYPE_MASK
Definition: virtio-pci.h:108
unsigned int uint32_t
Definition: stdint.h:12
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
#define VIRTIO_PCI_REGION_PORT
Definition: virtio-pci.h:112

References assert(), virtio_pci_region::base, CFG_POS, data, virtio_pci_region::flags, inw(), le32_to_cpu, offset, virtio_pci_modern_device::pci, pci_read_config_dword(), prep_pci_cfg_cap(), readw(), 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 240 of file virtio-pci.c.

241 {
242  int pos;
243  uint8_t type, bar;
244 
245  for (pos = pci_find_capability(pci, PCI_CAP_ID_VNDR);
246  pos > 0;
247  pos = pci_find_next_capability(pci, pos, PCI_CAP_ID_VNDR)) {
248 
249  pci_read_config_byte(pci, pos + offsetof(struct virtio_pci_cap,
250  cfg_type), &type);
251  pci_read_config_byte(pci, pos + offsetof(struct virtio_pci_cap,
252  bar), &bar);
253 
254  /* Ignore structures with reserved BAR values */
255  if (bar > 0x5) {
256  continue;
257  }
258 
259  if (type == cfg_type) {
260  return pos;
261  }
262  }
263  return 0;
264 }
int pci_find_capability(struct pci_device *pci, int cap)
Look for a PCI capability.
Definition: pciextra.c:36
uint8_t type
Type.
Definition: ena.h:16
#define PCI_CAP_ID_VNDR
Vendor-specific.
Definition: pci.h:95
#define offsetof(type, field)
Get offset of a field within a structure.
Definition: stddef.h:24
int pci_find_next_capability(struct pci_device *pci, int pos, int cap)
Look for another PCI capability.
Definition: pciextra.c:73
unsigned char uint8_t
Definition: stdint.h:10
int pci_read_config_byte(struct pci_device *pci, unsigned int where, uint8_t *value)
Read byte from PCI configuration space.

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 266 of file virtio-pci.c.

269 {
270  u8 bar;
271  u32 offset, length, base_raw;
272  unsigned long base;
273 
274  pci_read_config_byte(pci, cap + offsetof(struct virtio_pci_cap, bar), &bar);
276  &offset);
278  &length);
279 
280  if (length <= start) {
281  DBG("VIRTIO-PCI bad capability len %d (>%d expected)\n", length, start);
282  return -EINVAL;
283  }
284  if (length - start < minlen) {
285  DBG("VIRTIO-PCI bad capability len %d (>=%zd expected)\n", length, minlen);
286  return -EINVAL;
287  }
288  length -= start;
289  if (start + offset < offset) {
290  DBG("VIRTIO-PCI map wrap-around %d+%d\n", start, offset);
291  return -EINVAL;
292  }
293  offset += start;
294  if (offset & (align - 1)) {
295  DBG("VIRTIO-PCI offset %d not aligned to %d\n", offset, align);
296  return -EINVAL;
297  }
298  if (length > size) {
299  length = size;
300  }
301 
302  if (minlen + offset < minlen ||
303  minlen + offset > pci_bar_size(pci, PCI_BASE_ADDRESS(bar))) {
304  DBG("VIRTIO-PCI map virtio %zd@%d out of range on bar %i length %ld\n",
305  minlen, offset,
306  bar, pci_bar_size(pci, PCI_BASE_ADDRESS(bar)));
307  return -EINVAL;
308  }
309 
310  region->base = NULL;
311  region->length = length;
312  region->bar = bar;
313 
314  base = pci_bar_start(pci, PCI_BASE_ADDRESS(bar));
315  if (base) {
316  pci_read_config_dword(pci, PCI_BASE_ADDRESS(bar), &base_raw);
317 
318  if (base_raw & PCI_BASE_ADDRESS_SPACE_IO) {
319  /* Region accessed using port I/O */
320  region->base = (void *)(base + offset);
321  region->flags = VIRTIO_PCI_REGION_PORT;
322  } else {
323  /* Region mapped into memory space */
324  region->base = ioremap(base + offset, length);
326  }
327  }
328  if (!region->base) {
329  /* Region accessed via PCI config space window */
330  region->base = (void *)(intptr_t)offset;
332  }
333  return 0;
334 }
uint16_t length
Length.
Definition: intel.h:14
#define EINVAL
Invalid argument.
Definition: errno.h:428
#define VIRTIO_PCI_REGION_PCI_CONFIG
Definition: virtio-pci.h:114
#define VIRTIO_PCI_REGION_MEMORY
Definition: virtio-pci.h:110
#define offsetof(type, field)
Get offset of a field within a structure.
Definition: stddef.h:24
unsigned long intptr_t
Definition: stdint.h:21
#define PCI_BASE_ADDRESS(n)
PCI base address registers.
Definition: pci.h:60
uint32_t start
Starting offset.
Definition: netvsc.h:12
int pci_read_config_dword(struct pci_device *pci, unsigned int where, uint32_t *value)
Read 32-bit dword from PCI configuration space.
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
unsigned long pci_bar_start(struct pci_device *pci, unsigned int reg)
Find the start of a PCI BAR.
Definition: pci.c:96
unsigned long pci_bar_size(struct pci_device *pci, unsigned int reg)
Find the size of a PCI BAR.
Definition: pciextra.c:90
uint16_t base
Base address.
Definition: edd.h:14
#define PCI_BASE_ADDRESS_SPACE_IO
I/O BAR.
Definition: pci.h:67
uint8_t size
Entry size (in 32-bit words)
Definition: ena.h:16
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
void * ioremap(unsigned long bus_addr, size_t len)
Map bus address as an I/O address.
#define VIRTIO_PCI_REGION_PORT
Definition: virtio-pci.h:112
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
uint8_t u8
Definition: stdint.h:19
uint32_t u32
Definition: stdint.h:23
int pci_read_config_byte(struct pci_device *pci, unsigned int where, uint8_t *value)
Read byte from PCI configuration space.

References virtio_pci_region::bar, base, virtio_pci_region::base, DBG, EINVAL, virtio_pci_region::flags, ioremap(), length, virtio_pci_region::length, NULL, offset, offsetof, pci_bar_size(), pci_bar_start(), PCI_BASE_ADDRESS, PCI_BASE_ADDRESS_SPACE_IO, pci_read_config_byte(), pci_read_config_dword(), size, start, 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 336 of file virtio-pci.c.

337 {
338  unsigned region_type = region->flags & VIRTIO_PCI_REGION_TYPE_MASK;
339  if (region_type == VIRTIO_PCI_REGION_MEMORY) {
340  iounmap(region->base);
341  }
342 }
#define VIRTIO_PCI_REGION_MEMORY
Definition: virtio-pci.h:110
#define VIRTIO_PCI_REGION_TYPE_MASK
Definition: virtio-pci.h:108
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 344 of file virtio-pci.c.

346 {
347  vpm_iowrite16(vdev, &vq->notification, (u16)vq->queue_index, 0);
348 }
uint16_t u16
Definition: stdint.h:21
struct virtio_pci_region notification
Definition: virtio-ring.h:83
void vpm_iowrite16(struct virtio_pci_modern_device *vdev, struct virtio_pci_region *region, u16 data, size_t offset)
Definition: virtio-pci.c:129

References vring_virtqueue::notification, vring_virtqueue::queue_index, 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 
)

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

352 {
353  unsigned i;
354  struct vring_virtqueue *vq;
355  u16 size, off;
356  u32 notify_offset_multiplier;
357  int err;
358 
359  if (nvqs > vpm_ioread16(vdev, &vdev->common, COMMON_OFFSET(num_queues))) {
360  return -ENOENT;
361  }
362 
363  /* Read notify_off_multiplier from config space. */
366  notify_off_multiplier),
367  &notify_offset_multiplier);
368 
369  for (i = 0; i < nvqs; i++) {
370  /* Select the queue we're interested in */
371  vpm_iowrite16(vdev, &vdev->common, (u16)i, COMMON_OFFSET(queue_select));
372 
373  /* Check if queue is either not available or already active. */
374  size = vpm_ioread16(vdev, &vdev->common, COMMON_OFFSET(queue_size));
375  /* QEMU has a bug where queues don't revert to inactive on device
376  * reset. Skip checking the queue_enable field until it is fixed.
377  */
378  if (!size /*|| vpm_ioread16(vdev, &vdev->common.queue_enable)*/)
379  return -ENOENT;
380 
381  if (size & (size - 1)) {
382  DBG("VIRTIO-PCI %p: bad queue size %d\n", vdev, size);
383  return -EINVAL;
384  }
385 
386  if (size > MAX_QUEUE_NUM) {
387  /* iPXE networking tends to be not perf critical so there's no
388  * need to accept large queue sizes.
389  */
391  }
392 
393  vq = &vqs[i];
394  vq->queue_index = i;
395 
396  /* get offset of notification word for this vq */
397  off = vpm_ioread16(vdev, &vdev->common, COMMON_OFFSET(queue_notify_off));
398 
399  err = vp_alloc_vq(vq, size);
400  if (err) {
401  DBG("VIRTIO-PCI %p: failed to allocate queue memory\n", vdev);
402  return err;
403  }
404  vring_init(&vq->vring, size, vq->queue);
405 
406  /* activate the queue */
407  vpm_iowrite16(vdev, &vdev->common, size, COMMON_OFFSET(queue_size));
408 
409  vpm_iowrite64(vdev, &vdev->common, virt_to_phys(vq->vring.desc),
410  COMMON_OFFSET(queue_desc_lo),
411  COMMON_OFFSET(queue_desc_hi));
412  vpm_iowrite64(vdev, &vdev->common, virt_to_phys(vq->vring.avail),
413  COMMON_OFFSET(queue_avail_lo),
414  COMMON_OFFSET(queue_avail_hi));
415  vpm_iowrite64(vdev, &vdev->common, virt_to_phys(vq->vring.used),
416  COMMON_OFFSET(queue_used_lo),
417  COMMON_OFFSET(queue_used_hi));
418 
419  err = virtio_pci_map_capability(vdev->pci,
420  vdev->notify_cap_pos, 2, 2,
421  off * notify_offset_multiplier, 2,
422  &vq->notification);
423  if (err) {
424  return err;
425  }
426  }
427 
428  /* Select and activate all queues. Has to be done last: once we do
429  * this, there's no way to go back except reset.
430  */
431  for (i = 0; i < nvqs; i++) {
432  vq = &vqs[i];
433  vpm_iowrite16(vdev, &vdev->common, (u16)vq->queue_index,
434  COMMON_OFFSET(queue_select));
435  vpm_iowrite16(vdev, &vdev->common, 1, COMMON_OFFSET(queue_enable));
436  }
437  return 0;
438 }
uint16_t u16
Definition: stdint.h:21
#define EINVAL
Invalid argument.
Definition: errno.h:428
struct pci_device * pci
Definition: virtio-pci.h:120
unsigned char * queue
Definition: virtio-ring.h:76
struct vring vring
Definition: virtio-ring.h:77
struct vring_avail * avail
Definition: virtio-ring.h:65
#define ENOENT
No such file or directory.
Definition: errno.h:514
u16 vpm_ioread16(struct virtio_pci_modern_device *vdev, struct virtio_pci_region *region, size_t offset)
Definition: virtio-pci.c:194
#define offsetof(type, field)
Get offset of a field within a structure.
Definition: stddef.h:24
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:266
static void vring_init(struct vring *vr, unsigned int num, unsigned char *queue)
Definition: virtio-ring.h:91
static __always_inline unsigned long virt_to_phys(volatile const void *addr)
Convert virtual address to a physical address.
Definition: uaccess.h:287
int pci_read_config_dword(struct pci_device *pci, unsigned int where, uint32_t *value)
Read 32-bit dword from PCI configuration space.
#define MAX_QUEUE_NUM
Definition: virtio-ring.h:25
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:217
#define COMMON_OFFSET(field)
Definition: virtio-pci.h:236
struct virtio_pci_region notification
Definition: virtio-ring.h:83
struct virtio_pci_region common
Definition: virtio-pci.h:126
static int vp_alloc_vq(struct vring_virtqueue *vq, u16 num)
Definition: virtio-pci.c:24
struct vring_desc * desc
Definition: virtio-ring.h:64
uint8_t size
Entry size (in 32-bit words)
Definition: ena.h:16
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
struct vring_used * used
Definition: virtio-ring.h:66
uint32_t u32
Definition: stdint.h:23
void vpm_iowrite16(struct virtio_pci_modern_device *vdev, struct virtio_pci_region *region, u16 data, size_t offset)
Definition: virtio-pci.c:129

References vring::avail, virtio_pci_modern_device::common, COMMON_OFFSET, DBG, vring::desc, EINVAL, ENOENT, 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, size, vring::used, virt_to_phys(), virtio_pci_map_capability(), vp_alloc_vq(), vpm_ioread16(), vpm_iowrite16(), vpm_iowrite64(), vring_virtqueue::vring, and vring_init().

Referenced by virtnet_open_modern().