From de43d4ef0ed48ce522c5af2ed8c300cfdb0b7c1a Mon Sep 17 00:00:00 2001 From: acezhao Date: Sat, 14 Sep 2019 22:15:09 +0800 Subject: [PATCH] replace multiple instructions with macro SAVE_CONTEXT and RESTORE_CONTEXT --- arch/risc-v/common/tos_cpu.c | 122 ++-- arch/risc-v/common/tos_cpu.h | 64 +-- arch/risc-v/rv32i/port_c.c | 52 +- arch/risc-v/rv32i/port_s.S | 519 ++++++------------ arch/risc-v/rv32i/start.S | 52 +- .../{eclipse/hello_world => }/Src/main.c | 0 .../Inc => TOS-CONFIG}/tos_config.h | 0 .../QEMU_Spike/eclipse/hello_world/.cproject | 18 +- board/QEMU_Spike/eclipse/hello_world/.project | 15 + .../.settings/language.settings.xml | 2 +- 10 files changed, 342 insertions(+), 502 deletions(-) rename board/QEMU_Spike/{eclipse/hello_world => }/Src/main.c (100%) rename board/QEMU_Spike/{eclipse/hello_world/Inc => TOS-CONFIG}/tos_config.h (100%) diff --git a/arch/risc-v/common/tos_cpu.c b/arch/risc-v/common/tos_cpu.c index 9680fbba..ec7a7ebf 100644 --- a/arch/risc-v/common/tos_cpu.c +++ b/arch/risc-v/common/tos_cpu.c @@ -10,7 +10,7 @@ __KERNEL__ void cpu_systick_init(k_cycle_t cycle_per_tick) { - port_systick_priority_set(TOS_CFG_CPU_SYSTICK_PRIO); + port_systick_priority_set(TOS_CFG_CPU_SYSTICK_PRIO); port_systick_config(cycle_per_tick); } @@ -48,38 +48,38 @@ __KERNEL__ void cpu_sched_start(void) /* Inx Offset Register -31 124 x31 t6 -32 120 x30 t5 -29 116 x29 t4 -28 112 x28 t3 -27 108 x27 s11 -26 104 x26 s10 -25 100 x25 s9 -24 096 x24 s8 -23 092 x23 s7 -22 088 x22 s6 -21 084 x21 s5 -20 080 x20 s4 -19 076 x19 s3 -18 072 x18 s2 -17 068 x17 a7 -16 064 x16 a6 -15 060 x15 a5 -14 056 x14 a4 -13 052 x13 a3 -12 048 x12 a2 -11 044 x11 a1 -10 040 x10 a0 -09 036 x9 s1 -08 032 x8 s0/fp -07 028 x7 t2 -06 024 x6 t1 -05 020 x5 t0 -04 016 x4 tp -03 012 x3 gp -02 008 x1 ra -01 004 mstatus -00 000 epc +31 124 x31 t6 +32 120 x30 t5 +29 116 x29 t4 +28 112 x28 t3 +27 108 x27 s11 +26 104 x26 s10 +25 100 x25 s9 +24 096 x24 s8 +23 092 x23 s7 +22 088 x22 s6 +21 084 x21 s5 +20 080 x20 s4 +19 076 x19 s3 +18 072 x18 s2 +17 068 x17 a7 +16 064 x16 a6 +15 060 x15 a5 +14 056 x14 a4 +13 052 x13 a3 +12 048 x12 a2 +11 044 x11 a1 +10 040 x10 a0 +09 036 x9 s1 +08 032 x8 s0/fp +07 028 x7 t2 +06 024 x6 t1 +05 020 x5 t0 +04 016 x4 tp +03 012 x3 gp +02 008 x1 ra +01 004 mstatus +00 000 epc */ @@ -89,7 +89,7 @@ __KERNEL__ k_stack_t *cpu_task_stk_init(void *entry, k_stack_t *stk_base, size_t stk_size) { - cpu_data_t *sp = 0; + cpu_data_t *sp = 0; cpu_context_t *regs = 0; sp = (cpu_data_t *)&stk_base[stk_size]; @@ -101,16 +101,16 @@ __KERNEL__ k_stack_t *cpu_task_stk_init(void *entry, #if 1 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 + #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 } #endif - regs->a0 = (cpu_data_t)arg; // a0: argument - regs->ra = (cpu_data_t)0xACE00ACE; // ra: return address - regs->mstatus = (cpu_data_t)(MSTATUS_MPP | MSTATUS_MPIE); // return to machine mode and enable interrupt - regs->epc = (cpu_data_t)entry; + regs->a0 = (cpu_data_t)arg; // a0: argument + regs->ra = (cpu_data_t)0xACE00ACE; // ra: return address + regs->mstatus = (cpu_data_t)(MSTATUS_MPP | MSTATUS_MPIE); // return to machine mode and enable interrupt + regs->epc = (cpu_data_t)entry; return (k_stack_t*)sp; @@ -118,38 +118,38 @@ __KERNEL__ k_stack_t *cpu_task_stk_init(void *entry, void cpu_trap_entry(cpu_data_t cause, cpu_context_t *regs) { - while(1) { - // TODO - } + while(1) { + // TODO + } } void SysTick_IRQHandler() { - port_systick_config(k_cpu_cycle_per_tick); - if(tos_knl_is_running()) { - tos_knl_irq_enter(); - tos_tick_handler(); - tos_knl_irq_leave(); - } + port_systick_config(k_cpu_cycle_per_tick); + if(tos_knl_is_running()) { + tos_knl_irq_enter(); + tos_tick_handler(); + tos_knl_irq_leave(); + } } void cpu_irq_entry(cpu_data_t irq, cpu_context_t *regs) { #if 1 - if(irq != 7) { - return; - } + if(irq != 7) { + return; + } - SysTick_IRQHandler(); + SysTick_IRQHandler(); #else - void (*irq_handler)(); - extern void (*handler_vector_table[])(); + void (*irq_handler)(); + extern void (*handler_vector_table[])(); - irq_handler = handler_vector_table[irq]; - if((*irq_handler) == 0) { - return; - } + irq_handler = handler_vector_table[irq]; + if((*irq_handler) == 0) { + return; + } - (*irq_handler)(); + (*irq_handler)(); #endif } diff --git a/arch/risc-v/common/tos_cpu.h b/arch/risc-v/common/tos_cpu.h index ee39a3a4..75695178 100644 --- a/arch/risc-v/common/tos_cpu.h +++ b/arch/risc-v/common/tos_cpu.h @@ -3,38 +3,38 @@ typedef struct cpu_context_st { - cpu_data_t epc; - cpu_data_t mstatus; - union { cpu_data_t x1, ra; }; - union { cpu_data_t x3, gp; }; - union { cpu_data_t x4, tp; }; - union { cpu_data_t x5, t0; }; - union { cpu_data_t x6, t1; }; - union { cpu_data_t x7, t2; }; - union { cpu_data_t x8, s0, fp; }; - union { cpu_data_t x9, s1; }; - union { cpu_data_t x10, a0; }; - union { cpu_data_t x11, a1; }; - union { cpu_data_t x12, a2; }; - union { cpu_data_t x13, a3; }; - union { cpu_data_t x14, a4; }; - union { cpu_data_t x15, a5; }; - union { cpu_data_t x16, a6; }; - union { cpu_data_t x17, a7; }; - union { cpu_data_t x18, s2; }; - union { cpu_data_t x19, s3; }; - union { cpu_data_t x20, s4; }; - union { cpu_data_t x21, s5; }; - union { cpu_data_t x22, s6; }; - union { cpu_data_t x23, s7; }; - union { cpu_data_t x24, s8; }; - union { cpu_data_t x25, s9; }; - union { cpu_data_t x26, s10; }; - union { cpu_data_t x27, s11; }; - union { cpu_data_t x28, t3; }; - union { cpu_data_t x29, t4; }; - union { cpu_data_t x30, t5; }; - union { cpu_data_t x31, t6; }; + cpu_data_t epc; + cpu_data_t mstatus; + union { cpu_data_t x1, ra; }; + union { cpu_data_t x3, gp; }; + union { cpu_data_t x4, tp; }; + union { cpu_data_t x5, t0; }; + union { cpu_data_t x6, t1; }; + union { cpu_data_t x7, t2; }; + union { cpu_data_t x8, s0, fp; }; + union { cpu_data_t x9, s1; }; + union { cpu_data_t x10, a0; }; + union { cpu_data_t x11, a1; }; + union { cpu_data_t x12, a2; }; + union { cpu_data_t x13, a3; }; + union { cpu_data_t x14, a4; }; + union { cpu_data_t x15, a5; }; + union { cpu_data_t x16, a6; }; + union { cpu_data_t x17, a7; }; + union { cpu_data_t x18, s2; }; + union { cpu_data_t x19, s3; }; + union { cpu_data_t x20, s4; }; + union { cpu_data_t x21, s5; }; + union { cpu_data_t x22, s6; }; + union { cpu_data_t x23, s7; }; + union { cpu_data_t x24, s8; }; + union { cpu_data_t x25, s9; }; + union { cpu_data_t x26, s10; }; + union { cpu_data_t x27, s11; }; + union { cpu_data_t x28, t3; }; + union { cpu_data_t x29, t4; }; + union { cpu_data_t x30, t5; }; + union { cpu_data_t x31, t6; }; } cpu_context_t; __API__ uint32_t tos_cpu_clz(uint32_t val); diff --git a/arch/risc-v/rv32i/port_c.c b/arch/risc-v/rv32i/port_c.c index a3d2096d..fcb9958d 100644 --- a/arch/risc-v/rv32i/port_c.c +++ b/arch/risc-v/rv32i/port_c.c @@ -8,39 +8,39 @@ #include #define CLINT_CTRL_ADDR 0x2000000 -#define CLINT_MSIP 0x0000 -#define CLINT_MTIMECMP 0x4000 -#define CLINT_MTIME 0xBFF8 +#define CLINT_MSIP 0x0000 +#define CLINT_MTIMECMP 0x4000 +#define CLINT_MTIME 0xBFF8 __PORT__ void port_systick_config(uint32_t cycle_per_tick) { - // it cost cpu read two times, first mtime_lo and then mtime_hi - // if mtime_lo == 0xFFFFFFFF and mtime_hi = 0 at first read - // then mtime_lo == 0 and mtime_hi = 1 at next read - // the result will be 0x1FFFFFFFF, not 0x100000000 - uint64_t mtime = 0; - while(1) { - uint32_t mtime_hi = *(volatile uint32_t *)(CLINT_CTRL_ADDR + CLINT_MTIME + 4); - uint32_t mtime_lo = *(volatile uint32_t *)(CLINT_CTRL_ADDR + CLINT_MTIME + 0); - uint32_t mtime_hn = *(volatile uint32_t *)(CLINT_CTRL_ADDR + CLINT_MTIME + 4); - if(mtime_hi == mtime_hn) { - mtime += ((uint64_t)mtime_hi << 32) | mtime_lo; - break; - } - } + // it cost cpu read two times, first mtime_lo and then mtime_hi + // if mtime_lo == 0xFFFFFFFF and mtime_hi = 0 at first read + // then mtime_lo == 0 and mtime_hi = 1 at next read + // the result will be 0x1FFFFFFFF, not 0x100000000 + uint64_t mtime = 0; + while(1) { + uint32_t mtime_hi = *(volatile uint32_t *)(CLINT_CTRL_ADDR + CLINT_MTIME + 4); + uint32_t mtime_lo = *(volatile uint32_t *)(CLINT_CTRL_ADDR + CLINT_MTIME + 0); + uint32_t mtime_hn = *(volatile uint32_t *)(CLINT_CTRL_ADDR + CLINT_MTIME + 4); + if(mtime_hi == mtime_hn) { + mtime += ((uint64_t)mtime_hi << 32) | mtime_lo; + break; + } + } - // just set mtime to mtimecmp does not accurately reflect the passage of time - // cause some time cost on the path to deal with the interrupt - // so, we need to to fix the value with a multiple of cycle_per_tick - uint64_t tick = mtime / cycle_per_tick; - uint64_t mtimecmp = (tick + 1) * cycle_per_tick; + // just set mtime to mtimecmp does not accurately reflect the passage of time + // cause some time cost on the path to deal with the interrupt + // so, we need to to fix the value with a multiple of cycle_per_tick + uint64_t tick = mtime / cycle_per_tick; + uint64_t mtimecmp = (tick + 1) * cycle_per_tick; - // write to mtimecmp register - *(volatile uint32_t *)(CLINT_CTRL_ADDR + CLINT_MTIMECMP + 0) = 0xFFFFFFFF; - *(volatile uint32_t *)(CLINT_CTRL_ADDR + CLINT_MTIMECMP + 4) = 0xFFFFFFFF & (mtimecmp >> 32); - *(volatile uint32_t *)(CLINT_CTRL_ADDR + CLINT_MTIMECMP + 0) = 0xFFFFFFFF & (mtimecmp >> 0); + // write to mtimecmp register + *(volatile uint32_t *)(CLINT_CTRL_ADDR + CLINT_MTIMECMP + 0) = 0xFFFFFFFF; + *(volatile uint32_t *)(CLINT_CTRL_ADDR + CLINT_MTIMECMP + 4) = 0xFFFFFFFF & (mtimecmp >> 32); + *(volatile uint32_t *)(CLINT_CTRL_ADDR + CLINT_MTIMECMP + 0) = 0xFFFFFFFF & (mtimecmp >> 0); } __PORT__ void port_systick_priority_set(uint32_t prio) diff --git a/arch/risc-v/rv32i/port_s.S b/arch/risc-v/rv32i/port_s.S index 507af6b0..a7153dc0 100644 --- a/arch/risc-v/rv32i/port_s.S +++ b/arch/risc-v/rv32i/port_s.S @@ -12,6 +12,10 @@ .global port_context_switch .global port_irq_context_switch +.extern k_curr_task +.extern k_next_task + + #include "riscv_encoding.h" .text @@ -19,23 +23,23 @@ .type port_int_disable, %function port_int_disable: - csrci mstatus, MSTATUS_MIE - ret + csrci mstatus, MSTATUS_MIE + ret .type port_int_enable, %function port_int_enable: - csrsi mstatus, MSTATUS_MIE - ret + csrsi mstatus, MSTATUS_MIE + ret .type port_cpsr_save, %function port_cpsr_save: - csrrci a0, mstatus, MSTATUS_MIE - ret + csrrci a0, mstatus, MSTATUS_MIE + ret .type port_cpsr_restore, %function port_cpsr_restore: - csrw mstatus, a0 - ret + csrw mstatus, a0 + ret .type port_systick_resume, %function port_systick_resume: @@ -55,377 +59,200 @@ port_systick_pending_reset: csrc mip, t0 ret +#define REGBYTES 4 +.macro SAVE_CONTEXT + addi sp, sp, -32*REGBYTES + sw x1, 2*REGBYTES(sp) + sw x3, 3*REGBYTES(sp) + sw x4, 4*REGBYTES(sp) + sw x5, 5*REGBYTES(sp) + sw x6, 6*REGBYTES(sp) + sw x7, 7*REGBYTES(sp) + sw x8, 8*REGBYTES(sp) + sw x9, 9*REGBYTES(sp) + sw x10, 10*REGBYTES(sp) + sw x11, 11*REGBYTES(sp) + sw x12, 12*REGBYTES(sp) + sw x13, 13*REGBYTES(sp) + sw x14, 14*REGBYTES(sp) + sw x15, 15*REGBYTES(sp) + sw x16, 16*REGBYTES(sp) + sw x17, 17*REGBYTES(sp) + sw x18, 18*REGBYTES(sp) + sw x19, 19*REGBYTES(sp) + sw x20, 20*REGBYTES(sp) + sw x21, 21*REGBYTES(sp) + sw x22, 22*REGBYTES(sp) + sw x23, 23*REGBYTES(sp) + sw x24, 24*REGBYTES(sp) + sw x25, 25*REGBYTES(sp) + sw x26, 26*REGBYTES(sp) + sw x27, 27*REGBYTES(sp) + sw x28, 28*REGBYTES(sp) + sw x29, 29*REGBYTES(sp) + sw x30, 30*REGBYTES(sp) + sw x31, 31*REGBYTES(sp) +.endm -#define REGBYTES 4 -#define LOAD lw -#define STORE sw -.extern k_curr_task -.type port_sched_start, %function -port_sched_start: - // enable timer interrupt - li t0, MIE_MTIE - csrs mie, t0 +.macro RESTORE_CONTEXT + lw t0, 0*REGBYTES(sp) + csrw mepc, t0 - la t0, k_curr_task // t0 = &k_curr_task - LOAD t0, (t0) // t0 = &(k_curr_task->sp) - LOAD sp, (t0) // k_curr_task->sp = sp + lw t0, 1*REGBYTES(sp) + csrw mstatus, t0 - // save sp - addi t1, sp, 32*REGBYTES - STORE t1, (t0) + lw x1, 2*REGBYTES(sp) + lw x3, 3*REGBYTES(sp) + lw x4, 4*REGBYTES(sp) + lw x5, 5*REGBYTES(sp) + lw x6, 6*REGBYTES(sp) + lw x7, 7*REGBYTES(sp) + lw x8, 8*REGBYTES(sp) + lw x9, 9*REGBYTES(sp) + lw x10, 10*REGBYTES(sp) + lw x11, 11*REGBYTES(sp) + lw x12, 12*REGBYTES(sp) + lw x13, 13*REGBYTES(sp) + lw x14, 14*REGBYTES(sp) + lw x15, 15*REGBYTES(sp) + lw x16, 16*REGBYTES(sp) + lw x17, 17*REGBYTES(sp) + lw x18, 18*REGBYTES(sp) + lw x19, 19*REGBYTES(sp) + lw x20, 20*REGBYTES(sp) + lw x21, 21*REGBYTES(sp) + lw x22, 22*REGBYTES(sp) + lw x23, 23*REGBYTES(sp) + lw x24, 24*REGBYTES(sp) + lw x25, 25*REGBYTES(sp) + lw x26, 26*REGBYTES(sp) + lw x27, 27*REGBYTES(sp) + lw x28, 28*REGBYTES(sp) + lw x29, 29*REGBYTES(sp) + lw x30, 30*REGBYTES(sp) + lw x31, 31*REGBYTES(sp) - LOAD t0, 0*REGBYTES(sp) - csrw mepc, t0 - - LOAD t0, 1*REGBYTES(sp) - csrw mstatus, t0 - - LOAD x1, 2*REGBYTES(sp) - LOAD x3, 3*REGBYTES(sp) - 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 - - mret + addi sp, sp, 32*REGBYTES +.endm .align 2 -.global machine_trap_entry -machine_trap_entry: - addi sp, sp, -32*REGBYTES - STORE x1, 2*REGBYTES(sp) - STORE x3, 3*REGBYTES(sp) - 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) +context_switch_return: +irq_context_return: + ret -#if 1 - //li t0, MSTATUS_MPP | MSTATUS_MPIE // acutally MPIE is not need - csrr t0, mstatus - STORE t0, 1*REGBYTES(sp) +.align 2 +.type port_sched_start, %function +port_sched_start: + // enable timer interrupt + li t0, MIE_MTIE + csrs mie, t0 - csrr t0, mepc // just save information for handler - STORE t0, 0*REGBYTES(sp) + // load sp from k_curr_task->sp + la t0, k_curr_task // t0 = &k_curr_task + lw t0, (t0) // t0 = &(k_curr_task->sp) + lw sp, (t0) // sp = k_curr_task->sp + // save sp to stack + addi t1, sp, 32*REGBYTES + sw t1, (t0) - // save sp to k_curr_task.sp - la t0, k_curr_task // t0 = &k_curr_task - LOAD t1, (t0) - STORE sp, (t1) + RESTORE_CONTEXT - csrr a0, mcause - mv a1, sp - bltz a0, irq - call cpu_trap_entry - j restore -irq: - slli a0, a0, 1 - srli a0, a0, 1 - call cpu_irq_entry -restore: - LOAD t0, 0*REGBYTES(sp) - csrw mepc, t0 - - LOAD t0, 1*REGBYTES(sp) - csrw mstatus, t0 -#else - // for debug timer interrupt only - csrr a0, mcause - slli a0, a0, 1 - srli a0, a0, 1 - call cpu_irq_entry -#endif - LOAD x1, 2*REGBYTES(sp) - LOAD x3, 3*REGBYTES(sp) - 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 - - mret + mret .align 2 .type port_context_switch, %function port_context_switch: - nop - nop - addi sp, sp, -32*REGBYTES - STORE x1, 2*REGBYTES(sp) - STORE x3, 3*REGBYTES(sp) - 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) + SAVE_CONTEXT - li t0, MSTATUS_MPP // force use machine mode - csrr t1, mstatus - and t1, t1, MSTATUS_MIE - beqz t1, save_mstatus - or t0, t0, MSTATUS_MPIE -save_mstatus: - STORE t0, 1*REGBYTES(sp) - la t0, port_context_switch_return // just save information for handler - STORE t0, 0*REGBYTES(sp) + // return from port_context_switch as return from a function + la t0, context_switch_return + sw t0, 0*REGBYTES(sp) - // save sp to k_curr_task.sp - la t0, k_curr_task // t0 = &k_curr_task - LOAD t1, (t0) - STORE sp, (t1) + csrr t0, mstatus + li t1, MSTATUS_MPP + or t0, t0, t1 + sw t0, 1*REGBYTES(sp) - // k_curr_task = k_next_task - la t1, k_next_task // t1 = &k_next_task - LOAD t1, (t1) // t1 = k_next_task - STORE t1, (t0) + // save sp to k_curr_task.sp + la t0, k_curr_task // t0 = &k_curr_task + lw t1, (t0) + sw sp, (t1) - // load sp from k_next_task.sp - LOAD sp, (t1) + // 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 t0, 0*REGBYTES(sp) - csrw mepc, t0 + // load new task sp + lw sp, (t1) - LOAD t0, 1*REGBYTES(sp) - csrw mstatus, t0 + RESTORE_CONTEXT - LOAD x1, 2*REGBYTES(sp) - LOAD x3, 3*REGBYTES(sp) - 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 - - mret - -.align 2 -port_context_switch_return: - ret + mret .align 2 .type port_irq_context_switch, %function port_irq_context_switch: - addi sp, sp, -32*REGBYTES - STORE x1, 2*REGBYTES(sp) - STORE x3, 3*REGBYTES(sp) - 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) - - li t0, MSTATUS_MPP - STORE t0, 1*REGBYTES(sp) - la t0, irq_context_return - STORE t0, 0*REGBYTES(sp) - - // save sp to k_curr_task.sp - la t0, k_curr_task // t0 = &k_curr_task - LOAD t1, (t0) - STORE sp, (t1) - - // k_curr_task = k_next_task - la t1, k_next_task // t1 = &k_next_task - LOAD t1, (t1) // t1 = k_next_task - STORE t1, (t0) - - // load sp from k_next_task.sp - LOAD sp, (t1) - - LOAD t0, 1*REGBYTES(sp) - csrw mstatus, t0 - - LOAD t0, 0*REGBYTES(sp) - csrw mepc, t0 - - LOAD x1, 2*REGBYTES(sp) - LOAD x3, 3*REGBYTES(sp) - 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) + SAVE_CONTEXT - addi sp, sp, 32*REGBYTES + la t0, irq_context_return + sw t0, 0*REGBYTES(sp) - mret + li t0, MSTATUS_MPP + sw t0, 1*REGBYTES(sp) + + // save sp to k_curr_task.sp + la t0, k_curr_task // t0 = &k_curr_task + lw t1, (t0) + sw sp, (t1) + + // 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 + + mret -irq_context_return: - ret +.align 2 +.global machine_trap_entry +machine_trap_entry: + SAVE_CONTEXT + csrr t0, mepc + sw t0, 0*REGBYTES(sp) + + csrr t0, mstatus + sw t0, 1*REGBYTES(sp) + + // save sp to k_curr_task.sp + la t0, k_curr_task // t0 = &k_curr_task + lw t1, (t0) + sw sp, (t1) + + csrr a0, mcause + mv a1, sp + bltz a0, irq + call cpu_trap_entry + j restore +irq: + slli a0, a0, 1 + srli a0, a0, 1 + call cpu_irq_entry +restore: + RESTORE_CONTEXT + + mret diff --git a/arch/risc-v/rv32i/start.S b/arch/risc-v/rv32i/start.S index 87d48427..30b04422 100644 --- a/arch/risc-v/rv32i/start.S +++ b/arch/risc-v/rv32i/start.S @@ -3,39 +3,39 @@ #include "riscv_encoding.h" .section .text.entry - .globl _start - .type _start,@function + .globl _start + .type _start,@function _start: - csrc mstatus, MSTATUS_MIE - csrw mie, 0 + csrc mstatus, MSTATUS_MIE + csrw mie, 0 - la t0, machine_trap_entry - csrw mtvec, t0 + la t0, machine_trap_entry + csrw mtvec, t0 - la sp, _stack_top + la sp, _stack_top - /* Load data section */ - la a0, _load_data - la a1, _data - la a2, _edata - bgeu a1, a2, begin_clear_bss + /* Load data section */ + la a0, _load_data + la a1, _data + la a2, _edata + bgeu a1, a2, begin_clear_bss clear_data: - lw t0, (a0) - sw t0, (a1) - addi a0, a0, 4 - addi a1, a1, 4 - bltu a1, a2, clear_data + lw t0, (a0) + sw t0, (a1) + addi a0, a0, 4 + addi a1, a1, 4 + bltu a1, a2, clear_data begin_clear_bss: - // clear bss section - la a0, _bss - la a1, _ebss - bgeu a0, a1, init_finish + // clear bss section + la a0, _bss + la a1, _ebss + bgeu a0, a1, init_finish clear_bss: - sw zero, (a0) - addi a0, a0, 4 - bltu a0, a1, clear_bss + sw zero, (a0) + addi a0, a0, 4 + bltu a0, a1, clear_bss init_finish: - call main + call main __die: - j __die + j __die diff --git a/board/QEMU_Spike/eclipse/hello_world/Src/main.c b/board/QEMU_Spike/Src/main.c similarity index 100% rename from board/QEMU_Spike/eclipse/hello_world/Src/main.c rename to board/QEMU_Spike/Src/main.c diff --git a/board/QEMU_Spike/eclipse/hello_world/Inc/tos_config.h b/board/QEMU_Spike/TOS-CONFIG/tos_config.h similarity index 100% rename from board/QEMU_Spike/eclipse/hello_world/Inc/tos_config.h rename to board/QEMU_Spike/TOS-CONFIG/tos_config.h diff --git a/board/QEMU_Spike/eclipse/hello_world/.cproject b/board/QEMU_Spike/eclipse/hello_world/.cproject index 5f72b9a4..ad0ee72b 100644 --- a/board/QEMU_Spike/eclipse/hello_world/.cproject +++ b/board/QEMU_Spike/eclipse/hello_world/.cproject @@ -125,15 +125,17 @@ @@ -211,9 +213,7 @@ - - - + @@ -369,9 +369,7 @@ - - - + diff --git a/board/QEMU_Spike/eclipse/hello_world/.project b/board/QEMU_Spike/eclipse/hello_world/.project index 684db511..1730710c 100644 --- a/board/QEMU_Spike/eclipse/hello_world/.project +++ b/board/QEMU_Spike/eclipse/hello_world/.project @@ -24,6 +24,21 @@ org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + Inc + 2 + $%7BPARENT-2-PROJECT_LOC%7D/Inc + + + Src + 2 + $%7BPARENT-2-PROJECT_LOC%7D/Src + + + TOS-CONFIG + 2 + $%7BPARENT-2-PROJECT_LOC%7D/TOS-CONFIG + TencentOS_tiny 2 diff --git a/board/QEMU_Spike/eclipse/hello_world/.settings/language.settings.xml b/board/QEMU_Spike/eclipse/hello_world/.settings/language.settings.xml index 9bd2bb79..96b0cb0d 100644 --- a/board/QEMU_Spike/eclipse/hello_world/.settings/language.settings.xml +++ b/board/QEMU_Spike/eclipse/hello_world/.settings/language.settings.xml @@ -11,7 +11,7 @@ - +