398 lines
17 KiB
Plaintext
398 lines
17 KiB
Plaintext
$OpenBSD: patch-cpu_exception_cc,v 1.2 2001/03/01 22:44:18 todd Exp $
|
|
--- cpu/exception.cc.orig Sat Mar 25 21:39:08 2000
|
|
+++ cpu/exception.cc Tue Feb 27 10:29:42 2001
|
|
@@ -52,7 +52,7 @@ BX_CPU_C::interrupt(Bit8u vector, Boolea
|
|
BX_CPU_THIS_PTR show_flag |= Flag_intsig;
|
|
#endif
|
|
|
|
-//fprintf(stderr, "::interrupt(%u)\n", vector);
|
|
+//bio->printf("[CPU%d] interrupt(%u)\n", BX_SIM_ID, vector);
|
|
|
|
BX_INSTR_INTERRUPT(vector);
|
|
invalidate_prefetch_q();
|
|
@@ -65,8 +65,9 @@ BX_CPU_C::interrupt(Bit8u vector, Boolea
|
|
#if BX_CPU_LEVEL >= 2
|
|
// unsigned prev_errno;
|
|
|
|
- if (bx_dbg.interrupts)
|
|
- bx_printf("interrupt(): vector = %u, INT = %u, EXT = %u\n",
|
|
+ if (bio->getdbg().interrupts)
|
|
+ bio->printf("[CPU%u] interrupt(): vector = %u, INT = %u, EXT = %u\n",
|
|
+ BX_SIM_ID,
|
|
(unsigned) vector, (unsigned) is_INT, (unsigned) BX_CPU_THIS_PTR EXT);
|
|
|
|
BX_CPU_THIS_PTR save_cs = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS];
|
|
@@ -92,13 +93,13 @@ BX_CPU_THIS_PTR save_esp = ESP;
|
|
// interrupt vector must be within IDT table limits,
|
|
// else #GP(vector number*8 + 2 + EXT)
|
|
if ( (vector*8 + 7) > BX_CPU_THIS_PTR idtr.limit) {
|
|
- if (bx_dbg.interrupts) {
|
|
- bx_printf("IDT.limit = %04x\n", (unsigned) BX_CPU_THIS_PTR idtr.limit);
|
|
- bx_printf("IDT.base = %06x\n", (unsigned) BX_CPU_THIS_PTR idtr.base);
|
|
- bx_printf("interrupt vector must be within IDT table limits\n");
|
|
- bx_printf("bailing\n");
|
|
+ if (bio->getdbg().interrupts) {
|
|
+ bio->printf("[CPU%u] IDT.limit = %04x\n", BX_SIM_ID, (unsigned) BX_CPU_THIS_PTR idtr.limit);
|
|
+ bio->printf("[CPU%u] IDT.base = %06x\n", BX_SIM_ID, (unsigned) BX_CPU_THIS_PTR idtr.base);
|
|
+ bio->printf("[CPU%u] interrupt vector must be within IDT table limits\n",BX_SIM_ID);
|
|
+ bio->printf("[CPU%u] bailing\n",BX_SIM_ID);
|
|
}
|
|
- bx_printf("interrupt(): vector > idtr.limit\n");
|
|
+ bio->printf("[CPU%u] interrupt(): vector > idtr.limit\n",BX_SIM_ID);
|
|
|
|
exception(BX_GP_EXCEPTION, vector*8 + 2, 0);
|
|
}
|
|
@@ -113,7 +114,7 @@ BX_CPU_THIS_PTR save_esp = ESP;
|
|
parse_descriptor(dword1, dword2, &gate_descriptor);
|
|
|
|
if ( (gate_descriptor.valid==0) || gate_descriptor.segment) {
|
|
- bx_panic("interrupt(): gate descriptor is not valid sys seg\n");
|
|
+ bio->panic("[CPU%u] interrupt(): gate descriptor is not valid sys seg\n",BX_SIM_ID);
|
|
exception(BX_GP_EXCEPTION, vector*8 + 2, 0);
|
|
}
|
|
|
|
@@ -125,8 +126,8 @@ BX_CPU_THIS_PTR save_esp = ESP;
|
|
case 15: // 386 trap gate
|
|
break;
|
|
default:
|
|
- bx_printf("interrupt(): gate.type(%u) != {5,6,7,14,15}\n",
|
|
- (unsigned) gate_descriptor.type);
|
|
+ bio->printf("[CPU%u] interrupt(): gate.type(%u) != {5,6,7,14,15}\n",
|
|
+ BX_SIM_ID, (unsigned) gate_descriptor.type);
|
|
exception(BX_GP_EXCEPTION, vector*8 + 2, 0);
|
|
return;
|
|
}
|
|
@@ -135,14 +136,14 @@ BX_CPU_THIS_PTR save_esp = ESP;
|
|
// else #GP(vector * 8 + 2 + EXT)
|
|
if (is_INT && (gate_descriptor.dpl < CPL)) {
|
|
/* ??? */
|
|
- bx_printf("interrupt(): is_INT && (dpl < CPL)\n");
|
|
+ // bio->printf("[CPU%u] interrupt(): is_INT && (dpl < CPL)\n", BX_SIM_ID);
|
|
exception(BX_GP_EXCEPTION, vector*8 + 2, 0);
|
|
return;
|
|
}
|
|
|
|
// Gate must be present, else #NP(vector * 8 + 2 + EXT)
|
|
if (gate_descriptor.p == 0) {
|
|
- bx_printf("interrupt(): p == 0\n");
|
|
+ bio->printf("[CPU%u] interrupt(): p == 0\n", BX_SIM_ID);
|
|
exception(BX_NP_EXCEPTION, vector*8 + 2, 0);
|
|
}
|
|
|
|
@@ -158,7 +159,7 @@ BX_CPU_THIS_PTR save_esp = ESP;
|
|
// 486/Pent books say #TSS(selector)
|
|
// PPro+ says #GP(selector)
|
|
if (tss_selector.ti) {
|
|
- bx_panic("interrupt: tss_selector.ti=1\n");
|
|
+ bio->printf("[CPU%u] interrupt: tss_selector.ti=1\n",BX_SIM_ID);
|
|
exception(BX_TS_EXCEPTION, raw_tss_selector & 0xfffc, 0);
|
|
return;
|
|
}
|
|
@@ -171,12 +172,12 @@ BX_CPU_THIS_PTR save_esp = ESP;
|
|
// else #TS(TSS selector)
|
|
parse_descriptor(dword1, dword2, &tss_descriptor);
|
|
if (tss_descriptor.valid==0 || tss_descriptor.segment) {
|
|
- bx_panic("exception: TSS selector points to bad TSS\n");
|
|
+ bio->printf("[CPU%u] exception: TSS selector points to bad TSS\n",BX_SIM_ID);
|
|
exception(BX_TS_EXCEPTION, raw_tss_selector & 0xfffc, 0);
|
|
return;
|
|
}
|
|
if (tss_descriptor.type!=9 && tss_descriptor.type!=1) {
|
|
- bx_panic("exception: TSS selector points to bad TSS\n");
|
|
+ bio->panic("[CPU%u] exception: TSS selector points to bad TSS\n",BX_SIM_ID);
|
|
exception(BX_TS_EXCEPTION, raw_tss_selector & 0xfffc, 0);
|
|
return;
|
|
}
|
|
@@ -205,7 +206,7 @@ BX_CPU_THIS_PTR save_esp = ESP;
|
|
// instruction pointer must be in CS limit, else #GP(0)
|
|
//if (EIP > cs_descriptor.u.segment.limit_scaled) {}
|
|
if (EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) {
|
|
- bx_panic("exception(): eIP > CS.limit\n");
|
|
+ bio->panic("[CPU%u] exception(): eIP > CS.limit\n", BX_SIM_ID);
|
|
exception(BX_GP_EXCEPTION, 0x0000, 0);
|
|
}
|
|
return;
|
|
@@ -227,7 +228,7 @@ BX_CPU_THIS_PTR save_esp = ESP;
|
|
// examine CS selector and descriptor given in gate descriptor
|
|
// selector must be non-null else #GP(EXT)
|
|
if ( (gate_dest_selector & 0xfffc) == 0 ) {
|
|
- bx_panic("int_trap_gate(): selector null\n");
|
|
+ bio->panic("[CPU%u] int_trap_gate(): selector null\n", BX_SIM_ID);
|
|
exception(BX_GP_EXCEPTION, 0, 0);
|
|
}
|
|
|
|
@@ -245,13 +246,13 @@ BX_CPU_THIS_PTR save_esp = ESP;
|
|
cs_descriptor.segment==0 ||
|
|
cs_descriptor.u.segment.executable==0 ||
|
|
cs_descriptor.dpl>CPL ) {
|
|
- bx_printf("interrupt(): not code segment\n");
|
|
+ bio->printf("[CPU%u] interrupt(): not code segment\n",BX_SIM_ID);
|
|
exception(BX_GP_EXCEPTION, cs_selector.value & 0xfffc, 0);
|
|
}
|
|
|
|
// segment must be present, else #NP(selector + EXT)
|
|
if ( cs_descriptor.p==0 ) {
|
|
- bx_panic("interrupt(): segment not present\n");
|
|
+ bio->panic("[CPU%u] interrupt(): segment not present\n",BX_SIM_ID);
|
|
exception(BX_NP_EXCEPTION, cs_selector.value & 0xfffc, 0);
|
|
}
|
|
|
|
@@ -264,8 +265,8 @@ BX_CPU_THIS_PTR save_esp = ESP;
|
|
bx_selector_t ss_selector;
|
|
int bytes;
|
|
|
|
- if (bx_dbg.interrupts)
|
|
- bx_printf("interrupt(): INTERRUPT TO INNER PRIVILEGE\n");
|
|
+ if (bio->getdbg().interrupts)
|
|
+ bio->printf("[CPU%u] interrupt(): INTERRUPT TO INNER PRIVILEGE\n",BX_SIM_ID);
|
|
|
|
// check selector and descriptor for new stack in current TSS
|
|
get_SS_ESP_from_TSS(cs_descriptor.dpl,
|
|
@@ -273,7 +274,7 @@ BX_CPU_THIS_PTR save_esp = ESP;
|
|
|
|
// Selector must be non-null else #TS(EXT)
|
|
if ( (SS_for_cpl_x & 0xfffc) == 0 ) {
|
|
- bx_panic("interrupt(): SS selector null\n");
|
|
+ bio->panic("[CPU%u] interrupt(): SS selector null\n",BX_SIM_ID);
|
|
/* TS(ext) */
|
|
exception(BX_TS_EXCEPTION, 0, 0);
|
|
}
|
|
@@ -289,14 +290,14 @@ BX_CPU_THIS_PTR save_esp = ESP;
|
|
// selector rpl must = dpl of code segment,
|
|
// else #TS(SS selector + ext)
|
|
if (ss_selector.rpl != cs_descriptor.dpl) {
|
|
- bx_panic("interrupt(): SS.rpl != CS.dpl\n");
|
|
+ bio->panic("[CPU%u] interrupt(): SS.rpl != CS.dpl\n",BX_SIM_ID);
|
|
exception(BX_TS_EXCEPTION, SS_for_cpl_x & 0xfffc, 0);
|
|
}
|
|
|
|
// stack seg DPL must = DPL of code segment,
|
|
// else #TS(SS selector + ext)
|
|
if (ss_descriptor.dpl != cs_descriptor.dpl) {
|
|
- bx_panic("interrupt(): SS.dpl != CS.dpl\n");
|
|
+ bio->panic("[CPU%u] interrupt(): SS.dpl != CS.dpl\n",BX_SIM_ID);
|
|
exception(BX_TS_EXCEPTION, SS_for_cpl_x & 0xfffc, 0);
|
|
}
|
|
|
|
@@ -306,13 +307,13 @@ BX_CPU_THIS_PTR save_esp = ESP;
|
|
ss_descriptor.segment==0 ||
|
|
ss_descriptor.u.segment.executable==1 ||
|
|
ss_descriptor.u.segment.r_w==0) {
|
|
- bx_panic("interrupt(): SS not writable data segment\n");
|
|
+ bio->panic("[CPU%u] interrupt(): SS not writable data segment\n", BX_SIM_ID);
|
|
exception(BX_TS_EXCEPTION, SS_for_cpl_x & 0xfffc, 0);
|
|
}
|
|
|
|
// seg must be present, else #SS(SS selector + ext)
|
|
if (ss_descriptor.p==0) {
|
|
- bx_panic("interrupt(): SS not present\n");
|
|
+ bio->panic("[CPU%u] interrupt(): SS not present\n", BX_SIM_ID);
|
|
exception(BX_SS_EXCEPTION, SS_for_cpl_x & 0xfffc, 0);
|
|
}
|
|
|
|
@@ -334,7 +335,7 @@ BX_CPU_THIS_PTR save_esp = ESP;
|
|
bytes = 10;
|
|
if (v8086_mode()) {
|
|
bytes += 8;
|
|
- bx_panic("interrupt: int/trap gate VM\n");
|
|
+ bio->panic("[CPU%u] interrupt: int/trap gate VM\n",BX_SIM_ID);
|
|
}
|
|
}
|
|
|
|
@@ -343,14 +344,14 @@ BX_CPU_THIS_PTR save_esp = ESP;
|
|
// PPro+
|
|
// new stack must have room for 10/12 bytes, else #SS(seg selector)
|
|
if ( !can_push(&ss_descriptor, ESP_for_cpl_x, bytes) ) {
|
|
- bx_panic("interrupt(): new stack doesn't have room for %u bytes\n",
|
|
- (unsigned) bytes);
|
|
+ bio->panic("[CPU%u] interrupt(): new stack doesn't have room for %u bytes\n",
|
|
+ BX_SIM_ID, (unsigned) bytes);
|
|
// SS(???)
|
|
}
|
|
|
|
// IP must be within CS segment boundaries, else #GP(0)
|
|
if (gate_dest_offset > cs_descriptor.u.segment.limit_scaled) {
|
|
- bx_panic("interrupt(): gate eIP > CS.limit\n");
|
|
+ bio->panic("[CPU%u] interrupt(): gate eIP > CS.limit\n", BX_SIM_ID);
|
|
exception(BX_GP_EXCEPTION, 0, 0);
|
|
}
|
|
|
|
@@ -404,7 +405,7 @@ BX_CPU_THIS_PTR save_esp = ESP;
|
|
}
|
|
else { // 286 int/trap gate
|
|
if (v8086_mode()) {
|
|
- bx_panic("286 int/trap gate, VM\n");
|
|
+ bio->panic("[CPU%u] 286 int/trap gate, VM\n", BX_SIM_ID);
|
|
}
|
|
// push long pointer to old stack onto new stack
|
|
push_16(old_SS);
|
|
@@ -446,8 +447,8 @@ BX_CPU_THIS_PTR save_esp = ESP;
|
|
else
|
|
temp_ESP = SP;
|
|
|
|
- if (bx_dbg.interrupts)
|
|
- bx_printf("int_trap_gate286(): INTERRUPT TO SAME PRIVILEGE\n");
|
|
+ if (bio->getdbg().interrupts)
|
|
+ bio->printf("[CPU%u] int_trap_gate286(): INTERRUPT TO SAME PRIVILEGE\n",BX_SIM_ID);
|
|
|
|
// Current stack limits must allow pushing 6|8 bytes, else #SS(0)
|
|
if (gate_descriptor.type >= 14) { // 386 gate
|
|
@@ -465,13 +466,13 @@ BX_CPU_THIS_PTR save_esp = ESP;
|
|
|
|
if ( !can_push(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache,
|
|
temp_ESP, bytes) ) {
|
|
- bx_printf("interrupt(): stack doesn't have room\n");
|
|
+ bio->printf("[CPU%u] interrupt(): stack doesn't have room\n",BX_SIM_ID);
|
|
exception(BX_SS_EXCEPTION, 0, 0);
|
|
}
|
|
|
|
// eIP must be in CS limit else #GP(0)
|
|
if (gate_dest_offset > cs_descriptor.u.segment.limit_scaled) {
|
|
- bx_panic("interrupt(): IP > cs descriptor limit\n");
|
|
+ bio->panic("[CPU%u] interrupt(): IP > cs descriptor limit\n", BX_SIM_ID);
|
|
exception(BX_GP_EXCEPTION, 0, 0);
|
|
}
|
|
|
|
@@ -510,17 +511,17 @@ BX_CPU_THIS_PTR save_esp = ESP;
|
|
}
|
|
|
|
// else #GP(CS selector + ext)
|
|
- bx_printf("interrupt: bad descriptor\n");
|
|
- bx_printf("c_ed=%u, descriptor.dpl=%u, CPL=%u\n",
|
|
+ bio->printf("[CPU%u] interrupt: bad descriptor\n", BX_SIM_ID);
|
|
+ bio->printf("[CPU%u] c_ed=%u, descriptor.dpl=%u, CPL=%u\n", BX_SIM_ID,
|
|
(unsigned) cs_descriptor.u.segment.c_ed,
|
|
(unsigned) cs_descriptor.dpl,
|
|
(unsigned) CPL);
|
|
- bx_printf("cs.segment = %u\n", (unsigned) cs_descriptor.segment);
|
|
+ bio->printf("[CPU%u] cs.segment = %u\n", BX_SIM_ID, (unsigned) cs_descriptor.segment);
|
|
exception(BX_GP_EXCEPTION, cs_selector.value & 0xfffc, 0);
|
|
break;
|
|
|
|
default:
|
|
- bx_panic("bad descriptor type in interrupt()!\n");
|
|
+ bio->panic("[CPU%u] bad descriptor type in interrupt()!\n");
|
|
break;
|
|
}
|
|
}
|
|
@@ -530,7 +531,7 @@ BX_CPU_THIS_PTR save_esp = ESP;
|
|
Bit16u cs_selector, ip;
|
|
|
|
if ( (vector*4+3) > BX_CPU_THIS_PTR idtr.limit )
|
|
- bx_panic("interrupt(real mode) vector > limit\n");
|
|
+ bio->panic("[CPU%u] interrupt(real mode) vector > limit\n");
|
|
|
|
push_16(read_flags());
|
|
|
|
@@ -566,15 +567,15 @@ BX_CPU_C::exception(unsigned vector, Bit
|
|
Bit8u exception_type;
|
|
unsigned prev_errno;
|
|
|
|
-//fprintf(stderr, "::exception(%u)\n", vector);
|
|
+//bio->printf("::exception(%u)\n", vector);
|
|
|
|
BX_INSTR_EXCEPTION(vector);
|
|
invalidate_prefetch_q();
|
|
|
|
UNUSED(is_INT);
|
|
|
|
- if (bx_dbg.exceptions)
|
|
- bx_printf("exception(%02x h)\n", (unsigned) vector);
|
|
+ if (bio->getdbg().exceptions)
|
|
+ bio->printf("[CPU%u] exception(%02x h)\n", (unsigned) vector);
|
|
|
|
// if not initial error, restore previous register values from
|
|
// previous attempt to handle exception
|
|
@@ -587,7 +588,7 @@ BX_CPU_C::exception(unsigned vector, Bit
|
|
|
|
BX_CPU_THIS_PTR errorno++;
|
|
if (BX_CPU_THIS_PTR errorno >= 3) {
|
|
- bx_panic("exception(): 3rd exception with no resolution\n");
|
|
+ bio->panic("[CPU%u] exception(): 3rd exception with no resolution\n");
|
|
}
|
|
|
|
/* careful not to get here with curr_exception[1]==DOUBLE_FAULT */
|
|
@@ -595,7 +596,7 @@ BX_CPU_C::exception(unsigned vector, Bit
|
|
|
|
/* if 1st was a double fault (software INT?), then shutdown */
|
|
if ( (BX_CPU_THIS_PTR errorno==2) && (BX_CPU_THIS_PTR curr_exception[0]==BX_ET_DOUBLE_FAULT) ) {
|
|
- bx_panic("exception(): tripple fault encountered\n");
|
|
+ bio->panic("[CPU%u] exception(): tripple fault encountered\n");
|
|
}
|
|
|
|
/* ??? this is not totally correct, should be done depending on
|
|
@@ -652,7 +653,7 @@ BX_CPU_C::exception(unsigned vector, Bit
|
|
push_error = 0;
|
|
exception_type = BX_ET_CONTRIBUTORY;
|
|
BX_CPU_THIS_PTR eflags.rf = 1;
|
|
- bx_panic("exception(9): unfinished\n");
|
|
+ bio->panic("[CPU%u] exception(9): unfinished\n", BX_SIM_ID);
|
|
break;
|
|
case 10: // invalid TSS
|
|
push_error = 1;
|
|
@@ -685,7 +686,7 @@ BX_CPU_C::exception(unsigned vector, Bit
|
|
BX_CPU_THIS_PTR eflags.rf = 1;
|
|
break;
|
|
case 15: // reserved
|
|
- bx_panic("exception(15): reserved\n");
|
|
+ bio->panic("[CPU%u] exception(15): reserved\n",BX_SIM_ID);
|
|
push_error = 0; // keep compiler happy for now
|
|
exception_type = 0; // keep compiler happy for now
|
|
break;
|
|
@@ -696,7 +697,7 @@ BX_CPU_C::exception(unsigned vector, Bit
|
|
break;
|
|
#if BX_CPU_LEVEL >= 4
|
|
case 17: // alignment check
|
|
- bx_panic("exception(): alignment-check, vector 17 unimplemented\n");
|
|
+ bio->panic("[CPU%u] exception(): alignment-check, vector 17 unimplemented\n", BX_SIM_ID);
|
|
push_error = 0; // keep compiler happy for now
|
|
exception_type = 0; // keep compiler happy for now
|
|
BX_CPU_THIS_PTR eflags.rf = 1;
|
|
@@ -704,13 +705,13 @@ BX_CPU_C::exception(unsigned vector, Bit
|
|
#endif
|
|
#if BX_CPU_LEVEL >= 5
|
|
case 18: // machine check
|
|
- bx_panic("exception(): machine-check, vector 18 unimplemented\n");
|
|
+ bio->panic("[CPU%u] exception(): machine-check, vector 18 unimplemented\n", BX_SIM_ID);
|
|
push_error = 0; // keep compiler happy for now
|
|
exception_type = 0; // keep compiler happy for now
|
|
break;
|
|
#endif
|
|
default:
|
|
- bx_panic("exception(%u): bad vector\n", (unsigned) vector);
|
|
+ bio->panic("[CPU%u] exception(%u): bad vector\n", BX_SIM_ID, (unsigned) vector);
|
|
push_error = 0; // keep compiler happy for now
|
|
exception_type = 0; // keep compiler happy for now
|
|
break;
|
|
@@ -741,7 +742,7 @@ BX_CPU_C::exception(unsigned vector, Bit
|
|
prev_errno = BX_CPU_THIS_PTR errorno;
|
|
BX_CPU_THIS_PTR interrupt(vector, 0, push_error, error_code);
|
|
// if (BX_CPU_THIS_PTR errorno > prev_errno) {
|
|
-// bx_printf("segment_exception(): errorno changed\n");
|
|
+// bio->printf("[CPU%u] segment_exception(): errorno changed\n", BX_SIM_ID);
|
|
// longjmp(jmp_buf_env, 1); // go back to main decode loop
|
|
// return;
|
|
// }
|
|
@@ -754,7 +755,7 @@ BX_CPU_C::exception(unsigned vector, Bit
|
|
// else
|
|
// push_16(error_code);
|
|
// if (BX_CPU_THIS_PTR errorno > prev_errno) {
|
|
-// bx_panic("segment_exception(): errorno changed\n");
|
|
+// bio->panic("[CPU%u] segment_exception(): errorno changed\n", BX_SIM_ID);
|
|
// return;
|
|
// }
|
|
// }
|
|
@@ -786,10 +787,10 @@ BX_CPU_C::shutdown_cpu(void)
|
|
{
|
|
|
|
#if BX_CPU_LEVEL > 2
|
|
- bx_panic("shutdown_cpu(): not implemented for 386\n");
|
|
+ bio->panic("[CPU%u] shutdown_cpu(): not implemented for 386\n", BX_SIM_ID);
|
|
#endif
|
|
|
|
invalidate_prefetch_q();
|
|
- bx_panic("shutdown_cpu(): not finished\n");
|
|
+ bio->panic("[CPU%u] shutdown_cpu(): not finished\n", BX_SIM_ID);
|
|
|
|
}
|