#include "assym.h"
#include <machine/param.h>
#include <machine/psl.h>
#include <machine/trap.h>
#define SPR_VRSAVE 256
.abiversion 2
#define GET_CPUINFO(r) \
mfsprg0 r
#define GET_TOCBASE(r) \
bl 99f; \
99: mflr r; \
addis r, r, (.TOC. - 99b)@ha; \
addi r, r, (.TOC. - 99b)@l;
restore_usersrs:
GET_CPUINFO(%r28)
ld %r28, CI_USER_SLB_PA(%r28)
li %r29, 0
slbia
slbmfee %r31, %r29
clrrdi %r31, %r31, 28
slbie %r31
1: ld %r31, 0(%r28)
cmpdi %r31, 0
beqlr
ld %r30, 8(%r28)
slbmte %r30, %r31
addi %r28, %r28, 16
addi %r29, %r29, 1
cmpdi %r29, 32
blt 1b
blr
restore_kernsrs:
GET_CPUINFO(%r28)
addi %r28, %r28, CI_KERNEL_SLB
li %r29, 0
slbia
slbmfee %r31, %r29
clrrdi %r31, %r31, 28
slbie %r31
1: ld %r31, 0(%r28)
cmpdi %r31, 0
beqlr
ld %r30, 8(%r28)
slbmte %r30, %r31
addi %r28, %r28, 16
addi %r29, %r29, 1
cmpdi %r29, 31
blt 1b
blr
#define FRAME_SETUP(savearea) \
\
GET_CPUINFO(%r31); \
mfsrr0 %r30; \
std %r30, (savearea+CPUSAVE_SRR0)(%r31); \
mfsrr1 %r30; \
std %r30, (savearea+CPUSAVE_SRR1)(%r31); \
mfsprg1 %r31; \
mfmsr %r30; \
ori %r30, %r30, (PSL_DR|PSL_IR|PSL_RI)@l; \
mtmsr %r30; \
isync; \
stdu %r31, -(FRAMELEN+288)(%r1); \
std %r0, FRAME_0+32(%r1); \
std %r31, FRAME_1+32(%r1); \
std %r2, FRAME_2+32(%r1); \
std %r28, FRAME_LR+32(%r1); \
std %r29, FRAME_CR+32(%r1); \
GET_CPUINFO(%r2); \
ld %r27, (savearea+CPUSAVE_R27)(%r2); \
ld %r28, (savearea+CPUSAVE_R28)(%r2); \
ld %r29, (savearea+CPUSAVE_R29)(%r2); \
ld %r30, (savearea+CPUSAVE_R30)(%r2); \
ld %r31, (savearea+CPUSAVE_R31)(%r2); \
std %r3, FRAME_3+32(%r1); \
std %r4, FRAME_4+32(%r1); \
std %r5, FRAME_5+32(%r1); \
std %r6, FRAME_6+32(%r1); \
std %r7, FRAME_7+32(%r1); \
std %r8, FRAME_8+32(%r1); \
std %r9, FRAME_9+32(%r1); \
std %r10, FRAME_10+32(%r1); \
std %r11, FRAME_11+32(%r1); \
std %r12, FRAME_12+32(%r1); \
std %r13, FRAME_13+32(%r1); \
std %r14, FRAME_14+32(%r1); \
std %r15, FRAME_15+32(%r1); \
std %r16, FRAME_16+32(%r1); \
std %r17, FRAME_17+32(%r1); \
std %r18, FRAME_18+32(%r1); \
std %r19, FRAME_19+32(%r1); \
std %r20, FRAME_20+32(%r1); \
std %r21, FRAME_21+32(%r1); \
std %r22, FRAME_22+32(%r1); \
std %r23, FRAME_23+32(%r1); \
std %r24, FRAME_24+32(%r1); \
std %r25, FRAME_25+32(%r1); \
std %r26, FRAME_26+32(%r1); \
std %r27, FRAME_27+32(%r1); \
std %r28, FRAME_28+32(%r1); \
std %r29, FRAME_29+32(%r1); \
std %r30, FRAME_30+32(%r1); \
std %r31, FRAME_31+32(%r1); \
ld %r28, (savearea+CPUSAVE_DAR)(%r2); \
ld %r29, (savearea+CPUSAVE_DSISR)(%r2); \
ld %r30, (savearea+CPUSAVE_SRR0)(%r2); \
ld %r31, (savearea+CPUSAVE_SRR1)(%r2); \
mfxer %r3; \
mfctr %r4; \
mfsprg3 %r5; \
mfspr %r6, SPR_VRSAVE; \
std %r3, FRAME_XER+32(%r1); \
std %r4, FRAME_CTR+32(%r1); \
std %r5, FRAME_EXC+32(%r1); \
std %r6, FRAME_VRSAVE+32(%r1); \
std %r28, FRAME_DAR+32(%r1); \
std %r29, FRAME_DSISR+32(%r1); \
std %r30, FRAME_SRR0+32(%r1); \
std %r31, FRAME_SRR1+32(%r1);
#define FRAME_LEAVE(savearea) \
\
mfmsr %r2; \
andi. %r2,%r2,~PSL_EE@l; \
mtmsr %r2; \
isync; \
\
ld %r2, FRAME_SRR0+32(%r1); \
ld %r3, FRAME_SRR1+32(%r1); \
ld %r4, FRAME_CTR+32(%r1); \
ld %r5, FRAME_XER+32(%r1); \
ld %r6, FRAME_LR+32(%r1); \
GET_CPUINFO(%r7); \
std %r2, (savearea+CPUSAVE_SRR0)(%r7); \
std %r3, (savearea+CPUSAVE_SRR1)(%r7); \
ld %r7, FRAME_CR+32(%r1); \
ld %r8, FRAME_VRSAVE+32(%r1); \
mtctr %r4; \
mtxer %r5; \
mtlr %r6; \
mtsprg2 %r7; \
mtspr SPR_VRSAVE, %r8; \
ld %r31, FRAME_31+32(%r1); \
ld %r30, FRAME_30+32(%r1); \
ld %r29, FRAME_29+32(%r1); \
ld %r28, FRAME_28+32(%r1); \
ld %r27, FRAME_27+32(%r1); \
ld %r26, FRAME_26+32(%r1); \
ld %r25, FRAME_25+32(%r1); \
ld %r24, FRAME_24+32(%r1); \
ld %r23, FRAME_23+32(%r1); \
ld %r22, FRAME_22+32(%r1); \
ld %r21, FRAME_21+32(%r1); \
ld %r20, FRAME_20+32(%r1); \
ld %r19, FRAME_19+32(%r1); \
ld %r18, FRAME_18+32(%r1); \
ld %r17, FRAME_17+32(%r1); \
ld %r16, FRAME_16+32(%r1); \
ld %r15, FRAME_15+32(%r1); \
ld %r14, FRAME_14+32(%r1); \
ld %r13, FRAME_13+32(%r1); \
ld %r12, FRAME_12+32(%r1); \
ld %r11, FRAME_11+32(%r1); \
ld %r10, FRAME_10+32(%r1); \
ld %r9, FRAME_9+32(%r1); \
ld %r8, FRAME_8+32(%r1); \
ld %r7, FRAME_7+32(%r1); \
ld %r6, FRAME_6+32(%r1); \
ld %r5, FRAME_5+32(%r1); \
ld %r4, FRAME_4+32(%r1); \
ld %r3, FRAME_3+32(%r1); \
ld %r2, FRAME_2+32(%r1); \
ld %r0, FRAME_0+32(%r1); \
ld %r1, FRAME_1+32(%r1); \
\
mtsprg3 %r3; \
\
mfmsr %r3; \
andi. %r3, %r3, ~(PSL_DR|PSL_IR|PSL_ME|PSL_RI)@l; \
mtmsr %r3; \
isync; \
\
GET_CPUINFO(%r3); \
ld %r3, (savearea+CPUSAVE_SRR1)(%r3); \
mtcr %r3; \
bf 17, 1f; \
\
GET_CPUINFO(%r3); \
std %r27, (savearea+CPUSAVE_R27)(%r3); \
std %r28, (savearea+CPUSAVE_R28)(%r3); \
std %r29, (savearea+CPUSAVE_R29)(%r3); \
std %r30, (savearea+CPUSAVE_R30)(%r3); \
std %r31, (savearea+CPUSAVE_R31)(%r3); \
mflr %r27; \
bl restore_usersrs; \
mtlr %r27; \
ld %r31, (savearea+CPUSAVE_R31)(%r3); \
ld %r30, (savearea+CPUSAVE_R30)(%r3); \
ld %r29, (savearea+CPUSAVE_R29)(%r3); \
ld %r28, (savearea+CPUSAVE_R28)(%r3); \
ld %r27, (savearea+CPUSAVE_R27)(%r3); \
1: mfsprg2 %r3; \
mtcr %r3; \
GET_CPUINFO(%r3); \
ld %r3, (savearea+CPUSAVE_SRR0)(%r3); \
mtsrr0 %r3; \
GET_CPUINFO(%r3); \
ld %r3, (savearea+CPUSAVE_SRR1)(%r3); \
mtsrr1 %r3; \
mfsprg3 %r3
.text
.globl trapcode, trapcodeend
trapcode:
mtsprg1 %r1
mflr %r1
mtsprg2 %r1
ld %r1, TRAP_ENTRY(0)
mtlr %r1
li %r1, 0xe0
blrl
trapcodeend:
.globl hvtrapcode, hvtrapcodeend
hvtrapcode:
mtsprg1 %r1
mflr %r1
mtsprg2 %r1
ld %r1, TRAP_HVENTRY(0)
mtlr %r1
li %r1, 0xe0
blrl
hvtrapcodeend:
.globl rsttrapcode, rsttrapcodeend
rsttrapcode:
mtsprg1 %r1
mfcr %r1
mtsprg2 %r1
mfsrr1 %r1
andis. %r1, %r1, 0x3
beq 1f
ld %r1, TRAP_RSTENTRY(0)
mtctr %r1
bctr
1:
mfsprg2 %r1
mtcr %r1
mflr %r1
mtsprg2 %r1
ld %r1, TRAP_ENTRY(0)
mtlr %r1
li %r1, 0xe0
blrl
rsttrapcodeend:
.globl slbtrapcode, slbtrapcodeend
slbtrapcode:
mtsprg1 %r1
GET_CPUINFO(%r1)
std %r2, (CI_SLBSAVE+16)(%r1)
mfcr %r2
std %r2, (CI_SLBSAVE+104)(%r1)
mfsrr1 %r2
mtcr %r2
bf 17, 1f
ld %r2, (CI_SLBSAVE+104)(%r1)
mtcr %r2
ld %r2, (CI_SLBSAVE+16)(%r1)
mflr %r1
mtsprg2 %r1
ld %r1, TRAP_ENTRY(0)
mtlr %r1
li %r1, 0x80
blrl
1: mflr %r2
ld %r1, TRAP_SLBENTRY(0)
mtlr %r1
GET_CPUINFO(%r1)
blrl
slbtrapcodeend:
.globl kern_slbtrap
kern_slbtrap:
std %r2, (CI_SLBSAVE+136)(%r1)
std %r3, (CI_SLBSAVE+24)(%r1)
mfdar %r2
lis %r3, SEGMENT_MASK@h
ori %r3, %r3, SEGMENT_MASK@l
andc %r2, %r2, %r3
lis %r3, USER_ADDR@highesta
ori %r3, %r3, USER_ADDR@highera
sldi %r3, %r3, 32
oris %r3, %r3, USER_ADDR@ha
ori %r3, %r3, USER_ADDR@l
cmpd %r2, %r3
bne 1f
ld %r2, (CI_SLBSAVE+104)(%r1)
mtcr %r2
ld %r2, (CI_SLBSAVE+16)(%r1)
ld %r3, (CI_SLBSAVE+24)(%r1)
ld %r1, (CI_SLBSAVE+136)(%r1)
mtsprg2 %r1
li %r1, 0x80
b generictrap
1:
std %r0, (CI_SLBSAVE+0)(%r1)
mfsprg1 %r2
std %r2, (CI_SLBSAVE+8)(%r1)
std %r4, (CI_SLBSAVE+32)(%r1)
std %r5, (CI_SLBSAVE+40)(%r1)
std %r6, (CI_SLBSAVE+48)(%r1)
std %r7, (CI_SLBSAVE+56)(%r1)
std %r8, (CI_SLBSAVE+64)(%r1)
std %r9, (CI_SLBSAVE+72)(%r1)
std %r10, (CI_SLBSAVE+80)(%r1)
std %r11, (CI_SLBSAVE+88)(%r1)
std %r12, (CI_SLBSAVE+96)(%r1)
mfxer %r2
std %r2, (CI_SLBSAVE+112)(%r1)
mflr %r2
std %r2, (CI_SLBSAVE+120)(%r1)
mfctr %r2
std %r2, (CI_SLBSAVE+128)(%r1)
addi %r1, %r1, CI_SLBSTACK-48+1024
li %r2, ~15
and %r1, %r1, %r2
GET_TOCBASE(%r2)
mfdar %r3
bl pmap_spill_kernel_slb
nop
GET_CPUINFO(%r1)
ld %r4, (CI_SLBSAVE+32)(%r1)
ld %r5, (CI_SLBSAVE+40)(%r1)
ld %r6, (CI_SLBSAVE+48)(%r1)
ld %r7, (CI_SLBSAVE+56)(%r1)
ld %r8, (CI_SLBSAVE+64)(%r1)
ld %r9, (CI_SLBSAVE+72)(%r1)
ld %r10, (CI_SLBSAVE+80)(%r1)
ld %r11, (CI_SLBSAVE+88)(%r1)
ld %r12, (CI_SLBSAVE+96)(%r1)
std %r28, (CI_SLBSAVE+64)(%r1)
std %r29, (CI_SLBSAVE+72)(%r1)
std %r30, (CI_SLBSAVE+80)(%r1)
std %r31, (CI_SLBSAVE+88)(%r1)
bl restore_kernsrs
ld %r28, (CI_SLBSAVE+64)(%r1)
ld %r29, (CI_SLBSAVE+72)(%r1)
ld %r30, (CI_SLBSAVE+80)(%r1)
ld %r31, (CI_SLBSAVE+88)(%r1)
ld %r2, (CI_SLBSAVE+104)(%r1)
mtcr %r2
ld %r2, (CI_SLBSAVE+112)(%r1)
mtxer %r2
ld %r2, (CI_SLBSAVE+120)(%r1)
mtlr %r2
ld %r2, (CI_SLBSAVE+128)(%r1)
mtctr %r2
ld %r2, (CI_SLBSAVE+136)(%r1)
mtlr %r2
ld %r0, (CI_SLBSAVE+0)(%r1)
ld %r2, (CI_SLBSAVE+16)(%r1)
ld %r3, (CI_SLBSAVE+24)(%r1)
mfsprg1 %r1
rfid
.globl generichvtrap
generichvtrap:
mtsprg3 %r1
mfspr %r1, 314
mtsrr0 %r1
mfspr %r1, 315
mtsrr1 %r1
mfsprg3 %r1
.globl generictrap
.type generictrap, @function
generictrap:
mtsprg3 %r1
GET_CPUINFO(%r1)
std %r27, (CI_TEMPSAVE+CPUSAVE_R27)(%r1)
std %r28, (CI_TEMPSAVE+CPUSAVE_R28)(%r1)
std %r29, (CI_TEMPSAVE+CPUSAVE_R29)(%r1)
std %r30, (CI_TEMPSAVE+CPUSAVE_R30)(%r1)
std %r31, (CI_TEMPSAVE+CPUSAVE_R31)(%r1)
mfdar %r30
std %r30, (CI_TEMPSAVE+CPUSAVE_DAR)(%r1)
mfdsisr %r30
std %r30, (CI_TEMPSAVE+CPUSAVE_DSISR)(%r1)
mfsprg1 %r1
mfsprg2 %r28
mfcr %r29
mfsprg3 %r31
ori %r31, %r31, 0xff00
mflr %r30
addi %r30, %r30, -4
and %r30, %r30, %r31
mtsprg3 %r30
mfsrr1 %r31
mtcr %r31
bf 17, k_trap
u_trap:
GET_CPUINFO(%r1)
ld %r1, CI_CURPCB(%r1)
addi %r1, %r1, USPACE
mr %r27, %r28
mtsprg2 %r29
bl restore_kernsrs
mfsprg2 %r29
mr %r28, %r27
k_trap:
FRAME_SETUP(CI_TEMPSAVE)
GET_TOCBASE(%r2)
trapagain:
addi %r3, %r1, 32
bl trap
.globl trapexit
trapexit:
mfmsr %r3
andi. %r3, %r3, ~PSL_EE@l
mtmsr %r3
isync
ld %r5, FRAME_SRR1+32(%r1)
mtcr %r5
bf 17, 1f
GET_CPUINFO(%r3)
ld %r4, CI_CURPROC(%r3)
lwz %r4, P_MD_ASTPENDING(%r4)
cmpwi %r4, 0
beq 1f
li %r6, EXC_AST
std %r6, FRAME_EXC+32(%r1)
b trapagain
1:
FRAME_LEAVE(CI_TEMPSAVE)
rfid