diff --git a/bochs/cpu/Makefile.in b/bochs/cpu/Makefile.in index e2ade3866..372ab6dc8 100644 --- a/bochs/cpu/Makefile.in +++ b/bochs/cpu/Makefile.in @@ -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 \ diff --git a/bochs/cpu/cpu.h b/bochs/cpu/cpu.h index 09b0c2291..9685d1735 100644 --- a/bochs/cpu/cpu.h +++ b/bochs/cpu/cpu.h @@ -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); diff --git a/bochs/cpu/io.cc b/bochs/cpu/io.cc index f7356cfdf..d377d9216 100644 --- a/bochs/cpu/io.cc +++ b/bochs/cpu/io.cc @@ -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); } diff --git a/bochs/cpu/io_pro.cc b/bochs/cpu/io_pro.cc deleted file mode 100644 index 39e5c9a13..000000000 --- a/bochs/cpu/io_pro.cc +++ /dev/null @@ -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); -}