mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
641 lines
17 KiB
641 lines
17 KiB
/*[
|
|
|
|
c_xcptn.c
|
|
|
|
LOCAL CHAR SccsID[]="@(#)c_xcptn.c 1.14 01/31/95";
|
|
|
|
Exception Handling Support.
|
|
---------------------------
|
|
|
|
]*/
|
|
|
|
|
|
#include <stdio.h>
|
|
#include <insignia.h>
|
|
|
|
#include <host_def.h>
|
|
#include StringH
|
|
#include <xt.h>
|
|
|
|
#include <c_main.h>
|
|
#include <c_addr.h>
|
|
#include <c_bsic.h>
|
|
#include <c_prot.h>
|
|
#include <c_seg.h>
|
|
#include <c_stack.h>
|
|
#include <c_xcptn.h>
|
|
#include <c_reg.h>
|
|
#include <c_intr.h>
|
|
#include <c_xtrn.h>
|
|
#include <ccpupig.h>
|
|
#include <fault.h>
|
|
|
|
/*
|
|
Allow print out of exceptions or disallow it.
|
|
*/
|
|
GLOBAL BOOL show_exceptions = FALSE;
|
|
GLOBAL BOOL trap_exceptions = FALSE;
|
|
LOCAL BOOL first_exception = TRUE;
|
|
|
|
#define check_exception_env() \
|
|
{ \
|
|
IMPORT char *host_getenv IPT1 (char *, name); \
|
|
if (first_exception) \
|
|
{ \
|
|
char *env = host_getenv ("CCPU_SHOW_EXCEPTIONS"); \
|
|
if (env != NULL) \
|
|
{ \
|
|
show_exceptions = TRUE; \
|
|
if (strcasecmp(env, "TRAP") == 0) \
|
|
trap_exceptions = TRUE; \
|
|
} \
|
|
} \
|
|
first_exception = FALSE; \
|
|
}
|
|
|
|
IMPORT FILE *trace_file;
|
|
IMPORT IBOOL took_absolute_toc;
|
|
|
|
/*
|
|
Intel interrupt(exception) numbers.
|
|
*/
|
|
#define I0_INT_NR 0
|
|
#define I1_INT_NR 1
|
|
#define I5_INT_NR 5
|
|
#define I6_INT_NR 6
|
|
#define I7_INT_NR 7
|
|
#define I16_INT_NR 16
|
|
#define DF_INT_NR 8
|
|
#define GP_INT_NR 13
|
|
#define NP_INT_NR 11
|
|
#define PF_INT_NR 14
|
|
#define SF_INT_NR 12
|
|
#define TS_INT_NR 10
|
|
|
|
#define NULL_ERROR_CODE (IU16)0
|
|
|
|
/*
|
|
Intel IDT Error Code format.
|
|
*/
|
|
#define IDT_VECTOR_MASK 0xff
|
|
#define IDT_VECTOR_SHIFT 3
|
|
#define IDT_INDICATOR_BIT 2
|
|
|
|
/*
|
|
Interrupt/Fault Status.
|
|
*/
|
|
GLOBAL BOOL doing_contributory;
|
|
GLOBAL BOOL doing_page_fault;
|
|
GLOBAL BOOL doing_double_fault;
|
|
GLOBAL BOOL doing_fault; /* true: FAULT, false: TRAP or ABORT */
|
|
GLOBAL ISM32 EXT; /* external/internal source */
|
|
GLOBAL IU32 CCPU_save_EIP; /* IP at start of instruction */
|
|
|
|
/*
|
|
Prototype our internal functions.
|
|
*/
|
|
LOCAL VOID check_for_double_fault IPT1(IU16, xcode);
|
|
|
|
LOCAL VOID check_for_shutdown IPT1(IU16, xcode);
|
|
|
|
LOCAL VOID benign_exception IPT3( ISM32, nmbr, ISM32, source, IU16, xcode);
|
|
|
|
LOCAL VOID contributory_exception IPT3( IU16, selector, ISM32, nmbr, IU16, xcode);
|
|
|
|
LOCAL VOID contributory_idt_exception IPT3( IU16, vector, ISM32, nmbr, IU16, xcode);
|
|
|
|
LOCAL char *faultstr IPT1(ISM32, nmbr );
|
|
|
|
|
|
/*
|
|
=====================================================================
|
|
INTERNAL ROUTINES START HERE.
|
|
=====================================================================
|
|
*/
|
|
|
|
LOCAL char *faultstr IFN1(ISM32, nmbr )
|
|
{
|
|
char *faulttable[] =
|
|
{
|
|
"DIV", "DBG", "NMI", "BPT",
|
|
"OVF", "BND", "OPC", "NAV",
|
|
"DF", "9", "TSS", "NP", "SF",
|
|
"GP", "PF", "15", "FPE", "ALN"
|
|
};
|
|
SAVED char buf[4];
|
|
|
|
if (nmbr > 16)
|
|
{
|
|
sprintf(buf, "%d", nmbr);
|
|
return buf;
|
|
}
|
|
else
|
|
return faulttable[nmbr];
|
|
}
|
|
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
/* Determine if things are so bad we need a double fault. */
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
LOCAL VOID
|
|
check_for_double_fault IFN1( IU16, xcode)
|
|
{
|
|
if ( doing_contributory || doing_page_fault )
|
|
DF(xcode);
|
|
}
|
|
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
/* Determine if things are so bad we need to close down. */
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
LOCAL VOID check_for_shutdown IFN1(IU16, xcode)
|
|
{
|
|
if ( doing_double_fault )
|
|
{
|
|
doing_contributory = FALSE;
|
|
doing_page_fault = FALSE;
|
|
doing_double_fault = FALSE;
|
|
EXT = INTERNAL;
|
|
|
|
/* force a reset - see schematic for AT motherboard */
|
|
c_cpu_reset();
|
|
|
|
#ifdef PIG
|
|
save_last_xcptn_details("Exception:- Shutdown @%2d\n", xcode, 0, 0, 0, 0);
|
|
ccpu_synch_count++;
|
|
pig_cpu_action = CHECK_ALL;
|
|
c_cpu_unsimulate();
|
|
#endif /* PIG */
|
|
|
|
/* then carry on */
|
|
c_cpu_continue(); /* DOES NOT RETURN */
|
|
}
|
|
}
|
|
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
/* Handle Benign Exception */
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
LOCAL VOID
|
|
benign_exception
|
|
|
|
IFN3(
|
|
ISM32, nmbr, /* exception number */
|
|
ISM32, source, /* internal/external interrupt cause */
|
|
IU16, xcode /* insignia exception code */
|
|
)
|
|
|
|
|
|
{
|
|
SET_EIP(CCPU_save_EIP);
|
|
|
|
#ifdef NTVDM
|
|
{
|
|
extern BOOL host_exint_hook IPT2(IS32, exp_no, IS32, error_code);
|
|
|
|
if(GET_PE() && host_exint_hook((IS32) nmbr, NULL_ERROR_CODE))
|
|
c_cpu_continue(); /* DOES NOT RETURN */
|
|
}
|
|
#endif
|
|
|
|
/* Set default mode up */
|
|
SET_OPERAND_SIZE(GET_SR_AR_X(CS_REG));
|
|
SET_ADDRESS_SIZE(GET_SR_AR_X(CS_REG));
|
|
SET_POP_DISP(0);
|
|
|
|
EXT = source;
|
|
check_exception_env();
|
|
#ifdef PIG
|
|
save_last_xcptn_details("Exception:- #%s-%d @%2d \n", (IUH)faultstr(nmbr), nmbr, xcode, 0, 0);
|
|
#endif /* PIG */
|
|
if (show_exceptions){
|
|
fprintf(trace_file, "(%04x:%08x)Exception:- %d.\n",
|
|
GET_CS_SELECTOR(), GET_EIP(), nmbr);
|
|
if (trap_exceptions) force_yoda();
|
|
}
|
|
took_absolute_toc = TRUE;
|
|
do_intrupt((IU16)nmbr, FALSE, FALSE, NULL_ERROR_CODE);
|
|
|
|
c_cpu_continue(); /* DOES NOT RETURN */
|
|
}
|
|
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
/* Handle Contributory Exception */
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
LOCAL VOID
|
|
contributory_exception
|
|
|
|
IFN3(
|
|
IU16, selector, /* failing selector */
|
|
ISM32, nmbr, /* exception number */
|
|
IU16, xcode /* insignia exception code */
|
|
)
|
|
|
|
|
|
{
|
|
IU16 error_code;
|
|
|
|
|
|
/* check if exception caused by external caller */
|
|
check_interface_active(nmbr);
|
|
|
|
check_for_shutdown(xcode);
|
|
check_for_double_fault(xcode);
|
|
|
|
doing_contributory = TRUE;
|
|
|
|
error_code = (selector & 0xfffc) | EXT;
|
|
|
|
SET_EIP(CCPU_save_EIP);
|
|
|
|
#ifdef NTVDM
|
|
{
|
|
extern BOOL host_exint_hook IPT2(IS32, exp_no, IS32, error_code);
|
|
|
|
if(GET_PE() && host_exint_hook((IS32) nmbr, (IS32)error_code))
|
|
doing_contributory = FALSE;
|
|
c_cpu_continue(); /* DOES NOT RETURN */
|
|
}
|
|
#endif
|
|
|
|
/* Set default mode up */
|
|
SET_OPERAND_SIZE(GET_SR_AR_X(CS_REG));
|
|
SET_ADDRESS_SIZE(GET_SR_AR_X(CS_REG));
|
|
SET_POP_DISP(0);
|
|
|
|
EXT = INTERNAL;
|
|
check_exception_env();
|
|
#ifdef PIG
|
|
save_last_xcptn_details("Exception:- #%s-%d(%04x) @%2d\n", (IUH)faultstr(nmbr), nmbr, error_code, xcode, 0);
|
|
#endif /* PIG */
|
|
if (show_exceptions){
|
|
fprintf(trace_file, "(%04x:%08x)Exception:- %d(%04x).\n",
|
|
GET_CS_SELECTOR(), GET_EIP(), nmbr, error_code);
|
|
if (trap_exceptions) force_yoda();
|
|
}
|
|
took_absolute_toc = TRUE;
|
|
do_intrupt((IU16)nmbr, FALSE, TRUE, error_code);
|
|
|
|
c_cpu_continue(); /* DOES NOT RETURN */
|
|
}
|
|
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
/* Handle Contributory Exception (Via IDT). */
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
LOCAL VOID
|
|
contributory_idt_exception
|
|
|
|
IFN3(
|
|
IU16, vector, /* failing interrupt vector */
|
|
ISM32, nmbr, /* exception number */
|
|
IU16, xcode /* insignia exception code */
|
|
)
|
|
|
|
|
|
{
|
|
IU16 error_code;
|
|
|
|
/* check if exception caused by external caller */
|
|
check_interface_active(nmbr);
|
|
|
|
check_for_shutdown(xcode);
|
|
check_for_double_fault(xcode);
|
|
|
|
doing_contributory = TRUE;
|
|
error_code = ((vector & IDT_VECTOR_MASK) << IDT_VECTOR_SHIFT)
|
|
| IDT_INDICATOR_BIT
|
|
| EXT;
|
|
|
|
SET_EIP(CCPU_save_EIP);
|
|
|
|
#ifdef NTVDM
|
|
{
|
|
extern BOOL host_exint_hook IPT2(IS32, exp_no, IS32, error_code);
|
|
|
|
if(GET_PE() && host_exint_hook((IS32) nmbr, (IS32)error_code))
|
|
doing_contributory = FALSE;
|
|
c_cpu_continue(); /* DOES NOT RETURN */
|
|
}
|
|
#endif
|
|
|
|
/* Set default mode up */
|
|
SET_OPERAND_SIZE(GET_SR_AR_X(CS_REG));
|
|
SET_ADDRESS_SIZE(GET_SR_AR_X(CS_REG));
|
|
SET_POP_DISP(0);
|
|
|
|
EXT = INTERNAL;
|
|
check_exception_env();
|
|
#ifdef PIG
|
|
save_last_xcptn_details("Exception:- %s-%d(%04x) @%2d\n", (IUH)faultstr(nmbr), nmbr, error_code, xcode, 0);
|
|
#endif /* PIG */
|
|
if (show_exceptions){
|
|
if ( GET_IDT_LIMIT() != 0 ){
|
|
fprintf(trace_file, "(%04x:%08x)Exception:- %d(%04x).\n",
|
|
GET_CS_SELECTOR(), GET_EIP(), nmbr, error_code);
|
|
if (trap_exceptions) force_yoda();
|
|
}
|
|
}
|
|
took_absolute_toc = TRUE;
|
|
do_intrupt((IU16)nmbr, FALSE, TRUE, error_code);
|
|
|
|
c_cpu_continue(); /* DOES NOT RETURN */
|
|
}
|
|
|
|
|
|
/*
|
|
=====================================================================
|
|
EXTERNAL ROUTINES START HERE.
|
|
=====================================================================
|
|
*/
|
|
|
|
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
/* Interrupt Table Too Small/Double Fault Exception. */
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
GLOBAL VOID
|
|
DF
|
|
|
|
IFN1(
|
|
IU16, xcode /* insignia exception code */
|
|
)
|
|
{
|
|
doing_fault = FALSE;
|
|
|
|
if ( GET_PE() == 1 )
|
|
{
|
|
check_for_shutdown(xcode);
|
|
doing_double_fault = TRUE;
|
|
}
|
|
|
|
SET_EIP(CCPU_save_EIP);
|
|
|
|
#ifdef NTVDM
|
|
{
|
|
extern BOOL host_exint_hook IPT2(IS32, exp_no, IS32, error_code);
|
|
|
|
if(GET_PE() && host_exint_hook((IS32) DF_INT_NR, (IS32)NULL_ERROR_CODE))
|
|
doing_double_fault = FALSE;
|
|
c_cpu_continue(); /* DOES NOT RETURN */
|
|
}
|
|
#endif
|
|
|
|
/* Set default mode up */
|
|
SET_OPERAND_SIZE(GET_SR_AR_X(CS_REG));
|
|
SET_ADDRESS_SIZE(GET_SR_AR_X(CS_REG));
|
|
SET_POP_DISP(0);
|
|
|
|
EXT = INTERNAL;
|
|
check_exception_env();
|
|
#ifdef PIG
|
|
save_last_xcptn_details("Exception:- #DF-8 @%2d\n", xcode, 0, 0, 0, 0);
|
|
#endif /* PIG */
|
|
if (show_exceptions){
|
|
if ( GET_IDT_LIMIT() != 0 ){
|
|
fprintf(trace_file, "(%04x:%08x)Exception:- %d.\n",
|
|
GET_CS_SELECTOR(), GET_EIP(), DF_INT_NR);
|
|
if (trap_exceptions) force_yoda();
|
|
}
|
|
}
|
|
took_absolute_toc = TRUE;
|
|
do_intrupt((IU16)DF_INT_NR, FALSE, TRUE, NULL_ERROR_CODE);
|
|
|
|
c_cpu_continue(); /* DOES NOT RETURN */
|
|
}
|
|
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
/* General Protection Exception. */
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
GLOBAL VOID GP IFN2( IU16, selector, IU16, xcode)
|
|
{
|
|
doing_fault = TRUE;
|
|
contributory_exception(selector, GP_INT_NR, xcode);
|
|
}
|
|
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
/* General Protection Exception. (Via IDT) */
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
GLOBAL VOID GP_INT IFN2( IU16, vector, IU16, xcode)
|
|
{
|
|
doing_fault = TRUE;
|
|
contributory_idt_exception(vector, GP_INT_NR, xcode);
|
|
}
|
|
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
/* Divide Error Exception. */
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
GLOBAL VOID Int0 IFN0 ()
|
|
{
|
|
doing_fault = TRUE;
|
|
if ( GET_PE() == 1 )
|
|
{
|
|
doing_contributory = TRUE;
|
|
}
|
|
|
|
SET_EIP(CCPU_save_EIP);
|
|
|
|
#ifdef NTVDM
|
|
{
|
|
extern BOOL host_exint_hook IPT2(IS32, exp_no, IS32, error_code);
|
|
|
|
if(GET_PE() && host_exint_hook((IS32) I0_INT_NR, (IS32)NULL_ERROR_CODE))
|
|
doing_fault = FALSE;
|
|
doing_contributory = FALSE;
|
|
c_cpu_continue(); /* DOES NOT RETURN */
|
|
}
|
|
#endif
|
|
|
|
/* Set default mode up */
|
|
SET_OPERAND_SIZE(GET_SR_AR_X(CS_REG));
|
|
SET_ADDRESS_SIZE(GET_SR_AR_X(CS_REG));
|
|
SET_POP_DISP(0);
|
|
|
|
EXT = INTERNAL;
|
|
|
|
check_exception_env();
|
|
#ifdef PIG
|
|
save_last_xcptn_details("Exception:- #DIV-0\n", 0, 0, 0, 0, 0);
|
|
#endif /* PIG */
|
|
if (show_exceptions){
|
|
fprintf(trace_file, "(%04x:%08x)Exception:- %d.\n",
|
|
GET_CS_SELECTOR(), GET_EIP(), I0_INT_NR);
|
|
if (trap_exceptions) force_yoda();
|
|
}
|
|
took_absolute_toc = TRUE;
|
|
do_intrupt((IU16)I0_INT_NR, FALSE, FALSE, NULL_ERROR_CODE);
|
|
|
|
c_cpu_continue(); /* DOES NOT RETURN */
|
|
}
|
|
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
/* Single Step Exception. (FAULT) */
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
GLOBAL VOID
|
|
Int1_f()
|
|
{
|
|
doing_fault = TRUE;
|
|
benign_exception(I1_INT_NR, EXTERNAL, -1);
|
|
}
|
|
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
/* Single Step Exception. (TRAP) */
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
GLOBAL VOID
|
|
Int1_t()
|
|
{
|
|
doing_fault = FALSE;
|
|
benign_exception(I1_INT_NR, EXTERNAL, -1);
|
|
}
|
|
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
/* Bounds Check Exception. */
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
GLOBAL VOID
|
|
Int5()
|
|
{
|
|
doing_fault = TRUE;
|
|
benign_exception(I5_INT_NR, INTERNAL, -1);
|
|
}
|
|
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
/* Invalid Opcode Exception. */
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
GLOBAL VOID
|
|
Int6()
|
|
{
|
|
doing_fault = TRUE;
|
|
benign_exception(I6_INT_NR, INTERNAL, -1);
|
|
}
|
|
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
/* NPX Not Available Exception. */
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
GLOBAL VOID
|
|
Int7()
|
|
{
|
|
doing_fault = TRUE;
|
|
benign_exception(I7_INT_NR, INTERNAL, -1);
|
|
}
|
|
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
/* NPX Error Exception. */
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
GLOBAL VOID
|
|
Int16()
|
|
{
|
|
doing_fault = TRUE;
|
|
benign_exception(I16_INT_NR, EXTERNAL, -1);
|
|
}
|
|
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
/* Not Present Exception. */
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
GLOBAL VOID NP IFN2( IU16, selector, IU16, xcode)
|
|
{
|
|
doing_fault = TRUE;
|
|
contributory_exception(selector, NP_INT_NR, xcode);
|
|
}
|
|
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
/* Not Present Exception. (Via IDT) */
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
GLOBAL VOID
|
|
NP_INT
|
|
|
|
IFN2(
|
|
IU16, vector,
|
|
IU16, xcode
|
|
)
|
|
|
|
{
|
|
doing_fault = TRUE;
|
|
contributory_idt_exception(vector, NP_INT_NR, xcode);
|
|
}
|
|
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
/* Page Fault Exception. */
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
GLOBAL VOID
|
|
PF
|
|
|
|
IFN2(
|
|
IU16, page_error, /* correctly formatted page fault error code */
|
|
IU16, xcode
|
|
)
|
|
|
|
|
|
{
|
|
/* check if exception caused by external caller */
|
|
check_interface_active(PF_INT_NR);
|
|
|
|
doing_fault = TRUE;
|
|
|
|
check_for_shutdown(xcode);
|
|
|
|
/* Check for double page fault */
|
|
if ( doing_page_fault )
|
|
DF(xcode);
|
|
|
|
doing_page_fault = TRUE;
|
|
|
|
SET_EIP(CCPU_save_EIP);
|
|
|
|
#ifdef NTVDM
|
|
{
|
|
extern BOOL host_exint_hook IPT2(IS32, exp_no, IS32, error_code);
|
|
|
|
if(GET_PE() && host_exint_hook((IS32) PF_INT_NR, (IS32)page_error))
|
|
doing_fault = FALSE;
|
|
doing_page_fault = FALSE;
|
|
c_cpu_continue(); /* DOES NOT RETURN */
|
|
}
|
|
#endif
|
|
|
|
/* Set default mode up */
|
|
SET_OPERAND_SIZE(GET_SR_AR_X(CS_REG));
|
|
SET_ADDRESS_SIZE(GET_SR_AR_X(CS_REG));
|
|
SET_POP_DISP(0);
|
|
|
|
check_exception_env();
|
|
#ifdef PIG
|
|
save_last_xcptn_details("Exception:- #PF-14(%04x) CR2=%08x @%2d\n", page_error, GET_CR(CR_PFLA), xcode, 0, 0);
|
|
#endif /* PIG */
|
|
if (show_exceptions){
|
|
fprintf(trace_file, "(%04x:%08x)Exception:- %d(%04x) CR2=%08x.\n",
|
|
GET_CS_SELECTOR(), GET_EIP(), PF_INT_NR, page_error, GET_CR(CR_PFLA));
|
|
if (trap_exceptions) force_yoda();
|
|
}
|
|
took_absolute_toc = TRUE;
|
|
do_intrupt((IU16)PF_INT_NR, FALSE, TRUE, page_error);
|
|
|
|
c_cpu_continue(); /* DOES NOT RETURN */
|
|
}
|
|
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
/* Stack Fault Exception. */
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
GLOBAL VOID
|
|
SF
|
|
|
|
IFN2(
|
|
IU16, selector,
|
|
IU16, xcode
|
|
)
|
|
|
|
{
|
|
doing_fault = TRUE;
|
|
contributory_exception(selector, SF_INT_NR, xcode);
|
|
}
|
|
|
|
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
/* Task Switch Exception. */
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
GLOBAL VOID
|
|
TS
|
|
|
|
IFN2(
|
|
IU16, selector,
|
|
IU16, xcode
|
|
)
|
|
|
|
{
|
|
doing_fault = TRUE;
|
|
contributory_exception(selector, TS_INT_NR, xcode);
|
|
}
|