// The OS/K Team licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. #include int dying = 0; void _except(int _code, char *fmt, ...) { va_list ap; ulong handler; uint code = _code; uint effcode; ulong orig_frame; // // Interrupted earlier? // if (dying) { logerr("Exception thrown while dying=1\n"); exit(-12); } if (code >= IDT_SLOTS || code == 1023) goto actually_die; // // Check for E/I handlers // if (idt[code] == 0) { if (code == E_DBF) effcode = E_DBF; else if (code < 512) effcode = 0; else if (code < 768) effcode = 512; else effcode = 768; } else effcode = code; handler = idt[effcode]; // Found nothing? if (handler == 0) goto actually_die; // oh well // Is another handler already running? if (idt_handling[code] > 0) { // Triple fault? if (code == E_DBF) goto actually_die; // Double fault then? if (code < 512) _except(E_DBF, "Double Fault; previously handling: #%u", code); // Todo: queue INTs else goto actually_die; } // Is this a valid frame? if (rfs[handler] != NULL) { if (ctx->dumpsw) { trace("\n(Caught) Exception %u - ", code); va_start(ap, fmt); vprintf(fmt, ap); va_end(ap); trace("\n\n"); } orig_frame = rfs_current_idx; ctx->rf = rfs[handler]; rfs_current_idx = handler; R(R12) = code; R(R13) = effcode; R(R14) = orig_frame; R(R15) = R(RIP); idt_handling[effcode]++; longjmp(exc_jmp_buf, code); __builtin_unreachable(); } actually_die: logerr("\nException %u - ", code); va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); logerr("\n\n"); dying = 1; dumpregs(); logerr("\n"); die(code); }