diff --git a/bsp/tms320c6678/.ccsproject b/bsp/tms320c6678/.ccsproject new file mode 100644 index 0000000000..82f98bbb00 --- /dev/null +++ b/bsp/tms320c6678/.ccsproject @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/bsp/tms320c6678/.cproject b/bsp/tms320c6678/.cproject new file mode 100644 index 0000000000..a906191430 --- /dev/null +++ b/bsp/tms320c6678/.cproject @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bsp/tms320c6678/.project b/bsp/tms320c6678/.project new file mode 100644 index 0000000000..a0c5dddf40 --- /dev/null +++ b/bsp/tms320c6678/.project @@ -0,0 +1,154 @@ + + + ti-tms320c6678 + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + com.ti.ccstudio.core.ccsNature + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + clock.c + 1 + PARENT-2-PROJECT_LOC/git-source/rt-thread/src/clock.c + + + components.c + 1 + PARENT-2-PROJECT_LOC/git-source/rt-thread/src/components.c + + + context.asm + 1 + PARENT-2-PROJECT_LOC/git-source/rt-thread/libcpu/ti-dsp/c6x/context.asm + + + contextinc.asm + 1 + PARENT-2-PROJECT_LOC/git-source/rt-thread/libcpu/ti-dsp/c6x/contextinc.asm + + + cpu.c + 1 + PARENT-2-PROJECT_LOC/git-source/rt-thread/src/cpu.c + + + cpuport.c + 1 + PARENT-2-PROJECT_LOC/git-source/rt-thread/libcpu/ti-dsp/c6x/cpuport.c + + + device.c + 1 + PARENT-2-PROJECT_LOC/git-source/rt-thread/src/device.c + + + idle.c + 1 + PARENT-2-PROJECT_LOC/git-source/rt-thread/src/idle.c + + + interrupt.c + 1 + PARENT-2-PROJECT_LOC/git-source/rt-thread/libcpu/ti-dsp/c6x/interrupt.c + + + intexc.asm + 1 + PARENT-2-PROJECT_LOC/git-source/rt-thread/libcpu/ti-dsp/c6x/intexc.asm + + + ipc.c + 1 + PARENT-2-PROJECT_LOC/git-source/rt-thread/src/ipc.c + + + irq.c + 1 + PARENT-2-PROJECT_LOC/git-source/rt-thread/src/irq.c + + + kservice.c + 1 + PARENT-2-PROJECT_LOC/git-source/rt-thread/src/kservice.c + + + mem.c + 1 + PARENT-2-PROJECT_LOC/git-source/rt-thread/src/mem.c + + + memheap.c + 1 + PARENT-2-PROJECT_LOC/git-source/rt-thread/src/memheap.c + + + mempool.c + 1 + PARENT-2-PROJECT_LOC/git-source/rt-thread/src/mempool.c + + + object.c + 1 + PARENT-2-PROJECT_LOC/git-source/rt-thread/src/object.c + + + scheduler.c + 1 + PARENT-2-PROJECT_LOC/git-source/rt-thread/src/scheduler.c + + + signal.c + 1 + PARENT-2-PROJECT_LOC/git-source/rt-thread/src/signal.c + + + slab.c + 1 + PARENT-2-PROJECT_LOC/git-source/rt-thread/src/slab.c + + + stack.c + 1 + PARENT-2-PROJECT_LOC/git-source/rt-thread/libcpu/ti-dsp/c6x/stack.c + + + thread.c + 1 + PARENT-2-PROJECT_LOC/git-source/rt-thread/src/thread.c + + + timer.c + 1 + PARENT-2-PROJECT_LOC/git-source/rt-thread/src/timer.c + + + trap.c + 1 + PARENT-2-PROJECT_LOC/git-source/rt-thread/libcpu/ti-dsp/c6x/trap.c + + + vector.asm + 1 + PARENT-2-PROJECT_LOC/git-source/rt-thread/libcpu/ti-dsp/c6x/vector.asm + + + diff --git a/bsp/tms320c6678/.settings/org.eclipse.cdt.codan.core.prefs b/bsp/tms320c6678/.settings/org.eclipse.cdt.codan.core.prefs new file mode 100644 index 0000000000..f653028c53 --- /dev/null +++ b/bsp/tms320c6678/.settings/org.eclipse.cdt.codan.core.prefs @@ -0,0 +1,3 @@ +eclipse.preferences.version=1 +inEditor=false +onBuild=false diff --git a/bsp/tms320c6678/.settings/org.eclipse.cdt.debug.core.prefs b/bsp/tms320c6678/.settings/org.eclipse.cdt.debug.core.prefs new file mode 100644 index 0000000000..2adc7b1dde --- /dev/null +++ b/bsp/tms320c6678/.settings/org.eclipse.cdt.debug.core.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +org.eclipse.cdt.debug.core.toggleBreakpointModel=com.ti.ccstudio.debug.CCSBreakpointMarker diff --git a/bsp/tms320c6678/.settings/org.eclipse.core.resources.prefs b/bsp/tms320c6678/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000000..243442d787 --- /dev/null +++ b/bsp/tms320c6678/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,12 @@ +eclipse.preferences.version=1 +encoding//Debug/applications/subdir_rules.mk=UTF-8 +encoding//Debug/applications/subdir_vars.mk=UTF-8 +encoding//Debug/common/subdir_rules.mk=UTF-8 +encoding//Debug/common/subdir_vars.mk=UTF-8 +encoding//Debug/driver/subdir_rules.mk=UTF-8 +encoding//Debug/driver/subdir_vars.mk=UTF-8 +encoding//Debug/makefile=UTF-8 +encoding//Debug/objects.mk=UTF-8 +encoding//Debug/sources.mk=UTF-8 +encoding//Debug/subdir_rules.mk=UTF-8 +encoding//Debug/subdir_vars.mk=UTF-8 diff --git a/bsp/tms320c6678/KeyStone.cmd b/bsp/tms320c6678/KeyStone.cmd new file mode 100644 index 0000000000..0f30bc506e --- /dev/null +++ b/bsp/tms320c6678/KeyStone.cmd @@ -0,0 +1,47 @@ +/****************************************************************************/ +/* */ +/* M6678.cmd */ +/* Copyright (c): NUDT */ +/* */ +/* */ +/* Description: This file is a sample linker command file that can be */ +/* used for linking programs built with the C compiler and */ +/* running the resulting .out file on an M6678 */ +/* device. Use it as a guideline. You will want to */ +/* change the memory layout to match your specific C6xxx */ +/* target system. You may want to change the allocation */ +/* scheme according to the size of your program. */ +/* */ +/* */ +/****************************************************************************/ + +-heap 0x800 +-stack 0x1000 + +MEMORY +{ + VECTORS: o = 0x00800000 l = 0x00000200 + LL2_CODE: o = 0x00800200 l = 0x0001FE00 + LL2_RW_DATA: o = 0x00820000 l = 0x00020000 /*set memory protection attribitue as read/write*/ +} + +SECTIONS +{ + .vecs > VECTORS + + .text > LL2_CODE + .cinit > LL2_CODE + .const > LL2_CODE + .switch > LL2_CODE + .stack > LL2_RW_DATA + GROUP + { + .neardata + .rodata + .bss + } > LL2_RW_DATA + .far > LL2_RW_DATA + .fardata > LL2_RW_DATA + .cio > LL2_RW_DATA + .sysmem > LL2_RW_DATA +} diff --git a/bsp/tms320c6678/README.md b/bsp/tms320c6678/README.md new file mode 100644 index 0000000000..f78f4850bc --- /dev/null +++ b/bsp/tms320c6678/README.md @@ -0,0 +1,49 @@ +### 1. 简介 + +TMS320C6678是TI基于KeyStone的多核固定浮点数字信号处理器,DSP集成C66x CorePac,每个核心在1GHz至1.25 GHz的运行。该设备支持高性能的信号处理应用,如任务关键,医疗成像,测试和自动化。 + +### 2. 编译说明 + +TMS320C6678 工程的编译和下载要使用的是 TI 官方提供的 Code Composer Studio。在本工程使用的是 CCS5.5 版本编译调试,CCS5.5 Compiler version:TIv8.3.5进行编译,需要安装TI提供的CSL库pdk_C6678_1_1_2_6。 + +### 2.1 导入工程 + +首先打开 Code Composer Studio,点击 Project -> Import CCS Projects... + +![输入图片说明](figures/import(1).png) + +在打开的对话框中,点击 Select search -> directory 右边的 Browse... 选择 TMS320C6678 BSP 所在文件夹,如图所示。选择完成后点击 Finish 完成导入。 + +![输入图片说明](figures/import(2).png) + +### 2.2 检查工程路径和编译器 + +- 检查工程路径是否正确,是否成功安装pdk_C6678_1_1_2_6,本工程安装路径为C盘。 + +![输入图片说明](figures/filepath.png) + +- 检查编译器版本,本工程使用的是TIv8.3.5 + +![输入图片说明](figures/general.jpg) + +### 3. 编译工程 + +导入工程后,选中导入的 ti-tms320c6678 工程,右键点击,在弹出的菜单中选择 Build Project 即可开始编译。 + +### 4. 加载和调试 + +编译完成后,可以开始加载和调试。将板子和 XDS560 仿真器连接,仿真器可以将编译生成的可执行文件加载到L2或MSMC执行。 + +- 如下图ti-tms320c6678.out是编译之后生成的可执行文件。 + +![输入图片说明](figures/debug(1).png) + +- 本工程目前只支持单核运行,按如下图加载可执行文件。 + +![输入图片说明](figures/load.png) + +- 加载可执行文件完成后,CCS将进入调试模式,可以选择继续运行、单步调试、复位等操作。 + +![输入图片说明](figures/debug(2).png) + +到此,可以开启tms320c6678 + rt-thread的愉快旅程了 :smile: 。 \ No newline at end of file diff --git a/bsp/tms320c6678/applications/board.c b/bsp/tms320c6678/applications/board.c new file mode 100644 index 0000000000..bfa4057c1f --- /dev/null +++ b/bsp/tms320c6678/applications/board.c @@ -0,0 +1,37 @@ +/* + * 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 "board.h" +#include "interrupt.h" +#include "drv_timer.h" +#include "common.h" + +#include + +/** + * This function will initial board. + */ +void rt_hw_board_init(void) +{ + // initial CPU core + keystone_cpu_init(); + + // initial interrupt controller + rt_hw_interrupt_init(); + + // initial system timer + rt_hw_system_timer_init(); + + /* initialize memory system */ + rt_kprintf("heap: 0x%08x - 0x%08x\n", RT_HW_HEAP_BEGIN, RT_HW_HEAP_END); + rt_system_heap_init(RT_HW_HEAP_BEGIN, RT_HW_HEAP_END); + + rt_hw_system_timer_start(); +} diff --git a/bsp/tms320c6678/applications/board.h b/bsp/tms320c6678/applications/board.h new file mode 100644 index 0000000000..88e6e94e6e --- /dev/null +++ b/bsp/tms320c6678/applications/board.h @@ -0,0 +1,20 @@ +/* + * 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 __BOARD_H__ +#define __BOARD_H__ + +#define RT_HW_HEAP_BEGIN (void*)0x0C000000 +#define RT_HW_HEAP_END (void*)0x0C100000 + +void rt_hw_board_init(void); + +#endif /* __BOARD_H__ */ + diff --git a/bsp/tms320c6678/applications/main.c b/bsp/tms320c6678/applications/main.c new file mode 100644 index 0000000000..08c2d67fa4 --- /dev/null +++ b/bsp/tms320c6678/applications/main.c @@ -0,0 +1,79 @@ +/* + * 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 +#include + +#include "board.h" + +void rt_init_thread_entry(void *parameter) +{ + rt_kprintf("hello rt-thread\n"); +} + +int rt_application_init(void) +{ + rt_thread_t tid; + + tid = rt_thread_create("init", rt_init_thread_entry, RT_NULL, 4096, 3, 200); + if (tid != RT_NULL) + { + rt_thread_startup(tid); + } else { + return -1; + } + + return 0; +} + +/** + * This function will startup RT-Thread RTOS. + */ +void rtthread_startup(void) +{ + /* disable interrupt first */ + rt_hw_interrupt_disable(); + + /* init board */ + rt_hw_board_init(); + + /* show version */ + rt_show_version(); + + /* init timer system */ + rt_system_timer_init(); + + /* init scheduler system */ + rt_system_scheduler_init(); + + /* init application */ + rt_application_init(); + + /* init timer thread */ + rt_system_timer_thread_init(); + + /* init idle thread */ + rt_thread_idle_init(); + + /* start scheduler */ + rt_system_scheduler_start(); + + /* never reach here */ + return ; +} + +void main(void) +{ + /* startup RT-Thread RTOS */ + rtthread_startup(); + + for(;;){} +} + diff --git a/bsp/tms320c6678/common/common.c b/bsp/tms320c6678/common/common.c new file mode 100644 index 0000000000..1c362d76f8 --- /dev/null +++ b/bsp/tms320c6678/common/common.c @@ -0,0 +1,203 @@ +/* + * 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 "common.h" + +CSL_BootcfgRegs * gp_bootcfg_regs = (CSL_BootcfgRegs *)CSL_BOOT_CFG_REGS; +CSL_CgemRegs * gp_cgem_regs = (CSL_CgemRegs *)CSL_CGEM0_5_REG_BASE_ADDRESS_REGS; +CSL_TmrPlusRegs * gp_timer_regs[9] = { + (CSL_TmrPlusRegs *)CSL_TIMER_0_REGS, + (CSL_TmrPlusRegs *)CSL_TIMER_1_REGS, + (CSL_TmrPlusRegs *)CSL_TIMER_2_REGS, + (CSL_TmrPlusRegs *)CSL_TIMER_3_REGS, + (CSL_TmrPlusRegs *)CSL_TIMER_4_REGS, + (CSL_TmrPlusRegs *)CSL_TIMER_5_REGS, + (CSL_TmrPlusRegs *)CSL_TIMER_6_REGS, + (CSL_TmrPlusRegs *)CSL_TIMER_7_REGS, + (CSL_TmrPlusRegs *)(CSL_TIMER_7_REGS+(CSL_TIMER_7_REGS-CSL_TIMER_6_REGS)) +}; + +void cpu_interrupt_init(void) +{ + //clear interrupt and excpetion events + ICR = IFR; + ECR = EFR; + IER = 3; //disable all interrupts + + /* disable event combine */ + gp_cgem_regs->EVTMASK[0] = 0xffffffff; + gp_cgem_regs->EVTMASK[1] = 0xffffffff; + gp_cgem_regs->EVTMASK[2] = 0xffffffff; + gp_cgem_regs->EVTMASK[3] = 0xffffffff; + + /*Clear all CPU events*/ + gp_cgem_regs->EVTCLR[0] = 0xFFFFFFFF; + gp_cgem_regs->EVTCLR[1] = 0xFFFFFFFF; + gp_cgem_regs->EVTCLR[2] = 0xFFFFFFFF; + gp_cgem_regs->EVTCLR[3] = 0xFFFFFFFF; + + /*Interrupt Service Table Pointer to begining of LL2 memory*/ + ISTP = 0x800000; +} + +void keystone_cpu_init(void) +{ + /* clear all interrupt flag/status, setup ISTP to begining of LL2 */ + cpu_interrupt_init(); +} + +/*===============================Timer=================================*/ +void reset_timer(int timer_num) +{ + if(gp_timer_regs[timer_num]->TGCR) + { + gp_timer_regs[timer_num]->TGCR = 0; + gp_timer_regs[timer_num]->TCR= 0; + } +} + +void timer64_init(Timer64_Config * tmrCfg) +{ + reset_timer(tmrCfg->timer_num); + + gp_timer_regs[tmrCfg->timer_num]->CNTLO = 0; + gp_timer_regs[tmrCfg->timer_num]->CNTHI = 0; + + /*please note, in clock mode, two timer periods generate a clock, + one timer period output high voltage level, the other timer period + output low voltage level, so, the timer period should be half to the + desired output clock period*/ + if(TIMER_PERIODIC_CLOCK == tmrCfg->timerMode) + { + tmrCfg->period = tmrCfg->period/2; + } + + /*the value written into period register is the expected value minus one*/ + gp_timer_regs[tmrCfg->timer_num]->PRDLO = _loll(tmrCfg->period-1); + gp_timer_regs[tmrCfg->timer_num]->PRDHI = _hill(tmrCfg->period-1); + if(tmrCfg->reload_period>1) + { + gp_timer_regs[tmrCfg->timer_num]->RELLO = _loll(tmrCfg->reload_period-1); + gp_timer_regs[tmrCfg->timer_num]->RELHI = _hill(tmrCfg->reload_period-1); + } + + if(TIMER_WATCH_DOG == tmrCfg->timerMode) + { + gp_timer_regs[tmrCfg->timer_num]->TGCR = + /*Select watch-dog mode*/ + (CSL_TMR_TIMMODE_WDT << CSL_TMR_TGCR_TIMMODE_SHIFT) + /*Remove the timer from reset*/ + | (CSL_TMR_TGCR_TIMLORS_MASK) + | (CSL_TMR_TGCR_TIMHIRS_MASK); + } + else if(TIMER_PERIODIC_WAVE == tmrCfg->timerMode) + { + gp_timer_regs[tmrCfg->timer_num]->TGCR = TMR_TGCR_PLUSEN_MASK + /*for plus featuers, dual 32-bit unchained timer mode should be used*/ + | (CSL_TMR_TIMMODE_DUAL_UNCHAINED << CSL_TMR_TGCR_TIMMODE_SHIFT) + /*Remove the timer from reset*/ + | (CSL_TMR_TGCR_TIMLORS_MASK); + + //in plus mode, interrupt/event must be enabled manually + gp_timer_regs[tmrCfg->timer_num]->INTCTL_STAT= TMR_INTCTLSTAT_EN_ALL_CLR_ALL; + } + else + { + gp_timer_regs[tmrCfg->timer_num]->TGCR = + /*Select 64-bit general timer mode*/ + (CSL_TMR_TIMMODE_GPT << CSL_TMR_TGCR_TIMMODE_SHIFT) + /*Remove the timer from reset*/ + | (CSL_TMR_TGCR_TIMLORS_MASK) + | (CSL_TMR_TGCR_TIMHIRS_MASK); + } + + /*make timer stop with emulation*/ + gp_timer_regs[tmrCfg->timer_num]->EMUMGT_CLKSPD = (gp_timer_regs[tmrCfg->timer_num]->EMUMGT_CLKSPD& + ~(CSL_TMR_EMUMGT_CLKSPD_FREE_MASK|CSL_TMR_EMUMGT_CLKSPD_SOFT_MASK)); + + if(TIMER_WATCH_DOG == tmrCfg->timerMode) + { + /*enable watchdog timer*/ + gp_timer_regs[tmrCfg->timer_num]->WDTCR = CSL_TMR_WDTCR_WDEN_MASK + | (CSL_TMR_WDTCR_WDKEY_CMD1 << CSL_TMR_WDTCR_WDKEY_SHIFT); + + gp_timer_regs[tmrCfg->timer_num]->TCR = + (CSL_TMR_CLOCK_INP_NOGATE << CSL_TMR_TCR_TIEN_LO_SHIFT) + | (CSL_TMR_CLKSRC_INTERNAL << CSL_TMR_TCR_CLKSRC_LO_SHIFT) + /*The timer is enabled continuously*/ + | (CSL_TMR_ENAMODE_CONT << CSL_TMR_TCR_ENAMODE_LO_SHIFT) + | ((tmrCfg->pulseWidth << CSL_TMR_TCR_PWID_LO_SHIFT)&CSL_TMR_TCR_PWID_LO_MASK) + /*select pulse mode*/ + | (CSL_TMR_CP_PULSE << CSL_TMR_TCR_CP_LO_SHIFT) + | (CSL_TMR_INVINP_UNINVERTED << CSL_TMR_TCR_INVINP_LO_SHIFT) + | (CSL_TMR_INVOUTP_UNINVERTED << CSL_TMR_TCR_INVOUTP_LO_SHIFT) + | (0 << CSL_TMR_TCR_TSTAT_LO_SHIFT); + + /*active watchdog timer*/ + gp_timer_regs[tmrCfg->timer_num]->WDTCR = CSL_TMR_WDTCR_WDEN_MASK + | (CSL_TMR_WDTCR_WDKEY_CMD2 << CSL_TMR_WDTCR_WDKEY_SHIFT); + } + else if(TIMER_ONE_SHOT_PULSE == tmrCfg->timerMode) + { + gp_timer_regs[tmrCfg->timer_num]->TCR = + (CSL_TMR_CLOCK_INP_NOGATE << CSL_TMR_TCR_TIEN_LO_SHIFT) + | (CSL_TMR_CLKSRC_INTERNAL << CSL_TMR_TCR_CLKSRC_LO_SHIFT) + /*The timer is enabled one-shot*/ + | (CSL_TMR_ENAMODE_ENABLE << CSL_TMR_TCR_ENAMODE_LO_SHIFT) + | ((tmrCfg->pulseWidth << CSL_TMR_TCR_PWID_LO_SHIFT)&CSL_TMR_TCR_PWID_LO_MASK) + /*select pulse mode*/ + | (CSL_TMR_CP_PULSE << CSL_TMR_TCR_CP_LO_SHIFT) + | (CSL_TMR_INVINP_UNINVERTED << CSL_TMR_TCR_INVINP_LO_SHIFT) + | (CSL_TMR_INVOUTP_UNINVERTED << CSL_TMR_TCR_INVOUTP_LO_SHIFT) + | (0 << CSL_TMR_TCR_TSTAT_LO_SHIFT); + } + else if(TIMER_PERIODIC_CLOCK == tmrCfg->timerMode) + { + gp_timer_regs[tmrCfg->timer_num]->TCR = + (CSL_TMR_CLOCK_INP_NOGATE << CSL_TMR_TCR_TIEN_LO_SHIFT) + | (CSL_TMR_CLKSRC_INTERNAL << CSL_TMR_TCR_CLKSRC_LO_SHIFT) + /*The timer is enabled continuously*/ + | (CSL_TMR_ENAMODE_CONT << CSL_TMR_TCR_ENAMODE_LO_SHIFT) + | ((tmrCfg->pulseWidth << CSL_TMR_TCR_PWID_LO_SHIFT)&CSL_TMR_TCR_PWID_LO_MASK) + /*select clock mode*/ + | (CSL_TMR_CP_CLOCK << CSL_TMR_TCR_CP_LO_SHIFT) + | (CSL_TMR_INVINP_UNINVERTED << CSL_TMR_TCR_INVINP_LO_SHIFT) + | (CSL_TMR_INVOUTP_UNINVERTED << CSL_TMR_TCR_INVOUTP_LO_SHIFT) + | (0 << CSL_TMR_TCR_TSTAT_LO_SHIFT); + } + else if(TIMER_PERIODIC_WAVE == tmrCfg->timerMode) + { + gp_timer_regs[tmrCfg->timer_num]->TCR = + (CSL_TMR_CLOCK_INP_NOGATE << CSL_TMR_TCR_TIEN_LO_SHIFT) + | (CSL_TMR_CLKSRC_INTERNAL << CSL_TMR_TCR_CLKSRC_LO_SHIFT) + /*The timer is enabled continuously with period reload*/ + | (CSL_TMR_ENAMODE_CONT_RELOAD << CSL_TMR_TCR_ENAMODE_LO_SHIFT) + | ((tmrCfg->pulseWidth << CSL_TMR_TCR_PWID_LO_SHIFT)&CSL_TMR_TCR_PWID_LO_MASK) + /*select clock mode*/ + | (CSL_TMR_CP_CLOCK << CSL_TMR_TCR_CP_LO_SHIFT) + | (CSL_TMR_INVINP_UNINVERTED << CSL_TMR_TCR_INVINP_LO_SHIFT) + | (CSL_TMR_INVOUTP_UNINVERTED << CSL_TMR_TCR_INVOUTP_LO_SHIFT) + | (0 << CSL_TMR_TCR_TSTAT_LO_SHIFT); + } + else /*TIMER_PERIODIC_PULSE*/ + { + gp_timer_regs[tmrCfg->timer_num]->TCR = + (CSL_TMR_CLOCK_INP_NOGATE << CSL_TMR_TCR_TIEN_LO_SHIFT) + | (CSL_TMR_CLKSRC_INTERNAL << CSL_TMR_TCR_CLKSRC_LO_SHIFT) + /*The timer is enabled continuously*/ + | (CSL_TMR_ENAMODE_CONT << CSL_TMR_TCR_ENAMODE_LO_SHIFT) + | ((tmrCfg->pulseWidth << CSL_TMR_TCR_PWID_LO_SHIFT)&CSL_TMR_TCR_PWID_LO_MASK) + /*select clock mode*/ + | (CSL_TMR_CP_PULSE << CSL_TMR_TCR_CP_LO_SHIFT) + | (CSL_TMR_INVINP_UNINVERTED << CSL_TMR_TCR_INVINP_LO_SHIFT) + | (CSL_TMR_INVOUTP_UNINVERTED << CSL_TMR_TCR_INVOUTP_LO_SHIFT) + | (0 << CSL_TMR_TCR_TSTAT_LO_SHIFT); + } +} diff --git a/bsp/tms320c6678/common/common.h b/bsp/tms320c6678/common/common.h new file mode 100644 index 0000000000..de19893748 --- /dev/null +++ b/bsp/tms320c6678/common/common.h @@ -0,0 +1,110 @@ +/* + * 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 __COMMON_H__ +#define __COMMON_H__ + +#include +#include +#include +#include +#include +#include + +/* DSP core clock speed in Hz */ +#define DSP_CORE_SPEED_HZ 1000000000 + +extern CSL_CgemRegs * gp_cgem_regs; +extern CSL_BootcfgRegs * gp_bootcfg_regs; + +/*----------------------Timer plus registers definition----------------*/ +typedef struct { + volatile unsigned int PID12; + volatile unsigned int EMUMGT_CLKSPD; + volatile unsigned int GPINT_EN; + volatile unsigned int GPDIR_DAT; + volatile unsigned int CNTLO; + volatile unsigned int CNTHI; + volatile unsigned int PRDLO; + volatile unsigned int PRDHI; + volatile unsigned int TCR; + volatile unsigned int TGCR; + volatile unsigned int WDTCR; + volatile unsigned int TLGC; + volatile unsigned int TLMR; + volatile unsigned int RELLO; + volatile unsigned int RELHI; + volatile unsigned int CAPLO; + volatile unsigned int CAPHI; + volatile unsigned int INTCTL_STAT; + volatile unsigned char RSVD0[24]; + volatile unsigned int TIMERLO_COMPARE_REG[8]; + volatile unsigned char RSVD1[32]; +} CSL_TmrPlusRegs; + +#define TMR_TCR_READRSTMODE_HI_SHIFT (26) +#define TMR_TCR_CAPEVTMODE_LO_SHIFT (12) +#define TMR_TCR_CAPMODE_LO_SHIFT (11) +#define TMR_TCR_READRSTMODE_LO_SHIFT (10) + +#define TMR_TCR_READRSTMODE_HI_MASK (1<<26) +#define TMR_TCR_CAPEVTMODE_LO_MASK (3<<12) +#define TMR_TCR_CAPMODE_LO_MASK (1<<11) +#define TMR_TCR_READRSTMODE_LO_MASK (1<<10) + +#define TMR_TGCR_PLUSEN_SHIFT 4 +#define TMR_TGCR_PLUSEN_MASK (1<<4) + +#define TMR_INTCTLSTAT_EN_ALL_CLR_ALL 0x000F000F + +#define CSL_TMR_WDTCR_WDKEY_CMD1 (0x0000A5C6u) +#define CSL_TMR_WDTCR_WDKEY_CMD2 (0x0000DA7Eu) + +#define CSL_TMR_ENAMODE_CONT_RELOAD 3 + +extern CSL_TmrPlusRegs * gp_timer0_regs; +extern CSL_TmrPlusRegs * gp_timer1_regs; +extern CSL_TmrPlusRegs * gp_timer2_regs; +extern CSL_TmrPlusRegs * gp_timer3_regs; +extern CSL_TmrPlusRegs * gp_timer4_regs; +extern CSL_TmrPlusRegs * gp_timer5_regs; +extern CSL_TmrPlusRegs * gp_timer6_regs; +extern CSL_TmrPlusRegs * gp_timer7_regs; +extern CSL_TmrPlusRegs * gp_timer8_regs; +extern CSL_TmrPlusRegs * gp_timer_regs[]; + +typedef enum +{ + TIMER_ONE_SHOT_PULSE = 0, /*generate one shot pulse with timer*/ + TIMER_PERIODIC_PULSE, /*generate periodic pulse with timer*/ + TIMER_PERIODIC_CLOCK, /*generate periodic clock with timer*/ + /*generate periodic square wave with period reload feature, the difference + between wave and clock is the duty cycle of clock is always 50%*/ + TIMER_PERIODIC_WAVE, + TIMER_WATCH_DOG /*configure timer as watch dog*/ +}TTimerMode; + +typedef struct { + int timer_num; /*select one timer*/ + TTimerMode timerMode; /*select function of the timer*/ + unsigned long long period; /*in the unit of DSP core clock/6*/ + unsigned long long reload_period; /*the reload value of period*/ + int pulseWidth; /*pulse width between 0~3*/ +}Timer64_Config; + +/* Reset a 64-bit timer */ +extern void reset_timer(int timer_num); + +/* Initailize a 64-bit timer */ +extern void timer64_init(Timer64_Config * tmrCfg); + +extern void keystone_cpu_init(void); + +#endif /* __COMMON_H__ */ diff --git a/bsp/tms320c6678/driver/drv_timer.c b/bsp/tms320c6678/driver/drv_timer.c new file mode 100644 index 0000000000..56cc266645 --- /dev/null +++ b/bsp/tms320c6678/driver/drv_timer.c @@ -0,0 +1,66 @@ +/* + * 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 "drv_timer.h" +#include "interrupt.h" +#include "common.h" + +#include +#include + +/** + * This is the timer interrupt service routine. + * + */ +void rt_hw_systick_isr(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + rt_tick_increase(); + + /* leave interrupt */ + rt_interrupt_leave(); +} + +/** + * The function initial system timer interrupt. + */ +void rt_hw_system_timer_init(void) +{ + // initial system timer interrupt, map local timer interrupt to INT14 + gp_cgem_regs->INTMUX3 = (CSL_GEM_TINTLN << CSL_CGEM_INTMUX3_INTSEL14_SHIFT); + // enable CPU INT14 + rt_hw_interrupt_umask(1 << 14); + + return ; +} + +/** + * The function initial system timer. + * Use local timer (== DNUM of a core) to generate a clock on TIMO0,interrupts are generated as well + * + */ +void rt_hw_system_timer_start(void) +{ + Timer64_Config tmrCfg; + + // select output on TIMO0 from local timer. + gp_bootcfg_regs->TOUTSEL = (DNUM*2) << CSL_BOOTCFG_TOUTSEL_TOUTSEL0_SHIFT; + + // configure the timer to generate clocks and interrupts + tmrCfg.timer_num = DNUM; + tmrCfg.timerMode = TIMER_PERIODIC_CLOCK; + tmrCfg.period = (unsigned long long) RT_TICK_PER_SECOND * DSP_CORE_SPEED_HZ / 6000; + tmrCfg.reload_period = 0; + + // initial timer + timer64_init(&tmrCfg); +} diff --git a/bsp/tms320c6678/driver/drv_timer.h b/bsp/tms320c6678/driver/drv_timer.h new file mode 100644 index 0000000000..4545fdab6c --- /dev/null +++ b/bsp/tms320c6678/driver/drv_timer.h @@ -0,0 +1,22 @@ +/* + * 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 __SYS_TIMER_H__ +#define __SYS_TIMER_H__ + +#include +#include + +void rt_hw_system_timer_init(void); + +void rt_hw_system_timer_start(void); + +#endif /* __SYS_TIMER_H__ */ + diff --git a/bsp/tms320c6678/figures/debug(1).png b/bsp/tms320c6678/figures/debug(1).png new file mode 100644 index 0000000000..00f7616b49 Binary files /dev/null and b/bsp/tms320c6678/figures/debug(1).png differ diff --git a/bsp/tms320c6678/figures/debug(2).png b/bsp/tms320c6678/figures/debug(2).png new file mode 100644 index 0000000000..35d6f4e85f Binary files /dev/null and b/bsp/tms320c6678/figures/debug(2).png differ diff --git a/bsp/tms320c6678/figures/filepath.png b/bsp/tms320c6678/figures/filepath.png new file mode 100644 index 0000000000..71a11da2fd Binary files /dev/null and b/bsp/tms320c6678/figures/filepath.png differ diff --git a/bsp/tms320c6678/figures/general.jpg b/bsp/tms320c6678/figures/general.jpg new file mode 100644 index 0000000000..52b8ca9ffd Binary files /dev/null and b/bsp/tms320c6678/figures/general.jpg differ diff --git a/bsp/tms320c6678/figures/import(1).png b/bsp/tms320c6678/figures/import(1).png new file mode 100644 index 0000000000..9bc4eac5d2 Binary files /dev/null and b/bsp/tms320c6678/figures/import(1).png differ diff --git a/bsp/tms320c6678/figures/import(2).png b/bsp/tms320c6678/figures/import(2).png new file mode 100644 index 0000000000..d9d29af981 Binary files /dev/null and b/bsp/tms320c6678/figures/import(2).png differ diff --git a/bsp/tms320c6678/figures/load.png b/bsp/tms320c6678/figures/load.png new file mode 100644 index 0000000000..99d3b5f51c Binary files /dev/null and b/bsp/tms320c6678/figures/load.png differ diff --git a/bsp/tms320c6678/rtconfig.h b/bsp/tms320c6678/rtconfig.h new file mode 100644 index 0000000000..84e6488175 --- /dev/null +++ b/bsp/tms320c6678/rtconfig.h @@ -0,0 +1,122 @@ +#ifndef RT_CONFIG_H__ +#define RT_CONFIG_H__ + +/* Automatically generated file; DO NOT EDIT. */ +/* RT-Thread Configuration */ + +#define SOC_C6678 + +/* RT-Thread Kernel */ + +#define RT_NAME_MAX 8 +#define RT_USING_ARCH_DATA_TYPE +#define RT_ALIGN_SIZE 4 +#define RT_THREAD_PRIORITY_8 +#define RT_THREAD_PRIORITY_MAX 8 +#define RT_TICK_PER_SECOND 100 +//#define RT_USING_HOOK +//#define RT_USING_IDLE_HOOK +//#define RT_IDLE_HOOK_LIST_SIZE 4 +#define IDLE_THREAD_STACK_SIZE 4096 +//#define RT_DEBUG +//#define RT_DEBUG_COLOR + +/* Inter-Thread communication */ + +#define RT_USING_SEMAPHORE +#define RT_USING_MUTEX +#define RT_USING_EVENT +#define RT_USING_MAILBOX +#define RT_USING_MESSAGEQUEUE + +/* Memory Management */ + +#define RT_USING_MEMPOOL +#define RT_USING_SMALL_MEM +#define RT_USING_HEAP + +/* Kernel Device Object */ + +/* RT-Thread Components */ + +/* C++ features */ + + +/* Command shell */ + +/* Device virtual file system */ + + +/* Device Drivers */ + +/* Using WiFi */ + + +/* Using USB */ + + +/* POSIX layer and C standard library */ + + +/* Network */ + +/* Socket abstraction layer */ + + +/* light weight TCP/IP stack */ + + +/* Modbus master and slave stack */ + + +/* AT commands */ + + +/* VBUS(Virtual Software BUS) */ + + +/* Utilities */ + + +/* RT-Thread online packages */ + +/* IoT - internet of things */ + + +/* Wi-Fi */ + +/* Marvell WiFi */ + + +/* Wiced WiFi */ + + +/* IoT Cloud */ + + +/* security packages */ + + +/* language packages */ + + +/* multimedia packages */ + + +/* tools packages */ + + +/* system packages */ + + +/* peripheral libraries and drivers */ + + +/* miscellaneous packages */ + + +/* samples: kernel and components samples */ + +#include "rtconfig_project.h" + +#endif diff --git a/bsp/tms320c6678/rtconfig_project.h b/bsp/tms320c6678/rtconfig_project.h new file mode 100644 index 0000000000..104f3139c7 --- /dev/null +++ b/bsp/tms320c6678/rtconfig_project.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-03-27 xuzhuoyi the first version + */ + +#ifndef __RTCONFIG_PROJECT_H__ +#define __RTCONFIG_PROJECT_H__ + +typedef signed char rt_int8_t; /**< 8bit integer type */ +typedef signed short rt_int16_t; /**< 16bit integer type */ +typedef signed long rt_int32_t; /**< 32bit integer type */ +typedef signed long long rt_int64_t; /**< 64bit integer type */ +typedef unsigned char rt_uint8_t; /**< 8bit unsigned integer type */ +typedef unsigned short rt_uint16_t; /**< 16bit unsigned integer type */ +typedef unsigned long rt_uint32_t; /**< 32bit unsigned integer type */ +typedef unsigned long long rt_uint64_t; /**< 64bit unsigned integer type */ + +#endif 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 +#include + +#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 +#include + +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 +#include + +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 +#include +#include + +#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