Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pci PR kern/52107: for now (while we still use the l...
details: https://anonhg.NetBSD.org/src/rev/6e52d9ecf6a4
branches: trunk
changeset: 352314:6e52d9ecf6a4
user: martin <martin%NetBSD.org@localhost>
date: Sat Mar 25 13:05:09 2017 +0000
description:
PR kern/52107: for now (while we still use the legacy virtio spec) at least
hack around the endianess issues with that.
diffstat:
sys/dev/pci/virtio.c | 102 +++++++++++++++++++++++++++++++++++---------------
1 files changed, 71 insertions(+), 31 deletions(-)
diffs (246 lines):
diff -r 5dbcb6e620d7 -r 6e52d9ecf6a4 sys/dev/pci/virtio.c
--- a/sys/dev/pci/virtio.c Sat Mar 25 11:00:27 2017 +0000
+++ b/sys/dev/pci/virtio.c Sat Mar 25 13:05:09 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: virtio.c,v 1.19 2016/11/29 22:04:42 uwe Exp $ */
+/* $NetBSD: virtio.c,v 1.20 2017/03/25 13:05:09 martin Exp $ */
/*
* Copyright (c) 2010 Minoura Makoto.
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: virtio.c,v 1.19 2016/11/29 22:04:42 uwe Exp $");
+__KERNEL_RCSID(0, "$NetBSD: virtio.c,v 1.20 2017/03/25 13:05:09 martin Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -67,6 +67,45 @@
virtio_match, virtio_attach, virtio_detach, NULL, virtio_rescan, NULL,
DVF_DETACH_SHUTDOWN);
+/* we use the legacy virtio spec, so the pci registers are host native
+ * byte order, not pci (i.e. LE) byte order */
+static inline uint16_t
+nbo_bus_space_read_2(bus_space_tag_t space, bus_space_handle_t handle,
+ bus_size_t offset)
+{
+ return le16toh(bus_space_read_2(space, handle, offset));
+}
+
+static inline uint32_t
+nbo_bus_space_read_4(bus_space_tag_t space, bus_space_handle_t handle,
+ bus_size_t offset)
+{
+ return le32toh(bus_space_read_4(space, handle, offset));
+}
+
+static void
+nbo_bus_space_write_2(bus_space_tag_t space, bus_space_handle_t handle,
+ bus_size_t offset, uint16_t value)
+{
+ bus_space_write_2(space, handle, offset, htole16(value));
+}
+
+static void
+nbo_bus_space_write_4(bus_space_tag_t space, bus_space_handle_t handle,
+ bus_size_t offset, uint16_t value)
+{
+ bus_space_write_4(space, handle, offset, htole32(value));
+}
+
+/* some functions access registers at 4 byte offset for little/high halves */
+#if BYTE_ORDER == BIG_ENDIAN
+#define REG_HI_OFF 0
+#define REG_LO_OFF 4
+#else
+#define REG_HI_OFF 4
+#define REG_LO_OFF 0
+#endif
+
static void
virtio_set_status(struct virtio_softc *sc, int status)
{
@@ -126,8 +165,8 @@
offset = VIRTIO_CONFIG_MSI_CONFIG_VECTOR;
vector = VIRTIO_MSIX_CONFIG_VECTOR_INDEX;
- bus_space_write_2(sc->sc_iot, sc->sc_ioh, offset, vector);
- ret = bus_space_read_2(sc->sc_iot, sc->sc_ioh, offset);
+ nbo_bus_space_write_2(sc->sc_iot, sc->sc_ioh, offset, vector);
+ ret = nbo_bus_space_read_2(sc->sc_iot, sc->sc_ioh, offset);
aprint_debug_dev(sc->sc_dev, "expected=%d, actual=%d\n",
vector, ret);
if (ret != vector)
@@ -135,13 +174,13 @@
for (qid = 0; qid < sc->sc_nvqs; qid++) {
offset = VIRTIO_CONFIG_QUEUE_SELECT;
- bus_space_write_2(sc->sc_iot, sc->sc_ioh, offset, qid);
+ nbo_bus_space_write_2(sc->sc_iot, sc->sc_ioh, offset, qid);
offset = VIRTIO_CONFIG_MSI_QUEUE_VECTOR;
vector = VIRTIO_MSIX_QUEUE_VECTOR_INDEX;
- bus_space_write_2(sc->sc_iot, sc->sc_ioh, offset, vector);
- ret = bus_space_read_2(sc->sc_iot, sc->sc_ioh, offset);
+ nbo_bus_space_write_2(sc->sc_iot, sc->sc_ioh, offset, vector);
+ ret = nbo_bus_space_read_2(sc->sc_iot, sc->sc_ioh, offset);
aprint_debug_dev(sc->sc_dev, "expected=%d, actual=%d\n",
vector, ret);
if (ret != vector)
@@ -473,10 +512,10 @@
for (i = 0; i < sc->sc_nvqs; i++) {
int n;
struct virtqueue *vq = &sc->sc_vqs[i];
- bus_space_write_2(sc->sc_iot, sc->sc_ioh,
+ nbo_bus_space_write_2(sc->sc_iot, sc->sc_ioh,
VIRTIO_CONFIG_QUEUE_SELECT,
vq->vq_index);
- n = bus_space_read_2(sc->sc_iot, sc->sc_ioh,
+ n = nbo_bus_space_read_2(sc->sc_iot, sc->sc_ioh,
VIRTIO_CONFIG_QUEUE_SIZE);
if (n == 0) /* vq disappeared */
continue;
@@ -486,7 +525,7 @@
vq->vq_index);
}
virtio_init_vq(sc, vq, true);
- bus_space_write_4(sc->sc_iot, sc->sc_ioh,
+ nbo_bus_space_write_4(sc->sc_iot, sc->sc_ioh,
VIRTIO_CONFIG_QUEUE_ADDRESS,
(vq->vq_dmamap->dm_segs[0].ds_addr
/ VIRTIO_PAGE_SIZE));
@@ -519,10 +558,10 @@
if (!(device_cfdata(sc->sc_dev)->cf_flags & 1) &&
!(device_cfdata(sc->sc_child)->cf_flags & 1)) /* XXX */
guest_features |= VIRTIO_F_RING_INDIRECT_DESC;
- r = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
+ r = nbo_bus_space_read_4(sc->sc_iot, sc->sc_ioh,
VIRTIO_CONFIG_DEVICE_FEATURES);
r &= guest_features;
- bus_space_write_4(sc->sc_iot, sc->sc_ioh,
+ nbo_bus_space_write_4(sc->sc_iot, sc->sc_ioh,
VIRTIO_CONFIG_GUEST_FEATURES, r);
sc->sc_features = r;
if (r & VIRTIO_F_RING_INDIRECT_DESC)
@@ -546,14 +585,14 @@
uint16_t
virtio_read_device_config_2(struct virtio_softc *sc, int index)
{
- return bus_space_read_2(sc->sc_iot, sc->sc_ioh,
+ return nbo_bus_space_read_2(sc->sc_iot, sc->sc_ioh,
sc->sc_config_offset + index);
}
uint32_t
virtio_read_device_config_4(struct virtio_softc *sc, int index)
{
- return bus_space_read_4(sc->sc_iot, sc->sc_ioh,
+ return nbo_bus_space_read_4(sc->sc_iot, sc->sc_ioh,
sc->sc_config_offset + index);
}
@@ -562,11 +601,12 @@
{
uint64_t r;
- r = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
- sc->sc_config_offset + index + sizeof(uint32_t));
+ r = nbo_bus_space_read_4(sc->sc_iot, sc->sc_ioh,
+ sc->sc_config_offset + index + REG_HI_OFF);
r <<= 32;
- r += bus_space_read_4(sc->sc_iot, sc->sc_ioh,
- sc->sc_config_offset + index);
+ r |= nbo_bus_space_read_4(sc->sc_iot, sc->sc_ioh,
+ sc->sc_config_offset + index + REG_LO_OFF);
+
return r;
}
@@ -582,7 +622,7 @@
virtio_write_device_config_2(struct virtio_softc *sc,
int index, uint16_t value)
{
- bus_space_write_2(sc->sc_iot, sc->sc_ioh,
+ nbo_bus_space_write_2(sc->sc_iot, sc->sc_ioh,
sc->sc_config_offset + index, value);
}
@@ -590,7 +630,7 @@
virtio_write_device_config_4(struct virtio_softc *sc,
int index, uint32_t value)
{
- bus_space_write_4(sc->sc_iot, sc->sc_ioh,
+ nbo_bus_space_write_4(sc->sc_iot, sc->sc_ioh,
sc->sc_config_offset + index, value);
}
@@ -598,11 +638,11 @@
virtio_write_device_config_8(struct virtio_softc *sc,
int index, uint64_t value)
{
- bus_space_write_4(sc->sc_iot, sc->sc_ioh,
- sc->sc_config_offset + index,
+ nbo_bus_space_write_4(sc->sc_iot, sc->sc_ioh,
+ sc->sc_config_offset + index + REG_LO_OFF,
value & 0xffffffff);
- bus_space_write_4(sc->sc_iot, sc->sc_ioh,
- sc->sc_config_offset + index + sizeof(uint32_t),
+ nbo_bus_space_write_4(sc->sc_iot, sc->sc_ioh,
+ sc->sc_config_offset + index + REG_HI_OFF,
value >> 32);
}
@@ -822,9 +862,9 @@
memset(vq, 0, sizeof(*vq));
- bus_space_write_2(sc->sc_iot, sc->sc_ioh,
+ nbo_bus_space_write_2(sc->sc_iot, sc->sc_ioh,
VIRTIO_CONFIG_QUEUE_SELECT, index);
- vq_size = bus_space_read_2(sc->sc_iot, sc->sc_ioh,
+ vq_size = nbo_bus_space_read_2(sc->sc_iot, sc->sc_ioh,
VIRTIO_CONFIG_QUEUE_SIZE);
if (vq_size == 0) {
aprint_error_dev(sc->sc_dev,
@@ -880,7 +920,7 @@
}
/* set the vq address */
- bus_space_write_4(sc->sc_iot, sc->sc_ioh,
+ nbo_bus_space_write_4(sc->sc_iot, sc->sc_ioh,
VIRTIO_CONFIG_QUEUE_ADDRESS,
(vq->vq_dmamap->dm_segs[0].ds_addr
/ VIRTIO_PAGE_SIZE));
@@ -924,7 +964,7 @@
return 0;
err:
- bus_space_write_4(sc->sc_iot, sc->sc_ioh,
+ nbo_bus_space_write_4(sc->sc_iot, sc->sc_ioh,
VIRTIO_CONFIG_QUEUE_ADDRESS, 0);
if (vq->vq_dmamap)
bus_dmamap_destroy(sc->sc_dmat, vq->vq_dmamap);
@@ -955,9 +995,9 @@
}
/* tell device that there's no virtqueue any longer */
- bus_space_write_2(sc->sc_iot, sc->sc_ioh,
+ nbo_bus_space_write_2(sc->sc_iot, sc->sc_ioh,
VIRTIO_CONFIG_QUEUE_SELECT, vq->vq_index);
- bus_space_write_4(sc->sc_iot, sc->sc_ioh,
+ nbo_bus_space_write_4(sc->sc_iot, sc->sc_ioh,
VIRTIO_CONFIG_QUEUE_ADDRESS, 0);
kmem_free(vq->vq_entries, sizeof(*vq->vq_entries) * vq->vq_num);
@@ -1207,7 +1247,7 @@
vq_sync_uring(sc, vq, BUS_DMASYNC_POSTREAD);
membar_consumer();
if (!(vq->vq_used->flags & VRING_USED_F_NO_NOTIFY))
- bus_space_write_2(sc->sc_iot, sc->sc_ioh,
+ nbo_bus_space_write_2(sc->sc_iot, sc->sc_ioh,
VIRTIO_CONFIG_QUEUE_NOTIFY,
vq->vq_index);
}
Home |
Main Index |
Thread Index |
Old Index