Change bc x,y,z to their simplified mnemonics. During a kernel DSI fault,
if the exception address is < 1 page away from the KSP, switch to the that CPU's spill stack to handle the trap. Otherwise you can get in a infinite DSI fault loop.
This commit is contained in:
parent
0e50e47bb9
commit
9254350d6a
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: trap_subr.S,v 1.43 2003/08/04 00:32:50 matt Exp $ */
|
/* $NetBSD: trap_subr.S,v 1.44 2003/08/04 22:29:59 matt Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
|
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
|
||||||
@ -200,7 +200,7 @@ _C_LABEL(dsitrap):
|
|||||||
mtsprg2 %r30 /* in SPRG2 */
|
mtsprg2 %r30 /* in SPRG2 */
|
||||||
mfsrr1 %r31 /* test kernel mode */
|
mfsrr1 %r31 /* test kernel mode */
|
||||||
mtcr %r31
|
mtcr %r31
|
||||||
bc 12,17,1f /* branch if PSL_PR is set */
|
bt 17,1f /* branch if PSL_PR is set */
|
||||||
mfdar %r31 /* get fault address */
|
mfdar %r31 /* get fault address */
|
||||||
rlwinm %r31,%r31,7,25,28 /* get segment * 8 */
|
rlwinm %r31,%r31,7,25,28 /* get segment * 8 */
|
||||||
|
|
||||||
@ -208,7 +208,7 @@ _C_LABEL(dsitrap):
|
|||||||
addis %r31,%r31,_C_LABEL(battable)@ha
|
addis %r31,%r31,_C_LABEL(battable)@ha
|
||||||
ldreg %r30,_C_LABEL(battable)@l(%r31)
|
ldreg %r30,_C_LABEL(battable)@l(%r31)
|
||||||
mtcr %r30
|
mtcr %r30
|
||||||
bc 4,30,1f /* branch if supervisor valid is
|
bf 30,1f /* branch if supervisor valid is
|
||||||
false */
|
false */
|
||||||
/* get batl */
|
/* get batl */
|
||||||
ldreg %r31,_C_LABEL(battable)+SZREG@l(%r31)
|
ldreg %r31,_C_LABEL(battable)+SZREG@l(%r31)
|
||||||
@ -261,7 +261,7 @@ _C_LABEL(dsi601trap):
|
|||||||
mtsprg2 %r30 /* in SPRG2 */
|
mtsprg2 %r30 /* in SPRG2 */
|
||||||
mfsrr1 %r31 /* test kernel mode */
|
mfsrr1 %r31 /* test kernel mode */
|
||||||
mtcr %r31
|
mtcr %r31
|
||||||
bc 12,17,1f /* branch if PSL_PR is set */
|
bt 17,1f /* branch if PSL_PR is set */
|
||||||
mfdar %r31 /* get fault address */
|
mfdar %r31 /* get fault address */
|
||||||
rlwinm %r31,%r31,12,20,28 /* get "segment" battable offset */
|
rlwinm %r31,%r31,12,20,28 /* get "segment" battable offset */
|
||||||
|
|
||||||
@ -269,7 +269,7 @@ _C_LABEL(dsi601trap):
|
|||||||
addis %r31,%r31,_C_LABEL(battable)@ha
|
addis %r31,%r31,_C_LABEL(battable)@ha
|
||||||
ldreg %r30,_C_LABEL(battable)+SZREG@l(%r31)
|
ldreg %r30,_C_LABEL(battable)+SZREG@l(%r31)
|
||||||
mtcr %r30
|
mtcr %r30
|
||||||
bc 4,25,1f /* branch if Valid is is false,
|
bf 25,1f /* branch if Valid is is false,
|
||||||
presently assumes supervisor only */
|
presently assumes supervisor only */
|
||||||
|
|
||||||
/* get batu */
|
/* get batu */
|
||||||
@ -770,7 +770,7 @@ _C_LABEL(ipkdbsize) = .-_C_LABEL(ipkdblow)
|
|||||||
GET_CPUINFO(%r2); \
|
GET_CPUINFO(%r2); \
|
||||||
ldreg %r3,(savearea+CPUSAVE_SRR1)(%r2); \
|
ldreg %r3,(savearea+CPUSAVE_SRR1)(%r2); \
|
||||||
mtcr %r3; \
|
mtcr %r3; \
|
||||||
bc 4,17,1f; /* branch if PSL_PR is false */ \
|
bf 17,1f; /* branch if PSL_PR is false */ \
|
||||||
/* Restore user SRs */ \
|
/* Restore user SRs */ \
|
||||||
CPU601_KERN_LEAVE(%r2,%r3); \
|
CPU601_KERN_LEAVE(%r2,%r3); \
|
||||||
RESTORE_USER_SRS(%r2,%r3); \
|
RESTORE_USER_SRS(%r2,%r3); \
|
||||||
@ -801,6 +801,20 @@ disitrap:
|
|||||||
mfdsisr %r31
|
mfdsisr %r31
|
||||||
streg %r30,(CI_TEMPSAVE+CPUSAVE_DAR)(%r1)
|
streg %r30,(CI_TEMPSAVE+CPUSAVE_DAR)(%r1)
|
||||||
streg %r31,(CI_TEMPSAVE+CPUSAVE_DSISR)(%r1)
|
streg %r31,(CI_TEMPSAVE+CPUSAVE_DSISR)(%r1)
|
||||||
|
|
||||||
|
mfsrr1 %r30
|
||||||
|
mtcr %r30
|
||||||
|
|
||||||
|
bt 17,u_trap /* branch if PSL_PR is true */
|
||||||
|
mfsprg1 %r1 /* restore [K]SP */
|
||||||
|
subf %r30,%r30,%r1 /* get the distance between the KSP
|
||||||
|
and the exception address */
|
||||||
|
cmplwi %r30,NBPG /* distance less than a page? */
|
||||||
|
bgt+ k_trap /* no, use existing kernel stack */
|
||||||
|
GET_CPUINFO(%r1) /* get cpu_info for this cpu */
|
||||||
|
ldptr %r1,CI_SPILLSTK(%r1) /* get top of spill stack */
|
||||||
|
b k_trap
|
||||||
|
|
||||||
.globl _C_LABEL(trapstart)
|
.globl _C_LABEL(trapstart)
|
||||||
_C_LABEL(trapstart):
|
_C_LABEL(trapstart):
|
||||||
realtrap:
|
realtrap:
|
||||||
@ -810,8 +824,9 @@ realtrap:
|
|||||||
mfsprg1 %r1 /* restore SP (might have been
|
mfsprg1 %r1 /* restore SP (might have been
|
||||||
overwritten) */
|
overwritten) */
|
||||||
s_trap:
|
s_trap:
|
||||||
bc 4,17,k_trap /* branch if PSL_PR is false */
|
bf 17,k_trap /* branch if PSL_PR is false */
|
||||||
GET_CPUINFO(%r1)
|
u_trap:
|
||||||
|
GET_CPUINFO(%r1) /* get cpu_info for this cpu */
|
||||||
ldptr %r1,CI_CURPCB(%r1)
|
ldptr %r1,CI_CURPCB(%r1)
|
||||||
addi %r1,%r1,USPACE /* stack is top of user struct */
|
addi %r1,%r1,USPACE /* stack is top of user struct */
|
||||||
|
|
||||||
@ -843,7 +858,7 @@ trapexit:
|
|||||||
/* Test AST pending: */
|
/* Test AST pending: */
|
||||||
ldreg %r5,(FRAME_SRR1+(2*SZREG))(%r1)
|
ldreg %r5,(FRAME_SRR1+(2*SZREG))(%r1)
|
||||||
mtcr %r5
|
mtcr %r5
|
||||||
bc 4,17,1f /* branch if PSL_PR is false */
|
bf 17,1f /* branch if PSL_PR is false */
|
||||||
GET_CPUINFO(%r3)
|
GET_CPUINFO(%r3)
|
||||||
ldint %r4,CI_ASTPENDING(%r3)
|
ldint %r4,CI_ASTPENDING(%r3)
|
||||||
andi. %r4,%r4,1
|
andi. %r4,%r4,1
|
||||||
@ -945,7 +960,7 @@ _C_LABEL(sctrapexit):
|
|||||||
streg %r4,IFRAME_SRR0(%r1); \
|
streg %r4,IFRAME_SRR0(%r1); \
|
||||||
streg %r3,IFRAME_SRR1(%r1); \
|
streg %r3,IFRAME_SRR1(%r1); \
|
||||||
mtcr %r3; \
|
mtcr %r3; \
|
||||||
bc 4,17,99f; /* branch if PSL_PR is false */ \
|
bf 17,99f; /* branch if PSL_PR is false */ \
|
||||||
/* interrupts are recoverable here, and enable translation */ \
|
/* interrupts are recoverable here, and enable translation */ \
|
||||||
RESTORE_KERN_SRS(%r3,%r4); \
|
RESTORE_KERN_SRS(%r3,%r4); \
|
||||||
CPU601_KERN_ENTRY(%r3,%r4); \
|
CPU601_KERN_ENTRY(%r3,%r4); \
|
||||||
@ -991,7 +1006,7 @@ intr_exit:
|
|||||||
|
|
||||||
/* Returning to user mode? */
|
/* Returning to user mode? */
|
||||||
mtcr %r6 /* saved SRR1 */
|
mtcr %r6 /* saved SRR1 */
|
||||||
bc 4,17,1f /* branch if PSL_PR is false */
|
bf 17,1f /* branch if PSL_PR is false */
|
||||||
|
|
||||||
CPU601_KERN_LEAVE(%r3,%r4)
|
CPU601_KERN_LEAVE(%r3,%r4)
|
||||||
RESTORE_USER_SRS(%r3,%r4)
|
RESTORE_USER_SRS(%r3,%r4)
|
||||||
|
Loading…
Reference in New Issue
Block a user