#define GET_CPUINFO(r) mfsprg0 r
#define RES_GRANULE 64
#define RES_LOCK 0
#ifdef __powerpc64__
#define RES_RECURSE 8
#else
#define RES_RECURSE 4
#endif
#define STANDARD_PROLOG(sprg_sp, savearea, isrr0, isrr1) \
mtspr sprg_sp, %r1; \
GET_CPUINFO(%r1); \
STORE %r30, (savearea+CPUSAVE_R30)(%r1); \
STORE %r31, (savearea+CPUSAVE_R31)(%r1); \
mfspr %r30, SPR_DEAR; \
mfspr %r31, SPR_ESR; \
STORE %r30, (savearea+CPUSAVE_BOOKE_DEAR)(%r1); \
STORE %r31, (savearea+CPUSAVE_BOOKE_ESR)(%r1); \
mfspr %r30, isrr0; \
mfspr %r31, isrr1; \
STORE %r30, (savearea+CPUSAVE_SRR0)(%r1); \
STORE %r31, (savearea+CPUSAVE_SRR1)(%r1); \
isync; \
mfspr %r1, sprg_sp; \
mfcr %r30; \
\
mtcr %r31; \
bf 17, 1f; \
GET_CPUINFO(%r1); \
LOAD %r1, PC_CURPCB(%r1); \
1:
#define STANDARD_CRIT_PROLOG(sprg_sp, savearea, isrr0, isrr1) \
mtspr sprg_sp, %r1; \
GET_CPUINFO(%r1); \
STORE %r30, (savearea+CPUSAVE_R30)(%r1); \
STORE %r31, (savearea+CPUSAVE_R31)(%r1); \
mfspr %r30, SPR_DEAR; \
mfspr %r31, SPR_ESR; \
STORE %r30, (savearea+CPUSAVE_BOOKE_DEAR)(%r1); \
STORE %r31, (savearea+CPUSAVE_BOOKE_ESR)(%r1); \
mfspr %r30, isrr0; \
mfspr %r31, isrr1; \
STORE %r30, (savearea+CPUSAVE_SRR0)(%r1); \
STORE %r31, (savearea+CPUSAVE_SRR1)(%r1); \
mfspr %r30, SPR_SRR0; \
mfspr %r31, SPR_SRR1; \
STORE %r30, (savearea+BOOKE_CRITSAVE_SRR0)(%r1); \
STORE %r31, (savearea+BOOKE_CRITSAVE_SRR1)(%r1); \
isync; \
mfspr %r1, sprg_sp; \
mfcr %r30; \
\
mtcr %r31; \
bf 17, 1f; \
GET_CPUINFO(%r1); \
LOAD %r1, PC_CURPCB(%r1); \
1:
#ifdef __powerpc64__
#define SAVE_REGS(r) \
std %r3, FRAME_3+CALLSIZE(r); \
std %r4, FRAME_4+CALLSIZE(r); \
std %r5, FRAME_5+CALLSIZE(r); \
std %r6, FRAME_6+CALLSIZE(r); \
std %r7, FRAME_7+CALLSIZE(r); \
std %r8, FRAME_8+CALLSIZE(r); \
std %r9, FRAME_9+CALLSIZE(r); \
std %r10, FRAME_10+CALLSIZE(r); \
std %r11, FRAME_11+CALLSIZE(r); \
std %r12, FRAME_12+CALLSIZE(r); \
std %r13, FRAME_13+CALLSIZE(r); \
std %r14, FRAME_14+CALLSIZE(r); \
std %r15, FRAME_15+CALLSIZE(r); \
std %r16, FRAME_16+CALLSIZE(r); \
std %r17, FRAME_17+CALLSIZE(r); \
std %r18, FRAME_18+CALLSIZE(r); \
std %r19, FRAME_19+CALLSIZE(r); \
std %r20, FRAME_20+CALLSIZE(r); \
std %r21, FRAME_21+CALLSIZE(r); \
std %r22, FRAME_22+CALLSIZE(r); \
std %r23, FRAME_23+CALLSIZE(r); \
std %r24, FRAME_24+CALLSIZE(r); \
std %r25, FRAME_25+CALLSIZE(r); \
std %r26, FRAME_26+CALLSIZE(r); \
std %r27, FRAME_27+CALLSIZE(r); \
std %r28, FRAME_28+CALLSIZE(r); \
std %r29, FRAME_29+CALLSIZE(r); \
std %r30, FRAME_30+CALLSIZE(r); \
std %r31, FRAME_31+CALLSIZE(r)
#define LD_REGS(r) \
ld %r3, FRAME_3+CALLSIZE(r); \
ld %r4, FRAME_4+CALLSIZE(r); \
ld %r5, FRAME_5+CALLSIZE(r); \
ld %r6, FRAME_6+CALLSIZE(r); \
ld %r7, FRAME_7+CALLSIZE(r); \
ld %r8, FRAME_8+CALLSIZE(r); \
ld %r9, FRAME_9+CALLSIZE(r); \
ld %r10, FRAME_10+CALLSIZE(r); \
ld %r11, FRAME_11+CALLSIZE(r); \
ld %r12, FRAME_12+CALLSIZE(r); \
ld %r13, FRAME_13+CALLSIZE(r); \
ld %r14, FRAME_14+CALLSIZE(r); \
ld %r15, FRAME_15+CALLSIZE(r); \
ld %r16, FRAME_16+CALLSIZE(r); \
ld %r17, FRAME_17+CALLSIZE(r); \
ld %r18, FRAME_18+CALLSIZE(r); \
ld %r19, FRAME_19+CALLSIZE(r); \
ld %r20, FRAME_20+CALLSIZE(r); \
ld %r21, FRAME_21+CALLSIZE(r); \
ld %r22, FRAME_22+CALLSIZE(r); \
ld %r23, FRAME_23+CALLSIZE(r); \
ld %r24, FRAME_24+CALLSIZE(r); \
ld %r25, FRAME_25+CALLSIZE(r); \
ld %r26, FRAME_26+CALLSIZE(r); \
ld %r27, FRAME_27+CALLSIZE(r); \
ld %r28, FRAME_28+CALLSIZE(r); \
ld %r29, FRAME_29+CALLSIZE(r); \
ld %r30, FRAME_30+CALLSIZE(r); \
ld %r31, FRAME_31+CALLSIZE(r)
#else
#define SAVE_REGS(r) \
stmw %r3, FRAME_3+CALLSIZE(r)
#define LD_REGS(r) \
lmw %r3, FRAME_3+CALLSIZE(r)
#endif
#define FRAME_SETUP(sprg_sp, savearea, exc) \
mfspr %r31, sprg_sp; \
\
STU %r31, -(FRAMELEN+REDZONE)(%r1); \
STORE %r0, FRAME_0+CALLSIZE(%r1); \
STORE %r31, FRAME_1+CALLSIZE(%r1); \
STORE %r2, FRAME_2+CALLSIZE(%r1); \
mflr %r31; \
STORE %r31, FRAME_LR+CALLSIZE(%r1); \
STORE %r30, FRAME_CR+CALLSIZE(%r1); \
GET_CPUINFO(%r2); \
LOAD %r30, (savearea+CPUSAVE_R30)(%r2); \
LOAD %r31, (savearea+CPUSAVE_R31)(%r2); \
\
SAVE_REGS(%r1); \
\
LOAD %r28, (savearea+CPUSAVE_BOOKE_DEAR)(%r2); \
LOAD %r29, (savearea+CPUSAVE_BOOKE_ESR)(%r2); \
STORE %r28, FRAME_BOOKE_DEAR+CALLSIZE(%r1); \
STORE %r29, FRAME_BOOKE_ESR+CALLSIZE(%r1); \
\
mfxer %r3; \
mfctr %r4; \
STORE %r3, FRAME_XER+CALLSIZE(%r1); \
STORE %r4, FRAME_CTR+CALLSIZE(%r1); \
li %r5, exc; \
STORE %r5, FRAME_EXC+CALLSIZE(%r1); \
\
mfspr %r3, SPR_DBCR0; \
STORE %r3, FRAME_BOOKE_DBCR0+CALLSIZE(%r1); \
\
LOAD %r30, (savearea+CPUSAVE_SRR0)(%r2); \
LOAD %r31, (savearea+CPUSAVE_SRR1)(%r2); \
STORE %r30, FRAME_SRR0+CALLSIZE(%r1); \
STORE %r31, FRAME_SRR1+CALLSIZE(%r1); \
LOAD THREAD_REG, PC_CURTHREAD(%r2); \
#define FRAME_LEAVE(isrr0, isrr1) \
wrteei 0; \
\
LOAD %r4, FRAME_CTR+CALLSIZE(%r1); \
LOAD %r5, FRAME_XER+CALLSIZE(%r1); \
LOAD %r6, FRAME_LR+CALLSIZE(%r1); \
LOAD %r7, FRAME_CR+CALLSIZE(%r1); \
mtctr %r4; \
mtxer %r5; \
mtlr %r6; \
mtcr %r7; \
\
LOAD %r4, FRAME_BOOKE_DBCR0+CALLSIZE(%r1); \
mtspr SPR_DBCR0, %r4; \
\
LOAD %r30, FRAME_SRR0+CALLSIZE(%r1); \
LOAD %r31, FRAME_SRR1+CALLSIZE(%r1); \
mtspr isrr0, %r30; \
mtspr isrr1, %r31; \
\
LD_REGS(%r1); \
LOAD %r2, FRAME_2+CALLSIZE(%r1); \
LOAD %r0, FRAME_0+CALLSIZE(%r1); \
LOAD %r1, FRAME_1+CALLSIZE(%r1); \
isync
#ifdef __powerpc64__
#define TLB_SAVE_REGS(br) \
std %r20, (TLBSAVE_BOOKE_R20)(br); \
std %r21, (TLBSAVE_BOOKE_R21)(br); \
std %r22, (TLBSAVE_BOOKE_R22)(br); \
std %r23, (TLBSAVE_BOOKE_R23)(br); \
std %r24, (TLBSAVE_BOOKE_R24)(br); \
std %r25, (TLBSAVE_BOOKE_R25)(br); \
std %r26, (TLBSAVE_BOOKE_R26)(br); \
std %r27, (TLBSAVE_BOOKE_R27)(br); \
std %r28, (TLBSAVE_BOOKE_R28)(br); \
std %r29, (TLBSAVE_BOOKE_R29)(br); \
std %r30, (TLBSAVE_BOOKE_R30)(br); \
std %r31, (TLBSAVE_BOOKE_R31)(br);
#define TLB_RESTORE_REGS(br) \
ld %r20, (TLBSAVE_BOOKE_R20)(br); \
ld %r21, (TLBSAVE_BOOKE_R21)(br); \
ld %r22, (TLBSAVE_BOOKE_R22)(br); \
ld %r23, (TLBSAVE_BOOKE_R23)(br); \
ld %r24, (TLBSAVE_BOOKE_R24)(br); \
ld %r25, (TLBSAVE_BOOKE_R25)(br); \
ld %r26, (TLBSAVE_BOOKE_R26)(br); \
ld %r27, (TLBSAVE_BOOKE_R27)(br); \
ld %r28, (TLBSAVE_BOOKE_R28)(br); \
ld %r29, (TLBSAVE_BOOKE_R29)(br); \
ld %r30, (TLBSAVE_BOOKE_R30)(br); \
ld %r31, (TLBSAVE_BOOKE_R31)(br);
#define TLB_NEST(outr,inr) \
rlwinm outr, inr, 7, 23, 24;
#else
#define TLB_SAVE_REGS(br) \
stmw %r20, TLBSAVE_BOOKE_R20(br)
#define TLB_RESTORE_REGS(br) \
lmw %r20, TLBSAVE_BOOKE_R20(br)
#define TLB_NEST(outr,inr) \
rlwinm outr, inr, 6, 24, 25;
#endif
#define TLB_PROLOG \
mtspr SPR_SPRG4, %r1; \
mtspr SPR_SPRG5, %r28; \
mtspr SPR_SPRG6, %r29; \
\
GET_CPUINFO(%r1); \
LOAD %r28, PC_BOOKE_TLB_LEVEL(%r1); \
TLB_NEST(%r29,%r28); \
addi %r28, %r28, 1; \
STORE %r28, PC_BOOKE_TLB_LEVEL(%r1); \
addi %r29, %r29, PC_BOOKE_TLBSAVE@l; \
add %r1, %r1, %r29; \
\
\
mfspr %r28, SPR_SPRG5; \
mfspr %r29, SPR_SPRG6; \
TLB_SAVE_REGS(%r1); \
\
mflr %r30; \
mfcr %r31; \
STORE %r30, (TLBSAVE_BOOKE_LR)(%r1); \
STORE %r31, (TLBSAVE_BOOKE_CR)(%r1); \
\
mfsrr0 %r30; \
mfsrr1 %r31; \
STORE %r30, (TLBSAVE_BOOKE_SRR0)(%r1); \
STORE %r31, (TLBSAVE_BOOKE_SRR1)(%r1); \
isync; \
mfspr %r1, SPR_SPRG4
#define TLB_RESTORE \
mtspr SPR_SPRG4, %r1; \
GET_CPUINFO(%r1); \
\
LOAD %r28, PC_BOOKE_TLB_LEVEL(%r1); \
subi %r28, %r28, 1; \
STORE %r28, PC_BOOKE_TLB_LEVEL(%r1); \
TLB_NEST(%r29,%r28); \
addi %r29, %r29, PC_BOOKE_TLBSAVE@l; \
add %r1, %r1, %r29; \
\
\
LOAD %r30, (TLBSAVE_BOOKE_LR)(%r1); \
LOAD %r31, (TLBSAVE_BOOKE_CR)(%r1); \
mtlr %r30; \
mtcr %r31; \
\
LOAD %r30, (TLBSAVE_BOOKE_SRR0)(%r1); \
LOAD %r31, (TLBSAVE_BOOKE_SRR1)(%r1); \
mtsrr0 %r30; \
mtsrr1 %r31; \
\
TLB_RESTORE_REGS(%r1); \
mfspr %r1, SPR_SPRG4
#ifdef SMP
#define TLB_LOCK \
GET_CPUINFO(%r20); \
LOAD %r21, PC_CURTHREAD(%r20); \
LOAD %r22, PC_BOOKE_TLB_LOCK(%r20); \
\
1: LOADX %r23, 0, %r22; \
CMPI %r23, TLB_UNLOCKED; \
beq 2f; \
\
\
CMPL cr0, %r21, %r23; \
bne- 1b; \
\
2: \
STOREX %r21, 0, %r22; \
bne- 1b; \
\
\
lwz %r21, RES_RECURSE(%r22); \
addi %r21, %r21, 1; \
stw %r21, RES_RECURSE(%r22); \
isync; \
msync
#define TLB_UNLOCK \
GET_CPUINFO(%r20); \
LOAD %r21, PC_CURTHREAD(%r20); \
LOAD %r22, PC_BOOKE_TLB_LOCK(%r20); \
\
\
lwz %r23, RES_RECURSE(%r22); \
subi %r23, %r23, 1; \
stw %r23, RES_RECURSE(%r22); \
\
cmplwi %r23, 0; \
bne 1f; \
isync; \
msync; \
\
\
li %r23, TLB_UNLOCKED; \
STORE %r23, 0(%r22); \
1: isync; \
msync
#else
#define TLB_LOCK
#define TLB_UNLOCK
#endif
#define INTERRUPT(label) \
.globl label; \
.align 5; \
CNAME(label):
.text
.globl CNAME(interrupt_vector_base)
.align 5
interrupt_vector_base:
INTERRUPT(int_unknown)
STANDARD_PROLOG(SPR_SPRG1, PC_TEMPSAVE, SPR_SRR0, SPR_SRR1)
FRAME_SETUP(SPR_SPRG1, PC_TEMPSAVE, EXC_RSVD)
b trap_common
INTERRUPT(int_critical_input)
STANDARD_CRIT_PROLOG(SPR_SPRG2, PC_BOOKE_CRITSAVE, SPR_CSRR0, SPR_CSRR1)
FRAME_SETUP(SPR_SPRG2, PC_BOOKE_CRITSAVE, EXC_CRIT)
GET_TOCBASE(%r2)
addi %r3, %r1, CALLSIZE
bl CNAME(powerpc_interrupt)
TOC_RESTORE
FRAME_LEAVE(SPR_CSRR0, SPR_CSRR1)
rfci
INTERRUPT(int_machine_check)
STANDARD_PROLOG(SPR_SPRG3, PC_BOOKE_MCHKSAVE, SPR_MCSRR0, SPR_MCSRR1)
FRAME_SETUP(SPR_SPRG3, PC_BOOKE_MCHKSAVE, EXC_MCHK)
GET_TOCBASE(%r2)
addi %r3, %r1, CALLSIZE
bl CNAME(powerpc_interrupt)
TOC_RESTORE
FRAME_LEAVE(SPR_MCSRR0, SPR_MCSRR1)
rfmci
INTERRUPT(int_data_storage)
STANDARD_PROLOG(SPR_SPRG1, PC_DISISAVE, SPR_SRR0, SPR_SRR1)
FRAME_SETUP(SPR_SPRG1, PC_DISISAVE, EXC_DSI)
b trap_common
INTERRUPT(int_instr_storage)
STANDARD_PROLOG(SPR_SPRG1, PC_TEMPSAVE, SPR_SRR0, SPR_SRR1)
FRAME_SETUP(SPR_SPRG1, PC_TEMPSAVE, EXC_ISI)
b trap_common
INTERRUPT(int_external_input)
STANDARD_PROLOG(SPR_SPRG1, PC_TEMPSAVE, SPR_SRR0, SPR_SRR1)
FRAME_SETUP(SPR_SPRG1, PC_TEMPSAVE, EXC_EXI)
b trap_common
INTERRUPT(int_alignment)
STANDARD_PROLOG(SPR_SPRG1, PC_TEMPSAVE, SPR_SRR0, SPR_SRR1)
FRAME_SETUP(SPR_SPRG1, PC_TEMPSAVE, EXC_ALI)
b trap_common
INTERRUPT(int_program)
STANDARD_PROLOG(SPR_SPRG1, PC_TEMPSAVE, SPR_SRR0, SPR_SRR1)
FRAME_SETUP(SPR_SPRG1, PC_TEMPSAVE, EXC_PGM)
b trap_common
INTERRUPT(int_fpu)
STANDARD_PROLOG(SPR_SPRG1, PC_TEMPSAVE, SPR_SRR0, SPR_SRR1)
FRAME_SETUP(SPR_SPRG1, PC_TEMPSAVE, EXC_FPU)
b trap_common
INTERRUPT(int_syscall)
STANDARD_PROLOG(SPR_SPRG1, PC_TEMPSAVE, SPR_SRR0, SPR_SRR1)
FRAME_SETUP(SPR_SPRG1, PC_TEMPSAVE, EXC_SC)
b trap_common
INTERRUPT(int_decrementer)
STANDARD_PROLOG(SPR_SPRG1, PC_TEMPSAVE, SPR_SRR0, SPR_SRR1)
FRAME_SETUP(SPR_SPRG1, PC_TEMPSAVE, EXC_DECR)
b trap_common
INTERRUPT(int_fixed_interval_timer)
STANDARD_PROLOG(SPR_SPRG1, PC_TEMPSAVE, SPR_SRR0, SPR_SRR1)
FRAME_SETUP(SPR_SPRG1, PC_TEMPSAVE, EXC_FIT)
b trap_common
INTERRUPT(int_watchdog)
STANDARD_PROLOG(SPR_SPRG1, PC_TEMPSAVE, SPR_SRR0, SPR_SRR1)
FRAME_SETUP(SPR_SPRG1, PC_TEMPSAVE, EXC_WDOG)
b trap_common
INTERRUPT(int_vec)
STANDARD_PROLOG(SPR_SPRG1, PC_TEMPSAVE, SPR_SRR0, SPR_SRR1)
FRAME_SETUP(SPR_SPRG1, PC_TEMPSAVE, EXC_VEC)
b trap_common
INTERRUPT(int_vecast)
STANDARD_PROLOG(SPR_SPRG1, PC_TEMPSAVE, SPR_SRR0, SPR_SRR1)
FRAME_SETUP(SPR_SPRG1, PC_TEMPSAVE, EXC_VECAST_E)
b trap_common
#ifdef HWPMC_HOOKS
INTERRUPT(int_performance_counter)
STANDARD_PROLOG(SPR_SPRG3, PC_TEMPSAVE, SPR_SRR0, SPR_SRR1)
FRAME_SETUP(SPR_SPRG3, PC_TEMPSAVE, EXC_PERF)
b trap_common
#endif
INTERRUPT(int_data_tlb_error)
TLB_PROLOG
TLB_LOCK
mfspr %r31, SPR_DEAR
mfspr %r29, SPR_MAS0
mfspr %r28, SPR_MAS1
mfspr %r27, SPR_MAS2
LOAD_ADDR(%r21, VM_MAXUSER_ADDRESS)
CMPL cr0, %r31, %r21
blt search_user_pmap
mfsrr1 %r21
mtcr %r21
bt 17, search_failed
#ifdef __powerpc64__
srdi %r21, %r31, 48
cmpldi cr0, %r21, VM_MIN_KERNEL_ADDRESS@highest
#else
lis %r21, VM_MIN_KERNEL_ADDRESS@h
cmplw cr0, %r31, %r21
#endif
blt search_failed
search_kernel_pmap:
bl 1f
#ifdef __powerpc64__
.llong kernel_pmap_store-.
#else
.long kernel_pmap_store-.
#endif
1: mflr %r21
LOAD %r26, 0(%r21)
add %r26, %r21, %r26
li %r21, 0
rlwimi %r28, %r21, 0, 8, 15
tlb_miss_handle:
bl pte_lookup
CMPI %r25, 0
beq search_failed
bl tlb_fill_entry
tlb_miss_return:
TLB_UNLOCK
TLB_RESTORE
rfi
search_user_pmap:
GET_CPUINFO(%r26)
LOAD %r26, PC_CURPMAP(%r26)
b tlb_miss_handle
search_failed:
lis %r23, 0xffff0000@h
mtspr SPR_MAS0, %r29
mtspr SPR_MAS1, %r28
mtspr SPR_MAS2, %r27
mtspr SPR_MAS3, %r23
li %r23, 0
mtspr SPR_MAS7, %r23
isync
tlbwe
msync
isync
b tlb_miss_return
pte_lookup:
CMPI %r26, 0
beq 1f
#ifdef __powerpc64__
rldicl %r21, %r31, (64 - PG_ROOT_L), (64 - PG_ROOT_NUM)
slwi %r21, %r21, PG_ROOT_ENTRY_SHIFT
ld %r25, PM_ROOT(%r26)
ldx %r25, %r25, %r21
cmpdi %r25, 0
beq 2f
rldicl %r21, %r31, (64 - PDIR_L1_L), (64 - PDIR_L1_NUM)
slwi %r21, %r21, PDIR_L1_ENTRY_SHIFT
ldx %r25, %r25, %r21
cmpdi %r25, 0
beq 2f
rldicl %r21, %r31, (64 - PDIR_L), (64 - PDIR_NUM)
slwi %r21, %r21, PDIR_ENTRY_SHIFT
ldx %r25, %r25, %r21
cmpdi %r25, 0
beq 2f
rldicl %r21, %r31, (64 - PTBL_L), (64 - PTBL_NUM)
slwi %r21, %r21, PTBL_ENTRY_SHIFT
#else
srwi %r21, %r31, PDIR_SHIFT
slwi %r21, %r21, PDIR_ENTRY_SHIFT
lwz %r25, PM_PDIR(%r26)
lwzx %r25, %r25, %r21
cmpwi %r25, 0
beq 2f
lis %r21, PTBL_MASK@h
ori %r21, %r21, PTBL_MASK@l
and %r21, %r21, %r31
srwi %r21, %r21, (PTBL_SHIFT - PTBL_ENTRY_SHIFT)
#endif
add %r25, %r25, %r21
lwz %r21, PTE_FLAGS(%r25)
andi. %r21, %r21, PTE_VALID@l
bne 2f
1:
li %r25, 0
2:
blr
tlb_fill_entry:
li %r23, PTE_FLAGS
1:
lwarx %r21, %r23, %r25
oris %r21, %r21, PTE_REFERENCED@h
andi. %r22, %r21, (PTE_SW | PTE_UW)@l
beq 2f
ori %r21, %r21, PTE_MODIFIED@l
2:
stwcx. %r21, %r23, %r25
bne- 1b
rlwimi %r27, %r21, 13, 27, 30
LOAD %r23, PTE_RPN(%r25)
#ifdef __powerpc64__
rldicr %r22, %r23, 52, 51
rldicl %r23, %r23, 20, 54
rlwimi %r22, %r21, 30, 26, 31
#else
rlwinm %r22, %r23, 20, 0, 11
rlwimi %r22, %r21, 30, 26, 31
rlwimi %r22, %r21, 20, 12, 19
rlwinm %r23, %r23, 20, 24, 31
#endif
mtspr SPR_MAS0, %r29
mtspr SPR_MAS1, %r28
mtspr SPR_MAS2, %r27
mtspr SPR_MAS3, %r22
mtspr SPR_MAS7, %r23
isync
tlbwe
isync
msync
blr
INTERRUPT(int_inst_tlb_error)
TLB_PROLOG
TLB_LOCK
mfsrr0 %r31
mfspr %r29, SPR_MAS0
mfspr %r28, SPR_MAS1
mfspr %r27, SPR_MAS2
mfsrr1 %r21
mtcr %r21
bt 17, search_user_pmap
b search_kernel_pmap
.globl interrupt_vector_top
interrupt_vector_top:
INTERRUPT(int_debug)
STANDARD_CRIT_PROLOG(SPR_SPRG2, PC_BOOKE_CRITSAVE, SPR_CSRR0, SPR_CSRR1)
FRAME_SETUP(SPR_SPRG2, PC_BOOKE_CRITSAVE, EXC_DEBUG)
bl int_debug_int
FRAME_LEAVE(SPR_CSRR0, SPR_CSRR1)
rfci
INTERRUPT(int_debug_ed)
STANDARD_CRIT_PROLOG(SPR_SPRG2, PC_BOOKE_CRITSAVE, SPR_DSRR0, SPR_DSRR1)
FRAME_SETUP(SPR_SPRG2, PC_BOOKE_CRITSAVE, EXC_DEBUG)
bl int_debug_int
FRAME_LEAVE(SPR_DSRR0, SPR_DSRR1)
rfdi
int_debug_int:
mflr %r14
GET_CPUINFO(%r3)
LOAD %r3, (PC_BOOKE_CRITSAVE+CPUSAVE_SRR0)(%r3)
bl 0f
ADDR(interrupt_vector_base-.)
ADDR(interrupt_vector_top-.)
0: mflr %r5
LOAD %r4,0(%r5)
add %r4,%r4,%r5
CMPL cr0, %r3, %r4
blt trap_common
LOAD %r4,WORD_SIZE(%r5)
add %r4,%r4,%r5
addi %r4,%r4,4
CMPL cr0, %r3, %r4
bge trap_common
LOAD %r3, FRAME_SRR1+CALLSIZE(%r1);
rlwinm %r3, %r3, 0, 23, 21
STORE %r3, FRAME_SRR1+CALLSIZE(%r1);
GET_CPUINFO(%r4)
LOAD %r3, (PC_BOOKE_CRITSAVE+BOOKE_CRITSAVE_SRR0)(%r4);
mtspr SPR_SRR0, %r3
LOAD %r4, (PC_BOOKE_CRITSAVE+BOOKE_CRITSAVE_SRR1)(%r4);
mtspr SPR_SRR1, %r4
mtlr %r14
blr
trap_common:
GET_TOCBASE(%r2)
addi %r3, %r1, CALLSIZE
bl CNAME(powerpc_interrupt)
TOC_RESTORE
.globl CNAME(trapexit)
CNAME(trapexit):
wrteei 0
LOAD %r5, FRAME_SRR1+CALLSIZE(%r1)
mtcr %r5
bf 17, 1f
GET_CPUINFO(%r3)
LOAD %r4, PC_CURTHREAD(%r3)
lwz %r4, TD_AST(%r4)
cmpwi %r4, 0
beq 1f
wrteei 1
addi %r3, %r1, CALLSIZE
bl CNAME(ast)
TOC_RESTORE
.globl CNAME(asttrapexit)
CNAME(asttrapexit):
b trapexit
1:
FRAME_LEAVE(SPR_SRR0, SPR_SRR1)
rfi
#if defined(KDB)
ASENTRY_NOPROF(breakpoint)
mtsprg1 %r1
mfmsr %r3
mtsrr1 %r3
li %r4, ~(PSL_EE | PSL_ME)@l
oris %r4, %r4, ~(PSL_EE | PSL_ME)@h
and %r3, %r3, %r4
mtmsr %r3
isync
GET_CPUINFO(%r3)
STORE %r30, (PC_DBSAVE+CPUSAVE_R30)(%r3)
STORE %r31, (PC_DBSAVE+CPUSAVE_R31)(%r3)
mflr %r31
mtsrr0 %r31
mfspr %r30, SPR_DEAR
mfspr %r31, SPR_ESR
STORE %r30, (PC_DBSAVE+CPUSAVE_BOOKE_DEAR)(%r3)
STORE %r31, (PC_DBSAVE+CPUSAVE_BOOKE_ESR)(%r3)
mfsrr0 %r30
mfsrr1 %r31
STORE %r30, (PC_DBSAVE+CPUSAVE_SRR0)(%r3)
STORE %r31, (PC_DBSAVE+CPUSAVE_SRR1)(%r3)
isync
mfcr %r30
dbtrap:
FRAME_SETUP(SPR_SPRG1, PC_DBSAVE, EXC_DEBUG)
GET_TOCBASE(%r2)
addi %r3, %r1, CALLSIZE
bl CNAME(db_trap_glue)
TOC_RESTORE
or. %r3, %r3, %r3
bne dbleave
b trap_common
dbleave:
FRAME_LEAVE(SPR_SRR0, SPR_SRR1)
rfi
ASEND(breakpoint)
#endif
#ifdef SMP
ENTRY(tlb_lock)
GET_CPUINFO(%r5)
LOAD %r5, PC_CURTHREAD(%r5)
1: LOADX %r4, 0, %r3
CMPI %r4, TLB_UNLOCKED
bne 1b
STOREX %r5, 0, %r3
bne- 1b
isync
msync
blr
END(tlb_lock)
ENTRY(tlb_unlock)
isync
msync
li %r4, TLB_UNLOCKED
STORE %r4, 0(%r3)
isync
msync
blr
END(tlb_unlock)
.data
.align 5
GLOBAL(tlb0_miss_locks)
.space RES_GRANULE * MAXCPU
#endif