Removed can_push method - normal memory accesses will be used instead.
Fixed reset value of TR.TYPE
This commit is contained in:
parent
528d34f108
commit
9fcbf28cea
@ -1,5 +1,5 @@
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// $Id: call_far.cc,v 1.27 2008-02-15 19:03:53 sshwarts Exp $
|
||||
// $Id: call_far.cc,v 1.28 2008-03-24 22:13:03 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2005 Stanislav Shwartsman
|
||||
@ -244,7 +244,6 @@ BX_CPU_C::call_protected(bxInstruction_c *i, Bit16u cs_raw, bx_address disp)
|
||||
Bit32u ESP_for_cpl_x;
|
||||
bx_selector_t ss_selector;
|
||||
bx_descriptor_t ss_descriptor;
|
||||
unsigned room_needed;
|
||||
Bit16u return_SS, return_CS;
|
||||
Bit32u return_ESP, return_EIP;
|
||||
Bit16u parameter_word[32];
|
||||
@ -299,28 +298,9 @@ BX_CPU_C::call_protected(bxInstruction_c *i, Bit16u cs_raw, bx_address disp)
|
||||
exception(BX_SS_EXCEPTION, SS_for_cpl_x & 0xfffc, 0);
|
||||
}
|
||||
|
||||
if (cs_descriptor.u.segment.d_b)
|
||||
// new stack must have room for parameters plus 16 bytes
|
||||
room_needed = 16;
|
||||
else
|
||||
// new stack must have room for parameters plus 8 bytes
|
||||
room_needed = 8;
|
||||
|
||||
// get word count from call gate, mask to 5 bits
|
||||
unsigned param_count = gate_descriptor.u.gate.param_count & 0x1f;
|
||||
|
||||
if (gate_descriptor.type==BX_286_CALL_GATE)
|
||||
room_needed += param_count*2;
|
||||
else
|
||||
room_needed += param_count*4;
|
||||
|
||||
// new stack must have room for parameters plus return info
|
||||
// else #SS(SS selector)
|
||||
if (!can_push(&ss_descriptor, ESP_for_cpl_x, room_needed)) {
|
||||
BX_ERROR(("call_protected: stack doesn't have room"));
|
||||
exception(BX_SS_EXCEPTION, SS_for_cpl_x & 0xfffc, 0);
|
||||
}
|
||||
|
||||
// new eIP must be in code segment limit else #GP(0)
|
||||
if (new_EIP > cs_descriptor.u.segment.limit_scaled) {
|
||||
BX_ERROR(("call_protected: EIP not within CS limits"));
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: cpu.h,v 1.435 2008-03-22 21:29:39 sshwarts Exp $
|
||||
// $Id: cpu.h,v 1.436 2008-03-24 22:13:03 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -3043,7 +3043,6 @@ public: // for now...
|
||||
BX_SMF void push_64(Bit64u value64) BX_CPP_AttrRegparmN(1);
|
||||
BX_SMF Bit64u pop_64(void);
|
||||
#endif
|
||||
BX_SMF bx_bool can_push(bx_descriptor_t *descriptor, Bit32u esp, Bit32u bytes) BX_CPP_AttrRegparmN(3);
|
||||
BX_SMF bx_bool can_pop(Bit32u bytes) BX_CPP_AttrRegparmN(1);
|
||||
BX_SMF void sanity_checks(void);
|
||||
BX_SMF void assert_checks(void);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: exception.cc,v 1.102 2008-03-23 21:24:05 sshwarts Exp $
|
||||
// $Id: exception.cc,v 1.103 2008-03-24 22:13:04 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -287,7 +287,7 @@ void BX_CPU_C::long_mode_int(Bit8u vector, bx_bool is_INT, bx_bool is_error_code
|
||||
void BX_CPU_C::protected_mode_int(Bit8u vector, bx_bool is_INT, bx_bool is_error_code, Bit16u error_code)
|
||||
{
|
||||
// protected mode interrupt
|
||||
Bit32u dword1, dword2;
|
||||
Bit32u dword1, dword2;
|
||||
bx_descriptor_t gate_descriptor, cs_descriptor;
|
||||
bx_selector_t cs_selector;
|
||||
|
||||
@ -452,7 +452,6 @@ void BX_CPU_C::protected_mode_int(Bit8u vector, bx_bool is_INT, bx_bool is_error
|
||||
Bit32u ESP_for_cpl_x, old_EIP, old_ESP;
|
||||
bx_descriptor_t ss_descriptor;
|
||||
bx_selector_t ss_selector;
|
||||
int bytes;
|
||||
int is_v8086_mode = v8086_mode();
|
||||
|
||||
BX_DEBUG(("interrupt(): INTERRUPT TO INNER PRIVILEGE"));
|
||||
@ -510,35 +509,6 @@ void BX_CPU_C::protected_mode_int(Bit8u vector, bx_bool is_INT, bx_bool is_error
|
||||
exception(BX_SS_EXCEPTION, SS_for_cpl_x & 0xfffc, 0);
|
||||
}
|
||||
|
||||
if (gate_descriptor.type>=14) {
|
||||
// 386 int/trap gate
|
||||
// new stack must have room for 20|24 bytes, else #SS(0)
|
||||
if (is_error_code)
|
||||
bytes = 24;
|
||||
else
|
||||
bytes = 20;
|
||||
if (is_v8086_mode)
|
||||
bytes += 16;
|
||||
}
|
||||
else {
|
||||
// new stack must have room for 10|12 bytes, else #SS(0)
|
||||
if (is_error_code)
|
||||
bytes = 12;
|
||||
else
|
||||
bytes = 10;
|
||||
if (is_v8086_mode) {
|
||||
bytes += 8;
|
||||
BX_PANIC(("interrupt: int/trap gate VM"));
|
||||
}
|
||||
}
|
||||
|
||||
// new stack must have enough room, else #SS(seg selector)
|
||||
if (!can_push(&ss_descriptor, ESP_for_cpl_x, bytes))
|
||||
{
|
||||
BX_DEBUG(("interrupt(): new stack doesn't have room for %u bytes", (unsigned) bytes));
|
||||
exception(BX_SS_EXCEPTION, SS_for_cpl_x & 0xfffc, 0);
|
||||
}
|
||||
|
||||
// IP must be within CS segment boundaries, else #GP(0)
|
||||
if (gate_dest_offset > cs_descriptor.u.segment.limit_scaled) {
|
||||
BX_DEBUG(("interrupt(): gate EIP > CS.limit"));
|
||||
@ -666,8 +636,6 @@ void BX_CPU_C::protected_mode_int(Bit8u vector, bx_bool is_INT, bx_bool is_error
|
||||
// INTERRUPT TO SAME PRIVILEGE LEVEL:
|
||||
if (IS_CODE_SEGMENT_CONFORMING(cs_descriptor.type) || cs_descriptor.dpl==CPL)
|
||||
{
|
||||
int bytes;
|
||||
|
||||
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
|
||||
temp_ESP = ESP;
|
||||
else
|
||||
@ -675,26 +643,6 @@ void BX_CPU_C::protected_mode_int(Bit8u vector, bx_bool is_INT, bx_bool is_error
|
||||
|
||||
BX_DEBUG(("int_trap_gate286(): INTERRUPT TO SAME PRIVILEGE"));
|
||||
|
||||
// Current stack limits must allow pushing 6|8 bytes, else #SS(0)
|
||||
if (gate_descriptor.type >= 14) { // 386 gate
|
||||
if (is_error_code)
|
||||
bytes = 16;
|
||||
else
|
||||
bytes = 12;
|
||||
}
|
||||
else { // 286 gate
|
||||
if (is_error_code)
|
||||
bytes = 8;
|
||||
else
|
||||
bytes = 6;
|
||||
}
|
||||
|
||||
if (! can_push(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache, temp_ESP, bytes))
|
||||
{
|
||||
BX_DEBUG(("interrupt(): stack doesn't have room"));
|
||||
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_ERROR(("interrupt(): IP > cs descriptor limit"));
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: init.cc,v 1.155 2008-03-23 20:18:24 sshwarts Exp $
|
||||
// $Id: init.cc,v 1.156 2008-03-24 22:13:04 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -834,7 +834,7 @@ void BX_CPU_C::reset(unsigned source)
|
||||
BX_CPU_THIS_PTR tr.cache.p = 1; /* present */
|
||||
BX_CPU_THIS_PTR tr.cache.dpl = 0; /* field not used */
|
||||
BX_CPU_THIS_PTR tr.cache.segment = 0; /* system segment */
|
||||
BX_CPU_THIS_PTR tr.cache.type = BX_SYS_SEGMENT_BUSY_286_TSS;
|
||||
BX_CPU_THIS_PTR tr.cache.type = BX_SYS_SEGMENT_BUSY_386_TSS;
|
||||
BX_CPU_THIS_PTR tr.cache.u.system.base = 0x00000000;
|
||||
BX_CPU_THIS_PTR tr.cache.u.system.limit = 0xFFFF;
|
||||
#if BX_CPU_LEVEL >= 3
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: stack_pro.cc,v 1.40 2008-03-22 21:29:41 sshwarts Exp $
|
||||
// $Id: stack_pro.cc,v 1.41 2008-03-24 22:13:04 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -147,92 +147,6 @@ Bit64u BX_CPU_C::pop_64(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
bx_bool BX_CPP_AttrRegparmN(3)
|
||||
BX_CPU_C::can_push(bx_descriptor_t *descriptor, Bit32u esp, Bit32u bytes)
|
||||
{
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64) {
|
||||
return(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
// small stack compares against 16-bit SP
|
||||
if (!descriptor->u.segment.d_b)
|
||||
esp &= 0x0000ffff;
|
||||
|
||||
if (descriptor->valid==0) {
|
||||
BX_ERROR(("can_push(): SS invalidated."));
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (descriptor->p==0) {
|
||||
BX_ERROR(("can_push(): descriptor not present"));
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (IS_DATA_SEGMENT_EXPAND_DOWN(descriptor->type)) /* expand down segment */
|
||||
{
|
||||
Bit32u expand_down_limit;
|
||||
|
||||
if (descriptor->u.segment.d_b)
|
||||
expand_down_limit = 0xffffffff;
|
||||
else
|
||||
expand_down_limit = 0x0000ffff;
|
||||
|
||||
if (esp==0) {
|
||||
BX_PANIC(("can_push(): esp=0, wraparound?"));
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (esp < bytes) {
|
||||
BX_PANIC(("can_push(): expand-down: esp < N"));
|
||||
return(0);
|
||||
}
|
||||
if ((esp - bytes) <= descriptor->u.segment.limit_scaled) {
|
||||
BX_ERROR(("can_push(): expand-down: esp-N < limit"));
|
||||
return(0);
|
||||
}
|
||||
if (esp > expand_down_limit) {
|
||||
BX_ERROR(("can_push(): esp > expand-down-limit"));
|
||||
return(0);
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
else { /* normal (expand-up) segment */
|
||||
if (descriptor->u.segment.limit_scaled==0) {
|
||||
BX_PANIC(("can_push(): found limit of 0"));
|
||||
return(0);
|
||||
}
|
||||
|
||||
// Look at case where esp==0. Possibly, it's an intentional wraparound
|
||||
// If so, limit must be the maximum for the given stack size
|
||||
if (esp==0) {
|
||||
if (descriptor->u.segment.d_b && (descriptor->u.segment.limit_scaled==0xffffffff))
|
||||
return(1);
|
||||
if ((descriptor->u.segment.d_b==0) && (descriptor->u.segment.limit_scaled>=0xffff))
|
||||
return(1);
|
||||
BX_ERROR(("can_push(): esp=0, normal, wraparound? limit=%08x",
|
||||
descriptor->u.segment.limit_scaled));
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (!descriptor->u.segment.d_b) {
|
||||
// Weird case for 16-bit SP.
|
||||
esp = ((esp-bytes) & 0xffff) + bytes;
|
||||
}
|
||||
if (esp < bytes) {
|
||||
BX_ERROR(("can_push(): expand-up: esp < N"));
|
||||
return(0);
|
||||
}
|
||||
if ((esp-1) > descriptor->u.segment.limit_scaled) {
|
||||
BX_ERROR(("can_push(): expand-up: SP > limit"));
|
||||
return(0);
|
||||
}
|
||||
/* all checks pass */
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
|
||||
bx_bool BX_CPP_AttrRegparmN(1) BX_CPU_C::can_pop(Bit32u bytes)
|
||||
{
|
||||
Bit32u temp_ESP, expand_down_limit;
|
||||
|
Loading…
Reference in New Issue
Block a user