replace multiple instructions with macro SAVE_CONTEXT and RESTORE_CONTEXT

This commit is contained in:
acezhao
2019-09-14 22:15:09 +08:00
parent ad72fb73d2
commit de43d4ef0e
10 changed files with 342 additions and 502 deletions

View File

@@ -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
}

View File

@@ -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);

View File

@@ -8,39 +8,39 @@
#include <tos.h>
#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)

View File

@@ -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

View File

@@ -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

View File

@@ -125,16 +125,18 @@
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.include.paths.293419375" name="Include paths (-I)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.include.paths" useByScannerDiscovery="true" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/hello_world/TencentOS_tiny/arch/risc-v/rv32i}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/hello_world/TencentOS_tiny/arch/risc-v/common}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/hello_world/TencentOS_tiny/kernel/core/include}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/hello_world/TencentOS_tiny/kernel/pm/include}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/hello_world/TencentOS_tiny/arch/risc-v/common}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/hello_world/TencentOS_tiny/arch/risc-v/rv32i}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/hello_world/Inc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/hello_world/TOS-CONFIG}&quot;"/>
</option>
<inputType id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.input.905374687" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.input"/>
@@ -211,9 +213,7 @@
<sourceEntries>
<entry excluding="TencentOS_tiny|Src" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Src"/>
<entry excluding="TencentOS_tiny|Srcs" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="TencentOS_tiny"/>
@@ -369,9 +369,7 @@
<sourceEntries>
<entry excluding="Src" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Src"/>
<entry excluding="Srcs" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
</sourceEntries>

View File

@@ -24,6 +24,21 @@
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
<linkedResources>
<link>
<name>Inc</name>
<type>2</type>
<locationURI>$%7BPARENT-2-PROJECT_LOC%7D/Inc</locationURI>
</link>
<link>
<name>Src</name>
<type>2</type>
<locationURI>$%7BPARENT-2-PROJECT_LOC%7D/Src</locationURI>
</link>
<link>
<name>TOS-CONFIG</name>
<type>2</type>
<locationURI>$%7BPARENT-2-PROJECT_LOC%7D/TOS-CONFIG</locationURI>
</link>
<link>
<name>TencentOS_tiny</name>
<type>2</type>

View File

@@ -11,7 +11,7 @@
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="1380923165007189689" id="ilg.gnumcueclipse.managedbuild.cross.riscv.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT RISC-V Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} ${cross_toolchain_flags} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="1296816921559833178" id="ilg.gnumcueclipse.managedbuild.cross.riscv.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT RISC-V Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} ${cross_toolchain_flags} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>