From 93ae1c96cae7503294b725d0bcd97a80d8516b7b Mon Sep 17 00:00:00 2001 From: acevest Date: Sun, 6 Oct 2019 16:52:48 +0800 Subject: [PATCH 1/6] risc-v add irq stack --- arch/risc-v/common/tos_cpu.c | 10 +++++++++- arch/risc-v/rv32i/gcc/port_s.S | 12 ++++++++++++ board/GD32VF103C_START/TOS_CONFIG/tos_config.h | 3 +++ board/QEMU_Spike/TOS-CONFIG/tos_config.h | 1 + 4 files changed, 25 insertions(+), 1 deletion(-) diff --git a/arch/risc-v/common/tos_cpu.c b/arch/risc-v/common/tos_cpu.c index 3ae8f0ef..273f047b 100644 --- a/arch/risc-v/common/tos_cpu.c +++ b/arch/risc-v/common/tos_cpu.c @@ -1,6 +1,14 @@ #include #include +#ifndef TOS_CFG_IRQ_STK_SIZE +#warning "did not specify the irq stack size, use default value" +#define TOS_CFG_IRQ_STK_SIZE 128 +#endif + +k_stack_t k_irq_stk[TOS_CFG_IRQ_STK_SIZE]; +const k_stack_t *k_irq_stk_top = (k_stack_t *) ((char *)(k_irq_stk + TOS_CFG_IRQ_STK_SIZE) - sizeof(cpu_data_t)); + __KERNEL__ void cpu_systick_init(k_cycle_t cycle_per_tick) { port_systick_priority_set(TOS_CFG_CPU_SYSTICK_PRIO); @@ -9,6 +17,7 @@ __KERNEL__ void cpu_systick_init(k_cycle_t cycle_per_tick) __KERNEL__ void cpu_init(void) { k_cpu_cycle_per_tick = TOS_CFG_CPU_CLOCK / k_cpu_tick_per_second; + cpu_systick_init(k_cpu_cycle_per_tick); port_cpu_init(); @@ -173,4 +182,3 @@ __API__ uint32_t tos_cpu_clz(uint32_t val) return (nbr_lead_zeros); } - diff --git a/arch/risc-v/rv32i/gcc/port_s.S b/arch/risc-v/rv32i/gcc/port_s.S index 278cc199..233cc6cf 100644 --- a/arch/risc-v/rv32i/gcc/port_s.S +++ b/arch/risc-v/rv32i/gcc/port_s.S @@ -320,12 +320,24 @@ rv32_exception_entry: csrr t0, mstatus sw t0, __reg_mstatus__OFFSET(sp) + // switch to irq stack + mv t0, sp + la t1, k_irq_stk_top + lw sp, (t1) + andi sp, sp, 0xFFFFFFF0 + sw t0, (sp) + + // get irq num and call irq handler li t0, SOC_MCAUSE_EXP_MASK csrr a0, mcause and a0, a0, t0 call cpu_irq_entry + // switch back to task stack + lw t0, (sp) + mv sp, t0 + la t0, k_curr_task la t1, k_next_task diff --git a/board/GD32VF103C_START/TOS_CONFIG/tos_config.h b/board/GD32VF103C_START/TOS_CONFIG/tos_config.h index 939447d3..6c096ebf 100644 --- a/board/GD32VF103C_START/TOS_CONFIG/tos_config.h +++ b/board/GD32VF103C_START/TOS_CONFIG/tos_config.h @@ -48,6 +48,9 @@ // 配置TencentOS tiny空闲任务栈大小 #define TOS_CFG_IDLE_TASK_STK_SIZE 512u +// 配置TencentOS tiny中断栈大小 +#define TOS_CFG_IRQ_STK_SIZE 128u + // 配置TencentOS tiny的tick频率 #define TOS_CFG_CPU_TICK_PER_SECOND 1000u diff --git a/board/QEMU_Spike/TOS-CONFIG/tos_config.h b/board/QEMU_Spike/TOS-CONFIG/tos_config.h index 149d0915..2c46809f 100644 --- a/board/QEMU_Spike/TOS-CONFIG/tos_config.h +++ b/board/QEMU_Spike/TOS-CONFIG/tos_config.h @@ -43,5 +43,6 @@ #define TOS_CFG_MMBLK_EN 1u +#define TOS_CFG_IRQ_STK_SIZE 128u #endif /* INC_TOS_CONFIG_H_ */ From ae3ada8dfedee587d02eaeb5aac3b3dc75d4421c Mon Sep 17 00:00:00 2001 From: acevest Date: Sun, 6 Oct 2019 23:32:09 +0800 Subject: [PATCH 2/6] reduce one instruction when switch to irq stack --- arch/risc-v/bumblebee/gcc/riscv_port.h | 20 +++++++++--------- arch/risc-v/common/tos_cpu.c | 29 +++++++++++++++----------- arch/risc-v/rv32i/gcc/port_s.S | 5 +---- arch/risc-v/spike/gcc/riscv_port.h | 2 +- 4 files changed, 29 insertions(+), 27 deletions(-) diff --git a/arch/risc-v/bumblebee/gcc/riscv_port.h b/arch/risc-v/bumblebee/gcc/riscv_port.h index fca00a56..78b2aa44 100644 --- a/arch/risc-v/bumblebee/gcc/riscv_port.h +++ b/arch/risc-v/bumblebee/gcc/riscv_port.h @@ -25,16 +25,16 @@ #define CLINT_MTIME 0x0000 // the bumblebee mstatus register is different -// name bit detail -// INTERRUPT 31 0: exception or nmi, 1 irq -// MINHV 30 reading irq vector table -// MPP 29:28 == mstatus.MPP -// MPIE 27 == mstatus.MPIE -// Reserved 26:24 0 -// MPIL 23:16 previous interrupt level -// Reserved 15:12 0 -// EXCCODE 11:0 exception code -#define SOC_MCAUSE_EXP_MASK 0x00000FFF +// name bit detail +// INTERRUPT 31 0: exception or nmi, 1 irq +// MINHV 30 reading irq vector table +// MPP 29:28 == mstatus.MPP +// MPIE 27 == mstatus.MPIE +// Reserved 26:24 0 +// MPIL 23:16 previous interrupt level +// Reserved 15:12 0 +// EXCCODE 11:0 exception code +#define MCAUSE_EXP_CODE_MASK 0x00000FFF #ifndef __ASSEMBLER__ void port_cpu_init(); diff --git a/arch/risc-v/common/tos_cpu.c b/arch/risc-v/common/tos_cpu.c index 273f047b..ca77923a 100644 --- a/arch/risc-v/common/tos_cpu.c +++ b/arch/risc-v/common/tos_cpu.c @@ -7,7 +7,7 @@ #endif k_stack_t k_irq_stk[TOS_CFG_IRQ_STK_SIZE]; -const k_stack_t *k_irq_stk_top = (k_stack_t *) ((char *)(k_irq_stk + TOS_CFG_IRQ_STK_SIZE) - sizeof(cpu_data_t)); +k_stack_t *k_irq_stk_top = k_irq_stk + TOS_CFG_IRQ_STK_SIZE; __KERNEL__ void cpu_systick_init(k_cycle_t cycle_per_tick) { @@ -16,6 +16,12 @@ __KERNEL__ void cpu_systick_init(k_cycle_t cycle_per_tick) } __KERNEL__ void cpu_init(void) { + + // reserve storage space for sp registers + k_irq_stk_top = (k_stack_t *)(((cpu_addr_t) k_irq_stk_top) - sizeof(cpu_data_t)); + + k_irq_stk_top = (k_stack_t *)(((cpu_addr_t) k_irq_stk_top) & 0xFFFFFFFC); + k_cpu_cycle_per_tick = TOS_CFG_CPU_CLOCK / k_cpu_tick_per_second; cpu_systick_init(k_cpu_cycle_per_tick); @@ -97,27 +103,26 @@ __KERNEL__ k_stack_t *cpu_task_stk_init(void *entry, cpu_context_t *regs = 0; sp = (cpu_data_t *)&stk_base[stk_size]; - sp = (cpu_data_t *)((cpu_addr_t)(sp) & 0xFFFFFFF8); + sp = (cpu_data_t *)((cpu_addr_t)(sp) & 0xFFFFFFFC); sp -= (sizeof(cpu_context_t)/sizeof(cpu_data_t)); regs = (cpu_context_t*) sp; - for(int i=0; i<(sizeof(cpu_context_t)/sizeof(cpu_data_t)); i++) { - #define _V(v) ((unsigned int)((v/10) << 4 | (v % 10))) - *(sp + i) = (_V(i) << 24) | (_V(i) << 16) | (_V(i) << 8) | _V(i); - #undef _V + for(int i=1; i<(sizeof(cpu_context_t)/sizeof(cpu_data_t)); i+=2) { + // every task begin with "Tencent" + *(sp + i - 1) = 0x0054656E; + *(sp + i - 0) = 0x63656E74; } cpu_data_t gp = 0; __ASM__ __VOLATILE__ ("mv %0, gp":"=r"(gp)); - regs->gp = (cpu_data_t)gp; // gp: global pointer - regs->a0 = (cpu_data_t)arg; // a0: argument - regs->ra = (cpu_data_t)0xACE00ACE; // ra: return address - regs->mstatus = (cpu_data_t)0x00001880; // return to machine mode and enable interrupt - regs->mepc = (cpu_data_t)entry; - + regs->gp = (cpu_data_t)gp; // global pointer + regs->a0 = (cpu_data_t)arg; // argument + regs->ra = (cpu_data_t)0xACE00ACE; // return address + regs->mstatus = (cpu_data_t)0x00001880; // return to machine mode and enable interrupt + regs->epc = (cpu_data_t)entry; // task entry return (k_stack_t*)sp; } diff --git a/arch/risc-v/rv32i/gcc/port_s.S b/arch/risc-v/rv32i/gcc/port_s.S index 233cc6cf..6a36990e 100644 --- a/arch/risc-v/rv32i/gcc/port_s.S +++ b/arch/risc-v/rv32i/gcc/port_s.S @@ -226,7 +226,6 @@ port_context_switch: sw x30, __reg_x30_OFFSET(sp) sw x31, __reg_x31_OFFSET(sp) - sw ra, __reg_mepc_OFFSET(sp) csrr t0, mstatus @@ -324,12 +323,10 @@ rv32_exception_entry: mv t0, sp la t1, k_irq_stk_top lw sp, (t1) - andi sp, sp, 0xFFFFFFF0 sw t0, (sp) - // get irq num and call irq handler - li t0, SOC_MCAUSE_EXP_MASK + li t0, MCAUSE_EXP_CODE_MASK csrr a0, mcause and a0, a0, t0 call cpu_irq_entry diff --git a/arch/risc-v/spike/gcc/riscv_port.h b/arch/risc-v/spike/gcc/riscv_port.h index 383199b7..bbbbf3bf 100644 --- a/arch/risc-v/spike/gcc/riscv_port.h +++ b/arch/risc-v/spike/gcc/riscv_port.h @@ -23,7 +23,7 @@ #define CLINT_MTIMECMP 0x4000 #define CLINT_MTIME 0xBFF8 -#define SOC_MCAUSE_EXP_MASK 0x7FFFFFFF +#define MCAUSE_EXP_CODE_MASK 0x7FFFFFFF #ifndef __ASSEMBLER__ void port_cpu_init(); From 1fc66ae52788fff0e862dd7c64f49a9031c8a1bf Mon Sep 17 00:00:00 2001 From: acevest Date: Tue, 8 Oct 2019 21:24:02 +0800 Subject: [PATCH 3/6] fix did not save & restore register x1 --- arch/risc-v/common/tos_cpu.c | 2 +- arch/risc-v/rv32i/gcc/port_s.S | 82 +++++----------------------------- 2 files changed, 13 insertions(+), 71 deletions(-) diff --git a/arch/risc-v/common/tos_cpu.c b/arch/risc-v/common/tos_cpu.c index ca77923a..a0a369b9 100644 --- a/arch/risc-v/common/tos_cpu.c +++ b/arch/risc-v/common/tos_cpu.c @@ -122,7 +122,7 @@ __KERNEL__ k_stack_t *cpu_task_stk_init(void *entry, regs->a0 = (cpu_data_t)arg; // argument regs->ra = (cpu_data_t)0xACE00ACE; // return address regs->mstatus = (cpu_data_t)0x00001880; // return to machine mode and enable interrupt - regs->epc = (cpu_data_t)entry; // task entry + regs->mepc = (cpu_data_t)entry; // task entry return (k_stack_t*)sp; } diff --git a/arch/risc-v/rv32i/gcc/port_s.S b/arch/risc-v/rv32i/gcc/port_s.S index 6a36990e..e5bc021a 100644 --- a/arch/risc-v/rv32i/gcc/port_s.S +++ b/arch/risc-v/rv32i/gcc/port_s.S @@ -150,52 +150,14 @@ port_sched_start: addi t1, sp, 128 sw t1, (t0) - // restore context - lw t0, __reg_mepc__OFFSET(sp) - csrw mepc, t0 - - lw t0, __reg_mstatus__OFFSET(sp) - csrw mstatus, t0 - - lw x3, __reg_x3_OFFSET(sp) - lw x4, __reg_x4_OFFSET(sp) - lw x5, __reg_x5_OFFSET(sp) - lw x6, __reg_x6_OFFSET(sp) - lw x7, __reg_x7_OFFSET(sp) - lw x8, __reg_x8_OFFSET(sp) - lw x9, __reg_x9_OFFSET(sp) - lw x10, __reg_x10_OFFSET(sp) - lw x11, __reg_x11_OFFSET(sp) - lw x12, __reg_x12_OFFSET(sp) - lw x13, __reg_x13_OFFSET(sp) - lw x14, __reg_x14_OFFSET(sp) - lw x15, __reg_x15_OFFSET(sp) - lw x16, __reg_x16_OFFSET(sp) - lw x17, __reg_x17_OFFSET(sp) - lw x18, __reg_x18_OFFSET(sp) - lw x19, __reg_x19_OFFSET(sp) - lw x20, __reg_x20_OFFSET(sp) - lw x21, __reg_x21_OFFSET(sp) - lw x22, __reg_x22_OFFSET(sp) - lw x23, __reg_x23_OFFSET(sp) - lw x24, __reg_x24_OFFSET(sp) - lw x25, __reg_x25_OFFSET(sp) - lw x26, __reg_x26_OFFSET(sp) - lw x27, __reg_x27_OFFSET(sp) - lw x28, __reg_x28_OFFSET(sp) - lw x29, __reg_x29_OFFSET(sp) - lw x30, __reg_x30_OFFSET(sp) - lw x31, __reg_x31_OFFSET(sp) - - addi sp, sp, 128 - - mret + j restore_context .align 2 .type port_context_switch, %function port_context_switch: addi sp, sp, -128 + sw x1, __reg_x1_OFFSET(sp) sw x3, __reg_x3_OFFSET(sp) sw x4, __reg_x4_OFFSET(sp) sw x5, __reg_x5_OFFSET(sp) @@ -233,20 +195,24 @@ port_context_switch: or t0, t0, t1 sw t0, __reg_mstatus_OFFSET(sp) - // save sp to k_curr_task.sp + la t0, k_curr_task // t0 = &k_curr_task - lw t1, (t0) - sw sp, (t1) + la t1, k_next_task // t1 = &k_next_task + +switch_task: + // save sp to k_curr_task.sp + lw t2, (t0) + sw sp, (t2) // switch task // k_curr_task = k_next_task - la t1, k_next_task // t1 = &k_next_task lw t1, (t1) // t1 = k_next_task sw t1, (t0) // load new task sp lw sp, (t1) +restore_context: // restore context lw t0, __reg_mepc_OFFSET(sp) csrw mepc, t0 @@ -254,6 +220,7 @@ port_context_switch: lw t0, __reg_mstatus_OFFSET(sp) csrw mstatus, t0 + lw x1, __reg_x1_OFFSET(sp) lw x3, __reg_x3_OFFSET(sp) lw x4, __reg_x4_OFFSET(sp) lw x5, __reg_x5_OFFSET(sp) @@ -353,30 +320,7 @@ rv32_exception_entry: sw s10, __reg_s10__OFFSET(sp) sw s11, __reg_s11__OFFSET(sp) - // save sp to k_curr_task.sp - la t0, k_curr_task // t0 = &k_curr_task - lw t2, (t0) // t2 = k_curr_task->sp - sw sp, (t2) // k_curr_task->sp = sp - - // switch task - lw t1, (t1) // t1 = k_next_task - sw t1, (t0) // k_curr_task = k_next_task - - // load new task sp - lw sp, (t1) - - lw s0, __reg_s0__OFFSET(sp) - lw s1, __reg_s1__OFFSET(sp) - lw s2, __reg_s2__OFFSET(sp) - lw s3, __reg_s3__OFFSET(sp) - lw s4, __reg_s4__OFFSET(sp) - lw s5, __reg_s5__OFFSET(sp) - lw s6, __reg_s6__OFFSET(sp) - lw s7, __reg_s7__OFFSET(sp) - lw s8, __reg_s8__OFFSET(sp) - lw s9, __reg_s9__OFFSET(sp) - lw s10, __reg_s10__OFFSET(sp) - lw s11, __reg_s11__OFFSET(sp) + j switch_task irq_restore: lw t0, __reg_mepc_OFFSET(sp) @@ -406,5 +350,3 @@ irq_restore: addi sp, sp, 128 mret - - From 21f48361de42ced2d5d6e165783925fa5b35d980 Mon Sep 17 00:00:00 2001 From: acevest Date: Tue, 8 Oct 2019 21:36:51 +0800 Subject: [PATCH 4/6] make irq_restore be executed likely --- arch/risc-v/rv32i/gcc/port_s.S | 36 +++++++++++++++++----------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/arch/risc-v/rv32i/gcc/port_s.S b/arch/risc-v/rv32i/gcc/port_s.S index e5bc021a..489a13d6 100644 --- a/arch/risc-v/rv32i/gcc/port_s.S +++ b/arch/risc-v/rv32i/gcc/port_s.S @@ -250,7 +250,6 @@ restore_context: lw x29, __reg_x29_OFFSET(sp) lw x30, __reg_x30_OFFSET(sp) lw x31, __reg_x31_OFFSET(sp) - addi sp, sp, 128 mret @@ -260,7 +259,6 @@ restore_context: .global rv32_exception_entry rv32_exception_entry: addi sp, sp, -128 - sw ra, __reg_ra__OFFSET(sp) sw gp, __reg_gp__OFFSET(sp) sw tp, __reg_tp__OFFSET(sp) @@ -305,22 +303,8 @@ rv32_exception_entry: la t0, k_curr_task la t1, k_next_task - beq t0, t1, irq_restore - - sw s0, __reg_s0__OFFSET(sp) - sw s1, __reg_s1__OFFSET(sp) - sw s2, __reg_s2__OFFSET(sp) - sw s3, __reg_s3__OFFSET(sp) - sw s4, __reg_s4__OFFSET(sp) - sw s5, __reg_s5__OFFSET(sp) - sw s6, __reg_s6__OFFSET(sp) - sw s7, __reg_s7__OFFSET(sp) - sw s8, __reg_s8__OFFSET(sp) - sw s9, __reg_s9__OFFSET(sp) - sw s10, __reg_s10__OFFSET(sp) - sw s11, __reg_s11__OFFSET(sp) - - j switch_task + // unlikely + bne t0, t1, irq_task_switch irq_restore: lw t0, __reg_mepc_OFFSET(sp) @@ -350,3 +334,19 @@ irq_restore: addi sp, sp, 128 mret + +irq_task_switch: + sw s0, __reg_s0__OFFSET(sp) + sw s1, __reg_s1__OFFSET(sp) + sw s2, __reg_s2__OFFSET(sp) + sw s3, __reg_s3__OFFSET(sp) + sw s4, __reg_s4__OFFSET(sp) + sw s5, __reg_s5__OFFSET(sp) + sw s6, __reg_s6__OFFSET(sp) + sw s7, __reg_s7__OFFSET(sp) + sw s8, __reg_s8__OFFSET(sp) + sw s9, __reg_s9__OFFSET(sp) + sw s10, __reg_s10__OFFSET(sp) + sw s11, __reg_s11__OFFSET(sp) + + j switch_task From 19e65a4bb709af6c512f82110cea08ae1c033eaa Mon Sep 17 00:00:00 2001 From: acevest Date: Wed, 9 Oct 2019 11:43:56 +0800 Subject: [PATCH 5/6] remove extra instructions in port_sched_start --- arch/risc-v/rv32i/gcc/port_s.S | 4 ---- 1 file changed, 4 deletions(-) diff --git a/arch/risc-v/rv32i/gcc/port_s.S b/arch/risc-v/rv32i/gcc/port_s.S index 489a13d6..4de91bce 100644 --- a/arch/risc-v/rv32i/gcc/port_s.S +++ b/arch/risc-v/rv32i/gcc/port_s.S @@ -146,10 +146,6 @@ port_sched_start: lw t0, (t0) // t0 = &(k_curr_task->sp) lw sp, (t0) // sp = k_curr_task->sp - // save sp to stack - addi t1, sp, 128 - sw t1, (t0) - j restore_context From 308ad78e444cba0878ea8b6757307dcb36afcd3d Mon Sep 17 00:00:00 2001 From: acevest Date: Wed, 9 Oct 2019 12:10:19 +0800 Subject: [PATCH 6/6] mtvec exception handler use 4byte alignment --- arch/risc-v/bumblebee/gcc/riscv_port_s.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/risc-v/bumblebee/gcc/riscv_port_s.S b/arch/risc-v/bumblebee/gcc/riscv_port_s.S index 1683a0b6..68e7ee00 100644 --- a/arch/risc-v/bumblebee/gcc/riscv_port_s.S +++ b/arch/risc-v/bumblebee/gcc/riscv_port_s.S @@ -7,6 +7,6 @@ irq_entry: j rv32_exception_entry -.align 6 +.align 2 trap_entry: j rv32_exception_entry