diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2008-05-07 20:42:03 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2008-05-07 20:42:03 +0000 |
commit | 034625334503f3d798a17bde780904df9c17fd4a (patch) | |
tree | a95d0a30e3d84d89d37679d5900e917097c66886 /sys | |
parent | 51605671e44753905382328d274f0846612ddafa (diff) |
Move i386 to __HAVE_GENERIC_SOFT_INTERRUPTS
ok dlg@, tested by dlg@, oga@, jsg@, deraadt@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/i386/conf/files.i386 | 3 | ||||
-rw-r--r-- | sys/arch/i386/i386/apicvec.s | 11 | ||||
-rw-r--r-- | sys/arch/i386/i386/machdep.c | 13 | ||||
-rw-r--r-- | sys/arch/i386/i386/softintr.c | 168 | ||||
-rw-r--r-- | sys/arch/i386/include/_types.h | 3 | ||||
-rw-r--r-- | sys/arch/i386/include/intr.h | 70 | ||||
-rw-r--r-- | sys/arch/i386/isa/icu.s | 11 |
7 files changed, 261 insertions, 18 deletions
diff --git a/sys/arch/i386/conf/files.i386 b/sys/arch/i386/conf/files.i386 index 025faf337d0..b84bda356a3 100644 --- a/sys/arch/i386/conf/files.i386 +++ b/sys/arch/i386/conf/files.i386 @@ -1,4 +1,4 @@ -# $OpenBSD: files.i386,v 1.177 2008/04/25 14:51:35 jmc Exp $ +# $OpenBSD: files.i386,v 1.178 2008/05/07 20:42:02 kettenis Exp $ # # new style config file for i386 architecture # @@ -39,6 +39,7 @@ file arch/i386/i386/random.s file arch/i386/i386/sys_machdep.c file arch/i386/i386/trap.c file arch/i386/i386/vm_machdep.c +file arch/i386/i386/softintr.c file arch/i386/i386/dkcsum.c bios file lib/libz/adler32.c !ppp_deflate & !ipsec & !crypto file dev/cninit.c diff --git a/sys/arch/i386/i386/apicvec.s b/sys/arch/i386/i386/apicvec.s index 122c82d1aa4..8e827c19e2a 100644 --- a/sys/arch/i386/i386/apicvec.s +++ b/sys/arch/i386/i386/apicvec.s @@ -1,4 +1,4 @@ -/* $OpenBSD: apicvec.s,v 1.13 2008/04/26 14:33:27 kettenis Exp $ */ +/* $OpenBSD: apicvec.s,v 1.14 2008/05/07 20:42:02 kettenis Exp $ */ /* $NetBSD: apicvec.s,v 1.1.2.2 2000/02/21 21:54:01 sommerfeld Exp $ */ /*- @@ -175,7 +175,9 @@ XINTR(softclock): #ifdef MULTIPROCESSOR call _C_LABEL(i386_softintlock) #endif - call _C_LABEL(softclock) + pushl $I386_SOFTINTR_SOFTCLOCK + call _C_LABEL(softintr_dispatch) + addl $4,%esp #ifdef MULTIPROCESSOR call _C_LABEL(i386_softintunlock) #endif @@ -203,7 +205,12 @@ XINTR(softnet): #endif xorl %edi,%edi xchgl _C_LABEL(netisr),%edi + #include <net/netisr_dispatch.h> + + pushl $I386_SOFTINTR_SOFTNET + call _C_LABEL(softintr_dispatch) + addl $4,%esp #ifdef MULTIPROCESSOR call _C_LABEL(i386_softintunlock) #endif diff --git a/sys/arch/i386/i386/machdep.c b/sys/arch/i386/i386/machdep.c index d2847594867..db5b042a6d9 100644 --- a/sys/arch/i386/i386/machdep.c +++ b/sys/arch/i386/i386/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.426 2008/04/25 19:50:07 kettenis Exp $ */ +/* $OpenBSD: machdep.c,v 1.427 2008/05/07 20:42:02 kettenis Exp $ */ /* $NetBSD: machdep.c,v 1.214 1996/11/10 03:16:17 thorpej Exp $ */ /*- @@ -3139,6 +3139,8 @@ init386(paddr_t first_avail) kgdb_connect(1); } #endif /* KGDB */ + + softintr_init(); } /* @@ -4226,15 +4228,12 @@ i386_softintunlock(void) * We hand-code this to ensure that it's atomic. */ void -softintr(int sir, int vec) +softintr(int sir) { struct cpu_info *ci = curcpu(); - __asm __volatile("orl %1, %0" : "=m" (ci->ci_ipending) : "ir" (sir)); -#ifdef MULTIPROCESSOR - i82489_writereg(LAPIC_ICRLO, - vec | LAPIC_DLMODE_FIXED | LAPIC_LVL_ASSERT | LAPIC_DEST_SELF); -#endif + __asm __volatile("orl %1, %0" : + "=m" (ci->ci_ipending) : "ir" (1 << sir)); } /* diff --git a/sys/arch/i386/i386/softintr.c b/sys/arch/i386/i386/softintr.c new file mode 100644 index 00000000000..c071c3ef36d --- /dev/null +++ b/sys/arch/i386/i386/softintr.c @@ -0,0 +1,168 @@ +/* $OpenBSD: softintr.c,v 1.1 2008/05/07 20:42:02 kettenis Exp $ */ +/* $NetBSD: softintr.c,v 1.1 2003/02/26 21:26:12 fvdl Exp $ */ + +/*- + * Copyright (c) 2000, 2001 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 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. + */ + +/* + * Generic soft interrupt implementation for NetBSD/x86. + */ + +#include <sys/param.h> +#include <sys/malloc.h> + +#include <machine/intr.h> + +#include <uvm/uvm_extern.h> + +struct i386_soft_intr i386_soft_intrs[I386_NSOFTINTR]; + +const int i386_soft_intr_to_ssir[I386_NSOFTINTR] = { + SIR_CLOCK, + SIR_NET, + SIR_TTY, +}; + +/* + * softintr_init: + * + * Initialize the software interrupt system. + */ +void +softintr_init(void) +{ + struct i386_soft_intr *si; + int i; + + for (i = 0; i < I386_NSOFTINTR; i++) { + si = &i386_soft_intrs[i]; + TAILQ_INIT(&si->softintr_q); + simple_lock_init(&si->softintr_slock); + si->softintr_ssir = i386_soft_intr_to_ssir[i]; + } +} + +/* + * softintr_dispatch: + * + * Process pending software interrupts. + */ +void +softintr_dispatch(int which) +{ + struct i386_soft_intr *si = &i386_soft_intrs[which]; + struct i386_soft_intrhand *sih; + int s; + + for (;;) { + i386_softintr_lock(si, s); + sih = TAILQ_FIRST(&si->softintr_q); + if (sih == NULL) { + i386_softintr_unlock(si, s); + break; + } + TAILQ_REMOVE(&si->softintr_q, sih, sih_q); + sih->sih_pending = 0; + i386_softintr_unlock(si, s); + + uvmexp.softs++; + (*sih->sih_fn)(sih->sih_arg); + } +} + +/* + * softintr_establish: [interface] + * + * Register a software interrupt handler. + */ +void * +softintr_establish(int ipl, void (*func)(void *), void *arg) +{ + struct i386_soft_intr *si; + struct i386_soft_intrhand *sih; + int which; + + switch (ipl) { + case IPL_SOFTCLOCK: + which = I386_SOFTINTR_SOFTCLOCK; + break; + + case IPL_SOFTNET: + which = I386_SOFTINTR_SOFTNET; + break; + + case IPL_TTY: + case IPL_SOFTTTY: + which = I386_SOFTINTR_SOFTTTY; + break; + + default: + panic("softintr_establish"); + } + + si = &i386_soft_intrs[which]; + + sih = malloc(sizeof(*sih), M_DEVBUF, M_NOWAIT); + if (__predict_true(sih != NULL)) { + sih->sih_intrhead = si; + sih->sih_fn = func; + sih->sih_arg = arg; + sih->sih_pending = 0; + } + return (sih); +} + +/* + * softintr_disestablish: [interface] + * + * Unregister a software interrupt handler. + */ +void +softintr_disestablish(void *arg) +{ + struct i386_soft_intrhand *sih = arg; + struct i386_soft_intr *si = sih->sih_intrhead; + int s; + + i386_softintr_lock(si, s); + if (sih->sih_pending) { + TAILQ_REMOVE(&si->softintr_q, sih, sih_q); + sih->sih_pending = 0; + } + i386_softintr_unlock(si, s); + + free(sih, M_DEVBUF); +} diff --git a/sys/arch/i386/include/_types.h b/sys/arch/i386/include/_types.h index 4fc270e483e..81481c9162f 100644 --- a/sys/arch/i386/include/_types.h +++ b/sys/arch/i386/include/_types.h @@ -1,4 +1,4 @@ -/* $OpenBSD: _types.h,v 1.7 2007/05/16 17:27:30 art Exp $ */ +/* $OpenBSD: _types.h,v 1.8 2008/05/07 20:42:02 kettenis Exp $ */ /*- * Copyright (c) 1990, 1993 @@ -115,6 +115,7 @@ typedef void * __wctrans_t; typedef void * __wctype_t; /* Feature test macros */ +#define __HAVE_GENERIC_SOFT_INTERRUPTS #define __HAVE_TIMECOUNTER #endif /* _I386__TYPES_H_ */ diff --git a/sys/arch/i386/include/intr.h b/sys/arch/i386/include/intr.h index 5a701e1ca90..62ad4908849 100644 --- a/sys/arch/i386/include/intr.h +++ b/sys/arch/i386/include/intr.h @@ -1,4 +1,4 @@ -/* $OpenBSD: intr.h,v 1.34 2008/04/25 19:50:08 kettenis Exp $ */ +/* $OpenBSD: intr.h,v 1.35 2008/05/07 20:42:02 kettenis Exp $ */ /* $NetBSD: intr.h,v 1.5 1996/05/13 06:11:28 mycroft Exp $ */ /* @@ -56,7 +56,7 @@ extern void Xspllower(void); extern int splraise(int); extern int spllower(int); extern void splx(int); -extern void softintr(int, int); +extern void softintr(int); /* * compiler barrier: prevent reordering of instructions. @@ -128,9 +128,8 @@ void splassert_check(int, const char *); #define spllock() splhigh() #define spl0() spllower(IPL_NONE) -#define setsoftclock() softintr(1 << SIR_CLOCK, IPL_SOFTCLOCK) -#define setsoftnet() softintr(1 << SIR_NET, IPL_SOFTNET) -#define setsofttty() softintr(1 << SIR_TTY, IPL_SOFTTTY) +#define setsoftnet() softintr(SIR_NET) +#define setsofttty() softintr(SIR_TTY) struct cpu_info; @@ -151,4 +150,65 @@ extern void (*ipifunc[I386_NIPI])(struct cpu_info *); #endif /* !_LOCORE */ +/* + * Generic software interrupt support. + */ + +#define I386_SOFTINTR_SOFTCLOCK 0 +#define I386_SOFTINTR_SOFTNET 1 +#define I386_SOFTINTR_SOFTTTY 2 +#define I386_NSOFTINTR 3 + +#ifndef _LOCORE +#include <sys/queue.h> + +struct i386_soft_intrhand { + TAILQ_ENTRY(i386_soft_intrhand) + sih_q; + struct i386_soft_intr *sih_intrhead; + void (*sih_fn)(void *); + void *sih_arg; + int sih_pending; +}; + +struct i386_soft_intr { + TAILQ_HEAD(, i386_soft_intrhand) + softintr_q; + int softintr_ssir; + struct simplelock softintr_slock; +}; + +#define i386_softintr_lock(si, s) \ +do { \ + (s) = splhigh(); \ + simple_lock(&si->softintr_slock); \ +} while (/*CONSTCOND*/ 0) + +#define i386_softintr_unlock(si, s) \ +do { \ + simple_unlock(&si->softintr_slock); \ + splx((s)); \ +} while (/*CONSTCOND*/ 0) + +void *softintr_establish(int, void (*)(void *), void *); +void softintr_disestablish(void *); +void softintr_init(void); +void softintr_dispatch(int); + +#define softintr_schedule(arg) \ +do { \ + struct i386_soft_intrhand *__sih = (arg); \ + struct i386_soft_intr *__si = __sih->sih_intrhead; \ + int __s; \ + \ + i386_softintr_lock(__si, __s); \ + if (__sih->sih_pending == 0) { \ + TAILQ_INSERT_TAIL(&__si->softintr_q, __sih, sih_q); \ + __sih->sih_pending = 1; \ + softintr(__si->softintr_ssir); \ + } \ + i386_softintr_unlock(__si, __s); \ +} while (/*CONSTCOND*/ 0) +#endif /* _LOCORE */ + #endif /* !_I386_INTR_H_ */ diff --git a/sys/arch/i386/isa/icu.s b/sys/arch/i386/isa/icu.s index 5b448e0781e..02612a94cba 100644 --- a/sys/arch/i386/isa/icu.s +++ b/sys/arch/i386/isa/icu.s @@ -1,4 +1,4 @@ -/* $OpenBSD: icu.s,v 1.27 2008/04/26 14:33:27 kettenis Exp $ */ +/* $OpenBSD: icu.s,v 1.28 2008/05/07 20:42:02 kettenis Exp $ */ /* $NetBSD: icu.s,v 1.45 1996/01/07 03:59:34 mycroft Exp $ */ /*- @@ -152,7 +152,12 @@ IDTVEC(softnet) #endif xorl %edi,%edi xchgl _C_LABEL(netisr),%edi + #include <net/netisr_dispatch.h> + + pushl $I386_SOFTINTR_SOFTNET + call _C_LABEL(softintr_dispatch) + addl $4,%esp #ifdef MULTIPROCESSOR call _C_LABEL(i386_softintunlock) #endif @@ -166,7 +171,9 @@ IDTVEC(softclock) #ifdef MULTIPROCESSOR call _C_LABEL(i386_softintlock) #endif - call _C_LABEL(softclock) + pushl $I386_SOFTINTR_SOFTCLOCK + call _C_LABEL(softintr_dispatch) + addl $4,%esp #ifdef MULTIPROCESSOR call _C_LABEL(i386_softintunlock) #endif |