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__); +}