123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329 |
- ;
- ; Copyright (c) 2006-2022, RT-Thread Development Team
- ;
- ; SPDX-License-Identifier: Apache-2.0
- ;
- ; Change Logs:
- ; Date Author Notes
- ; 2018-09-01 xuzhuoyi the first version.
- ; 2019-06-17 zhaoxiaowei fix bugs of old c28x interrupt api.
- ; 2019-07-03 zhaoxiaowei add _rt_hw_calc_csb function to support __rt_ffs.
- ; 2019-12-05 xiaolifan add support for hardware fpu32
- ;
- .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_calc_csb
- .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
- ;workaround for importing fpu settings from the compiler
- .cdecls C,NOLIST
- %{
- #ifdef __TMS320C28XX_FPU32__
- #define __FPU32__ 1
- #else
- #define __FPU32__ 0
- #endif
- %}
- RT_CTX_SAVE .macro
- PUSH AR1H:AR0H
- PUSH XAR2
- PUSH XAR3
- PUSH XAR4
- PUSH XAR5
- PUSH XAR6
- PUSH XAR7
- PUSH XT
- PUSH RPC
- .if __FPU32__
- PUSH RB
- MOV32 *SP++, STF
- MOV32 *SP++, R0H
- MOV32 *SP++, R1H
- MOV32 *SP++, R2H
- MOV32 *SP++, R3H
- MOV32 *SP++, R4H
- MOV32 *SP++, R5H
- MOV32 *SP++, R6H
- MOV32 *SP++, R7H
- .endif
- .endm
- RT_CTX_RESTORE .macro
- .if __FPU32__
- MOV32 R7H, *--SP, UNCF
- MOV32 R6H, *--SP, UNCF
- MOV32 R5H, *--SP, UNCF
- MOV32 R4H, *--SP, UNCF
- MOV32 R3H, *--SP, UNCF
- MOV32 R2H, *--SP, UNCF
- MOV32 R1H, *--SP, UNCF
- MOV32 R0H, *--SP, UNCF
- MOV32 STF, *--SP
- POP RB
- .endif
- 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:
- PUSH ST1
- SETC INTM,DBGM
- MOV AL, *--SP
- LRETR
- .endasmfunc
- ;
- ; void rt_hw_interrupt_enable(rt_base_t level);
- ;
- .asmfunc
- _rt_hw_interrupt_enable:
- MOV *SP++, AL
- POP ST1
- LRETR
- .endasmfunc
- ;
- ; void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
- ; r0 --> from
- ; r4 --> to
- .asmfunc
- _rt_hw_context_switch_interrupt:
- 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
- LRETR
- .endasmfunc
- ;
- ; void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
- ; r0 --> from
- ; r4 --> to
- .asmfunc
- _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 _reswitch2, EQ
- MOVL XAR6, #1
- MOVL *XAR5, XAR6
- MOVL XAR5, #_rt_interrupt_from_thread ; set rt_interrupt_from_thread
- MOVL *XAR5, XAR0
- _reswitch2:
- 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
- ;#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 AR0, 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
- 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
- ; C28x do not have a build-in "__ffs" func in its C compiler.
- ; We can use the "Count Sign Bits" (CSB) instruction to make one.
- ; CSB will return the number of 0's minus 1 above the highest set bit.
- ; The count is placed in T. For example:
- ; ACC T maxbit
- ; 0x00000001 30 0
- ; 0x00000010 26 4
- ; 0x000001FF 22 8
- ; 0x000001F0 22 8
- .asmfunc
- _rt_hw_calc_csb:
- MOV AH, #0
- CSB ACC ; T = no. of sign bits - 1
- MOVU ACC, T ; ACC = no. of sign bits - 1
- SUBB ACC, #30 ; ACC = ACC - 30
- ABS ACC ; ACC = |ACC|
- 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
|