unify branch_far32 and branhc_far64 methods

This commit is contained in:
Stanislav Shwartsman 2019-12-14 17:20:35 +00:00
parent a01a0262be
commit bcfcaf3958
7 changed files with 27 additions and 52 deletions

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2005-2012 Stanislav Shwartsman
// Copyright (c) 2005-2019 Stanislav Shwartsman
// Written by Stanislav Shwartsman [sshwarts at sourceforge net]
//
// This library is free software; you can redistribute it and/or
@ -81,7 +81,7 @@ BX_CPU_C::call_protected(bxInstruction_c *i, Bit16u cs_raw, bx_address disp)
// load code segment descriptor into CS cache
// load CS with new code segment selector
// set RPL of CS to CPL
branch_far64(&cs_selector, &cs_descriptor, disp, CPL);
branch_far(&cs_selector, &cs_descriptor, disp, CPL);
RSP = temp_rsp;
}
@ -127,7 +127,7 @@ BX_CPU_C::call_protected(bxInstruction_c *i, Bit16u cs_raw, bx_address disp)
// load code segment descriptor into CS cache
// load CS with new code segment selector
// set RPL of CS to CPL
branch_far64(&cs_selector, &cs_descriptor, disp, CPL);
branch_far(&cs_selector, &cs_descriptor, disp, CPL);
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
ESP = (Bit32u) temp_RSP;
@ -451,7 +451,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::call_gate(bx_descriptor_t *gate_descriptor
// load CS:EIP from gate
// load code segment descriptor into CS register
// set RPL of CS to CPL
branch_far32(&cs_selector, &cs_descriptor, new_EIP, CPL);
branch_far(&cs_selector, &cs_descriptor, new_EIP, CPL);
}
}
@ -535,7 +535,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::call_gate64(bx_selector_t *gate_selector)
RSP_for_cpl_x -= 32;
// load CS:RIP (guaranteed to be in 64 bit mode)
branch_far64(&cs_selector, &cs_descriptor, new_RIP, cs_descriptor.dpl);
branch_far(&cs_selector, &cs_descriptor, new_RIP, cs_descriptor.dpl);
// set up null SS descriptor
load_null_selector(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS], cs_descriptor.dpl);
@ -551,7 +551,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::call_gate64(bx_selector_t *gate_selector)
write_new_stack_qword(RSP - 16, CPL, old_RIP);
// load CS:RIP (guaranteed to be in 64 bit mode)
branch_far64(&cs_selector, &cs_descriptor, new_RIP, CPL);
branch_far(&cs_selector, &cs_descriptor, new_RIP, CPL);
RSP -= 16;
}

View File

