kvisc/vm/pc/except.c

121 lines
2.1 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-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-08-03 19:01:12 +02:00
void _except(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-07-04 20:33:49 +02:00
uint effcode;
2019-05-16 21:42:23 +02:00
2019-07-09 21:02:26 +02:00
ulong orig_frame;
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-16 12:48:30 +02:00
exit(-12);
}
2019-06-05 22:59:32 +02:00
2019-06-30 13:46:44 +02:00
if (code >= IDT_SLOTS || code == 1023)
2019-06-18 22:56:41 +02:00
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)
{
2019-07-04 20:33:49 +02:00
if (code == E_DBF)
effcode = E_DBF;
2019-07-09 21:02:26 +02:00
else if (code < 512)
2019-07-04 20:33:49 +02:00
effcode = 0;
2019-05-30 12:44:56 +02:00
2019-06-18 22:56:41 +02:00
else if (code < 768)
2019-07-04 20:33:49 +02:00
effcode = 512;
2019-06-18 22:56:41 +02:00
else
2019-07-04 20:33:49 +02:00
effcode = 768;
2019-06-18 22:56:41 +02:00
}
else
2019-07-04 20:33:49 +02:00
effcode = code;
handler = idt[effcode];
2019-06-18 22:56:41 +02:00
// 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)
2019-08-03 19:01:12 +02:00
_except(E_DBF, "Double Fault; previously handling: #%u", code);
2019-06-18 22:56:41 +02:00
2019-07-04 20:33:49 +02:00
// Todo: queue INTs
2019-06-18 22:56:41 +02:00
else
goto actually_die;
}
// Is this a valid frame?
if (rfs[handler] != NULL)
{
2019-07-17 22:25:50 +02:00
if (ctx->dumpsw)
{
2019-08-14 20:23:05 +02:00
trace("\n(Caught) Exception %u - ", code);
2019-07-17 22:25:50 +02:00
va_start(ap, fmt);
2019-07-24 16:52:26 +02:00
vprintf(fmt, ap);
2019-07-17 22:25:50 +02:00
va_end(ap);
trace("\n\n");
}
2019-06-18 22:56:41 +02:00
orig_frame = rfs_current_idx;
ctx->rf = rfs[handler];
rfs_current_idx = handler;
2019-07-22 13:18:13 +02:00
R(R12) = code;
R(R13) = effcode;
R(R14) = orig_frame;
R(R15) = R(RIP);
2019-06-18 22:56:41 +02:00
2019-07-04 20:33:49 +02:00
idt_handling[effcode]++;
2019-06-18 22:56:41 +02:00
2019-06-21 22:19:55 +02:00
longjmp(exc_jmp_buf, code);
2019-07-04 20:33:49 +02:00
__builtin_unreachable();
2019-06-18 22:56:41 +02:00
}
actually_die:
2019-07-17 22:25:50 +02:00
logerr("\nException %u - ", code);
va_start(ap, fmt);
2019-07-24 16:52:26 +02:00
vfprintf(stderr, fmt, ap);
2019-07-17 22:25:50 +02:00
va_end(ap);
logerr("\n\n");
2019-06-18 22:56:41 +02:00
dying = 1;
2019-08-03 19:01:12 +02:00
dumpregs();
2019-07-17 22:25:50 +02:00
logerr("\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
}