Page MenuHomeFreeBSD

D28947.id84758.diff
No OneTemporary

D28947.id84758.diff

Index: sys/dev/virtio/pci/virtio_pci_modern.c
===================================================================
--- sys/dev/virtio/pci/virtio_pci_modern.c
+++ sys/dev/virtio/pci/virtio_pci_modern.c
@@ -146,6 +146,11 @@
static void vtpci_modern_probe_and_attach_child(struct vtpci_modern_softc *);
+static void vtpci_modern_read_dev_common(device_t dev, bus_size_t offset,
+ void *dst, int length);
+static void vtpci_modern_write_dev_common(device_t dev, bus_size_t offset,
+ void *src, int length);
+
static uint64_t vtpci_modern_read_features(struct vtpci_modern_softc *);
static void vtpci_modern_write_features(struct vtpci_modern_softc *,
uint64_t);
@@ -167,8 +172,6 @@
bus_size_t, uint16_t);
static void vtpci_modern_write_common_4(struct vtpci_modern_softc *,
bus_size_t, uint32_t);
-static void vtpci_modern_write_common_8(struct vtpci_modern_softc *,
- bus_size_t, uint64_t);
static void vtpci_modern_write_notify_2(struct vtpci_modern_softc *,
bus_size_t, uint16_t);
static uint8_t vtpci_modern_read_isr_1(struct vtpci_modern_softc *,
@@ -487,12 +490,13 @@
static uint64_t
vtpci_modern_read_features(struct vtpci_modern_softc *sc)
{
- uint32_t features0, features1;
+ uint32_t features0, features1, val = 0;
- vtpci_modern_write_common_4(sc, VIRTIO_PCI_COMMON_DFSELECT, 0);
- features0 = vtpci_modern_read_common_4(sc, VIRTIO_PCI_COMMON_DF);
- vtpci_modern_write_common_4(sc, VIRTIO_PCI_COMMON_DFSELECT, 1);
- features1 = vtpci_modern_read_common_4(sc, VIRTIO_PCI_COMMON_DF);
+ vtpci_modern_write_dev_common(sc->vtpci_dev, VIRTIO_PCI_COMMON_DFSELECT, &val, 4);
+ vtpci_modern_read_dev_common(sc->vtpci_dev, VIRTIO_PCI_COMMON_DF, &features0, 4);
+ val = 1;
+ vtpci_modern_write_dev_common(sc->vtpci_dev, VIRTIO_PCI_COMMON_DFSELECT, &val, 4);
+ vtpci_modern_read_dev_common(sc->vtpci_dev, VIRTIO_PCI_COMMON_DF, &features1, 4);
return (((uint64_t) features1 << 32) | features0);
}
@@ -500,15 +504,16 @@
static void
vtpci_modern_write_features(struct vtpci_modern_softc *sc, uint64_t features)
{
- uint32_t features0, features1;
+ uint32_t features0, features1, val = 0;
features0 = features;
features1 = features >> 32;
- vtpci_modern_write_common_4(sc, VIRTIO_PCI_COMMON_GFSELECT, 0);
- vtpci_modern_write_common_4(sc, VIRTIO_PCI_COMMON_GF, features0);
- vtpci_modern_write_common_4(sc, VIRTIO_PCI_COMMON_GFSELECT, 1);
- vtpci_modern_write_common_4(sc, VIRTIO_PCI_COMMON_GF, features1);
+ vtpci_modern_write_dev_common(sc->vtpci_dev, VIRTIO_PCI_COMMON_GFSELECT, &val, 4);
+ vtpci_modern_write_dev_common(sc->vtpci_dev, VIRTIO_PCI_COMMON_GF, &features0, 4);
+ val = 1;
+ vtpci_modern_write_dev_common(sc->vtpci_dev, VIRTIO_PCI_COMMON_GFSELECT, &val, 4);
+ vtpci_modern_write_dev_common(sc->vtpci_dev, VIRTIO_PCI_COMMON_GF, &features1, 4);
}
static int
@@ -522,7 +527,8 @@
sc = device_get_softc(dev);
cn = &sc->vtpci_common;
- max_nvqs = vtpci_modern_read_common_2(sc, VIRTIO_PCI_COMMON_NUMQ);
+ vtpci_modern_read_dev_common(sc->vtpci_dev, VIRTIO_PCI_COMMON_NUMQ, &max_nvqs, 2);
+
if (nvqs > max_nvqs) {
device_printf(sc->vtpci_dev, "requested virtqueue count %d "
"exceeds max %d\n", nvqs, max_nvqs);
@@ -650,6 +656,80 @@
return (gen);
}
+static void
+vtpci_modern_read_dev_common(device_t dev, bus_size_t offset, void *dst,
+ int length)
+{
+ struct vtpci_modern_softc *sc;
+
+ sc = device_get_softc(dev);
+
+ if (sc->vtpci_common_res_map.vtrm_map.r_size == 0) {
+ panic("%s: attempt to read dev common but not present",
+ __func__);
+ }
+
+ switch (length) {
+ case 1:
+ *(uint8_t *) dst = vtpci_modern_read_common_1(sc, offset);
+ break;
+ case 2:
+ *(uint16_t *) dst = virtio_htog16(true,
+ vtpci_modern_read_common_2(sc, offset));
+ break;
+ case 4:
+ *(uint32_t *) dst = virtio_htog32(true,
+ vtpci_modern_read_common_4(sc, offset));
+ break;
+ default:
+ panic("%s: device %s invalid common read length %d offset %d",
+ __func__, device_get_nameunit(dev), length, (int) offset);
+ }
+}
+
+static void
+vtpci_modern_write_dev_common(device_t dev, bus_size_t offset, void *src,
+ int length)
+{
+ struct vtpci_modern_softc *sc;
+
+ sc = device_get_softc(dev);
+
+ if (sc->vtpci_common_res_map.vtrm_map.r_size == 0) {
+ panic("%s: attempt to write dev common but not present",
+ __func__);
+ }
+
+ switch (length) {
+ case 1:
+ vtpci_modern_write_common_1(sc, offset, *(uint8_t *) src);
+ break;
+ case 2: {
+ uint16_t val = virtio_gtoh16(true, *(uint16_t *) src);
+ vtpci_modern_write_common_2(sc, offset, val);
+ break;
+ }
+ case 4: {
+ uint32_t val = virtio_gtoh32(true, *(uint32_t *) src);
+ vtpci_modern_write_common_4(sc, offset, val);
+ break;
+ }
+ case 8: {
+ uint32_t val0, val1;
+ val0 = *(uint64_t *) src;
+ val1 = (*(uint64_t *) src) >> 32;
+ vtpci_modern_write_common_4(sc, offset, virtio_gtoh32(true, val0));
+ vtpci_modern_write_common_4(sc, offset + 4, virtio_gtoh32(true, val1));
+ break;
+ }
+ default:
+ panic("%s: device %s invalid common write length %d offset %d",
+ __func__, device_get_nameunit(dev), length, (int) offset);
+ }
+}
+
+
+
static void
vtpci_modern_read_dev_config(device_t dev, bus_size_t offset, void *dst,
int length)
@@ -1160,7 +1240,7 @@
vtpci_modern_register_msix(struct vtpci_modern_softc *sc, int offset,
struct vtpci_interrupt *intr)
{
- uint16_t vector;
+ uint16_t vector, val;
if (intr != NULL) {
/* Map from guest rid to host vector. */
@@ -1168,8 +1248,9 @@
} else
vector = VIRTIO_MSI_NO_VECTOR;
- vtpci_modern_write_common_2(sc, offset, vector);
- return (vtpci_modern_read_common_2(sc, offset) == vector ? 0 : ENODEV);
+ vtpci_modern_write_dev_common(sc->vtpci_dev, offset, &vector, 2);
+ vtpci_modern_read_dev_common(sc->vtpci_dev, offset, &val, 2);
+ return (val == vector ? 0 : ENODEV);
}
static int
@@ -1227,7 +1308,8 @@
static void
vtpci_modern_select_virtqueue(struct vtpci_modern_softc *sc, int idx)
{
- vtpci_modern_write_common_2(sc, VIRTIO_PCI_COMMON_Q_SELECT, idx);
+ uint16_t uint16_idx = (uint16_t) idx;
+ vtpci_modern_write_dev_common(sc->vtpci_dev, VIRTIO_PCI_COMMON_Q_SELECT, &uint16_idx, 2);
}
static uint8_t
@@ -1240,11 +1322,12 @@
vtpci_modern_get_vq_size(device_t dev, int idx)
{
struct vtpci_modern_softc *sc;
+ uint16_t vtq_size;
sc = device_get_softc(dev);
-
vtpci_modern_select_virtqueue(sc, idx);
- return (vtpci_modern_read_common_2(sc, VIRTIO_PCI_COMMON_Q_SIZE));
+ vtpci_modern_read_dev_common(dev, VIRTIO_PCI_COMMON_Q_SIZE, &vtq_size, 2);
+ return vtq_size;
}
static bus_size_t
@@ -1256,7 +1339,7 @@
sc = device_get_softc(dev);
vtpci_modern_select_virtqueue(sc, idx);
- q_notify_off = vtpci_modern_read_common_2(sc, VIRTIO_PCI_COMMON_Q_NOFF);
+ vtpci_modern_read_dev_common(dev, VIRTIO_PCI_COMMON_Q_NOFF, &q_notify_off, 2);
return (q_notify_off * sc->vtpci_notify_offset_multiplier);
}
@@ -1265,44 +1348,48 @@
vtpci_modern_set_vq(device_t dev, struct virtqueue *vq)
{
struct vtpci_modern_softc *sc;
+ uint16_t vtq_size;
+ uint64_t addr;
sc = device_get_softc(dev);
vtpci_modern_select_virtqueue(sc, virtqueue_index(vq));
/* BMV: Currently we never adjust the device's proposed VQ size. */
- vtpci_modern_write_common_2(sc,
- VIRTIO_PCI_COMMON_Q_SIZE, virtqueue_size(vq));
+ vtq_size = virtqueue_size(vq);
+ vtpci_modern_write_dev_common(sc->vtpci_dev, VIRTIO_PCI_COMMON_Q_SIZE, &vtq_size, 2);
- vtpci_modern_write_common_8(sc,
- VIRTIO_PCI_COMMON_Q_DESCLO, virtqueue_desc_paddr(vq));
- vtpci_modern_write_common_8(sc,
- VIRTIO_PCI_COMMON_Q_AVAILLO, virtqueue_avail_paddr(vq));
- vtpci_modern_write_common_8(sc,
- VIRTIO_PCI_COMMON_Q_USEDLO, virtqueue_used_paddr(vq));
+ addr = virtqueue_desc_paddr(vq);
+ vtpci_modern_write_dev_common(sc->vtpci_dev, VIRTIO_PCI_COMMON_Q_DESCLO, &addr, 8);
+ addr = virtqueue_avail_paddr(vq);
+ vtpci_modern_write_dev_common(sc->vtpci_dev, VIRTIO_PCI_COMMON_Q_AVAILLO, &addr, 8);
+ addr = virtqueue_used_paddr(vq);
+ vtpci_modern_write_dev_common(sc->vtpci_dev, VIRTIO_PCI_COMMON_Q_USEDLO, &addr, 8);
}
static void
vtpci_modern_disable_vq(device_t dev, int idx)
{
struct vtpci_modern_softc *sc;
+ uint64_t addr = 0ULL;
sc = device_get_softc(dev);
vtpci_modern_select_virtqueue(sc, idx);
- vtpci_modern_write_common_8(sc, VIRTIO_PCI_COMMON_Q_DESCLO, 0ULL);
- vtpci_modern_write_common_8(sc, VIRTIO_PCI_COMMON_Q_AVAILLO, 0ULL);
- vtpci_modern_write_common_8(sc, VIRTIO_PCI_COMMON_Q_USEDLO, 0ULL);
+ vtpci_modern_write_dev_common(sc->vtpci_dev, VIRTIO_PCI_COMMON_Q_DESCLO, &addr, 8);
+ vtpci_modern_write_dev_common(sc->vtpci_dev, VIRTIO_PCI_COMMON_Q_AVAILLO, &addr, 8);
+ vtpci_modern_write_dev_common(sc->vtpci_dev, VIRTIO_PCI_COMMON_Q_USEDLO, &addr, 8);
}
static void
vtpci_modern_enable_virtqueues(struct vtpci_modern_softc *sc)
{
int idx;
+ uint16_t enable = 1;
for (idx = 0; idx < sc->vtpci_common.vtpci_nvqs; idx++) {
vtpci_modern_select_virtqueue(sc, idx);
- vtpci_modern_write_common_2(sc, VIRTIO_PCI_COMMON_Q_ENABLE, 1);
+ vtpci_modern_write_dev_common(sc->vtpci_dev, VIRTIO_PCI_COMMON_Q_ENABLE, &enable, 2);
}
}
@@ -1345,19 +1432,6 @@
bus_write_4(&sc->vtpci_common_res_map.vtrm_map, off, val);
}
-static void
-vtpci_modern_write_common_8(struct vtpci_modern_softc *sc, bus_size_t off,
- uint64_t val)
-{
- uint32_t val0, val1;
-
- val0 = (uint32_t) val;
- val1 = val >> 32;
-
- vtpci_modern_write_common_4(sc, off, val0);
- vtpci_modern_write_common_4(sc, off + 4, val1);
-}
-
static void
vtpci_modern_write_notify_2(struct vtpci_modern_softc *sc, bus_size_t off,
uint16_t val)

File Metadata

Mime Type
text/plain
Expires
Tue, Sep 24, 4:34 AM (4 h, 8 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
12628539
Default Alt Text
D28947.id84758.diff (9 KB)

Event Timeline