diff options
| author | Bernard Xiong <[email protected]> | 2020-09-22 22:03:26 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2020-09-22 22:03:26 +0800 |
| commit | d92fbba3c1dfd304b377da2d6d48e317c10fc3c4 (patch) | |
| tree | 3a6f0539b28286f5721c4b5d7d482fd4a7fea4b4 /libcpu | |
| parent | 8302a7224302c0624b9918855a25e12f3a3ede59 (diff) | |
| parent | 60287b69fdff377ea9fdfd2f06b4ea3f6f34e32a (diff) | |
Merge pull request #3919 from wormsX/T-head_Smart-v1.0.0
add t-head smart-evb bsp, and risc-v cpu e906
Diffstat (limited to 'libcpu')
| -rw-r--r-- | libcpu/risc-v/SConscript | 13 | ||||
| -rw-r--r-- | libcpu/risc-v/t-head/e906/SConscript | 12 | ||||
| -rw-r--r-- | libcpu/risc-v/t-head/e906/context_gcc.S | 323 | ||||
| -rw-r--r-- | libcpu/risc-v/t-head/e906/cpuport.c | 170 | ||||
| -rw-r--r-- | libcpu/risc-v/t-head/e906/cpuport.h | 55 |
5 files changed, 570 insertions, 3 deletions
diff --git a/libcpu/risc-v/SConscript b/libcpu/risc-v/SConscript index 024cc5ba44..5055b533e6 100644 --- a/libcpu/risc-v/SConscript +++ b/libcpu/risc-v/SConscript @@ -10,10 +10,17 @@ group = [] list = os.listdir(cwd) # add common code files -if rtconfig.CPU != "nuclei": - group = group + SConscript(os.path.join('common', 'SConscript')) +if rtconfig.VENDOR == "t-head" : + group = group +elif rtconfig.CPU == "nuclei" : + group = group +else : + group = group + SConscript(os.path.join(cwd, 'common', 'SConscript')) # cpu porting code files -group = group + SConscript(os.path.join(rtconfig.CPU, 'SConscript')) +if rtconfig.VENDOR == "t-head" : + group = group + SConscript(os.path.join(cwd, rtconfig.VENDOR, rtconfig.CPU, 'SConscript')) +else : + group = group + SConscript(os.path.join(cwd, rtconfig.CPU, 'SConscript')) Return('group') diff --git a/libcpu/risc-v/t-head/e906/SConscript b/libcpu/risc-v/t-head/e906/SConscript new file mode 100644 index 0000000000..2f698f530a --- /dev/null +++ b/libcpu/risc-v/t-head/e906/SConscript @@ -0,0 +1,12 @@ +# RT-Thread building script for component + +from building import * + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') +CPPPATH = [cwd] +ASFLAGS = '' + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS) + +Return('group') diff --git a/libcpu/risc-v/t-head/e906/context_gcc.S b/libcpu/risc-v/t-head/e906/context_gcc.S new file mode 100644 index 0000000000..2f5223ae63 --- /dev/null +++ b/libcpu/risc-v/t-head/e906/context_gcc.S @@ -0,0 +1,323 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020/08/20 zx.chen The T-HEAD RISC-V CPU E906 porting implementation + */ + +#include "cpuport.h" + +#ifdef RT_USING_SMP +#define rt_hw_interrupt_disable rt_hw_local_irq_disable +#define rt_hw_interrupt_enable rt_hw_local_irq_enable +#endif + +/* + * Functions: vPortYield + */ +.global vPortYield +.type vPortYield, %function +vPortYield: + li t0, 0xE080100C + lb t1, (t0) + li t2, 0x01 + or t1, t1, t2 + sb t1, (t0) + + ret + + + +/* + * #ifdef RT_USING_SMP + * void rt_hw_context_switch_to(rt_ubase_t to, stuct rt_thread *to_thread); + * #else + * void rt_hw_context_switch_to(rt_ubase_t to); + * #endif + * a0 --> to + * a1 --> to_thread + */ + .globl rt_hw_context_switch_to +rt_hw_context_switch_to: + /* save a0 to to_thread */ + la t0, rt_interrupt_to_thread + STORE a0, (t0) + + /* save 0 to from_thread */ + la t0, rt_interrupt_from_thread + li t1, 0 + STORE t1, (t0) + + /* set rt_thread_switch_interrupt_flag=1 */ + la t0, rt_thread_switch_interrupt_flag + li t1, 1 + STORE t1, (t0) + + /* enable mexstatus SPUSHEN and SPSWAPEN */ +#if ((CONFIG_CPU_E906==1) || (CONFIG_CPU_E906F==1) || (CONFIG_CPU_E906FD==1)) + uint32_t mexstatus; + mexstatus = __get_MEXSTATUS(); + mexstatus |= (0x2 << 16); + __set_MEXSTATUS(mexstatus); +#endif + + csrw mscratch, sp + /* set software interrupt */ + li t0, 0xE080100C + lb t1, (t0) + li t2, 0x01 + or t1, t1, t2 + sb t1, (t0) + + /* enable global interrup */ + csrsi mstatus, 8 + + ret + +/* + * #ifdef RT_USING_SMP + * void rt_hw_context_switch(rt_ubase_t from, rt_ubase_t to, struct rt_thread *to_thread); + * #else + * void rt_hw_context_switch(rt_ubase_t from, rt_ubase_t to); + * #endif + * + * a0 --> from + * a1 --> to + * a2 --> to_thread + */ + .globl rt_hw_context_switch +rt_hw_context_switch: + .globl rt_hw_context_switch_interrupt +rt_hw_context_switch_interrupt: + /* check rt_thread_switch_interrupt_flag */ + la t0, rt_thread_switch_interrupt_flag + lw t1, (t0) + li t2, 1 + beq t1, t2, .reswitch + /* set rt_thread_switch_interrupt_flag=1 */ + STORE t2, (t0) + + /* update from_thread */ + la t0, rt_interrupt_from_thread + STORE a0, (t0) + +.reswitch: + /* update to_thread */ + la t0, rt_interrupt_to_thread + STORE a1, (t0) + /* set software interrupt */ + li t0, 0xE080100C + lb t1, (t0) + li t2, 0x01 + or t1, t1, t2 + sb t1, (t0) + + ret + +/* + * PendSV_Handler + */ +.global PendSV_Handler +.type PendSV_Handler, %function +PendSV_Handler: + + /* check rt_thread_switch_interrupt_flag */ + sw t0, (-4)(sp) + sw t1, (-8)(sp) + la t0, rt_thread_switch_interrupt_flag + lw t1, (t0) + beqz t1, .pendsv_exit + + /* clear rt_thread_switch_interrupt_flag */ + li t1, 0x0 + sw t1, (t0) + + /* check rt_interrupt_from_thread */ + la t0, rt_interrupt_from_thread + lw t1, (t0) + beqz t1, .switch_to_thead + + /* save from thread context */ + lw t0, (-4)(sp) + lw t1, (-8)(sp) + +#ifdef ARCH_RISCV_FPU + addi sp, sp, -32 * FREGBYTES + + FSTORE f0, 0 * FREGBYTES(sp) + FSTORE f1, 1 * FREGBYTES(sp) + FSTORE f2, 2 * FREGBYTES(sp) + FSTORE f3, 3 * FREGBYTES(sp) + FSTORE f4, 4 * FREGBYTES(sp) + FSTORE f5, 5 * FREGBYTES(sp) + FSTORE f6, 6 * FREGBYTES(sp) + FSTORE f7, 7 * FREGBYTES(sp) + FSTORE f8, 8 * FREGBYTES(sp) + FSTORE f9, 9 * FREGBYTES(sp) + FSTORE f10, 10 * FREGBYTES(sp) + FSTORE f11, 11 * FREGBYTES(sp) + FSTORE f12, 12 * FREGBYTES(sp) + FSTORE f13, 13 * FREGBYTES(sp) + FSTORE f14, 14 * FREGBYTES(sp) + FSTORE f15, 15 * FREGBYTES(sp) + FSTORE f16, 16 * FREGBYTES(sp) + FSTORE f17, 17 * FREGBYTES(sp) + FSTORE f18, 18 * FREGBYTES(sp) + FSTORE f19, 19 * FREGBYTES(sp) + FSTORE f20, 20 * FREGBYTES(sp) + FSTORE f21, 21 * FREGBYTES(sp) + FSTORE f22, 22 * FREGBYTES(sp) + FSTORE f23, 23 * FREGBYTES(sp) + FSTORE f24, 24 * FREGBYTES(sp) + FSTORE f25, 25 * FREGBYTES(sp) + FSTORE f26, 26 * FREGBYTES(sp) + FSTORE f27, 27 * FREGBYTES(sp) + FSTORE f28, 28 * FREGBYTES(sp) + FSTORE f29, 29 * FREGBYTES(sp) + FSTORE f30, 30 * FREGBYTES(sp) + FSTORE f31, 31 * FREGBYTES(sp) +#endif + + addi sp, sp, -32 * REGBYTES + + STORE x1, 1 * REGBYTES(sp) + csrr x1, mepc + STORE x1, 0 * REGBYTES(sp) + csrr x1, mstatus + andi x1, x1, 8 + beqz x1, .save_mpie + li x1, 0x80 +.save_mpie: + STORE x1, 2 * REGBYTES(sp) + /* x3 don't need save */ + STORE x4, 4 * REGBYTES(sp) + STORE x5, 5 * REGBYTES(sp) + STORE x6, 6 * REGBYTES(sp) + STORE x7, 7 * REGBYTES(sp) + STORE x8, 8 * REGBYTES(sp) + STORE x9, 9 * REGBYTES(sp) + STORE x10, 10 * REGBYTES(sp) + STORE x11, 11 * REGBYTES(sp) + STORE x12, 12 * REGBYTES(sp) + STORE x13, 13 * REGBYTES(sp) + STORE x14, 14 * REGBYTES(sp) + STORE x15, 15 * REGBYTES(sp) + STORE x16, 16 * REGBYTES(sp) + STORE x17, 17 * REGBYTES(sp) + STORE x18, 18 * REGBYTES(sp) + STORE x19, 19 * REGBYTES(sp) + STORE x20, 20 * REGBYTES(sp) + STORE x21, 21 * REGBYTES(sp) + STORE x22, 22 * REGBYTES(sp) + STORE x23, 23 * REGBYTES(sp) + STORE x24, 24 * REGBYTES(sp) + STORE x25, 25 * REGBYTES(sp) + STORE x26, 26 * REGBYTES(sp) + STORE x27, 27 * REGBYTES(sp) + STORE x28, 28 * REGBYTES(sp) + STORE x29, 29 * REGBYTES(sp) + STORE x30, 30 * REGBYTES(sp) + STORE x31, 31 * REGBYTES(sp) + + /* store from_thread sp */ + la t0, rt_interrupt_from_thread + lw t0, (t0) + sw sp, (t0) + +.switch_to_thead: + /* restore to thread context + * sp(0) -> epc; + * sp(1) -> ra; + * sp(i) -> x(i+2) + */ + la t0, rt_interrupt_to_thread + lw t0, (t0) + LOAD sp, (t0) + + /* restore ra to mepc */ + LOAD a1, 0 * REGBYTES(sp) + csrw mepc, a1 + LOAD x1, 1 * REGBYTES(sp) + + /* force to machin mode(MPP=11) */ + li a1, 0x1880 + csrs mstatus, a1 + LOAD a1, 2 * REGBYTES(sp) + csrs mstatus, a1 + /* x3 don't need restore */ + LOAD x4, 4 * REGBYTES(sp) + LOAD x5, 5 * REGBYTES(sp) + LOAD x6, 6 * REGBYTES(sp) + LOAD x7, 7 * REGBYTES(sp) + LOAD x8, 8 * REGBYTES(sp) + LOAD x9, 9 * REGBYTES(sp) + LOAD x10, 10 * REGBYTES(sp) + LOAD x11, 11 * REGBYTES(sp) + LOAD x12, 12 * REGBYTES(sp) + LOAD x13, 13 * REGBYTES(sp) + LOAD x14, 14 * REGBYTES(sp) + LOAD x15, 15 * REGBYTES(sp) + LOAD x16, 16 * REGBYTES(sp) + LOAD x17, 17 * REGBYTES(sp) + LOAD x18, 18 * REGBYTES(sp) + LOAD x19, 19 * REGBYTES(sp) + LOAD x20, 20 * REGBYTES(sp) + LOAD x21, 21 * REGBYTES(sp) + LOAD x22, 22 * REGBYTES(sp) + LOAD x23, 23 * REGBYTES(sp) + LOAD x24, 24 * REGBYTES(sp) + LOAD x25, 25 * REGBYTES(sp) + LOAD x26, 26 * REGBYTES(sp) + LOAD x27, 27 * REGBYTES(sp) + LOAD x28, 28 * REGBYTES(sp) + LOAD x29, 29 * REGBYTES(sp) + LOAD x30, 30 * REGBYTES(sp) + LOAD x31, 31 * REGBYTES(sp) + + addi sp, sp, 32 * REGBYTES + +#ifdef ARCH_RISCV_FPU + FLOAD f0, 0 * FREGBYTES(sp) + FLOAD f1, 1 * FREGBYTES(sp) + FLOAD f2, 2 * FREGBYTES(sp) + FLOAD f3, 3 * FREGBYTES(sp) + FLOAD f4, 4 * FREGBYTES(sp) + FLOAD f5, 5 * FREGBYTES(sp) + FLOAD f6, 6 * FREGBYTES(sp) + FLOAD f7, 7 * FREGBYTES(sp) + FLOAD f8, 8 * FREGBYTES(sp) + FLOAD f9, 9 * FREGBYTES(sp) + FLOAD f10, 10 * FREGBYTES(sp) + FLOAD f11, 11 * FREGBYTES(sp) + FLOAD f12, 12 * FREGBYTES(sp) + FLOAD f13, 13 * FREGBYTES(sp) + FLOAD f14, 14 * FREGBYTES(sp) + FLOAD f15, 15 * FREGBYTES(sp) + FLOAD f16, 16 * FREGBYTES(sp) + FLOAD f17, 17 * FREGBYTES(sp) + FLOAD f18, 18 * FREGBYTES(sp) + FLOAD f19, 19 * FREGBYTES(sp) + FLOAD f20, 20 * FREGBYTES(sp) + FLOAD f21, 21 * FREGBYTES(sp) + FLOAD f22, 22 * FREGBYTES(sp) + FLOAD f23, 23 * FREGBYTES(sp) + FLOAD f24, 24 * FREGBYTES(sp) + FLOAD f25, 25 * FREGBYTES(sp) + FLOAD f26, 26 * FREGBYTES(sp) + FLOAD f27, 27 * FREGBYTES(sp) + FLOAD f28, 28 * FREGBYTES(sp) + FLOAD f29, 29 * FREGBYTES(sp) + FLOAD f30, 30 * FREGBYTES(sp) + FLOAD f31, 31 * FREGBYTES(sp) + + addi sp, sp, 32 * FREGBYTES +#endif + +.pendsv_exit: + mret + + + diff --git a/libcpu/risc-v/t-head/e906/cpuport.c b/libcpu/risc-v/t-head/e906/cpuport.c new file mode 100644 index 0000000000..5597aa237a --- /dev/null +++ b/libcpu/risc-v/t-head/e906/cpuport.c @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020/08/20 zx.chen The T-HEAD RISC-V CPU E906 porting code. + */ + +#include <rthw.h> +#include <rtthread.h> + +#include "cpuport.h" + +#ifndef RT_USING_SMP +volatile rt_ubase_t rt_interrupt_from_thread = 0; +volatile rt_ubase_t rt_interrupt_to_thread = 0; +volatile rt_uint32_t rt_thread_switch_interrupt_flag = 0; +#endif + +struct rt_hw_stack_frame +{ + rt_ubase_t epc; /* epc - epc - program counter */ + rt_ubase_t ra; /* x1 - ra - return address for jumps */ + rt_ubase_t mstatus; /* - machine status register */ + rt_ubase_t gp; /* x3 - gp - global pointer */ + rt_ubase_t tp; /* x4 - tp - thread pointer */ + rt_ubase_t t0; /* x5 - t0 - temporary register 0 */ + rt_ubase_t t1; /* x6 - t1 - temporary register 1 */ + rt_ubase_t t2; /* x7 - t2 - temporary register 2 */ + rt_ubase_t s0_fp; /* x8 - s0/fp - saved register 0 or frame pointer */ + rt_ubase_t s1; /* x9 - s1 - saved register 1 */ + rt_ubase_t a0; /* x10 - a0 - return value or function argument 0 */ + rt_ubase_t a1; /* x11 - a1 - return value or function argument 1 */ + rt_ubase_t a2; /* x12 - a2 - function argument 2 */ + rt_ubase_t a3; /* x13 - a3 - function argument 3 */ + rt_ubase_t a4; /* x14 - a4 - function argument 4 */ + rt_ubase_t a5; /* x15 - a5 - function argument 5 */ + rt_ubase_t a6; /* x16 - a6 - function argument 6 */ + rt_ubase_t a7; /* x17 - s7 - function argument 7 */ + rt_ubase_t s2; /* x18 - s2 - saved register 2 */ + rt_ubase_t s3; /* x19 - s3 - saved register 3 */ + rt_ubase_t s4; /* x20 - s4 - saved register 4 */ + rt_ubase_t s5; /* x21 - s5 - saved register 5 */ + rt_ubase_t s6; /* x22 - s6 - saved register 6 */ + rt_ubase_t s7; /* x23 - s7 - saved register 7 */ + rt_ubase_t s8; /* x24 - s8 - saved register 8 */ + rt_ubase_t s9; /* x25 - s9 - saved register 9 */ + rt_ubase_t s10; /* x26 - s10 - saved register 10 */ + rt_ubase_t s11; /* x27 - s11 - saved register 11 */ + rt_ubase_t t3; /* x28 - t3 - temporary register 3 */ + rt_ubase_t t4; /* x29 - t4 - temporary register 4 */ + rt_ubase_t t5; /* x30 - t5 - temporary register 5 */ + rt_ubase_t t6; /* x31 - t6 - temporary register 6 */ +#ifdef ARCH_RISCV_FPU + rv_floatreg_t f0; /* f0 */ + rv_floatreg_t f1; /* f1 */ + rv_floatreg_t f2; /* f2 */ + rv_floatreg_t f3; /* f3 */ + rv_floatreg_t f4; /* f4 */ + rv_floatreg_t f5; /* f5 */ + rv_floatreg_t f6; /* f6 */ + rv_floatreg_t f7; /* f7 */ + rv_floatreg_t f8; /* f8 */ + rv_floatreg_t f9; /* f9 */ + rv_floatreg_t f10; /* f10 */ + rv_floatreg_t f11; /* f11 */ + rv_floatreg_t f12; /* f12 */ + rv_floatreg_t f13; /* f13 */ + rv_floatreg_t f14; /* f14 */ + rv_floatreg_t f15; /* f15 */ + rv_floatreg_t f16; /* f16 */ + rv_floatreg_t f17; /* f17 */ + rv_floatreg_t f18; /* f18 */ + rv_floatreg_t f19; /* f19 */ + rv_floatreg_t f20; /* f20 */ + rv_floatreg_t f21; /* f21 */ + rv_floatreg_t f22; /* f22 */ + rv_floatreg_t f23; /* f23 */ + rv_floatreg_t f24; /* f24 */ + rv_floatreg_t f25; /* f25 */ + rv_floatreg_t f26; /* f26 */ + rv_floatreg_t f27; /* f27 */ + rv_floatreg_t f28; /* f28 */ + rv_floatreg_t f29; /* f29 */ + rv_floatreg_t f30; /* f30 */ + rv_floatreg_t f31; /* f31 */ +#endif +}; + +/** + * 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) +{ + struct rt_hw_stack_frame *frame; + rt_uint8_t *stk; + int i; + + stk = stack_addr + sizeof(rt_ubase_t); + stk = (rt_uint8_t *)RT_ALIGN_DOWN((rt_ubase_t)stk, REGBYTES); + stk -= sizeof(struct rt_hw_stack_frame); + + frame = (struct rt_hw_stack_frame *)stk; + + for (i = 0; i < sizeof(struct rt_hw_stack_frame) / sizeof(rt_ubase_t); i++) + { + ((rt_ubase_t *)frame)[i] = 0xdeadbeef; + } + + frame->ra = (rt_ubase_t)texit; + frame->a0 = (rt_ubase_t)parameter; + frame->epc = (rt_ubase_t)tentry; + + /* force to machine mode(MPP=11) and set MPIE to 1 */ + frame->mstatus = 0x00007880; + + return stk; +} + + +/** + * This function will disable global interrupt + * + * @param none + * + * @return zero + */ + +rt_base_t rt_hw_interrupt_disable(void) +{ + __asm volatile("csrc mstatus, 8"); + return 0; +} + +/** + * This function will ennable global interrupt + * + * @param level not used + * + * @return none + */ +void rt_hw_interrupt_enable(rt_base_t level) +{ + __asm volatile("csrs mstatus, 8"); +} + +/** shutdown CPU */ +void rt_hw_cpu_shutdown() +{ + rt_uint32_t level; + rt_kprintf("shutdown...\n"); + + level = rt_hw_interrupt_disable(); + while (level) + { + RT_ASSERT(0); + } +} diff --git a/libcpu/risc-v/t-head/e906/cpuport.h b/libcpu/risc-v/t-head/e906/cpuport.h new file mode 100644 index 0000000000..90efc07653 --- /dev/null +++ b/libcpu/risc-v/t-head/e906/cpuport.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-08-20 zx.chen The first version + */ + +#ifndef CPUPORT_H__ +#define CPUPORT_H__ + +#include <rtconfig.h> + +/* bytes of register width */ +#ifdef ARCH_RISCV_64 +#define DFSTORE fsd +#define DFLOAD fld +#define SFSTORE fsw +#define SFLOAD flw +#define STORE sd +#define LOAD ld +#define REGBYTES 8 +#define SFREGBYTES 4 +#define DFREGBYTES 8 +#else +#define DFSTORE fsd +#define DFLOAD fld +#define SFSTORE fsw +#define SFLOAD flw +#define STORE sw +#define LOAD lw + +#define REGBYTES 4 +#define SFREGBYTES 4 +#define DFREGBYTES 8 +#endif + +#ifdef ARCH_RISCV_FPU +#ifdef ARCH_RISCV_FPU_D +#define FSTORE fsd +#define FLOAD fld +#define FREGBYTES 8 +#define rv_floatreg_t rt_int64_t +#endif +#ifdef ARCH_RISCV_FPU_S +#define FSTORE fsw +#define FLOAD flw +#define FREGBYTES 4 +#define rv_floatreg_t rt_int32_t +#endif +#endif + +#endif |
