Lines Matching +full:virtio +full:- +full:pci

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
34 #include <dev/virtio/virtio.h>
35 #include <dev/virtio/virtio_ring.h>
36 #include <dev/virtio/pci/virtio_pci_var.h>
39 * These are derived from several virtio specifications.
42 * https://github.com/rustyrussell/virtio-spec
43 * http://people.redhat.com/pbonzini/virtio-spec.pdf
48 * Each virtqueue uses at least two 4096-byte pages, laid out thus:
50 * +-----------------------------------------------+
52 * | ----------------------------------------- |
54 * | ----------------------------------------- |
56 * +-----------------------------------------------+
58 * | ----------------------------------------- |
60 * +-----------------------------------------------+
63 * limited to no more than 32768 (as it must fit in a 16-bit field).
68 * The <N> 16-byte "desc" descriptors consist of a 64-bit guest
69 * physical address <addr>, a 32-bit length <len>, a 16-bit
70 * <flags>, and a 16-bit <next> field (all in guest byte order).
91 * range [0 .. N) (i.e., the half-open interval). (Inside an
97 * begin with a 16-bit <flags> field and 16-bit index <idx>, then
98 * have <N> 16-bit <ring> values, followed by one final 16-bit
107 * This begins with a 16-bit <flags> and 16-bit <idx>, then there
108 * are <N> "vring_used" elements, followed by a 16-bit <avail_event>.
109 * The <N> "vring_used" elements consist of a 32-bit <id> and a
110 * 32-bit <len> (vu_tlen below). The <id> is simply the index of
117 * avail and used rings (respectively -- note the reversal!), are
120 * negotiation. Similarly, both rings provide a flag --
121 * VRING_AVAIL_F_NO_INTERRUPT and VRING_USED_F_NO_NOTIFY -- in
133 * PCI config space. However, a device that has two or more
135 * The number of queues is determinable via the PCI config space
140 * QNUM is a read-only register containing a nonzero power of two
145 * provides either two -- 0 = receive, 1 = transmit -- or three,
152 * QNOTIFY is effectively write-only: when the guest writes a queue
163 * PCI vendor/device IDs
175 * PCI revision IDs
180 * PCI subvendor IDs
185 * PCI subdevice IDs
189 /* From section 2.3, "Virtqueue Configuration", of the virtio specification */
202 * queues and some size (possibly 0) of configuration-space
205 * virtio_softc is also a pointer to the more specific, derived-
206 * from-virtio driver's softc.
208 * Note: inside each hypervisor virtio driver, changes to these
210 * Except for PCI config space register read/write, we assume each
212 * lock (if there is one) for PCI config space read/write ops.
219 * generic-layer size. (So, drivers can just use the offset as
222 * (The virtio layer also makes sure that the read or write is to/
231 #define VIRTIO_EVENT_IDX 0x02 /* use the event-index values */
238 struct pci_devinst *vs_pi; /* PCI device instance */
243 uint8_t vs_isr; /* ISR flags, if not MSI-X */
244 uint16_t vs_msix_cfg_idx; /* MSI-X vector for config event */
249 if (vs->vs_mtx) \
250 pthread_mutex_lock(vs->vs_mtx); \
255 if (vs->vs_mtx) \
256 pthread_mutex_unlock(vs->vs_mtx); \
262 size_t vc_cfgsize; /* size of dev-specific config regs */
272 uint64_t vc_hv_caps; /* hypervisor-provided capabilities */
284 * vs->vs_vc->vc_reset(); then the data structure below is
285 * reinitialized (for each virtqueue: vs->vs_vc->vc_nvq).
287 * The remaining fields should only be fussed-with by the generic
307 uint16_t vq_last_avail; /* a recent value of vq_avail->idx */
309 uint16_t vq_save_used; /* saved vq_used->idx; see vq_endchains */
310 uint16_t vq_msix_idx; /* MSI-X index, or VIRTIO_MSI_NO_VECTOR */
319 /* as noted above, these are sort of backwards, name-wise */
321 (*(uint16_t *)&(vq)->vq_used->ring[(vq)->vq_qsize])
323 ((vq)->vq_avail->ring[(vq)->vq_qsize])
332 return (vq->vq_flags & VQ_ALLOC); in vq_ring_ready()
343 return (vq_ring_ready(vq) && vq->vq_last_avail != in vq_has_descs()
344 vq->vq_avail->idx); in vq_has_descs()
348 * Deliver an interrupt to the guest for a specific MSI-X queue or
355 if (pci_msix_enabled(vs->vs_pi)) in vi_interrupt()
356 pci_generate_msix(vs->vs_pi, msix_idx); in vi_interrupt()
359 vs->vs_isr |= isr; in vi_interrupt()
360 pci_generate_msi(vs->vs_pi, 0); in vi_interrupt()
361 pci_lintr_assert(vs->vs_pi); in vi_interrupt()
368 * possible, or a generic MSI interrupt if not using MSI-X).
374 vi_interrupt(vs, VIRTIO_PCI_ISR_INTR, vq->vq_msix_idx); in vq_interrupt()
381 vq->vq_used->flags &= ~VRING_USED_F_NO_NOTIFY; in vq_kick_enable()
383 * Full memory barrier to make sure the store to vq_used->flags in vq_kick_enable()
384 * happens before the load from vq_avail->idx, which results from a in vq_kick_enable()
394 vq->vq_used->flags |= VRING_USED_F_NO_NOTIFY; in vq_kick_disable()