tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: patch review: VirtIO early console support




For future reference, here's the patch inlined:

---8<---

c5fc57dbf69fc9832722b277cb601ebc471bbfb7 viocon(4) console support for early kernel messages
diff --git a/share/man/man4/viocon.4 b/share/man/man4/viocon.4
index 26f2bd6c26d..f6ce5da46ad 100644
--- a/share/man/man4/viocon.4
+++ b/share/man/man4/viocon.4
@@ -58,9 +58,11 @@ by
 .An Stefan Fritsch Aq Mt sf%sfritsch.de@localhost .
 It was ported to
 .Nx 10.0 .
-.Sh BUGS
-Use as a kernel console for
-.Nx
-is not yet supported.
 .Pp
+Kernel support was implemented by
+.An Taylor R. Campbell Aq Mt riastradh%NetBSD.org@localhost .
+.Pp
+Early console support was implemented by
+.An Emile So iMil Sc Heitor Aq Mt imil%NetBSD.org@localhost .
+.Sh BUGS
 The multiport feature is not yet supported.
diff --git a/sys/arch/x86/conf/MICROVM.common b/sys/arch/x86/conf/MICROVM.common
index 2969150a6fa..70701f66a4d 100644
--- a/sys/arch/x86/conf/MICROVM.common
+++ b/sys/arch/x86/conf/MICROVM.common
@@ -118,3 +118,5 @@ pseudo-device	drvctl

 file-system	PUFFS
 pseudo-device	putter
+
+options		VIOCON_CONSOLE
diff --git a/sys/arch/x86/x86/consinit.c b/sys/arch/x86/x86/consinit.c
index 9ef384c2c07..78f60c4e82b 100644
--- a/sys/arch/x86/x86/consinit.c
+++ b/sys/arch/x86/x86/consinit.c
@@ -32,6 +32,7 @@ __KERNEL_RCSID(0, "$NetBSD: consinit.c,v 1.41 2025/04/30 05:15:08 imil Exp $");
 #include "opt_kgdb.h"
 #include "opt_puc.h"
 #include "opt_xen.h"
+#include "opt_viocon.h"

 #include <sys/param.h>
 #include <sys/systm.h>
@@ -104,6 +105,13 @@ __KERNEL_RCSID(0, "$NetBSD: consinit.c,v 1.41 2025/04/30 05:15:08 imil Exp $");
 #include <xen/xen.h>
 #endif

+#ifdef VIOCON_CONSOLE
+#include <dev/virtio/virtio_vioconvar.h>
+#include <dev/virtio/virtio_mmiovar.h>
+#include <dev/virtio/arch/x86/virtio_mmio_parse.h>
+#include <uvm/uvm_extern.h> /* for kernel_map */
+#endif
+
 #ifndef CONSDEVNAME
 #define CONSDEVNAME "pc"
 #endif
@@ -263,6 +271,22 @@ dokbd:
 			       error);
 		return;
 	}
