ACPI changes for DMAR and new directory hierarchy.
[akaros.git] / kern / arch / riscv / trap.c
index 6ddaf16..b41cd3e 100644 (file)
@@ -24,7 +24,7 @@
  *
  * TODO: if these end up becoming contended cache lines, move this to
  * per_cpu_info. */
-uintptr_t core_stacktops[MAX_NUM_CPUS] = {0xcafebabe, 0};
+uintptr_t core_stacktops[MAX_NUM_CORES] = {0xcafebabe, 0};
 
 void
 advance_pc(struct hw_trapframe *state)
@@ -53,21 +53,28 @@ idt_init(void)
 {
 }
 
-void
-sysenter_init(void)
+/* Helper.  For now, this copies out the TF to pcpui, and sets cur_ctx to point
+ * to it. */
+static void set_current_ctx_hw(struct per_cpu_info *pcpui,
+                               struct hw_trapframe *hw_tf)
 {
+       if (irq_is_enabled())
+               warn("Turn off IRQs until cur_ctx is set!");
+       assert(!pcpui->cur_ctx);
+       pcpui->actual_ctx.type = ROS_HW_CTX;
+       pcpui->actual_ctx.tf.hw_tf = *hw_tf;
+       pcpui->cur_ctx = &pcpui->actual_ctx;
 }
 
-/* Helper.  For now, this copies out the TF to pcpui, and sets cur_tf to point
- * to it. */
-static void
-set_current_tf(struct per_cpu_info *pcpui, struct trapframe *tf)
+static void set_current_ctx_sw(struct per_cpu_info *pcpui,
+                               struct sw_trapframe *sw_tf)
 {
        if (irq_is_enabled())
-               warn("Turn off IRQs until cur_tf is set!");
-       assert(!pcpui->cur_tf);
-       pcpui->actual_tf = *tf;
-       pcpui->cur_tf = &pcpui->actual_tf;
+               warn("Turn off IRQs until cur_ctx is set!");
+       assert(!pcpui->cur_ctx);
+       pcpui->actual_ctx.type = ROS_SW_CTX;
+       pcpui->actual_ctx.tf.sw_tf = *sw_tf;
+       pcpui->cur_ctx = &pcpui->actual_ctx;
 }
 
 static int
@@ -82,10 +89,10 @@ format_trapframe(struct hw_trapframe *hw_tf, char* buf, int bufsz)
        int len = snprintf(buf,bufsz,"TRAP frame at %p on core %d\n",
                           hw_tf, core_id());
        static const char* regnames[] = {
-         "z ", "ra", "v0", "v1", "a0", "a1", "a2", "a3",
-         "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3",
-         "t4", "t5", "t6", "t7", "s0", "s1", "s2", "s3",
-         "s4", "s5", "s6", "s7", "s8", "fp", "sp", "tp"
+         "z ", "ra", "s0", "s1", "s2", "s3", "s4", "s5",
+         "s6", "s7", "s8", "s9", "sA", "sB", "sp", "tp",
+         "v0", "v1", "a0", "a1", "a2", "a3", "a4", "a5",
+         "a6", "a7", "a8", "a9", "aA", "aB", "aC", "aD"
        };
        
        hw_tf->gpr[0] = 0;
@@ -105,25 +112,36 @@ format_trapframe(struct hw_trapframe *hw_tf, char* buf, int bufsz)
        return len;
 }
 
-void
-print_trapframe(struct hw_trapframe *hw_tf)
+void print_trapframe(struct hw_trapframe *hw_tf)
 {
        char buf[1024];
        int len = format_trapframe(hw_tf, buf, sizeof(buf));
        cputbuf(buf,len);
 }
 
+void print_swtrapframe(struct sw_trapframe *sw_tf)
+{
+       #warning "fix me"
+}
+
+void print_vmtrapframe(struct vm_trapframe *vm_tf)
+{
+       #warning "fix me"
+}
+
 static void exit_halt_loop(struct hw_trapframe *hw_tf)
 {
        extern char after_cpu_halt;
        if ((char*)hw_tf->epc >= (char*)&cpu_halt &&
            (char*)hw_tf->epc < &after_cpu_halt)
-               hw_tf->epc = hw_tf->gpr[1];
+               hw_tf->epc = hw_tf->gpr[GPR_RA];
 }
 
 static void handle_keypress(char c)
 {
-       amr_t handler = c == 'G' ? __run_mon : __cons_add_char;
+       /* brho: not sure if this will work on riscv or not... */
+       #define capchar2ctl(x) ((x) - '@')
+       amr_t handler = c == capchar2ctl('G') ? __run_mon : __cons_add_char;
        send_kernel_message(core_id(), handler, (long)&cons_buf, (long)c, 0,
                            KMSG_ROUTINE);
        cons_init();
@@ -173,7 +191,6 @@ unhandled_trap(struct hw_trapframe *state, const char* name)
                spin_unlock(&screwup_lock);
 
                assert(current);
-               enable_irq();
                proc_destroy(current);
        }
 }
@@ -205,8 +222,9 @@ handle_fault_fetch(struct hw_trapframe *state)
                panic("Instruction Page Fault in the Kernel at %p!", state->epc);
        }
 
-       set_current_tf(&per_cpu_info[core_id()], state);
+       set_current_ctx_hw(&per_cpu_info[core_id()], state);
 
