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);
+}