+#ifdef VIOCON_CONSOLE
+	if (!strcmp(console_devname, "viocon")) {
+		/* We need uvm to be ready before we can map the MMIO region */
+		if (!kernel_map) {
+			initted = 0;
+			return;
+		}
+		/*
+		 * In x86 microvm, mmio device enumeration is done by parsing
+		 * the kernel command line
+		 */
+		enumerate_mmio_devices = mmio_args_parse;
+		if (!viocon_earlyinit())
+			return;
+	}
+#endif
 #if (NCOM > 0)
 	if (!strcmp(console_devname, "com")) {
 		int addr = consinfo->addr;
diff --git a/sys/dev/virtio/arch/x86/virtio_mmio_cmdline.c b/sys/dev/virtio/arch/x86/virtio_mmio_cmdline.c
index 18a0ce9f8bc..b55c5a03ae4 100644
--- a/sys/dev/virtio/arch/x86/virtio_mmio_cmdline.c
+++ b/sys/dev/virtio/arch/x86/virtio_mmio_cmdline.c
@@ -63,21 +63,17 @@

 #define VIRTIO_PRIVATE
 #include <dev/virtio/virtio_mmiovar.h>
+#include <dev/virtio/arch/x86/virtio_mmio_parse.h>
 #include <arch/x86/pv/pvvar.h>
 #include <xen/hypervisor.h>
+#include <uvm/uvm_extern.h>
+#include <dev/cons.h>

 #include <machine/i82093var.h>
 #include "ioapic.h"

 #define VMMIOSTR "virtio_mmio.device="

-struct mmio_args {
-	uint64_t	sz;
-	uint64_t	baseaddr;
-	uint64_t	irq;
-	uint64_t	id;
-};
-
 struct virtio_mmio_cmdline_softc {
 	struct virtio_mmio_softc	sc_msc;
 	struct mmio_args		margs;
@@ -112,6 +108,8 @@ parsearg(struct mmio_args *margs, const char *arg)
 {
 	char *p;

+	/* Bus space type */
+	margs->bst = x86_bus_space_mem;
 	/* <size> */
 	margs->sz = strtoull(arg, (char **)&p, 0);
 	if ((margs->sz == 0) || (margs->sz == UINT64_MAX))
@@ -186,50 +184,75 @@ bad:
 	aprint_error("Error parsing virtio_mmio parameter: %s\n", arg);
 }

+int
+mmio_args_parse(struct mmio_args *margs)
+{
+	int keylen = strlen(VMMIOSTR);
+	char *next;
+	static char cmdline[LINE_MAX], *parg;
+
+	/* first pass, or emptied parg from last pass */
+	if (parg == NULL) {
+		strlcpy(cmdline, xen_start_info.cmd_line, sizeof(cmdline));
+		parg = strstr(cmdline, VMMIOSTR);
+	}
+
+	/* no args were found */
+	if (parg == NULL) {
+		return MMIO_NO_ARG;
+	}
+
+	/* useless, no parameters */
+	if (strlen(parg) <= keylen) {
+		parg = NULL;
+		return MMIO_NO_ARG;
+	}
+
+	parg += keylen;
+
+	next = parg;
+	while (*next && *next != ' ') /* find end of argument */
+		next++;
+	if (*next) { /* space */
+		*next++ = '\0'; /* end the argument string */
+		next = strstr(next,VMMIOSTR);
+	}
+	parsearg(margs, parg);
+
+	if (next != NULL)
+		parg = next;
+
+	if (!*parg) {
+		parg = NULL;
+		return MMIO_LAST_ARG;
+	}
+
+	return MMIO_NEXT_ARG;
+}
+
 static void
 virtio_mmio_cmdline_attach(device_t parent, device_t self, void *aux)
 {
 	struct virtio_mmio_cmdline_softc *sc = device_private(self);
 	struct pv_attach_args *pvaa = aux;
 	struct mmio_args *margs = &sc->margs;
-	int keylen = strlen(VMMIOSTR);
-	char *next;
-	static char cmdline[LINE_MAX], *parg = NULL;
+	int mmioarg;

 	aprint_normal("\n");
 	aprint_naive("\n");

-	if (parg == NULL) { /* first pass */
-		strlcpy(cmdline, xen_start_info.cmd_line, sizeof(cmdline));
-		aprint_verbose_dev(self, "kernel parameters: %s\n",
-		    cmdline);
-		parg = strstr(cmdline, VMMIOSTR);
-	}
+	mmioarg = mmio_args_parse(margs);

-	if (parg != NULL) {
-		parg += keylen;
-		if (!*parg)
-			return;
-
-		next = parg;
-		while (*next && *next != ' ') /* find end of argument */
-			next++;
-		if (*next) { /* space */
-			*next++ = '\0'; /* end the argument string */
-			next = strstr(next, VMMIOSTR);
-		}
-
-		aprint_normal_dev(self, "viommio: %s\n", parg);
-		parsearg(margs, parg);
-
-		if (virtio_mmio_cmdline_do_attach(self, pvaa, margs))
-			return;
-
-		if (next) {
-			parg = next;
-			config_found(parent, pvaa, NULL, CFARGS_NONE);
-		}
-	}
+	if (mmioarg == MMIO_NO_ARG)
+		return;
+
+	aprint_normal_dev(self, "viommio: @%#" PRIxPADDR "\n", margs->baseaddr);
+
+	if (virtio_mmio_cmdline_do_attach(self, pvaa, margs))
+		return;
+
+	if (mmioarg == MMIO_NEXT_ARG)
+		config_found(parent, pvaa, NULL, CFARGS_NONE);
 }

 static int
@@ -250,11 +273,10 @@ virtio_mmio_cmdline_do_attach(device_t self,
 	error = bus_space_map(msc->sc_iot, margs->baseaddr, margs->sz, 0,
 	    &msc->sc_ioh);
 	if (error) {
-		aprint_error_dev(self, "couldn't map %#" PRIx64 ": %d",
+		aprint_error_dev(self, "couldn't map %#" PRIxPADDR ": %d",
 		    margs->baseaddr, error);
 		return error;
 	}
-
 	msc->sc_alloc_interrupts = virtio_mmio_cmdline_alloc_interrupts;
 	msc->sc_free_interrupts = virtio_mmio_cmdline_free_interrupts;

diff --git a/sys/dev/virtio/arch/x86/virtio_mmio_parse.h b/sys/dev/virtio/arch/x86/virtio_mmio_parse.h
new file mode 100644
index 00000000000..e78ac50b6d3
--- /dev/null
+++ b/sys/dev/virtio/arch/x86/virtio_mmio_parse.h
@@ -0,0 +1,41 @@
+/* $NetBSD$ */
+
+/*-
+ * Copyright (c) 2025 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Emile 'iMil' Heitor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _VIRTIO_MMIO_PARSE_H_
+#define _VIRTIO_MMIO_PARSE_H_
+
+#define MMIO_NEXT_ARG 2
+#define MMIO_LAST_ARG 1
+#define MMIO_NO_ARG 0
+
+int mmio_args_parse(struct mmio_args *);
+
+#endif /* _VIRTIO_MMIO_PARSE_H_ */
diff --git a/sys/dev/virtio/files.virtio b/sys/dev/virtio/files.virtio
index 4e399624ab0..4724a4c3347 100644
--- a/sys/dev/virtio/files.virtio
+++ b/sys/dev/virtio/files.virtio
@@ -5,6 +5,7 @@ include "dev/pci/files.virtio"

 file	dev/virtio/virtio_mmio.c	virtio_mmio

+defflag opt_viocon.h	VIOCON_CONSOLE
 device	viocon
 attach	viocon at virtio
 file	dev/virtio/viocon.c		viocon
diff --git a/sys/dev/virtio/viocon.c b/sys/dev/virtio/viocon.c
index 73c938936be..cce0b55c639 100644
--- a/sys/dev/virtio/viocon.c
+++ b/sys/dev/virtio/viocon.c
@@ -33,8 +33,16 @@ __KERNEL_RCSID(0, "$NetBSD: viocon.c,v 1.10 2024/08/05 19:13:34 riastradh Exp $"
 #include <sys/systm.h>
 #include <sys/tty.h>

+#include "opt_viocon.h"
+
+#ifdef VIOCON_CONSOLE
+#include <dev/cons.h>
+#include <uvm/uvm_extern.h>
+#include <dev/virtio/virtio_vioconvar.h>
+#endif
+
 #include <dev/pci/virtioreg.h>
-#include <dev/pci/virtiovar.h>
+#include <dev/virtio/virtio_mmiovar.h>

 #include "ioconf.h"

@@ -117,6 +125,13 @@ struct viocon_port {
 	uint16_t		 vp_cols;
 	u_char			*vp_rx_buf;
 	u_char			*vp_tx_buf;
+
+#ifdef VIOCON_CONSOLE
+	struct consdev		 vp_cntab;
+	unsigned int		 vp_pollpos;
+	unsigned int		 vp_polllen;
+	bool			 vp_polling;
+#endif
 };

 struct viocon_softc {
@@ -153,6 +168,26 @@ void	vioconstop(struct tty *, int);
 int	vioconioctl(dev_t, u_long, void *, int, struct lwp *);
 struct tty	*viocontty(dev_t dev);

+#ifdef VIOCON_CONSOLE
+static void viocon_cnpollc(dev_t, int);
+static int viocon_cngetc(dev_t);
+static void viocon_cnputc(dev_t, int);
+static void viocon_early_putc(dev_t, int);
+
+static uint32_t *early_console;
+static vaddr_t viocon_mmio_vaddr = 0;
+
+int (*enumerate_mmio_devices)(struct mmio_args *) = NULL;
+
+static struct consdev viocon_early_consdev = {
+    .cn_putc = viocon_early_putc,
+    .cn_getc = NULL,
+    .cn_pollc = NULL,
+    .cn_dev = NODEV,
+    .cn_pri = CN_NORMAL
+};
+#endif
+
 CFATTACH_DECL_NEW(viocon, sizeof(struct viocon_softc),
     viocon_match, viocon_attach, /*detach*/NULL, /*activate*/NULL);

@@ -183,7 +218,88 @@ dev2port(dev_t dev)
 	return dev2sc(dev)->sc_ports[VIOCONPORT(dev)];
 }

-int viocon_match(struct device *parent, struct cfdata *match, void *aux)
+#ifdef VIOCON_CONSOLE
+static void
+viocon_early_putc(dev_t dev, int c)
+{
+	*early_console = c;
+}
+
+static void
+free_viocon_mmio_vaddr(void)
+{
+	if (!viocon_mmio_vaddr)
+		return;
+
+	pmap_kremove(viocon_mmio_vaddr, PAGE_SIZE);
+	pmap_update(pmap_kernel());
+	uvm_km_free(kernel_map, viocon_mmio_vaddr, PAGE_SIZE, UVM_KMF_VAONLY);
+	viocon_mmio_vaddr = 0;
+}
+
+int
+viocon_earlyinit(void)
+{
+	struct mmio_args margs;
+	paddr_t mmio_baseaddr = 0;
+	struct virtio_mmio_softc sc;
+
+	if (enumerate_mmio_devices == NULL)
+		return -1;
+
+	while ((*enumerate_mmio_devices)(&margs)) {
+		if (!mmio_baseaddr) {
+			/* Fetch a page for early MMIO mapping */
+			viocon_mmio_vaddr = uvm_km_alloc(kernel_map, PAGE_SIZE, 0,
+			    UVM_KMF_VAONLY | UVM_KMF_NOWAIT);
+			if (!viocon_mmio_vaddr)
+				return -1;
+			/* map a page for early virtio console */
+			mmio_baseaddr = margs.baseaddr & ~(PAGE_SIZE - 1);
+			pmap_kenter_pa(viocon_mmio_vaddr, mmio_baseaddr,
+			    VM_PROT_READ|VM_PROT_WRITE, PMAP_NOCACHE);
+			pmap_update(pmap_kernel());
+		}
+
+		sc.sc_iot = margs.bst;
+		/*
+		 * viocon_mmio_vaddr = reserved page
+		 * margs.baseaddr = pa
+		 * mmio_baseaddr = MMIO base address
+		 */
+		sc.sc_ioh = viocon_mmio_vaddr + (margs.baseaddr - mmio_baseaddr);
+		sc.sc_iosize = margs.sz;
+		sc.sc_le_regs = (BYTE_ORDER == LITTLE_ENDIAN);
+
+		aprint_verbose("mmio addr:%#" PRIxPADDR "\n", margs.baseaddr);
+
+		if (bus_space_read_4(sc.sc_iot, sc.sc_ioh,
+		    VIRTIO_MMIO_MAGIC_VALUE) != VIRTIO_MMIO_MAGIC)
+			continue;
+		if (virtio_mmio_reg_read(&sc, VIRTIO_MMIO_DEVICE_ID) !=
+		    VIRTIO_DEVICE_ID_CONSOLE)
+			continue;
+		if (!(virtio_mmio_reg_read(&sc, VIRTIO_MMIO_DEVICE_FEATURES) &
+		    VIRTIO_CONSOLE_F_EMERG_WRITE))
+			continue;
+
+		early_console =
+		    (uint32_t *)(sc.sc_ioh +
+		    VIRTIO_MMIO_CONFIG + VIRTIO_CONSOLE_EMERG_WR);
+
+		cn_tab = &viocon_early_consdev;
+
+		return 0;
+	}
+
+	free_viocon_mmio_vaddr();
+
+	return -1;
+}
+#endif
+
+int
+viocon_match(struct device *parent, struct cfdata *match, void *aux)
 {
 	struct virtio_attach_args *va = aux;
 	if (va->sc_childdevid == VIRTIO_DEVICE_ID_CONSOLE)
@@ -229,6 +345,22 @@ viocon_attach(struct device *parent, struct device *self, void *aux)

 	viocon_rx_fill(sc->sc_ports[0]);

+#ifdef VIOCON_CONSOLE
+	if (cn_tab == NULL || cn_tab->cn_dev == NODEV) {
+		sc->sc_ports[0]->vp_cntab = (struct consdev) {
+			.cn_pollc = viocon_cnpollc,
+			.cn_getc = viocon_cngetc,
+			.cn_putc = viocon_cnputc,
+			.cn_dev = VIOCONDEV(device_unit(self), 0),
+			.cn_pri = CN_REMOTE,
+		};
+		aprint_normal_dev(sc->sc_dev, "console\n");
+		cn_tab = &sc->sc_ports[0]->vp_cntab;
+		/* if a page was mapped for early console, free it */
+		free_viocon_mmio_vaddr();
+	}
+#endif
+
 	return;
 err:
 	kmem_free(sc->sc_vqs, nvqs * sizeof(sc->sc_vqs[0]));
@@ -634,3 +766,75 @@ vioconioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
 		return error2;
 	return ENOTTY;
 }
+
+#ifdef VIOCON_CONSOLE
+static void
+viocon_cnpollc(dev_t dev, int on)
+{
+	struct viocon_port *vp = dev2port(dev);
+	int s;
+
+	KASSERT((bool)on != vp->vp_polling);
+
+	s = spltty();
+	vp->vp_polling = on;
+	vioconhwiflow(vp->vp_tty, on);
+	splx(s);
+}
+
+static int
+viocon_cngetc(dev_t dev)
+{
+	struct viocon_softc *sc = dev2sc(dev);
+	struct viocon_port *vp = dev2port(dev);
+	struct virtqueue *vq = vp->vp_rx;
+	struct virtio_softc *vsc = sc->sc_virtio;
+	int slot, len;
+
+	KASSERT(vp->vp_polling);
+	while (vp->vp_polllen == 0) {
+		if (virtio_dequeue(vsc, vq, &slot, &len) == 0) {
+			KASSERTMSG(slot >= 0, "slot=%d", slot);
+			KASSERTMSG(slot < vq->vq_num, "slot=%d", slot);
+			KASSERTMSG(len > 0, "len=%d", len);
+			KASSERTMSG(len <= BUFSIZE, "len=%d", len);
+			bus_dmamap_sync(virtio_dmat(vsc), vp->vp_dmamap,
+			    slot * BUFSIZE, BUFSIZE, BUS_DMASYNC_POSTREAD);
+			vp->vp_polllen = len;
+			vp->vp_pollpos = slot * BUFSIZE;
+		}
+	}
+	KASSERT(vp->vp_pollpos <= vq->vq_num * BUFSIZE);
+	vp->vp_polllen--;
+	return vp->vp_rx_buf[vp->vp_pollpos++];
+}
+
+static void
+viocon_cnputc(dev_t dev, int c)
+{
+	struct viocon_softc *sc = dev2sc(dev);
+	struct viocon_port *vp = dev2port(dev);
+	struct virtqueue *vq = vp->vp_tx;
+	struct virtio_softc *vsc = sc->sc_virtio;
+	int slot;
+	int s, error;
+
+	s = spltty();
+	KERNEL_LOCK(1, NULL);
+	(void)viocon_tx_drain(vp, vq);
+	error = virtio_enqueue_prep(vsc, vq, &slot);
+	if (error == 0) {
+		error = virtio_enqueue_reserve(vsc, vq, slot, 1);
+		KASSERTMSG(error == 0, "error=%d", error);
+		vp->vp_tx_buf[slot * BUFSIZE] = c;
+		bus_dmamap_sync(virtio_dmat(vsc), vp->vp_dmamap,
+		    vp->vp_tx_buf - vp->vp_rx_buf + slot * BUFSIZE, 1,
+		    BUS_DMASYNC_PREWRITE);
+		virtio_enqueue_p(vsc, vq, slot, vp->vp_dmamap,
+		    vp->vp_tx_buf - vp->vp_rx_buf + slot * BUFSIZE, 1, 1);
+		virtio_enqueue_commit(vsc, vq, slot, 1);
+	}
+	KERNEL_UNLOCK_ONE(NULL);
+	splx(s);
+}
+#endif
diff --git a/sys/dev/virtio/virtio_mmio.c b/sys/dev/virtio/virtio_mmio.c
index eb827f528f7..5c3f085577b 100644
--- a/sys/dev/virtio/virtio_mmio.c
+++ b/sys/dev/virtio/virtio_mmio.c
@@ -66,39 +66,8 @@ __KERNEL_RCSID(0, "$NetBSD: virtio_mmio.c,v 1.14 2024/03/09 11:55:59 isaki Exp $
 #include <sys/device.h>
 #include <sys/mutex.h>

-#define VIRTIO_PRIVATE
 #include <dev/virtio/virtio_mmiovar.h>

-#define VIRTIO_MMIO_MAGIC		('v' | 'i' << 8 | 'r' << 16 | 't' << 24)
-
-#define VIRTIO_MMIO_MAGIC_VALUE		0x000
-#define VIRTIO_MMIO_VERSION		0x004
-#define VIRTIO_MMIO_DEVICE_ID		0x008
-#define VIRTIO_MMIO_VENDOR_ID		0x00c
-#define VIRTIO_MMIO_DEVICE_FEATURES	0x010	/* "HostFeatures" in v1 */
-#define VIRTIO_MMIO_DEVICE_FEATURES_SEL	0x014	/* "HostFeaturesSel" in v1 */
-#define VIRTIO_MMIO_DRIVER_FEATURES	0x020	/* "GuestFeatures" in v1 */
-#define VIRTIO_MMIO_DRIVER_FEATURES_SEL	0x024	/* "GuestFeaturesSel" in v1 */
-#define VIRTIO_MMIO_V1_GUEST_PAGE_SIZE	0x028
-#define VIRTIO_MMIO_QUEUE_SEL		0x030
-#define VIRTIO_MMIO_QUEUE_NUM_MAX	0x034
-#define VIRTIO_MMIO_QUEUE_NUM		0x038
-#define VIRTIO_MMIO_V1_QUEUE_ALIGN	0x03c
-#define VIRTIO_MMIO_V1_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_V2_QUEUE_DESC_LOW	0x080
-#define	VIRTIO_MMIO_V2_QUEUE_DESC_HIGH	0x084
-#define	VIRTIO_MMIO_V2_QUEUE_AVAIL_LOW	0x090
-#define	VIRTIO_MMIO_V2_QUEUE_AVAIL_HIGH	0x094
-#define	VIRTIO_MMIO_V2_QUEUE_USED_LOW	0x0a0
-#define	VIRTIO_MMIO_V2_QUEUE_USED_HIGH	0x0a4
-#define	VIRTIO_MMIO_V2_CONFIG_GEN	0x0fc
-#define VIRTIO_MMIO_CONFIG		0x100
-
 /*
  * MMIO configuration space for virtio-mmio v1 is in guest byte order.
  *
@@ -128,7 +97,7 @@ static int	virtio_mmio_alloc_interrupts(struct virtio_softc *);
 static void	virtio_mmio_free_interrupts(struct virtio_softc *);
 static int	virtio_mmio_setup_interrupts(struct virtio_softc *, int);

-static uint32_t
+uint32_t
 virtio_mmio_reg_read(struct virtio_mmio_softc *sc, bus_addr_t reg)
 {
 	uint32_t val;
diff --git a/sys/dev/virtio/virtio_mmiovar.h b/sys/dev/virtio/virtio_mmiovar.h
index c95ec285287..bcd4066b756 100644
--- a/sys/dev/virtio/virtio_mmiovar.h
+++ b/sys/dev/virtio/virtio_mmiovar.h
@@ -28,8 +28,40 @@
 #ifndef _VIRTIO_MMIOVAR_H_
 #define _VIRTIO_MMIOVAR_H_

+#define VIRTIO_PRIVATE
+
 #include <dev/pci/virtiovar.h> /* XXX: move to non-pci */

+#define VIRTIO_MMIO_MAGIC		('v' | 'i' << 8 | 'r' << 16 | 't' << 24)
+
+#define VIRTIO_MMIO_MAGIC_VALUE		0x000
+#define VIRTIO_MMIO_VERSION		0x004
+#define VIRTIO_MMIO_DEVICE_ID		0x008
+#define VIRTIO_MMIO_VENDOR_ID		0x00c
+#define VIRTIO_MMIO_DEVICE_FEATURES	0x010	/* "HostFeatures" in v1 */
+#define VIRTIO_MMIO_DEVICE_FEATURES_SEL	0x014	/* "HostFeaturesSel" in v1 */
+#define VIRTIO_MMIO_DRIVER_FEATURES	0x020	/* "GuestFeatures" in v1 */
+#define VIRTIO_MMIO_DRIVER_FEATURES_SEL	0x024	/* "GuestFeaturesSel" in v1 */
+#define VIRTIO_MMIO_V1_GUEST_PAGE_SIZE	0x028
+#define VIRTIO_MMIO_QUEUE_SEL		0x030
+#define VIRTIO_MMIO_QUEUE_NUM_MAX	0x034
+#define VIRTIO_MMIO_QUEUE_NUM		0x038
+#define VIRTIO_MMIO_V1_QUEUE_ALIGN	0x03c
+#define VIRTIO_MMIO_V1_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_V2_QUEUE_DESC_LOW	0x080
+#define	VIRTIO_MMIO_V2_QUEUE_DESC_HIGH	0x084
+#define	VIRTIO_MMIO_V2_QUEUE_AVAIL_LOW	0x090
+#define	VIRTIO_MMIO_V2_QUEUE_AVAIL_HIGH	0x094
+#define	VIRTIO_MMIO_V2_QUEUE_USED_LOW	0x0a0
+#define	VIRTIO_MMIO_V2_QUEUE_USED_HIGH	0x0a4
+#define	VIRTIO_MMIO_V2_CONFIG_GEN	0x0fc
+#define VIRTIO_MMIO_CONFIG		0x100
+
 struct virtio_mmio_softc {
 	struct virtio_softc	sc_sc;

@@ -46,9 +78,20 @@ struct virtio_mmio_softc {

 };

+struct mmio_args {
+	bus_space_tag_t		bst;
+	uint64_t		sz;
+	paddr_t			baseaddr;
+	uint64_t		irq;
+	uint64_t		id;
+};
+
+uint32_t virtio_mmio_reg_read(struct virtio_mmio_softc *, bus_addr_t);
 bool virtio_mmio_common_probe_present(struct virtio_mmio_softc *);
 void virtio_mmio_common_attach(struct virtio_mmio_softc *);
 int virtio_mmio_common_detach(struct virtio_mmio_softc *, int);
 int virtio_mmio_intr(void *);

+extern int (*enumerate_mmio_devices)(struct mmio_args *);
+
 #endif /* _VIRTIO_MMIOVAR_H_ */

--->8---

------------------------------------------------------------------------
Emile `iMil' Heitor <imil@{home.imil.net,NetBSD.org}> | https://imil.net



Home | Main Index | Thread Index | Old Index