Merge io.cc and io_pro.cc (required for future VMX use)

This commit is contained in:
Stanislav Shwartsman 2009-01-15 16:53:08 +00:00
parent aee488ea3a
commit 0836545037
4 changed files with 190 additions and 178 deletions

View File

@ -72,7 +72,6 @@ OBJS = \
xsave.o \
aes.o \
soft_int.o \
io_pro.o \
apic.o \
bcd.o \
mult16.o \
@ -467,16 +466,6 @@ io.o: io.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h ../bx_debug/debug.h \
../cpu/xmm.h stack.h ../iodev/iodev.h ../iodev/vga.h \
../iodev/svga_cirrus.h ../iodev/ioapic.h ../cpu/apic.h \
../iodev/keyboard.h
io_pro.o: io_pro.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h ../bx_debug/debug.h \
../config.h ../osdep.h ../bxversion.h ../gui/siminterface.h \
../memory/memory.h ../pc_system.h ../plugin.h ../extplugin.h ../ltdl.h \
../gui/gui.h ../gui/textconfig.h ../gui/keymap.h \
../instrument/stubs/instrument.h cpu.h ../disasm/disasm.h crregs.h \
descriptor.h instr.h lazy_flags.h icache.h apic.h ../cpu/i387.h \
../fpu/softfloat.h ../fpu/tag_w.h ../fpu/status_w.h ../fpu/control_w.h \
../cpu/xmm.h stack.h ../iodev/iodev.h ../iodev/vga.h \
../iodev/svga_cirrus.h ../iodev/ioapic.h ../cpu/apic.h \
../iodev/keyboard.h
iret.o: iret.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h ../bx_debug/debug.h \
../config.h ../osdep.h ../bxversion.h ../gui/siminterface.h \
../memory/memory.h ../pc_system.h ../plugin.h ../extplugin.h ../ltdl.h \

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: cpu.h,v 1.549 2009-01-10 10:07:57 sshwarts Exp $
// $Id: cpu.h,v 1.550 2009-01-15 16:53:08 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -3142,12 +3142,6 @@ public: // for now...
BX_SMF Bit32u force_flags(void);
BX_SMF Bit32u read_eflags(void) { return BX_CPU_THIS_PTR force_flags(); }
BX_SMF Bit8u inp8(Bit16u addr) BX_CPP_AttrRegparmN(1);
BX_SMF void outp8(Bit16u addr, Bit8u value) BX_CPP_AttrRegparmN(2);
BX_SMF Bit16u inp16(Bit16u addr) BX_CPP_AttrRegparmN(1);
BX_SMF void outp16(Bit16u addr, Bit16u value) BX_CPP_AttrRegparmN(2);
BX_SMF Bit32u inp32(Bit16u addr) BX_CPP_AttrRegparmN(1);
BX_SMF void outp32(Bit16u addr, Bit32u value) BX_CPP_AttrRegparmN(2);
BX_SMF bx_bool allow_io(Bit16u addr, unsigned len);
BX_SMF void parse_selector(Bit16u raw_selector, bx_selector_t *selector) BX_CPP_AttrRegparmN(2);
BX_SMF void parse_descriptor(Bit32u dword1, Bit32u dword2, bx_descriptor_t *temp) BX_CPP_AttrRegparmN(3);

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: io.cc,v 1.70 2008-12-29 17:35:35 sshwarts Exp $
// $Id: io.cc,v 1.71 2009-01-15 16:53:08 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -683,60 +683,236 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::OUTSD64_DXXd(bxInstruction_c *i)
void BX_CPP_AttrRegparmN(1) BX_CPU_C::IN_ALIb(bxInstruction_c *i)
{
AL = BX_CPU_THIS_PTR inp8(i->Ib());
unsigned port = i->Ib();
if (! BX_CPU_THIS_PTR allow_io(port, 1)) {
BX_DEBUG(("IN_ALIb: I/O access not allowed !"));
exception(BX_GP_EXCEPTION, 0, 0);
}
#if BX_SUPPORT_VMX
VMexit_IO(i, port, VMEXIT_IO_INTR_LEN(1) | VMEXIT_IO_INSTR_PORTIN | VMEXIT_IO_INSTR_IMM);
#endif
AL = BX_INP(port, 1);
}
void BX_CPP_AttrRegparmN(1) BX_CPU_C::IN_AXIb(bxInstruction_c *i)
{
AX = BX_CPU_THIS_PTR inp16(i->Ib());
unsigned port = i->Ib();
if (! BX_CPU_THIS_PTR allow_io(port, 2)) {
BX_DEBUG(("IN_AXIb: I/O access not allowed !"));
exception(BX_GP_EXCEPTION, 0, 0);
}
#if BX_SUPPORT_VMX
VMexit_IO(i, port, VMEXIT_IO_INTR_LEN(2) | VMEXIT_IO_INSTR_PORTIN | VMEXIT_IO_INSTR_IMM);
#endif
AX = BX_INP(port, 2);
}
void BX_CPP_AttrRegparmN(1) BX_CPU_C::IN_EAXIb(bxInstruction_c *i)
{
RAX = BX_CPU_THIS_PTR inp32(i->Ib());
unsigned port = i->Ib();
if (! BX_CPU_THIS_PTR allow_io(port, 4)) {
BX_DEBUG(("IN_EAXIb: I/O access not allowed !"));
exception(BX_GP_EXCEPTION, 0, 0);
}
#if BX_SUPPORT_VMX
VMexit_IO(i, port, VMEXIT_IO_INTR_LEN(4) | VMEXIT_IO_INSTR_PORTIN | VMEXIT_IO_INSTR_IMM);
#endif
RAX = BX_INP(port, 4);
}
void BX_CPP_AttrRegparmN(1) BX_CPU_C::OUT_IbAL(bxInstruction_c *i)
{
BX_CPU_THIS_PTR outp8(i->Ib(), AL);
unsigned port = i->Ib();
if (! BX_CPU_THIS_PTR allow_io(port, 1)) {
BX_DEBUG(("OUT_IbAL: I/O access not allowed !"));
exception(BX_GP_EXCEPTION, 0, 0);
}
#if BX_SUPPORT_VMX
VMexit_IO(i, port, VMEXIT_IO_INTR_LEN(1) | VMEXIT_IO_INSTR_IMM);
#endif
BX_OUTP(port, AL, 1);
}
void BX_CPP_AttrRegparmN(1) BX_CPU_C::OUT_IbAX(bxInstruction_c *i)
{
BX_CPU_THIS_PTR outp16(i->Ib(), AX);
unsigned port = i->Ib();
if (! BX_CPU_THIS_PTR allow_io(port, 2)) {
BX_DEBUG(("OUT_IbAX: I/O access not allowed !"));
exception(BX_GP_EXCEPTION, 0, 0);
}
#if BX_SUPPORT_VMX
VMexit_IO(i, port, VMEXIT_IO_INTR_LEN(2) | VMEXIT_IO_INSTR_IMM);
#endif
BX_OUTP(port, AX, 2);
}
void BX_CPP_AttrRegparmN(1) BX_CPU_C::OUT_IbEAX(bxInstruction_c *i)
{
BX_CPU_THIS_PTR outp32(i->Ib(), EAX);
unsigned port = i->Ib();
if (! BX_CPU_THIS_PTR allow_io(port, 4)) {
BX_DEBUG(("OUT_IbEAX: I/O access not allowed !"));
exception(BX_GP_EXCEPTION, 0, 0);
}
#if BX_SUPPORT_VMX
VMexit_IO(i, port, VMEXIT_IO_INTR_LEN(4) | VMEXIT_IO_INSTR_IMM);
#endif
BX_OUTP(port, EAX, 4);
}
void BX_CPP_AttrRegparmN(1) BX_CPU_C::IN_ALDX(bxInstruction_c *i)
{
AL = BX_CPU_THIS_PTR inp8(DX);
unsigned port = DX;
if (! BX_CPU_THIS_PTR allow_io(port, 1)) {
BX_DEBUG(("IN_ALDX: I/O access not allowed !"));
exception(BX_GP_EXCEPTION, 0, 0);
}
#if BX_SUPPORT_VMX
VMexit_IO(i, port, VMEXIT_IO_INTR_LEN(1) | VMEXIT_IO_INSTR_PORTIN);
#endif
AL = BX_INP(port, 1);
}
void BX_CPP_AttrRegparmN(1) BX_CPU_C::IN_AXDX(bxInstruction_c *i)
{
AX = BX_CPU_THIS_PTR inp16(DX);
unsigned port = DX;
if (! BX_CPU_THIS_PTR allow_io(port, 2)) {
BX_DEBUG(("IN_AXDX: I/O access not allowed !"));
exception(BX_GP_EXCEPTION, 0, 0);
}
#if BX_SUPPORT_VMX
VMexit_IO(i, port, VMEXIT_IO_INTR_LEN(2) | VMEXIT_IO_INSTR_PORTIN);
#endif
AX = BX_INP(port, 2);
}
void BX_CPP_AttrRegparmN(1) BX_CPU_C::IN_EAXDX(bxInstruction_c *i)
{
RAX = BX_CPU_THIS_PTR inp32(DX);
unsigned port = DX;
if (! BX_CPU_THIS_PTR allow_io(port, 4)) {
BX_DEBUG(("IN_EAXDX: I/O access not allowed !"));
exception(BX_GP_EXCEPTION, 0, 0);
}
#if BX_SUPPORT_VMX
VMexit_IO(i, port, VMEXIT_IO_INTR_LEN(4) | VMEXIT_IO_INSTR_PORTIN);
#endif
RAX = BX_INP(port, 4);
}
void BX_CPP_AttrRegparmN(1) BX_CPU_C::OUT_DXAL(bxInstruction_c *i)
{
BX_CPU_THIS_PTR outp8(DX, AL);
unsigned port = DX;
if (! BX_CPU_THIS_PTR allow_io(port, 1)) {
BX_DEBUG(("OUT_DXAL: I/O access not allowed !"));
exception(BX_GP_EXCEPTION, 0, 0);
}
#if BX_SUPPORT_VMX
VMexit_IO(i, port, VMEXIT_IO_INTR_LEN(1));
#endif
BX_OUTP(port, AL, 1);
}
void BX_CPP_AttrRegparmN(1) BX_CPU_C::OUT_DXAX(bxInstruction_c *i)
{
BX_CPU_THIS_PTR outp16(DX, AX);
unsigned port = DX;
if (! BX_CPU_THIS_PTR allow_io(port, 2)) {
BX_DEBUG(("OUT_DXAX: I/O access not allowed !"));
exception(BX_GP_EXCEPTION, 0, 0);
}
#if BX_SUPPORT_VMX
VMexit_IO(i, port, VMEXIT_IO_INTR_LEN(2));
#endif
BX_OUTP(port, AX, 2);
}
void BX_CPP_AttrRegparmN(1) BX_CPU_C::OUT_DXEAX(bxInstruction_c *i)
{
BX_CPU_THIS_PTR outp32(DX, EAX);
unsigned port = DX;
if (! BX_CPU_THIS_PTR allow_io(port, 4)) {
BX_DEBUG(("OUT_DXEAX: I/O access not allowed !"));
exception(BX_GP_EXCEPTION, 0, 0);
}
#if BX_SUPPORT_VMX
VMexit_IO(i, port, VMEXIT_IO_INTR_LEN(4));
#endif
BX_OUTP(port, EAX, 4);
}
bx_bool BX_CPU_C::allow_io(Bit16u port, unsigned len)
{
/* If CPL <= IOPL, then all IO portesses 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 &&
BX_CPU_THIS_PTR tr.cache.type != BX_SYS_SEGMENT_BUSY_386_TSS))
{
BX_ERROR(("allow_io(): TR doesn't point to a valid 32bit TSS, TR.TYPE=%u", BX_CPU_THIS_PTR tr.cache.type));
return(0);
}
if (BX_CPU_THIS_PTR tr.cache.u.system.limit_scaled < 103) {
BX_ERROR(("allow_io(): TR.limit < 103"));
return(0);
}
Bit16u io_base = system_read_word(BX_CPU_THIS_PTR tr.cache.u.system.base + 102);
if ((io_base + port/8) >= BX_CPU_THIS_PTR tr.cache.u.system.limit_scaled) {
BX_DEBUG(("allow_io(): IO port %x (len %d) outside TSS IO permission map (base=%x, limit=%x) #GP(0)",
port, len, io_base, BX_CPU_THIS_PTR tr.cache.u.system.limit_scaled));
return(0);
}
Bit16u permission16 = system_read_word(BX_CPU_THIS_PTR tr.cache.u.system.base + io_base + port/8);
unsigned bit_index = port & 0x7;
unsigned mask = (1 << len) - 1;
if ((permission16 >> bit_index) & mask)
return(0);
}
#if BX_X86_DEBUGGER
iobreakpoint_match(port, len);
#endif
return(1);
}

View File

@ -1,147 +0,0 @@
/////////////////////////////////////////////////////////////////////////
// $Id: io_pro.cc,v 1.39 2008-09-14 20:58:20 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
//
// MandrakeSoft S.A.
// 43, rue d'Aboukir
// 75002 Paris - France
// http://www.linux-mandrake.com/
// http://www.mandrakesoft.com/
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
/////////////////////////////////////////////////////////////////////////
#define NEED_CPU_REG_SHORTCUTS 1
#include "bochs.h"
#include "cpu.h"
#define LOG_THIS BX_CPU_THIS_PTR
#include "iodev/iodev.h"
Bit16u BX_CPP_AttrRegparmN(1)
BX_CPU_C::inp16(Bit16u port)
{
if (! BX_CPU_THIS_PTR allow_io(port, 2)) {
BX_DEBUG(("inp16(): I/O access not allowed !"));
exception(BX_GP_EXCEPTION, 0, 0);
}
Bit16u ret16 = BX_INP(port, 2);
return ret16;
}
void BX_CPP_AttrRegparmN(2)
BX_CPU_C::outp16(Bit16u port, Bit16u value)
{
if (! BX_CPU_THIS_PTR allow_io(port, 2)) {
BX_DEBUG(("outp16(): I/O access not allowed !"));
exception(BX_GP_EXCEPTION, 0, 0);
}
BX_OUTP(port, value, 2);
}
Bit32u BX_CPP_AttrRegparmN(1)
BX_CPU_C::inp32(Bit16u port)
{
if (! BX_CPU_THIS_PTR allow_io(port, 4)) {
BX_DEBUG(("inp32(): I/O access not allowed !"));
exception(BX_GP_EXCEPTION, 0, 0);
}
Bit32u ret32 = BX_INP(port, 4);
return ret32;
}
void BX_CPP_AttrRegparmN(2)
BX_CPU_C::outp32(Bit16u port, Bit32u value)
{
if (! BX_CPU_THIS_PTR allow_io(port, 4)) {
BX_DEBUG(("outp32(): I/O access not allowed !"));
exception(BX_GP_EXCEPTION, 0, 0);
}
BX_OUTP(port, value, 4);
}
Bit8u BX_CPP_AttrRegparmN(1)
BX_CPU_C::inp8(Bit16u port)
{
if (! BX_CPU_THIS_PTR allow_io(port, 1)) {
BX_DEBUG(("inp8(): I/O access not allowed !"));
exception(BX_GP_EXCEPTION, 0, 0);
}
Bit8u ret8 = BX_INP(port, 1);
return ret8;
}
void BX_CPP_AttrRegparmN(2)
BX_CPU_C::outp8(Bit16u port, Bit8u value)
{
if (! BX_CPU_THIS_PTR allow_io(port, 1)) {
BX_DEBUG(("outp8(): I/O access not allowed !"));
exception(BX_GP_EXCEPTION, 0, 0);
}
BX_OUTP(port, value, 1);
}
bx_bool BX_CPU_C::allow_io(Bit16u port, unsigned len)
{
/* If CPL <= IOPL, then all IO portesses 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 &&
BX_CPU_THIS_PTR tr.cache.type != BX_SYS_SEGMENT_BUSY_386_TSS))
{
BX_ERROR(("allow_io(): TR doesn't point to a valid 32bit TSS, TR.TYPE=%u", BX_CPU_THIS_PTR tr.cache.type));
return(0);
}
if (BX_CPU_THIS_PTR tr.cache.u.system.limit_scaled < 103) {
BX_ERROR(("allow_io(): TR.limit < 103"));
return(0);
}
Bit16u io_base = system_read_word(BX_CPU_THIS_PTR tr.cache.u.system.base + 102);
if ((io_base + port/8) >= BX_CPU_THIS_PTR tr.cache.u.system.limit_scaled) {
BX_DEBUG(("allow_io(): IO port %x (len %d) outside TSS IO permission map (base=%x, limit=%x) #GP(0)",
port, len, io_base, BX_CPU_THIS_PTR tr.cache.u.system.limit_scaled));
return(0);
}
Bit16u permission16 = system_read_word(BX_CPU_THIS_PTR tr.cache.u.system.base + io_base + port/8);
unsigned bit_index = port & 0x7;
unsigned mask = (1 << len) - 1;
if ((permission16 >> bit_index) & mask)
return(0);
}
#if BX_X86_DEBUGGER
iobreakpoint_match(port, len);
#endif
return(1);
}