diff options
| author | Man, Jianting (Meco) <[email protected]> | 2022-01-28 13:50:04 -0500 |
|---|---|---|
| committer | Bernard Xiong <[email protected]> | 2022-01-29 16:11:42 +0800 |
| commit | 71ba65e7c0fdb388aa35e019fefbbb5672d39d0a (patch) | |
| tree | ece3a5249598a0cff37ba322dd1810e93cc52544 /libcpu | |
| parent | 909b464e783a74d1cb6c178af86d033c3d228cf0 (diff) | |
add new bsp tms320c6678
原始提交PR:https://gitee.com/rtthread/rt-thread/pulls/372
提交者:https://gitee.com/wei-handong
----------------------
在TI公司C6000 DSP处理器上成功移植rt-thread操作系统;主要在libcpu/ti-dsp/c6x添加keystone架构底层代码,在bsp/ti-c6678添加bsp工程,该工程已在本人的开发板上成功运行
* 添加TMS320C6678处理器,keystone架构底层代码
* 添加支持中断栈部分代码,修改格式
* 修改汇编rt_hw_context_switch_to处关于时间槽的使用;修改格式
* 修改使用C语言构建任务栈帧,清除fls和ffs对<c6x.h>文件的依赖
* 修改bsp tms320c6678工程,并测试
* 删除依赖TI的KeyStone_common.c文件
* 添加编译说明
* update bsp/ti-tms320c6678/README.md.
* format code
Co-authored-by: Huang bo <[email protected]>
Co-authored-by: hdwei <[email protected]>
Co-authored-by: bernard <[email protected]>
Co-authored-by: rtthread-bot <[email protected]>
Co-authored-by: Meco Man <[email protected]>
Diffstat (limited to 'libcpu')
| -rw-r--r-- | libcpu/ti-dsp/c28x/cpuport.c | 2 | ||||
| -rw-r--r-- | libcpu/ti-dsp/c6x/SConscript | 14 | ||||
| -rw-r--r-- | libcpu/ti-dsp/c6x/c66xx.h | 98 | ||||
| -rw-r--r-- | libcpu/ti-dsp/c6x/context.asm | 351 | ||||
| -rw-r--r-- | libcpu/ti-dsp/c6x/contextinc.asm | 192 | ||||
| -rw-r--r-- | libcpu/ti-dsp/c6x/cpuport.c | 196 | ||||
| -rw-r--r-- | libcpu/ti-dsp/c6x/interrupt.c | 104 | ||||
| -rw-r--r-- | libcpu/ti-dsp/c6x/interrupt.h | 24 | ||||
| -rw-r--r-- | libcpu/ti-dsp/c6x/intexc.asm | 263 | ||||
| -rw-r--r-- | libcpu/ti-dsp/c6x/stack.c | 120 | ||||
| -rw-r--r-- | libcpu/ti-dsp/c6x/trap.c | 367 | ||||
| -rw-r--r-- | libcpu/ti-dsp/c6x/trap.h | 117 | ||||
| -rw-r--r-- | libcpu/ti-dsp/c6x/vector.asm | 95 |
13 files changed, 1942 insertions, 1 deletions
diff --git a/libcpu/ti-dsp/c28x/cpuport.c b/libcpu/ti-dsp/c28x/cpuport.c index 44876a5af5..8903ea0a40 100644 --- a/libcpu/ti-dsp/c28x/cpuport.c +++ b/libcpu/ti-dsp/c28x/cpuport.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2021, RT-Thread Development Team + * Copyright (c) 2006-2022, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * diff --git a/libcpu/ti-dsp/c6x/SConscript b/libcpu/ti-dsp/c6x/SConscript new file mode 100644 index 0000000000..0fe94fd9a6 --- /dev/null +++ b/libcpu/ti-dsp/c6x/SConscript @@ -0,0 +1,14 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') + Glob('*.asm') +CPPPATH = [cwd] +ASFLAGS = '' + +group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) + +Return('group') diff --git a/libcpu/ti-dsp/c6x/c66xx.h b/libcpu/ti-dsp/c6x/c66xx.h new file mode 100644 index 0000000000..6ec7d1995e --- /dev/null +++ b/libcpu/ti-dsp/c6x/c66xx.h @@ -0,0 +1,98 @@ +/* + * 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 + */ + +#ifndef __C66XX_H__ +#define __C66XX_H__ + +extern __cregister volatile unsigned int IERR; /* Internal Exception Report Register */ +extern __cregister volatile unsigned int ECR; /* Exception Clear Register */ +extern __cregister volatile unsigned int EFR; /* Exception Flag Register */ +extern __cregister volatile unsigned int TSR; /* Task State Register */ +extern __cregister volatile unsigned int ITSR; /* Interrupt Task State Register */ +extern __cregister volatile unsigned int NTSR; /* NMI/exception Task State Register */ +extern __cregister volatile unsigned int TSCL; /* Time Stamp Counter Register - Low Half */ +extern __cregister volatile unsigned int TSCH; /* Time Stamp Counter Register - High Half */ +extern __cregister volatile unsigned int DNUM; /* Core number */ + +extern __cregister volatile unsigned int AMR; +extern __cregister volatile unsigned int CSR; +extern __cregister volatile unsigned int IFR; +extern __cregister volatile unsigned int ISR; +extern __cregister volatile unsigned int ICR; +extern __cregister volatile unsigned int IER; +extern __cregister volatile unsigned int ISTP; +extern __cregister volatile unsigned int IRP; +extern __cregister volatile unsigned int NRP; + +#ifdef _BIG_ENDIAN +#define RT_REG_PAIR(odd, even) unsigned long odd; unsigned long even +#else +#define RT_REG_PAIR(odd, even) unsigned long even; unsigned long odd +#endif + +struct rt_hw_register +{ + RT_REG_PAIR(b17, b16); + RT_REG_PAIR(b19, b18); + RT_REG_PAIR(b21, b20); + RT_REG_PAIR(b23, b22); + RT_REG_PAIR(b25, b24); + RT_REG_PAIR(b27, b26); + RT_REG_PAIR(b29, b28); + RT_REG_PAIR(b31, b30); + + RT_REG_PAIR(b1, b0); + RT_REG_PAIR(b3, b2); + RT_REG_PAIR(b5, b4); + RT_REG_PAIR(b7, b6); + RT_REG_PAIR(b9, b8); + RT_REG_PAIR(b11, b10); + RT_REG_PAIR(b13, b12); + + RT_REG_PAIR(a17, a16); + RT_REG_PAIR(a19, a18); + RT_REG_PAIR(a21, a20); + RT_REG_PAIR(a23, a22); + RT_REG_PAIR(a25, a24); + RT_REG_PAIR(a27, a26); + RT_REG_PAIR(a29, a28); + RT_REG_PAIR(a31, a30); + + RT_REG_PAIR(a1, a0); + RT_REG_PAIR(a3, a2); + RT_REG_PAIR(a5, a4); + RT_REG_PAIR(a7, a6); + RT_REG_PAIR(a9, a8); + RT_REG_PAIR(a11, a10); + RT_REG_PAIR(a13, a12); + + RT_REG_PAIR(a15, a14); + RT_REG_PAIR(sp, dp); +}; + +typedef struct rt_hw_exp_stack_register +{ + RT_REG_PAIR(tsr, orig_a4); + RT_REG_PAIR(rilc, ilc); + RT_REG_PAIR(pc, csr); + struct rt_hw_register hw_register; +} rt_hw_thread_stack_register; + +#define __dint() asm(" DINT") +#define __rint() asm(" RINT") +#define __system_call() asm(" SWE") +#define __enter_idle() asm(" IDLE") +#define __nop() asm(" NOP") +#define __mfence() asm(" MFENCE") + +#define __SYSREG(ADDR, TYPE) (*(volatile TYPE*)(ADDR)) +#define __SYSREGA(ADDR, TYPE) ((volatile TYPE*)(ADDR)) + +#endif /* __C66XX_H__ */ diff --git a/libcpu/ti-dsp/c6x/context.asm b/libcpu/ti-dsp/c6x/context.asm new file mode 100644 index 0000000000..1a73ec6590 --- /dev/null +++ b/libcpu/ti-dsp/c6x/context.asm @@ -0,0 +1,351 @@ +; +; 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 diff --git a/libcpu/ti-dsp/c6x/contextinc.asm b/libcpu/ti-dsp/c6x/contextinc.asm new file mode 100644 index 0000000000..74a830f883 --- /dev/null +++ b/libcpu/ti-dsp/c6x/contextinc.asm @@ -0,0 +1,192 @@ +; +; 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 +; + +;----------------------------------------------------------- +; extern variable +;----------------------------------------------------------- + .ref rt_system_stack_top + +;----------------------------------------------------------- +; macro definition +;----------------------------------------------------------- +SAVE_ALL .macro __rp, __tsr + STW .D2T2 B0,*SP--[2] ; save original B0 + MVKL .S2 rt_system_stack_top,B0 + MVKH .S2 rt_system_stack_top,B0 + LDW .D2T2 *B0,B1 ; system stack + + NOP 3 + STW .D2T2 B1,*+SP[1] ; save original B1 + XOR .D2 SP,B1,B0 ; check current stack types + LDW .D2T2 *+SP[1],B1 ; restore B0/B1 + LDW .D2T2 *++SP[2],B0 + SHR .S2 B0,12,B0 ; 0 if already using system stack + [B0] STDW .D2T2 SP:DP,*--B1[1] ; thread: save thread sp/dp system stack + [B0] MV .S2 B1,SP ; and switch to system stack +||[!B0] STDW .D2T2 SP:DP,*--SP[1] ; kernel: nest interrupt save(not support) + + SUBAW .D2 SP,2,SP + + ADD .D1X SP,-8,A15 + || STDW .D2T1 A15:A14,*SP--[16] ; save A15:A14 + + STDW .D2T2 B13:B12,*SP--[1] + || STDW .D1T1 A13:A12,*A15--[1] + || MVC .S2 __rp,B13 + STDW .D2T2 B11:B10,*SP--[1] + || STDW .D1T1 A11:A10,*A15--[1] + || MVC .S2 CSR,B12 + + STDW .D2T2 B9:B8,*SP--[1] + || STDW .D1T1 A9:A8,*A15--[1] + || MVC .S2 RILC,B11 + STDW .D2T2 B7:B6,*SP--[1] + || STDW .D1T1 A7:A6,*A15--[1] + || MVC .S2 ILC,B10 + STDW .D2T2 B5:B4,*SP--[1] + || STDW .D1T1 A5:A4,*A15--[1] + STDW .D2T2 B3:B2,*SP--[1] + || STDW .D1T1 A3:A2,*A15--[1] + || MVC .S2 __tsr,B5 + STDW .D2T2 B1:B0,*SP--[1] + || STDW .D1T1 A1:A0,*A15--[1] + || MV .S1X B5,A5 + + STDW .D2T2 B31:B30,*SP--[1] + || STDW .D1T1 A31:A30,*A15--[1] + || MVKL 1,A4 + + STDW .D2T2 B29:B28,*SP--[1] + || STDW .D1T1 A29:A28,*A15--[1] + STDW .D2T2 B27:B26,*SP--[1] + || STDW .D1T1 A27:A26,*A15--[1] + STDW .D2T2 B25:B24,*SP--[1] + || STDW .D1T1 A25:A24,*A15--[1] + STDW .D2T2 B23:B22,*SP--[1] + || STDW .D1T1 A23:A22,*A15--[1] + STDW .D2T2 B21:B20,*SP--[1] + || STDW .D1T1 A21:A20,*A15--[1] + STDW .D2T2 B19:B18,*SP--[1] + || STDW .D1T1 A19:A18,*A15--[1] + STDW .D2T2 B17:B16,*SP--[1] + || STDW .D1T1 A17:A16,*A15--[1] + + STDW .D2T2 B13:B12,*SP--[1] ; save PC and CSR + STDW .D2T2 B11:B10,*SP--[1] ; save RILC and ILC + STDW .D2T1 A5:A4,*SP--[1] ; save TSR and orig A4(stack type) + .endm + +RESTORE_ALL .macro __rp, __tsr + 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,__tsr + 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,__rp + + 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 + LDDW .D2T2 *+SP[1],SP:DP + NOP 4 + .endm + +THREAD_SAVE_ALL .macro __rp, __tsr + STDW .D2T2 SP:DP,*--SP[1] + SUBAW .D2 SP,2,SP + + ADD .D1X SP,-8,A15 + || STDW .D2T1 A15:A14,*SP--[16] ; save A15:A14 + + STDW .D2T2 B13:B12,*SP--[1] + || STDW .D1T1 A13:A12,*A15--[1] + || MVC .S2 __rp,B13 + STDW .D2T2 B11:B10,*SP--[1] + || STDW .D1T1 A11:A10,*A15--[1] + || MVC .S2 CSR,B12 + + STDW .D2T2 B9:B8,*SP--[1] + || STDW .D1T1 A9:A8,*A15--[1] + || MVC .S2 RILC,B11 + STDW .D2T2 B7:B6,*SP--[1] + || STDW .D1T1 A7:A6,*A15--[1] + || MVC .S2 ILC,B10 + STDW .D2T2 B5:B4,*SP--[1] + || STDW .D1T1 A5:A4,*A15--[1] + STDW .D2T2 B3:B2,*SP--[1] + || STDW .D1T1 A3:A2,*A15--[1] + || MVC .S2 __tsr,B5 + STDW .D2T2 B1:B0,*SP--[1] + || STDW .D1T1 A1:A0,*A15--[1] + || MV .S1X B5,A5 + + STDW .D2T2 B31:B30,*SP--[1] + || STDW .D1T1 A31:A30,*A15--[1] + || MVKL 1,A4 + STDW .D2T2 B29:B28,*SP--[1] + || STDW .D1T1 A29:A28,*A15--[1] + STDW .D2T2 B27:B26,*SP--[1] + || STDW .D1T1 A27:A26,*A15--[1] + STDW .D2T2 B25:B24,*SP--[1] + || STDW .D1T1 A25:A24,*A15--[1] + STDW .D2T2 B23:B22,*SP--[1] + || STDW .D1T1 A23:A22,*A15--[1] + STDW .D2T2 B21:B20,*SP--[1] + || STDW .D1T1 A21:A20,*A15--[1] + STDW .D2T2 B19:B18,*SP--[1] + || STDW .D1T1 A19:A18,*A15--[1] + STDW .D2T2 B17:B16,*SP--[1] + || STDW .D1T1 A17:A16,*A15--[1] + + STDW .D2T2 B13:B12,*SP--[1] ; save PC and CSR + STDW .D2T2 B11:B10,*SP--[1] ; save RILC and ILC + STDW .D2T1 A5:A4,*SP--[1] ; save TSR and orig A4(stack type) + .endm diff --git a/libcpu/ti-dsp/c6x/cpuport.c b/libcpu/ti-dsp/c6x/cpuport.c new file mode 100644 index 0000000000..158f587311 --- /dev/null +++ b/libcpu/ti-dsp/c6x/cpuport.c @@ -0,0 +1,196 @@ +/* + * 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 + */ + +#include <rthw.h> +#include <rtthread.h> + +#include "trap.h" + +/*------------ rt_hw_cpu_shutdown() function ---------------------------------- + * DESCRIPTION: Shutdown CPU + * ARGUMENTS: + * None + * RETURNED VALUE: None +-----------------------------------------------------------------------------*/ +RT_WEAK void rt_hw_cpu_shutdown(void) +{ + rt_kprintf("shutdown...\n"); + + rt_hw_interrupt_disable(); + + RT_ASSERT(0); +} + +/*------------ nested_exception_handler() function --------------------------- + * DESCRIPTION: Function handles Nested Exception + * ARGUMENTS: + * None + * RETURNED VALUE: None +-----------------------------------------------------------------------------*/ + +void nested_exception_handler(void) +{ + for(;;){} +} + +/*------------ hw_nmi_handler() function -------------------------------------- + * DESCRIPTION: Function handles NMI interrupt + * ARGUMENTS: + * None + * RETURNED VALUE: None +-----------------------------------------------------------------------------*/ +void hw_nmi_handler(struct rt_hw_exp_stack_register *regs) +{ + for(;;){} +} + +/*------------ hw_bad_handler() function -------------------------------------- + * DESCRIPTION: Function handles Bad interrupt + * ARGUMENTS: + * None + * RETURNED VALUE: None +-----------------------------------------------------------------------------*/ +void hw_bad_handler(void) +{ + for(;;){} +} + +/*------------ hw_int4_handler() function ------------------------------------- + * DESCRIPTION: Function handles INT4 interrupt + * ARGUMENTS: + * None + * RETURNED VALUE: None +-----------------------------------------------------------------------------*/ +void hw_int4_handler(void) +{ + +} + +/*------------ hw_int5_handler() function ------------------------------------- + * DESCRIPTION: Function handles INT5 interrupt + * ARGUMENTS: + * None + * RETURNED VALUE: None +-----------------------------------------------------------------------------*/ +void hw_int5_handler(void) +{ + +} + +/*------------ hw_int6_handler() function ------------------------------------- + * DESCRIPTION: Function handles INT6 interrupt + * ARGUMENTS: + * None + * RETURNED VALUE: None +-----------------------------------------------------------------------------*/ +void hw_int6_handler(void) +{ + +} + +/*------------ hw_int7_handler() function ------------------------------------- + * DESCRIPTION: Function handles INT7 interrupt + * ARGUMENTS: + * None + * RETURNED VALUE: None +-----------------------------------------------------------------------------*/ +void hw_int7_handler(void) +{ + +} + +/*------------ hw_int8_handler() function ------------------------------------- + * DESCRIPTION: Function handles INT8 interrupt + * ARGUMENTS: + * None + * RETURNED VALUE: None +-----------------------------------------------------------------------------*/ +void hw_int8_handler(void) +{ + +} + +/*------------ hw_int9_handler() function ------------------------------------- + * DESCRIPTION: Function handles INT9 interrupt + * ARGUMENTS: + * None + * RETURNED VALUE: None +-----------------------------------------------------------------------------*/ +void hw_int9_handler(void) +{ + +} + +/*------------ hw_int10_handler() function ------------------------------------ + * DESCRIPTION: Function handles INT10 interrupt + * ARGUMENTS: + * None + * RETURNED VALUE: None +-----------------------------------------------------------------------------*/ +void hw_int10_handler(void) +{ + +} + +/*------------ hw_int11_handler() function ------------------------------------ + * DESCRIPTION: Function handles INT11 interrupt + * ARGUMENTS: + * None + * RETURNED VALUE: None +-----------------------------------------------------------------------------*/ +void hw_int11_handler(void) +{ + +} + +/*------------ hw_int12_handler() function ------------------------------------ + * DESCRIPTION: Function handles INT12 interrupt + * ARGUMENTS: + * None + * RETURNED VALUE: None +-----------------------------------------------------------------------------*/ +void hw_int12_handler(void) +{ + +} + +/*------------ hw_int13_handler() function ------------------------------------ + * DESCRIPTION: Function handles INT13 interrupt + * ARGUMENTS: + * None + * RETURNED VALUE: None +-----------------------------------------------------------------------------*/ +void hw_int13_handler(void) +{ + +} + +/*------------------ hw_int14_handler() function ------------------------------ + * DESCRIPTION: Function handles INT14 interrupt + * ARGUMENTS: + * None + * RETURNED VALUE: +-----------------------------------------------------------------------------*/ +void hw_int14_handler(void) +{ +extern void rt_hw_systick_isr(); + rt_hw_systick_isr(); +} + +/*------------ hw_int15_handler() function ------------------------------------ + * DESCRIPTION: Function handles INT15 interrupt + * ARGUMENTS: + * None + * RETURNED VALUE: None +-----------------------------------------------------------------------------*/ +void hw_int15_handler(void) +{ + +} diff --git a/libcpu/ti-dsp/c6x/interrupt.c b/libcpu/ti-dsp/c6x/interrupt.c new file mode 100644 index 0000000000..6e48cb8efa --- /dev/null +++ b/libcpu/ti-dsp/c6x/interrupt.c @@ -0,0 +1,104 @@ +/* + * 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 + */ + +#include "interrupt.h" +#include "c66xx.h" +#include "trap.h" + +#define MAX_HANDLERS 128 + +extern volatile rt_uint8_t rt_interrupt_nest; +struct rt_irq_desc isr_table[MAX_HANDLERS]; +rt_uint32_t rt_interrupt_from_thread; +rt_uint32_t rt_interrupt_to_thread; +rt_uint32_t rt_thread_switch_interrupt_flag; + +/** + * This function will initialize hardware interrupt + */ +void rt_hw_interrupt_init(void) +{ + // initial system trap + //rt_trap_init(); + + /* init exceptions table */ + rt_memset(isr_table, 0x00, sizeof(isr_table)); + + /* init interrupt nest, and context in thread sp */ + rt_interrupt_nest = 0; + rt_interrupt_from_thread = 0; + rt_interrupt_to_thread = 0; + rt_thread_switch_interrupt_flag = 0; +} + +/** + * This function will mask a interrupt. + * @param vector the interrupt number + */ +void rt_hw_interrupt_mask(int vector) +{ + if (vector < 0 || vector >= MAX_HANDLERS) + { + return; + } +} + +/** + * This function will un-mask a interrupt. + * @param vector the interrupt number + */ +void rt_hw_interrupt_umask(int vector) +{ + if (vector < 0 || vector >= MAX_HANDLERS) + { + return; + } + ICR = vector; + IER |= vector; + + //enable GIE + TSR = TSR | 1; +} + +/** + * This function will install a interrupt service routine to a interrupt. + * @param vector the interrupt number + * @param new_handler the interrupt service routine to be installed + * @param old_handler the old interrupt service routine + */ +rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, + void *param, const char *name) +{ + rt_isr_handler_t old_handler = RT_NULL; + + if (vector < MAX_HANDLERS || vector >= 0) + { + old_handler = isr_table[vector].handler; + + if (handler != RT_NULL) + { +#ifdef RT_USING_INTERRUPT_INFO + rt_strncpy(isr_table[vector].name, name, RT_NAME_MAX); +#endif /* RT_USING_INTERRUPT_INFO */ + isr_table[vector].handler = handler; + isr_table[vector].param = param; + } + } + + return old_handler; +} + +void rt_hw_interrupt_clear(int vector) +{ + if (vector < 0 || vector >= MAX_HANDLERS) + { + return; + } +} diff --git a/libcpu/ti-dsp/c6x/interrupt.h b/libcpu/ti-dsp/c6x/interrupt.h new file mode 100644 index 0000000000..de7935b38a --- /dev/null +++ b/libcpu/ti-dsp/c6x/interrupt.h @@ -0,0 +1,24 @@ +/* + * 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 + */ + +#ifndef __INTERRUPT_H__ +#define __INTERRUPT_H__ + +#include <rthw.h> +#include <rtthread.h> + +void rt_hw_interrupt_init(void); +void rt_hw_interrupt_mask(int vector); +void rt_hw_interrupt_umask(int vector); +void rt_hw_interrupt_clear(int vector); +rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, + void *param, const char *name); + +#endif /* __INTERRUPT_H__ */ diff --git a/libcpu/ti-dsp/c6x/intexc.asm b/libcpu/ti-dsp/c6x/intexc.asm new file mode 100644 index 0000000000..edd365a3ef --- /dev/null +++ b/libcpu/ti-dsp/c6x/intexc.asm @@ -0,0 +1,263 @@ +; +; 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 +; + +;----------------------------------------------------------- +; interrupt and execption handler for C6000 DSP +;----------------------------------------------------------- + +;----------------------------------------------------------- +; macro definition +;----------------------------------------------------------- +DP .set B14 +SP .set B15 +; +;----------------------------------------------------------- +; + .include "contextinc.asm" +;----------------------------------------------------------- +; global function +;----------------------------------------------------------- + .global _nmi_handler + .global _bad_handler + .global _int4_handler + .global _int5_handler + .global _int6_handler + .global _int7_handler + .global _int8_handler + .global _int9_handler + .global _int10_handler + .global _int11_handler + .global _int12_handler + .global _int13_handler + .global _int14_handler + .global _int15_handler +; +;----------------------------------------------------------- +; + +;----------------------------------------------------------- +; extern function +;----------------------------------------------------------- + .ref hw_nmi_handler + .ref hw_bad_handler + .ref hw_int4_handler + .ref hw_int5_handler + .ref hw_int6_handler + .ref hw_int7_handler + .ref hw_int8_handler + .ref hw_int9_handler + .ref hw_int10_handler + .ref hw_int11_handler + .ref hw_int12_handler + .ref hw_int13_handler + .ref hw_int14_handler + .ref hw_int15_handler + .ref rt_hw_process_exception + .ref rt_interrupt_context_restore +; +;----------------------------------------------------------- +; + +;----------------------------------------------------------- +; interrupt macro definition +;----------------------------------------------------------- +RT_INTERRUPT_ENTRY .macro + SAVE_ALL IRP,ITSR + .endm + +RT_CALL_INT .macro __isr + B __isr + ADDKPC $1 ,B3,4 +$1: + B .S1 rt_interrupt_context_restore + NOP 5 + .endm +;----------------------------------------------------------- +; execption macro definition +;----------------------------------------------------------- +RT_EXECPTION_ENTRY .macro + SAVE_ALL NRP,NTSR + .endm + +RT_EXECPTION_EXIT .macro + RESTORE_ALL NRP,NTSR + B .S2 NRP ; return from execption + NOP 5 + .endm + +; +;----------------------------------------------------------- +; + + .sect ".text" +; +;----------------------------------------------------------- +; + +;----------------------------------------------------------- +; handler NMI interrupt +;----------------------------------------------------------- +_nmi_handler: +;{ + RT_EXECPTION_ENTRY + MVC .S2 EFR,B2 + CMPEQ .L2 1,B2,B2 + || MVC .S2 TSR,B1 + MV .D1X B2,A2 + || CLR .S2 B1,10,10,B1 + MVC .S2 B1,TSR + [!A2] MVKL .S1 rt_hw_process_exception,A0 + ||[B2] MVKL .S2 rt_hw_software_exception,B1 + [!A2] MVKH .S1 rt_hw_process_exception,A0 + ||[B2] MVKH .S2 rt_hw_software_exception,B1 + [!B2] B .S2X A0 + [B2] B .S2 B1 + [!B2] ADDAW .D2 SP,2,B1 + [!B2] MV .D1X B1,A4 + ADDKPC .S2 ret_from_trap,B3,2 +; +; return from trap +; +ret_from_trap: + MV .D2X A4,B0 + [!B0] MVKL .S2 ret_from_exception,B3 + [!B0] MVKH .S2 ret_from_exception,B3 + [!B0] BNOP .S2 B3,5 +; +; return from trap restore exception context +; +ret_from_exception: + RT_EXECPTION_EXIT +; +rt_hw_software_exception: + MVKL .S1 rt_hw_process_exception,A0 + MVKH .S1 rt_hw_process_exception,A0 + B .S2X A0 + ADDAW .D2 SP,2,B1 + MV .D1X B1,A4 + ADDKPC .S2 ret_from_trap,B3,2 + NOP 2 +;} + +;----------------------------------------------------------- +; handler bad interrupt +;----------------------------------------------------------- +_bad_handler: +;{ + RT_INTERRUPT_ENTRY + RT_CALL_INT hw_bad_handler +;} + +;----------------------------------------------------------- +; handler INT4 interrupt +;----------------------------------------------------------- +_int4_handler: +;{ + RT_INTERRUPT_ENTRY + RT_CALL_INT hw_int4_handler +;} + +;----------------------------------------------------------- +; handler INT5 interrupt +;----------------------------------------------------------- +_int5_handler: +;{ + RT_INTERRUPT_ENTRY + RT_CALL_INT hw_int5_handler +;} + +;----------------------------------------------------------- +; handler INT6 interrupt +;----------------------------------------------------------- +_int6_handler: +;{ + RT_INTERRUPT_ENTRY + RT_CALL_INT hw_int6_handler +;} + +;----------------------------------------------------------- +; handler INT7 interrupt +;----------------------------------------------------------- +_int7_handler: +;{ + RT_INTERRUPT_ENTRY + RT_CALL_INT hw_int7_handler +;} +;----------------------------------------------------------- +; handler INT8 interrupt +;----------------------------------------------------------- +_int8_handler: +;{ + RT_INTERRUPT_ENTRY + RT_CALL_INT hw_int8_handler +;} + +;----------------------------------------------------------- +; handler INT9 interrupt +;----------------------------------------------------------- +_int9_handler: +;{ + RT_INTERRUPT_ENTRY + RT_CALL_INT hw_int9_handler +;} + +;----------------------------------------------------------- +; handler INT10 interrupt +;----------------------------------------------------------- +_int10_handler: +;{ + RT_INTERRUPT_ENTRY + RT_CALL_INT hw_int10_handler +;} + +;----------------------------------------------------------- +; handler INT11 interrupt +;----------------------------------------------------------- +_int11_handler: +;{ + RT_INTERRUPT_ENTRY + RT_CALL_INT hw_int11_handler +;} + +;----------------------------------------------------------- +; handler INT12 interrupt +;----------------------------------------------------------- +_int12_handler: +;{ + RT_INTERRUPT_ENTRY + RT_CALL_INT hw_int12_handler +;} + +;----------------------------------------------------------- +; handler INT13 interrupt +;----------------------------------------------------------- +_int13_handler: +;{ + RT_INTERRUPT_ENTRY + RT_CALL_INT hw_int13_handler +;} + +;----------------------------------------------------------- +; handler INT14 interrupt +;----------------------------------------------------------- +_int14_handler: +;{ + RT_INTERRUPT_ENTRY + RT_CALL_INT hw_int14_handler +;} +;----------------------------------------------------------- +; handler INT15 interrupt +;----------------------------------------------------------- +_int15_handler: +;{ + RT_INTERRUPT_ENTRY + RT_CALL_INT hw_int15_handler +;} + .end diff --git a/libcpu/ti-dsp/c6x/stack.c b/libcpu/ti-dsp/c6x/stack.c new file mode 100644 index 0000000000..05e9534538 --- /dev/null +++ b/libcpu/ti-dsp/c6x/stack.c @@ -0,0 +1,120 @@ +/* + * 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 + */ + +#include <rtthread.h> +#include <c66xx.h> + +extern rt_uint32_t rt_hw_get_current_dp(void); + +/** + * @addtogroup C66xx + */ +/*@{*/ + +/** + * This function will initialize thread stack + * + * @param tentry the entry of thread + * @param parameter the parameter of entry + * @param stack_addr the beginning stack address + * @param texit the function will be called when thread exit + * + * @return stack address + */ +rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, + rt_uint8_t *stack_addr, void *texit) +{ + rt_hw_thread_stack_register *thread_context = RT_NULL; + rt_uint32_t stk = 0; + + stack_addr += sizeof(rt_uint32_t); + stack_addr = (rt_uint8_t *)RT_ALIGN_DOWN((rt_uint32_t)stack_addr, 8); + stk = (rt_uint32_t)stack_addr; + thread_context = (rt_hw_thread_stack_register *)(stk - sizeof(rt_hw_thread_stack_register)); + + thread_context->pc = (rt_uint32_t)tentry; + thread_context->csr = 0x0103; + thread_context->tsr = 0x3; + thread_context->orig_a4 = 1; + thread_context->ilc = 0; + thread_context->rilc = 0; + + thread_context->hw_register.b17 = 0xB17; + thread_context->hw_register.b16 = 0xB16; + thread_context->hw_register.b19 = 0xB19; + thread_context->hw_register.b18 = 0xB18; + thread_context->hw_register.b21 = 0xB21; + thread_context->hw_register.b20 = 0xB20; + thread_context->hw_register.b23 = 0xB23; + thread_context->hw_register.b22 = 0xB22; + thread_context->hw_register.b25 = 0xB25; + thread_context->hw_register.b24 = 0xB24; + thread_context->hw_register.b27 = 0xB27; + thread_context->hw_register.b26 = 0xB26; + thread_context->hw_register.b29 = 0xB29; + thread_context->hw_register.b28 = 0xB28; + thread_context->hw_register.b31 = 0xB31; + thread_context->hw_register.b30 = 0xB30; + + thread_context->hw_register.b1 = 0xB01; + thread_context->hw_register.b0 = 0xB00; + thread_context->hw_register.b3 = (rt_uint32_t)texit; + thread_context->hw_register.b2 = 0xB02; + thread_context->hw_register.b5 = 0xB05; + thread_context->hw_register.b4 = 0xB04; + thread_context->hw_register.b7 = 0xB07; + thread_context->hw_register.b6 = 0xB06; + thread_context->hw_register.b9 = 0xB09; + thread_context->hw_register.b8 = 0xB08; + thread_context->hw_register.b11 = 0xB11; + thread_context->hw_register.b10 = 0xB10; + thread_context->hw_register.b13 = 0xB13; + thread_context->hw_register.b12 = 0xB12; + + thread_context->hw_register.a17 = 0xA17; + thread_context->hw_register.a16 = 0xA16; + thread_context->hw_register.a19 = 0xA19; + thread_context->hw_register.a18 = 0xA18; + thread_context->hw_register.a21 = 0xA21; + thread_context->hw_register.a20 = 0xA20; + thread_context->hw_register.a23 = 0xA23; + thread_context->hw_register.a22 = 0xA22; + thread_context->hw_register.a25 = 0xA25; + thread_context->hw_register.a24 = 0xA24; + thread_context->hw_register.a27 = 0xA27; + thread_context->hw_register.a26 = 0xA26; + thread_context->hw_register.a29 = 0xA29; + thread_context->hw_register.a28 = 0xA28; + thread_context->hw_register.a31 = 0xA31; + thread_context->hw_register.a30 = 0xA30; + + thread_context->hw_register.a1 = 0xA01; + thread_context->hw_register.a0 = 0xA00; + thread_context->hw_register.a3 = 0xA03; + thread_context->hw_register.a2 = 0xA02; + thread_context->hw_register.a5 = 0xA05; + thread_context->hw_register.a4 = (rt_uint32_t)parameter; + thread_context->hw_register.a7 = 0xA07; + thread_context->hw_register.a6 = 0xA06; + thread_context->hw_register.a9 = 0xA09; + thread_context->hw_register.a8 = 0xA08; + thread_context->hw_register.a11 = 0xA11; + thread_context->hw_register.a10 = 0xA10; + thread_context->hw_register.a13 = 0xA13; + thread_context->hw_register.a12 = 0xA12; + + thread_context->hw_register.a15 = 0xA15; + thread_context->hw_register.a14 = 0xA14; + thread_context->hw_register.dp = rt_hw_get_current_dp(); + thread_context->hw_register.sp = (rt_uint32_t)stk; + + /* return task's current stack address */ + return (rt_uint8_t *)thread_context - 8; +} diff --git a/libcpu/ti-dsp/c6x/trap.c b/libcpu/ti-dsp/c6x/trap.c new file mode 100644 index 0000000000..814e352e10 --- /dev/null +++ b/libcpu/ti-dsp/c6x/trap.c @@ -0,0 +1,367 @@ +/* + * 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 + */ + +#include "trap.h" +#include "c66xx.h" + +#include <rthw.h> +#include <rtdef.h> +#include <rtthread.h> + +#define RT_SYS_STACK_SIZE 4096 + +rt_uint8_t rt_system_stack[RT_SYS_STACK_SIZE]; +rt_uint8_t *rt_system_stack_top; + +void rt_trap_init(void) +{ + rt_system_stack_top = &rt_system_stack[RT_SYS_STACK_SIZE-1]; + rt_system_stack_top = (rt_uint8_t *)RT_ALIGN_DOWN((rt_uint32_t)rt_system_stack_top, 8); + + ack_exception(EXCEPT_TYPE_NXF); + ack_exception(EXCEPT_TYPE_EXC); + ack_exception(EXCEPT_TYPE_IXF); + ack_exception(EXCEPT_TYPE_SXF); + rt_hw_enable_exception(); +} + +void show_regs(struct rt_hw_exp_stack_register *regs) +{ + rt_kprintf("\n"); + rt_kprintf("PC: %08lx SP: %08lx\n", + regs->pc, regs->hw_register.sp); + rt_kprintf("Status: %08lx ORIG_A4: %08lx\n", + regs->csr, regs->orig_a4); + rt_kprintf("A0: %08lx B0: %08lx\n", + regs->hw_register.a0, regs->hw_register.b0); + rt_kprintf("A1: %08lx B1: %08lx\n", + regs->hw_register.a1, regs->hw_register.b1); + rt_kprintf("A2: %08lx B2: %08lx\n", + regs->hw_register.a2, regs->hw_register.b2); + rt_kprintf("A3: %08lx B3: %08lx\n", + regs->hw_register.a3, regs->hw_register.b3); + rt_kprintf("A4: %08lx B4: %08lx\n", + regs->hw_register.a4, regs->hw_register.b4); + rt_kprintf("A5: %08lx B5: %08lx\n", + regs->hw_register.a5, regs->hw_register.b5); + rt_kprintf("A6: %08lx B6: %08lx\n", + regs->hw_register.a6, regs->hw_register.b6); + rt_kprintf("A7: %08lx B7: %08lx\n", + regs->hw_register.a7, regs->hw_register.b7); + rt_kprintf("A8: %08lx B8: %08lx\n", + regs->hw_register.a8, regs->hw_register.b8); + rt_kprintf("A9: %08lx B9: %08lx\n", + regs->hw_register.a9, regs->hw_register.b9); + rt_kprintf("A10: %08lx B10: %08lx\n", + regs->hw_register.a10, regs->hw_register.b10); + rt_kprintf("A11: %08lx B11: %08lx\n", + regs->hw_register.a11, regs->hw_register.b11); + rt_kprintf("A12: %08lx B12: %08lx\n", + regs->hw_register.a12, regs->hw_register.b12); + rt_kprintf("A13: %08lx B13: %08lx\n", + regs->hw_register.a13, regs->hw_register.b13); + rt_kprintf("A14: %08lx B14: %08lx\n", + regs->hw_register.a14, regs->hw_register.dp); + rt_kprintf("A15: %08lx B15: %08lx\n", + regs->hw_register.a15, regs->hw_register.sp); + rt_kprintf("A16: %08lx B16: %08lx\n", + regs->hw_register.a16, regs->hw_register.b16); + rt_kprintf("A17: %08lx B17: %08lx\n", + regs->hw_register.a17, regs->hw_register.b17); + rt_kprintf("A18: %08lx B18: %08lx\n", + regs->hw_register.a18, regs->hw_register.b18); + rt_kprintf("A19: %08lx B19: %08lx\n", + regs->hw_register.a19, regs->hw_register.b19); + rt_kprintf("A20: %08lx B20: %08lx\n", + regs->hw_register.a20, regs->hw_register.b20); + rt_kprintf("A21: %08lx B21: %08lx\n", + regs->hw_register.a21, regs->hw_register.b21); + rt_kprintf("A22: %08lx B22: %08lx\n", + regs->hw_register.a22, regs->hw_register.b22); + rt_kprintf("A23: %08lx B23: %08lx\n", + regs->hw_register.a23, regs->hw_register.b23); + rt_kprintf("A24: %08lx B24: %08lx\n", + regs->hw_register.a24, regs->hw_register.b24); + rt_kprintf("A25: %08lx B25: %08lx\n", + regs->hw_register.a25, regs->hw_register.b25); + rt_kprintf("A26: %08lx B26: %08lx\n", + regs->hw_register.a26, regs->hw_register.b26); + rt_kprintf("A27: %08lx B27: %08lx\n", + regs->hw_register.a27, regs->hw_register.b27); + rt_kprintf("A28: %08lx B28: %08lx\n", + regs->hw_register.a28, regs->hw_register.b28); + rt_kprintf("A29: %08lx B29: %08lx\n", + regs->hw_register.a29, regs->hw_register.b29); + rt_kprintf("A30: %08lx B30: %08lx\n", + regs->hw_register.a30, regs->hw_register.b30); + rt_kprintf("A31: %08lx B31: %08lx\n", + regs->hw_register.a31, regs->hw_register.b31); +} + +void do_trap(struct rt_exception_info *except_info, struct rt_hw_exp_stack_register *regs) +{ + rt_kprintf("Enter exception: %s\n", except_info->kernel_str); + + show_regs(regs); + + for(;;){} +} + +static struct rt_exception_info iexcept_table[10] = { + { " - instruction fetch", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - fetch packet", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - execute packet", ABORT_TYPE_UNDDEF, ABORT_OPCODE_ILL }, + { " - undefined instruction", ABORT_TYPE_UNDDEF, ABORT_OPCODE_ILL }, + { " - resource conflict", ABORT_TYPE_UNDDEF, ABORT_OPCODE_ILL }, + { " - resource access", ABORT_TYPE_UNDDEF, ABORT_PRVREG_ILL }, + { " - privilege", ABORT_TYPE_UNDDEF, ABORT_PRVOPC_ILL }, + { " - loops buffer", ABORT_TYPE_UNDDEF, ABORT_PRVOPC_ILL }, + { " - software exception", ABORT_TYPE_UNDDEF, ABORT_ILLTRP_ILL }, + { " - unknown exception", ABORT_TYPE_UNDDEF, ABORT_PRVOPC_ILL } +}; + +/* + * Process an internal exception (non maskable) + */ +static int process_iexcept(struct rt_hw_exp_stack_register *regs) +{ + unsigned int iexcept_report = get_iexcept(); + unsigned int iexcept_num = 0; + + ack_exception(EXCEPT_TYPE_IXF); + + while(iexcept_report) + { + iexcept_num = ffs(iexcept_report); + iexcept_report &= ~(1 << iexcept_num); + set_iexcept(iexcept_report); + + if (*(unsigned int *)regs->pc == BKPT_OPCODE) + { + /* This is a breakpoint */ + struct rt_exception_info bkpt_exception = \ + { " - undefined instruction",\ + ABORT_TYPE_UNDDEF, ABORT_BRKPT_ILL }; + do_trap(&bkpt_exception, regs); + iexcept_report &= ~(0xFF); + set_iexcept(iexcept_report); + continue; + } + do_trap(&iexcept_table[iexcept_num], regs); + } + return 0; +} + +static struct rt_exception_info eexcept_table[128] = { + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + { " - external exception", ABORT_TYPE_BUS, ABORT_BUS_ADDRERR }, + + { " - CPU memory protection fault", ABORT_TYPE_MAP, ABORT_BUS_ACCERR }, + { " - CPU memory protection fault in L1P", ABORT_TYPE_MAP, ABORT_BUS_ACCERR }, + { " - DMA memory protection fault in L1P", ABORT_TYPE_MAP, ABORT_BUS_ACCERR }, + { " - CPU memory protection fault in L1D", ABORT_TYPE_MAP, ABORT_BUS_ACCERR }, + { " - DMA memory protection fault in L1D", ABORT_TYPE_MAP, ABORT_BUS_ACCERR }, + { " - CPU memory protection fault in L2", ABORT_TYPE_MAP, ABORT_BUS_ACCERR }, + { " - DMA memory protection fault in L2", ABORT_TYPE_MAP, ABORT_BUS_ACCERR }, + { " - EMC CPU memory protection fault", ABORT_TYPE_MAP, ABORT_BUS_ACCERR }, + { " - EMC bus error", ABORT_TYPE_MAP, ABORT_BUS_ADDRERR } +}; + +/* + * Process an external exception (maskable) + */ +static void process_eexcept(struct rt_hw_exp_stack_register *regs) +{ + int except_num = 0; + int bank = 0; + int i = 0; + + for (i = 0; i <= 3; i++) + { + while (INTC_MEXPMASK[i]) + { + __dint(); + except_num = ffs(INTC_MEXPMASK[i]); + INTC_MEXPMASK[i] &= ~(1 << except_num); /* ack the external exception */ + __rint(); + do_trap(&eexcept_table[except_num + (bank << 5)], regs); + } + bank++; + } + + ack_exception(EXCEPT_TYPE_EXC); +} + +extern void hw_nmi_handler(struct rt_hw_exp_stack_register *regs); +/* + * Main exception processing + */ +int rt_hw_process_exception(struct rt_hw_exp_stack_register *regs) +{ + int type = 0; + int type_num = 0; + int ie_num = 9; /* default is unknown exception */ + + while ((type = get_except_type()) != 0) { + type_num = fls(type) - 1; + + switch(type_num) { + case EXCEPT_TYPE_NXF: /* NMI exception */ + ack_exception(EXCEPT_TYPE_NXF); /* clear exception */ + if (hw_nmi_handler != RT_NULL) + { + hw_nmi_handler(regs); + } + break; + + case EXCEPT_TYPE_IXF: /* internal exception */ + if (process_iexcept(regs)) + { + return 1; + } + break; + + case EXCEPT_TYPE_EXC: /* external exception */ + process_eexcept(regs); + break; + + case EXCEPT_TYPE_SXF: /* software exception */ + ie_num = 8; + ack_exception(type_num); + break; + default: /* clear exception */ + ack_exception(type_num); + do_trap(&iexcept_table[ie_num], regs); + break; + } + } + return 0; +} + diff --git a/libcpu/ti-dsp/c6x/trap.h b/libcpu/ti-dsp/c6x/trap.h new file mode 100644 index 0000000000..d895344728 --- /dev/null +++ b/libcpu/ti-dsp/c6x/trap.h @@ -0,0 +1,117 @@ +/* + * 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 + */ + +#ifndef __TRAP_H__ +#define __TRAP_H__ + +#include "c66xx.h" + +/* + * exception operation macro + */ +#define disable_exception() +#define get_except_type() EFR +#define ack_exception(type) ECR = 1ul << (type) +#define get_iexcept() IERR +#define set_iexcept(mask) IERR = (mask) + +/* + * exception types + */ +#define EXCEPT_TYPE_NXF 31 /* NMI */ +#define EXCEPT_TYPE_EXC 30 /* external exception */ +#define EXCEPT_TYPE_IXF 1 /* internal exception */ +#define EXCEPT_TYPE_SXF 0 /* software exception */ + +#define EXCEPT_CAUSE_LBX (1 << 7) /* loop buffer exception */ +#define EXCEPT_CAUSE_PRX (1 << 6) /* privilege exception */ +#define EXCEPT_CAUSE_RAX (1 << 5) /* resource access exception */ +#define EXCEPT_CAUSE_RCX (1 << 4) /* resource conflict exception */ +#define EXCEPT_CAUSE_OPX (1 << 3) /* opcode exception */ +#define EXCEPT_CAUSE_EPX (1 << 2) /* execute packet exception */ +#define EXCEPT_CAUSE_FPX (1 << 1) /* fetch packet exception */ +#define EXCEPT_CAUSE_IFX (1 << 0) /* instruction fetch exception */ + +enum SYSTEM_TRAP_CODE +{ + ABORT_BUS_ADDRERR = 0, // bus address error + ABORT_BUS_ACCERR, // bus access permission error + ABORT_OPCODE_ILL, // illegal opcode + ABORT_PRVREG_ILL, // privilege register + ABORT_PRVOPC_ILL, // privileged opcode + ABORT_ILLTRP_ILL, // illegal trap + ABORT_BRKPT_ILL, // handling breakpoints +}; + +/* + * abort types + */ +#define ABORT_TYPE_BUS 0 // bus access abnormal +#define ABORT_TYPE_MAP 1 // page table mapping error +#define ABORT_TYPE_UNDDEF 0xff // undefined exception +#define ABORT_TYPE_FATAL 0xffffffff // fatal error + +struct rt_exception_info { + char *kernel_str; + int type; + int code; +}; + +#define BKPT_OPCODE 0x56454314 /* illegal opcode */ +#define INTC_MEXPMASK __SYSREGA(0x018000e0, unsigned int) + +extern void rt_trap_init(void); +extern void rt_hw_enable_exception(void); +extern int __fls(int val); +extern int __ffs(int val); + +/* + * ffz - find first zero in word. + * @word: The word to search + * + * Undefined if no zero exists, so code should check against ~0UL first. + */ +#define ffz(x) __ffs(~(x)) + +/** + * fls - find last (most-significant) bit set + * @x: the word to search + * + * This is defined the same way as ffs. + * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32. + */ +static inline int fls(int x) +{ + if (!x) + { + return 0; + } + return 32 - __fls(x); +} + +/** + * ffs - find first bit set + * @x: the word to search + * + * This is defined the same way as + * the libc and compiler builtin ffs routines, therefore + * differs in spirit from the above ffz (man ffs). + * Note ffs(0) = 0, ffs(1) = 1, ffs(0x80000000) = 32. + */ +static inline int ffs(int x) +{ + if (!x) + { + return 0; + } + return __ffs(x) + 1; +} + +#endif /* __TRAP_H__ */ diff --git a/libcpu/ti-dsp/c6x/vector.asm b/libcpu/ti-dsp/c6x/vector.asm new file mode 100644 index 0000000000..9c74de1bb7 --- /dev/null +++ b/libcpu/ti-dsp/c6x/vector.asm @@ -0,0 +1,95 @@ +; +; 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 +; + +;----------------------------------------------------------- +; interrupt vector table for C6000 DSP +;----------------------------------------------------------- + +;----------------------------------------------------------- +; extern function +;----------------------------------------------------------- + .ref _c_int00 ; entry point + .ref _nmi_handler + .ref _bad_handler + .ref _int4_handler + .ref _int5_handler + .ref _int6_handler + .ref _int7_handler + .ref _int8_handler + .ref _int9_handler + .ref _int10_handler + .ref _int11_handler + .ref _int12_handler + .ref _int13_handler + .ref _int14_handler + .ref _int15_handler + +;----------------------------------------------------------- +; macro definition +;----------------------------------------------------------- + +; +; create interrupt vector for reset (interrupt 0) +; +VEC_RESET .macro addr + MVKL addr,B0 + MVKH addr,B0 + B B0 + MVC PCE1,B0 + NOP 4 + .align 32 + .endm + +; +; create interrupt vector for other used interrupts +; +IRQVEC .macro __name, __isr + .align 32 + .hidden __name + .global __name +__name: + B .S2 __isr + NOP + NOP + NOP + NOP + NOP + NOP + NOP + .endm +; +;----------------------------------------------------------- +; + +; +; vector table +; + .sect ".vecs" + .align 32 + .global vector +vector: + VEC_RESET _c_int00 + IRQVEC NMI, _nmi_handler + IRQVEC AINT, _bad_handler + IRQVEC MSGINT, _bad_handler + IRQVEC INT4, _int4_handler + IRQVEC INT5, _int5_handler + IRQVEC INT6, _int6_handler + IRQVEC INT7, _int7_handler + IRQVEC INT8, _int8_handler + IRQVEC INT9, _int9_handler + IRQVEC INT10, _int10_handler + IRQVEC INT11, _int11_handler + IRQVEC INT12, _int12_handler + IRQVEC INT13, _int13_handler + IRQVEC INT14, _int14_handler + IRQVEC INT15, _int15_handler + + .end |
