Fixed a lot of code duplication and possible bug with oncorrect implementation of repeat speedup in 64-bit guest
This commit is contained in:
parent
fe2e0525da
commit
d032a30429
102
bochs/cpu/io.cc
102
bochs/cpu/io.cc
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: io.cc,v 1.43 2007-12-16 21:03:45 sshwarts Exp $
|
||||
// $Id: io.cc,v 1.44 2007-12-17 21:13:55 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -329,12 +329,10 @@ void BX_CPU_C::INSB_YbDX(bxInstruction_c *i)
|
||||
{
|
||||
Bit8u value8=0;
|
||||
|
||||
if (BX_CPU_THIS_PTR cr0.get_PE() && (BX_CPU_THIS_PTR get_VM() || (CPL>BX_CPU_THIS_PTR get_IOPL()))) {
|
||||
if (! BX_CPU_THIS_PTR allow_io(DX, 1)) {
|
||||
BX_DEBUG(("INSB_YbDX: I/O access not allowed !"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (i->as64L()) {
|
||||
@ -391,40 +389,54 @@ void BX_CPU_C::INSB_YbDX(bxInstruction_c *i)
|
||||
// input word from port to string
|
||||
void BX_CPU_C::INSW_YwDX(bxInstruction_c *i)
|
||||
{
|
||||
bx_address edi;
|
||||
unsigned int incr = 2;
|
||||
bx_address rdi;
|
||||
Bit32u incr = 2;
|
||||
Bit16u value16=0;
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (i->as64L())
|
||||
edi = RDI;
|
||||
if (i->as64L()) {
|
||||
rdi = RDI;
|
||||
|
||||
// Write a zero to memory, to trigger any segment or page
|
||||
// faults before reading from IO port.
|
||||
write_virtual_word(BX_SEG_REG_ES, rdi, &value16);
|
||||
|
||||
value16 = BX_INP(DX, 2);
|
||||
|
||||
/* no seg override allowed */
|
||||
write_virtual_word(BX_SEG_REG_ES, rdi, &value16);
|
||||
|
||||
if (BX_CPU_THIS_PTR get_DF())
|
||||
rdi -= 2;
|
||||
else
|
||||
rdi += 2;
|
||||
|
||||
RDI = rdi;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (i->as32L())
|
||||
edi = EDI;
|
||||
rdi = EDI;
|
||||
else
|
||||
edi = DI;
|
||||
|
||||
Bit16u value16=0;
|
||||
rdi = DI;
|
||||
|
||||
#if (BX_SupportRepeatSpeedups) && (BX_DEBUGGER == 0)
|
||||
/* If conditions are right, we can transfer IO to physical memory
|
||||
* in a batch, rather than one instruction at a time.
|
||||
*/
|
||||
if (i->repUsedL() && !BX_CPU_THIS_PTR async_event) {
|
||||
if (i->repUsedL() && !BX_CPU_THIS_PTR async_event)
|
||||
{
|
||||
Bit32u wordCount;
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (i->as64L())
|
||||
wordCount = RCX; // Truncated to 32bits. (we're only doing 1 page)
|
||||
else
|
||||
#endif
|
||||
if (i->as32L())
|
||||
wordCount = ECX;
|
||||
else
|
||||
wordCount = CX;
|
||||
|
||||
BX_ASSERT(wordCount > 0);
|
||||
wordCount = FastRepINSW(i, edi, DX, wordCount);
|
||||
|
||||
wordCount = FastRepINSW(i, rdi, DX, wordCount);
|
||||
if (wordCount)
|
||||
{
|
||||
// Decrement the ticks count by the number of iterations, minus
|
||||
@ -433,11 +445,6 @@ void BX_CPU_C::INSW_YwDX(bxInstruction_c *i)
|
||||
// don't roll it under zero.
|
||||
BX_TICKN(wordCount-1);
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (i->as64L())
|
||||
RCX -= (wordCount-1);
|
||||
else
|
||||
#endif
|
||||
if (i->as32L())
|
||||
RCX = ECX - (wordCount-1);
|
||||
else
|
||||
@ -451,27 +458,17 @@ void BX_CPU_C::INSW_YwDX(bxInstruction_c *i)
|
||||
|
||||
// Write a zero to memory, to trigger any segment or page
|
||||
// faults before reading from IO port.
|
||||
write_virtual_word(BX_SEG_REG_ES, edi, &value16);
|
||||
write_virtual_word(BX_SEG_REG_ES, rdi, &value16);
|
||||
|
||||
value16 = BX_INP(DX, 2);
|
||||
|
||||
/* no seg override allowed */
|
||||
write_virtual_word(BX_SEG_REG_ES, edi, &value16);
|
||||
incr = 2;
|
||||
write_virtual_word(BX_SEG_REG_ES, rdi, &value16);
|
||||
|
||||
#if (BX_SupportRepeatSpeedups) && (BX_DEBUGGER == 0)
|
||||
doIncr:
|
||||
#endif
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (i->as64L()) {
|
||||
if (BX_CPU_THIS_PTR get_DF())
|
||||
RDI = RDI - incr;
|
||||
else
|
||||
RDI = RDI + incr;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (i->as32L()) {
|
||||
if (BX_CPU_THIS_PTR get_DF())
|
||||
RDI = EDI - incr;
|
||||
@ -480,51 +477,50 @@ doIncr:
|
||||
}
|
||||
else {
|
||||
if (BX_CPU_THIS_PTR get_DF())
|
||||
DI = DI - incr;
|
||||
DI -= incr;
|
||||
else
|
||||
DI = DI + incr;
|
||||
DI += incr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// input doubleword from port to string
|
||||
void BX_CPU_C::INSD_YdDX(bxInstruction_c *i)
|
||||
{
|
||||
if (BX_CPU_THIS_PTR cr0.get_PE() && (BX_CPU_THIS_PTR get_VM() || (CPL>BX_CPU_THIS_PTR get_IOPL()))) {
|
||||
if (! BX_CPU_THIS_PTR allow_io(DX, 4)) {
|
||||
BX_DEBUG(("INSD_YdDX: I/O access not allowed !"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
bx_address edi;
|
||||
bx_address rdi;
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (i->as64L())
|
||||
edi = RDI;
|
||||
rdi = RDI;
|
||||
else
|
||||
#endif
|
||||
if (i->as32L())
|
||||
edi = EDI;
|
||||
rdi = EDI;
|
||||
else
|
||||
edi = DI;
|
||||
rdi = DI;
|
||||
|
||||
Bit32u value32=0;
|
||||
|
||||
// Write a zero to memory, to trigger any segment or page
|
||||
// faults before reading from IO port.
|
||||
write_virtual_dword(BX_SEG_REG_ES, edi, &value32);
|
||||
write_virtual_dword(BX_SEG_REG_ES, rdi, &value32);
|
||||
|
||||
value32 = BX_INP(DX, 4);
|
||||
|
||||
/* no seg override allowed */
|
||||
write_virtual_dword(BX_SEG_REG_ES, edi, &value32);
|
||||
write_virtual_dword(BX_SEG_REG_ES, rdi, &value32);
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (i->as64L()) {
|
||||
if (BX_CPU_THIS_PTR get_DF())
|
||||
RDI = RDI - 4;
|
||||
RDI -= 4;
|
||||
else
|
||||
RDI = RDI + 4;
|
||||
RDI += 4;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
@ -536,9 +532,9 @@ void BX_CPU_C::INSD_YdDX(bxInstruction_c *i)
|
||||
}
|
||||
else {
|
||||
if (BX_CPU_THIS_PTR get_DF())
|
||||
DI = DI - 4;
|
||||
DI -= 4;
|
||||
else
|
||||
DI = DI + 4;
|
||||
DI += 4;
|
||||
}
|
||||
}
|
||||
|
||||
@ -570,12 +566,10 @@ void BX_CPU_C::OUTSB_DXXb(bxInstruction_c *i)
|
||||
Bit8u value8;
|
||||
bx_address esi;
|
||||
|
||||
if (BX_CPU_THIS_PTR cr0.get_PE() && (BX_CPU_THIS_PTR get_VM() || (CPL>BX_CPU_THIS_PTR get_IOPL()))) {
|
||||
if (! BX_CPU_THIS_PTR allow_io(DX, 1)) {
|
||||
BX_DEBUG(("OUTSB_DXXb: I/O access not allowed !"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (i->as64L())
|
||||
@ -618,14 +612,12 @@ void BX_CPU_C::OUTSB_DXXb(bxInstruction_c *i)
|
||||
void BX_CPU_C::OUTSW_DXXw(bxInstruction_c *i)
|
||||
{
|
||||
bx_address esi;
|
||||
unsigned incr = 2;
|
||||
Bit32u incr = 2;
|
||||
|
||||
if (BX_CPU_THIS_PTR cr0.get_PE() && (BX_CPU_THIS_PTR get_VM() || (CPL>BX_CPU_THIS_PTR get_IOPL()))) {
|
||||
if (! BX_CPU_THIS_PTR allow_io(DX, 2)) {
|
||||
BX_DEBUG(("OUTSW_DXXw: I/O access not allowed !"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (i->as64L())
|
||||
@ -711,12 +703,10 @@ void BX_CPU_C::OUTSW_DXXw(bxInstruction_c *i)
|
||||
// output doubleword string to port
|
||||
void BX_CPU_C::OUTSD_DXXd(bxInstruction_c *i)
|
||||
{
|
||||
if (BX_CPU_THIS_PTR cr0.get_PE() && (BX_CPU_THIS_PTR get_VM() || (CPL>BX_CPU_THIS_PTR get_IOPL()))) {
|
||||
if (! BX_CPU_THIS_PTR allow_io(DX, 4)) {
|
||||
BX_DEBUG(("OUTSD_DXXd: I/O access not allowed !"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
bx_address esi;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: io_pro.cc,v 1.25 2007-11-29 21:45:10 sshwarts Exp $
|
||||
// $Id: io_pro.cc,v 1.26 2007-12-17 21:13:55 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -35,32 +35,22 @@
|
||||
Bit16u BX_CPP_AttrRegparmN(1)
|
||||
BX_CPU_C::inp16(Bit16u addr)
|
||||
{
|
||||
Bit16u ret16;
|
||||
|
||||
if (BX_CPU_THIS_PTR cr0.get_PE() && (BX_CPU_THIS_PTR get_VM() || (CPL>BX_CPU_THIS_PTR get_IOPL()))) {
|
||||
if (! BX_CPU_THIS_PTR allow_io(addr, 2)) {
|
||||
BX_DEBUG(("inp16(): I/O access not allowed !"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
ret16 = BX_INP(addr, 2);
|
||||
Bit16u ret16 = BX_INP(addr, 2);
|
||||
return ret16;
|
||||
}
|
||||
|
||||
void BX_CPP_AttrRegparmN(2)
|
||||
BX_CPU_C::outp16(Bit16u addr, Bit16u value)
|
||||
{
|
||||
/* If CPL <= IOPL, then all IO addresses are accessible.
|
||||
* Otherwise, must check the IO permission map on >286.
|
||||
* On the 286, there is no IO permissions map */
|
||||
|
||||
if (BX_CPU_THIS_PTR cr0.get_PE() && (BX_CPU_THIS_PTR get_VM() || (CPL>BX_CPU_THIS_PTR get_IOPL()))) {
|
||||
if (! BX_CPU_THIS_PTR allow_io(addr, 2)) {
|
||||
BX_DEBUG(("outp16(): I/O access not allowed !"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
BX_OUTP(addr, value, 2);
|
||||
}
|
||||
@ -68,32 +58,22 @@ BX_CPU_C::outp16(Bit16u addr, Bit16u value)
|
||||
Bit32u BX_CPP_AttrRegparmN(1)
|
||||
BX_CPU_C::inp32(Bit16u addr)
|
||||
{
|
||||
Bit32u ret32;
|
||||
|
||||
if (BX_CPU_THIS_PTR cr0.get_PE() && (BX_CPU_THIS_PTR get_VM() || (CPL>BX_CPU_THIS_PTR get_IOPL()))) {
|
||||
if (! BX_CPU_THIS_PTR allow_io(addr, 4)) {
|
||||
BX_DEBUG(("inp32(): I/O access not allowed !"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
ret32 = BX_INP(addr, 4);
|
||||
Bit32u ret32 = BX_INP(addr, 4);
|
||||
return ret32;
|
||||
}
|
||||
|
||||
void BX_CPP_AttrRegparmN(2)
|
||||
BX_CPU_C::outp32(Bit16u addr, Bit32u value)
|
||||
{
|
||||
/* If CPL <= IOPL, then all IO addresses are accessible.
|
||||
* Otherwise, must check the IO permission map on >286.
|
||||
* On the 286, there is no IO permissions map */
|
||||
|
||||
if (BX_CPU_THIS_PTR cr0.get_PE() && (BX_CPU_THIS_PTR get_VM() || (CPL>BX_CPU_THIS_PTR get_IOPL()))) {
|
||||
if (! BX_CPU_THIS_PTR allow_io(addr, 4)) {
|
||||
BX_DEBUG(("outp32(): I/O access not allowed !"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
BX_OUTP(addr, value, 4);
|
||||
}
|
||||
@ -101,33 +81,22 @@ BX_CPU_C::outp32(Bit16u addr, Bit32u value)
|
||||
Bit8u BX_CPP_AttrRegparmN(1)
|
||||
BX_CPU_C::inp8(Bit16u addr)
|
||||
{
|
||||
Bit8u ret8;
|
||||
|
||||
if (BX_CPU_THIS_PTR cr0.get_PE() && (BX_CPU_THIS_PTR get_VM() || (CPL>BX_CPU_THIS_PTR get_IOPL()))) {
|
||||
if (! BX_CPU_THIS_PTR allow_io(addr, 1)) {
|
||||
BX_DEBUG(("inp8(): I/O access not allowed !"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
ret8 = BX_INP(addr, 1);
|
||||
Bit8u ret8 = BX_INP(addr, 1);
|
||||
return ret8;
|
||||
}
|
||||
|
||||
|
||||
void BX_CPP_AttrRegparmN(2)
|
||||
BX_CPU_C::outp8(Bit16u addr, Bit8u value)
|
||||
{
|
||||
/* If CPL <= IOPL, then all IO addresses are accessible.
|
||||
* Otherwise, must check the IO permission map on >286.
|
||||
* On the 286, there is no IO permissions map */
|
||||
|
||||
if (BX_CPU_THIS_PTR cr0.get_PE() && (BX_CPU_THIS_PTR get_VM() || (CPL>BX_CPU_THIS_PTR get_IOPL()))) {
|
||||
if (! BX_CPU_THIS_PTR allow_io(addr, 1)) {
|
||||
BX_DEBUG(("outp8(): I/O access not allowed !"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
BX_OUTP(addr, value, 1);
|
||||
}
|
||||
@ -136,6 +105,12 @@ bx_bool BX_CPU_C::allow_io(Bit16u addr, unsigned len)
|
||||
{
|
||||
Bit16u io_base, permission16;
|
||||
|
||||
/* If CPL <= IOPL, then all IO addresses are accessible.
|
||||
* Otherwise, must check the IO permission map on >286.
|
||||
* On the 286, there is no IO permissions map */
|
||||
|
||||
if (BX_CPU_THIS_PTR cr0.get_PE() && (BX_CPU_THIS_PTR get_VM() || (CPL>BX_CPU_THIS_PTR get_IOPL())))
|
||||
{
|
||||
if (BX_CPU_THIS_PTR tr.cache.valid==0 ||
|
||||
BX_CPU_THIS_PTR tr.cache.type != BX_SYS_SEGMENT_AVAIL_386_TSS)
|
||||
{
|
||||
@ -172,6 +147,7 @@ bx_bool BX_CPU_C::allow_io(Bit16u addr, unsigned len)
|
||||
return(0);
|
||||
permission16 >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user