+#warning "returns EAGAIN if you should reflect the fault"
        if(handle_page_fault(current, state->epc, PROT_EXEC))
                unhandled_trap(state, "Instruction Page Fault");
 }
@@ -220,8 +238,9 @@ handle_fault_load(struct hw_trapframe *state)
                panic("Load Page Fault in the Kernel at %p!", state->badvaddr);
        }
 
-       set_current_tf(&per_cpu_info[core_id()], state);
+       set_current_ctx_hw(&per_cpu_info[core_id()], state);
 
+#warning "returns EAGAIN if you should reflect the fault"
        if(handle_page_fault(current, state->badvaddr, PROT_READ))
                unhandled_trap(state, "Load Page Fault");
 }
@@ -235,7 +254,7 @@ handle_fault_store(struct hw_trapframe *state)
                panic("Store Page Fault in the Kernel at %p!", state->badvaddr);
        }
 
-       set_current_tf(&per_cpu_info[core_id()], state);
+       set_current_ctx_hw(&per_cpu_info[core_id()], state);
 
        if(handle_page_fault(current, state->badvaddr, PROT_WRITE))
                unhandled_trap(state, "Store Page Fault");
@@ -247,10 +266,10 @@ handle_illegal_instruction(struct hw_trapframe *state)
        assert(!in_kernel(state));
 
        struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
-       set_current_tf(pcpui, state);
+       set_current_ctx_hw(pcpui, state);
        if (emulate_fpu(state) == 0)
        {
-               advance_pc(pcpui->cur_tf);
+               advance_pc(&pcpui->cur_ctx->tf.hw_tf);
                return;
        }
 
@@ -258,23 +277,13 @@ handle_illegal_instruction(struct hw_trapframe *state)
 }
 
 static void
-handle_fp_disabled(struct hw_trapframe *hw_tf)
-{
-       if (in_kernel(hw_tf))
-               panic("kernel executed an FP instruction!");
-
-       hw_tf->sr |= SR_EF;
-       env_pop_tf(hw_tf); /* We didn't save our TF, so don't proc_restartcore */
-}
-
-static void
 handle_syscall(struct hw_trapframe *state)
 {
-       uintptr_t a0 = state->gpr[4];
-       uintptr_t a1 = state->gpr[5];
+       uintptr_t a0 = state->gpr[GPR_A0];
+       uintptr_t a1 = state->gpr[GPR_A1];
 
        advance_pc(state);
-       set_current_tf(&per_cpu_info[core_id()], state);
+       set_current_ctx_hw(&per_cpu_info[core_id()], state);
        enable_irq();
        prep_syscalls(current, (struct syscall*)a0, a1);
 }
@@ -294,7 +303,6 @@ handle_trap(struct hw_trapframe *hw_tf)
          [CAUSE_FAULT_FETCH] = handle_fault_fetch,
          [CAUSE_ILLEGAL_INSTRUCTION] = handle_illegal_instruction,
          [CAUSE_PRIVILEGED_INSTRUCTION] = handle_illegal_instruction,
-         [CAUSE_FP_DISABLED] = handle_fp_disabled,
          [CAUSE_SYSCALL] = handle_syscall,
          [CAUSE_BREAKPOINT] = handle_breakpoint,
          [CAUSE_MISALIGNED_LOAD] = handle_misaligned_load,
@@ -319,7 +327,7 @@ handle_trap(struct hw_trapframe *hw_tf)
                if (in_kernel(hw_tf))
                        exit_halt_loop(hw_tf);
                else
-                       set_current_tf(&per_cpu_info[core_id()], hw_tf);
+                       set_current_ctx_hw(&per_cpu_info[core_id()], hw_tf);
 
                inc_irq_depth(pcpui);
                irq_handlers[irq](hw_tf);
@@ -336,13 +344,16 @@ handle_trap(struct hw_trapframe *hw_tf)
                } else {
                        trap_handlers[hw_tf->cause](hw_tf);
                }
+               #warning "if a trap wasn't handled fully, like an MCP pf, reflect it
+               reflect_unhandled_trap(hw_tf->tf_trapno, hw_tf->tf_err, aux);
        }
        
+       extern void pop_hw_tf(struct hw_trapframe *tf); /* in asm */
        /* Return to the current process, which should be runnable.  If we're the
         * kernel, we should just return naturally.  Note that current and tf need
         * to still be okay (might not be after blocking) */
        if (in_kernel(hw_tf))
-               env_pop_tf(hw_tf);      /* TODO: for a kernel tf?  change names? */
+               pop_hw_tf(hw_tf);
        else
                proc_restartcore();
 }
@@ -350,4 +361,23 @@ handle_trap(struct hw_trapframe *hw_tf)
 /* We don't have NMIs now. */
 void send_nmi(uint32_t os_coreid)
 {
+       printk("%s not implemented\n", __FUNCTION);
+}
+
+int register_irq(int irq, isr_t handler, void *irq_arg, uint32_t tbdf)
+{
+       printk("%s not implemented\n", __FUNCTION);
+       return -1;
+}
+
+int route_irqs(int cpu_vec, int coreid)
+{
+       printk("%s not implemented\n", __FUNCTION);
+       return -1;
+}
+
+void __arch_reflect_trap_hwtf(struct hw_trapframe *hw_tf, unsigned int trap_nr,
+                              unsigned int err, unsigned long aux)
+{
+       printk("%s not implemented\n", __FUNCTION);
 }