Module Name: src Committed By: thorpej Date: Tue Jan 16 07:07:00 UTC 2024
Modified Files: src/sys/arch/hp300/dev: dio.c dma.c dmavar.h src/sys/arch/hp300/hp300: autoconf.c src/sys/arch/hp300/include: intr.h Log Message: Fix computation of the appropriate auto-vector interrupt level to use for the DMA controller by tracking all of the DIO devices that have "ISRPRI_BIO" interrupt handlers, and finding the highest auto-vector level among them and informing the DMA controller. Previously, in a post-flattening world, the DMA controller was always told to interrupt at lev5, which is fine I guess although definitely not ideal, but would not work on aaaancient HP320 Rev A DMA boards. To that effect, print a warning if a Rev B DMA board ends up at ipl != 3 (we can't differentiate between a Rev A and a Rev B board). To generate a diff of this commit: cvs rdiff -u -r1.42 -r1.43 src/sys/arch/hp300/dev/dio.c cvs rdiff -u -r1.46 -r1.47 src/sys/arch/hp300/dev/dma.c cvs rdiff -u -r1.14 -r1.15 src/sys/arch/hp300/dev/dmavar.h cvs rdiff -u -r1.111 -r1.112 src/sys/arch/hp300/hp300/autoconf.c cvs rdiff -u -r1.37 -r1.38 src/sys/arch/hp300/include/intr.h 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/hp300/dev/dio.c diff -u src/sys/arch/hp300/dev/dio.c:1.42 src/sys/arch/hp300/dev/dio.c:1.43 --- src/sys/arch/hp300/dev/dio.c:1.42 Tue Jan 16 03:44:43 2024 +++ src/sys/arch/hp300/dev/dio.c Tue Jan 16 07:06:59 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: dio.c,v 1.42 2024/01/16 03:44:43 thorpej Exp $ */ +/* $NetBSD: dio.c,v 1.43 2024/01/16 07:06:59 thorpej Exp $ */ /*- * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc. @@ -34,7 +34,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: dio.c,v 1.42 2024/01/16 03:44:43 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: dio.c,v 1.43 2024/01/16 07:06:59 thorpej Exp $"); #define _M68K_INTR_PRIVATE @@ -78,6 +78,9 @@ static int diosubmatch(device_t, cfdata_ CFATTACH_DECL_NEW(dio, sizeof(struct dio_softc), diomatch, dioattach, NULL, NULL); +static LIST_HEAD(, hp300_intrhand) dio_dma_users = + LIST_HEAD_INITIALIZER(dio_dma_users); + static int diomatch(device_t parent, cfdata_t cf, void *aux) { @@ -280,18 +283,40 @@ dio_devinfo(struct dio_attach_args *da, } /* + * Enumerate the list of DMA controller users (the HPIB and SCSI + * controllers, essentially), and calculate what the highest + * auto-vector level used by those devices is. Then tell the DMA + * controller to interrupt at that level. + */ +static void +dio_dma_users_changed(void) +{ + struct hp300_intrhand *ih; + int ipl = 0; + + LIST_FOREACH(ih, &dio_dma_users, ih_dio_link) { + KASSERT(ih->ih_super.ih_isrpri == ISRPRI_BIO); + if (ih->ih_super.ih_ipl > ipl) { + ipl = ih->ih_super.ih_ipl; + } + } + dmaupdateipl(ipl); +} + +/* * Establish an interrupt handler for a DIO device. */ void * dio_intr_establish(int (*func)(void *), void *arg, int ipl, int isrpri) { - void *ih; + struct hp300_intrhand *ih; ih = intr_establish(func, arg, ipl, isrpri); - /* XXX XXX XXX */ - if (isrpri == IPL_BIO) - dmacomputeipl(); + if (ih != NULL && isrpri == ISRPRI_BIO) { + LIST_INSERT_HEAD(&dio_dma_users, ih, ih_dio_link); + dio_dma_users_changed(); + } return ih; } @@ -302,14 +327,18 @@ dio_intr_establish(int (*func)(void *), void dio_intr_disestablish(void *arg) { - struct m68k_intrhand *ih = arg; - int isrpri = ih->ih_isrpri; + struct hp300_intrhand *ih = arg; + int isrpri = ih->ih_super.ih_isrpri; + + if (isrpri == ISRPRI_BIO) { + LIST_REMOVE(ih, ih_dio_link); + } intr_disestablish(arg); - /* XXX XXX XXX */ - if (isrpri == IPL_BIO) - dmacomputeipl(); + if (isrpri == ISRPRI_BIO) { + dio_dma_users_changed(); + } } /* Index: src/sys/arch/hp300/dev/dma.c diff -u src/sys/arch/hp300/dev/dma.c:1.46 src/sys/arch/hp300/dev/dma.c:1.47 --- src/sys/arch/hp300/dev/dma.c:1.46 Tue Jan 16 05:48:28 2024 +++ src/sys/arch/hp300/dev/dma.c Tue Jan 16 07:06:59 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: dma.c,v 1.46 2024/01/16 05:48:28 thorpej Exp $ */ +/* $NetBSD: dma.c,v 1.47 2024/01/16 07:06:59 thorpej Exp $ */ /*- * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc. @@ -67,7 +67,7 @@ #include "opt_m68k_arch.h" #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: dma.c,v 1.46 2024/01/16 05:48:28 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: dma.c,v 1.47 2024/01/16 07:06:59 thorpej Exp $"); #include <machine/hp300spu.h> /* XXX param.h includes cpu.h */ @@ -263,19 +263,30 @@ dmaattach(device_t parent, device_t self * for the DMA controller. */ void -dmacomputeipl(void) +dmaupdateipl(int ipl) { struct dma_softc *sc = dma_softc; - if (sc->sc_ih != NULL) + if (sc->sc_ih != NULL && sc->sc_ipl == ipl) { + /* No change. */ + return; + } + + if (sc->sc_ih != NULL) { intr_disestablish(sc->sc_ih); + } + + if ((sc->sc_ipl == ipl) == 0) { + /* Don't hook up a new handler. */ + return; + } - /* - * Our interrupt level must be as high as the highest - * device using DMA (i.e. splbio). - */ - sc->sc_ipl = PSLTOIPL(ipl2psl_table[IPL_VM]); sc->sc_ih = intr_establish(dmaintr, sc, sc->sc_ipl, ISRPRI_BIO); + if (sc->sc_type == DMA_B && sc->sc_ipl != 3) { + aprint_error_dev(sc->sc_dev, + "WARNING: IPL set to %d on maybe-rev. A card!\n", + sc->sc_ipl); + } } int Index: src/sys/arch/hp300/dev/dmavar.h diff -u src/sys/arch/hp300/dev/dmavar.h:1.14 src/sys/arch/hp300/dev/dmavar.h:1.15 --- src/sys/arch/hp300/dev/dmavar.h:1.14 Mon Apr 28 20:23:19 2008 +++ src/sys/arch/hp300/dev/dmavar.h Tue Jan 16 07:06:59 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: dmavar.h,v 1.14 2008/04/28 20:23:19 martin Exp $ */ +/* $NetBSD: dmavar.h,v 1.15 2024/01/16 07:06:59 thorpej Exp $ */ /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. @@ -98,5 +98,5 @@ void dmago(int, char *, int, int); void dmastop(int); void dmafree(struct dmaqueue *); int dmareq(struct dmaqueue *); -void dmacomputeipl(void); +void dmaupdateipl(int); #endif /* _KERNEL */ Index: src/sys/arch/hp300/hp300/autoconf.c diff -u src/sys/arch/hp300/hp300/autoconf.c:1.111 src/sys/arch/hp300/hp300/autoconf.c:1.112 --- src/sys/arch/hp300/hp300/autoconf.c:1.111 Sun Jan 15 06:19:46 2023 +++ src/sys/arch/hp300/hp300/autoconf.c Tue Jan 16 07:07:00 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: autoconf.c,v 1.111 2023/01/15 06:19:46 tsutsui Exp $ */ +/* $NetBSD: autoconf.c,v 1.112 2024/01/16 07:07:00 thorpej Exp $ */ /*- * Copyright (c) 1996, 1997, 2002 The NetBSD Foundation, Inc. @@ -88,7 +88,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.111 2023/01/15 06:19:46 tsutsui Exp $"); +__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.112 2024/01/16 07:07:00 thorpej Exp $"); #include "dvbox.h" #include "gbox.h" @@ -102,6 +102,8 @@ __KERNEL_RCSID(0, "$NetBSD: autoconf.c,v #include "com_frodo.h" #include "dcm.h" +#define _M68K_INTR_PRIVATE + #include <sys/param.h> #include <sys/systm.h> #include <sys/buf.h> @@ -274,6 +276,30 @@ mainbussearch(device_t parent, cfdata_t } /* + * hp300 systems need to track all DIO interrupt handlers on a single + * list in order to compute the auto-vector interrupt level the DMA + * controller should interrupt at. So, we provide a custom allocator + * for the common interrupt dispatch code that allocates us handles + * with linkage for this list. + */ +static struct m68k_intrhand * +hp300_ih_alloc(int km_flag) +{ + return kmem_zalloc(sizeof(struct hp300_intrhand), km_flag); +} + +static void +hp300_ih_free(struct m68k_intrhand *ih) +{ + kmem_free(ih, sizeof(struct hp300_intrhand)); +} + +static const struct m68k_ih_allocfuncs hp300_ih_allocfuncs = { + .alloc = hp300_ih_alloc, + .free = hp300_ih_free, +}; + +/* * Determine the device configuration for the running system. */ void @@ -291,7 +317,7 @@ cpu_configure(void) (void)splhigh(); /* Initialize the interrupt handlers. */ - intr_init(); + m68k_intr_init(&hp300_ih_allocfuncs); if (config_rootfound("mainbus", NULL) == NULL) panic("no mainbus found"); Index: src/sys/arch/hp300/include/intr.h diff -u src/sys/arch/hp300/include/intr.h:1.37 src/sys/arch/hp300/include/intr.h:1.38 --- src/sys/arch/hp300/include/intr.h:1.37 Tue Jan 16 03:44:44 2024 +++ src/sys/arch/hp300/include/intr.h Tue Jan 16 07:07:00 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: intr.h,v 1.37 2024/01/16 03:44:44 thorpej Exp $ */ +/* $NetBSD: intr.h,v 1.38 2024/01/16 07:07:00 thorpej Exp $ */ /*- * Copyright (c) 2024 The NetBSD Foundation, Inc. @@ -60,6 +60,13 @@ #include <m68k/intr.h> +#ifdef _M68K_INTR_PRIVATE +struct hp300_intrhand { + struct m68k_intrhand ih_super; + LIST_ENTRY(hp300_intrhand) ih_dio_link; +}; +#endif + /* These spl calls are _not_ to be used by machine-independent code. */ #define splhil() splraise1() #define splkbd() splhil() @@ -68,12 +75,6 @@ * Interface wrappers. */ -static inline void -intr_init(void) -{ - m68k_intr_init(NULL); -} - static inline void * intr_establish(int (*func)(void *), void *arg, int ipl, int isrpri) {