#include <arch.h>
#include <debug.h>
#include <process.h>
+#include <signal.h>
#include "cpu.h"
#include "defs.h"
*/
/* PANIC("Unhandled interrupt"); */
- switch(ctx.intn) {
- case INT_KEYBOARD: {
-#if FEATURE(DEBUG)
- extern struct cpu _cpu[CONFIG_SMP_CPUS];
-#endif /* FEATURE(DEBUG) */
-
- dbg_printf("Keyboard interrupt\n");
-
-#if FEATURE(DEBUG)
- /* hacky reboot: clear IDT entries for
- * #DF and #GP, then cause a #GP */
- _cpu[CPU_ID].cpu_idt[EXC_DOUBLEFAULT].sd_low = 0;
- _cpu[CPU_ID].cpu_idt[EXC_DOUBLEFAULT].sd_high = 0;
- _cpu[CPU_ID].cpu_idt[EXC_PROTECTION].sd_low = 0;
- _cpu[CPU_ID].cpu_idt[EXC_PROTECTION].sd_high = 0;
-
- /* this is such a retarded thing to do, I don't see how this
- * could not cause a triple fault */
- asm volatile("ljmp $0x30, $0xfee00020"); /* LEEROY JENKINS!!! */
-#endif /* FEATURE(DEBUG) */
- break;
- }
-
- case INT_TIMER:
+ if(ctx.intn == INT_TIMER) {
sched_tick();
- break;
-
- default:
- dbg_printf("Interrupt %u occurred\n", ctx.intn);
- break;
+ } else {
+ /* FIXME: handle interrupt */
}
return;
cproc = process_get_current();
- dbg_printf("Exception %u [%s] occurred. Error code 0x%08x.\n", ctx.intn, ctx.intn < EXC_MAX ? _exc_name[ctx.intn] : 0, ctx.error);
- dbg_printf("In context %p [pid %u]\n", cproc, process_get_id(cproc));
- dbg_printf("Fault in 0x%02x:%08x; EFLAGS = 0x%08x\n", ctx.cs, ctx.eip, ctx.eflags);
+ if(ctx.cs == KERNEL_CODE) {
+ /* kernel bug */
+
+ dbg_printf("Exception %u [%s] occurred. Error code 0x%08x.\n",
+ ctx.intn, ctx.intn < EXC_MAX ? _exc_name[ctx.intn] : 0, ctx.error);
+ dbg_printf("In context %p [pid %u]\n", cproc, process_get_id(cproc));
+ dbg_printf("Fault in 0x%02x:%08x; EFLAGS = 0x%08x\n", ctx.cs, ctx.eip, ctx.eflags);
- if(ctx.intn == EXC_PAGEFAULT) {
- u32_t cr2;
- pg_dir_t *pd;
+ if(ctx.intn == EXC_PAGEFAULT) {
+ u32_t cr2;
+ pg_dir_t *pd;
- asm volatile("movl %%cr2, %%eax; movl %%eax, %0" : "=r"(cr2));
- dbg_printf("Page fault address: 0x%08x\n", cr2);
+ asm volatile("movl %%cr2, %%eax; movl %%eax, %0" : "=r"(cr2));
+ dbg_printf("Page fault address: 0x%08x\n", cr2);
- if(process_get_pagedir(cproc, &pd) == 0) {
- pg_fault_debug(pd, (void*)cr2);
+ if(process_get_pagedir(cproc, &pd) == 0) {
+ pg_fault_debug(pd, (void*)cr2);
+ }
}
- }
- PANIC("Unhandled exception");
+ PANIC("Unhandled exception");
+
+ } else {
+ /* deliver exception to causing process */
+
+ int sig;
+
+ switch(ctx.intn) {
+ default:
+ case EXC_DEBUG:
+ case EXC_NMI:
+ case EXC_BREAKPOINT:
+ case EXC_OVERFLOW:
+ case EXC_BOUNDRANGE:
+ case EXC_DEVNOTAVAIL:
+ case EXC_DOUBLEFAULT:
+ case EXC_COPROCSEGM:
+ case EXC_INVALIDTSS:
+ case EXC_SEGMNOTPRES:
+ case EXC_STACKFAULT:
+ case EXC_PROTECTION:
+ case EXC_PAGEFAULT:
+ case EXC_ALIGNMENT:
+ case EXC_MACHINECHECK:
+ case EXC_VIRTUALIZATION:
+ sig = SIGSEGV;
+ break;
+
+ case EXC_INVALOPCODE:
+ sig = SIGILL;
+ break;
+
+ case EXC_DIVERR:
+ case EXC_FPUERROR:
+ case EXC_SIMD:
+ sig = SIGFPE;
+ break;
+ }
+
+ /*
+ * Deliver the signal to the current process. The process_signal_deliver()
+ * function will make sure that the signal is handled by the current task.
+ */
+ process_signal_deliver(cproc, sig);
+ }
return;
}