From 0b692e79417510633878c41a7fee73c8a6eede77 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Mon, 30 Apr 2007 16:46:01 +0000 Subject: [PATCH] Reorder cpu interrupt enablement, do it in the code that drops the critical section during booting. Add a new interrupt controller ABI function 'cleanup' which is called after interrupts are enabled but before the critical section is dropped. --- sys/kern/init_main.c | 6 +++- sys/kern/kern_intr.c | 8 +++-- sys/platform/pc32/apic/apic_abi.c | 37 +++++++++++++++----- sys/platform/pc32/apic/apicvar.h | 9 +---- sys/platform/pc32/apic/mpapic.c | 10 +++++- sys/platform/pc32/i386/autoconf.c | 8 +---- sys/platform/pc32/icu/icu_abi.c | 43 +++++++++++++++++++----- sys/platform/vkernel/platform/machintr.c | 21 ++++++++---- sys/sys/machintr.h | 3 +- 9 files changed, 101 insertions(+), 44 deletions(-) diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index c1c197eeef..00f72929c6 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -40,7 +40,7 @@ * * @(#)init_main.c 8.9 (Berkeley) 1/21/94 * $FreeBSD: src/sys/kern/init_main.c,v 1.134.2.8 2003/06/06 20:21:32 tegge Exp $ - * $DragonFly: src/sys/kern/init_main.c,v 1.77 2007/04/30 07:18:53 dillon Exp $ + * $DragonFly: src/sys/kern/init_main.c,v 1.78 2007/04/30 16:45:53 dillon Exp $ */ #include "opt_init_path.h" @@ -62,6 +62,7 @@ #include #include #include +#include #include #include #include @@ -273,6 +274,9 @@ SYSINIT(announce, SI_BOOT1_COPYRIGHT, SI_ORDER_FIRST, print_caddr_t, copyright) static void leavecrit(void *dummy __unused) { + MachIntrABI.finalize(); + cpu_enable_intr(); + MachIntrABI.cleanup(); crit_exit(); KKASSERT(!IN_CRITICAL_SECT(curthread)); if (bootverbose) diff --git a/sys/kern/kern_intr.c b/sys/kern/kern_intr.c index f7e5f6cd7c..8f9458e314 100644 --- a/sys/kern/kern_intr.c +++ b/sys/kern/kern_intr.c @@ -24,7 +24,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/kern/kern_intr.c,v 1.24.2.1 2001/10/14 20:05:50 luigi Exp $ - * $DragonFly: src/sys/kern/kern_intr.c,v 1.47 2007/04/30 07:18:53 dillon Exp $ + * $DragonFly: src/sys/kern/kern_intr.c,v 1.48 2007/04/30 16:45:53 dillon Exp $ * */ @@ -487,7 +487,8 @@ sched_ithd(int intr) ++info->i_count; if (info->i_state != ISTATE_NOTHREAD) { if (info->i_reclist == NULL) { - kprintf("sched_ithd: stray interrupt %d\n", intr); + kprintf("sched_ithd: stray interrupt %d on cpu %d\n", + intr, mycpuid); } else { #ifdef SMP if (info->i_thread.td_gd == mycpu) { @@ -509,7 +510,8 @@ sched_ithd(int intr) #endif } } else { - kprintf("sched_ithd: stray interrupt %d\n", intr); + kprintf("sched_ithd: stray interrupt %d on cpu %d\n", + intr, mycpuid); } } diff --git a/sys/platform/pc32/apic/apic_abi.c b/sys/platform/pc32/apic/apic_abi.c index 3f774cc382..bcf3df594e 100644 --- a/sys/platform/pc32/apic/apic_abi.c +++ b/sys/platform/pc32/apic/apic_abi.c @@ -37,7 +37,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/platform/pc32/apic/apic_abi.c,v 1.11 2006/11/07 06:43:24 dillon Exp $ + * $DragonFly: src/sys/platform/pc32/apic/apic_abi.c,v 1.12 2007/04/30 16:45:55 dillon Exp $ */ #include @@ -46,12 +46,17 @@ #include #include #include + #include #include #include #include /* apic_8254_intr */ #include #include +#include + +#include + #include "apic_ipl.h" #ifdef APIC_IO @@ -105,6 +110,7 @@ static int apic_setvar(int, const void *); static int apic_getvar(int, void *); static int apic_vectorctl(int, int, int); static void apic_finalize(void); +static void apic_cleanup(void); static inthand_t *apic_fastintr[APIC_HWI_VECTORS] = { &IDTVEC(apic_fastintr0), &IDTVEC(apic_fastintr1), @@ -155,12 +161,13 @@ static int apic_imcr_present; struct machintr_abi MachIntrABI = { MACHINTR_APIC, - APIC_INTRDIS, - APIC_INTREN, - apic_vectorctl, - apic_setvar, - apic_getvar, - apic_finalize + .intrdis = APIC_INTRDIS, + .intren = APIC_INTREN, + .vectorctl = apic_vectorctl, + .setvar = apic_setvar, + .getvar = apic_getvar, + .finalize = apic_finalize, + .cleanup = apic_cleanup }; static int @@ -196,7 +203,9 @@ apic_getvar(int varid, void *buf) } /* - * Final configuration of the BSP's local APIC: + * Called before interrupts are physically enabled, this routine does the + * final configuration of the BSP's local APIC: + * * - disable 'pic mode'. * - disable 'virtual wire mode'. * - enable NMI. @@ -236,6 +245,18 @@ apic_finalize(void) apic_dump("bsp_apic_configure()"); } +/* + * This routine is called after physical interrupts are enabled but before + * the critical section is released. We need to clean out any interrupts + * that had already been posted to the cpu. + */ +static void +apic_cleanup(void) +{ + mdcpu->gd_fpending = 0; + mdcpu->gd_ipending = 0; +} + static int apic_vectorctl(int op, int intr, int flags) diff --git a/sys/platform/pc32/apic/apicvar.h b/sys/platform/pc32/apic/apicvar.h index 1215e56b85..f3d23b90eb 100644 --- a/sys/platform/pc32/apic/apicvar.h +++ b/sys/platform/pc32/apic/apicvar.h @@ -27,7 +27,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/i386/include/apicvar.h,v 1.5 2003/11/14 22:21:30 peter Exp $ - * $DragonFly: src/sys/platform/pc32/apic/apicvar.h,v 1.3 2007/01/22 19:37:04 corecode Exp $ + * $DragonFly: src/sys/platform/pc32/apic/apicvar.h,v 1.4 2007/04/30 16:45:55 dillon Exp $ */ #ifndef _MACHINE_APICVAR_H_ @@ -115,13 +115,6 @@ struct apic_enumerator { SLIST_ENTRY(apic_enumerator) apic_next; }; -#if 0 -inthand_t - IDTVEC(apic_isr1), IDTVEC(apic_isr2), IDTVEC(apic_isr3), - IDTVEC(apic_isr4), IDTVEC(apic_isr5), IDTVEC(apic_isr6), - IDTVEC(apic_isr7), IDTVEC(spuriousint); -#endif - u_int apic_irq_to_idt(u_int irq); u_int apic_idt_to_irq(u_int vector); void apic_register_enumerator(struct apic_enumerator *enumerator); diff --git a/sys/platform/pc32/apic/mpapic.c b/sys/platform/pc32/apic/mpapic.c index dddddee57b..31c6bf0d4c 100644 --- a/sys/platform/pc32/apic/mpapic.c +++ b/sys/platform/pc32/apic/mpapic.c @@ -23,7 +23,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/i386/i386/mpapic.c,v 1.37.2.7 2003/01/25 02:31:47 peter Exp $ - * $DragonFly: src/sys/platform/pc32/apic/mpapic.c,v 1.20 2006/12/23 00:27:03 swildner Exp $ + * $DragonFly: src/sys/platform/pc32/apic/mpapic.c,v 1.21 2007/04/30 16:45:55 dillon Exp $ */ #include @@ -127,6 +127,14 @@ apic_initialize(void) lapic.svr = temp; + /* + * Pump out a few EOIs to clean out interrupts that got through + * before we were able to set the TPR. + */ + lapic.eoi = 0; + lapic.eoi = 0; + lapic.eoi = 0; + if (bootverbose) apic_dump("apic_initialize()"); } diff --git a/sys/platform/pc32/i386/autoconf.c b/sys/platform/pc32/i386/autoconf.c index 45f4c48226..c16e64b64b 100644 --- a/sys/platform/pc32/i386/autoconf.c +++ b/sys/platform/pc32/i386/autoconf.c @@ -35,7 +35,7 @@ * * from: @(#)autoconf.c 7.1 (Berkeley) 5/9/91 * $FreeBSD: src/sys/i386/i386/autoconf.c,v 1.146.2.2 2001/06/07 06:05:58 dd Exp $ - * $DragonFly: src/sys/platform/pc32/i386/autoconf.c,v 1.34 2006/12/23 00:27:03 swildner Exp $ + * $DragonFly: src/sys/platform/pc32/i386/autoconf.c,v 1.35 2007/04/30 16:45:56 dillon Exp $ */ /* @@ -122,12 +122,6 @@ configure_first(void *dummy) static void configure(void *dummy) { - /* - * Final interrupt support acviation, then enable hardware interrupts. - */ - MachIntrABI.finalize(); - cpu_enable_intr(); - /* * This will configure all devices, generally starting with the * nexus (i386/i386/nexus.c). The nexus ISA code explicitly diff --git a/sys/platform/pc32/icu/icu_abi.c b/sys/platform/pc32/icu/icu_abi.c index 43e20f1466..be223c8968 100644 --- a/sys/platform/pc32/icu/icu_abi.c +++ b/sys/platform/pc32/icu/icu_abi.c @@ -36,7 +36,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/platform/pc32/icu/icu_abi.c,v 1.11 2006/11/07 06:43:24 dillon Exp $ + * $DragonFly: src/sys/platform/pc32/icu/icu_abi.c,v 1.12 2007/04/30 16:45:58 dillon Exp $ */ #include @@ -49,6 +49,9 @@ #include #include #include +#include + +#include #include "icu.h" #include "icu_ipl.h" @@ -82,6 +85,7 @@ static int icu_vectorctl(int, int, int); static int icu_setvar(int, const void *); static int icu_getvar(int, void *); static void icu_finalize(void); +static void icu_cleanup(void); static inthand_t *icu_fastintr[ICU_HWI_VECTORS] = { &IDTVEC(icu_fastintr0), &IDTVEC(icu_fastintr1), @@ -107,12 +111,13 @@ static inthand_t *icu_slowintr[ICU_HWI_VECTORS] = { struct machintr_abi MachIntrABI = { MACHINTR_ICU, - ICU_INTRDIS, - ICU_INTREN, - icu_vectorctl, - icu_setvar, - icu_getvar, - icu_finalize + .intrdis = ICU_INTRDIS, + .intren = ICU_INTREN, + .vectorctl =icu_vectorctl, + .setvar = icu_setvar, + .getvar = icu_getvar, + .finalize = icu_finalize, + .cleanup = icu_cleanup }; static int icu_imcr_present; @@ -120,7 +125,6 @@ static int icu_imcr_present; /* * WARNING! SMP builds can use the ICU now so this code must be MP safe. */ - static int icu_setvar(int varid __unused, const void *buf __unused) @@ -155,9 +159,17 @@ icu_getvar(int varid __unused, void *buf __unused) return (error); } +/* + * Called before interrupts are physically enabled + */ static void icu_finalize(void) { + int intr; + + for (intr = 0; intr < ICU_HWI_VECTORS; ++intr) { + machintr_intrdis(intr); + } machintr_intren(ICU_IRQ_SLAVE); /* @@ -177,6 +189,21 @@ icu_finalize(void) } } +/* + * Called after interrupts physically enabled but before the + * critical section is released. + */ +static +void +icu_cleanup(void) +{ + kprintf("fpending %08x ipending %08x\n", + mdcpu->gd_fpending, mdcpu->gd_ipending); + mdcpu->gd_fpending = 0; + mdcpu->gd_ipending = 0; +} + + static int icu_vectorctl(int op, int intr, int flags) diff --git a/sys/platform/vkernel/platform/machintr.c b/sys/platform/vkernel/platform/machintr.c index c165f812c4..d606937958 100644 --- a/sys/platform/vkernel/platform/machintr.c +++ b/sys/platform/vkernel/platform/machintr.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/platform/vkernel/platform/machintr.c,v 1.10 2007/01/15 01:29:04 dillon Exp $ + * $DragonFly: src/sys/platform/vkernel/platform/machintr.c,v 1.11 2007/04/30 16:45:59 dillon Exp $ */ #include @@ -56,15 +56,17 @@ static int dummy_vectorctl(int, int, int); static int dummy_setvar(int, const void *); static int dummy_getvar(int, void *); static void dummy_finalize(void); +static void dummy_intrcleanup(void); struct machintr_abi MachIntrABI = { MACHINTR_GENERIC, - dummy_intrdis, - dummy_intren, - dummy_vectorctl, - dummy_setvar, - dummy_getvar, - dummy_finalize + .intrdis = dummy_intrdis, + .intren = dummy_intren, + .vectorctl = dummy_vectorctl, + .setvar = dummy_setvar, + .getvar = dummy_getvar, + .finalize = dummy_finalize, + .cleanup = dummy_intrcleanup }; static void @@ -101,6 +103,11 @@ dummy_finalize(void) { } +static void +dummy_intrcleanup(void) +{ +} + /* * Process pending interrupts */ diff --git a/sys/sys/machintr.h b/sys/sys/machintr.h index 0ed2667a1e..33e8ee0653 100644 --- a/sys/sys/machintr.h +++ b/sys/sys/machintr.h @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/sys/machintr.h,v 1.6 2006/12/05 17:06:15 dillon Exp $ + * $DragonFly: src/sys/sys/machintr.h,v 1.7 2007/04/30 16:46:01 dillon Exp $ */ /* * This module defines the ABI for the machine-independant cpu interrupt @@ -63,6 +63,7 @@ struct machintr_abi { int (*setvar)(int, const void *); /* set miscellanious info */ int (*getvar)(int, void *); /* get miscellanious info */ void (*finalize)(void); /* final before ints enabled */ + void (*cleanup)(void); /* cleanup */ }; #define machintr_intren(intr) MachIntrABI.intren(intr) -- 2.41.0