diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2009-10-22 22:08:55 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2009-10-22 22:08:55 +0000 |
commit | 96629079d3f1a0da94f72c0045f030432bddc51d (patch) | |
tree | 91639a4e0d7c5dc462c850a9bed7dc553484768d /sys/arch/mips64 | |
parent | 94815ddee781a683d8d1d9258ec9c8959763443f (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.h | 4 | ||||
-rw-r--r-- | sys/arch/mips64/include/cpustate.h | 4 | ||||
-rw-r--r-- | sys/arch/mips64/include/frame.h | 4 | ||||
-rw-r--r-- | sys/arch/mips64/include/trap.h | 6 | ||||
-rw-r--r-- | sys/arch/mips64/mips64/clock.c | 5 | ||||
-rw-r--r-- | sys/arch/mips64/mips64/context.S | 6 | ||||
-rw-r--r-- | sys/arch/mips64/mips64/exception.S | 6 | ||||
-rw-r--r-- | sys/arch/mips64/mips64/interrupt.c | 118 | ||||
-rw-r--r-- | sys/arch/mips64/mips64/process_machdep.c | 10 | ||||
-rw-r--r-- | sys/arch/mips64/mips64/softintr.c | 6 | ||||
-rw-r--r-- | sys/arch/mips64/mips64/vm_machdep.c | 6 |
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 |