Many fixes to low-level trap and interrupt handling:

- Tidy up clock code.  Don't repeatedly call hardclock().
- Remove intrnames, decrnest and intrcnt from locore.s
- Coalesce all trap handling into a single stub that then calls a dispatch
  function.

Submitted by:	Peter Grehan <peterg@ptree32.com.au>
This commit is contained in:
Benno Rice 2002-06-29 09:28:21 +00:00
parent 0c079d8c6f
commit 6c2a062580
10 changed files with 303 additions and 512 deletions

View File

@ -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

View File

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

123
sys/powerpc/aim/interrupt.c Normal file
View File

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

View File

@ -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 */

View File

@ -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"
@ -274,48 +272,6 @@ CNAME(isitrap601):
bla s_isitrap
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
@ -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)
/*

View File

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

View File

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

View File

@ -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 */

View File

@ -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 */

View File

@ -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"
@ -274,48 +272,6 @@ CNAME(isitrap601):
bla s_isitrap
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
@ -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)
/*