Module Name: src Committed By: macallan Date: Thu Jun 16 02:43:43 UTC 2011
Modified Files: src/sys/arch/powerpc/include: intr.h src/sys/arch/powerpc/oea: genassym.cf src/sys/arch/powerpc/pic: files.pic intr.c src/sys/arch/powerpc/powerpc: clock.c Added Files: src/sys/arch/powerpc/pic: pic_subr.c Log Message: enable FAST_SOFTINTR support for all ports that use powerpc/pic/ This has been successfully tested on macppc TODO: - ibm4xx needs to be adapted - SMP doesn't work yet, 2nd CPU crashes when trying to leave the idle loop To generate a diff of this commit: cvs rdiff -u -r1.5 -r1.6 src/sys/arch/powerpc/include/intr.h cvs rdiff -u -r1.18 -r1.19 src/sys/arch/powerpc/oea/genassym.cf cvs rdiff -u -r1.5 -r1.6 src/sys/arch/powerpc/pic/files.pic cvs rdiff -u -r1.11 -r1.12 src/sys/arch/powerpc/pic/intr.c cvs rdiff -u -r0 -r1.1 src/sys/arch/powerpc/pic/pic_subr.c cvs rdiff -u -r1.10 -r1.11 src/sys/arch/powerpc/powerpc/clock.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/include/intr.h diff -u src/sys/arch/powerpc/include/intr.h:1.5 src/sys/arch/powerpc/include/intr.h:1.6 --- src/sys/arch/powerpc/include/intr.h:1.5 Sun Apr 25 12:26:07 2010 +++ src/sys/arch/powerpc/include/intr.h Thu Jun 16 02:43:42 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: intr.h,v 1.5 2010/04/25 12:26:07 kiyohara Exp $ */ +/* $NetBSD: intr.h,v 1.6 2011/06/16 02:43:42 macallan Exp $ */ /*- * Copyright (c) 2007 Michael Lorenz @@ -26,16 +26,22 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef _LOCORE #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: intr.h,v 1.5 2010/04/25 12:26:07 kiyohara Exp $"); +__KERNEL_RCSID(0, "$NetBSD: intr.h,v 1.6 2011/06/16 02:43:42 macallan Exp $"); +#endif #ifndef POWERPC_INTR_MACHDEP_H #define POWERPC_INTR_MACHDEP_H +#define __HAVE_FAST_SOFTINTS 1 + +#ifndef _LOCORE void *intr_establish(int, int, int, int (*)(void *), void *); void intr_disestablish(void *); const char *intr_typename(int); void genppc_cpu_configure(void); +#endif /* Interrupt priority `levels'. */ #define IPL_NONE 0 /* nothing */ @@ -54,6 +60,10 @@ #define IST_EDGE 2 /* edge-triggered */ #define IST_LEVEL 3 /* level-triggered */ +#ifdef _LOCORE +#define splhigh __splhigh +#endif + #ifndef _LOCORE /* * Interrupt handler chains. intr_establish() inserts a handler into @@ -70,7 +80,11 @@ int splraise(int); int spllower(int); void splx(int); -void softintr(int); + +void softint_fast_dispatch(struct lwp *, int); + +#define softint_init_md powerpc_softint_init_md +#define softint_trigger powerpc_softint_trigger typedef u_int imask_t; extern imask_t imask[]; @@ -83,18 +97,6 @@ #define MS_PENDING(p) (31 - cntlzw(p)) -/* Soft interrupt masks. */ -#define SIR_CLOCK 27 -#define SIR_BIO 28 -#define SIR_NET 29 -#define SIR_SERIAL 30 -#define SPL_CLOCK 31 - -#define setsoftclock() softintr(SIR_CLOCK) -#define setsoftbio() softintr(SIR_BIO) -#define setsoftnet() softintr(SIR_NET) -#define setsoftserial() softintr(SIR_SERIAL) - #define spl0() spllower(0) typedef int ipl_t; @@ -113,7 +115,7 @@ splraiseipl(ipl_cookie_t icookie) { - return splraise(imask[icookie._ipl]); + return splraise(icookie._ipl); } #include <sys/spl.h> Index: src/sys/arch/powerpc/oea/genassym.cf diff -u src/sys/arch/powerpc/oea/genassym.cf:1.18 src/sys/arch/powerpc/oea/genassym.cf:1.19 --- src/sys/arch/powerpc/oea/genassym.cf:1.18 Sun Jun 5 16:52:25 2011 +++ src/sys/arch/powerpc/oea/genassym.cf Thu Jun 16 02:43:43 2011 @@ -1,4 +1,4 @@ -# $NetBSD: genassym.cf,v 1.18 2011/06/05 16:52:25 matt Exp $ +# $NetBSD: genassym.cf,v 1.19 2011/06/16 02:43:43 macallan Exp $ # # Copyright (C) 1995, 1996 Wolfgang Solfrank. @@ -217,6 +217,7 @@ define L_MD_ASTPENDING offsetof(struct lwp, l_md.md_astpending) define L_MD_UTF offsetof(struct lwp, l_md.md_utf) define L_PROC offsetof(struct lwp, l_proc) +define L_CTXSWTCH offsetof(struct lwp, l_ctxswtch) define P_MD_SYSCALL offsetof(struct proc, p_md.md_syscall) @@ -232,6 +233,7 @@ define CI_IPKDBSAVE offsetof(struct cpu_info, ci_ipkdbsave) define CI_DISISAVE offsetof(struct cpu_info, ci_disisave) define CI_IDLESPIN offsetof(struct cpu_info, ci_idlespin) +define CI_MTX_COUNT offsetof(struct cpu_info, ci_mtx_count) define CPUSAVE_R28 CPUSAVE_R28*sizeof(register_t) define CPUSAVE_R29 CPUSAVE_R29*sizeof(register_t) Index: src/sys/arch/powerpc/pic/files.pic diff -u src/sys/arch/powerpc/pic/files.pic:1.5 src/sys/arch/powerpc/pic/files.pic:1.6 --- src/sys/arch/powerpc/pic/files.pic:1.5 Sun Jun 5 16:52:26 2011 +++ src/sys/arch/powerpc/pic/files.pic Thu Jun 16 02:43:43 2011 @@ -1,9 +1,11 @@ # -# $NetBSD: files.pic,v 1.5 2011/06/05 16:52:26 matt Exp $ +# $NetBSD: files.pic,v 1.6 2011/06/16 02:43:43 macallan Exp $ # # generic PIC abstraction file arch/powerpc/pic/intr.c +file arch/powerpc/pic/pic_subr.c + defflag opt_pic.h PIC_DEBUG define pic_openpic Index: src/sys/arch/powerpc/pic/intr.c diff -u src/sys/arch/powerpc/pic/intr.c:1.11 src/sys/arch/powerpc/pic/intr.c:1.12 --- src/sys/arch/powerpc/pic/intr.c:1.11 Sun Jun 5 16:52:26 2011 +++ src/sys/arch/powerpc/pic/intr.c Thu Jun 16 02:43:43 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: intr.c,v 1.11 2011/06/05 16:52:26 matt Exp $ */ +/* $NetBSD: intr.c,v 1.12 2011/06/16 02:43:43 macallan Exp $ */ /*- * Copyright (c) 2007 Michael Lorenz @@ -27,10 +27,12 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.11 2011/06/05 16:52:26 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.12 2011/06/16 02:43:43 macallan Exp $"); #include "opt_multiprocessor.h" +#define __INTR_PRIVATE + #include <sys/param.h> #include <sys/malloc.h> #include <sys/kernel.h> @@ -47,6 +49,10 @@ #include <arch/powerpc/pic/ipivar.h> #endif +#ifdef __HAVE_FAST_SOFTINTS +#include <powerpc/softint.h> +#endif + #define MAX_PICS 8 /* 8 PICs ought to be enough for everyone */ #define LEGAL_VIRQ(x) ((x) >= 0 && (x) < NVIRQ) @@ -353,19 +359,6 @@ } /* - * IPL_CLOCK should mask clock interrupt even if interrupt handler - * is not registered. - */ - imask[IPL_CLOCK] |= 1ULL << SPL_CLOCK; - - /* - * Initialize soft interrupt masks to block themselves. - */ - imask[IPL_SOFTCLOCK] = 1ULL << SIR_CLOCK; - imask[IPL_SOFTNET] = 1ULL << SIR_NET; - imask[IPL_SOFTSERIAL] = 1ULL << SIR_SERIAL; - - /* * IPL_NONE is used for hardware interrupts that are never blocked, * and do not block anything else. */ @@ -483,12 +476,14 @@ pcpl = ci->ci_cpl; #ifdef __HAVE_FAST_SOFTINTS +#if 0 again: #endif +#endif /* Do now unmasked pendings */ ci->ci_idepth++; - while ((hwpend = (ci->ci_ipending & ~pcpl & HWIRQ_MASK)) != 0) { + while ((hwpend = (ci->ci_ipending & ~imask[pcpl] & HWIRQ_MASK)) != 0) { /* Get most significant pending bit */ irq = MS_PENDING(hwpend); KASSERT(irq <= virq_max); @@ -500,7 +495,7 @@ is = &intrsources[irq]; pic = is->is_pic; - splraise(is->is_mask); + splraise(is->is_level); mtmsr(emsr); ih = is->is_hand; while (ih) { @@ -530,6 +525,7 @@ ci->ci_idepth--; #ifdef __HAVE_FAST_SOFTINTS +#if 0 if ((ci->ci_ipending & ~pcpl) & (1ULL << SIR_SERIAL)) { ci->ci_ipending &= ~(1ULL << SIR_SERIAL); splsoftserial(); @@ -560,6 +556,16 @@ ci->ci_ev_softclock.ev_count++; goto again; } +#else + const u_int softints = (ci->ci_data.cpu_softints << pcpl) & IPL_SOFTMASK; + + if (__predict_false(softints != 0)) { + splhigh(); + powerpc_softint(ci, pcpl, + (vaddr_t)__builtin_return_address(0)); + ci->ci_cpl = pcpl; + } +#endif #endif ci->ci_cpl = pcpl; /* Don't use splx... we are here already! */ @@ -610,7 +616,7 @@ r_imen = 1ULL << irq; is = &intrsources[irq]; - if ((pcpl & r_imen) != 0) { + if ((imask[pcpl] & r_imen) != 0) { ci->ci_ipending |= r_imen; /* Masked! Mark this as pending */ pic->pic_disable_irq(pic, realirq); @@ -620,7 +626,7 @@ ci->ci_ipending &= ~r_imen; ci->ci_idepth++; - splraise(is->is_mask); + splraise(is->is_level); mtmsr(msr | PSL_EE); ih = is->is_hand; bail = 0; @@ -677,11 +683,13 @@ struct cpu_info *ci = curcpu(); int ocpl; + if (ncpl == ci->ci_cpl) return ncpl; __asm volatile("sync; eieio"); /* don't reorder.... */ - ocpl = ci->ci_cpl; - ci->ci_cpl = ocpl | ncpl; + KASSERT(ncpl < NIPL); + ci->ci_cpl = max(ncpl, ocpl); __asm volatile("sync; eieio"); /* reorder protect */ + __insn_barrier(); return ocpl; } @@ -690,9 +698,11 @@ { struct cpu_info *ci = curcpu(); + __insn_barrier(); __asm volatile("sync; eieio"); /* reorder protect */ ci->ci_cpl = ncpl; - if (ci->ci_ipending & ~ncpl) + if ((ci->ci_ipending & ~imask[ncpl]) || + ((ci->ci_data.cpu_softints << ncpl) & IPL_SOFTMASK)) pic_do_pending_int(); __asm volatile("sync; eieio"); /* reorder protect */ } @@ -703,29 +713,17 @@ struct cpu_info *ci = curcpu(); int ocpl; + __insn_barrier(); __asm volatile("sync; eieio"); /* reorder protect */ ocpl = ci->ci_cpl; ci->ci_cpl = ncpl; - if (ci->ci_ipending & ~ncpl) + if ((ci->ci_ipending & ~imask[ncpl]) || + ((ci->ci_data.cpu_softints << ncpl) & IPL_SOFTMASK)) pic_do_pending_int(); __asm volatile("sync; eieio"); /* reorder protect */ return ocpl; } -/* Following code should be implemented with lwarx/stwcx to avoid - * the disable/enable. i need to read the manual once more.... */ -void -softintr(int ipl) -{ - struct cpu_info *ci = curcpu(); - int msrsave; - - msrsave = mfmsr(); - mtmsr(msrsave & ~PSL_EE); - ci->ci_ipending |= 1ULL << ipl; - mtmsr(msrsave); -} - void genppc_cpu_configure(void) { Index: src/sys/arch/powerpc/powerpc/clock.c diff -u src/sys/arch/powerpc/powerpc/clock.c:1.10 src/sys/arch/powerpc/powerpc/clock.c:1.11 --- src/sys/arch/powerpc/powerpc/clock.c:1.10 Tue Jan 18 01:02:55 2011 +++ src/sys/arch/powerpc/powerpc/clock.c Thu Jun 16 02:43:43 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: clock.c,v 1.10 2011/01/18 01:02:55 matt Exp $ */ +/* $NetBSD: clock.c,v 1.11 2011/06/16 02:43:43 macallan Exp $ */ /* $OpenBSD: clock.c,v 1.3 1997/10/13 13:42:53 pefo Exp $ */ /* @@ -33,7 +33,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.10 2011/01/18 01:02:55 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.11 2011/06/16 02:43:43 macallan Exp $"); #include <sys/param.h> #include <sys/kernel.h> @@ -141,7 +141,7 @@ ci->ci_ev_clock.ev_count++; pri = splclock(); - if (pri & (1 << SPL_CLOCK)) { + if (pri >= IPL_CLOCK) { ci->ci_tickspending += nticks; } else { nticks += ci->ci_tickspending; Added files: Index: src/sys/arch/powerpc/pic/pic_subr.c diff -u /dev/null src/sys/arch/powerpc/pic/pic_subr.c:1.1 --- /dev/null Thu Jun 16 02:43:43 2011 +++ src/sys/arch/powerpc/pic/pic_subr.c Thu Jun 16 02:43:43 2011 @@ -0,0 +1,49 @@ +/* $NetBSD: pic_subr.c,v 1.1 2011/06/16 02:43:43 macallan Exp $ */ + +/*- + * Copyright (c) 2011 Michael Lorenz + * All rights reserved. + * + * 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. + */ + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: pic_subr.c,v 1.1 2011/06/16 02:43:43 macallan Exp $"); + +#define __INTR_NOINLINE + +#include <sys/param.h> +#include <sys/cpu.h> +#include <sys/intr.h> + +#include <machine/intr.h> + +int __splhigh(void); + +/* + * This is called by softint_cleanup so we need a non-static version + */ +int +__splhigh(void) +{ + return splraise(IPL_HIGH); +}