123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351 |
- ;
- ; Copyright (c) 2021, Shenzhen Academy of Aerospace Technology
- ;
- ; SPDX-License-Identifier: Apache-2.0
- ;
- ; Change Logs:
- ; Date Author Notes
- ; 2021-11-16 Dystopia the first version
- ;
- ;-----------------------------------------------------------
- ; context switch for C6000 DSP
- ;-----------------------------------------------------------
- .include "contextinc.asm"
- ;-----------------------------------------------------------
- ; macro definition
- ;-----------------------------------------------------------
- DP .set B14
- SP .set B15
- ;
- ;-----------------------------------------------------------
- ;
- ;-----------------------------------------------------------
- ; global variable
- ;-----------------------------------------------------------
- .global rt_interrupt_from_thread
- .global rt_interrupt_to_thread
- .global rt_thread_switch_interrupt_flag
- ;
- ;-----------------------------------------------------------
- ;
- .sect ".text"
- ;-----------------------------------------------------------
- ; void rt_hw_enable_exception(void)
- ;-----------------------------------------------------------
- .global rt_hw_enable_exception
- rt_hw_enable_exception:
- DINT
- MVC .S2 TSR,B0
- MVC .S2 B3,NRP
- MVK .L2 0xC,B1
- OR .D2 B0,B1,B0
- MVC .S2 B0,TSR ; Set GEE and XEN in TSR
- B .S2 NRP
- NOP 5
- ;-----------------------------------------------------------
- ; rt_base_t rt_hw_interrupt_enable(void)
- ;-----------------------------------------------------------
- .global rt_hw_interrupt_disable
- rt_hw_interrupt_disable:
- ;{
- MVC CSR,B4
- MV B4,A4
- AND 1,B4,B0
- [!B0] CLR B4,1,1,B4
- [B0] SET B4,1,1,B4
- CLR B4,0,0,B4
- MVC B4,CSR
- B B3
- NOP 5
- ;}
- ;-----------------------------------------------------------
- ; void rt_hw_interrupt_enable(rt_base_t scr)
- ;-----------------------------------------------------------
- .global rt_hw_interrupt_enable
- rt_hw_interrupt_enable:
- ;{
- MVC A4,CSR
- B B3
- NOP 5
- ;}
- ;-----------------------------------------------------------
- ; rt_uint32_t rt_hw_get_current_dp(void)
- ;-----------------------------------------------------------
- .global rt_hw_get_current_dp
- rt_hw_get_current_dp:
- ;{
- B B3
- MV B14, A4
- NOP 4
- ;}
- ;-----------------------------------------------------------
- ; rt_int32_t __fls(rt_int32_t val)
- ;-----------------------------------------------------------
- .global __fls
- __fls:
- ;{
- B B3
- LMBD .L1 1,A4,A4
- NOP 4
- ;}
- ;-----------------------------------------------------------
- ; rt_int32_t __ffs(rt_int32_t val)
- ;-----------------------------------------------------------
- .global __ffs
- __ffs:
- ;{
- BITR .M1 A4,A4
- B B3
- LMBD .L1 1,A4,A4
- NOP 4
- ;}
- ;
- ;-----------------------------------------------------------
- ;
- ;
- ; void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
- ; A4 --> from
- ; B4 --> to
- ;
- .global rt_hw_context_switch
- rt_hw_context_switch:
- ; {
- SUBAW .D2 SP,2,SP
- ADD .D1X SP,-8,A15
- || STDW .D2T1 A15:A14,*SP--[3] ; Store A15:A14
- STDW .D2T2 B13:B12,*SP--[1] ; Store B13:B12
- || STDW .D1T1 A13:A12,*A15--[1] ; Store A13:A12
- || MV B3,B13
- STDW .D2T2 B11:B10,*SP--[1] ; Store B11:B10
- || STDW .D1T1 A11:A10,*A15--[1] ; Store A11:A10
- || MVC .S2 CSR,B12
- STDW .D2T2 B13:B12,*SP--[1] ; Store PC:CSR
- || MVC .S2 TSR,B5
- MVC .S2 ILC,B11
- MVC .S2 RILC,B10
- STDW .D2T2 B11:B10,*SP--[1] ; Store RILC:ILC
- || MV .S1X B5,A3
- ZERO A2 ;
- STDW .D2T1 A3:A2,*SP--[1] ; Store TSR:stack type
- STW SP,*A4 ; Save thread's stack pointer
- B rt_hw_context_switch_to
- MV B4,A4
- NOP 4
- ;}
- ;
- ; void rt_hw_context_switch_to(rt_uint32 to);
- ; A4 --> to
- ;
- .global rt_hw_context_switch_to
- rt_hw_context_switch_to:
- ;{
- LDW *A4,SP
- NOP 4
- LDDW .D2T2 *++SP[1],B9:B8 ; get TSR (B9) and stack frame type (B8)
- LDDW .D2T2 *++SP[1],B11:B10 ; get RILC (B11) and ILC (B10)
- LDDW .D2T2 *++SP[1],B13:B12 ; get PC (B13) and CSR (B12)
- NOP 2
- MV B8,B0
- [B0] BNOP _rt_thread_interrupt_stack, 5
- ;
- ; this maybe do better
- ;
- LDDW .D2T2 *++SP[1],B11:B10
- || MVC .S2 B11,RILC ; Restore RILC
- LDDW .D2T2 *++SP[1],B13:B12
- || MVC .S2 B10,ILC ; Restore ILC
- LDDW .D2T1 *++SP[1],A11:A10
- || MV B13,B3 ; Restore PC
- LDDW .D2T1 *++SP[1],A13:A12
- || MVC .S2 B12,CSR ; Restore CSR
- LDDW .D2T1 *++SP[1],A15:A14
- B B3 ; Return to caller
- ADDAW .D2 SP,2,SP
- NOP 4 ; Delay slots
- _rt_thread_interrupt_stack:
- ADDAW .D1X SP,30,A15
- LDDW .D1T1 *++A15[1],A17:A16
- || LDDW .D2T2 *++SP[1],B17:B16
- LDDW .D1T1 *++A15[1],A19:A18
- || LDDW .D2T2 *++SP[1],B19:B18
- LDDW .D1T1 *++A15[1],A21:A20
- || LDDW .D2T2 *++SP[1],B21:B20
- LDDW .D1T1 *++A15[1],A23:A22
- || LDDW .D2T2 *++SP[1],B23:B22
- LDDW .D1T1 *++A15[1],A25:A24
- || LDDW .D2T2 *++SP[1],B25:B24
- LDDW .D1T1 *++A15[1],A27:A26
- || LDDW .D2T2 *++SP[1],B27:B26
- LDDW .D1T1 *++A15[1],A29:A28
- || LDDW .D2T2 *++SP[1],B29:B28
- LDDW .D1T1 *++A15[1],A31:A30
- || LDDW .D2T2 *++SP[1],B31:B30
- LDDW .D1T1 *++A15[1],A1:A0
- || LDDW .D2T2 *++SP[1],B1:B0
- LDDW .D1T1 *++A15[1],A3:A2
- || LDDW .D2T2 *++SP[1],B3:B2
- || MVC .S2 B9,ITSR ; Restore ITSR
- LDDW .D1T1 *++A15[1],A5:A4
- || LDDW .D2T2 *++SP[1],B5:B4
- || MVC .S2 B11,RILC ; Restore RILC
- LDDW .D1T1 *++A15[1],A7:A6
- || LDDW .D2T2 *++SP[1],B7:B6
- || MVC .S2 B10,ILC ; Restore ILC
- LDDW .D1T1 *++A15[1],A9:A8
- || LDDW .D2T2 *++SP[1],B9:B8
- || MVC .S2 B13,IRP ; Restore IPR
- LDDW .D1T1 *++A15[1],A11:A10
- || LDDW .D2T2 *++SP[1],B11:B10
- || MVC .S2 B12,CSR ; Restore CSR
- LDDW .D1T1 *++A15[1],A13:A12
- || LDDW .D2T2 *++SP[1],B13:B12
- MV .D2X A15,SP
- LDDW .D2T1 *++SP[1],A15:A14
- B IRP ; Return to point of interrupt
- LDDW .D2T2 *+SP[1],SP:DP
- NOP 4 ; Delay slots
- ;}
- ;
- ;-----------------------------------------------------------
- ;
- ;
- ; void rt_hw_context_switch_interrupt(rt_uint32_t from, rt_uint32_t to)
- ; A4 --> from
- ; B4 --> to
- ;{
- .global rt_hw_context_switch_interrupt
- rt_hw_context_switch_interrupt:
- SUB B15,0x8,B15
- STW B4,*B15[2]
- STW A4,*B15[1]
- LDW *+B14(rt_thread_switch_interrupt_flag),B4
- NOP 4
- CMPEQ 1,B4,B0
- [ B0] BNOP _reswitch,5
- MVK 1,B4
- STW B4,*+B14(rt_thread_switch_interrupt_flag)
- MV A4,B4
- STW B4,*+B14(rt_interrupt_from_thread)
- _reswitch:
- LDW *B15[2],B4
- NOP 4
- STW B4,*+B14(rt_interrupt_to_thread)
- ADD 8,B15,B15
- BNOP B3,5
- ;}
- ;-----------------------------------------------------------
- ;
- ;void rt_interrupt_context_restore(void)
- ;
- .global rt_interrupt_context_restore
- rt_interrupt_context_restore:
- ;{
- MVKL rt_thread_switch_interrupt_flag,A3
- MVKH rt_thread_switch_interrupt_flag,A3
- LDW *A3,A1
- NOP 4
- CMPEQ 1,A1,A2
- [A2] BNOP rt_preempt_context_restore,5
- LDDW .D2T2 *++SP[1],B9:B8 ; get TSR (B9)
- LDDW .D2T2 *++SP[1],B11:B10 ; get RILC (B11) and ILC (B10)
- LDDW .D2T2 *++SP[1],B13:B12 ; get PC (B13) and CSR (B12)
- ADDAW .D1X SP,30,A15
- LDDW .D1T1 *++A15[1],A17:A16
- || LDDW .D2T2 *++SP[1],B17:B16
- LDDW .D1T1 *++A15[1],A19:A18
- || LDDW .D2T2 *++SP[1],B19:B18
- LDDW .D1T1 *++A15[1],A21:A20
- || LDDW .D2T2 *++SP[1],B21:B20
- LDDW .D1T1 *++A15[1],A23:A22
- || LDDW .D2T2 *++SP[1],B23:B22
- LDDW .D1T1 *++A15[1],A25:A24
- || LDDW .D2T2 *++SP[1],B25:B24
- LDDW .D1T1 *++A15[1],A27:A26
- || LDDW .D2T2 *++SP[1],B27:B26
- LDDW .D1T1 *++A15[1],A29:A28
- || LDDW .D2T2 *++SP[1],B29:B28
- LDDW .D1T1 *++A15[1],A31:A30
- || LDDW .D2T2 *++SP[1],B31:B30
- LDDW .D1T1 *++A15[1],A1:A0
- || LDDW .D2T2 *++SP[1],B1:B0
- LDDW .D1T1 *++A15[1],A3:A2
- || LDDW .D2T2 *++SP[1],B3:B2
- || MVC .S2 B9,ITSR
- LDDW .D1T1 *++A15[1],A5:A4
- || LDDW .D2T2 *++SP[1],B5:B4
- || MVC .S2 B11,RILC
- LDDW .D1T1 *++A15[1],A7:A6
- || LDDW .D2T2 *++SP[1],B7:B6
- || MVC .S2 B10,ILC
- LDDW .D1T1 *++A15[1],A9:A8
- || LDDW .D2T2 *++SP[1],B9:B8
- || MVC .S2 B13,IRP
- LDDW .D1T1 *++A15[1],A11:A10
- || LDDW .D2T2 *++SP[1],B11:B10
- || MVC .S2 B12,CSR
- LDDW .D1T1 *++A15[1],A13:A12
- || LDDW .D2T2 *++SP[1],B13:B12
- MV .D2X A15,SP
- || MVKL .S1 rt_system_stack_top,A15
- MVKH .S1 rt_system_stack_top,A15
- || ADDAW .D1X SP,6,A14
- STW .D1T1 A14,*A15 ; save system stack pointer
- LDDW .D2T1 *++SP[1],A15:A14
- B .S2 IRP ; return from interruption
- LDDW .D2T2 *+SP[1],SP:DP
- NOP 4
- rt_preempt_context_restore:
- ZERO A12
- STW A12,*A3 ; clear rt_thread_switch_interrupt_flag
- ;
- ; restore saved registers by system stack
- ;
- RESTORE_ALL IRP,ITSR
- ;
- ; store registers to thread stack
- ;
- THREAD_SAVE_ALL IRP,ITSR
- MVKL rt_interrupt_from_thread,A11
- MVKH rt_interrupt_from_thread,A11
- LDW *A11,A10
- NOP
- MVKL rt_interrupt_to_thread,B10
- MVKH rt_interrupt_to_thread,B10
- LDW *B10,B11
- NOP 3
- STW SP,*A10 ; store sp in preempted tasks's TCB
- B rt_hw_context_switch_to
- MV B11,A4
- NOP 4
- ;}
- .end
|