update libcpu/arm/cortex-m4: support lazy stack optimized.
This commit is contained in:
parent
b045f93b47
commit
34d59ccb0f
|
@ -12,10 +12,11 @@
|
||||||
* 2009-10-11 Bernard first version
|
* 2009-10-11 Bernard first version
|
||||||
* 2012-01-01 aozima support context switch load/store FPU register.
|
* 2012-01-01 aozima support context switch load/store FPU register.
|
||||||
* 2013-06-18 aozima add restore MSP feature.
|
* 2013-06-18 aozima add restore MSP feature.
|
||||||
|
* 2013-06-23 aozima support lazy stack optimized.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @addtogroup STM32
|
* @addtogroup cortex-m4
|
||||||
*/
|
*/
|
||||||
/*@{*/
|
/*@{*/
|
||||||
|
|
||||||
|
@ -108,10 +109,21 @@ PendSV_Handler:
|
||||||
MRS r1, psp /* get from thread stack pointer */
|
MRS r1, psp /* get from thread stack pointer */
|
||||||
|
|
||||||
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
|
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
|
||||||
|
TST lr, #0x10 /* if(!EXC_RETURN[4]) */
|
||||||
VSTMDB r1!, {d8 - d15} /* push FPU register s16~s31 */
|
VSTMDB r1!, {d8 - d15} /* push FPU register s16~s31 */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
STMFD r1!, {r4 - r11} /* push r4 - r11 register */
|
STMFD r1!, {r4 - r11} /* push r4 - r11 register */
|
||||||
|
|
||||||
|
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
|
||||||
|
MOV r4, #0x00 /* flag = 0 */
|
||||||
|
|
||||||
|
TST lr, #0x10 /* if(!EXC_RETURN[4]) */
|
||||||
|
MOVEQ r4, #0x01 /* flag = 1 */
|
||||||
|
|
||||||
|
STMFD r1!, {r4} /* push flag */
|
||||||
|
#endif
|
||||||
|
|
||||||
LDR r0, [r0]
|
LDR r0, [r0]
|
||||||
STR r1, [r0] /* update from thread stack pointer */
|
STR r1, [r0] /* update from thread stack pointer */
|
||||||
|
|
||||||
|
@ -120,10 +132,15 @@ swtich_to_thread:
|
||||||
LDR r1, [r1]
|
LDR r1, [r1]
|
||||||
LDR r1, [r1] /* load thread stack pointer */
|
LDR r1, [r1] /* load thread stack pointer */
|
||||||
|
|
||||||
|
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
|
||||||
|
LDMFD r1!, {r3} /* pop flag */
|
||||||
|
#endif
|
||||||
|
|
||||||
LDMFD r1!, {r4 - r11} /* pop r4 - r11 register */
|
LDMFD r1!, {r4 - r11} /* pop r4 - r11 register */
|
||||||
|
|
||||||
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
|
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
|
||||||
VLDMIA r1!, {d8 - d15} /* pop FPU register s16~s31 */
|
CMP r3, #0 /* if(flag_r3 != 0) */
|
||||||
|
VLDMIANE r1!, {d8 - d15} /* pop FPU register s16~s31 */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
MSR psp, r1 /* update stack pointer */
|
MSR psp, r1 /* update stack pointer */
|
||||||
|
@ -132,6 +149,12 @@ pendsv_exit:
|
||||||
/* restore interrupt */
|
/* restore interrupt */
|
||||||
MSR PRIMASK, r2
|
MSR PRIMASK, r2
|
||||||
|
|
||||||
|
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
|
||||||
|
ORR lr, lr, #0x10 /* lr |= (1 << 4), clean FPCA. */
|
||||||
|
CMP r3, #0 /* if(flag_r3 != 0) */
|
||||||
|
BICNE lr, lr, #0x10 /* lr &= ~(1 << 4), set FPCA. */
|
||||||
|
#endif
|
||||||
|
|
||||||
ORR lr, lr, #0x04
|
ORR lr, lr, #0x04
|
||||||
BX lr
|
BX lr
|
||||||
|
|
||||||
|
@ -145,6 +168,13 @@ rt_hw_context_switch_to:
|
||||||
LDR r1, =rt_interrupt_to_thread
|
LDR r1, =rt_interrupt_to_thread
|
||||||
STR r0, [r1]
|
STR r0, [r1]
|
||||||
|
|
||||||
|
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
|
||||||
|
/* CLEAR CONTROL.FPCA */
|
||||||
|
MRS r2, CONTROL /* read */
|
||||||
|
BIC r2, #0x04 /* modify */
|
||||||
|
MSR CONTROL, r2 /* write-back */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* set from thread to 0 */
|
/* set from thread to 0 */
|
||||||
LDR r1, =rt_interrupt_from_thread
|
LDR r1, =rt_interrupt_from_thread
|
||||||
MOV r0, #0x0
|
MOV r0, #0x0
|
||||||
|
|
|
@ -13,10 +13,11 @@
|
||||||
; * 2009-09-27 Bernard add protect when contex switch occurs
|
; * 2009-09-27 Bernard add protect when contex switch occurs
|
||||||
; * 2012-01-01 aozima support context switch load/store FPU register.
|
; * 2012-01-01 aozima support context switch load/store FPU register.
|
||||||
; * 2013-06-18 aozima add restore MSP feature.
|
; * 2013-06-18 aozima add restore MSP feature.
|
||||||
|
; * 2013-06-23 aozima support lazy stack optimized.
|
||||||
; */
|
; */
|
||||||
|
|
||||||
;/**
|
;/**
|
||||||
; * @addtogroup STM32
|
; * @addtogroup cortex-m4
|
||||||
; */
|
; */
|
||||||
;/*@{*/
|
;/*@{*/
|
||||||
|
|
||||||
|
@ -107,10 +108,25 @@ PendSV_Handler:
|
||||||
MRS r1, psp ; get from thread stack pointer
|
MRS r1, psp ; get from thread stack pointer
|
||||||
|
|
||||||
#if defined ( __ARMVFP__ )
|
#if defined ( __ARMVFP__ )
|
||||||
|
TST lr, #0x10 ; if(!EXC_RETURN[4])
|
||||||
|
BNE skip_push_fpu
|
||||||
VSTMDB r1!, {d8 - d15} ; push FPU register s16~s31
|
VSTMDB r1!, {d8 - d15} ; push FPU register s16~s31
|
||||||
|
skip_push_fpu
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
STMFD r1!, {r4 - r11} ; push r4 - r11 register
|
STMFD r1!, {r4 - r11} ; push r4 - r11 register
|
||||||
|
|
||||||
|
#if defined ( __ARMVFP__ )
|
||||||
|
MOV r4, #0x00 ; flag = 0
|
||||||
|
TST lr, #0x10 ; if(!EXC_RETURN[4])
|
||||||
|
BNE push_flag
|
||||||
|
MOV r4, #0x01 ; flag = 1
|
||||||
|
push_flag
|
||||||
|
;STMFD r1!, {r4} ; push flag
|
||||||
|
SUB r1, r1, #0x04
|
||||||
|
STR r4, [r1]
|
||||||
|
#endif
|
||||||
|
|
||||||
LDR r0, [r0]
|
LDR r0, [r0]
|
||||||
STR r1, [r0] ; update from thread stack pointer
|
STR r1, [r0] ; update from thread stack pointer
|
||||||
|
|
||||||
|
@ -119,10 +135,16 @@ swtich_to_thread
|
||||||
LDR r1, [r1]
|
LDR r1, [r1]
|
||||||
LDR r1, [r1] ; load thread stack pointer
|
LDR r1, [r1] ; load thread stack pointer
|
||||||
|
|
||||||
|
#if defined ( __ARMVFP__ )
|
||||||
|
LDMFD r1!, {r3} ; pop flag
|
||||||
|
#endif
|
||||||
|
|
||||||
LDMFD r1!, {r4 - r11} ; pop r4 - r11 register
|
LDMFD r1!, {r4 - r11} ; pop r4 - r11 register
|
||||||
|
|
||||||
#if defined ( __ARMVFP__ )
|
#if defined ( __ARMVFP__ )
|
||||||
|
CBZ r3, skip_pop_fpu
|
||||||
VLDMIA r1!, {d8 - d15} ; pop FPU register s16~s31
|
VLDMIA r1!, {d8 - d15} ; pop FPU register s16~s31
|
||||||
|
skip_pop_fpu
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
MSR psp, r1 ; update stack pointer
|
MSR psp, r1 ; update stack pointer
|
||||||
|
@ -131,6 +153,13 @@ pendsv_exit
|
||||||
; restore interrupt
|
; restore interrupt
|
||||||
MSR PRIMASK, r2
|
MSR PRIMASK, r2
|
||||||
|
|
||||||
|
#if defined ( __ARMVFP__ )
|
||||||
|
ORR lr, lr, #0x10 ; lr |= (1 << 4), clean FPCA.
|
||||||
|
CBZ r3, return_without_fpu ; if(flag_r3 != 0)
|
||||||
|
BIC lr, lr, #0x10 ; lr &= ~(1 << 4), set FPCA.
|
||||||
|
return_without_fpu
|
||||||
|
#endif
|
||||||
|
|
||||||
ORR lr, lr, #0x04
|
ORR lr, lr, #0x04
|
||||||
BX lr
|
BX lr
|
||||||
|
|
||||||
|
@ -143,6 +172,13 @@ rt_hw_context_switch_to:
|
||||||
LDR r1, =rt_interrupt_to_thread
|
LDR r1, =rt_interrupt_to_thread
|
||||||
STR r0, [r1]
|
STR r0, [r1]
|
||||||
|
|
||||||
|
#if defined ( __ARMVFP__ )
|
||||||
|
; CLEAR CONTROL.FPCA
|
||||||
|
MRS r2, CONTROL ; read
|
||||||
|
BIC r2, r2, #0x04 ; modify
|
||||||
|
MSR CONTROL, r2 ; write-back
|
||||||
|
#endif
|
||||||
|
|
||||||
; set from thread to 0
|
; set from thread to 0
|
||||||
LDR r1, =rt_interrupt_from_thread
|
LDR r1, =rt_interrupt_from_thread
|
||||||
MOV r0, #0x0
|
MOV r0, #0x0
|
||||||
|
|
|
@ -12,10 +12,11 @@
|
||||||
; * 2009-01-17 Bernard first version.
|
; * 2009-01-17 Bernard first version.
|
||||||
; * 2012-01-01 aozima support context switch load/store FPU register.
|
; * 2012-01-01 aozima support context switch load/store FPU register.
|
||||||
; * 2013-06-18 aozima add restore MSP feature.
|
; * 2013-06-18 aozima add restore MSP feature.
|
||||||
|
; * 2013-06-23 aozima support lazy stack optimized.
|
||||||
; */
|
; */
|
||||||
|
|
||||||
;/**
|
;/**
|
||||||
; * @addtogroup STM32
|
; * @addtogroup cortex-m4
|
||||||
; */
|
; */
|
||||||
;/*@{*/
|
;/*@{*/
|
||||||
|
|
||||||
|
@ -110,10 +111,21 @@ PendSV_Handler PROC
|
||||||
MRS r1, psp ; get from thread stack pointer
|
MRS r1, psp ; get from thread stack pointer
|
||||||
|
|
||||||
IF {FPU} != "SoftVFP"
|
IF {FPU} != "SoftVFP"
|
||||||
VSTMFD r1!, {d8 - d15} ; push FPU register s16~s31
|
TST lr, #0x10 ; if(!EXC_RETURN[4])
|
||||||
|
VSTMFDEQ r1!, {d8 - d15} ; push FPU register s16~s31
|
||||||
ENDIF
|
ENDIF
|
||||||
|
|
||||||
STMFD r1!, {r4 - r11} ; push r4 - r11 register
|
STMFD r1!, {r4 - r11} ; push r4 - r11 register
|
||||||
|
|
||||||
|
IF {FPU} != "SoftVFP"
|
||||||
|
MOV r4, #0x00 ; flag = 0
|
||||||
|
|
||||||
|
TST lr, #0x10 ; if(!EXC_RETURN[4])
|
||||||
|
MOVEQ r4, #0x01 ; flag = 1
|
||||||
|
|
||||||
|
STMFD r1!, {r4} ; push flag
|
||||||
|
ENDIF
|
||||||
|
|
||||||
LDR r0, [r0]
|
LDR r0, [r0]
|
||||||
STR r1, [r0] ; update from thread stack pointer
|
STR r1, [r0] ; update from thread stack pointer
|
||||||
|
|
||||||
|
@ -122,10 +134,15 @@ swtich_to_thread
|
||||||
LDR r1, [r1]
|
LDR r1, [r1]
|
||||||
LDR r1, [r1] ; load thread stack pointer
|
LDR r1, [r1] ; load thread stack pointer
|
||||||
|
|
||||||
|
IF {FPU} != "SoftVFP"
|
||||||
|
LDMFD r1!, {r3} ; pop flag
|
||||||
|
ENDIF
|
||||||
|
|
||||||
LDMFD r1!, {r4 - r11} ; pop r4 - r11 register
|
LDMFD r1!, {r4 - r11} ; pop r4 - r11 register
|
||||||
|
|
||||||
IF {FPU} != "SoftVFP"
|
IF {FPU} != "SoftVFP"
|
||||||
VLDMFD r1!, {d8 - d15} ; pop FPU register s16~s31
|
CMP r3, #0 ; if(flag_r3 != 0)
|
||||||
|
VLDMFDNE r1!, {d8 - d15} ; pop FPU register s16~s31
|
||||||
ENDIF
|
ENDIF
|
||||||
|
|
||||||
MSR psp, r1 ; update stack pointer
|
MSR psp, r1 ; update stack pointer
|
||||||
|
@ -134,6 +151,12 @@ pendsv_exit
|
||||||
; restore interrupt
|
; restore interrupt
|
||||||
MSR PRIMASK, r2
|
MSR PRIMASK, r2
|
||||||
|
|
||||||
|
IF {FPU} != "SoftVFP"
|
||||||
|
ORR lr, lr, #0x10 ; lr |= (1 << 4), clean FPCA.
|
||||||
|
CMP r3, #0 ; if(flag_r3 != 0)
|
||||||
|
BICNE lr, lr, #0x10 ; lr &= ~(1 << 4), set FPCA.
|
||||||
|
ENDIF
|
||||||
|
|
||||||
ORR lr, lr, #0x04
|
ORR lr, lr, #0x04
|
||||||
BX lr
|
BX lr
|
||||||
ENDP
|
ENDP
|
||||||
|
@ -149,6 +172,13 @@ rt_hw_context_switch_to PROC
|
||||||
LDR r1, =rt_interrupt_to_thread
|
LDR r1, =rt_interrupt_to_thread
|
||||||
STR r0, [r1]
|
STR r0, [r1]
|
||||||
|
|
||||||
|
IF {FPU} != "SoftVFP"
|
||||||
|
; CLEAR CONTROL.FPCA
|
||||||
|
MRS r2, CONTROL ; read
|
||||||
|
BIC r2, #0x04 ; modify
|
||||||
|
MSR CONTROL, r2 ; write-back
|
||||||
|
ENDIF
|
||||||
|
|
||||||
; set from thread to 0
|
; set from thread to 0
|
||||||
LDR r1, =rt_interrupt_from_thread
|
LDR r1, =rt_interrupt_from_thread
|
||||||
MOV r0, #0x0
|
MOV r0, #0x0
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
* 2012-12-11 lgnq fixed the coding style.
|
* 2012-12-11 lgnq fixed the coding style.
|
||||||
* 2012-12-23 aozima stack addr align to 8byte.
|
* 2012-12-23 aozima stack addr align to 8byte.
|
||||||
* 2012-12-29 Bernard Add exception hook.
|
* 2012-12-29 Bernard Add exception hook.
|
||||||
|
* 2013-06-23 aozima support lazy stack optimized.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <rtthread.h>
|
#include <rtthread.h>
|
||||||
|
@ -32,6 +33,37 @@ rt_uint32_t rt_thread_switch_interrupt_flag;
|
||||||
static rt_err_t (*rt_exception_hook)(void *context) = RT_NULL;
|
static rt_err_t (*rt_exception_hook)(void *context) = RT_NULL;
|
||||||
|
|
||||||
struct exception_stack_frame
|
struct exception_stack_frame
|
||||||
|
{
|
||||||
|
rt_uint32_t r0;
|
||||||
|
rt_uint32_t r1;
|
||||||
|
rt_uint32_t r2;
|
||||||
|
rt_uint32_t r3;
|
||||||
|
rt_uint32_t r12;
|
||||||
|
rt_uint32_t lr;
|
||||||
|
rt_uint32_t pc;
|
||||||
|
rt_uint32_t psr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct stack_frame
|
||||||
|
{
|
||||||
|
#if USE_FPU
|
||||||
|
rt_uint32_t flag;
|
||||||
|
#endif /* USE_FPU */
|
||||||
|
|
||||||
|
/* r4 ~ r11 register */
|
||||||
|
rt_uint32_t r4;
|
||||||
|
rt_uint32_t r5;
|
||||||
|
rt_uint32_t r6;
|
||||||
|
rt_uint32_t r7;
|
||||||
|
rt_uint32_t r8;
|
||||||
|
rt_uint32_t r9;
|
||||||
|
rt_uint32_t r10;
|
||||||
|
rt_uint32_t r11;
|
||||||
|
|
||||||
|
struct exception_stack_frame exception_stack_frame;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct exception_stack_frame_fpu
|
||||||
{
|
{
|
||||||
rt_uint32_t r0;
|
rt_uint32_t r0;
|
||||||
rt_uint32_t r1;
|
rt_uint32_t r1;
|
||||||
|
@ -65,8 +97,10 @@ struct exception_stack_frame
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct stack_frame
|
struct stack_frame_fpu
|
||||||
{
|
{
|
||||||
|
rt_uint32_t flag;
|
||||||
|
|
||||||
/* r4 ~ r11 register */
|
/* r4 ~ r11 register */
|
||||||
rt_uint32_t r4;
|
rt_uint32_t r4;
|
||||||
rt_uint32_t r5;
|
rt_uint32_t r5;
|
||||||
|
@ -97,7 +131,7 @@ struct stack_frame
|
||||||
rt_uint32_t s31;
|
rt_uint32_t s31;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct exception_stack_frame exception_stack_frame;
|
struct exception_stack_frame_fpu exception_stack_frame;
|
||||||
};
|
};
|
||||||
|
|
||||||
rt_uint8_t *rt_hw_stack_init(void *tentry,
|
rt_uint8_t *rt_hw_stack_init(void *tentry,
|
||||||
|
@ -130,6 +164,10 @@ rt_uint8_t *rt_hw_stack_init(void *tentry,
|
||||||
stack_frame->exception_stack_frame.pc = (unsigned long)tentry; /* entry point, pc */
|
stack_frame->exception_stack_frame.pc = (unsigned long)tentry; /* entry point, pc */
|
||||||
stack_frame->exception_stack_frame.psr = 0x01000000L; /* PSR */
|
stack_frame->exception_stack_frame.psr = 0x01000000L; /* PSR */
|
||||||
|
|
||||||
|
#if USE_FPU
|
||||||
|
stack_frame->flag = 0;
|
||||||
|
#endif /* USE_FPU */
|
||||||
|
|
||||||
/* return task's current stack address */
|
/* return task's current stack address */
|
||||||
return stk;
|
return stk;
|
||||||
}
|
}
|
||||||
|
@ -141,20 +179,20 @@ rt_uint8_t *rt_hw_stack_init(void *tentry,
|
||||||
*/
|
*/
|
||||||
void rt_hw_exception_install(rt_err_t (*exception_handle)(void* context))
|
void rt_hw_exception_install(rt_err_t (*exception_handle)(void* context))
|
||||||
{
|
{
|
||||||
rt_exception_hook = exception_handle;
|
rt_exception_hook = exception_handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rt_hw_hard_fault_exception(struct exception_stack_frame *exception_stack)
|
void rt_hw_hard_fault_exception(struct exception_stack_frame *exception_stack)
|
||||||
{
|
{
|
||||||
extern long list_thread(void);
|
extern long list_thread(void);
|
||||||
|
|
||||||
if (rt_exception_hook != RT_NULL)
|
if (rt_exception_hook != RT_NULL)
|
||||||
{
|
{
|
||||||
rt_err_t result;
|
rt_err_t result;
|
||||||
|
|
||||||
result = rt_exception_hook(exception_stack);
|
result = rt_exception_hook(exception_stack);
|
||||||
if (result == RT_EOK) return;
|
if (result == RT_EOK) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
rt_kprintf("psr: 0x%08x\n", exception_stack->psr);
|
rt_kprintf("psr: 0x%08x\n", exception_stack->psr);
|
||||||
rt_kprintf(" pc: 0x%08x\n", exception_stack->pc);
|
rt_kprintf(" pc: 0x%08x\n", exception_stack->pc);
|
||||||
|
|
Loading…
Reference in New Issue