242 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			242 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
;
 | 
						|
; Copyright (c) 2006-2018, RT-Thread Development Team
 | 
						|
;
 | 
						|
; SPDX-License-Identifier: Apache-2.0
 | 
						|
;
 | 
						|
; Change Logs:
 | 
						|
; Date           Author       Notes
 | 
						|
; 2018-09-01     xuzhuoyi     the first version.
 | 
						|
;
 | 
						|
 | 
						|
    .ref   _rt_interrupt_to_thread
 | 
						|
    .ref   _rt_interrupt_from_thread
 | 
						|
    .ref   _rt_thread_switch_interrupt_flag
 | 
						|
 | 
						|
    .def   _RTOSINT_Handler
 | 
						|
    .def   _rt_hw_get_st0
 | 
						|
    .def   _rt_hw_get_st1
 | 
						|
    .def   _rt_hw_context_switch_interrupt
 | 
						|
    .def   _rt_hw_context_switch
 | 
						|
    .def   _rt_hw_context_switch_to
 | 
						|
    .def   _rt_hw_interrupt_thread_switch
 | 
						|
    .def   _rt_hw_interrupt_disable
 | 
						|
    .def   _rt_hw_interrupt_enable
 | 
						|
 | 
						|
 | 
						|
RT_CTX_SAVE  .macro      
 | 
						|
 | 
						|
 | 
						|
    PUSH    AR1H:AR0H
 | 
						|
    PUSH    XAR2
 | 
						|
    PUSH    XAR3
 | 
						|
    PUSH    XAR4
 | 
						|
    PUSH    XAR5
 | 
						|
    PUSH    XAR6
 | 
						|
    PUSH    XAR7
 | 
						|
    PUSH    XT
 | 
						|
    PUSH    RPC
 | 
						|
 | 
						|
 
 | 
						|
    .endm
 | 
						|
 | 
						|
 | 
						|
RT_CTX_RESTORE  .macro
 | 
						|
                                  
 | 
						|
    POP     RPC
 | 
						|
    POP     XT
 | 
						|
    POP     XAR7
 | 
						|
    POP     XAR6
 | 
						|
    POP     XAR5
 | 
						|
    POP     XAR4
 | 
						|
    POP     XAR3
 | 
						|
    POP     XAR2
 | 
						|
 | 
						|
 | 
						|
    MOVZ    AR0 , @SP                                           
 | 
						|
    SUBB    XAR0, #6
 | 
						|
    MOVL    ACC , *XAR0
 | 
						|
    AND     ACC, #0xFFFF << 16
 | 
						|
    MOV     AL, IER
 | 
						|
    MOVL   *XAR0, ACC
 | 
						|
 | 
						|
 | 
						|
    POP     AR1H:AR0H
 | 
						|
 | 
						|
    .endm
 | 
						|
 | 
						|
 | 
						|
.text
 | 
						|
    .newblock
 | 
						|
 | 
						|
;
 | 
						|
; rt_base_t rt_hw_interrupt_disable();
 | 
						|
;
 | 
						|
    .asmfunc
 | 
						|
_rt_hw_interrupt_disable:
 | 
						|
    DINT
 | 
						|
    LRETR
 | 
						|
    .endasmfunc
 | 
						|
 | 
						|
;
 | 
						|
; void rt_hw_interrupt_enable(rt_base_t level);
 | 
						|
;
 | 
						|
    .asmfunc
 | 
						|
_rt_hw_interrupt_enable:
 | 
						|
    EINT
 | 
						|
    LRETR
 | 
						|
    .endasmfunc
 | 
						|
    
 | 
						|
;
 | 
						|
; void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
 | 
						|
; r0 --> from
 | 
						|
; r4 --> to
 | 
						|
 | 
						|
 
 | 
						|
    .asmfunc
 | 
						|
_rt_hw_context_switch_interrupt:
 | 
						|
_rt_hw_context_switch:
 | 
						|
    MOVL    XAR0, #0
 | 
						|
    MOV     AR0, AL
 | 
						|
    MOVL    XAR4, *-SP[4]
 | 
						|
    ; set rt_thread_switch_interrupt_flag to 1 
 | 
						|
    MOVL    XAR5, #_rt_thread_switch_interrupt_flag
 | 
						|
    MOVL    XAR6, *XAR5
 | 
						|
    MOVL    ACC, XAR6
 | 
						|
    CMPB    AL, #1
 | 
						|
    B       _reswitch, EQ
 | 
						|
    MOVL     XAR6, #1
 | 
						|
    MOVL    *XAR5, XAR6
 | 
						|
 | 
						|
    MOVL    XAR5, #_rt_interrupt_from_thread   ; set rt_interrupt_from_thread
 | 
						|
    MOVL    *XAR5, XAR0
 | 
						|
 | 
						|
_reswitch:
 | 
						|
    MOVL    XAR5, #_rt_interrupt_to_thread     ; set rt_interrupt_to_thread
 | 
						|
    MOVL    *XAR5, XAR4
 | 
						|
 | 
						|
    TRAP    #16
 | 
						|
    LRETR
 | 
						|
    .endasmfunc
 | 
						|
     
 | 
						|
     .asmfunc
 | 
						|
