summaryrefslogtreecommitdiff
path: root/src/kernel/trap/handler.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel/trap/handler.cc')
-rw-r--r--src/kernel/trap/handler.cc123
1 files changed, 123 insertions, 0 deletions
diff --git a/src/kernel/trap/handler.cc b/src/kernel/trap/handler.cc
new file mode 100644
index 0000000..9cc19d1
--- /dev/null
+++ b/src/kernel/trap/handler.cc
@@ -0,0 +1,123 @@
+#include "kernel/trap.h"
+#include "common/types.h"
+#include "drivers/uart.h"
+
+void panic(const char *s)
+{
+ Drivers::uart_puts("\n\n!!! KERNEL PANIC !!!\n");
+ Drivers::uart_puts(s);
+ Drivers::uart_puts("\nSystem Halted.\n");
+ while (1)
+ ;
+}
+
+namespace Trap
+{
+ void init()
+ {
+ uint64 stvec_val = (uint64)kernelvec;
+ asm volatile("csrw stvec, %0" : : "r"(stvec_val));
+
+ uint64 sstatus;
+ asm volatile("csrr %0, sstatus" : "=r"(sstatus));
+ sstatus &= ~(1L << 1);
+ asm volatile("csrw sstatus, %0" : : "r"(sstatus));
+
+ Drivers::uart_puts("[Trap] Initialized stvec to: ");
+ Drivers::print_hex(stvec_val);
+ Drivers::uart_puts("\n");
+ }
+
+ extern "C" void kerneltrap(struct Trapframe *tf)
+ {
+ uint64 scause, stval, sepc;
+
+ asm volatile("csrr %0, scause" : "=r"(scause));
+ asm volatile("csrr %0, stval" : "=r"(stval));
+ asm volatile("csrr %0, sepc" : "=r"(sepc));
+
+ if (scause & (1L << 63))
+ {
+ uint64 cause_code = scause & 0x7FFFFFFFFFFFFFFFL;
+ switch (cause_code)
+ {
+ case 1:
+ Drivers::uart_puts("[IRQ] Software Interrupt\n");
+ asm volatile("csrc sip, %0" : : "r"(1 << 1));
+ break;
+
+ case 5:
+ Drivers::uart_puts("[IRQ] Timer Interrupt\n");
+
+ break;
+
+ case 9:
+ Drivers::uart_puts("[IRQ] External Interrupt\n");
+ break;
+
+ default:
+ Drivers::uart_puts("[IRQ] Unknown Interrupt: ");
+ Drivers::print_hex(cause_code);
+ Drivers::uart_puts("\n");
+ break;
+ }
+ }
+ else
+ {
+ switch (scause)
+ {
+ case 8:
+ Drivers::uart_puts("[Syscall] ecall for User Mode\n");
+ tf->epc += 4;
+ break;
+
+ case 12:
+ case 13:
+ case 15:
+ Drivers::uart_puts("\n--- PAGE FAULT ---\n");
+ Drivers::uart_puts("Cause Code: ");
+ Drivers::print_hex(scause);
+ Drivers::uart_puts("\n");
+ Drivers::uart_puts("Fault Addr (stval): ");
+ Drivers::print_hex(stval);
+ Drivers::uart_puts("\n");
+ Drivers::uart_puts("Instruction (sepc): ");
+ Drivers::print_hex(sepc);
+ Drivers::uart_puts("\n");
+
+ if (stval == 0)
+ {
+ panic("Null Pointer Dereference!");
+ }
+ else if (stval < 0x80000000)
+ {
+ panic("Invalid Low Memory Access!");
+ }
+ else
+ {
+ panic("Segmentation Fault (Unmapped Area)");
+ }
+ break;
+
+ case 2:
+ Drivers::uart_puts("\n--- ILLEGAL INSTRUCTION ---\n");
+ Drivers::uart_puts("Instruction (sepc): ");
+ Drivers::print_hex(sepc);
+ Drivers::uart_puts("\n");
+ panic("CPU encountered an unknown opcode");
+ break;
+
+ default:
+ Drivers::uart_puts("\n--- UNHANDLED EXCEPTION ---\n");
+ Drivers::uart_puts("Cause: ");
+ Drivers::print_hex(scause);
+ Drivers::uart_puts("\n");
+ Drivers::uart_puts("sepc: ");
+ Drivers::print_hex(sepc);
+ Drivers::uart_puts("\n");
+ panic("System Halt");
+ break;
+ }
+ }
+ }
+} \ No newline at end of file