From 78ae905091e61ecede6cd289be5933cc0f6b3219 Mon Sep 17 00:00:00 2001 From: doot <gugegby@gmail.com> Date: Thu, 20 May 2021 08:35:45 +0800 Subject: [PATCH] add: interrupt management funtions. --- kernel/cpu.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ kernel/cpu.h | 25 +++++++++++++++++++++++++ kernel/kvec.c | 4 ++-- kernel/process.c | 10 ++++------ kernel/uvec.c | 4 +++- 5 files changed, 81 insertions(+), 9 deletions(-) create mode 100644 kernel/cpu.c create mode 100644 kernel/cpu.h diff --git a/kernel/cpu.c b/kernel/cpu.c new file mode 100644 index 00000000..4a5a4959 --- /dev/null +++ b/kernel/cpu.c @@ -0,0 +1,47 @@ +#include "cpu.h" +#include "defs.h" +#include "riscv.h" + +struct cpu_t cpus[HART_NUM]; + +struct cpu_t *get_cpu() { + return &cpus[get_hartid()]; +} + +void cpu_struct_init() { + for(int i = 0; i < HART_NUM; ++i) { + cpus[i].int_depth = 0; + } +} + +void cpu_int_push() { + struct cpu_t *cpu = get_cpu(); + uint64_t old = intr_get(); + intr_off(); + if(cpu->int_depth == 0) { + cpu->int_enable = old; + } + cpu->int_depth++; +} + +void cpu_int_pop() { + struct cpu_t *cpu = get_cpu(); + cpu->int_depth--; + if(cpu->int_depth == 0 && intr_get()) { + intr_on(); + } +} + +void intr_off() { + c_sstatus(SSTATUS_SIE); +} + +void intr_on() { + s_sstatus(SSTATUS_SIE); +} + +uint64_t intr_get() { + return r_sstatus() & SSTATUS_SIE; +} + + diff --git a/kernel/cpu.h b/kernel/cpu.h new file mode 100644 index 00000000..c71fe404 --- /dev/null +++ b/kernel/cpu.h @@ -0,0 +1,25 @@ +#ifndef __CPU_H_ +#define __CPU_H_ + +#include "process.h" +#include "riscv.h" + +struct cpu_t { + struct task_struct *curent_task; + struct context schduler_ctx; + int64_t int_depth; + uint64_t int_enable; +}; + +struct cpu_t *get_cpu(); + +void cpu_struct_init(); +void cpu_int_push(); +void cpu_int_pop(); + +void intr_off(); +void intr_on(); +uint64_t intr_get(); + + +#endif // __CPU_H_ diff --git a/kernel/kvec.c b/kernel/kvec.c index f286ea10..03064aa5 100644 --- a/kernel/kvec.c +++ b/kernel/kvec.c @@ -19,11 +19,11 @@ void kvec() { if(scause == SCAUSE_SUPV_TIMER) { sbi_legacy_set_timer(r_time() + 30000000); printf("timer!\n"); - } if(scause == SCAUSE_ECALL_USER) { + } else if(scause == SCAUSE_ECALL_USER) { printf("ecall from user\n"); } else { // unhandled interrupt or exception - printf("unhandled interrupt, sscause: %l, sstval: %l\n", scause, stval); + printf("unhandled interrupt, sscause: %x, sstval: %x\n", scause, stval); KERNEL_PANIC(); } } diff --git a/kernel/process.c b/kernel/process.c index 57647cd2..ce9731b5 100644 --- a/kernel/process.c +++ b/kernel/process.c @@ -12,6 +12,7 @@ #include "riscv.h" #include "uvec.h" #include "extdef.h" +#include "cpu.h" bool task_aux_check_elf(Elf64_Ehdr *ehdr) { @@ -246,7 +247,7 @@ struct task_struct *task_create(struct vnode *image, struct task_struct *parent) task->ctx.sp = (uint64_t)(task->kstack_pa + PAGE_SIZE * 2); task->tfp->hartid = get_hartid(); - task->tfp->kernel_sp = task->kstack_pa + PAGE_SIZE; + task->tfp->kernel_sp = (uint64_t)(task->kstack_pa + PAGE_SIZE); task->tfp->kernel_satp = r_satp(); task->tfp->utrap_entry = (uint64_t)utrap_entry; task->tfp->epc = ehdr->e_entry; @@ -338,12 +339,9 @@ void tasK_add(struct task_struct *task); void task_del(struct task_struct *task); -// not exposed to public -struct task_struct *global_task[HART_NUM]; - struct task_struct *task_get_current() { - return global_task[get_hartid()]; + return get_cpu()->curent_task; } void task_set_current(struct task_struct *task) { - global_task[get_hartid()] = task; + get_cpu()->curent_task = task; } diff --git a/kernel/uvec.c b/kernel/uvec.c index a1cacd0e..460ab17f 100644 --- a/kernel/uvec.c +++ b/kernel/uvec.c @@ -12,6 +12,9 @@ typedef void (*uvec_ret_func)(uint64_t, uint64_t); void utrap_entry() { uint64_t scause = r_scause(); + w_stvec((uint64_t)kvec_asm); + + if(scause == SCAUSE_ECALL_USER) { printf("ecall from user\n"); } else if(scause == SCAUSE_SUPV_TIMER) { @@ -20,7 +23,6 @@ void utrap_entry() { printf("unknown int from user, scause: %l\n", scause); } - while(1); utrap_ret(); } -- GitLab