summaryrefslogtreecommitdiff
path: root/sys/dev/fdt
diff options
context:
space:
mode:
authorPatrick Wildt <patrick@cvs.openbsd.org>2021-04-15 17:07:00 +0000
committerPatrick Wildt <patrick@cvs.openbsd.org>2021-04-15 17:07:00 +0000
commit6297a191e62feeab4df14235923cd4fa81956618 (patch)
treedddc5f6615bcbea36025664e823388e4c706bc6f /sys/dev/fdt
parentc00780d226253cc60d6c59a6fd955b875a27ac6a (diff)
Implement version 2 of virtio(4) at fdt, as used by Parallels on the
Apple M1. With this vio(4) shows up and we can properly install and use OpenBSD as VM. "not afraid of the virtio diff" deraadt@ "okie dokie" jcs@
Diffstat (limited to 'sys/dev/fdt')
-rw-r--r--sys/dev/fdt/virtio_mmio.c53
1 files changed, 42 insertions, 11 deletions
diff --git a/sys/dev/fdt/virtio_mmio.c b/sys/dev/fdt/virtio_mmio.c
index 88e45436c00..9dff7feae40 100644
--- a/sys/dev/fdt/virtio_mmio.c
+++ b/sys/dev/fdt/virtio_mmio.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: virtio_mmio.c,v 1.8 2019/05/26 15:20:04 sf Exp $ */
+/* $OpenBSD: virtio_mmio.c,v 1.9 2021/04/15 17:06:59 patrick Exp $ */
/* $NetBSD: virtio.c,v 1.3 2011/11/02 23:05:52 njoly Exp $ */
/*
@@ -58,10 +58,17 @@
#define VIRTIO_MMIO_QUEUE_NUM 0x038
#define VIRTIO_MMIO_QUEUE_ALIGN 0x03c
#define VIRTIO_MMIO_QUEUE_PFN 0x040
+#define VIRTIO_MMIO_QUEUE_READY 0x044
#define VIRTIO_MMIO_QUEUE_NOTIFY 0x050
#define VIRTIO_MMIO_INTERRUPT_STATUS 0x060
#define VIRTIO_MMIO_INTERRUPT_ACK 0x064
#define VIRTIO_MMIO_STATUS 0x070
+#define VIRTIO_MMIO_QUEUE_DESC_LOW 0x080
+#define VIRTIO_MMIO_QUEUE_DESC_HIGH 0x084
+#define VIRTIO_MMIO_QUEUE_AVAIL_LOW 0x090
+#define VIRTIO_MMIO_QUEUE_AVAIL_HIGH 0x094
+#define VIRTIO_MMIO_QUEUE_USED_LOW 0x0a0
+#define VIRTIO_MMIO_QUEUE_USED_HIGH 0x0a4
#define VIRTIO_MMIO_CONFIG 0x100
#define VIRTIO_MMIO_INT_VRING (1 << 0)
@@ -106,6 +113,7 @@ struct virtio_mmio_softc {
void *sc_ih;
int sc_config_offset;
+ uint32_t sc_version;
};
struct cfattach virtio_mmio_ca = {
@@ -159,10 +167,31 @@ virtio_mmio_setup_queue(struct virtio_softc *vsc, struct virtqueue *vq,
vq->vq_index);
bus_space_write_4(sc->sc_iot, sc->sc_ioh, VIRTIO_MMIO_QUEUE_NUM,
bus_space_read_4(sc->sc_iot, sc->sc_ioh, VIRTIO_MMIO_QUEUE_NUM_MAX));
- bus_space_write_4(sc->sc_iot, sc->sc_ioh, VIRTIO_MMIO_QUEUE_ALIGN,
- PAGE_SIZE);
- bus_space_write_4(sc->sc_iot, sc->sc_ioh, VIRTIO_MMIO_QUEUE_PFN,
- addr / VIRTIO_PAGE_SIZE);
+ if (sc->sc_version == 1) {
+ bus_space_write_4(sc->sc_iot, sc->sc_ioh,
+ VIRTIO_MMIO_QUEUE_ALIGN, PAGE_SIZE);
+ bus_space_write_4(sc->sc_iot, sc->sc_ioh,
+ VIRTIO_MMIO_QUEUE_PFN, addr / VIRTIO_PAGE_SIZE);
+ } else {
+ bus_space_write_4(sc->sc_iot, sc->sc_ioh,
+ VIRTIO_MMIO_QUEUE_DESC_LOW, addr);
+ bus_space_write_4(sc->sc_iot, sc->sc_ioh,
+ VIRTIO_MMIO_QUEUE_DESC_HIGH, addr >> 32);
+ bus_space_write_4(sc->sc_iot, sc->sc_ioh,
+ VIRTIO_MMIO_QUEUE_AVAIL_LOW,
+ addr + vq->vq_availoffset);
+ bus_space_write_4(sc->sc_iot, sc->sc_ioh,
+ VIRTIO_MMIO_QUEUE_AVAIL_HIGH,
+ (addr + vq->vq_availoffset) >> 32);
+ bus_space_write_4(sc->sc_iot, sc->sc_ioh,
+ VIRTIO_MMIO_QUEUE_USED_LOW,
+ addr + vq->vq_usedoffset);
+ bus_space_write_4(sc->sc_iot, sc->sc_ioh,
+ VIRTIO_MMIO_QUEUE_USED_HIGH,
+ (addr + vq->vq_usedoffset) >> 32);
+ bus_space_write_4(sc->sc_iot, sc->sc_ioh,
+ VIRTIO_MMIO_QUEUE_READY, 1);
+ }
}
void
@@ -192,7 +221,7 @@ virtio_mmio_attach(struct device *parent, struct device *self, void *aux)
struct fdt_attach_args *faa = aux;
struct virtio_mmio_softc *sc = (struct virtio_mmio_softc *)self;
struct virtio_softc *vsc = &sc->sc_sc;
- uint32_t id, magic, version;
+ uint32_t id, magic;
if (faa->fa_nreg < 1) {
printf(": no register data\n");
@@ -213,17 +242,19 @@ virtio_mmio_attach(struct device *parent, struct device *self, void *aux)
return;
}
- version = bus_space_read_4(sc->sc_iot, sc->sc_ioh, VIRTIO_MMIO_VERSION);
- if (version != 1) {
- printf(": unknown version 0x%02x; giving up\n", version);
+ sc->sc_version = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
+ VIRTIO_MMIO_VERSION);
+ if (sc->sc_version < 1 || sc->sc_version > 2) {
+ printf(": unknown version 0x%02x; giving up\n", sc->sc_version);
return;
}
id = bus_space_read_4(sc->sc_iot, sc->sc_ioh, VIRTIO_MMIO_DEVICE_ID);
printf(": Virtio %s Device", virtio_device_string(id));
- bus_space_write_4(sc->sc_iot, sc->sc_ioh, VIRTIO_MMIO_GUEST_PAGE_SIZE,
- PAGE_SIZE);
+ if (sc->sc_version == 1)
+ bus_space_write_4(sc->sc_iot, sc->sc_ioh,
+ VIRTIO_MMIO_GUEST_PAGE_SIZE, PAGE_SIZE);
printf("\n");