context.s 4.9 KB
Newer Older
armink_ztl's avatar
armink_ztl 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241
;
; 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