#ifdef _KERNEL_OPT
#include "opt_altivec.h"
#include "opt_ddb.h"
#include "opt_kgdb.h"
#include "opt_ppcarch.h"
#include "opt_multiprocessor.h"
#endif
#ifdef ALTIVEC
#define SAVE_VRSAVE(tf,b) \
mfspr b,SPR_VRSAVE; \
stint b,FRAME_VRSAVE(tf);
#define RESTORE_VRSAVE(tf,b) \
ldint b,FRAME_VRSAVE(tf); \
mtspr SPR_VRSAVE,b;
#else
#define SAVE_VRSAVE(tf,b)
#define RESTORE_VRSAVE(tf,b)
#endif
#if defined (PPC_OEA64) || defined (PPC_OEA64_BRIDGE)
#define RFI rfid
#else
#define RFI rfi
#endif
#ifdef MULTIPROCESSOR
#define CLEAR_RESERVATION \
POWERPC_STWCX_PRE(0,%r1); \
stwcx. %r1,0,%r1;
#else
#define CLEAR_RESERVATION
#endif
#if defined (PPC_OEA64_BRIDGE)
#define ENABLE_64BIT_BRIDGE(t0) \
mfmsr t0; \
clrldi t0,t0,1; \
mtmsrd t0;
#else
#define ENABLE_64BIT_BRIDGE(t0)
#endif
#if defined(PPC_OEA64)
#define RESTORE_USER_SRS(t0,t1) \
GET_CPUINFO(t0); \
ldptr t0,CI_CURPM(t0); \
ldreg t0,PM_STEG(t0); \
mtasr t0
#define RESTORE_KERN_SRS(t0,t1) \
lis t0,_C_LABEL(kernel_pmap_)@ha; \
ldreg t0,_C_LABEL(kernel_pmap_)+PM_STEG@l(t0); \
mtasr t0
#elif defined(PPC_MPC8XX)
#define RESTORE_USER_SRS(t0,t1)
#define RESTORE_KERN_SRS(t0,t1)
#else
#define RESTORE_SRS(pmap,sr) mtsr 0,sr; \
ldreg sr,4(pmap); mtsr 1,sr; \
ldreg sr,8(pmap); mtsr 2,sr; \
ldreg sr,12(pmap); mtsr 3,sr; \
ldreg sr,16(pmap); mtsr 4,sr; \
ldreg sr,20(pmap); mtsr 5,sr; \
ldreg sr,24(pmap); mtsr 6,sr; \
ldreg sr,28(pmap); mtsr 7,sr; \
ldreg sr,32(pmap); mtsr 8,sr; \
ldreg sr,36(pmap); mtsr 9,sr; \
ldreg sr,40(pmap); mtsr 10,sr; \
ldreg sr,44(pmap); mtsr 11,sr; \
ldreg sr,48(pmap); mtsr 12,sr; \
ldreg sr,52(pmap); mtsr 13,sr; \
ldreg sr,56(pmap); mtsr 14,sr; \
ldreg sr,60(pmap); mtsr 15,sr; isync;
#define RESTORE_USER_SRS(pmap,sr) \
GET_CPUINFO(pmap); \
ldptr pmap,CI_CURPM(pmap); \
ldregu sr,PM_SR(pmap); \
RESTORE_SRS(pmap,sr); \
\
li sr,0; \
mtibatl 0,sr; \
mtibatl 1,sr; \
mtibatl 2,sr; \
mtibatl 3,sr
#define RESTORE_KERN_SRS(pmap,sr) \
lis pmap,_C_LABEL(kernel_pmap_)@ha; \
ldregu sr,_C_LABEL(kernel_pmap_)+PM_SR@l(pmap); \
RESTORE_SRS(pmap,sr); \
\
lis pmap,_C_LABEL(battable)@ha; \
ldregu sr,_C_LABEL(battable)@l(pmap); \
mtibatu 0,sr; \
ldreg sr,4(pmap); mtibatl 0,sr; \
ldreg sr,8(pmap); mtibatu 1,sr; \
ldreg sr,12(pmap); mtibatl 1,sr
#endif
#if defined(PPC_OEA601)
#define SAVE_MQ(tf,b) \
mfspr b,SPR_MQ; \
streg b,FRAME_MQ(tf);
#define RESTORE_MQ(tf,b) \
ldreg b,FRAME_MQ(tf); \
mtspr SPR_MQ,b;
#else
#define SAVE_MQ(tf,b)
#define RESTORE_MQ(tf,b)
#endif
.text
.globl _C_LABEL(trapcode),_C_LABEL(trapsize)
_C_LABEL(trapcode):
mtsprg1 %r1
ENABLE_64BIT_BRIDGE(%r1)
GET_CPUINFO(%r1)
streg %r28,(CI_TEMPSAVE+CPUSAVE_R28)(%r1)
streg %r29,(CI_TEMPSAVE+CPUSAVE_R29)(%r1)
streg %r30,(CI_TEMPSAVE+CPUSAVE_R30)(%r1)
streg %r31,(CI_TEMPSAVE+CPUSAVE_R31)(%r1)
mfsprg1 %r1
mflr %r28
mfcr %r29
mfsrr1 %r31
mtcr %r31
#if defined(DISTANT_KERNEL)
lis %r31,s_trap@ha
addi %r31,%r31,s_trap@l
mtlr %r31
blrl
#else
bla s_trap
#endif
_C_LABEL(trapsize) = .-_C_LABEL(trapcode)
.globl _C_LABEL(alitrap),_C_LABEL(alisize)
_C_LABEL(alitrap):
mtsprg1 %r1
ENABLE_64BIT_BRIDGE(%r1)
GET_CPUINFO(%r1)
streg %r28,(CI_TEMPSAVE+CPUSAVE_R28)(%r1)
streg %r29,(CI_TEMPSAVE+CPUSAVE_R29)(%r1)
streg %r30,(CI_TEMPSAVE+CPUSAVE_R30)(%r1)
streg %r31,(CI_TEMPSAVE+CPUSAVE_R31)(%r1)
mfdar %r30
mfdsisr %r31
streg %r30,(CI_TEMPSAVE+CPUSAVE_DAR)(%r1)
streg %r31,(CI_TEMPSAVE+CPUSAVE_DSISR)(%r1)
mfsprg1 %r1
mflr %r28
mfcr %r29
mfsrr1 %r31
mtcr %r31
#if defined(DISTANT_KERNEL)
lis %r31,s_trap@ha
addi %r31,%r31,s_trap@l
mtlr %r31
blrl
#else
bla s_trap
#endif
_C_LABEL(alisize) = .-_C_LABEL(alitrap)
#if !defined(PPC_MPC8XX)
.globl _C_LABEL(dsitrap),_C_LABEL(dsisize)
_C_LABEL(dsitrap):
mtsprg1 %r1
ENABLE_64BIT_BRIDGE(%r1)
GET_CPUINFO(%r1)
streg %r28,(CI_DISISAVE+CPUSAVE_R28)(%r1)
streg %r29,(CI_DISISAVE+CPUSAVE_R29)(%r1)
streg %r30,(CI_DISISAVE+CPUSAVE_R30)(%r1)
streg %r31,(CI_DISISAVE+CPUSAVE_R31)(%r1)
mfsprg1 %r1
mfcr %r29
mfsrr1 %r31
mtcr %r31
#if !defined(PPC_MPC8XX)
mfxer %r30
mtsprg2 %r30
bt MSR_PR,1f
mfdar %r31
rlwinm %r31,%r31,3+(32-BAT_ADDR_SHIFT),BAT_ADDR_SHIFT-3,28
GET_CPUINFO(%r30)
ldreg %r30,CI_BATTABLE(%r30)
add %r31,%r31,%r30
ldreg %r30,0(%r31)
mtcr %r30
bf 30,1f
ldreg %r31,SZREG(%r31)
mftb %r28
mtcr %r28
.globl dsitrap_fix_dbat4, dsitrap_fix_dbat5
.globl dsitrap_fix_dbat6, dsitrap_fix_dbat7
dsitrap_fix_dbat4:
bt 31,3f
mtspr SPR_DBAT2U,%r30
mtspr SPR_DBAT2L,%r31
b 8f
b 8f
dsitrap_fix_dbat5:
mtspr SPR_DBAT5U,%r30
mtspr SPR_DBAT5L,%r31
b 8f
dsitrap_fix_dbat6:
bt 30,3f
mtspr SPR_DBAT6U,%r30
mtspr SPR_DBAT6L,%r31
b 8f
3:
dsitrap_fix_dbat7:
mtspr SPR_DBAT3U,%r30
mtspr SPR_DBAT3L,%r31
8:
mfsprg2 %r30
mtxer %r30
mtcr %r29
mtsprg1 %r1
GET_CPUINFO(%r1)
ldreg %r28,(CI_DISISAVE+CPUSAVE_R28)(%r1)
ldreg %r29,(CI_DISISAVE+CPUSAVE_R29)(%r1)
ldreg %r30,(CI_DISISAVE+CPUSAVE_R30)(%r1)
ldreg %r31,(CI_DISISAVE+CPUSAVE_R31)(%r1)
mfsprg1 %r1
RFI
1:
#endif
mflr %r28
mtsprg1 %r1
#if defined(DISTANT_KERNEL)
lis %r31,disitrap@ha
addi %r31,%r31,disitrap@l
mtlr %r31
blrl
#else
bla disitrap
#endif
_C_LABEL(dsisize) = .-_C_LABEL(dsitrap)
#endif
#if defined(PPC_OEA601)
.globl _C_LABEL(dsi601trap),_C_LABEL(dsi601size)
_C_LABEL(dsi601trap):
mtsprg1 %r1
ENABLE_64BIT_BRIDGE(%r1)
GET_CPUINFO(%r1)
streg %r28,(CI_DISISAVE+CPUSAVE_R28)(%r1)
streg %r29,(CI_DISISAVE+CPUSAVE_R29)(%r1)
streg %r30,(CI_DISISAVE+CPUSAVE_R30)(%r1)
streg %r31,(CI_DISISAVE+CPUSAVE_R31)(%r1)
mfsprg1 %r1
mfcr %r29
mfxer %r30
mtsprg2 %r30
mfsrr1 %r31
mtcr %r31
bt MSR_PR,1f
mfdar %r31
rlwinm %r31,%r31,12,20,28
GET_CPUINFO(%r30)
ldreg %r30,CI_BATTABLE(%r30)
add %r31,%r31,%r30
ldreg %r30,SZREG(%r31)
mtcr %r30
bf 25,1f
ldreg %r31,0(%r31)
mfspr %r28,SPR_RTCL_R
andi. %r28,%r28,128
bne 2f
mtibatu 2,%r31
mtibatl 2,%r30
b 3f
2:
mtibatu 3,%r31
mtibatl 3,%r30
3:
mfsprg2 %r30
mtxer %r30
mtcr %r29
mtsprg1 %r1
GET_CPUINFO(%r1)
ldreg %r28,(CI_DISISAVE+CPUSAVE_R28)(%r1)
ldreg %r29,(CI_DISISAVE+CPUSAVE_R29)(%r1)
ldreg %r30,(CI_DISISAVE+CPUSAVE_R30)(%r1)
ldreg %r31,(CI_DISISAVE+CPUSAVE_R31)(%r1)
mfsprg1 %r1
RFI
1:
mflr %r28
mtsprg1 %r1
#if defined(DISTANT_KERNEL)
lis %r31,disitrap@ha
addi %r31,%r31,disitrap@l
mtlr %r31
blrl
#else
bla disitrap
#endif
_C_LABEL(dsi601size) = .-_C_LABEL(dsi601trap)
#endif
.globl _C_LABEL(extint),_C_LABEL(extsize)
_C_LABEL(extint):
mtsprg1 %r1
ENABLE_64BIT_BRIDGE(%r1)
GET_CPUINFO(%r1)
streg %r28,(CI_TEMPSAVE+CPUSAVE_R28)(%r1)
streg %r29,(CI_TEMPSAVE+CPUSAVE_R29)(%r1)
streg %r30,(CI_TEMPSAVE+CPUSAVE_R30)(%r1)
streg %r31,(CI_TEMPSAVE+CPUSAVE_R31)(%r1)
mflr %r28
mfcr %r29
mfsrr1 %r31
mtcr %r31
mr %r30,%r1
mfsprg1 %r1
bf MSR_PR,1f
ldptr %r1,CI_CURPCB(%r30)
addi %r1,%r1,USPACE-CALLFRAMELEN
RESTORE_KERN_SRS(%r30, %r31)
1:
#if defined(DISTANT_KERNEL)
lis %r31,extintr@ha
addi %r31,%r31,extintr@l
mtlr %r31
blr
#else
ba extintr
#endif
_C_LABEL(extsize) = .-_C_LABEL(extint)
.globl _C_LABEL(decrint),_C_LABEL(decrsize)
_C_LABEL(decrint):
mtsprg1 %r1
ENABLE_64BIT_BRIDGE(%r1)
GET_CPUINFO(%r1)
streg %r28,(CI_TEMPSAVE+CPUSAVE_R28)(%r1)
streg %r29,(CI_TEMPSAVE+CPUSAVE_R29)(%r1)
streg %r30,(CI_TEMPSAVE+CPUSAVE_R30)(%r1)
streg %r31,(CI_TEMPSAVE+CPUSAVE_R31)(%r1)
mflr %r28
mfcr %r29
mfsrr1 %r31
mtcr %r31
mr %r30,%r1
mfsprg1 %r1
bf MSR_PR,1f
ldptr %r1,CI_CURPCB(%r30)
addi %r1,%r1,USPACE-CALLFRAMELEN
RESTORE_KERN_SRS(%r30, %r31)
1:
#if defined(DISTANT_KERNEL)
lis %r31,decrintr@ha
addi %r31,%r31,decrintr@l
mtlr %r31
blr
#else
ba decrintr
#endif
_C_LABEL(decrsize) = .-_C_LABEL(decrint)
#if !defined(PPC_OEA64) && !defined(PPC_MPC8XX)
.globl _C_LABEL(tlbimiss),_C_LABEL(tlbimsize)
_C_LABEL(tlbimiss):
mfspr %r2,SPR_HASH1
li %r1,8
mfctr %r0
mfspr %r3,SPR_ICMP
addi %r2,%r2,-8
1:
mtctr %r1
2:
ldregu %r1,8(%r2)
cmplw %r1,%r3
bdneq 2b
bne 3f
ldreg %r1,4(%r2)
andi. %r3,%r1,PTE_G
bne 4f
mtctr %r0
mfspr %r0,SPR_IMISS
mfsrr1 %r3
mtcrf 0x80,%r3
ori %r1,%r1,PTE_REF
mtspr SPR_RPA,1
srwi %r1,%r1,8
tlbli %r0
stb %r1,6(%r2)
RFI
3:
andi. %r1,%r3,PTE_HID
bne 5f
mfspr %r2,SPR_HASH2
ori %r3,%r3,PTE_HID
li %r1,8
addi %r2,%r2,-8
b 1b
4:
mfsrr1 %r3
andi. %r2,%r3,0xffff
oris %r2,%r2,DSISR_PROTECT@h
b 6f
5:
mfsrr1 %r3
andi. %r2,%r3,0xffff
oris %r2,%r2,DSISR_NOTFOUND@h
6:
mtctr %r0
mtsrr1 %r2
mfmsr %r0
xoris %r0,%r0,PSL_TGPR@h
mtcrf 0x80,%r3
mtmsr %r0
isync
#if defined(PPC_HIGH_VEC)
ba EXC_HIGHVEC+EXC_ISI
#else
ba EXC_ISI
#endif
_C_LABEL(tlbimsize) = .-_C_LABEL(tlbimiss)
.globl _C_LABEL(tlbdlmiss),_C_LABEL(tlbdlmsize)
_C_LABEL(tlbdlmiss):
mfspr %r2,SPR_HASH1
li %r1,8
mfctr %r0
mfspr %r3,SPR_DCMP
addi %r2,%r2,-8
1:
mtctr %r1
2:
ldregu %r1,8(%r2)
cmplw %r1,%r3
bdneq 2b
bne 3f
ldreg %r1,4(%r2)
mtctr %r0
mfspr %r0,SPR_DMISS
mfsrr1 %r3
mtcrf 0x80,%r3
ori %r1,%r1,PTE_REF
mtspr SPR_RPA,%r1
srwi %r1,%r1,8
tlbld %r0
stb %r1,6(%r2)
RFI
3:
andi. %r1,%r3,PTE_HID
bne 5f
mfspr %r2,SPR_HASH2
ori %r3,%r3,PTE_HID
li %r1,8
addi %r2,%r2,-8
b 1b
5:
mfsrr1 %r3
lis %r1,DSISR_NOTFOUND@h
mtctr %r0
andi. %r2,%r3,0xffff
mtsrr1 %r2
mtdsisr %r1
mfspr %r1,SPR_DMISS
mtdar %r1
mfmsr %r0
xoris %r0,%r0,PSL_TGPR@h
mtcrf 0x80,%r3
mtmsr %r0
isync
#if defined(PPC_HIGH_VEC)
ba EXC_HIGHVEC+EXC_DSI
#else
ba EXC_DSI
#endif
_C_LABEL(tlbdlmsize) = .-_C_LABEL(tlbdlmiss)
.globl _C_LABEL(tlbdsmiss),_C_LABEL(tlbdsmsize)
_C_LABEL(tlbdsmiss):
mfspr %r2,SPR_HASH1
li %r1,8
mfctr %r0
mfspr %r3,SPR_DCMP
addi %r2,%r2,-8
1:
mtctr %r1
2:
ldregu %r1,8(%r2)
cmplw %r1,%r3
bdneq 2b
bne 3f
ldreg %r1,4(%r2)
andi. %r3,%r1,PTE_CHG
beq 4f
5:
mtctr %r0
mfspr %r0,SPR_DMISS
mfsrr1 %r3
mtcrf 0x80,%r3
mtspr SPR_RPA,%r1
tlbld %r0
RFI
3:
andi. %r1,%r3,PTE_HID
bne 5f
mfspr %r2,SPR_HASH2
ori %r3,%r3,PTE_HID
li %r1,8
addi %r2,%r2,-8
b 1b
4:
rlwinm. %r3,%r1,30,0,1
bge- 7f
andi. %r3,%r1,1
beq+ 8f
9:
mfsrr1 %r3
lis %r1,(DSISR_PROTECT|DSISR_STORE)@h
b 1f
7:
mfspr %r3,SPR_DMISS
mfsrin %r1,%r3
mfsrr1 %r3
rlwinm %r3,%r3,18,31,31
rlwnm. %r1,%r1,%r3,1,1
bne- 9b
8:
ldreg %r1,4(%r2)
ori %r1,%r1,(PTE_REF|PTE_CHG)
sth %r1,6(%r2)
b 5b
5:
mfsrr1 %r3
lis %r1,(DSISR_NOTFOUND|DSISR_STORE)@h
1:
mtctr %r0
andi. %r2,%r3,0xffff
mtsrr1 %r2
mtdsisr %r1
mfspr %r1,SPR_DMISS
mtdar %r1
mfmsr %r0
xoris %r0,%r0,PSL_TGPR@h
mtcrf 0x80,%r3
mtmsr %r0
isync
#if defined(PPC_HIGH_VEC)
ba EXC_HIGHVEC+EXC_DSI
#else
ba EXC_DSI
#endif
_C_LABEL(tlbdsmsize) = .-_C_LABEL(tlbdsmiss)
#endif
#if defined(DDB) || defined(KGDB)
.local ddbstk
.comm ddbstk,INTSTK,8
.globl _C_LABEL(ddblow),_C_LABEL(ddbsize)
_C_LABEL(ddblow):
mtsprg1 %r1
ENABLE_64BIT_BRIDGE(%r1)
mtsprg2 %r29
mfcr %r29
mfsrr1 %r1
mtcr %r1
GET_CPUINFO(%r1)
bf MSR_PR,1f
streg %r28,(CI_TEMPSAVE+CPUSAVE_R28)(%r1)
mfsprg2 %r28
streg %r28,(CI_TEMPSAVE+CPUSAVE_R29)(%r1)
streg %r30,(CI_TEMPSAVE+CPUSAVE_R30)(%r1)
streg %r31,(CI_TEMPSAVE+CPUSAVE_R31)(%r1)
mflr %r28
#if defined(DISTANT_KERNEL)
lis %r31,u_trap@ha
addi %r31,%r31,u_trap@l
mtlr %r31
blrl
#else
bla u_trap
#endif
1:
streg %r28,(CI_DDBSAVE+CPUSAVE_R28)(%r1)
mfsprg2 %r28
streg %r28,(CI_DDBSAVE+CPUSAVE_R29)(%r1)
streg %r30,(CI_DDBSAVE+CPUSAVE_R30)(%r1)
streg %r31,(CI_DDBSAVE+CPUSAVE_R31)(%r1)
mflr %r28
lis %r1,ddbstk+INTSTK@ha
addi %r1,%r1,ddbstk+INTSTK@l
#if defined(DISTANT_KERNEL)
lis %r31,ddbtrap@ha
addi %r31,%r31,ddbtrap@l
mtlr %r31
blrl
#else
bla ddbtrap
#endif
_C_LABEL(ddbsize) = .-_C_LABEL(ddblow)
#endif
#define FRAME_SETUP(savearea) \
\
GET_CPUINFO(%r31); \
mfsrr0 %r30; \
streg %r30,(savearea+CPUSAVE_SRR0)(%r31); \
mfsrr1 %r30; \
streg %r30,(savearea+CPUSAVE_SRR1)(%r31); \
mfmsr %r30; \
ori %r30,%r30,(PSL_DR|PSL_IR); \
mtmsr %r30; \
isync; \
mfsprg1 %r31; \
stregu %r31,-FRAMELEN(%r1); \
streg %r0,FRAME_R0(%r1); \
streg %r31,FRAME_R1(%r1); \
streg %r2,FRAME_R2(%r1); \
streg %r28,FRAME_LR(%r1); \
stint %r29,FRAME_CR(%r1); \
GET_CPUINFO(%r2); \
ldreg %r31,(savearea+CPUSAVE_R31)(%r2); \
ldreg %r30,(savearea+CPUSAVE_R30)(%r2); \
ldreg %r29,(savearea+CPUSAVE_R29)(%r2); \
ldreg %r28,(savearea+CPUSAVE_R28)(%r2); \
streg %r3,FRAME_R3(%r1); \
streg %r4,FRAME_R4(%r1); \
streg %r5,FRAME_R5(%r1); \
streg %r6,FRAME_R6(%r1); \
streg %r7,FRAME_R7(%r1); \
streg %r8,FRAME_R8(%r1); \
streg %r9,FRAME_R9(%r1); \
streg %r10,FRAME_R10(%r1); \
streg %r11,FRAME_R11(%r1); \
streg %r12,FRAME_R12(%r1); \
streg %r13,FRAME_R13(%r1); \
streg %r14,FRAME_R14(%r1); \
streg %r15,FRAME_R15(%r1); \
streg %r16,FRAME_R16(%r1); \
streg %r17,FRAME_R17(%r1); \
streg %r18,FRAME_R18(%r1); \
streg %r19,FRAME_R19(%r1); \
streg %r20,FRAME_R20(%r1); \
streg %r21,FRAME_R21(%r1); \
streg %r22,FRAME_R22(%r1); \
streg %r23,FRAME_R23(%r1); \
streg %r24,FRAME_R24(%r1); \
streg %r25,FRAME_R25(%r1); \
streg %r26,FRAME_R26(%r1); \
streg %r27,FRAME_R27(%r1); \
streg %r28,FRAME_R28(%r1); \
streg %r29,FRAME_R29(%r1); \
streg %r30,FRAME_R30(%r1); \
streg %r31,FRAME_R31(%r1); \
ldreg %r28,(savearea+CPUSAVE_DAR)(%r2); \
ldreg %r29,(savearea+CPUSAVE_DSISR)(%r2); \
ldreg %r30,(savearea+CPUSAVE_SRR0)(%r2); \
ldreg %r31,(savearea+CPUSAVE_SRR1)(%r2); \
ldptr %r13,CI_CURLWP(%r2); \
mfxer %r3; \
mfctr %r4; \
mflr %r5; \
andi. %r5,%r5,0xff00; \
stint %r3,FRAME_XER(%r1); \
streg %r4,FRAME_CTR(%r1); \
streg %r30,FRAME_SRR0(%r1); \
streg %r31,FRAME_SRR1(%r1); \
streg %r28,FRAME_DAR(%r1); \
stint %r29,FRAME_DSISR(%r1); \
stint %r5,FRAME_EXC(%r1); \
SAVE_VRSAVE(%r1,%r6); \
SAVE_MQ(%r1,%r7)
#define FRAME_RESTORE_CALLEE \
ldreg %r31,FRAME_R31(%r1); \
ldreg %r30,FRAME_R30(%r1); \
ldreg %r29,FRAME_R29(%r1); \
ldreg %r28,FRAME_R28(%r1); \
ldreg %r27,FRAME_R27(%r1); \
ldreg %r26,FRAME_R26(%r1); \
ldreg %r25,FRAME_R25(%r1); \
ldreg %r24,FRAME_R24(%r1); \
ldreg %r23,FRAME_R23(%r1); \
ldreg %r22,FRAME_R22(%r1); \
ldreg %r21,FRAME_R21(%r1); \
ldreg %r20,FRAME_R20(%r1); \
ldreg %r19,FRAME_R19(%r1); \
ldreg %r18,FRAME_R18(%r1); \
ldreg %r17,FRAME_R17(%r1); \
ldreg %r16,FRAME_R16(%r1); \
ldreg %r15,FRAME_R15(%r1); \
ldreg %r14,FRAME_R14(%r1);
#define FRAME_LEAVE(savearea) \
\
ldreg %r2,FRAME_SRR0(%r1); \
ldreg %r3,FRAME_SRR1(%r1); \
ldreg %r4,FRAME_CTR(%r1); \
ldint %r5,FRAME_XER(%r1); \
ldreg %r6,FRAME_LR(%r1); \
RESTORE_MQ(%r1,%r8); \
RESTORE_VRSAVE(%r1,%r9); \
GET_CPUINFO(%r7); \
streg %r2,(savearea+CPUSAVE_SRR0)(%r7); \
streg %r3,(savearea+CPUSAVE_SRR1)(%r7); \
ldint %r7,FRAME_CR(%r1); \
mtctr %r4; \
mtxer %r5; \
mtlr %r6; \
mtsprg1 %r7; \
ldreg %r13,FRAME_R13(%r1); \
ldreg %r12,FRAME_R12(%r1); \
ldreg %r11,FRAME_R11(%r1); \
ldreg %r10,FRAME_R10(%r1); \
ldreg %r9,FRAME_R9(%r1); \
ldreg %r8,FRAME_R8(%r1); \
ldreg %r7,FRAME_R7(%r1); \
ldreg %r6,FRAME_R6(%r1); \
ldreg %r5,FRAME_R5(%r1); \
ldreg %r4,FRAME_R4(%r1); \
ldreg %r3,FRAME_R3(%r1); \
ldreg %r2,FRAME_R2(%r1); \
ldreg %r0,FRAME_R0(%r1); \
ldreg %r1,FRAME_R1(%r1); \
\
mtsprg2 %r2; \
mtsprg3 %r3; \
\
mfmsr %r2; \
andi. %r2,%r2,~(PSL_DR|PSL_IR|PSL_ME|PSL_RI)@l; \
mtmsr %r2; \
isync; \
\
GET_CPUINFO(%r2); \
ldreg %r3,(savearea+CPUSAVE_SRR1)(%r2); \
mtcr %r3; \
bf MSR_PR,1f; \
\
RESTORE_USER_SRS(%r2,%r3); \
1: mfsprg1 %r2; \
mtcr %r2; \
GET_CPUINFO(%r2); \
ldreg %r3,(savearea+CPUSAVE_SRR0)(%r2); \
mtsrr0 %r3; \
ldreg %r3,(savearea+CPUSAVE_SRR1)(%r2); \
mtsrr1 %r3; \
mfsprg2 %r2; \
mfsprg3 %r3
disitrap:
GET_CPUINFO(%r1)
ldreg %r30,(CI_DISISAVE+CPUSAVE_R28)(%r1)
streg %r30,(CI_TEMPSAVE+CPUSAVE_R28)(%r1)
ldreg %r31,(CI_DISISAVE+CPUSAVE_R29)(%r1)
streg %r31,(CI_TEMPSAVE+CPUSAVE_R29)(%r1)
ldreg %r30,(CI_DISISAVE+CPUSAVE_R30)(%r1)
streg %r30,(CI_TEMPSAVE+CPUSAVE_R30)(%r1)
ldreg %r31,(CI_DISISAVE+CPUSAVE_R31)(%r1)
streg %r31,(CI_TEMPSAVE+CPUSAVE_R31)(%r1)
mfdar %r30
mfdsisr %r31
streg %r30,(CI_TEMPSAVE+CPUSAVE_DAR)(%r1)
streg %r31,(CI_TEMPSAVE+CPUSAVE_DSISR)(%r1)
#ifdef DDB
mfsrr1 %r31
mtcr %r31
bt MSR_PR,trapstart
mfsprg1 %r31
#if 0
subf %r30,%r30,%r31
addi %r30,%r30,2048
cmplwi %cr0,%r30,4096
#else
xor. %r30,%r30,%r31
cmplwi %cr0,%r30,4096
#endif
bge %cr0,trapstart
GET_CPUINFO(%r1)
ldreg %r30,(CI_DISISAVE+CPUSAVE_R28)(%r1)
streg %r30,(CI_DDBSAVE +CPUSAVE_R28)(%r1)
ldreg %r31,(CI_DISISAVE+CPUSAVE_R29)(%r1)
streg %r31,(CI_DDBSAVE +CPUSAVE_R29)(%r1)
ldreg %r30,(CI_DISISAVE+CPUSAVE_R30)(%r1)
streg %r30,(CI_DDBSAVE +CPUSAVE_R30)(%r1)
ldreg %r31,(CI_DISISAVE+CPUSAVE_R31)(%r1)
streg %r31,(CI_DDBSAVE +CPUSAVE_R31)(%r1)
lis %r1,ddbstk+INTSTK@ha
addi %r1,%r1,ddbstk+INTSTK@l
b ddbtrap
#endif
.globl _C_LABEL(trapstart)
.type _C_LABEL(trapstart),@function
_C_LABEL(trapstart):
realtrap:
mfsrr1 %r1
mtcr %r1
mfsprg1 %r1
s_trap:
bf MSR_PR,k_trap
GET_CPUINFO(%r1)
u_trap:
ldptr %r1,CI_CURPCB(%r1)
addi %r1,%r1,USPACE-CALLFRAMELEN
RESTORE_KERN_SRS(%r30,%r31)
k_trap:
FRAME_SETUP(CI_TEMPSAVE)
trapagain:
mfmsr %r7
ldreg %r6, FRAME_SRR1(%r1)
andi. %r6,%r6,(PSL_EE|PSL_ME|PSL_RI)@l
or %r7,%r7,%r6
mtmsr %r7
isync
addi %r3,%r1,FRAME_TF
bl _C_LABEL(trap)
.globl trapexit
trapexit:
mfmsr %r3
andi. %r3,%r3,~PSL_EE@l
mtmsr %r3
mtcr %r31
bf MSR_PR,trapleave
ldint %r4,L_MD_ASTPENDING(%r13)
andi. %r4,%r4,1
beq trapleave
li %r6,EXC_AST
stint %r6,FRAME_EXC(%r1)
b trapagain
trapleave:
FRAME_RESTORE_CALLEE
intrleave:
CLEAR_RESERVATION
FRAME_LEAVE(CI_TEMPSAVE)
RFI
.globl _C_LABEL(sctrap),_C_LABEL(scsize),_C_LABEL(sctrapexit)
_C_LABEL(sctrap):
mtsprg1 %r1
ENABLE_64BIT_BRIDGE(%r1)
GET_CPUINFO(%r1)
streg %r28,(CI_TEMPSAVE+CPUSAVE_R28)(%r1)
streg %r29,(CI_TEMPSAVE+CPUSAVE_R29)(%r1)
streg %r30,(CI_TEMPSAVE+CPUSAVE_R30)(%r1)
streg %r31,(CI_TEMPSAVE+CPUSAVE_R31)(%r1)
mflr %r28
mfcr %r29
#if defined(DISTANT_KERNEL)
lis %r31,s_sctrap@ha
addi %r31,%r31,s_sctrap@l
mtlr %r31
blrl
#else
bla s_sctrap
#endif
_C_LABEL(scsize) = .-_C_LABEL(sctrap)
s_sctrap:
GET_CPUINFO(%r1)
ldptr %r1,CI_CURPCB(%r1)
addi %r1,%r1,USPACE-CALLFRAMELEN
RESTORE_KERN_SRS(%r30,%r31)
FRAME_SETUP(CI_TEMPSAVE)
mfmsr %r7
ori %r7,%r7,(PSL_EE|PSL_ME|PSL_RI)@l
mtmsr %r7
isync
addi %r3,%r1,FRAME_TF
ldptr %r4,L_PROC(%r13)
ldptr %r4,P_MD_SYSCALL(%r4)
mtctr %r4
bctrl
_C_LABEL(sctrapexit):
b trapexit
#define INTR_SETUP(savearea,exc) \
\
GET_CPUINFO(%r31); \
mfsrr0 %r30; \
streg %r30,(savearea+CPUSAVE_SRR0)(%r31); \
mfsrr1 %r30; \
streg %r30,(savearea+CPUSAVE_SRR1)(%r31); \
mfmsr %r30; \
ori %r30,%r30,(PSL_DR|PSL_IR); \
mtmsr %r30; \
isync; \
mfsprg1 %r31; \
stregu %r31,-FRAMELEN(%r1); \
streg %r0,FRAME_R0(%r1); \
streg %r31,FRAME_R1(%r1); \
streg %r2,FRAME_R2(%r1); \
streg %r28,FRAME_LR(%r1); \
stint %r29,FRAME_CR(%r1); \
GET_CPUINFO(%r2); \
ldreg %r31,(savearea+CPUSAVE_R31)(%r2); \
ldreg %r30,(savearea+CPUSAVE_R30)(%r2); \
ldreg %r29,(savearea+CPUSAVE_R29)(%r2); \
ldreg %r28,(savearea+CPUSAVE_R28)(%r2); \
streg %r3,FRAME_R3(%r1); \
streg %r4,FRAME_R4(%r1); \
streg %r5,FRAME_R5(%r1); \
streg %r6,FRAME_R6(%r1); \
streg %r7,FRAME_R7(%r1); \
streg %r8,FRAME_R8(%r1); \
streg %r9,FRAME_R9(%r1); \
streg %r10,FRAME_R10(%r1); \
streg %r11,FRAME_R11(%r1); \
streg %r12,FRAME_R12(%r1); \
streg %r13,FRAME_R13(%r1); \
ldreg %r11,(savearea+CPUSAVE_SRR0)(%r2); \
ldreg %r12,(savearea+CPUSAVE_SRR1)(%r2); \
ldptr %r13,CI_CURLWP(%r2); \
ldint %r3,CI_IDEPTH(%r2); \
stint %r3,FRAME_IDEPTH(%r1); \
mfxer %r3; \
mfctr %r4; \
li %r5,exc; \
stint %r5,FRAME_EXC(%r1); \
stint %r3,FRAME_XER(%r1); \
streg %r4,FRAME_CTR(%r1); \
streg %r11,FRAME_SRR0(%r1); \
streg %r12,FRAME_SRR1(%r1); \
mfmsr %r6; \
ori %r6,%r6,PSL_RI; \
mtmsr %r6; \
SAVE_VRSAVE(%r1,%r6); \
SAVE_MQ(%r1,%r7)
.globl _C_LABEL(extint_call)
extintr:
INTR_SETUP(CI_TEMPSAVE, EXC_EXI)
addi %r3,%r1,FRAME_TF
_C_LABEL(extint_call):
bl _C_LABEL(extint_call)
intr_exit:
mfmsr %r3
andi. %r3,%r3,~(PSL_EE|PSL_ME|PSL_RI)@l
mtmsr %r3
isync
ldreg %r4,FRAME_SRR1(%r1)
mtcr %r4
bf MSR_PR,intrleave
ldint %r3,L_MD_ASTPENDING(%r13)
andi. %r3,%r3,1
beq intrleave
streg %r14,FRAME_R14(%r1)
streg %r15,FRAME_R15(%r1)
streg %r16,FRAME_R16(%r1)
streg %r17,FRAME_R17(%r1)
streg %r18,FRAME_R18(%r1)
streg %r19,FRAME_R19(%r1)
streg %r20,FRAME_R20(%r1)
streg %r21,FRAME_R21(%r1)
streg %r22,FRAME_R22(%r1)
streg %r23,FRAME_R23(%r1)
streg %r24,FRAME_R24(%r1)
streg %r25,FRAME_R25(%r1)
streg %r26,FRAME_R26(%r1)
streg %r27,FRAME_R27(%r1)
streg %r28,FRAME_R28(%r1)
streg %r29,FRAME_R29(%r1)
streg %r30,FRAME_R30(%r1)
streg %r31,FRAME_R31(%r1)
li %r6,EXC_AST
stint %r6,FRAME_EXC(%r1)
mr %r31, %r4
b trapagain
decrintr:
INTR_SETUP(CI_TEMPSAVE, EXC_DECR)
addi %r3,%r1,FRAME_CF
bl _C_LABEL(decr_intr)
b intr_exit
#ifdef DDB
.globl _C_LABEL(ddb_trap)
_C_LABEL(ddb_trap):
mtsprg1 %r1
mfmsr %r3
mtsrr1 %r3
andi. %r3,%r3,~(PSL_EE|PSL_ME)@l
mtmsr %r3
isync
ENABLE_64BIT_BRIDGE(%r3)
GET_CPUINFO(%r3)
streg %r28,(CI_DDBSAVE+CPUSAVE_R28)(%r3)
streg %r29,(CI_DDBSAVE+CPUSAVE_R29)(%r3)
streg %r30,(CI_DDBSAVE+CPUSAVE_R30)(%r3)
streg %r31,(CI_DDBSAVE+CPUSAVE_R31)(%r3)
mflr %r28
li %r29,EXC_BPT
mtlr %r29
mfcr %r29
mtsrr0 %r28
#endif
#if defined(DDB) || defined(KGDB)
ddbtrap:
FRAME_SETUP(CI_DDBSAVE)
addi %r3,%r1,FRAME_TF
bl _C_LABEL(ddb_trap_glue)
or. %r3,%r3,%r3
beq trapagain
FRAME_RESTORE_CALLEE
CLEAR_RESERVATION
FRAME_LEAVE(CI_DDBSAVE)
RFI
#endif
.globl _C_LABEL(trapend)
_C_LABEL(trapend):
#if !defined(PPC_MPC8XX)
#include <powerpc/powerpc/fpu_subr.S>
#include <powerpc/oea/altivec_subr.S>
#endif