_RTOSINT_Handler:
 | 
						|
; disable interrupt to protect context switch 
 | 
						|
    DINT
 | 
						|
 | 
						|
    ; get rt_thread_switch_interrupt_flag 
 | 
						|
    MOV     AR0, #_rt_thread_switch_interrupt_flag
 | 
						|
    MOV     AL, *AR0
 | 
						|
    MOV     AR1, AL
 | 
						|
    CMP     AR1, #0
 | 
						|
    B       rtosint_exit, EQ         ; pendsv already handled 
 | 
						|
 | 
						|
    ; clear rt_thread_switch_interrupt_flag to 0 
 | 
						|
    MOV     AR1, #0x00
 | 
						|
    MOV     *AR0, AR1
 | 
						|
 | 
						|
    MOV     AR0, #_rt_interrupt_from_thread
 | 
						|
    MOV     AL, *AR0
 | 
						|
    MOV     AR1, AL
 | 
						|
    CMP     AR1, #0
 | 
						|
    B       switch_to_thread, EQ    ; skip register save at the first time 
 | 
						|
 | 
						|
    ;MOVZ    AR1, @SP                 ; get from thread stack pointer 
 | 
						|
    
 | 
						|
;#if defined (__VFP_FP__) && !defined(__SOFTFP__)
 | 
						|
;    TST     lr, #0x10           ; if(!EXC_RETURN[4]) 
 | 
						|
;    VSTMDBEQ r1!, {d8 - d15}    ; push FPU register s16~s31 
 | 
						|
;#endif
 | 
						|
    
 | 
						|
    RT_CTX_SAVE     ; 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
 | 
						|
 | 
						|
    MOV     AL, *AR0
 | 
						|
    MOV     AR1, AL
 | 
						|
    MOVZ    AR1, @SP                 ; get from thread stack pointer
 | 
						|
    MOV     *AR0, AR1                ; update from thread stack pointer 
 | 
						|
 | 
						|
switch_to_thread:
 | 
						|
    MOV     AR1, #_rt_interrupt_to_thread
 | 
						|
    MOV     AL, *AR1
 | 
						|
    MOV     AR1, AL
 | 
						|
    MOV     AL, *AR1
 | 
						|
    MOV     AR1, AL                ; load thread stack pointer 
 | 
						|
 | 
						|
;#if defined (__VFP_FP__) && !defined(__SOFTFP__)
 | 
						|
;    LDMFD   r1!, {r3}           ; pop flag 
 | 
						|
;#endif
 | 
						|
 | 
						|
    MOV     @SP, AR1
 | 
						|
    INC     SP
 | 
						|
    RT_CTX_RESTORE     ; pop r4 - r11 register
 | 
						|
 | 
						|
rtosint_exit:
 | 
						|
    ; restore interrupt 
 | 
						|
    EINT
 | 
						|
 | 
						|
    IRET
 | 
						|
    .endasmfunc
 | 
						|
 | 
						|
    .asmfunc
 | 
						|
_rt_hw_get_st0:
 | 
						|
    PUSH    ST0
 | 
						|
    POP     AL
 | 
						|
    LRETR
 | 
						|
    .endasmfunc
 | 
						|
 | 
						|
    .asmfunc
 | 
						|
_rt_hw_get_st1:
 | 
						|
    PUSH    ST1
 | 
						|
    POP     AL
 | 
						|
    LRETR
 | 
						|
    .endasmfunc
 | 
						|
 | 
						|
;
 | 
						|
; * void rt_hw_context_switch_to(rt_uint32 to);
 | 
						|
; * r0 --> to
 | 
						|
 
 | 
						|
    .asmfunc
 | 
						|
_rt_hw_context_switch_to:
 | 
						|
    MOV     AR1, #_rt_interrupt_to_thread
 | 
						|
    MOV     *AR1, AL
 | 
						|
 | 
						|
;#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 
 | 
						|
    MOV     AR1, #_rt_interrupt_from_thread
 | 
						|
    MOV     AR0, #0x0
 | 
						|
    MOV     *AR1, AR0
 | 
						|
 | 
						|
    ; set interrupt flag to 1 
 | 
						|
    MOV     AR1, #_rt_thread_switch_interrupt_flag
 | 
						|
    MOV     AR0, #1
 | 
						|
    MOV     *AR1, AR0
 | 
						|
 | 
						|
    TRAP    #16
 | 
						|
 | 
						|
 | 
						|
    ; never reach here! 
 | 
						|
    .endasmfunc
 | 
						|
    
 | 
						|
; compatible with old version 
 | 
						|
    .asmfunc
 | 
						|
_rt_hw_interrupt_thread_switch:
 | 
						|
    LRETR
 | 
						|
    NOP
 | 
						|
    .endasmfunc
 | 
						|
    
 | 
						|
.end
 |