// 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(ctx_t *ctx, int _code, char *fmt, ...) { va_list ap; ulong handler; uint code = _code; uint effcode; ulong orig_frame; trace("\nException %u - ", code); va_start(ap, fmt); vlog(fmt, ap); va_end(ap); trace("\n\n"); // // Interrupted earlier? // if (dying) { logerr("Exception thrown while dying=1\n"); enable_stdin_echoing(); 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(ctx, E_DBF, "Double Fault; previously handling: #%u", code); // Todo: queue INTs else goto actually_die; } // Is this a valid frame? if (rfs[handler] != NULL) { orig_frame = rfs_current_idx; ctx->rf = rfs[handler]; rfs_current_idx = handler; fc2 = 0; R(R10) = code; R(R11) = effcode; R(R12) = orig_frame; R(R13) = rip; idt_handling[effcode]++; longjmp(exc_jmp_buf, code); __builtin_unreachable(); } actually_die: dying = 1; dumpregs(ctx); trace("\n"); die(code); }