Module Name: src
Committed By: reinoud
Date: Mon Feb 15 22:39:46 UTC 2021
Modified Files:
src/sys/arch/evbmips/mipssim: autoconf.h machdep.c mainbus.c
mipssim_bus_io.c mipssim_intr.c mipssimreg.h mipssimvar.h
Added Files:
src/sys/arch/evbmips/mipssim: mipssim_dma.c virtio_mainbus.c
Log Message:
Add VirtIO devices to the MIPSSIM target for use in Qemu. Its supported by a
local patch starting at Qemu-5.1.0nb12
To generate a diff of this commit:
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/evbmips/mipssim/autoconf.h \
src/sys/arch/evbmips/mipssim/machdep.c \
src/sys/arch/evbmips/mipssim/mainbus.c \
src/sys/arch/evbmips/mipssim/mipssim_bus_io.c \
src/sys/arch/evbmips/mipssim/mipssim_intr.c \
src/sys/arch/evbmips/mipssim/mipssimreg.h \
src/sys/arch/evbmips/mipssim/mipssimvar.h
cvs rdiff -u -r0 -r1.1 src/sys/arch/evbmips/mipssim/mipssim_dma.c \
src/sys/arch/evbmips/mipssim/virtio_mainbus.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/evbmips/mipssim/autoconf.h
diff -u src/sys/arch/evbmips/mipssim/autoconf.h:1.1 src/sys/arch/evbmips/mipssim/autoconf.h:1.2
--- src/sys/arch/evbmips/mipssim/autoconf.h:1.1 Wed Jan 27 05:24:16 2021
+++ src/sys/arch/evbmips/mipssim/autoconf.h Mon Feb 15 22:39:46 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: autoconf.h,v 1.1 2021/01/27 05:24:16 simonb Exp $ */
+/* $NetBSD: autoconf.h,v 1.2 2021/02/15 22:39:46 reinoud Exp $ */
/*
* Copyright 2002 Wasabi Systems, Inc.
@@ -42,4 +42,5 @@ struct mainbus_attach_args {
unsigned long ma_addr;
int ma_irq;
bus_space_tag_t ma_iot;
+ bus_dma_tag_t ma_dmat;
};
Index: src/sys/arch/evbmips/mipssim/machdep.c
diff -u src/sys/arch/evbmips/mipssim/machdep.c:1.1 src/sys/arch/evbmips/mipssim/machdep.c:1.2
--- src/sys/arch/evbmips/mipssim/machdep.c:1.1 Wed Jan 27 05:24:16 2021
+++ src/sys/arch/evbmips/mipssim/machdep.c Mon Feb 15 22:39:46 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: machdep.c,v 1.1 2021/01/27 05:24:16 simonb Exp $ */
+/* $NetBSD: machdep.c,v 1.2 2021/02/15 22:39:46 reinoud Exp $ */
/*-
* Copyright (c) 2001,2021 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.1 2021/01/27 05:24:16 simonb Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.2 2021/02/15 22:39:46 reinoud Exp $");
#include "opt_ddb.h"
#include "opt_kgdb.h"
@@ -113,8 +113,11 @@ cal_timer(void)
{
uint32_t cntfreq;
- /* Pick a random clock frequency. XXX Any better way? */
- cntfreq = curcpu()->ci_cpu_freq = 10 * 1000 * 1000;
+ /*
+ * Qemu seems to default to 200 MHz; wall clock looks the right speed
+ * but we don't have an RTC to check.
+ */
+ cntfreq = curcpu()->ci_cpu_freq = 200 * 1000 * 1000;
if (mips_options.mips_cpu_flags & CPU_MIPS_DOUBLE_COUNT)
cntfreq /= 2;
@@ -157,6 +160,8 @@ mach_init(u_long arg0, u_long arg1, u_lo
* Initialize bus space tags and bring up the main console.
*/
mipssim_bus_io_init(&mcp->mc_iot, mcp);
+ mipssim_dma_init(mcp);
+
if (comcnattach(&mcp->mc_iot, MIPSSIM_UART0_ADDR, COMCNRATE,
COM_FREQ, COM_TYPE_NORMAL,
(TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8) != 0)
Index: src/sys/arch/evbmips/mipssim/mainbus.c
diff -u src/sys/arch/evbmips/mipssim/mainbus.c:1.1 src/sys/arch/evbmips/mipssim/mainbus.c:1.2
--- src/sys/arch/evbmips/mipssim/mainbus.c:1.1 Wed Jan 27 05:24:16 2021
+++ src/sys/arch/evbmips/mipssim/mainbus.c Mon Feb 15 22:39:46 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: mainbus.c,v 1.1 2021/01/27 05:24:16 simonb Exp $ */
+/* $NetBSD: mainbus.c,v 1.2 2021/02/15 22:39:46 reinoud Exp $ */
/*-
* Copyright (c) 2021 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mainbus.c,v 1.1 2021/01/27 05:24:16 simonb Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mainbus.c,v 1.2 2021/02/15 22:39:46 reinoud Exp $");
#include <sys/param.h>
#include <sys/device.h>
@@ -84,11 +84,23 @@ mainbus_attach(device_t parent, device_t
mainbus_found = 1;
printf("\n");
+ /* attach children */
for (md = mainbusdevs; md->md_name != NULL; md++) {
maa.ma_name = md->md_name;
maa.ma_addr = md->md_addr;
maa.ma_irq = md->md_irq;
maa.ma_iot = &mcp->mc_iot;
+ maa.ma_dmat = &mcp->mc_dmat;
+ config_found_ia(self, "mainbus", &maa, mainbus_print);
+ }
+
+ /* attach virtio children */
+ for (int i = 0; i < VIRTIO_NUM_TRANSPORTS; i++) {
+ maa.ma_name = "virtio";
+ maa.ma_addr = MIPSSIM_VIRTIO_ADDR + VIRTIO_STRIDE * i;
+ maa.ma_irq = 1;
+ maa.ma_iot = &mcp->mc_iot;
+ maa.ma_dmat = &mcp->mc_dmat;
config_found_ia(self, "mainbus", &maa, mainbus_print);
}
}
Index: src/sys/arch/evbmips/mipssim/mipssim_bus_io.c
diff -u src/sys/arch/evbmips/mipssim/mipssim_bus_io.c:1.1 src/sys/arch/evbmips/mipssim/mipssim_bus_io.c:1.2
--- src/sys/arch/evbmips/mipssim/mipssim_bus_io.c:1.1 Wed Jan 27 05:24:16 2021
+++ src/sys/arch/evbmips/mipssim/mipssim_bus_io.c Mon Feb 15 22:39:46 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: mipssim_bus_io.c,v 1.1 2021/01/27 05:24:16 simonb Exp $ */
+/* $NetBSD: mipssim_bus_io.c,v 1.2 2021/02/15 22:39:46 reinoud Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mipssim_bus_io.c,v 1.1 2021/01/27 05:24:16 simonb Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mipssim_bus_io.c,v 1.2 2021/02/15 22:39:46 reinoud Exp $");
#include <sys/param.h>
@@ -49,8 +49,8 @@ __KERNEL_RCSID(0, "$NetBSD: mipssim_bus_
/* IO region 1 */
#define CHIP_W1_BUS_START(v) 0
-#define CHIP_W1_BUS_END(v) MIPSSIM_ISA_IO_SIZE
+#define CHIP_W1_BUS_END(v) (MIPSSIM_ISA_IO_SIZE + MIPSSIM_VIRTIO_IO_SIZE)
#define CHIP_W1_SYS_START(v) MIPSSIM_ISA_IO_BASE
-#define CHIP_W1_SYS_END(v) (CHIP_W1_SYS_START(v) + CHIP_W1_SYS_START(v))
+#define CHIP_W1_SYS_END(v) (CHIP_W1_SYS_START(v) + CHIP_W1_BUS_END(v))
#include <mips/mips/bus_space_alignstride_chipdep.c>
Index: src/sys/arch/evbmips/mipssim/mipssim_intr.c
diff -u src/sys/arch/evbmips/mipssim/mipssim_intr.c:1.1 src/sys/arch/evbmips/mipssim/mipssim_intr.c:1.2
--- src/sys/arch/evbmips/mipssim/mipssim_intr.c:1.1 Wed Jan 27 05:24:16 2021
+++ src/sys/arch/evbmips/mipssim/mipssim_intr.c Mon Feb 15 22:39:46 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: mipssim_intr.c,v 1.1 2021/01/27 05:24:16 simonb Exp $ */
+/* $NetBSD: mipssim_intr.c,v 1.2 2021/02/15 22:39:46 reinoud Exp $ */
/*-
* Copyright (c) 2014 Michael Lorenz
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mipssim_intr.c,v 1.1 2021/01/27 05:24:16 simonb Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mipssim_intr.c,v 1.2 2021/02/15 22:39:46 reinoud Exp $");
#define __INTR_PRIVATE
@@ -35,6 +35,7 @@ __KERNEL_RCSID(0, "$NetBSD: mipssim_intr
#include <sys/cpu.h>
#include <sys/kernel.h>
#include <sys/systm.h>
+#include <sys/kmem.h>
#include <mips/locore.h>
#include <machine/intr.h>
@@ -49,10 +50,11 @@ static const struct ipl_sr_map mipssim_i
[IPL_SOFTCLOCK] = MIPS_SOFT_INT_MASK_0,
[IPL_SOFTNET] = MIPS_SOFT_INT_MASK,
[IPL_VM] = MIPS_SOFT_INT_MASK
- | MIPS_INT_MASK_0 | MIPS_INT_MASK_2,
+ | MIPS_INT_MASK_0 | MIPS_INT_MASK_1
+ | MIPS_INT_MASK_2,
[IPL_SCHED] = MIPS_SOFT_INT_MASK
- | MIPS_INT_MASK_0 | MIPS_INT_MASK_2
- | MIPS_INT_MASK_5,
+ | MIPS_INT_MASK_0 | MIPS_INT_MASK_1
+ | MIPS_INT_MASK_2 | MIPS_INT_MASK_5,
[IPL_DDB] = MIPS_INT_MASK,
[IPL_HIGH] = MIPS_INT_MASK,
},
@@ -61,7 +63,6 @@ static const struct ipl_sr_map mipssim_i
/* XXX - add evcnt bits to <machine/intr.h> struct evbmips_intrhand */
struct intrhand {
LIST_ENTRY(intrhand) ih_q;
- struct evcnt ih_count;
int (*ih_func)(void *);
void *ih_arg;
int ih_irq;
@@ -74,10 +75,12 @@ struct intrhand {
*/
#define NINTR 5 /* MIPS INT0 - INT4 */
-struct intrhand intrs[NINTR];
+LIST_HEAD(intrlist, intrhand) intrs[NINTR];
+struct evcnt ih_count[NINTR];
+
const char * const intrnames[NINTR] = {
"int 0 (mipsnet)",
- "int 1 (unused)",
+ "int 1 (virtio)",
"int 2 (uart)",
"int 3 (unused)",
"int 4 (unused)",
@@ -94,10 +97,8 @@ evbmips_intr_init(void)
/* zero all handlers */
for (i = 0; i < NINTR; i++) {
- intrs[i].ih_func = NULL;
- intrs[i].ih_arg = NULL;
- intrs[i].ih_irq = i;
- evcnt_attach_dynamic(&intrs[i].ih_count, EVCNT_TYPE_INTR,
+ LIST_INIT(&intrs[i]);
+ evcnt_attach_dynamic(&ih_count[i], EVCNT_TYPE_INTR,
NULL, "cpu", intrnames[i]);
}
}
@@ -105,6 +106,7 @@ evbmips_intr_init(void)
void
evbmips_iointr(int ipl, uint32_t ipending, struct clockframe *cf)
{
+ struct intrlist *list;
for (int level = NINTR - 1; level >= 0; level--) {
struct intrhand *ih;
@@ -112,11 +114,13 @@ evbmips_iointr(int ipl, uint32_t ipendin
if ((ipending & (MIPS_INT_MASK_0 << level)) == 0)
continue;
- ih = &intrs[level];
+ ih_count[level].ev_count++;
+ list = &intrs[level];
- ih->ih_count.ev_count++;
- if (ih->ih_func) {
- (*ih->ih_func)(ih->ih_arg);
+ LIST_FOREACH(ih, list, ih_q) {
+ if (ih->ih_func) {
+ (*ih->ih_func)(ih->ih_arg);
+ }
}
}
}
@@ -124,6 +128,7 @@ evbmips_iointr(int ipl, uint32_t ipendin
void *
evbmips_intr_establish(int irq, int (*func)(void *), void *arg)
{
+ struct intrlist *list;
struct intrhand *ih;
int s;
@@ -132,11 +137,15 @@ evbmips_intr_establish(int irq, int (*fu
return NULL;
}
- ih = &intrs[irq];
+ list = &intrs[irq];
+ ih = kmem_alloc(sizeof(struct intrhand), KM_SLEEP);
s = splhigh();
+
ih->ih_func = func;
ih->ih_arg = arg;
+ ih->ih_irq = irq;
+ LIST_INSERT_HEAD(list, ih, ih_q);
/* now enable the IRQ (nothing to do here?) */
@@ -159,6 +168,8 @@ evbmips_intr_disestablish(void *cookie)
ih->ih_func = NULL;
ih->ih_arg = NULL;
+ LIST_REMOVE(ih, ih_q);
+ kmem_free(ih, sizeof(struct intrhand));
splx(s);
}
Index: src/sys/arch/evbmips/mipssim/mipssimreg.h
diff -u src/sys/arch/evbmips/mipssim/mipssimreg.h:1.1 src/sys/arch/evbmips/mipssim/mipssimreg.h:1.2
--- src/sys/arch/evbmips/mipssim/mipssimreg.h:1.1 Wed Jan 27 05:24:16 2021
+++ src/sys/arch/evbmips/mipssim/mipssimreg.h Mon Feb 15 22:39:46 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: mipssimreg.h,v 1.1 2021/01/27 05:24:16 simonb Exp $ */
+/* $NetBSD: mipssimreg.h,v 1.2 2021/02/15 22:39:46 reinoud Exp $ */
/*-
* Copyright (c) 2021 The NetBSD Foundation, Inc.
@@ -35,15 +35,27 @@
*
* 0000.0000 128MB RAM (max ~500MB)
* 1fd0.0000 64kB ISA IO space
+ * 1fd1.0000 64kB 'ISA' VirtIO IO space (non standard)
*
* CPU interrupts
*
* 0 mipsnet
+ * 1 virtio
* 2 16450 UART
*/
-#define MIPSSIM_UART0_ADDR 0x3f8
-#define MIPSSIM_MIPSNET0_ADDR 0x4200
+#define MIPSSIM_UART0_ADDR 0x003f8
+#define MIPSSIM_MIPSNET0_ADDR 0x04200
+#define MIPSSIM_VIRTIO_ADDR 0x10000
#define MIPSSIM_ISA_IO_BASE 0x1fd00000 /* ISA IO memory: */
#define MIPSSIM_ISA_IO_SIZE 0x00010000 /* 64 kByte */
+#define MIPSSIM_VIRTIO_IO_SIZE 0x00010000 /* 64 kByte */
+
+#define MIPSSIM_DMA_BASE 0x00000000
+#define MIPSSIM_DMA_PHYSBASE 0x00000000
+#define MIPSSIM_DMA_SIZE (MIPSSIM_ISA_IO_BASE - MIPSSIM_DMA_BASE)
+
+#define VIRTIO_NUM_TRANSPORTS 32
+#define VIRTIO_STRIDE 512
+
Index: src/sys/arch/evbmips/mipssim/mipssimvar.h
diff -u src/sys/arch/evbmips/mipssim/mipssimvar.h:1.1 src/sys/arch/evbmips/mipssim/mipssimvar.h:1.2
--- src/sys/arch/evbmips/mipssim/mipssimvar.h:1.1 Wed Jan 27 05:24:16 2021
+++ src/sys/arch/evbmips/mipssim/mipssimvar.h Mon Feb 15 22:39:46 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: mipssimvar.h,v 1.1 2021/01/27 05:24:16 simonb Exp $ */
+/* $NetBSD: mipssimvar.h,v 1.2 2021/02/15 22:39:46 reinoud Exp $ */
/*-
* Copyright (c) 2001,2021 The NetBSD Foundation, Inc.
@@ -33,9 +33,10 @@
#include <dev/isa/isavar.h>
struct mipssim_config {
- struct mips_bus_space mc_iot;
+ struct mips_bus_space mc_iot;
+ struct mips_bus_dma_tag mc_dmat;
- struct mips_isa_chipset mc_ic;
+ struct mips_isa_chipset mc_ic;
struct extent *mc_io_ex;
@@ -45,3 +46,4 @@ struct mipssim_config {
extern struct mipssim_config mipssim_configuration;
void mipssim_bus_io_init(bus_space_tag_t, void *);
+void mipssim_dma_init(struct mipssim_config *);
Added files:
Index: src/sys/arch/evbmips/mipssim/mipssim_dma.c
diff -u /dev/null src/sys/arch/evbmips/mipssim/mipssim_dma.c:1.1
--- /dev/null Mon Feb 15 22:39:46 2021
+++ src/sys/arch/evbmips/mipssim/mipssim_dma.c Mon Feb 15 22:39:46 2021
@@ -0,0 +1,63 @@
+/* $NetBSD: mipssim_dma.c,v 1.1 2021/02/15 22:39:46 reinoud Exp $ */
+
+/*-
+ * Copyright (c) 2021 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe.
+ *
+ * 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.
+ */
+
+/*
+ * Platform-specific DMA support for the mipssim.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: mipssim_dma.c,v 1.1 2021/02/15 22:39:46 reinoud Exp $");
+
+#include <sys/param.h>
+#include <sys/device.h>
+
+#define _MIPS_BUS_DMA_PRIVATE
+#include <sys/bus.h>
+
+#include <dev/isa/isavar.h>
+
+#include <evbmips/mipssim/mipssimreg.h>
+#include <evbmips/mipssim/mipssimvar.h>
+
+void
+mipssim_dma_init(struct mipssim_config *mcp)
+{
+ bus_dma_tag_t t;
+
+ t = &mcp->mc_dmat;
+ t->_cookie = mcp;
+ t->_wbase = MIPSSIM_DMA_BASE;
+ t->_bounce_alloc_lo = MIPSSIM_DMA_PHYSBASE;
+ t->_bounce_alloc_hi = MIPSSIM_DMA_PHYSBASE + MIPSSIM_DMA_SIZE;
+ t->_dmamap_ops = mips_bus_dmamap_ops;
+ t->_dmamem_ops = mips_bus_dmamem_ops;
+ t->_dmatag_ops = mips_bus_dmatag_ops;
+}
Index: src/sys/arch/evbmips/mipssim/virtio_mainbus.c
diff -u /dev/null src/sys/arch/evbmips/mipssim/virtio_mainbus.c:1.1
--- /dev/null Mon Feb 15 22:39:46 2021
+++ src/sys/arch/evbmips/mipssim/virtio_mainbus.c Mon Feb 15 22:39:46 2021
@@ -0,0 +1,172 @@
+/* $NetBSD: virtio_mainbus.c,v 1.1 2021/02/15 22:39:46 reinoud Exp $ */
+
+/*
+ * Copyright (c) 2021 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Reinoud Zandijk
+ *
+ * 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: virtio_mainbus.c,v 1.1 2021/02/15 22:39:46 reinoud Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <sys/device.h>
+#include <evbmips/mipssim/autoconf.h>
+#include <evbmips/mipssim/mipssimreg.h>
+
+#define VIRTIO_PRIVATE
+#include <dev/virtio/virtio_mmiovar.h>
+
+
+static int virtio_mainbus_match(device_t, cfdata_t, void *);
+static void virtio_mainbus_attach(device_t, device_t, void *);
+static int virtio_mainbus_rescan(device_t, const char *, const int *);
+static int virtio_mainbus_detach(device_t, int);
+
+static int virtio_mainbus_setup_interrupts(struct virtio_mmio_softc *);
+static void virtio_mainbus_free_interrupts(struct virtio_mmio_softc *);
+
+struct virtio_mainbus_softc {
+ struct virtio_mmio_softc sc_msc;
+
+ int sc_irq;
+ void *sc_ih;
+};
+
+
+CFATTACH_DECL3_NEW(virtio_mainbus, sizeof(struct virtio_mainbus_softc),
+ virtio_mainbus_match, virtio_mainbus_attach,
+ virtio_mainbus_detach, NULL,
+ virtio_mainbus_rescan, (void *)voidop, DVF_DETACH_SHUTDOWN);
+
+
+static int
+virtio_mainbus_match(device_t parent, cfdata_t match, void *aux)
+{
+ struct mainbus_attach_args *ma = aux;
+
+ /* TODO can we check here if its present? */
+ if (strcmp(ma->ma_name, match->cf_name) == 0)
+ return (1<<1);
+
+ return (0);
+}
+
+
+void
+virtio_mainbus_attach(device_t parent, device_t self, void *aux)
+{
+ struct virtio_mainbus_softc *sc = device_private(self);
+ struct virtio_mmio_softc *msc = &sc->sc_msc;
+ struct virtio_softc *vsc = &msc->sc_sc;
+ struct mainbus_attach_args *ma = aux;
+ bus_space_handle_t ioh;
+
+ if (bus_space_map(ma->ma_iot, ma->ma_addr, VIRTIO_STRIDE, 0, &ioh) != 0) {
+ aprint_error(": can't map i/o space\n");
+ return;
+ }
+
+ aprint_normal("\n");
+ aprint_naive("\n");
+
+ sc->sc_irq = ma->ma_irq;
+
+ msc->sc_iot = ma->ma_iot;
+ msc->sc_ioh = ioh;
+ msc->sc_iosize = VIRTIO_STRIDE;
+ msc->sc_setup_interrupts = virtio_mainbus_setup_interrupts;
+ msc->sc_free_interrupts = virtio_mainbus_free_interrupts;
+
+ vsc->sc_dev = self;
+ vsc->sc_dmat = ma->ma_dmat;
+ if (virtio_mmio_common_probe_present(msc))
+ virtio_mmio_common_attach(msc);
+
+ virtio_mainbus_rescan(self, "virtio", NULL);
+}
+
+
+/* ARGSUSED */
+static int
+virtio_mainbus_rescan(device_t self, const char *attr, const int *scan_flags)
+{
+ struct virtio_mainbus_softc *sc = device_private(self);
+ struct virtio_mmio_softc *msc = &sc->sc_msc;
+ struct virtio_softc *vsc = &msc->sc_sc;
+ struct virtio_attach_args va;
+
+ if (vsc->sc_child) /* child already attached? */
+ return 0;
+
+ memset(&va, 0, sizeof(va));
+ va.sc_childdevid = vsc->sc_childdevid;
+
+ config_found_ia(self, attr, &va, NULL);
+
+ if (virtio_attach_failed(vsc))
+ return 0;
+ return 0;
+}
+
+
+static int
+virtio_mainbus_detach(device_t self, int flags)
+{
+ struct virtio_mainbus_softc *sc = device_private(self);
+ struct virtio_mmio_softc * const msc = &sc->sc_msc;
+
+ return virtio_mmio_common_detach(msc, flags);
+}
+
+
+static int
+virtio_mainbus_setup_interrupts(struct virtio_mmio_softc *msc)
+{
+ struct virtio_mainbus_softc *sc = (struct virtio_mainbus_softc *) msc;
+ struct virtio_softc * const vsc = &msc->sc_sc;
+
+ msc->sc_ih = evbmips_intr_establish(sc->sc_irq, virtio_mmio_intr,
+ msc);
+ if (msc->sc_ih == NULL) {
+ aprint_error_dev(vsc->sc_dev,
+ "couldn't install interrupt handler\n");
+ return -1;
+ }
+
+ aprint_normal_dev(vsc->sc_dev, "interrupting at irq %d\n", sc->sc_irq);
+
+ return 0;
+}
+
+
+static void
+virtio_mainbus_free_interrupts(struct virtio_mmio_softc *msc)
+{
+ panic("%s not implemented\n", __func__);
+}