summaryrefslogtreecommitdiff
path: root/sys/arch/mips64
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2009-10-22 22:08:55 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2009-10-22 22:08:55 +0000
commit96629079d3f1a0da94f72c0045f030432bddc51d (patch)
tree91639a4e0d7c5dc462c850a9bed7dc553484768d /sys/arch/mips64
parent94815ddee781a683d8d1d9258ec9c8959763443f (diff)
Completely overhaul interrupt handling on sgi. Cpu state now only stores a
logical IPL level, and per-platform (IP27/IP30/IP32) code will from the necessary hardware mask registers. This allows the use of more than one interrupt mask register. Also, the generic (platform independent) interrupt code shrinks a lot, and the actual interrupt handler chains and masking information is now per-platform private data. Interrupt dispatching is generated from a template; more routines will be added to the template to reduce platform-specific changes and share as much code as possible. Tested on IP27, IP30, IP32 and IP35.
Diffstat (limited to 'sys/arch/mips64')
-rw-r--r--sys/arch/mips64/include/cpu.h4
-rw-r--r--sys/arch/mips64/include/cpustate.h4
-rw-r--r--sys/arch/mips64/include/frame.h4
-rw-r--r--sys/arch/mips64/include/trap.h6
-rw-r--r--sys/arch/mips64/mips64/clock.c5
-rw-r--r--sys/arch/mips64/mips64/context.S6
-rw-r--r--sys/arch/mips64/mips64/exception.S6
-rw-r--r--sys/arch/mips64/mips64/interrupt.c118
-rw-r--r--sys/arch/mips64/mips64/process_machdep.c10
-rw-r--r--sys/arch/mips64/mips64/softintr.c6
-rw-r--r--sys/arch/mips64/mips64/vm_machdep.c6
11 files changed, 75 insertions, 100 deletions
diff --git a/sys/arch/mips64/include/cpu.h b/sys/arch/mips64/include/cpu.h
index ad44f2270a2..a1eb25d6591 100644
--- a/sys/arch/mips64/include/cpu.h
+++ b/sys/arch/mips64/include/cpu.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.h,v 1.40 2009/10/22 20:59:22 miod Exp $ */
+/* $OpenBSD: cpu.h,v 1.41 2009/10/22 22:08:52 miod Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -374,7 +374,7 @@ struct cpu_info {
int ci_want_resched; /* need_resched() invoked */
cpuid_t ci_cpuid; /* our CPU ID */
uint32_t ci_randseed; /* per cpu random seed */
- uint32_t ci_cpl;
+ int ci_ipl; /* software IPL */
uint32_t ci_softpending; /* pending soft interrupts */
#ifdef MULTIPROCESSOR
u_long ci_flags; /* flags; see below */
diff --git a/sys/arch/mips64/include/cpustate.h b/sys/arch/mips64/include/cpustate.h
index 7512fdbf9c5..80f642bcc1e 100644
--- a/sys/arch/mips64/include/cpustate.h
+++ b/sys/arch/mips64/include/cpustate.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpustate.h,v 1.7 2009/10/07 08:35:47 syuu Exp $ */
+/* $OpenBSD: cpustate.h,v 1.8 2009/10/22 22:08:52 miod Exp $ */
/*
* Copyright (c) 2002-2003 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -80,7 +80,7 @@
SAVE_REG(sp, SP, frame, bo) ;\
PTR_ADDU a0, frame, bo ;\
GET_CPU_INFO(v0, v1) ;\
- lw a2, CI_CPL(v0) ;\
+ lw a2, CI_IPL(v0) ;\
SAVE_REG(a2, CPL, frame, bo)
/*
diff --git a/sys/arch/mips64/include/frame.h b/sys/arch/mips64/include/frame.h
index baac64d131c..874fcdb566f 100644
--- a/sys/arch/mips64/include/frame.h
+++ b/sys/arch/mips64/include/frame.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: frame.h,v 1.4 2004/09/27 17:42:23 pefo Exp $ */
+/* $OpenBSD: frame.h,v 1.5 2009/10/22 22:08:52 miod Exp $ */
/*
* Copyright (c) 1998-2003 Opsycon AB (www.opsycon.se)
@@ -76,7 +76,7 @@ struct trap_frame {
register_t cause;
register_t pc;
register_t ic;
- register_t cpl;
+ register_t ipl;
/* From here and on, only saved user processes. */
diff --git a/sys/arch/mips64/include/trap.h b/sys/arch/mips64/include/trap.h
index 8095310ad01..413a7c1ef6a 100644
--- a/sys/arch/mips64/include/trap.h
+++ b/sys/arch/mips64/include/trap.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.h,v 1.9 2008/04/07 22:37:16 miod Exp $ */
+/* $OpenBSD: trap.h,v 1.10 2009/10/22 22:08:52 miod Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@@ -91,7 +91,7 @@ struct trapdebug { /* trap history buffer for debugging */
u_long ra;
u_long sp;
u_int code;
- u_int cpl;
+ u_int ipl;
};
#define trapdebug_enter(x, cd) { \
@@ -102,7 +102,7 @@ struct trapdebug { /* trap history buffer for debugging */
trp->pc = x->pc; \
trp->sp = x->sp; \
trp->ra = x->ra; \
- trp->cpl = x->cpl; \
+ trp->ipl = x->ipl; \
trp->code = cd; \
if (++trp == &trapdebug[TRAPSIZE]) \
trp = trapdebug; \
diff --git a/sys/arch/mips64/mips64/clock.c b/sys/arch/mips64/mips64/clock.c
index 1db4204d7e6..765b87eeed0 100644
--- a/sys/arch/mips64/mips64/clock.c
+++ b/sys/arch/mips64/mips64/clock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: clock.c,v 1.24 2009/10/22 20:05:27 miod Exp $ */
+/* $OpenBSD: clock.c,v 1.25 2009/10/22 22:08:54 miod Exp $ */
/*
* Copyright (c) 2001-2004 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -161,13 +161,12 @@ clock_int5(uint32_t mask, struct trap_frame *tf)
/*
* Process clock interrupt unless it is currently masked.
*/
- if ((tf->cpl & SPL_CLOCKMASK) == 0) {
+ if (tf->ipl < IPL_CLOCK)
while (pendingticks) {
clk_count.ec_count++;
hardclock(tf);
pendingticks--;
}
- }
return CR_INT_5; /* Clock is always on 5 */
}
diff --git a/sys/arch/mips64/mips64/context.S b/sys/arch/mips64/mips64/context.S
index a6f26117414..cf05fc6188b 100644
--- a/sys/arch/mips64/mips64/context.S
+++ b/sys/arch/mips64/mips64/context.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: context.S,v 1.29 2009/10/22 18:46:48 miod Exp $ */
+/* $OpenBSD: context.S,v 1.30 2009/10/22 22:08:54 miod Exp $ */
/*
* Copyright (c) 2002-2003 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -61,7 +61,7 @@ LEAF(savectx, 0)
REG_S ra, PCB_CONTEXT+10*REGSZ(a0)
REG_S v0, PCB_CONTEXT+11*REGSZ(a0)
GET_CPU_INFO(t0, t1)
- lw t0, CI_CPL(t0)
+ lw t0, CI_IPL(t0)
#ifdef RM7000_ICR
cfc0 t1, COP_0_ICR
REG_S t1, PCB_CONTEXT+12*REGSZ(a0) # save status register
@@ -117,7 +117,7 @@ NON_LEAF(cpu_switchto, FRAMESZ(CF_SZ), ra)
beqz a0, 1f
mfc0 v0, COP_0_STATUS_REG
- lw t0, CI_CPL(t1)
+ lw t0, CI_IPL(t1)
REG_S s0, PCB_CONTEXT+0*REGSZ(t3) # do a 'savectx()'
REG_S s1, PCB_CONTEXT+1*REGSZ(t3)
REG_S s2, PCB_CONTEXT+2*REGSZ(t3)
diff --git a/sys/arch/mips64/mips64/exception.S b/sys/arch/mips64/mips64/exception.S
index f4d69d3fe59..3aafc6637a6 100644
--- a/sys/arch/mips64/mips64/exception.S
+++ b/sys/arch/mips64/mips64/exception.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: exception.S,v 1.25 2009/10/22 18:46:48 miod Exp $ */
+/* $OpenBSD: exception.S,v 1.26 2009/10/22 22:08:54 miod Exp $ */
/*
* Copyright (c) 2002-2003 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -330,7 +330,7 @@ NNON_LEAF(u_intr, FRAMESZ(CF_SZ), ra)
GET_CPU_INFO(k1, k0)
PTR_L k0, CI_CURPROCPADDR(k1)
RESTORE_REG(a3, CPL, k0, 0)
- sw a3, CI_CPL(k1)
+ sw a3, CI_IPL(k1)
.set noat
RESTORE_REG(a0, PC, k0, 0)
#ifdef RM7000_ICR
@@ -491,7 +491,7 @@ NNON_LEAF(u_general, FRAMESZ(CF_SZ), ra)
GET_CPU_INFO(k1, k0)
PTR_L k0, CI_CURPROCPADDR(k1)
RESTORE_REG(a3, CPL, k0, 0)
- sw a3, CI_CPL(k1)
+ sw a3, CI_IPL(k1)
.set noat
RESTORE_CPU_SREG(k0, 0)
RESTORE_REG(a0, PC, k0, 0)
diff --git a/sys/arch/mips64/mips64/interrupt.c b/sys/arch/mips64/mips64/interrupt.c
index aa94dd46b3b..8ec207ab116 100644
--- a/sys/arch/mips64/mips64/interrupt.c
+++ b/sys/arch/mips64/mips64/interrupt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: interrupt.c,v 1.48 2009/10/22 20:59:24 miod Exp $ */
+/* $OpenBSD: interrupt.c,v 1.49 2009/10/22 22:08:54 miod Exp $ */
/*
* Copyright (c) 2001-2004 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -29,26 +29,16 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
-#include <sys/signalvar.h>
#include <sys/user.h>
-#include <sys/malloc.h>
-#include <sys/device.h>
-#ifdef KTRACE
-#include <sys/ktrace.h>
-#endif
-#include <machine/trap.h>
+#include <uvm/uvm_extern.h>
+
#include <machine/cpu.h>
#include <machine/intr.h>
-#include <machine/autoconf.h>
#include <machine/frame.h>
-#include <machine/regnum.h>
-#include <machine/atomic.h>
#include <mips64/rm7000.h>
-#include <mips64/archtype.h>
-
#ifdef DDB
#include <mips64/db_machdep.h>
#include <ddb/db_sym.h>
@@ -60,8 +50,6 @@ void interrupt(struct trap_frame *);
static struct evcount soft_count;
static int soft_irq = 0;
-uint32_t imask[NIPLS];
-
uint32_t idle_mask;
int last_low_int;
@@ -98,7 +86,7 @@ int_f *splx_hand = &dummy_splx;
*/
/*
- * Handle an interrupt. Both kernel and user mode is handled here.
+ * Handle an interrupt. Both kernel and user mode are handled here.
*
* The interrupt handler is called with the CR_INT bits set that
* were given when the handler was registered.
@@ -111,9 +99,7 @@ interrupt(struct trap_frame *trapframe)
{
struct cpu_info *ci = curcpu();
u_int32_t pending;
- u_int32_t cause;
- int i;
- uint32_t xcpl;
+ int i, s;
/*
* Paranoic? Perhaps. But if we got here with the enable
@@ -133,83 +119,69 @@ interrupt(struct trap_frame *trapframe)
/* Mask out interrupts from cause that are unmasked */
pending = trapframe->cause & CR_IPEND & trapframe->sr;
- cause = pending;
- if (cause & SOFT_INT_MASK_0) {
+ if (pending & SOFT_INT_MASK_0) {
clearsoftintr0();
soft_count.ec_count++;
}
#ifdef RM7K_PERFCNTR
- if (cause & CR_INT_PERF) {
+ if (pending & CR_INT_PERF)
rm7k_perfintr(trapframe);
- cause &= ~CR_INT_PERF;
- }
#endif
for (i = 0; i <= last_low_int; i++) {
uint32_t active;
active = cpu_int_tab[i].int_mask & pending;
- if (active) {
- cause &= ~(*cpu_int_tab[i].int_hand)(active, trapframe);
- }
+ if (active != 0)
+ (*cpu_int_tab[i].int_hand)(active, trapframe);
}
/*
- * Reenable all non served hardware levels.
+ * Dispatch soft interrupts if current ipl allows them.
*/
-#if 0
- /* XXX the following should, when req., change the IC reg as well */
- setsr((trapframe->sr & ~pending) | SR_INT_ENAB);
-#endif
-
- xcpl = splsoft();
- if (ci->ci_softpending & ~xcpl) {
- dosoftint(xcpl);
+ if (ci->ci_ipl < IPL_SOFTINT && ci->ci_softpending != 0) {
+ s = splsoft();
+ dosoftint();
+ __asm__ (".set noreorder\n");
+ ci->ci_ipl = s; /* no-overhead splx */
+ __asm__ ("sync\n\t.set reorder\n");
}
-
- __asm__ (" .set noreorder\n");
- ci->ci_cpl = xcpl;
- __asm__ (" sync\n .set reorder\n");
}
/*
- * Set up handler for external interrupt events.
- * Use CR_INT_<n> to select the proper interrupt
- * condition to dispatch on. We also enable the
- * software ints here since they are always on.
+ * Set up handler for external interrupt events.
+ * Use CR_INT_<n> to select the proper interrupt condition to dispatch on.
+ * We also enable the software ints here since they are always on.
*/
void
set_intr(int pri, uint32_t mask,
- uint32_t (*int_hand)(uint32_t, struct trap_frame *))
+ uint32_t (*int_hand)(uint32_t, struct trap_frame *))
{
if ((idle_mask & SOFT_INT_MASK) == 0)
- evcount_attach(&soft_count, "soft", (void *)&soft_irq, &evcount_intr);
- if (pri < 0 || pri >= NLOWINT) {
- panic("set_intr: to high priority");
- }
+ evcount_attach(&soft_count, "soft", (void *)&soft_irq,
+ &evcount_intr);
+ if (pri < 0 || pri >= NLOWINT)
+ panic("set_intr: too high priority (%d), increase NLOWINT",
+ pri);
if (pri > last_low_int)
last_low_int = pri;
- if ((mask & ~CR_IPEND) != 0) {
+ if ((mask & ~CR_IPEND) != 0)
panic("set_intr: invalid mask 0x%x", mask);
- }
if (cpu_int_tab[pri].int_mask != 0 &&
(cpu_int_tab[pri].int_mask != mask ||
- cpu_int_tab[pri].int_hand != int_hand)) {
+ cpu_int_tab[pri].int_hand != int_hand))
panic("set_intr: int already set at pri %d", pri);
- }
cpu_int_tab[pri].int_hand = int_hand;
cpu_int_tab[pri].int_mask = mask;
idle_mask |= mask | SOFT_INT_MASK;
}
-struct intrhand *intrhand[INTMASKSIZE];
-
void
dummy_splx(int newcpl)
{
@@ -233,7 +205,7 @@ splinit()
/*
* Update proc0 pcb to contain proper values.
*/
- pcb->pcb_context.val[13] = 0; /* IPL_NONE */
+ pcb->pcb_context.val[13] = IPL_NONE;
#ifdef RM7000_ICR
pcb->pcb_context.val[12] = (idle_mask << 8) & IC_INT_MASK;
#endif
@@ -247,31 +219,35 @@ splinit()
}
int
-splraise(int newcpl)
+splraise(int newipl)
{
struct cpu_info *ci = curcpu();
- int oldcpl;
-
- __asm__ (" .set noreorder\n");
- oldcpl = ci->ci_cpl;
- ci->ci_cpl = oldcpl | newcpl;
- __asm__ (" sync\n .set reorder\n");
- return (oldcpl);
+ int oldipl;
+
+ __asm__ (".set noreorder\n");
+ oldipl = ci->ci_ipl;
+ if (oldipl < newipl) {
+ /* XXX to kill warning about dla being used in a delay slot */
+ __asm__("nop");
+ ci->ci_ipl = newipl;
+ }
+ __asm__ ("sync\n\t.set reorder\n");
+ return oldipl;
}
void
-splx(int newcpl)
+splx(int newipl)
{
- (*splx_hand)(newcpl);
+ (*splx_hand)(newipl);
}
int
-spllower(int newcpl)
+spllower(int newipl)
{
struct cpu_info *ci = curcpu();
- int oldcpl;
+ int oldipl;
- oldcpl = ci->ci_cpl;
- splx(newcpl);
- return (oldcpl);
+ oldipl = ci->ci_ipl;
+ splx(newipl);
+ return oldipl;
}
diff --git a/sys/arch/mips64/mips64/process_machdep.c b/sys/arch/mips64/mips64/process_machdep.c
index 505ecf55e1c..bdd3609d288 100644
--- a/sys/arch/mips64/mips64/process_machdep.c
+++ b/sys/arch/mips64/mips64/process_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: process_machdep.c,v 1.10 2009/05/22 20:37:53 miod Exp $ */
+/* $OpenBSD: process_machdep.c,v 1.11 2009/10/22 22:08:54 miod Exp $ */
/*
* Copyright (c) 1994 Adam Glass
@@ -40,7 +40,7 @@
* From:
* Id: procfs_i386.c,v 4.1 1993/12/17 10:47:45 jsp Rel
*
- * $Id: process_machdep.c,v 1.10 2009/05/22 20:37:53 miod Exp $
+ * $Id: process_machdep.c,v 1.11 2009/10/22 22:08:54 miod Exp $
*/
/*
@@ -103,7 +103,7 @@ process_write_regs(p, regs)
struct proc *p;
struct reg *regs;
{
- register_t sr, ic, cpl;
+ register_t sr, ic, ipl;
extern struct proc *machFPCurProcPtr;
if (p == machFPCurProcPtr) {
@@ -114,11 +114,11 @@ process_write_regs(p, regs)
}
sr = p->p_md.md_regs->sr;
ic = p->p_md.md_regs->ic;
- cpl = p->p_md.md_regs->cpl;
+ ipl = p->p_md.md_regs->ipl;
bcopy((caddr_t)regs, (caddr_t)p->p_md.md_regs, REGSIZE);
p->p_md.md_regs->sr = sr;
p->p_md.md_regs->ic = ic;
- p->p_md.md_regs->cpl = cpl;
+ p->p_md.md_regs->ipl = ipl;
return (0);
}
diff --git a/sys/arch/mips64/mips64/softintr.c b/sys/arch/mips64/mips64/softintr.c
index 748657f0ccd..f818219550b 100644
--- a/sys/arch/mips64/mips64/softintr.c
+++ b/sys/arch/mips64/mips64/softintr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: softintr.c,v 1.4 2009/10/22 20:59:24 miod Exp $ */
+/* $OpenBSD: softintr.c,v 1.5 2009/10/22 22:08:54 miod Exp $ */
/* $NetBSD: softintr.c,v 1.2 2003/07/15 00:24:39 lukem Exp $ */
/*
@@ -200,12 +200,12 @@ netintr(void)
}
void
-dosoftint(uint32_t xcpl)
+dosoftint()
{
struct cpu_info *ci = curcpu();
int sir, q, mask;
- while ((sir = (ci->ci_softpending & ~xcpl)) != 0) {
+ while ((sir = ci->ci_softpending) != 0) {
atomic_clearbits_int(&ci->ci_softpending, sir);
for (q = SI_NQUEUES - 1; q >= 0; q--) {
diff --git a/sys/arch/mips64/mips64/vm_machdep.c b/sys/arch/mips64/mips64/vm_machdep.c
index 8ac4a8ffdcd..a73db7dfd0a 100644
--- a/sys/arch/mips64/mips64/vm_machdep.c
+++ b/sys/arch/mips64/mips64/vm_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vm_machdep.c,v 1.19 2009/10/22 18:46:48 miod Exp $ */
+/* $OpenBSD: vm_machdep.c,v 1.20 2009/10/22 22:08:54 miod Exp $ */
/*
* Copyright (c) 1988 University of Utah.
* Copyright (c) 1992, 1993
@@ -104,11 +104,11 @@ cpu_fork(p1, p2, stack, stacksize, func, arg)
/*
* Copy the process control block to the new proc and
* create a clean stack for exit through trampoline.
- * pcb_context has s0-s7, sp, s8, ra, sr, icr, cpl.
+ * pcb_context has s0-s7, sp, s8, ra, sr, icr, ipl.
*/
if (p1 != curproc) {
- pcb->pcb_context.val[13] = 0;
+ pcb->pcb_context.val[13] = IPL_NONE;
#ifdef RM7000_ICR
pcb->pcb_context.val[12] = (idle_mask << 8) & IC_INT_MASK;
#endif