@ -4416,10 +4416,8 @@ public: // for now...
#if BX_SUPPORT_X86_64
BX_SMF void branch_near64(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
#endif
BX_SMF void branch_far32(bx_selector_t *selector,
bx_descriptor_t *descriptor, Bit32u eip, Bit8u cpl);
BX_SMF void branch_far64(bx_selector_t *selector,
bx_descriptor_t *descriptor, bx_address rip, Bit8u cpl);
BX_SMF void branch_far(bx_selector_t *selector,
bx_descriptor_t *descriptor, bx_address rip, unsigned cpl);
#if BX_SUPPORT_REPEAT_SPEEDUPS
BX_SMF Bit32u FastRepMOVSB(unsigned srcSeg, Bit32u srcOff, unsigned dstSeg, Bit32u dstOff, Bit32u byteCount, Bit32u granularity);

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001-2015 The Bochs Project
// Copyright (C) 2001-2019 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@ -112,30 +112,12 @@ BX_CPU_C::load_cs(bx_selector_t *selector, bx_descriptor_t *descriptor, Bit8u cp
invalidate_prefetch_q();
}
void BX_CPU_C::branch_far32(bx_selector_t *selector,
bx_descriptor_t *descriptor, Bit32u eip, Bit8u cpl)
{
/* instruction pointer must be in code segment limit else #GP(0) */
if (eip > descriptor->u.segment.limit_scaled) {
BX_ERROR(("branch_far32: EIP > limit"));
exception(BX_GP_EXCEPTION, 0);
}
/* Load CS:IP from destination pointer */
/* Load CS-cache with new segment descriptor */
load_cs(selector, descriptor, cpl);
/* Change the EIP value */
EIP = eip;
}
void BX_CPU_C::branch_far64(bx_selector_t *selector,
bx_descriptor_t *descriptor, bx_address rip, Bit8u cpl)
void BX_CPU_C::branch_far(bx_selector_t *selector, bx_descriptor_t *descriptor, bx_address rip, unsigned cpl)
{
#if BX_SUPPORT_X86_64
if (long_mode() && descriptor->u.segment.l) {
if (! IsCanonical(rip)) {
BX_ERROR(("branch_far64: canonical RIP violation"));
BX_ERROR(("branch_far: canonical RIP violation"));
exception(BX_GP_EXCEPTION, 0);
}
}
@ -146,7 +128,7 @@ void BX_CPU_C::branch_far64(bx_selector_t *selector,
/* instruction pointer must be in code segment limit else #GP(0) */
if (rip > descriptor->u.segment.limit_scaled) {
BX_ERROR(("branch_far64: RIP > limit"));
BX_ERROR(("branch_far: RIP > limit"));
exception(BX_GP_EXCEPTION, 0);
}
}

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001-2013 The Bochs Project
// Copyright (C) 2001-2019 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@ -174,7 +174,7 @@ void BX_CPU_C::long_mode_int(Bit8u vector, unsigned soft_int, bx_bool push_error
}
// load CS:RIP (guaranteed to be in 64 bit mode)
branch_far64(&cs_selector, &cs_descriptor, gate_dest_offset, cs_descriptor.dpl);
branch_far(&cs_selector, &cs_descriptor, gate_dest_offset, cs_descriptor.dpl);
// set up null SS descriptor
load_null_selector(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS], cs_descriptor.dpl);
@ -215,7 +215,7 @@ void BX_CPU_C::long_mode_int(Bit8u vector, unsigned soft_int, bx_bool push_error
}
// set the RPL field of CS to CPL
branch_far64(&cs_selector, &cs_descriptor, gate_dest_offset, CPL);
branch_far(&cs_selector, &cs_descriptor, gate_dest_offset, CPL);
}
else {
BX_ERROR(("interrupt(long mode): bad descriptor type %u (CS.DPL=%u CPL=%u)",

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2005-2017 Stanislav Shwartsman
// Copyright (c) 2005-2019 Stanislav Shwartsman
// Written by Stanislav Shwartsman [sshwarts at sourceforge net]
//
// This library is free software; you can redistribute it and/or
@ -167,7 +167,7 @@ BX_CPU_C::iret_protected(bxInstruction_c *i)
if (cs_selector.rpl == CPL) { /* INTERRUPT RETURN TO SAME LEVEL */
/* load CS-cache with new code segment descriptor */
branch_far32(&cs_selector, &cs_descriptor, new_eip, cs_selector.rpl);
branch_far(&cs_selector, &cs_descriptor, new_eip, cs_selector.rpl);
/* top 6/12 bytes on stack must be within limits, else #SS(0) */
/* satisfied above */
@ -287,7 +287,7 @@ BX_CPU_C::iret_protected(bxInstruction_c *i)
/* load CS:EIP from stack */
/* load the CS-cache with CS descriptor */
/* set CPL to the RPL of the return CS selector */
branch_far32(&cs_selector, &cs_descriptor, new_eip, cs_selector.rpl);
branch_far(&cs_selector, &cs_descriptor, new_eip, cs_selector.rpl);
// IF only changed if (prev_CPL <= EFLAGS.IOPL)
// VIF, VIP, IOPL only changed if prev_CPL == 0
@ -397,12 +397,7 @@ BX_CPU_C::long_iret(bxInstruction_c *i)
/* load CS:EIP from stack */
/* load CS-cache with new code segment descriptor */
if(cs_descriptor.u.segment.l) {
branch_far64(&cs_selector, &cs_descriptor, new_rip, CPL);
}
else {
branch_far32(&cs_selector, &cs_descriptor, (Bit32u) new_rip, CPL);
}
branch_far(&cs_selector, &cs_descriptor, new_rip, CPL);
// ID,VIP,VIF,AC,VM,RF,x,NT,IOPL,OF,DF,IF,TF,SF,ZF,x,AF,x,PF,x,CF
Bit32u changeMask = EFlagsOSZAPCMask | EFlagsTFMask | EFlagsDFMask |
@ -514,7 +509,7 @@ BX_CPU_C::long_iret(bxInstruction_c *i)
changeMask &= 0xffff;
/* set CPL to the RPL of the return CS selector */
branch_far64(&cs_selector, &cs_descriptor, new_rip, cs_selector.rpl);
branch_far(&cs_selector, &cs_descriptor, new_rip, cs_selector.rpl);
// IF only changed if (prev_CPL <= EFLAGS.IOPL)
// VIF, VIP, IOPL only changed if prev_CPL == 0

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2005-2012 Stanislav Shwartsman
// Copyright (c) 2005-2019 Stanislav Shwartsman
// Written by Stanislav Shwartsman [sshwarts at sourceforge net]
//
// This library is free software; you can redistribute it and/or
@ -50,7 +50,7 @@ BX_CPU_C::jump_protected(bxInstruction_c *i, Bit16u cs_raw, bx_address disp)
if (descriptor.segment) {
check_cs(&descriptor, cs_raw, BX_SELECTOR_RPL(cs_raw), CPL);
branch_far64(&selector, &descriptor, disp, CPL);
branch_far(&selector, &descriptor, disp, CPL);
return;
}
else {
@ -210,7 +210,7 @@ BX_CPU_C::jmp_call_gate(bx_selector_t *selector, bx_descriptor_t *gate_descripto
check_cs(&gate_cs_descriptor, gate_cs_raw, 0, CPL);
Bit32u temp_EIP = gate_descriptor->u.gate.dest_offset;
branch_far32(&gate_cs_selector, &gate_cs_descriptor, temp_EIP, CPL);
branch_far(&gate_cs_selector, &gate_cs_descriptor, temp_EIP, CPL);
}
#if BX_SUPPORT_X86_64
@ -264,6 +264,6 @@ BX_CPU_C::jmp_call_gate64(bx_selector_t *gate_selector)
// check code-segment descriptor
check_cs(&cs_descriptor, dest_selector, 0, CPL);
// and transfer the control
branch_far64(&cs_selector, &cs_descriptor, new_RIP, CPL);
branch_far(&cs_selector, &cs_descriptor, new_RIP, CPL);
}
#endif

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2005-2012 Stanislav Shwartsman
// Copyright (c) 2005-2019 Stanislav Shwartsman
// Written by Stanislav Shwartsman [sshwarts at sourceforge net]
//
// This library is free software; you can redistribute it and/or
@ -103,7 +103,7 @@ BX_CPU_C::return_protected(bxInstruction_c *i, Bit16u pop_bytes)
{
BX_DEBUG(("return_protected: return to SAME PRIVILEGE LEVEL"));
branch_far64(&cs_selector, &cs_descriptor, return_RIP, CPL);
branch_far(&cs_selector, &cs_descriptor, return_RIP, CPL);
#if BX_SUPPORT_X86_64
if (long64_mode())
@ -200,7 +200,7 @@ BX_CPU_C::return_protected(bxInstruction_c *i, Bit16u pop_bytes)
}
}
branch_far64(&cs_selector, &cs_descriptor, return_RIP, cs_selector.rpl);
branch_far(&cs_selector, &cs_descriptor, return_RIP, cs_selector.rpl);
if ((raw_ss_selector & 0xfffc) != 0) {
// load SS:RSP from stack