kvisc/vm/pc/except.c

103 lines
1.8 KiB
C
Raw Normal View History

2019-05-16 21:42:23 +02:00
// The OS/K Team licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
2019-06-13 23:12:11 +02:00
#include <pc/dev.h>
2019-06-16 12:48:30 +02:00
int dying = 0;
2019-05-16 21:42:23 +02:00
2019-06-18 22:56:41 +02:00
void _except(ctx_t *ctx, int _code, char *fmt, ...)
2019-05-16 21:42:23 +02:00
{
va_list ap;
2019-06-18 22:56:41 +02:00
ulong handler;
uint code = _code;
2019-05-16 21:42:23 +02:00
2019-06-18 22:56:41 +02:00
ulong orig_frame;
2019-06-19 21:41:22 +02:00
logerr("\nException %u - ", code);
2019-06-18 22:56:41 +02:00
va_start(ap, fmt);
vlog(fmt, ap);
va_end(ap);
2019-06-19 21:41:22 +02:00
logerr("\n\n");
2019-06-18 22:56:41 +02:00
//
// Interrupted earlier?
//
2019-06-16 12:48:30 +02:00
if (dying)
{
2019-06-19 21:41:22 +02:00
logerr("Exception thrown while dying=1\n");
2019-06-18 22:56:41 +02:00
enable_stdin_echoing();
2019-06-16 12:48:30 +02:00
exit(-12);
}
2019-06-05 22:59:32 +02:00
2019-06-18 22:56:41 +02:00
if (code >= IDT_SLOTS)
goto actually_die;
2019-05-30 12:44:56 +02:00
2019-06-18 22:56:41 +02:00
//
// Check for E/I handlers
//
if (idt[code] == 0)
{
if (code < 512 && code != E_DBF)
handler = idt[0];
2019-05-30 12:44:56 +02:00
2019-06-18 22:56:41 +02:00
else if (code < 768)
handler = idt[512];
else
handler = idt[768];
}
else
handler = idt[code];
// 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);
// XXX Queue TRAPs and 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;
rax = code;
R(CR6) = rip;
R(CR7) = orig_frame;
idt_handling[code]++;
main_loop();
}
actually_die:
dying = 1;
2019-05-16 21:42:23 +02:00
dumpregs(ctx);
2019-06-19 21:41:22 +02:00
trace("\n");
2019-06-05 19:31:48 +02:00
2019-06-19 21:41:22 +02:00
die(code);
2019-05-16 21:42:23 +02:00
}