powerpc/32: Dismantle EXC_XFER_STD/LITE/TEMPLATE
In order to get more control in exception prolog, dismantle all non standard exception macros, finishing with EXC_XFER_STD and EXC_XFER_LITE and EXC_XFER_TEMPLATE. Also remove transfer_to_handler_full and ret_from_except and ret_from_except_full as they are not used anymore. Last parameter of EXCEPTION() is now ignored, will be removed in a later patch to avoid too much churn. Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/ca5795d04a220586b7037dbbbe6951dfa9e768eb.1615552867.git.christophe.leroy@csgroup.eu
This commit is contained in:
parent
8f6ff5bd9b
commit
4c0104a83f
@ -48,30 +48,6 @@
|
|||||||
*/
|
*/
|
||||||
.align 12
|
.align 12
|
||||||
|
|
||||||
#ifdef CONFIG_BOOKE
|
|
||||||
.globl mcheck_transfer_to_handler
|
|
||||||
mcheck_transfer_to_handler:
|
|
||||||
/* fall through */
|
|
||||||
_ASM_NOKPROBE_SYMBOL(mcheck_transfer_to_handler)
|
|
||||||
|
|
||||||
.globl debug_transfer_to_handler
|
|
||||||
debug_transfer_to_handler:
|
|
||||||
/* fall through */
|
|
||||||
_ASM_NOKPROBE_SYMBOL(debug_transfer_to_handler)
|
|
||||||
|
|
||||||
.globl crit_transfer_to_handler
|
|
||||||
crit_transfer_to_handler:
|
|
||||||
/* fall through */
|
|
||||||
_ASM_NOKPROBE_SYMBOL(crit_transfer_to_handler)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_40x
|
|
||||||
.globl crit_transfer_to_handler
|
|
||||||
crit_transfer_to_handler:
|
|
||||||
/* fall through */
|
|
||||||
_ASM_NOKPROBE_SYMBOL(crit_transfer_to_handler)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This code finishes saving the registers to the exception frame
|
* This code finishes saving the registers to the exception frame
|
||||||
* and jumps to the appropriate handler for the exception, turning
|
* and jumps to the appropriate handler for the exception, turning
|
||||||
@ -79,13 +55,6 @@ _ASM_NOKPROBE_SYMBOL(crit_transfer_to_handler)
|
|||||||
* Note that we rely on the caller having set cr0.eq iff the exception
|
* Note that we rely on the caller having set cr0.eq iff the exception
|
||||||
* occurred in kernel mode (i.e. MSR:PR = 0).
|
* occurred in kernel mode (i.e. MSR:PR = 0).
|
||||||
*/
|
*/
|
||||||
.globl transfer_to_handler_full
|
|
||||||
transfer_to_handler_full:
|
|
||||||
_ASM_NOKPROBE_SYMBOL(transfer_to_handler_full)
|
|
||||||
/* fall through */
|
|
||||||
|
|
||||||
.globl transfer_to_handler
|
|
||||||
transfer_to_handler:
|
|
||||||
.globl prepare_transfer_to_handler
|
.globl prepare_transfer_to_handler
|
||||||
prepare_transfer_to_handler:
|
prepare_transfer_to_handler:
|
||||||
SAVE_NVGPRS(r11)
|
SAVE_NVGPRS(r11)
|
||||||
@ -136,7 +105,6 @@ transfer_to_handler_cont:
|
|||||||
b fast_exception_return
|
b fast_exception_return
|
||||||
#endif
|
#endif
|
||||||
_ASM_NOKPROBE_SYMBOL(prepare_transfer_to_handler)
|
_ASM_NOKPROBE_SYMBOL(prepare_transfer_to_handler)
|
||||||
_ASM_NOKPROBE_SYMBOL(transfer_to_handler)
|
|
||||||
_ASM_NOKPROBE_SYMBOL(transfer_to_handler_cont)
|
_ASM_NOKPROBE_SYMBOL(transfer_to_handler_cont)
|
||||||
|
|
||||||
.globl transfer_to_syscall
|
.globl transfer_to_syscall
|
||||||
@ -352,18 +320,10 @@ _ASM_NOKPROBE_SYMBOL(fast_exception_return)
|
|||||||
3:
|
3:
|
||||||
li r10,-1
|
li r10,-1
|
||||||
stw r10,_TRAP(r11)
|
stw r10,_TRAP(r11)
|
||||||
bl transfer_to_handler_full
|
prepare_transfer_to_handler
|
||||||
bl unrecoverable_exception
|
bl unrecoverable_exception
|
||||||
trap /* should not get here */
|
trap /* should not get here */
|
||||||
|
|
||||||
.globl ret_from_except_full
|
|
||||||
ret_from_except_full:
|
|
||||||
/* fall through */
|
|
||||||
|
|
||||||
.globl ret_from_except
|
|
||||||
ret_from_except:
|
|
||||||
_ASM_NOKPROBE_SYMBOL(ret_from_except)
|
|
||||||
|
|
||||||
.globl interrupt_return
|
.globl interrupt_return
|
||||||
interrupt_return:
|
interrupt_return:
|
||||||
lwz r4,_MSR(r1)
|
lwz r4,_MSR(r1)
|
||||||
|
@ -189,20 +189,9 @@ label:
|
|||||||
#define EXCEPTION(n, label, hdlr, xfer) \
|
#define EXCEPTION(n, label, hdlr, xfer) \
|
||||||
START_EXCEPTION(n, label) \
|
START_EXCEPTION(n, label) \
|
||||||
EXCEPTION_PROLOG n label; \
|
EXCEPTION_PROLOG n label; \
|
||||||
xfer(n, hdlr)
|
prepare_transfer_to_handler; \
|
||||||
|
bl hdlr; \
|
||||||
#define EXC_XFER_TEMPLATE(hdlr, trap, msr, tfer, ret) \
|
b interrupt_return
|
||||||
bl tfer; \
|
|
||||||
bl hdlr; \
|
|
||||||
b ret
|
|
||||||
|
|
||||||
#define EXC_XFER_STD(n, hdlr) \
|
|
||||||
EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, transfer_to_handler_full, \
|
|
||||||
ret_from_except_full)
|
|
||||||
|
|
||||||
#define EXC_XFER_LITE(n, hdlr) \
|
|
||||||
EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, transfer_to_handler, \
|
|
||||||
ret_from_except)
|
|
||||||
|
|
||||||
.macro vmap_stack_overflow_exception
|
.macro vmap_stack_overflow_exception
|
||||||
__HEAD
|
__HEAD
|
||||||
@ -218,7 +207,9 @@ vmap_stack_overflow:
|
|||||||
lwz r1, emergency_ctx@l(r1)
|
lwz r1, emergency_ctx@l(r1)
|
||||||
addi r1, r1, THREAD_SIZE - INT_FRAME_SIZE
|
addi r1, r1, THREAD_SIZE - INT_FRAME_SIZE
|
||||||
EXCEPTION_PROLOG_2 0 vmap_stack_overflow
|
EXCEPTION_PROLOG_2 0 vmap_stack_overflow
|
||||||
EXC_XFER_STD(0, stack_overflow_exception)
|
prepare_transfer_to_handler
|
||||||
|
bl stack_overflow_exception
|
||||||
|
b interrupt_return
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
#endif /* __HEAD_32_H__ */
|
#endif /* __HEAD_32_H__ */
|
||||||
|
@ -187,8 +187,9 @@ _ASM_NOKPROBE_SYMBOL(\name\()_virt)
|
|||||||
#define CRITICAL_EXCEPTION(n, label, hdlr) \
|
#define CRITICAL_EXCEPTION(n, label, hdlr) \
|
||||||
START_EXCEPTION(n, label); \
|
START_EXCEPTION(n, label); \
|
||||||
CRITICAL_EXCEPTION_PROLOG n label; \
|
CRITICAL_EXCEPTION_PROLOG n label; \
|
||||||
EXC_XFER_TEMPLATE(hdlr, n+2, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \
|
prepare_transfer_to_handler; \
|
||||||
crit_transfer_to_handler, ret_from_crit_exc)
|
bl hdlr; \
|
||||||
|
b ret_from_crit_exc
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 0x0100 - Critical Interrupt Exception
|
* 0x0100 - Critical Interrupt Exception
|
||||||
@ -209,7 +210,9 @@ _ASM_NOKPROBE_SYMBOL(\name\()_virt)
|
|||||||
*/
|
*/
|
||||||
START_EXCEPTION(0x0300, DataStorage)
|
START_EXCEPTION(0x0300, DataStorage)
|
||||||
EXCEPTION_PROLOG 0x300 DataStorage handle_dar_dsisr=1
|
EXCEPTION_PROLOG 0x300 DataStorage handle_dar_dsisr=1
|
||||||
EXC_XFER_LITE(0x300, do_page_fault)
|
prepare_transfer_to_handler
|
||||||
|
bl do_page_fault
|
||||||
|
b interrupt_return
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 0x0400 - Instruction Storage Exception
|
* 0x0400 - Instruction Storage Exception
|
||||||
@ -220,7 +223,9 @@ _ASM_NOKPROBE_SYMBOL(\name\()_virt)
|
|||||||
li r5,0
|
li r5,0
|
||||||
stw r5, _ESR(r11) /* Zero ESR */
|
stw r5, _ESR(r11) /* Zero ESR */
|
||||||
stw r12, _DEAR(r11) /* SRR0 as DEAR */
|
stw r12, _DEAR(r11) /* SRR0 as DEAR */
|
||||||
EXC_XFER_LITE(0x400, do_page_fault)
|
prepare_transfer_to_handler
|
||||||
|
bl do_page_fault
|
||||||
|
b interrupt_return
|
||||||
|
|
||||||
/* 0x0500 - External Interrupt Exception */
|
/* 0x0500 - External Interrupt Exception */
|
||||||
EXCEPTION(0x0500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE)
|
EXCEPTION(0x0500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE)
|
||||||
@ -499,9 +504,9 @@ _ASM_NOKPROBE_SYMBOL(\name\()_virt)
|
|||||||
/* continue normal handling for a critical exception... */
|
/* continue normal handling for a critical exception... */
|
||||||
2: mfspr r4,SPRN_DBSR
|
2: mfspr r4,SPRN_DBSR
|
||||||
stw r4,_ESR(r11) /* DebugException takes DBSR in _ESR */
|
stw r4,_ESR(r11) /* DebugException takes DBSR in _ESR */
|
||||||
EXC_XFER_TEMPLATE(DebugException, 0x2002, \
|
prepare_transfer_to_handler
|
||||||
(MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \
|
bl DebugException
|
||||||
crit_transfer_to_handler, ret_from_crit_exc)
|
b ret_from_crit_exc
|
||||||
|
|
||||||
/* Programmable Interval Timer (PIT) Exception. (from 0x1000) */
|
/* Programmable Interval Timer (PIT) Exception. (from 0x1000) */
|
||||||
__HEAD
|
__HEAD
|
||||||
@ -509,21 +514,25 @@ Decrementer:
|
|||||||
EXCEPTION_PROLOG 0x1000 Decrementer
|
EXCEPTION_PROLOG 0x1000 Decrementer
|
||||||
lis r0,TSR_PIS@h
|
lis r0,TSR_PIS@h
|
||||||
mtspr SPRN_TSR,r0 /* Clear the PIT exception */
|
mtspr SPRN_TSR,r0 /* Clear the PIT exception */
|
||||||
EXC_XFER_LITE(0x1000, timer_interrupt)
|
prepare_transfer_to_handler
|
||||||
|
bl timer_interrupt
|
||||||
|
b interrupt_return
|
||||||
|
|
||||||
/* Fixed Interval Timer (FIT) Exception. (from 0x1010) */
|
/* Fixed Interval Timer (FIT) Exception. (from 0x1010) */
|
||||||
__HEAD
|
__HEAD
|
||||||
FITException:
|
FITException:
|
||||||
EXCEPTION_PROLOG 0x1010 FITException
|
EXCEPTION_PROLOG 0x1010 FITException
|
||||||
EXC_XFER_STD(0x1010, unknown_exception)
|
prepare_transfer_to_handler
|
||||||
|
bl unknown_exception
|
||||||
|
b interrupt_return
|
||||||
|
|
||||||
/* Watchdog Timer (WDT) Exception. (from 0x1020) */
|
/* Watchdog Timer (WDT) Exception. (from 0x1020) */
|
||||||
__HEAD
|
__HEAD
|
||||||
WDTException:
|
WDTException:
|
||||||
CRITICAL_EXCEPTION_PROLOG 0x1020 WDTException
|
CRITICAL_EXCEPTION_PROLOG 0x1020 WDTException
|
||||||
EXC_XFER_TEMPLATE(WatchdogException, 0x1020+2,
|
prepare_transfer_to_handler
|
||||||
(MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)),
|
bl WatchdogException
|
||||||
crit_transfer_to_handler, ret_from_crit_exc)
|
b ret_from_crit_exc
|
||||||
|
|
||||||
/* Other PowerPC processors, namely those derived from the 6xx-series
|
/* Other PowerPC processors, namely those derived from the 6xx-series
|
||||||
* have vectors from 0x2100 through 0x2F00 defined, but marked as reserved.
|
* have vectors from 0x2100 through 0x2F00 defined, but marked as reserved.
|
||||||
|
@ -123,7 +123,9 @@ instruction_counter:
|
|||||||
/* Machine check */
|
/* Machine check */
|
||||||
START_EXCEPTION(0x200, MachineCheck)
|
START_EXCEPTION(0x200, MachineCheck)
|
||||||
EXCEPTION_PROLOG 0x200 MachineCheck handle_dar_dsisr=1
|
EXCEPTION_PROLOG 0x200 MachineCheck handle_dar_dsisr=1
|
||||||
EXC_XFER_STD(0x200, machine_check_exception)
|
prepare_transfer_to_handler
|
||||||
|
bl machine_check_exception
|
||||||
|
b interrupt_return
|
||||||
|
|
||||||
/* External interrupt */
|
/* External interrupt */
|
||||||
EXCEPTION(0x500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE)
|
EXCEPTION(0x500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE)
|
||||||
@ -314,7 +316,9 @@ instruction_counter:
|
|||||||
.Litlbie:
|
.Litlbie:
|
||||||
stw r12, _DAR(r11)
|
stw r12, _DAR(r11)
|
||||||
stw r5, _DSISR(r11)
|
stw r5, _DSISR(r11)
|
||||||
EXC_XFER_LITE(0x400, do_page_fault)
|
prepare_transfer_to_handler
|
||||||
|
bl do_page_fault
|
||||||
|
b interrupt_return
|
||||||
|
|
||||||
/* This is the data TLB error on the MPC8xx. This could be due to
|
/* This is the data TLB error on the MPC8xx. This could be due to
|
||||||
* many reasons, including a dirty update to a pte. We bail out to
|
* many reasons, including a dirty update to a pte. We bail out to
|
||||||
@ -335,7 +339,9 @@ DARFixed:/* Return from dcbx instruction bug workaround */
|
|||||||
beq+ .Ldtlbie
|
beq+ .Ldtlbie
|
||||||
tlbie r4
|
tlbie r4
|
||||||
.Ldtlbie:
|
.Ldtlbie:
|
||||||
EXC_XFER_LITE(0x300, do_page_fault)
|
prepare_transfer_to_handler
|
||||||
|
bl do_page_fault
|
||||||
|
b interrupt_return
|
||||||
|
|
||||||
#ifdef CONFIG_VMAP_STACK
|
#ifdef CONFIG_VMAP_STACK
|
||||||
vmap_stack_overflow_exception
|
vmap_stack_overflow_exception
|
||||||
|
@ -271,7 +271,9 @@ __secondary_hold_acknowledge:
|
|||||||
beq cr1, 1f
|
beq cr1, 1f
|
||||||
twi 31, 0, 0
|
twi 31, 0, 0
|
||||||
#endif
|
#endif
|
||||||
1: EXC_XFER_STD(0x200, machine_check_exception)
|
1: prepare_transfer_to_handler
|
||||||
|
bl machine_check_exception
|
||||||
|
b interrupt_return
|
||||||
|
|
||||||
/* Data access exception. */
|
/* Data access exception. */
|
||||||
START_EXCEPTION(0x300, DataAccess)
|
START_EXCEPTION(0x300, DataAccess)
|
||||||
@ -296,12 +298,13 @@ ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_HPTE_TABLE)
|
|||||||
1: EXCEPTION_PROLOG_0 handle_dar_dsisr=1
|
1: EXCEPTION_PROLOG_0 handle_dar_dsisr=1
|
||||||
EXCEPTION_PROLOG_1
|
EXCEPTION_PROLOG_1
|
||||||
EXCEPTION_PROLOG_2 0x300 DataAccess handle_dar_dsisr=1
|
EXCEPTION_PROLOG_2 0x300 DataAccess handle_dar_dsisr=1
|
||||||
|
prepare_transfer_to_handler
|
||||||
lwz r5, _DSISR(r11)
|
lwz r5, _DSISR(r11)
|
||||||
andis. r0, r5, DSISR_DABRMATCH@h
|
andis. r0, r5, DSISR_DABRMATCH@h
|
||||||
bne- 1f
|
bne- 1f
|
||||||
EXC_XFER_LITE(0x300, do_page_fault)
|
bl do_page_fault
|
||||||
1: prepare_transfer_to_handler
|
b interrupt_return
|
||||||
bl do_break
|
1: bl do_break
|
||||||
REST_NVGPRS(r1)
|
REST_NVGPRS(r1)
|
||||||
b interrupt_return
|
b interrupt_return
|
||||||
|
|
||||||
@ -331,7 +334,9 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE)
|
|||||||
andis. r5,r9,DSISR_SRR1_MATCH_32S@h /* Filter relevant SRR1 bits */
|
andis. r5,r9,DSISR_SRR1_MATCH_32S@h /* Filter relevant SRR1 bits */
|
||||||
stw r5, _DSISR(r11)
|
stw r5, _DSISR(r11)
|
||||||
stw r12, _DAR(r11)
|
stw r12, _DAR(r11)
|
||||||
EXC_XFER_LITE(0x400, do_page_fault)
|
prepare_transfer_to_handler
|
||||||
|
bl do_page_fault
|
||||||
|
b interrupt_return
|
||||||
|
|
||||||
/* External interrupt */
|
/* External interrupt */
|
||||||
EXCEPTION(0x500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE)
|
EXCEPTION(0x500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE)
|
||||||
@ -366,7 +371,9 @@ END_FTR_SECTION_IFSET(CPU_FTR_FPU_UNAVAILABLE)
|
|||||||
beq 1f
|
beq 1f
|
||||||
bl load_up_fpu /* if from user, just load it up */
|
bl load_up_fpu /* if from user, just load it up */
|
||||||
b fast_exception_return
|
b fast_exception_return
|
||||||
1: EXC_XFER_LITE(0x800, kernel_fp_unavailable_exception)
|
1: prepare_transfer_to_handler
|
||||||
|
bl kernel_fp_unavailable_exception
|
||||||
|
b interrupt_return
|
||||||
#else
|
#else
|
||||||
b ProgramCheck
|
b ProgramCheck
|
||||||
#endif
|
#endif
|
||||||
@ -730,12 +737,16 @@ AltiVecUnavailable:
|
|||||||
bl load_up_altivec /* if from user, just load it up */
|
bl load_up_altivec /* if from user, just load it up */
|
||||||
b fast_exception_return
|
b fast_exception_return
|
||||||
#endif /* CONFIG_ALTIVEC */
|
#endif /* CONFIG_ALTIVEC */
|
||||||
1: EXC_XFER_LITE(0xf20, altivec_unavailable_exception)
|
1: prepare_transfer_to_handler
|
||||||
|
bl altivec_unavailable_exception
|
||||||
|
b interrupt_return
|
||||||
|
|
||||||
__HEAD
|
__HEAD
|
||||||
PerformanceMonitor:
|
PerformanceMonitor:
|
||||||
EXCEPTION_PROLOG 0xf00 PerformanceMonitor
|
EXCEPTION_PROLOG 0xf00 PerformanceMonitor
|
||||||
EXC_XFER_STD(0xf00, performance_monitor_exception)
|
prepare_transfer_to_handler
|
||||||
|
bl performance_monitor_exception
|
||||||
|
b interrupt_return
|
||||||
|
|
||||||
|
|
||||||
__HEAD
|
__HEAD
|
||||||
|
@ -302,15 +302,18 @@ label:
|
|||||||
#define EXCEPTION(n, intno, label, hdlr, xfer) \
|
#define EXCEPTION(n, intno, label, hdlr, xfer) \
|
||||||
START_EXCEPTION(label); \
|
START_EXCEPTION(label); \
|
||||||
NORMAL_EXCEPTION_PROLOG(n, intno); \
|
NORMAL_EXCEPTION_PROLOG(n, intno); \
|
||||||
xfer(n, hdlr)
|
prepare_transfer_to_handler; \
|
||||||
|
bl hdlr; \
|
||||||
|
b interrupt_return
|
||||||
|
|
||||||
#define CRITICAL_EXCEPTION(n, intno, label, hdlr) \
|
#define CRITICAL_EXCEPTION(n, intno, label, hdlr) \
|
||||||
START_EXCEPTION(label); \
|
START_EXCEPTION(label); \
|
||||||
CRITICAL_EXCEPTION_PROLOG(n, intno); \
|
CRITICAL_EXCEPTION_PROLOG(n, intno); \
|
||||||
SAVE_MMU_REGS; \
|
SAVE_MMU_REGS; \
|
||||||
SAVE_xSRR(SRR); \
|
SAVE_xSRR(SRR); \
|
||||||
EXC_XFER_TEMPLATE(hdlr, n+2, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \
|
prepare_transfer_to_handler; \
|
||||||
crit_transfer_to_handler, ret_from_crit_exc)
|
bl hdlr; \
|
||||||
|
b ret_from_crit_exc
|
||||||
|
|
||||||
#define MCHECK_EXCEPTION(n, label, hdlr) \
|
#define MCHECK_EXCEPTION(n, label, hdlr) \
|
||||||
START_EXCEPTION(label); \
|
START_EXCEPTION(label); \
|
||||||
@ -321,21 +324,9 @@ label:
|
|||||||
SAVE_xSRR(CSRR); \
|
SAVE_xSRR(CSRR); \
|
||||||
SAVE_MMU_REGS; \
|
SAVE_MMU_REGS; \
|
||||||
SAVE_xSRR(SRR); \
|
SAVE_xSRR(SRR); \
|
||||||
EXC_XFER_TEMPLATE(hdlr, n+4, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \
|
prepare_transfer_to_handler; \
|
||||||
mcheck_transfer_to_handler, ret_from_mcheck_exc)
|
|
||||||
|
|
||||||
#define EXC_XFER_TEMPLATE(hdlr, trap, msr, tfer, ret) \
|
|
||||||
bl tfer; \
|
|
||||||
bl hdlr; \
|
bl hdlr; \
|
||||||
b ret; \
|
b ret_from_mcheck_exc
|
||||||
|
|
||||||
#define EXC_XFER_STD(n, hdlr) \
|
|
||||||
EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, transfer_to_handler_full, \
|
|
||||||
ret_from_except_full)
|
|
||||||
|
|
||||||
#define EXC_XFER_LITE(n, hdlr) \
|
|
||||||
EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, transfer_to_handler, \
|
|
||||||
ret_from_except)
|
|
||||||
|
|
||||||
/* Check for a single step debug exception while in an exception
|
/* Check for a single step debug exception while in an exception
|
||||||
* handler before state has been saved. This is to catch the case
|
* handler before state has been saved. This is to catch the case
|
||||||
@ -404,7 +395,9 @@ label:
|
|||||||
SAVE_xSRR(CSRR); \
|
SAVE_xSRR(CSRR); \
|
||||||
SAVE_MMU_REGS; \
|
SAVE_MMU_REGS; \
|
||||||
SAVE_xSRR(SRR); \
|
SAVE_xSRR(SRR); \
|
||||||
EXC_XFER_TEMPLATE(DebugException, 0x2008, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), debug_transfer_to_handler, ret_from_debug_exc)
|
prepare_transfer_to_handler; \
|
||||||
|
bl DebugException; \
|
||||||
|
b ret_from_debug_exc
|
||||||
|
|
||||||
#define DEBUG_CRIT_EXCEPTION \
|
#define DEBUG_CRIT_EXCEPTION \
|
||||||
START_EXCEPTION(DebugCrit); \
|
START_EXCEPTION(DebugCrit); \
|
||||||
@ -459,7 +452,9 @@ label:
|
|||||||
stw r4,_ESR(r11); /* DebugException takes DBSR in _ESR */\
|
stw r4,_ESR(r11); /* DebugException takes DBSR in _ESR */\
|
||||||
SAVE_MMU_REGS; \
|
SAVE_MMU_REGS; \
|
||||||
SAVE_xSRR(SRR); \
|
SAVE_xSRR(SRR); \
|
||||||
EXC_XFER_TEMPLATE(DebugException, 0x2002, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), crit_transfer_to_handler, ret_from_crit_exc)
|
prepare_transfer_to_handler; \
|
||||||
|
bl DebugException; \
|
||||||
|
b ret_from_crit_exc
|
||||||
|
|
||||||
#define DATA_STORAGE_EXCEPTION \
|
#define DATA_STORAGE_EXCEPTION \
|
||||||
START_EXCEPTION(DataStorage) \
|
START_EXCEPTION(DataStorage) \
|
||||||
@ -468,7 +463,9 @@ label:
|
|||||||
stw r5,_ESR(r11); \
|
stw r5,_ESR(r11); \
|
||||||
mfspr r4,SPRN_DEAR; /* Grab the DEAR */ \
|
mfspr r4,SPRN_DEAR; /* Grab the DEAR */ \
|
||||||
stw r4, _DEAR(r11); \
|
stw r4, _DEAR(r11); \
|
||||||
EXC_XFER_LITE(0x0300, do_page_fault)
|
prepare_transfer_to_handler; \
|
||||||
|
bl do_page_fault; \
|
||||||
|
b interrupt_return
|
||||||
|
|
||||||
#define INSTRUCTION_STORAGE_EXCEPTION \
|
#define INSTRUCTION_STORAGE_EXCEPTION \
|
||||||
START_EXCEPTION(InstructionStorage) \
|
START_EXCEPTION(InstructionStorage) \
|
||||||
@ -476,7 +473,9 @@ label:
|
|||||||
mfspr r5,SPRN_ESR; /* Grab the ESR and save it */ \
|
mfspr r5,SPRN_ESR; /* Grab the ESR and save it */ \
|
||||||
stw r5,_ESR(r11); \
|
stw r5,_ESR(r11); \
|
||||||
stw r12, _DEAR(r11); /* Pass SRR0 as arg2 */ \
|
stw r12, _DEAR(r11); /* Pass SRR0 as arg2 */ \
|
||||||
EXC_XFER_LITE(0x0400, do_page_fault)
|
prepare_transfer_to_handler; \
|
||||||
|
bl do_page_fault; \
|
||||||
|
b interrupt_return
|
||||||
|
|
||||||
#define ALIGNMENT_EXCEPTION \
|
#define ALIGNMENT_EXCEPTION \
|
||||||
START_EXCEPTION(Alignment) \
|
START_EXCEPTION(Alignment) \
|
||||||
@ -503,7 +502,9 @@ label:
|
|||||||
NORMAL_EXCEPTION_PROLOG(0x900, DECREMENTER); \
|
NORMAL_EXCEPTION_PROLOG(0x900, DECREMENTER); \
|
||||||
lis r0,TSR_DIS@h; /* Setup the DEC interrupt mask */ \
|
lis r0,TSR_DIS@h; /* Setup the DEC interrupt mask */ \
|
||||||
mtspr SPRN_TSR,r0; /* Clear the DEC interrupt */ \
|
mtspr SPRN_TSR,r0; /* Clear the DEC interrupt */ \
|
||||||
EXC_XFER_LITE(0x0900, timer_interrupt)
|
prepare_transfer_to_handler; \
|
||||||
|
bl timer_interrupt; \
|
||||||
|
b interrupt_return
|
||||||
|
|
||||||
#define FP_UNAVAILABLE_EXCEPTION \
|
#define FP_UNAVAILABLE_EXCEPTION \
|
||||||
START_EXCEPTION(FloatingPointUnavailable) \
|
START_EXCEPTION(FloatingPointUnavailable) \
|
||||||
@ -511,7 +512,9 @@ label:
|
|||||||
beq 1f; \
|
beq 1f; \
|
||||||
bl load_up_fpu; /* if from user, just load it up */ \
|
bl load_up_fpu; /* if from user, just load it up */ \
|
||||||
b fast_exception_return; \
|
b fast_exception_return; \
|
||||||
1: EXC_XFER_STD(0x800, kernel_fp_unavailable_exception)
|
1: prepare_transfer_to_handler; \
|
||||||
|
bl kernel_fp_unavailable_exception; \
|
||||||
|
b interrupt_return
|
||||||
|
|
||||||
#else /* __ASSEMBLY__ */
|
#else /* __ASSEMBLY__ */
|
||||||
struct exception_regs {
|
struct exception_regs {
|
||||||
|
@ -370,9 +370,13 @@ interrupt_base:
|
|||||||
stw r4, _DEAR(r11)
|
stw r4, _DEAR(r11)
|
||||||
andis. r10,r5,(ESR_ILK|ESR_DLK)@h
|
andis. r10,r5,(ESR_ILK|ESR_DLK)@h
|
||||||
bne 1f
|
bne 1f
|
||||||
EXC_XFER_LITE(0x0300, do_page_fault)
|
prepare_transfer_to_handler
|
||||||
|
bl do_page_fault
|
||||||
|
b interrupt_return
|
||||||
1:
|
1:
|
||||||
EXC_XFER_LITE(0x0300, CacheLockingException)
|
prepare_transfer_to_handler
|
||||||
|
bl CacheLockingException
|
||||||
|
b interrupt_return
|
||||||
|
|
||||||
/* Instruction Storage Interrupt */
|
/* Instruction Storage Interrupt */
|
||||||
INSTRUCTION_STORAGE_EXCEPTION
|
INSTRUCTION_STORAGE_EXCEPTION
|
||||||
@ -617,7 +621,9 @@ END_BTB_FLUSH_SECTION
|
|||||||
beq 1f
|
beq 1f
|
||||||
bl load_up_spe
|
bl load_up_spe
|
||||||
b fast_exception_return
|
b fast_exception_return
|
||||||
1: EXC_XFER_LITE(0x2010, KernelSPE)
|
1: prepare_transfer_to_handler
|
||||||
|
bl KernelSPE
|
||||||
|
b interrupt_return
|
||||||
#elif defined(CONFIG_SPE_POSSIBLE)
|
#elif defined(CONFIG_SPE_POSSIBLE)
|
||||||
EXCEPTION(0x2020, SPE_UNAVAIL, SPEUnavailable, \
|
EXCEPTION(0x2020, SPE_UNAVAIL, SPEUnavailable, \
|
||||||
unknown_exception, EXC_XFER_STD)
|
unknown_exception, EXC_XFER_STD)
|
||||||
@ -860,7 +866,7 @@ KernelSPE:
|
|||||||
lwz r5,_NIP(r1)
|
lwz r5,_NIP(r1)
|
||||||
bl printk
|
bl printk
|
||||||
#endif
|
#endif
|
||||||
b ret_from_except
|
b interrupt_return
|
||||||
#ifdef CONFIG_PRINTK
|
#ifdef CONFIG_PRINTK
|
||||||
87: .string "SPE used in kernel (task=%p, pc=%x) \n"
|
87: .string "SPE used in kernel (task=%p, pc=%x) \n"
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user