summaryrefslogtreecommitdiff
path: root/libcpu/ti-dsp/c28x/context.s
diff options
context:
space:
mode:
Diffstat (limited to 'libcpu/ti-dsp/c28x/context.s')
-rw-r--r--libcpu/ti-dsp/c28x/context.s338
1 files changed, 205 insertions, 133 deletions
diff --git a/libcpu/ti-dsp/c28x/context.s b/libcpu/ti-dsp/c28x/context.s
index 297b3b2119..82207bce1b 100644
--- a/libcpu/ti-dsp/c28x/context.s
+++ b/libcpu/ti-dsp/c28x/context.s
@@ -11,95 +11,57 @@
; 2019-12-05 xiaolifan add support for hardware fpu32
; 2022-06-21 guyunjie trim pendsv (RTOSINT_Handler)
; 2022-08-24 guyunjie fix bugs in context switching
+; 2022-10-15 guyunjie add zero-latency interrupt
- .ref _rt_interrupt_to_thread
- .ref _rt_interrupt_from_thread
- .ref _rt_thread_switch_interrupt_flag
+ .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
+ .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
+ ;importing settings from compiler and config
.cdecls C,NOLIST
%{
+ #include <rtconfig.h>
+
#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
+ #ifdef __TMS320C28XX_FPU64__
+ #define __FPU64__ 1
+ #else
+ #define __FPU64__ 0
+ #endif
- POP AR1H:AR0H
+ #ifdef __TMS320C28XX_VCRC__
+ #define __VCRC__ 1
+ #else
+ #define __VCRC__ 0
+ #endif
- .endm
+ #ifdef RT_USING_ZERO_LATENCY
+ #define ZERO_LATENCY 1
+ #ifndef ZERO_LATENCY_INT_MASK
+ #error ZERO_LATENCY_INT_MASK must be defined for zero latency interrupt
+ #elif ZERO_LATENCY_INT_MASK & 0x8000
+ #error RTOS bit (0x8000) must not be set in ZERO_LATENCY_INT_MASK
+ #endif
+ #else
+ #define ZERO_LATENCY 0
+ #endif
+ %}
.text
@@ -109,10 +71,16 @@ RT_CTX_RESTORE .macro
; rt_base_t rt_hw_interrupt_disable();
;
.asmfunc
-_rt_hw_interrupt_disable:
+rt_hw_interrupt_disable:
+ .if ZERO_LATENCY
+ MOV AL, IER
+ AND IER, #ZERO_LATENCY_INT_MASK
+ .else
PUSH ST1
- SETC INTM,DBGM
- MOV AL, *--SP
+ SETC INTM
+ POP AL
+ .endif
+ MOV AH, #0
LRETR
.endasmfunc
@@ -120,9 +88,13 @@ _rt_hw_interrupt_disable:
; void rt_hw_interrupt_enable(rt_base_t level);
;
.asmfunc
-_rt_hw_interrupt_enable:
- MOV *SP++, AL
+rt_hw_interrupt_enable:
+ .if ZERO_LATENCY
+ MOV IER, AL
+ .else
+ PUSH AL
POP ST1
+ .endif
LRETR
.endasmfunc
@@ -132,23 +104,29 @@ _rt_hw_interrupt_enable:
; SP[4] --> to
;
.asmfunc
-_rt_hw_context_switch_interrupt:
- MOVL XAR0, ACC
+rt_hw_context_switch_interrupt:
+
+; ACC, XAR4-7 are "save on call" following TI C28x C/C++ compiler convention
+; and therefore can be used in a function without being saved on stack first
+; (the compiler has already saved it before the call).
+; Reference: TMS320C28x Optimizing CC++ Compiler
+; note this convention is only applicable to normal functions not to isrs
+
+ MOVL XAR6, ACC
MOVL XAR4, *-SP[4]
; set rt_thread_switch_interrupt_flag to 1
- MOVL XAR5, #_rt_thread_switch_interrupt_flag
+ MOVL XAR5, #rt_thread_switch_interrupt_flag
MOVL ACC, *XAR5
- BF _reswitch, NEQ ; ACC!=0
+ BF reswitch2, NEQ ; ACC!=0
MOVB ACC, #1
MOVL *XAR5, ACC
- MOVL XAR5, #_rt_interrupt_from_thread ; set rt_interrupt_from_thread
- MOVL *XAR5, XAR0
+ MOVL XAR5, #rt_interrupt_from_thread ; set rt_interrupt_from_thread
+ MOVL *XAR5, XAR6
-_reswitch:
- MOVL XAR5, #_rt_interrupt_to_thread ; set rt_interrupt_to_thread
+reswitch2:
+ MOVL XAR5, #rt_interrupt_to_thread ; set rt_interrupt_to_thread
MOVL *XAR5, XAR4
-
LRETR
.endasmfunc
@@ -158,102 +136,196 @@ _reswitch:
; SP[4] --> to
;
.asmfunc
-_rt_hw_context_switch:
- MOVL XAR0, ACC
+rt_hw_context_switch:
+
+ MOVL XAR6, ACC
MOVL XAR4, *-SP[4]
; set rt_thread_switch_interrupt_flag to 1
- MOVL XAR5, #_rt_thread_switch_interrupt_flag
+ MOVL XAR5, #rt_thread_switch_interrupt_flag
MOVL ACC, *XAR5
- BF _reswitch2, NEQ ; ACC!=0
+ BF reswitch1, NEQ ; ACC!=0
MOVB ACC, #1
MOVL *XAR5, ACC
- MOVL XAR5, #_rt_interrupt_from_thread ; set rt_interrupt_from_thread
- MOVL *XAR5, XAR0
+ MOVL XAR5, #rt_interrupt_from_thread ; set rt_interrupt_from_thread
+ MOVL *XAR5, XAR6
-_reswitch2:
- MOVL XAR5, #_rt_interrupt_to_thread ; set rt_interrupt_to_thread
+reswitch1:
+ MOVL XAR5, #rt_interrupt_to_thread ; set rt_interrupt_to_thread
MOVL *XAR5, XAR4
-
- TRAP #16
+ OR IFR, #0x8000
LRETR
.endasmfunc
-
;
; * void rt_hw_context_switch_to(rt_uint32 to);
; * ACC --> to
;
.asmfunc
-_rt_hw_context_switch_to:
+rt_hw_context_switch_to:
; get to thread
- MOVL XAR1, #_rt_interrupt_to_thread
- MOVL *XAR1, ACC
+ MOVL XAR5, #rt_interrupt_to_thread
+ MOVL *XAR5, ACC
; set from thread to 0
- MOVL XAR1, #_rt_interrupt_from_thread
- MOVL XAR0, #0
- MOVL *XAR1, XAR0
+ MOVL XAR5, #rt_interrupt_from_thread
+ MOVL XAR4, #0
+ MOVL *XAR5, XAR4
; set interrupt flag to 1
- MOVL XAR1, #_rt_thread_switch_interrupt_flag
- MOVL XAR0, #1
- MOVL *XAR1, XAR0
+ MOVL XAR5, #rt_thread_switch_interrupt_flag
+ MOVL XAR4, #1
+ MOVL *XAR5, XAR4
- TRAP #16
+ ; trigger rtos interrupt
+ OR IFR, #0x8000
+ OR IER, #0x8000
+ CLRC INTM
; never reach here!
.endasmfunc
.asmfunc
-_RTOSINT_Handler:
- ; disable interrupt to protect context switch
- ; DINT ;this is done by hardware so not needed
+rtosint_handler:
+
+ .if ZERO_LATENCY
+ ; mask out non-critical interrupts and enable global interrupt
+ ; so rtosint_handler won't block critical interrupts
+ AND IER, #ZERO_LATENCY_INT_MASK
+ CLRC INTM
+ .endif
+
+ MOVL ACC, *-SP[4]
+ MOV AR0, AL ; save original IER
+
+ PUSH AR1H:AR0H
+ PUSH XAR2
; get rt_thread_switch_interrupt_flag
- MOVL XAR0, #_rt_thread_switch_interrupt_flag
- MOVL ACC, *XAR0
- BF rtosint_exit, EQ ; pendsv already handled
+ MOVL XAR1, #rt_thread_switch_interrupt_flag
+ MOVL ACC, *XAR1
+ BF rtosint_exit, EQ ; rtos_int already handled
; clear rt_thread_switch_interrupt_flag to 0
- MOVL XAR1, #0
- MOVL *XAR0, XAR1
+ MOVL XAR2, #0
+ MOVL *XAR1, XAR2
- MOVL XAR0, #_rt_interrupt_from_thread
- MOVL ACC, *XAR0
+ MOVL XAR1, #rt_interrupt_from_thread
+ MOVL ACC, *XAR1
BF switch_to_thread, EQ ; skip register save at the first time
- RT_CTX_SAVE ; push cpu registers
+ PUSH XAR3
+ PUSH XAR4
+ PUSH XAR5
+ PUSH XAR6
+ PUSH XAR7
+ PUSH XT
+ PUSH RPC
- MOVL ACC, *XAR0
- MOVL XAR0, ACC
- MOVZ AR1, @SP ; get from thread stack pointer
- MOVL *XAR0, XAR1 ; update from thread stack pointer
+ .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
+
+ .if __FPU64__
+ MOV32 *SP++, R0L
+ MOV32 *SP++, R1L
+ MOV32 *SP++, R2L
+ MOV32 *SP++, R3L
+ MOV32 *SP++, R4L
+ MOV32 *SP++, R5L
+ MOV32 *SP++, R6L
+ MOV32 *SP++, R7L
+ .endif
+
+ .if __VCRC__
+ VMOV32 *SP++, VCRC
+ VMOV32 *SP++, VSTATUS
+ VMOV32 *SP++, VCRCPOLY
+ VMOV32 *SP++, VCRCSIZE
+ .endif
+
+ MOVL ACC, *XAR1
+ MOVL XAR1, ACC
+ MOVZ AR2, @SP ; get from thread stack pointer
+ MOVL *XAR1, XAR2 ; update from thread stack pointer
switch_to_thread:
- MOVL XAR1, #_rt_interrupt_to_thread
+ MOVL XAR1, #rt_interrupt_to_thread
MOVL ACC, *XAR1
MOVL XAR1, ACC
MOVL ACC, *XAR1
MOV @SP, AL ; load thread stack pointer
- RT_CTX_RESTORE ; pop cpu registers
+ .if __VCRC__
+ VMOV32 VCRCSIZE, *--SP
+ VMOV32 VCRCPOLY, *--SP
+ VMOV32 VSTATUS, *--SP
+ VMOV32 VCRC, *--SP
+ .endif
+
+ .if __FPU64__
+ MOV32 R7L, *--SP
+ MOV32 R6L, *--SP
+ MOV32 R5L, *--SP
+ MOV32 R4L, *--SP
+ MOV32 R3L, *--SP
+ MOV32 R2L, *--SP
+ MOV32 R1L, *--SP
+ MOV32 R0L, *--SP
+ .endif
+
+ .if __FPU32__
+ MOV32 R7H, *--SP
+ MOV32 R6H, *--SP
+ MOV32 R5H, *--SP
+ MOV32 R4H, *--SP
+ MOV32 R3H, *--SP
+ MOV32 R2H, *--SP
+ MOV32 R1H, *--SP
+ MOV32 R0H, *--SP
+ MOV32 STF, *--SP
+ POP RB
+ .endif
+
+ POP RPC
+ POP XT
+ POP XAR7
+ POP XAR6
+ POP XAR5
+ POP XAR4
+ POP XAR3
rtosint_exit:
; do not restore interrupt here: to be restored according to the
; switched-to context during IRET (automaticlly by hardware)
+ POP XAR2
+ POP AR1H:AR0H
+
+ MOVL ACC , *-SP[4]
+ MOV AL, AR0
+ MOVL *-SP[4], ACC
+
IRET
.endasmfunc
.asmfunc
-_rt_hw_get_st0:
+rt_hw_get_st0:
PUSH ST0
POP AL
LRETR
.endasmfunc
.asmfunc
-_rt_hw_get_st1:
+rt_hw_get_st1:
PUSH ST1
POP AL
LRETR
@@ -269,18 +341,18 @@ _rt_hw_get_st1:
; 0x000001FF 22 8
; 0x000001F0 22 8
.asmfunc
-_rt_hw_calc_csb:
+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
+ LRETR
.endasmfunc
; compatible with old version
.asmfunc
-_rt_hw_interrupt_thread_switch:
+rt_hw_interrupt_thread_switch:
LRETR
NOP
.endasmfunc