phy62xx_exception: using armv6-m exception_common code.
Signed-off-by: wangbowen6 <wangbowen6@xiaomi.com>
This commit is contained in:
parent
8f4421a79e
commit
7de7ba1b7e
@ -182,7 +182,7 @@ static inline void phy62xx_clrpend(int irq)
|
||||
****************************************************************************/
|
||||
|
||||
extern void exception_common(void);
|
||||
extern void exception_common_inline(void);
|
||||
extern void exception_origin(void);
|
||||
|
||||
#define svc(code) asm volatile("svc %[immediate]"::[immediate]"I"(code))
|
||||
#define SVC_CALL_WR 0
|
||||
@ -241,46 +241,46 @@ void up_irqinitialize(void)
|
||||
|
||||
/* register jump table irq handler */
|
||||
|
||||
JUMP_FUNCTION(NMI_HANDLER) = (uint32_t)&exception_common_inline;
|
||||
JUMP_FUNCTION(NMI_HANDLER) = (uint32_t)&exception_origin;
|
||||
JUMP_FUNCTION(HARDFAULT_HANDLER) = (uint32_t)&exception_common;
|
||||
JUMP_FUNCTION(SVC_HANDLER) = (uint32_t)&exception_common_inline;
|
||||
JUMP_FUNCTION(PENDSV_HANDLER) = (uint32_t)&exception_common_inline;
|
||||
JUMP_FUNCTION(SYSTICK_HANDLER) = (uint32_t)&exception_common_inline;
|
||||
JUMP_FUNCTION(SVC_HANDLER) = (uint32_t)&exception_origin;
|
||||
JUMP_FUNCTION(PENDSV_HANDLER) = (uint32_t)&exception_origin;
|
||||
JUMP_FUNCTION(SYSTICK_HANDLER) = (uint32_t)&exception_origin;
|
||||
|
||||
/* Vectors 16 - 47 external irq handler */
|
||||
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 0) = (unsigned)&exception_common_inline, /* 16+0 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 1) = (unsigned)&exception_common_inline, /* 16+1 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 2) = (unsigned)&exception_common_inline, /* 16+2 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 3) = (unsigned)&exception_common_inline, /* 16+3 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 4) = (unsigned)&exception_common , /* 16+4 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 5) = (unsigned)&exception_common_inline, /* 16+5 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 6) = (unsigned)&exception_common_inline, /* 16+6 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 7) = (unsigned)&exception_common_inline, /* 16+7 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 8) = (unsigned)&exception_common_inline, /* 16+8 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 9) = (unsigned)&exception_common_inline, /* 16+9 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 10) = (unsigned)&exception_common_inline, /* 16+10 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 11) = (unsigned)&exception_common , /* 16+11 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 12) = (unsigned)&exception_common_inline, /* 16+12 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 13) = (unsigned)&exception_common_inline, /* 16+13 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 14) = (unsigned)&exception_common_inline, /* 16+14 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 15) = (unsigned)&exception_common_inline, /* 16+15 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 16) = (unsigned)&exception_common , /* 16+16 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 17) = (unsigned)&exception_common_inline, /* 16+17 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 18) = (unsigned)&exception_common , /* 16+18 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 19) = (unsigned)&exception_common_inline, /* 16+19 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 20) = (unsigned)&exception_common , /* 16+20 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 21) = (unsigned)&exception_common , /* 16+21 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 22) = (unsigned)&exception_common , /* 16+22 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 23) = (unsigned)&exception_common , /* 16+23 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 24) = (unsigned)&exception_common_inline, /* 16+24 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 25) = (unsigned)&exception_common_inline, /* 16+25 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 26) = (unsigned)&exception_common_inline, /* 16+26 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 27) = (unsigned)&exception_common_inline, /* 16+27 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 28) = (unsigned)&exception_common_inline, /* 16+28 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 29) = (unsigned)&exception_common_inline, /* 16+29 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 30) = (unsigned)&exception_common_inline, /* 16+30 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 31) = (unsigned)&exception_common_inline, /* 16+31 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 0) = (unsigned)&exception_origin, /* 16+0 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 1) = (unsigned)&exception_origin, /* 16+1 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 2) = (unsigned)&exception_origin, /* 16+2 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 3) = (unsigned)&exception_origin, /* 16+3 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 4) = (unsigned)&exception_common, /* 16+4 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 5) = (unsigned)&exception_origin, /* 16+5 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 6) = (unsigned)&exception_origin, /* 16+6 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 7) = (unsigned)&exception_origin, /* 16+7 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 8) = (unsigned)&exception_origin, /* 16+8 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 9) = (unsigned)&exception_origin, /* 16+9 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 10) = (unsigned)&exception_origin, /* 16+10 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 11) = (unsigned)&exception_common, /* 16+11 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 12) = (unsigned)&exception_origin, /* 16+12 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 13) = (unsigned)&exception_origin, /* 16+13 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 14) = (unsigned)&exception_origin, /* 16+14 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 15) = (unsigned)&exception_origin, /* 16+15 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 16) = (unsigned)&exception_common, /* 16+16 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 17) = (unsigned)&exception_origin, /* 16+17 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 18) = (unsigned)&exception_common, /* 16+18 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 19) = (unsigned)&exception_origin, /* 16+19 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 20) = (unsigned)&exception_common, /* 16+20 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 21) = (unsigned)&exception_common, /* 16+21 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 22) = (unsigned)&exception_common, /* 16+22 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 23) = (unsigned)&exception_common, /* 16+23 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 24) = (unsigned)&exception_origin, /* 16+24 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 25) = (unsigned)&exception_origin, /* 16+25 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 26) = (unsigned)&exception_origin, /* 16+26 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 27) = (unsigned)&exception_origin, /* 16+27 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 28) = (unsigned)&exception_origin, /* 16+28 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 29) = (unsigned)&exception_origin, /* 16+29 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 30) = (unsigned)&exception_origin, /* 16+30 */
|
||||
JUMP_FUNCTION(V0_IRQ_HANDLER + 31) = (unsigned)&exception_origin, /* 16+31 */
|
||||
|
||||
/* currents_regs is non-NULL only while processing an interrupt */
|
||||
|
||||
|
@ -13,7 +13,6 @@
|
||||
****************************************************************************/
|
||||
|
||||
.globl exception_common
|
||||
.globl exception_common_inline
|
||||
.file "arm_exception.S"
|
||||
|
||||
/****************************************************************************
|
||||
@ -47,335 +46,16 @@ exception_common:
|
||||
|
||||
/* Complete the context save */
|
||||
|
||||
pop {r4}
|
||||
mrs r1, msp
|
||||
add r1, #4
|
||||
msr msp, r1
|
||||
/* Get the current stack pointer. The EXC_RETURN value tells us whether
|
||||
* the context is on the MSP or PSP.
|
||||
*/
|
||||
mrs r1, msp /* R1=The main stack pointer */
|
||||
pop {r4}
|
||||
pop {r1}
|
||||
|
||||
/* R1 is the current stack pointer. HW_XCPT_REGS were pushed onto the stack
|
||||
* when the interrupt was taken so (R1)+HW_XCPT_SIZE is the value of the
|
||||
* stack pointer before the interrupt. The total size of the context save
|
||||
* area is XCPTCONTEXT_SIZE = SW_XCPT_SIZE + HW_XCPT_SIZE so (R1)-SW_XCPT_SIZE
|
||||
* is the address of the beginning of the context save area.
|
||||
*/
|
||||
/* Jump to exception_origin in arm_exception.S */
|
||||
|
||||
/*stack layout:(*for SP position)*/
|
||||
/*init: *Jump(2W) + Exception(2W)*/
|
||||
/*before doIrq: *SW_XCpt(10W) + Exception(2W) + Jump(2W) + Exception(2W)*/
|
||||
/*after doIrq: *SW_XCpt(10W) + Jump(2W) + Exception(2W)*/
|
||||
/*stack layout:*/
|
||||
|
||||
2:
|
||||
/* Save SP, PRIMASK, and R4-R7 in the context array */
|
||||
sub r1, #SW_XCPT_SIZE /* R1=Beginning of context array on the stack */
|
||||
//sub r1, #XCPTCONTEXT_SIZE //new data should duplicate hw exception stack
|
||||
mov r2, #XCPTCONTEXT_SIZE /* R2=Size of the context array */
|
||||
add r2, r1 /* R2=MSP/PSP before the interrupt was taken */
|
||||
/* (ignoring the xPSR[9] alignment bit) */
|
||||
mrs r3, primask /* R3=Current PRIMASK setting */
|
||||
mov r0, r1 /* Copy the context array pointer */
|
||||
stmia r0!, {r2-r7} /* Save the SP, PRIMASK, and R4-R7 in the context array */
|
||||
|
||||
/* Save R8-R11 and the EXEC_RETURN value in the context array */
|
||||
|
||||
mov r2, r8 /* Copy high registers to low */
|
||||
mov r3, r9
|
||||
mov r4, r10
|
||||
mov r5, r11
|
||||
stmia r0!, {r2-r5} /* Save the high registers r8-r11 */
|
||||
|
||||
/*load hw interrupt stack*/
|
||||
//mov r3, r0
|
||||
//add r3, #40 /*total 10 word, 2 word is for jump table*/
|
||||
//ldmia r3!, {r4-r7} /* Fetch four registers from the HW save area */
|
||||
//stmia r0!, {r4-r7}
|
||||
//ldmia r3!, {r4-r7} /* Fetch four registers from the HW save area */
|
||||
//stmia r0!, {r4-r7}
|
||||
|
||||
/* Get the exception number in R0=IRQ, R1=register save area on stack */
|
||||
|
||||
mrs r0, ipsr /* R0=exception number */
|
||||
|
||||
/* Reserve xcpcontext to ensure that signal processing can have
|
||||
* a separate xcpcontext to handle signal context
|
||||
* (reference: arm_schedulesigaction.c):
|
||||
* ----------------------
|
||||
* | IRQ XCP context |
|
||||
* ----------------------
|
||||
* | Signal XCP context |
|
||||
* ---------------------- <- SP
|
||||
* also the sp should be restore after arm_doirq()
|
||||
*/
|
||||
|
||||
sub r1, r1, #XCPTCONTEXT_SIZE /* Reserve signal context */
|
||||
|
||||
msr msp, r1 /* We are using the main stack pointer */
|
||||
bl arm_doirq /* R0=IRQ, R1=register save area on stack */
|
||||
|
||||
add r1, r1, #XCPTCONTEXT_SIZE /* Restore signal context */
|
||||
|
||||
mrs r1, msp /* Recover R1=main stack pointer */
|
||||
|
||||
/* On return from arm_doirq, R0 will hold a pointer to register context
|
||||
* array to use for the interrupt return. If that return value is the same
|
||||
* as current stack pointer, then things are relatively easy.
|
||||
*/
|
||||
|
||||
cmp r0, r1 /* Context switch? */
|
||||
beq 3f /* Branch if no context switch */
|
||||
|
||||
/* We are returning with a pending context switch. This case is different
|
||||
* because in this case, the register save structure does not lie on the
|
||||
* stack but, rather within a TCB structure. We'll have to copy some
|
||||
* values to the stack.
|
||||
*/
|
||||
|
||||
/* Copy the hardware-saved context to the new stack */
|
||||
|
||||
mov r2, #SW_XCPT_SIZE /* R2=Size of software-saved portion of the context array */
|
||||
add r1, r0, r2 /* R1=Address of HW save area in reg array */
|
||||
//add r1, #8 /* skip dummy */
|
||||
ldr r2, [r0, #(4*REG_SP)] /* R2=Value of SP before the interrupt */
|
||||
//sub r2, #(HW_XCPT_SIZE-8) /* R2=Address of HW save area on the return stack and skip dummy */
|
||||
sub r2, #(HW_XCPT_SIZE) /* R2=Address of HW save area on the return stack and skip dummy */
|
||||
ldmia r1!, {r4-r7} /* Fetch four registers from the HW save area */
|
||||
stmia r2!, {r4-r7} /* Copy four registers to the return stack */
|
||||
ldmia r1!, {r4-r7} /* Fetch four registers from the HW save area */
|
||||
stmia r2!, {r4-r7} /* Copy four registers to the return stack */
|
||||
|
||||
/* Restore the register contents */
|
||||
|
||||
mov r1, r0
|
||||
|
||||
3:
|
||||
/* We are returning with no context switch. We simply need to "unwind"
|
||||
* the same stack frame that we created at entry.
|
||||
*/
|
||||
|
||||
/* Recover R8-R11 and EXEC_RETURN (5 registers) */
|
||||
|
||||
mov r2, #(4*REG_R8) /* R2=Offset to R8 storage */
|
||||
add r0, r1, r2 /* R0=Address of R8 storage */
|
||||
|
||||
ldmia r0!, {r2-r5} /* Recover R8-R11 and R14 (5 registers)*/
|
||||
mov r8, r2 /* Move to position in high registers */
|
||||
mov r9, r3
|
||||
mov r10, r4
|
||||
mov r11, r5
|
||||
|
||||
/* Recover SP (R2), PRIMASK (R3), and R4-R7. Determine the value of
|
||||
* the stack pointer as it was on entry to the exception handler.
|
||||
*/
|
||||
|
||||
ldmia r1!, {r2-r7} /* Recover R4-R7 + 2 temp values */
|
||||
//mov r1, #(HW_XCPT_SIZE-8) /* R1=Size of hardware-saved portion of the context array */
|
||||
mov r1, #HW_XCPT_SIZE /* R1=Size of hardware-saved portion of the context array */
|
||||
sub r1, r2, r1 /* R1=Value of MSP/PSP on exception entry */
|
||||
|
||||
/* Restore the stack pointer. The EXC_RETURN value tells us whether the
|
||||
* context is on the MSP or PSP.
|
||||
*/
|
||||
|
||||
msr msp, r1 /* R1=The main stack pointer */
|
||||
ldr r0, =EXC_RETURN_PRIVTHR /* R0=EXC_RETURN to privileged mode */
|
||||
mov r14, r0 /* R14=EXC_RETURN to privileged mode */
|
||||
|
||||
/* Restore the interrupt state */
|
||||
|
||||
msr primask, r3 /* Restore interrupts priority masking*/
|
||||
|
||||
/* Always return with R14 containing the special value that will: (1)
|
||||
* return to thread mode, and (2) select the correct stack.
|
||||
*/
|
||||
|
||||
bx r14 /* And return */
|
||||
b exception_origin
|
||||
|
||||
.size exception_common, .-exception_common
|
||||
|
||||
/****************************************************************************
|
||||
* Name: g_intstackalloc/g_intstacktop
|
||||
*
|
||||
* Description:
|
||||
* Shouldn't happen
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
.text
|
||||
.align 2
|
||||
.code 16
|
||||
.thumb_func
|
||||
.type exception_common_inline, function
|
||||
exception_common_inline:
|
||||
#define exception_common exception_origin
|
||||
#include "arm_exception.S"
|
||||
|
||||
/* Complete the context save */
|
||||
|
||||
/* Get the current stack pointer. The EXC_RETURN value tells us whether
|
||||
* the context is on the MSP or PSP.
|
||||
*/
|
||||
mrs r1, msp /* R1=The main stack pointer */
|
||||
//sub r1, #8 /* align to normal jumpfunction mode */
|
||||
|
||||
/* R1 is the current stack pointer. HW_XCPT_REGS were pushed onto the stack
|
||||
* when the interrupt was taken so (R1)+HW_XCPT_SIZE is the value of the
|
||||
* stack pointer before the interrupt. The total size of the context save
|
||||
* area is XCPTCONTEXT_SIZE = SW_XCPT_SIZE + HW_XCPT_SIZE so (R1)-SW_XCPT_SIZE
|
||||
* is the address of the beginning of the context save area.
|
||||
*/
|
||||
|
||||
/*stack layout:(*for SP position)*/
|
||||
/*init: *Jump(2W) + Exception(2W)*/
|
||||
/*before doIrq: *SW_XCpt(10W) + Exception(2W) + Jump(2W) + Exception(2W)*/
|
||||
/*after doIrq: *SW_XCpt(10W) + Jump(2W) + Exception(2W)*/
|
||||
/*stack layout:*/
|
||||
|
||||
2:
|
||||
/* Save SP, PRIMASK, and R4-R7 in the context array */
|
||||
sub r1, #SW_XCPT_SIZE /* R1=Beginning of context array on the stack */
|
||||
//sub r1, #XCPTCONTEXT_SIZE //new data should duplicate hw exception stack
|
||||
mov r2, #XCPTCONTEXT_SIZE /* R2=Size of the context array */
|
||||
add r2, r1 /* R2=MSP/PSP before the interrupt was taken */
|
||||
/* (ignoring the xPSR[9] alignment bit) */
|
||||
mrs r3, primask /* R3=Current PRIMASK setting */
|
||||
mov r0, r1 /* Copy the context array pointer */
|
||||
stmia r0!, {r2-r7} /* Save the SP, PRIMASK, and R4-R7 in the context array */
|
||||
|
||||
/* Save R8-R11 and the EXEC_RETURN value in the context array */
|
||||
|
||||
mov r2, r8 /* Copy high registers to low */
|
||||
mov r3, r9
|
||||
mov r4, r10
|
||||
mov r5, r11
|
||||
stmia r0!, {r2-r5} /* Save the high registers r8-r11 */
|
||||
|
||||
/*load hw interrupt stack*/
|
||||
//mov r3, r0
|
||||
//add r3, #40 /*total 10 word, 2 word is for jump table*/
|
||||
//ldmia r3!, {r4-r7} /* Fetch four registers from the HW save area */
|
||||
//stmia r0!, {r4-r7}
|
||||
//ldmia r3!, {r4-r7} /* Fetch four registers from the HW save area */
|
||||
//stmia r0!, {r4-r7}
|
||||
|
||||
/* Get the exception number in R0=IRQ, R1=register save area on stack */
|
||||
|
||||
mrs r0, ipsr /* R0=exception number */
|
||||
|
||||
/* Reserve xcpcontext to ensure that signal processing can have
|
||||
* a separate xcpcontext to handle signal context
|
||||
* (reference: arm_schedulesigaction.c):
|
||||
* ----------------------
|
||||
* | IRQ XCP context |
|
||||
* ----------------------
|
||||
* | Signal XCP context |
|
||||
* ---------------------- <- SP
|
||||
* also the sp should be restore after arm_doirq()
|
||||
*/
|
||||
|
||||
sub r1, r1, #XCPTCONTEXT_SIZE /* Reserve signal context */
|
||||
|
||||
msr msp, r1 /* We are using the main stack pointer */
|
||||
bl arm_doirq /* R0=IRQ, R1=register save area on stack */
|
||||
|
||||
add r1, r1, #XCPTCONTEXT_SIZE /* Restore signal context */
|
||||
|
||||
mrs r1, msp /* Recover R1=main stack pointer */
|
||||
|
||||
/* On return from arm_doirq, R0 will hold a pointer to register context
|
||||
* array to use for the interrupt return. If that return value is the same
|
||||
* as current stack pointer, then things are relatively easy.
|
||||
*/
|
||||
|
||||
cmp r0, r1 /* Context switch? */
|
||||
beq 3f /* Branch if no context switch */
|
||||
|
||||
/* We are returning with a pending context switch. This case is different
|
||||
* because in this case, the register save structure does not lie on the
|
||||
* stack but, rather within a TCB structure. We'll have to copy some
|
||||
* values to the stack.
|
||||
*/
|
||||
|
||||
/* Copy the hardware-saved context to the new stack */
|
||||
|
||||
mov r2, #SW_XCPT_SIZE /* R2=Size of software-saved portion of the context array */
|
||||
add r1, r0, r2 /* R1=Address of HW save area in reg array */
|
||||
//add r1, #8 /* skip dummy */
|
||||
ldr r2, [r0, #(4*REG_SP)] /* R2=Value of SP before the interrupt */
|
||||
//sub r2, #(HW_XCPT_SIZE-8) /* R2=Address of HW save area on the return stack and skip dummy */
|
||||
sub r2, #(HW_XCPT_SIZE) /* R2=Address of HW save area on the return stack and skip dummy */
|
||||
ldmia r1!, {r4-r7} /* Fetch four registers from the HW save area */
|
||||
stmia r2!, {r4-r7} /* Copy four registers to the return stack */
|
||||
ldmia r1!, {r4-r7} /* Fetch four registers from the HW save area */
|
||||
stmia r2!, {r4-r7} /* Copy four registers to the return stack */
|
||||
|
||||
/* Restore the register contents */
|
||||
|
||||
mov r1, r0
|
||||
|
||||
3:
|
||||
/* We are returning with no context switch. We simply need to "unwind"
|
||||
* the same stack frame that we created at entry.
|
||||
*/
|
||||
|
||||
/* Recover R8-R11 and EXEC_RETURN (5 registers) */
|
||||
|
||||
mov r2, #(4*REG_R8) /* R2=Offset to R8 storage */
|
||||
add r0, r1, r2 /* R0=Address of R8 storage */
|
||||
|
||||
ldmia r0!, {r2-r5} /* Recover R8-R11 and R14 (5 registers)*/
|
||||
mov r8, r2 /* Move to position in high registers */
|
||||
mov r9, r3
|
||||
mov r10, r4
|
||||
mov r11, r5
|
||||
|
||||
/* Recover SP (R2), PRIMASK (R3), and R4-R7. Determine the value of
|
||||
* the stack pointer as it was on entry to the exception handler.
|
||||
*/
|
||||
|
||||
ldmia r1!, {r2-r7} /* Recover R4-R7 + 2 temp values */
|
||||
//mov r1, #(HW_XCPT_SIZE-8) /* R1=Size of hardware-saved portion of the context array */
|
||||
mov r1, #(HW_XCPT_SIZE) /* R1=Size of hardware-saved portion of the context array */
|
||||
sub r1, r2, r1 /* R1=Value of MSP/PSP on exception entry */
|
||||
|
||||
/* Restore the stack pointer. The EXC_RETURN value tells us whether the
|
||||
* context is on the MSP or PSP.
|
||||
*/
|
||||
|
||||
msr msp, r1 /* R1=The main stack pointer */
|
||||
ldr r0, =EXC_RETURN_PRIVTHR /* R0=EXC_RETURN to privileged mode */
|
||||
mov r14, r0 /* R14=EXC_RETURN to privileged mode */
|
||||
|
||||
/* Restore the interrupt state */
|
||||
|
||||
msr primask, r3 /* Restore interrupts priority masking*/
|
||||
|
||||
/* Always return with R14 containing the special value that will: (1)
|
||||
* return to thread mode, and (2) select the correct stack.
|
||||
*/
|
||||
|
||||
bx r14 /* And return */
|
||||
|
||||
.size exception_common_inline, .-exception_common_inline
|
||||
|
||||
/****************************************************************************
|
||||
* Name: g_intstackalloc/g_intstacktop
|
||||
*
|
||||
* Description:
|
||||
* Shouldn't happen
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
.bss
|
||||
.global g_intstackalloc
|
||||
.global g_intstacktop
|
||||
.balign 4
|
||||
g_intstackalloc:
|
||||
.skip (CONFIG_ARCH_INTERRUPTSTACK & ~3)
|
||||
g_intstacktop:
|
||||
.size g_intstackalloc, .-g_intstackalloc
|
||||
#endif
|
||||
|
||||
.end
|
||||
|
Loading…
Reference in New Issue
Block a user