phy62xx_exception: using armv6-m exception_common code.

Signed-off-by: wangbowen6 <wangbowen6@xiaomi.com>
This commit is contained in:
wangbowen6 2022-03-07 14:47:51 +08:00 committed by archer
parent 8f4421a79e
commit 7de7ba1b7e
2 changed files with 43 additions and 363 deletions

View File

@ -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 */

View File

@ -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