Hi, Parallels 16 for Mac supports the Apple M1 SoC now, and since it does provide an EFI 'BIOS', our images boot out of the box (once converted to 'hdd' or supplied as USB stick).
Unfortunately virtio doesn't attach, because Parallels seems to provide a 'new' version 2. The following diff adds support for version 2 and I used it to install the VM over vio(4) network. And I was able to install packages over vio(4) network. Disk is ahci(4), USB passthrough is xhci(4), so that works nicely out of the box. Not sure if we want this for 6.9 or not. I think it wouldn't break the current version 1, so I think it shouldn't hurt. If you're wondering why I'm 'so late' with this: jcs@ asked me to have a look at the official Parallels for M1 release, and I just did that. So I couldn't be any faster than this anyway. Opinions? Patrick diff --git a/sys/dev/fdt/virtio_mmio.c b/sys/dev/fdt/virtio_mmio.c index 88e45436c00..e474bad9e6b 100644 --- a/sys/dev/fdt/virtio_mmio.c +++ b/sys/dev/fdt/virtio_mmio.c @@ -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");