#include #include #include #include #include "memory.h" void kpanic(const char *reason){ kputs("\n!!! PANIC !!!\n"); kputs(reason); kputs("\n!!! PANIC !!!\n"); poweroff(); } void kpanic_force() { kprint("\n!!! FORCE PANIC !!!\n"); // 'ebreak' is the standard RISC-V way to trigger a debug trap. __asm__ volatile("ebreak"); kprint("Force panic falled. Power off. \n"); poweroff(); kprint("Force panic falled. Power off failed. sleep until interupt. \n"); while(1) { __asm__ volatile("wfi"); } } void handle_trap() { kprint("\n!!! HARDWARE EXCEPTION DETECTED !!!\n"); // Read the 'mcause' register to see WHY we trapped unsigned long cause; __asm__ volatile("csrr %0, mcause" : "=r"(cause)); // fault address (if applicable) uintptr_t mtval; asm volatile("csrr %0, mtval" : "=r"(mtval)); switch(cause) { case 0: kprint("Reason: Instruction Address Misaligned\n"); break; case 1: kprint("Reason: Instruction Access Fault\n"); break; case 2: kprint("Reason: Illegal Instruction\n"); break; case 3: kprint("Reason: Breakpoint (ebreak)\n"); break; case 4: kprint("Reason: Load Address Misaligned\n"); break; case 5: kprint("Reason: Load Access Fault\n"); break; case 6: kprint("Reason: Store/AMO Address Misaligned\n"); break; case 7: kprint("Reason: Store/AMO Access Fault\n"); break; default: kprintf("Reason: Unknown Exception Code %d\n", cause); } kprintf("Faulting Address (if applicable): 0x%p\n", mtval); heap_stats(); poweroff(); }