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-21 22:19:55 +02:00
|
|
|
#include <pc/device.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;
|
|
|
|
|
2019-06-23 21:12:25 +02:00
|
|
|
rx2 = 0;
|
2019-06-18 22:56:41 +02:00
|
|
|
rax = code;
|
|
|
|
R(CR6) = rip;
|
|
|
|
R(CR7) = orig_frame;
|
|
|
|
|
|
|
|
idt_handling[code]++;
|
|
|
|
|
2019-06-21 22:19:55 +02:00
|
|
|
longjmp(exc_jmp_buf, code);
|
2019-06-18 22:56:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|