Module Name: src Committed By: matt Date: Tue Jun 14 22:36:13 UTC 2011
Modified Files: src/sys/arch/powerpc/booke: e500_intr.c src/sys/arch/powerpc/conf: files.powerpc src/sys/arch/powerpc/include: cpu.h src/sys/arch/powerpc/include/booke: cpuvar.h Added Files: src/sys/arch/powerpc/include: softint.h src/sys/arch/powerpc/powerpc: softint_machdep.c Log Message: Take the fast softint support in e500_intr.c and make generic so that it can be used to provide fast softint for other interrupt implementations. To generate a diff of this commit: cvs rdiff -u -r1.9 -r1.10 src/sys/arch/powerpc/booke/e500_intr.c cvs rdiff -u -r1.78 -r1.79 src/sys/arch/powerpc/conf/files.powerpc cvs rdiff -u -r1.79 -r1.80 src/sys/arch/powerpc/include/cpu.h cvs rdiff -u -r0 -r1.1 src/sys/arch/powerpc/include/softint.h cvs rdiff -u -r1.6 -r1.7 src/sys/arch/powerpc/include/booke/cpuvar.h cvs rdiff -u -r0 -r1.1 src/sys/arch/powerpc/powerpc/softint_machdep.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/powerpc/booke/e500_intr.c diff -u src/sys/arch/powerpc/booke/e500_intr.c:1.9 src/sys/arch/powerpc/booke/e500_intr.c:1.10 --- src/sys/arch/powerpc/booke/e500_intr.c:1.9 Wed Jun 8 05:13:00 2011 +++ src/sys/arch/powerpc/booke/e500_intr.c Tue Jun 14 22:36:12 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: e500_intr.c,v 1.9 2011/06/08 05:13:00 matt Exp $ */ +/* $NetBSD: e500_intr.c,v 1.10 2011/06/14 22:36:12 matt Exp $ */ /*- * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc. * All rights reserved. @@ -50,6 +50,10 @@ #include <uvm/uvm_extern.h> +#ifdef __HAVE_FAST_SOFTINTS +#include <powerpc/softint.h> +#endif + #include <powerpc/spr.h> #include <powerpc/booke/spr.h> @@ -63,24 +67,6 @@ #define IST_PERCPU_P(ist) ((ist) >= IST_TIMER) -#ifdef __HAVE_PREEMPTION -#define IPL_PREEMPT_SOFTMASK (1 << IPL_NONE) -#else -#define IPL_PREEMPT_SOFTMASK 0 -#endif - -#define IPL_SOFTMASK \ - ((1 << IPL_SOFTSERIAL) | (1 << IPL_SOFTNET ) \ - |(1 << IPL_SOFTBIO ) | (1 << IPL_SOFTCLOCK ) \ - |IPL_PREEMPT_SOFTMASK) - -#define SOFTINT2IPL_MAP \ - ((IPL_SOFTSERIAL << (4*SOFTINT_SERIAL)) \ - |(IPL_SOFTNET << (4*SOFTINT_NET )) \ - |(IPL_SOFTBIO << (4*SOFTINT_BIO )) \ - |(IPL_SOFTCLOCK << (4*SOFTINT_CLOCK ))) -#define SOFTINT2IPL(si_level) ((SOFTINT2IPL_MAP >> (4 * si_level)) & 0x0f) - struct e500_intr_irq_info { bus_addr_t irq_vpr; bus_addr_t irq_dr; @@ -374,10 +360,6 @@ static void e500_spl0(void); static int e500_splraise(int); static void e500_splx(int); -#ifdef __HAVE_FAST_SOFTINTS -static void e500_softint_init_md(lwp_t *l, u_int si_level, uintptr_t *machdep_p); -static void e500_softint_trigger(uintptr_t machdep); -#endif const struct intrsw e500_intrsw = { .intrsw_establish = e500_intr_establish, @@ -399,8 +381,8 @@ .intrsw_spl0 = e500_spl0, #ifdef __HAVE_FAST_SOFTINTS - .intrsw_softint_init_md = e500_softint_init_md, - .intrsw_softint_trigger = e500_softint_trigger, + .intrsw_softint_init_md = powerpc_softint_init_md, + .intrsw_softint_trigger = powerpc_softint_trigger, #endif }; @@ -454,64 +436,6 @@ return name; } -#ifdef __HAVE_FAST_SOFTINTS -static inline void -e500_softint_deliver(struct cpu_info *ci, struct cpu_softc *cpu, - int ipl, int si_level) -{ - KASSERT(ci->ci_data.cpu_softints & (1 << ipl)); - ci->ci_data.cpu_softints ^= 1 << ipl; - softint_fast_dispatch(cpu->cpu_softlwps[si_level], ipl); - KASSERT(cpu->cpu_softlwps[si_level]->l_ctxswtch == 0); - KASSERTMSG(ci->ci_cpl == IPL_HIGH, - ("%s: cpl (%d) != HIGH", __func__, ci->ci_cpl)); -} - -static inline void -e500_softint(struct cpu_info *ci, struct cpu_softc *cpu, int old_ipl, - vaddr_t pc) -{ - const u_int softint_mask = (IPL_SOFTMASK << old_ipl) & IPL_SOFTMASK; - u_int softints; - - KASSERT(ci->ci_mtx_count == 0); - KASSERT(ci->ci_cpl == IPL_HIGH); - while ((softints = (ci->ci_data.cpu_softints & softint_mask)) != 0) { - KASSERT(old_ipl < IPL_SOFTSERIAL); - if (softints & (1 << IPL_SOFTSERIAL)) { - e500_softint_deliver(ci, cpu, IPL_SOFTSERIAL, - SOFTINT_SERIAL); - continue; - } - KASSERT(old_ipl < IPL_SOFTNET); - if (softints & (1 << IPL_SOFTNET)) { - e500_softint_deliver(ci, cpu, IPL_SOFTNET, - SOFTINT_NET); - continue; - } - KASSERT(old_ipl < IPL_SOFTBIO); - if (softints & (1 << IPL_SOFTBIO)) { - e500_softint_deliver(ci, cpu, IPL_SOFTBIO, - SOFTINT_BIO); - continue; - } - KASSERT(old_ipl < IPL_SOFTCLOCK); - if (softints & (1 << IPL_SOFTCLOCK)) { - e500_softint_deliver(ci, cpu, IPL_SOFTCLOCK, - SOFTINT_CLOCK); - continue; - } -#ifdef __HAVE_PREEMPTION - KASSERT(old_ipl == IPL_NONE); - if (softints & (1 << IPL_NONE)) { - ci->ci_data.cpu_softints ^= (1 << IPL_NONE); - kpreempt(pc); - } -#endif - } -} -#endif /* __HAVE_FAST_SOFTINTS */ - static inline void e500_splset(struct cpu_info *ci, int ipl) { @@ -547,7 +471,7 @@ #ifdef __HAVE_FAST_SOFTINTS if (__predict_false(ci->ci_data.cpu_softints != 0)) { e500_splset(ci, IPL_HIGH); - e500_softint(ci, ci->ci_softc, IPL_NONE, + powerpc_softint(ci, IPL_NONE, (vaddr_t)__builtin_return_address(0)); } #endif /* __HAVE_FAST_SOFTINTS */ @@ -580,7 +504,7 @@ const u_int softints = (ci->ci_data.cpu_softints << ipl) & IPL_SOFTMASK; if (__predict_false(softints != 0)) { e500_splset(ci, IPL_HIGH); - e500_softint(ci, ci->ci_softc, ipl, + powerpc_softint(ci, ipl, (vaddr_t)__builtin_return_address(0)); } #endif /* __HAVE_FAST_SOFTINTS */ @@ -622,27 +546,6 @@ return old_ipl; } -#ifdef __HAVE_FAST_SOFTINTS -static void -e500_softint_init_md(lwp_t *l, u_int si_level, uintptr_t *machdep_p) -{ - struct cpu_info * const ci = l->l_cpu; - struct cpu_softc * const cpu = ci->ci_softc; - - *machdep_p = 1 << SOFTINT2IPL(si_level); - KASSERT(*machdep_p & IPL_SOFTMASK); - cpu->cpu_softlwps[si_level] = l; -} - -static void -e500_softint_trigger(uintptr_t machdep) -{ - struct cpu_info * const ci = curcpu(); - - atomic_or_uint(&ci->ci_data.cpu_softints, machdep); -} -#endif /* __HAVE_FAST_SOFTINTS */ - static int e500_intr_spurious(void *arg) { @@ -1022,7 +925,7 @@ if (__predict_false(softints != 0)) { KASSERT(old_ipl < IPL_VM); e500_splset(ci, IPL_HIGH); /* pop to high */ - e500_softint(ci, cpu, old_ipl, /* deal with them */ + powerpc_softint(ci, old_ipl, /* deal with them */ tf->tf_srr0); e500_splset(ci, old_ipl); /* and drop back */ } @@ -1235,7 +1138,7 @@ static void e500_ipi_kpreempt(void) { - e500_softint_trigger(1 << IPL_NONE); + poowerpc_softint_trigger(1 << IPL_NONE); } #endif Index: src/sys/arch/powerpc/conf/files.powerpc diff -u src/sys/arch/powerpc/conf/files.powerpc:1.78 src/sys/arch/powerpc/conf/files.powerpc:1.79 --- src/sys/arch/powerpc/conf/files.powerpc:1.78 Sun Jun 12 03:35:45 2011 +++ src/sys/arch/powerpc/conf/files.powerpc Tue Jun 14 22:36:12 2011 @@ -1,4 +1,4 @@ -# $NetBSD: files.powerpc,v 1.78 2011/06/12 03:35:45 rmind Exp $ +# $NetBSD: files.powerpc,v 1.79 2011/06/14 22:36:12 matt Exp $ defflag opt_altivec.h ALTIVEC K_ALTIVEC PPC_HAVE_SPE defflag opt_openpic.h OPENPIC OPENPIC_SERIAL_MODE OPENPIC_DISTRIBUTE @@ -23,6 +23,7 @@ file arch/powerpc/powerpc/setfault.S file arch/powerpc/powerpc/sig_machdep.c file arch/powerpc/powerpc/sigcode.S +file arch/powerpc/powerpc/softint_machdep.c file arch/powerpc/powerpc/subyte.c file arch/powerpc/powerpc/suword.c file arch/powerpc/powerpc/suswintr.c Index: src/sys/arch/powerpc/include/cpu.h diff -u src/sys/arch/powerpc/include/cpu.h:1.79 src/sys/arch/powerpc/include/cpu.h:1.80 --- src/sys/arch/powerpc/include/cpu.h:1.79 Mon Jun 13 21:19:01 2011 +++ src/sys/arch/powerpc/include/cpu.h Tue Jun 14 22:36:12 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: cpu.h,v 1.79 2011/06/13 21:19:01 matt Exp $ */ +/* $NetBSD: cpu.h,v 1.80 2011/06/14 22:36:12 matt Exp $ */ /* * Copyright (C) 1999 Wolfgang Solfrank. @@ -68,6 +68,7 @@ struct pcb *ci_curpcb; struct pmap *ci_curpm; + struct lwp *ci_softlwps[SOFTINT_COUNT]; int ci_cpuid; /* from SPR_PIR */ int ci_want_resched; Index: src/sys/arch/powerpc/include/booke/cpuvar.h diff -u src/sys/arch/powerpc/include/booke/cpuvar.h:1.6 src/sys/arch/powerpc/include/booke/cpuvar.h:1.7 --- src/sys/arch/powerpc/include/booke/cpuvar.h:1.6 Sun Jun 5 16:52:25 2011 +++ src/sys/arch/powerpc/include/booke/cpuvar.h Tue Jun 14 22:36:12 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: cpuvar.h,v 1.6 2011/06/05 16:52:25 matt Exp $ */ +/* $NetBSD: cpuvar.h,v 1.7 2011/06/14 22:36:12 matt Exp $ */ /*- * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc. * All rights reserved. @@ -57,7 +57,6 @@ u_int cpu_pcpls[5]; struct evcnt cpu_evcnt_spurious_intr; - struct lwp *cpu_softlwps[SOFTINT_COUNT]; struct evcnt cpu_ev_late_clock; u_long cpu_ticks_per_clock_intr; Added files: Index: src/sys/arch/powerpc/include/softint.h diff -u /dev/null src/sys/arch/powerpc/include/softint.h:1.1 --- /dev/null Tue Jun 14 22:36:13 2011 +++ src/sys/arch/powerpc/include/softint.h Tue Jun 14 22:36:12 2011 @@ -0,0 +1,77 @@ +/* $NetBSD: softint.h,v 1.1 2011/06/14 22:36:12 matt Exp $ */ +/*- + * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Raytheon BBN Technologies Corp and Defense Advanced Research Projects + * Agency and which was developed by Matt Thomas of 3am Software Foundry. + * + * This material is based upon work supported by the Defense Advanced Research + * Projects Agency and Space and Naval Warfare Systems Center, Pacific, under + * Contract No. N66001-09-C-2073. + * Approved for Public Release, Distribution Unlimited + * + * 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. + */ + +#ifdef __INTR_PRIVATE +#ifndef _POWERPC_SOFTINT_H_ +#define _POWERPC_SOFTINT_H_ + +#include <sys/intr.h> + +#ifdef __HAVE_FAST_SOFTINTS + +#ifdef __HAVE_PREEMPTION +#define IPL_PREEMPT_SOFTMASK (1 << IPL_NONE) +#else +#define IPL_PREEMPT_SOFTMASK 0 +#endif + +#define IPL_SOFTMASK \ + ((1 << IPL_SOFTSERIAL) | (1 << IPL_SOFTNET ) \ + |(1 << IPL_SOFTBIO ) | (1 << IPL_SOFTCLOCK ) \ + |IPL_PREEMPT_SOFTMASK) + +#define SOFTINT2IPL_MAP \ + ((IPL_SOFTSERIAL << (4*SOFTINT_SERIAL)) \ + |(IPL_SOFTNET << (4*SOFTINT_NET )) \ + |(IPL_SOFTBIO << (4*SOFTINT_BIO )) \ + |(IPL_SOFTCLOCK << (4*SOFTINT_CLOCK ))) +#define SOFTINT2IPL(si_level) ((SOFTINT2IPL_MAP >> (4 * (si_level))) & 0x0f) +#define IPL2SOFTINT_MAP \ + ((SOFTINT_SERIAL << (4*IPL_SOFTSERIAL)) \ + |(SOFTINT_NET << (4*IPL_SOFTNET )) \ + |(SOFTINT_BIO << (4*IPL_SOFTBIO )) \ + |(SOFTINT_CLOCK << (4*IPL_SOFTCLOCK ))) +#define IPL2SOFTINT(ipl) ((IPL2SOFTINT_MAP >> (4 * (ipl))) & 0x0f) + +#ifdef _KERNEL +void powerpc_softint(struct cpu_info *, int, vaddr_t); +void powerpc_softint_init_md(lwp_t *, u_int, uintptr_t *); +void powerpc_softint_trigger(uintptr_t); +#endif + +#endif /* __HAVE_FAST_SOFTINTS */ +#endif /* !_POWERPC_SOFTINT_H_ */ +#endif /* __INTR_PRIVATE */ Index: src/sys/arch/powerpc/powerpc/softint_machdep.c diff -u /dev/null src/sys/arch/powerpc/powerpc/softint_machdep.c:1.1 --- /dev/null Tue Jun 14 22:36:13 2011 +++ src/sys/arch/powerpc/powerpc/softint_machdep.c Tue Jun 14 22:36:13 2011 @@ -0,0 +1,122 @@ +/* $NetBSD: softint_machdep.c,v 1.1 2011/06/14 22:36:13 matt Exp $ */ +/*- + * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Raytheon BBN Technologies Corp and Defense Advanced Research Projects + * Agency and which was developed by Matt Thomas of 3am Software Foundry. + * + * This material is based upon work supported by the Defense Advanced Research + * Projects Agency and Space and Naval Warfare Systems Center, Pacific, under + * Contract No. N66001-09-C-2073. + * Approved for Public Release, Distribution Unlimited + * + * 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. + */ + +#define __INTR_PRIVATE + +#include <sys/param.h> +#include <sys/intr.h> +#include <sys/cpu.h> +#include <sys/atomic.h> + +#ifdef __HAVE_FAST_SOFTINTS +#include <powerpc/softint.h> + +__CTASSERT(IPL_NONE < IPL_SOFTCLOCK); +__CTASSERT(IPL_SOFTCLOCK < IPL_SOFTBIO); +__CTASSERT(IPL_SOFTBIO < IPL_SOFTNET); +__CTASSERT(IPL_SOFTNET < IPL_SOFTSERIAL); +__CTASSERT(IPL_SOFTSERIAL < IPL_VM); +__CTASSERT(IPL_SOFTSERIAL < sizeof(uint32_t)*2); + +static inline void +softint_deliver(struct cpu_info *ci, int ipl) +{ + const int si_level = IPL2SOFTINT(ipl); + KASSERT(ci->ci_data.cpu_softints & (1 << ipl)); + ci->ci_data.cpu_softints ^= 1 << ipl; + softint_fast_dispatch(ci->ci_softlwps[si_level], ipl); + KASSERT(ci->ci_softlwps[si_level]->l_ctxswtch == 0); + KASSERTMSG(ci->ci_cpl == IPL_HIGH, + ("%s: cpl (%d) != HIGH", __func__, ci->ci_cpl)); +} + +void +powerpc_softint(struct cpu_info *ci, int old_ipl, vaddr_t pc) +{ + const u_int softint_mask = (IPL_SOFTMASK << old_ipl) & IPL_SOFTMASK; + u_int softints; + + KASSERT(ci->ci_mtx_count == 0); + KASSERT(ci->ci_cpl == IPL_HIGH); + while ((softints = (ci->ci_data.cpu_softints & softint_mask)) != 0) { + KASSERT(old_ipl < IPL_SOFTSERIAL); + if (softints & (1 << IPL_SOFTSERIAL)) { + softint_deliver(ci, IPL_SOFTSERIAL); + continue; + } + KASSERT(old_ipl < IPL_SOFTNET); + if (softints & (1 << IPL_SOFTNET)) { + softint_deliver(ci, IPL_SOFTNET); + continue; + } + KASSERT(old_ipl < IPL_SOFTBIO); + if (softints & (1 << IPL_SOFTBIO)) { + softint_deliver(ci, IPL_SOFTBIO); + continue; + } + KASSERT(old_ipl < IPL_SOFTCLOCK); + if (softints & (1 << IPL_SOFTCLOCK)) { + softint_deliver(ci, IPL_SOFTCLOCK); + continue; + } +#ifdef __HAVE_PREEMPTION + KASSERT(old_ipl == IPL_NONE); + KASSERT(softints == (1 << IPL_NONE)); + ci->ci_data.cpu_softints ^= (1 << IPL_NONE); + kpreempt(pc); +#endif + } +} + +void +powerpc_softint_init_md(lwp_t *l, u_int si_level, uintptr_t *machdep_p) +{ + struct cpu_info * const ci = l->l_cpu; + + *machdep_p = 1 << SOFTINT2IPL(si_level); + KASSERT(*machdep_p & IPL_SOFTMASK); + ci->ci_softlwps[si_level] = l; +} + +void +powerpc_softint_trigger(uintptr_t machdep) +{ + struct cpu_info * const ci = curcpu(); + + atomic_or_uint(&ci->ci_data.cpu_softints, machdep); +} + +#endif /* __HAVE_FAST_SOFTINTS */