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