diff options
-rw-r--r-- | sys/conf/files.powerpc | 1 | ||||
-rw-r--r-- | sys/powerpc/aim/clock.c | 14 | ||||
-rw-r--r-- | sys/powerpc/aim/interrupt.c | 123 | ||||
-rw-r--r-- | sys/powerpc/aim/locore.S | 30 | ||||
-rw-r--r-- | sys/powerpc/aim/trap_subr.S | 225 | ||||
-rw-r--r-- | sys/powerpc/powerpc/clock.c | 14 | ||||
-rw-r--r-- | sys/powerpc/powerpc/interrupt.c | 123 | ||||
-rw-r--r-- | sys/powerpc/powerpc/locore.S | 30 | ||||
-rw-r--r-- | sys/powerpc/powerpc/locore.s | 30 | ||||
-rw-r--r-- | sys/powerpc/powerpc/trap_subr.S | 225 |
10 files changed, 303 insertions, 512 deletions
diff --git a/sys/conf/files.powerpc b/sys/conf/files.powerpc index 1845b53..2f91ace 100644 --- a/sys/conf/files.powerpc +++ b/sys/conf/files.powerpc @@ -21,6 +21,7 @@ powerpc/powerpc/elf_machdep.c standard powerpc/powerpc/extintr.c standard powerpc/powerpc/fpu.c standard powerpc/powerpc/fuswintr.c standard +powerpc/powerpc/interrupt.c standard powerpc/powerpc/machdep.c standard powerpc/powerpc/nexus.c standard powerpc/powerpc/ofwmagic.s standard diff --git a/sys/powerpc/aim/clock.c b/sys/powerpc/aim/clock.c index 3194674..5aa880f 100644 --- a/sys/powerpc/aim/clock.c +++ b/sys/powerpc/aim/clock.c @@ -83,7 +83,8 @@ static const char rcsid[] = /* * Initially we assume a processor with a bus frequency of 12.5 MHz. */ -static u_long ticks_per_sec = 12500000; +u_int tickspending; +static u_long ticks_per_sec = 12500000; static u_long ns_per_tick = 80; static long ticks_per_intr; static volatile u_long lasttb; @@ -189,28 +190,25 @@ decr_intr(struct clockframe *frame) */ lasttb = tb + tick - ticks_per_intr; - /* - * This probably needs some kind of locking. - */ - - intrcnt[CNT_CLOCK]++; - nticks += tickspending; tickspending = 0; /* * Reenable interrupts */ +#if 0 msr = mfmsr(); mtmsr(msr | PSL_EE | PSL_RI); - +#endif /* * Do standard timer interrupt stuff. * Do softclock stuff only on the last iteration. */ +#if 0 while (--nticks > 0) { hardclock(frame); } +#endif hardclock(frame); } diff --git a/sys/powerpc/aim/interrupt.c b/sys/powerpc/aim/interrupt.c new file mode 100644 index 0000000..491f53d --- /dev/null +++ b/sys/powerpc/aim/interrupt.c @@ -0,0 +1,123 @@ +/* + * Copyright 2002 by Peter Grehan. 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * $FreeBSD$ + */ + +/* + * Interrupts are dispatched to here from locore asm + */ + +#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/bus.h> +#include <sys/interrupt.h> +#include <sys/kernel.h> +#include <sys/kthread.h> +#include <sys/ktr.h> +#include <sys/lock.h> +#include <sys/malloc.h> +#include <sys/mutex.h> +#include <sys/proc.h> +#include <sys/smp.h> +#include <sys/unistd.h> +#include <sys/vmmeter.h> + +#include <machine/cpu.h> +#include <machine/db_machdep.h> +#include <machine/fpu.h> +#include <machine/frame.h> +#include <machine/pcb.h> +#include <machine/psl.h> +#include <machine/trap.h> +#include <machine/spr.h> +#include <machine/sr.h> +#include <machine/interruptvar.h> + +void powerpc_interrupt(struct trapframe *); + +u_long intrcnt[1]; +u_long eintrcnt[1]; + +char intrnames[1]; +char eintrnames[1]; + +/* + * External interrupt install routines + */ +static void (*powerpc_extintr_handler)(void); + +void +ext_intr_install(void (*new_extint)(void)) +{ + powerpc_extintr_handler = new_extint; +} + +extern void decr_intr(struct clockframe *); +extern void trap(struct trapframe *); + +/* + * A very short dispatch, to try and maximise assembler code use + * between all exception types. Maybe 'true' interrupts should go + * here, and the trap code can come in separately + */ +void +powerpc_interrupt(struct trapframe *framep) +{ + struct thread *td; + struct clockframe ckframe; + + td = curthread; + + switch (framep->exc) { + case EXC_EXI: + atomic_add_int(&td->td_intr_nesting_level, 1); + (*powerpc_extintr_handler)(); + atomic_subtract_int(&td->td_intr_nesting_level, 1); + break; + + case EXC_DECR: + atomic_add_int(&td->td_intr_nesting_level, 1); + ckframe.srr0 = framep->srr0; + ckframe.srr1 = framep->srr1; + decr_intr(&ckframe); + atomic_subtract_int(&td->td_intr_nesting_level, 1); + break; + + default: + /* + * Re-enable interrupts and call the generic trap code + */ +#if 0 + printf("powerpc_interrupt: got trap\n"); +#endif + mtmsr(mfmsr() | PSL_EE); + isync(); + trap(framep); + } +} diff --git a/sys/powerpc/aim/locore.S b/sys/powerpc/aim/locore.S index fa231e8..f8d0eb1 100644 --- a/sys/powerpc/aim/locore.S +++ b/sys/powerpc/aim/locore.S @@ -86,36 +86,6 @@ GLOBAL(proc0paddr) .long 0 /* proc0 p_addr */ GLOBAL(PTmap) .long 0 /* PTmap */ -GLOBAL(decrnest) - .long 0 - -GLOBAL(intrnames) - .asciz "irq0", "irq1", "irq2", "irq3" - .asciz "irq4", "irq5", "irq6", "irq7" - .asciz "irq8", "irq9", "irq10", "irq11" - .asciz "irq12", "irq13", "irq14", "irq15" - .asciz "irq16", "irq17", "irq18", "irq19" - .asciz "irq20", "irq21", "irq22", "irq23" - .asciz "irq24", "irq25", "irq26", "irq27" - .asciz "irq28", "irq29", "irq30", "irq31" - .asciz "irq32", "irq33", "irq34", "irq35" - .asciz "irq36", "irq37", "irq38", "irq39" - .asciz "irq40", "irq41", "irq42", "irq43" - .asciz "irq44", "irq45", "irq46", "irq47" - .asciz "irq48", "irq49", "irq50", "irq51" - .asciz "irq52", "irq53", "irq54", "irq55" - .asciz "irq56", "irq57", "irq58", "irq59" - .asciz "irq60", "irq61", "irq62", "irq63" - .asciz "clock", "softclock", "softnet", "softserial" -GLOBAL(eintrnames) - .align 4 -GLOBAL(intrcnt) - .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .long 0,0,0,0 -GLOBAL(eintrcnt) GLOBAL(ofmsr) .long 0 /* msr used in Open Firmware */ diff --git a/sys/powerpc/aim/trap_subr.S b/sys/powerpc/aim/trap_subr.S index 09b152b..0340d78 100644 --- a/sys/powerpc/aim/trap_subr.S +++ b/sys/powerpc/aim/trap_subr.S @@ -46,8 +46,6 @@ #define EXC_AST 0x3000 .data .align 4 -astpending: - .long 0 cpassert: .asciz "attempting to return from kernel with no current pmap" @@ -275,48 +273,6 @@ CNAME(isitrap601): CNAME(isi601size)= .-CNAME(isitrap601) /* - * This one for the external interrupt handler. - */ - .globl CNAME(extint),CNAME(extsize) -CNAME(extint): - mtsprg 1,1 /* save SP */ - stmw 28,tempsave(0) /* free r28-r31 */ - mflr 28 /* save LR */ - mfcr 29 /* save CR */ - mfxer 30 /* save XER */ - lis 1,intstk+INTSTK@ha /* get interrupt stack */ - addi 1,1,intstk+INTSTK@l /* this is really intr_depth! */ - lwz 31,0(1) /* were we already running on intstk? */ - addic. 31,31,1 - stw 31,0(1) - beq 1f - mfsprg 1,1 /* yes, get old SP */ -1: - ba extintr -CNAME(extsize) = .-CNAME(extint) - -/* - * And this one for the decrementer interrupt handler. - */ - .globl CNAME(decrint),CNAME(decrsize) -CNAME(decrint): - mtsprg 1,1 /* save SP */ - stmw 28,tempsave(0) /* free r28-r31 */ - mflr 28 /* save LR */ - mfcr 29 /* save CR */ - mfxer 30 /* save XER */ - lis 1,intstk+INTSTK@ha /* get interrupt stack */ - addi 1,1,intstk+INTSTK@l - lwz 31,0(1) /* were we already running on intstk? */ - addic. 31,31,1 - stw 31,0(1) - beq 1f - mfsprg 1,1 /* yes, get old SP */ -1: - ba decrintr -CNAME(decrsize) = .-CNAME(decrint) - -/* * Now the tlb software load for 603 processors: * (Code essentially from the 603e User Manual, Chapter 5, but * corrected a lot.) @@ -579,7 +535,7 @@ CNAME(ipkdbsize) = .-CNAME(ipkdblow) mfsrr1 31; \ stmw 30,savearea+24(0); \ mfmsr 30; \ - ori 30,30,(PSL_DR|PSL_IR); \ + ori 30,30,(PSL_DR|PSL_IR)@l; \ mtmsr 30; \ isync; \ mfsprg 31,1; \ @@ -710,16 +666,20 @@ s_trap: mtsr 7,31 FRAME_SETUP(tempsave) /* Now we can recover interrupts again: */ +#if 0 mfmsr 7 ori 7,7,(PSL_EE|PSL_ME|PSL_RI)@l mtmsr 7 isync -/* Call C trap code: */ +#endif +/* Call C interrupt dispatcher: */ trapagain: addi 3,1,8 - bl CNAME(trap) + bl CNAME(powerpc_interrupt) .globl CNAME(trapexit) CNAME(trapexit): + +#if 0 /* Disable interrupts: */ mfmsr 3 andi. 3,3,~PSL_EE@l @@ -728,14 +688,24 @@ CNAME(trapexit): lwz 5,FRAME_SRR1+8(1) mtcr 5 bc 4,17,1f /* branch if PSL_PR is false */ - lis 3,CNAME(astpending)@ha - lwz 4,CNAME(astpending)@l(3) - andi. 4,4,1 + + mfsprg 3, 0 /* get per-CPU pointer */ + lwz 4, PC_CURTHREAD(3) /* deref to get curthread */ + lwz 3, TD_KSE(4) /* deref to get current KSE */ + lwz 4, KE_FLAGS(3) /* get KSE flags value */ + andi. 4,4,KEF_ASTPENDING|KEF_NEEDRESCHED beq 1f - li 6,EXC_AST + li 6,EXC_AST /* update exception type */ stw 6,FRAME_EXC+8(1) - b trapagain + mfmsr 3 /* re-enable interrupts */ + ori 3,3,PSL_EE@l + mtmsr 3 + isync + addi 3,1,8 + bl CNAME(ast_test) + b trapexit /* test ast ret value ? */ 1: +#endif FRAME_LEAVE(tempsave) rfi @@ -820,157 +790,6 @@ s_isitrap: mfsrr0 3 b s_pte_spill /* above */ -/* - * External interrupt second level handler - */ -#define INTRENTER \ -/* Save non-volatile registers: */ \ - stwu 1,-IFRAMELEN(1); /* temporarily */ \ - stw 0,IFRAME_R0(1); \ - mfsprg 0,1; /* get original SP */ \ - stw 0,IFRAME_R1(1); /* and store it */ \ - stw 3,IFRAME_R3(1); \ - stw 4,IFRAME_R4(1); \ - stw 5,IFRAME_R5(1); \ - stw 6,IFRAME_R6(1); \ - stw 7,IFRAME_R7(1); \ - stw 8,IFRAME_R8(1); \ - stw 9,IFRAME_R9(1); \ - stw 10,IFRAME_R10(1); \ - stw 11,IFRAME_R11(1); \ - stw 12,IFRAME_R12(1); \ - stw 28,IFRAME_LR(1); /* saved LR */ \ - stw 29,IFRAME_CR(1); /* saved CR */ \ - stw 30,IFRAME_XER(1); /* saved XER */ \ - lmw 28,tempsave(0); /* restore r28-r31 */ \ - mfctr 6; \ - lis 5,CNAME(intr_depth)@ha; \ - lwz 5,CNAME(intr_depth)@l(5); \ - mfsrr0 4; \ - mfsrr1 3; \ - stw 6,IFRAME_CTR(1); \ - stw 5,IFRAME_INTR_DEPTH(1); \ - stw 4,IFRAME_SRR0(1); \ - stw 3,IFRAME_SRR1(1); \ - mtcr 3; \ - bc 4,17,99f; /* branch if PSL_PR is false */ \ - lis 3,EMPTY_SEGMENT@h; \ - ori 3,3,EMPTY_SEGMENT@l; \ - mtsr 0,3; /* reset SRs so BAT spills work */ \ - mtsr 1,3; \ - mtsr 2,3; \ - mtsr 3,3; \ - mtsr 4,3; \ - mtsr 5,3; \ - mtsr 6,3; \ - mtsr 7,3; \ -/* interrupts are recoverable here, and enable translation */ \ - lis 3,(KERNEL_SEGMENT|SR_KS|SR_KP)@h; \ - ori 3,3,(KERNEL_SEGMENT|SR_KS|SR_KP)@l; \ - mtsr KERNEL_SR,3; \ -99: mfmsr 5; \ - ori 5,5,(PSL_IR|PSL_DR|PSL_RI); \ - mtmsr 5; \ - isync - - .globl CNAME(extint_call) -extintr: - INTRENTER -CNAME(extint_call): - bl CNAME(extint_call) /* to be filled in later */ - -intr_exit: -/* Disable interrupts (should already be disabled) and MMU here: */ - mfmsr 3 - andi. 3,3,~(PSL_EE|PSL_ME|PSL_RI|PSL_DR|PSL_IR)@l - mtmsr 3 - isync -/* restore possibly overwritten registers: */ - lwz 12,IFRAME_R12(1) - lwz 11,IFRAME_R11(1) - lwz 10,IFRAME_R10(1) - lwz 9,IFRAME_R9(1) - lwz 8,IFRAME_R8(1) - lwz 7,IFRAME_R7(1) - lwz 6,IFRAME_SRR1(1) - lwz 5,IFRAME_SRR0(1) - lwz 4,IFRAME_CTR(1) - lwz 3,IFRAME_XER(1) - mtsrr1 6 - mtsrr0 5 - mtctr 4 - mtxer 3 -/* Returning to user mode? */ - mtcr 6 /* saved SRR1 */ - bc 4,17,1f /* branch if PSL_PR is false */ - mfsprg 31,0 - lwz 3,PC_CURPMAP(31) - lwz 4,PM_SR+0(3) - mtsr 0,4 /* Restore SR0 */ - lwz 4,PM_SR+4(3) - mtsr 1,4 /* Restore SR1 */ - lwz 4,PM_SR+8(3) - mtsr 2,4 /* Restore SR2 */ - lwz 4,PM_SR+12(3) - mtsr 3,4 /* Restore SR3 */ - lwz 4,PM_SR+16(3) - mtsr 4,4 /* Restore SR4 */ - lwz 4,PM_SR+20(3) - mtsr 5,4 /* Restore SR5 */ - lwz 4,PM_SR+24(3) - mtsr 6,4 /* Restore SR6 */ - lwz 4,PM_SR+28(3) - mtsr 7,4 /* Restore SR7 */ - lwz 3,PM_KERNELSR(3) - mtsr KERNEL_SR,3 /* Restore kernel SR */ - lis 3,CNAME(astpending)@ha /* Test AST pending */ - lwz 4,CNAME(astpending)@l(3) - andi. 4,4,1 - beq 1f -/* Setup for entry to realtrap: */ - lwz 3,IFRAME_R1(1) /* get saved SP */ - mtsprg 1,3 - li 6,EXC_AST - stmw 28,tempsave(0) /* establish tempsave again */ - mtlr 6 - lwz 28,IFRAME_LR(1) /* saved LR */ - lwz 29,IFRAME_CR(1) /* saved CR */ - lwz 6,IFRAME_R6(1) - lwz 5,IFRAME_R5(1) - lwz 4,IFRAME_R4(1) - lwz 3,IFRAME_R3(1) - lwz 0,IFRAME_R0(1) - lis 30,CNAME(intr_depth)@ha /* adjust reentrancy count */ - lwz 31,CNAME(intr_depth)@l(30) - addi 31,31,-1 - stw 31,CNAME(intr_depth)@l(30) - b realtrap -1: -/* Here is the normal exit of extintr: */ - lwz 5,IFRAME_CR(1) - lwz 6,IFRAME_LR(1) - mtcr 5 - mtlr 6 - lwz 6,IFRAME_R6(1) - lwz 5,IFRAME_R5(1) - lis 3,CNAME(intr_depth)@ha /* adjust reentrancy count */ - lwz 4,CNAME(intr_depth)@l(3) - addi 4,4,-1 - stw 4,CNAME(intr_depth)@l(3) - lwz 4,IFRAME_R4(1) - lwz 3,IFRAME_R3(1) - lwz 0,IFRAME_R0(1) - lwz 1,IFRAME_R1(1) - rfi - -/* - * Decrementer interrupt second level handler - */ -decrintr: - INTRENTER - addi 3,1,8 /* intr frame -> clock frame */ - bl CNAME(decr_intr) - b intr_exit #if defined(DDB) /* diff --git a/sys/powerpc/powerpc/clock.c b/sys/powerpc/powerpc/clock.c index 3194674..5aa880f 100644 --- a/sys/powerpc/powerpc/clock.c +++ b/sys/powerpc/powerpc/clock.c @@ -83,7 +83,8 @@ static const char rcsid[] = /* * Initially we assume a processor with a bus frequency of 12.5 MHz. */ -static u_long ticks_per_sec = 12500000; +u_int tickspending; +static u_long ticks_per_sec = 12500000; static u_long ns_per_tick = 80; static long ticks_per_intr; static volatile u_long lasttb; @@ -189,28 +190,25 @@ decr_intr(struct clockframe *frame) */ lasttb = tb + tick - ticks_per_intr; - /* - * This probably needs some kind of locking. - */ - - intrcnt[CNT_CLOCK]++; - nticks += tickspending; tickspending = 0; /* * Reenable interrupts */ +#if 0 msr = mfmsr(); mtmsr(msr | PSL_EE | PSL_RI); - +#endif /* * Do standard timer interrupt stuff. * Do softclock stuff only on the last iteration. */ +#if 0 while (--nticks > 0) { hardclock(frame); } +#endif hardclock(frame); } diff --git a/sys/powerpc/powerpc/interrupt.c b/sys/powerpc/powerpc/interrupt.c new file mode 100644 index 0000000..491f53d --- /dev/null +++ b/sys/powerpc/powerpc/interrupt.c @@ -0,0 +1,123 @@ +/* + * Copyright 2002 by Peter Grehan. 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * $FreeBSD$ + */ + +/* + * Interrupts are dispatched to here from locore asm + */ + +#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/bus.h> +#include <sys/interrupt.h> +#include <sys/kernel.h> +#include <sys/kthread.h> +#include <sys/ktr.h> +#include <sys/lock.h> +#include <sys/malloc.h> +#include <sys/mutex.h> +#include <sys/proc.h> +#include <sys/smp.h> +#include <sys/unistd.h> +#include <sys/vmmeter.h> + +#include <machine/cpu.h> +#include <machine/db_machdep.h> +#include <machine/fpu.h> +#include <machine/frame.h> +#include <machine/pcb.h> +#include <machine/psl.h> +#include <machine/trap.h> +#include <machine/spr.h> +#include <machine/sr.h> +#include <machine/interruptvar.h> + +void powerpc_interrupt(struct trapframe *); + +u_long intrcnt[1]; +u_long eintrcnt[1]; + +char intrnames[1]; +char eintrnames[1]; + +/* + * External interrupt install routines + */ +static void (*powerpc_extintr_handler)(void); + +void +ext_intr_install(void (*new_extint)(void)) +{ + powerpc_extintr_handler = new_extint; +} + +extern void decr_intr(struct clockframe *); +extern void trap(struct trapframe *); + +/* + * A very short dispatch, to try and maximise assembler code use + * between all exception types. Maybe 'true' interrupts should go + * here, and the trap code can come in separately + */ +void +powerpc_interrupt(struct trapframe *framep) +{ + struct thread *td; + struct clockframe ckframe; + + td = curthread; + + switch (framep->exc) { + case EXC_EXI: + atomic_add_int(&td->td_intr_nesting_level, 1); + (*powerpc_extintr_handler)(); + atomic_subtract_int(&td->td_intr_nesting_level, 1); + break; + + case EXC_DECR: + atomic_add_int(&td->td_intr_nesting_level, 1); + ckframe.srr0 = framep->srr0; + ckframe.srr1 = framep->srr1; + decr_intr(&ckframe); + atomic_subtract_int(&td->td_intr_nesting_level, 1); + break; + + default: + /* + * Re-enable interrupts and call the generic trap code + */ +#if 0 + printf("powerpc_interrupt: got trap\n"); +#endif + mtmsr(mfmsr() | PSL_EE); + isync(); + trap(framep); + } +} diff --git a/sys/powerpc/powerpc/locore.S b/sys/powerpc/powerpc/locore.S index fa231e8..f8d0eb1 100644 --- a/sys/powerpc/powerpc/locore.S +++ b/sys/powerpc/powerpc/locore.S @@ -86,36 +86,6 @@ GLOBAL(proc0paddr) .long 0 /* proc0 p_addr */ GLOBAL(PTmap) .long 0 /* PTmap */ -GLOBAL(decrnest) - .long 0 - -GLOBAL(intrnames) - .asciz "irq0", "irq1", "irq2", "irq3" - .asciz "irq4", "irq5", "irq6", "irq7" - .asciz "irq8", "irq9", "irq10", "irq11" - .asciz "irq12", "irq13", "irq14", "irq15" - .asciz "irq16", "irq17", "irq18", "irq19" - .asciz "irq20", "irq21", "irq22", "irq23" - .asciz "irq24", "irq25", "irq26", "irq27" - .asciz "irq28", "irq29", "irq30", "irq31" - .asciz "irq32", "irq33", "irq34", "irq35" - .asciz "irq36", "irq37", "irq38", "irq39" - .asciz "irq40", "irq41", "irq42", "irq43" - .asciz "irq44", "irq45", "irq46", "irq47" - .asciz "irq48", "irq49", "irq50", "irq51" - .asciz "irq52", "irq53", "irq54", "irq55" - .asciz "irq56", "irq57", "irq58", "irq59" - .asciz "irq60", "irq61", "irq62", "irq63" - .asciz "clock", "softclock", "softnet", "softserial" -GLOBAL(eintrnames) - .align 4 -GLOBAL(intrcnt) - .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .long 0,0,0,0 -GLOBAL(eintrcnt) GLOBAL(ofmsr) .long 0 /* msr used in Open Firmware */ diff --git a/sys/powerpc/powerpc/locore.s b/sys/powerpc/powerpc/locore.s index fa231e8..f8d0eb1 100644 --- a/sys/powerpc/powerpc/locore.s +++ b/sys/powerpc/powerpc/locore.s @@ -86,36 +86,6 @@ GLOBAL(proc0paddr) .long 0 /* proc0 p_addr */ GLOBAL(PTmap) .long 0 /* PTmap */ -GLOBAL(decrnest) - .long 0 - -GLOBAL(intrnames) - .asciz "irq0", "irq1", "irq2", "irq3" - .asciz "irq4", "irq5", "irq6", "irq7" - .asciz "irq8", "irq9", "irq10", "irq11" - .asciz "irq12", "irq13", "irq14", "irq15" - .asciz "irq16", "irq17", "irq18", "irq19" - .asciz "irq20", "irq21", "irq22", "irq23" - .asciz "irq24", "irq25", "irq26", "irq27" - .asciz "irq28", "irq29", "irq30", "irq31" - .asciz "irq32", "irq33", "irq34", "irq35" - .asciz "irq36", "irq37", "irq38", "irq39" - .asciz "irq40", "irq41", "irq42", "irq43" - .asciz "irq44", "irq45", "irq46", "irq47" - .asciz "irq48", "irq49", "irq50", "irq51" - .asciz "irq52", "irq53", "irq54", "irq55" - .asciz "irq56", "irq57", "irq58", "irq59" - .asciz "irq60", "irq61", "irq62", "irq63" - .asciz "clock", "softclock", "softnet", "softserial" -GLOBAL(eintrnames) - .align 4 -GLOBAL(intrcnt) - .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .long 0,0,0,0 -GLOBAL(eintrcnt) GLOBAL(ofmsr) .long 0 /* msr used in Open Firmware */ diff --git a/sys/powerpc/powerpc/trap_subr.S b/sys/powerpc/powerpc/trap_subr.S index 09b152b..0340d78 100644 --- a/sys/powerpc/powerpc/trap_subr.S +++ b/sys/powerpc/powerpc/trap_subr.S @@ -46,8 +46,6 @@ #define EXC_AST 0x3000 .data .align 4 -astpending: - .long 0 cpassert: .asciz "attempting to return from kernel with no current pmap" @@ -275,48 +273,6 @@ CNAME(isitrap601): CNAME(isi601size)= .-CNAME(isitrap601) /* - * This one for the external interrupt handler. - */ - .globl CNAME(extint),CNAME(extsize) -CNAME(extint): - mtsprg 1,1 /* save SP */ - stmw 28,tempsave(0) /* free r28-r31 */ - mflr 28 /* save LR */ - mfcr 29 /* save CR */ - mfxer 30 /* save XER */ - lis 1,intstk+INTSTK@ha /* get interrupt stack */ - addi 1,1,intstk+INTSTK@l /* this is really intr_depth! */ - lwz 31,0(1) /* were we already running on intstk? */ - addic. 31,31,1 - stw 31,0(1) - beq 1f - mfsprg 1,1 /* yes, get old SP */ -1: - ba extintr -CNAME(extsize) = .-CNAME(extint) - -/* - * And this one for the decrementer interrupt handler. - */ - .globl CNAME(decrint),CNAME(decrsize) -CNAME(decrint): - mtsprg 1,1 /* save SP */ - stmw 28,tempsave(0) /* free r28-r31 */ - mflr 28 /* save LR */ - mfcr 29 /* save CR */ - mfxer 30 /* save XER */ - lis 1,intstk+INTSTK@ha /* get interrupt stack */ - addi 1,1,intstk+INTSTK@l - lwz 31,0(1) /* were we already running on intstk? */ - addic. 31,31,1 - stw 31,0(1) - beq 1f - mfsprg 1,1 /* yes, get old SP */ -1: - ba decrintr -CNAME(decrsize) = .-CNAME(decrint) - -/* * Now the tlb software load for 603 processors: * (Code essentially from the 603e User Manual, Chapter 5, but * corrected a lot.) @@ -579,7 +535,7 @@ CNAME(ipkdbsize) = .-CNAME(ipkdblow) mfsrr1 31; \ stmw 30,savearea+24(0); \ mfmsr 30; \ - ori 30,30,(PSL_DR|PSL_IR); \ + ori 30,30,(PSL_DR|PSL_IR)@l; \ mtmsr 30; \ isync; \ mfsprg 31,1; \ @@ -710,16 +666,20 @@ s_trap: mtsr 7,31 FRAME_SETUP(tempsave) /* Now we can recover interrupts again: */ +#if 0 mfmsr 7 ori 7,7,(PSL_EE|PSL_ME|PSL_RI)@l mtmsr 7 isync -/* Call C trap code: */ +#endif +/* Call C interrupt dispatcher: */ trapagain: addi 3,1,8 - bl CNAME(trap) + bl CNAME(powerpc_interrupt) .globl CNAME(trapexit) CNAME(trapexit): + +#if 0 /* Disable interrupts: */ mfmsr 3 andi. 3,3,~PSL_EE@l @@ -728,14 +688,24 @@ CNAME(trapexit): lwz 5,FRAME_SRR1+8(1) mtcr 5 bc 4,17,1f /* branch if PSL_PR is false */ - lis 3,CNAME(astpending)@ha - lwz 4,CNAME(astpending)@l(3) - andi. 4,4,1 + + mfsprg 3, 0 /* get per-CPU pointer */ + lwz 4, PC_CURTHREAD(3) /* deref to get curthread */ + lwz 3, TD_KSE(4) /* deref to get current KSE */ + lwz 4, KE_FLAGS(3) /* get KSE flags value */ + andi. 4,4,KEF_ASTPENDING|KEF_NEEDRESCHED beq 1f - li 6,EXC_AST + li 6,EXC_AST /* update exception type */ stw 6,FRAME_EXC+8(1) - b trapagain + mfmsr 3 /* re-enable interrupts */ + ori 3,3,PSL_EE@l + mtmsr 3 + isync + addi 3,1,8 + bl CNAME(ast_test) + b trapexit /* test ast ret value ? */ 1: +#endif FRAME_LEAVE(tempsave) rfi @@ -820,157 +790,6 @@ s_isitrap: mfsrr0 3 b s_pte_spill /* above */ -/* - * External interrupt second level handler - */ -#define INTRENTER \ -/* Save non-volatile registers: */ \ - stwu 1,-IFRAMELEN(1); /* temporarily */ \ - stw 0,IFRAME_R0(1); \ - mfsprg 0,1; /* get original SP */ \ - stw 0,IFRAME_R1(1); /* and store it */ \ - stw 3,IFRAME_R3(1); \ - stw 4,IFRAME_R4(1); \ - stw 5,IFRAME_R5(1); \ - stw 6,IFRAME_R6(1); \ - stw 7,IFRAME_R7(1); \ - stw 8,IFRAME_R8(1); \ - stw 9,IFRAME_R9(1); \ - stw 10,IFRAME_R10(1); \ - stw 11,IFRAME_R11(1); \ - stw 12,IFRAME_R12(1); \ - stw 28,IFRAME_LR(1); /* saved LR */ \ - stw 29,IFRAME_CR(1); /* saved CR */ \ - stw 30,IFRAME_XER(1); /* saved XER */ \ - lmw 28,tempsave(0); /* restore r28-r31 */ \ - mfctr 6; \ - lis 5,CNAME(intr_depth)@ha; \ - lwz 5,CNAME(intr_depth)@l(5); \ - mfsrr0 4; \ - mfsrr1 3; \ - stw 6,IFRAME_CTR(1); \ - stw 5,IFRAME_INTR_DEPTH(1); \ - stw 4,IFRAME_SRR0(1); \ - stw 3,IFRAME_SRR1(1); \ - mtcr 3; \ - bc 4,17,99f; /* branch if PSL_PR is false */ \ - lis 3,EMPTY_SEGMENT@h; \ - ori 3,3,EMPTY_SEGMENT@l; \ - mtsr 0,3; /* reset SRs so BAT spills work */ \ - mtsr 1,3; \ - mtsr 2,3; \ - mtsr 3,3; \ - mtsr 4,3; \ - mtsr 5,3; \ - mtsr 6,3; \ - mtsr 7,3; \ -/* interrupts are recoverable here, and enable translation */ \ - lis 3,(KERNEL_SEGMENT|SR_KS|SR_KP)@h; \ - ori 3,3,(KERNEL_SEGMENT|SR_KS|SR_KP)@l; \ - mtsr KERNEL_SR,3; \ -99: mfmsr 5; \ - ori 5,5,(PSL_IR|PSL_DR|PSL_RI); \ - mtmsr 5; \ - isync - - .globl CNAME(extint_call) -extintr: - INTRENTER -CNAME(extint_call): - bl CNAME(extint_call) /* to be filled in later */ - -intr_exit: -/* Disable interrupts (should already be disabled) and MMU here: */ - mfmsr 3 - andi. 3,3,~(PSL_EE|PSL_ME|PSL_RI|PSL_DR|PSL_IR)@l - mtmsr 3 - isync -/* restore possibly overwritten registers: */ - lwz 12,IFRAME_R12(1) - lwz 11,IFRAME_R11(1) - lwz 10,IFRAME_R10(1) - lwz 9,IFRAME_R9(1) - lwz 8,IFRAME_R8(1) - lwz 7,IFRAME_R7(1) - lwz 6,IFRAME_SRR1(1) - lwz 5,IFRAME_SRR0(1) - lwz 4,IFRAME_CTR(1) - lwz 3,IFRAME_XER(1) - mtsrr1 6 - mtsrr0 5 - mtctr 4 - mtxer 3 -/* Returning to user mode? */ - mtcr 6 /* saved SRR1 */ - bc 4,17,1f /* branch if PSL_PR is false */ - mfsprg 31,0 - lwz 3,PC_CURPMAP(31) - lwz 4,PM_SR+0(3) - mtsr 0,4 /* Restore SR0 */ - lwz 4,PM_SR+4(3) - mtsr 1,4 /* Restore SR1 */ - lwz 4,PM_SR+8(3) - mtsr 2,4 /* Restore SR2 */ - lwz 4,PM_SR+12(3) - mtsr 3,4 /* Restore SR3 */ - lwz 4,PM_SR+16(3) - mtsr 4,4 /* Restore SR4 */ - lwz 4,PM_SR+20(3) - mtsr 5,4 /* Restore SR5 */ - lwz 4,PM_SR+24(3) - mtsr 6,4 /* Restore SR6 */ - lwz 4,PM_SR+28(3) - mtsr 7,4 /* Restore SR7 */ - lwz 3,PM_KERNELSR(3) - mtsr KERNEL_SR,3 /* Restore kernel SR */ - lis 3,CNAME(astpending)@ha /* Test AST pending */ - lwz 4,CNAME(astpending)@l(3) - andi. 4,4,1 - beq 1f -/* Setup for entry to realtrap: */ - lwz 3,IFRAME_R1(1) /* get saved SP */ - mtsprg 1,3 - li 6,EXC_AST - stmw 28,tempsave(0) /* establish tempsave again */ - mtlr 6 - lwz 28,IFRAME_LR(1) /* saved LR */ - lwz 29,IFRAME_CR(1) /* saved CR */ - lwz 6,IFRAME_R6(1) - lwz 5,IFRAME_R5(1) - lwz 4,IFRAME_R4(1) - lwz 3,IFRAME_R3(1) - lwz 0,IFRAME_R0(1) - lis 30,CNAME(intr_depth)@ha /* adjust reentrancy count */ - lwz 31,CNAME(intr_depth)@l(30) - addi 31,31,-1 - stw 31,CNAME(intr_depth)@l(30) - b realtrap -1: -/* Here is the normal exit of extintr: */ - lwz 5,IFRAME_CR(1) - lwz 6,IFRAME_LR(1) - mtcr 5 - mtlr 6 - lwz 6,IFRAME_R6(1) - lwz 5,IFRAME_R5(1) - lis 3,CNAME(intr_depth)@ha /* adjust reentrancy count */ - lwz 4,CNAME(intr_depth)@l(3) - addi 4,4,-1 - stw 4,CNAME(intr_depth)@l(3) - lwz 4,IFRAME_R4(1) - lwz 3,IFRAME_R3(1) - lwz 0,IFRAME_R0(1) - lwz 1,IFRAME_R1(1) - rfi - -/* - * Decrementer interrupt second level handler - */ -decrintr: - INTRENTER - addi 3,1,8 /* intr frame -> clock frame */ - bl CNAME(decr_intr) - b intr_exit #if defined(DDB) /* |