summaryrefslogtreecommitdiff
path: root/src/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel')
-rw-r--r--src/kernel/main.cc46
-rw-r--r--src/kernel/trap/handler.cc123
-rw-r--r--src/kernel/trap/trap.S87
3 files changed, 240 insertions, 16 deletions
diff --git a/src/kernel/main.cc b/src/kernel/main.cc
index beda9dc..2fa10a2 100644
--- a/src/kernel/main.cc
+++ b/src/kernel/main.cc
@@ -1,20 +1,21 @@
#include "drivers/uart.h"
#include "kernel/pmm.h"
#include "kernel/mm.h"
+#include "kernel/trap.h"
-void print_hex(uint64_t val)
-{
- char buf[17];
- buf[16] = 0;
- const char *digits = "0123456789ABCDEF";
- for (int i = 15; i >= 0; i--)
- {
- buf[i] = digits[val & 0xf];
- val >>= 4;
- }
- Drivers::uart_puts("0x");
- Drivers::uart_puts(buf);
-}
+// void print_hex(uint64_t val)
+// {
+// char buf[17];
+// buf[16] = 0;
+// const char *digits = "0123456789ABCDEF";
+// for (int i = 15; i >= 0; i--)
+// {
+// buf[i] = digits[val & 0xf];
+// val >>= 4;
+// }
+// Drivers::uart_puts("0x");
+// Drivers::uart_puts(buf);
+// }
extern "C" void kernel_main()
{
@@ -33,11 +34,11 @@ extern "C" void kernel_main()
void *p2 = PMM::alloc_page();
Drivers::uart_puts("Allocated Page 1: ");
- print_hex((uint64_t)p1);
+ Drivers::print_hex((uint64_t)p1);
Drivers::uart_puts("\n");
Drivers::uart_puts("Allocated Page 2: ");
- print_hex((uint64_t)p2);
+ Drivers::print_hex((uint64_t)p2);
Drivers::uart_puts("\n");
Drivers::uart_puts("[Kernel] Freeing Page 1...\n");
@@ -45,7 +46,7 @@ extern "C" void kernel_main()
void *p3 = PMM::alloc_page();
Drivers::uart_puts("Allocated Page 3: ");
- print_hex((uint64_t)p3);
+ Drivers::print_hex((uint64_t)p3);
Drivers::uart_puts("\n");
if (p3 == p1)
@@ -63,6 +64,19 @@ extern "C" void kernel_main()
VM::kvminithart();
Drivers::uart_puts("[Boot] MMU ENABLED! We are now using virtual addresses.\n");
+ Trap::init();
+ Drivers::uart_puts("[Boot] Trap Handler Installed.\n");
+
+ Drivers::uart_puts("\n[Test] Triggering Page Fault by reading 0x0...\n");
+ volatile int *p = (int *)0x0;
+ int crash = *p;
+ (void)crash;
+
+ Drivers::uart_puts("[Test Failed] Shuold not reach here.\n");
+
+ Drivers::uart_puts("\n[Test] Triggering Store Fault on Text Segment...\n");
+ *(int*)0x80000000 = 1234;
+
while (1)
{
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
diff --git a/src/kernel/trap/trap.S b/src/kernel/trap/trap.S
new file mode 100644
index 0000000..ffce52a
--- /dev/null
+++ b/src/kernel/trap/trap.S
@@ -0,0 +1,87 @@
+.section .text
+.global kernelvec
+.align 4
+
+kernelvec:
+
+ addi sp, sp, -256
+
+ sd ra, 40(sp)
+ sd sp, 48(sp)
+ sd gp, 56(sp)
+ sd tp, 64(sp)
+ sd t0, 72(sp)
+ sd t1, 80(sp)
+ sd t2, 88(sp)
+ sd s0, 96(sp)
+ sd s1, 104(sp)
+ sd a0, 112(sp)
+ sd a1, 120(sp)
+ sd a2, 128(sp)
+ sd a3, 136(sp)
+ sd a4, 144(sp)
+ sd a5, 152(sp)
+ sd a6, 160(sp)
+ sd a7, 168(sp)
+ sd s2, 176(sp)
+ sd s3, 184(sp)
+ sd s4, 192(sp)
+ sd s5, 200(sp)
+ sd s6, 208(sp)
+ sd s7, 216(sp)
+ sd s8, 224(sp)
+ sd s9, 232(sp)
+ sd s10, 240(sp)
+ sd s11, 248(sp)
+ sd t3, 256(sp)
+ sd t4, 264(sp)
+ sd t5, 272(sp)
+ sd t6, 280(sp)
+
+ csrr t0, sepc
+ csrr t1, sstatus
+ sd t0, 24(sp) # Trapframe.epc
+ sd t1, 32(sp) # Trapframe.kernel_hartid
+
+ mv a0, sp
+ call kerneltrap
+
+ ld t0, 24(sp)
+ ld t1, 32(sp)
+ csrw sepc, t0
+ csrw sstatus, t1
+
+ ld ra, 40(sp)
+ ld gp, 56(sp)
+ ld tp, 64(sp)
+ ld t0, 72(sp)
+ ld t1, 80(sp)
+ ld t2, 88(sp)
+ ld s0, 96(sp)
+ ld s1, 104(sp)
+ ld a0, 112(sp)
+ ld a1, 120(sp)
+ ld a2, 128(sp)
+ ld a3, 136(sp)
+ ld a4, 144(sp)
+ ld a5, 152(sp)
+ ld a6, 160(sp)
+ ld a7, 168(sp)
+ ld s2, 176(sp)
+ ld s3, 184(sp)
+ ld s4, 192(sp)
+ ld s5, 200(sp)
+ ld s6, 208(sp)
+ ld s7, 216(sp)
+ ld s8, 224(sp)
+ ld s9, 232(sp)
+ ld s10, 240(sp)
+ ld s11, 248(sp)
+ ld t3, 256(sp)
+ ld t4, 264(sp)
+ ld t5, 272(sp)
+ ld t6, 280(sp)
+
+ addi sp, sp, 256
+
+ sret \ No newline at end of file