Getting little bit closer to VME feature

This commit is contained in:
Stanislav Shwartsman 2005-03-09 22:01:13 +00:00
parent a91c27c855
commit 24fa5935c1
4 changed files with 74 additions and 59 deletions

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: cpu.h,v 1.201 2005-03-01 21:44:00 sshwarts Exp $
// $Id: cpu.h,v 1.202 2005-03-09 22:01:12 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -2669,6 +2669,7 @@ public: // for now...
BX_SMF void stack_return_to_v86(Bit32u new_eip, Bit32u raw_cs_selector,
Bit32u flags32);
BX_SMF void stack_return_from_v86(bxInstruction_c *);
BX_SMF void v86_redirect_interrupt(Bit32u vector);
BX_SMF void init_v8086_mode(void);
BX_SMF void v8086_message(void);
BX_SMF void task_switch(bx_selector_t *selector,

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: io_pro.cc,v 1.15 2004-06-19 15:20:07 sshwarts Exp $
// $Id: io_pro.cc,v 1.16 2005-03-09 22:01:13 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -38,11 +38,10 @@ BX_CPU_C::inp16(Bit16u addr)
if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR get_VM () || (CPL>BX_CPU_THIS_PTR get_IOPL ()))) {
if ( !BX_CPU_THIS_PTR allow_io(addr, 2) ) {
// BX_INFO(("cpu_inp16: GP0()!"));
exception(BX_GP_EXCEPTION, 0, 0);
return(0);
}
}
}
ret16 = BX_INP(addr, 2);
return( ret16 );
@ -57,11 +56,10 @@ BX_CPU_C::outp16(Bit16u addr, Bit16u value)
if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR get_VM() || (CPL>BX_CPU_THIS_PTR get_IOPL()))) {
if ( !BX_CPU_THIS_PTR allow_io(addr, 2) ) {
// BX_INFO(("cpu_outp16: GP0()!"));
exception(BX_GP_EXCEPTION, 0, 0);
return;
}
}
}
BX_OUTP(addr, value, 2);
}
@ -73,11 +71,10 @@ BX_CPU_C::inp32(Bit16u addr)
if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR get_VM() || (CPL>BX_CPU_THIS_PTR get_IOPL()))) {
if ( !BX_CPU_THIS_PTR allow_io(addr, 4) ) {
// BX_INFO(("cpu_inp32: GP0()!"));
exception(BX_GP_EXCEPTION, 0, 0);
return(0);
}
}
}
ret32 = BX_INP(addr, 4);
return( ret32 );
@ -92,11 +89,10 @@ BX_CPU_C::outp32(Bit16u addr, Bit32u value)
if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR get_VM() || (CPL>BX_CPU_THIS_PTR get_IOPL()))) {
if ( !BX_CPU_THIS_PTR allow_io(addr, 4) ) {
// BX_INFO(("cpu_outp32: GP0()!"));
exception(BX_GP_EXCEPTION, 0, 0);
return;
}
}
}
BX_OUTP(addr, value, 4);
}
@ -108,11 +104,10 @@ BX_CPU_C::inp8(Bit16u addr)
if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR get_VM() || (CPL>BX_CPU_THIS_PTR get_IOPL()))) {
if ( !BX_CPU_THIS_PTR allow_io(addr, 1) ) {
// BX_INFO(("cpu_inp8: GP0()!"));
exception(BX_GP_EXCEPTION, 0, 0);
return(0);
}
}
}
ret8 = BX_INP(addr, 1);
return( ret8 );
@ -128,11 +123,10 @@ BX_CPU_C::outp8(Bit16u addr, Bit8u value)
if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR get_VM() || (CPL>BX_CPU_THIS_PTR get_IOPL()))) {
if ( !BX_CPU_THIS_PTR allow_io(addr, 1) ) {
// BX_INFO(("cpu_outp8: GP0()!"));
exception(BX_GP_EXCEPTION, 0, 0);
return;
}
}
}
BX_OUTP(addr, value, 1);
}
@ -147,30 +141,29 @@ BX_CPU_C::allow_io(Bit16u addr, unsigned len)
if (BX_CPU_THIS_PTR tr.cache.valid==0 || BX_CPU_THIS_PTR tr.cache.type!=9) {
BX_INFO(("allow_io(): TR doesn't point to a valid 32bit TSS"));
return(0);
}
}
if (BX_CPU_THIS_PTR tr.cache.u.tss386.limit_scaled < 103) {
BX_PANIC(("allow_io(): TR.limit < 103"));
}
}
access_linear(BX_CPU_THIS_PTR tr.cache.u.tss386.base + 102,
2, 0, BX_READ, &io_base);
access_linear(BX_CPU_THIS_PTR tr.cache.u.tss386.base + 102, 2, 0, BX_READ,
&io_base);
if (io_base <= 103) {
BX_INFO(("PE is %u", BX_CPU_THIS_PTR cr0.pe));
BX_INFO(("VM is %u", BX_CPU_THIS_PTR getB_VM ()));
BX_INFO(("CPL is %u", CPL));
BX_INFO(("IOPL is %u", BX_CPU_THIS_PTR get_IOPL ()));
BX_INFO(("addr is %u", addr));
BX_INFO(("len is %u", len));
BX_PANIC(("allow_io(): TR:io_base (%u) <= 103",io_base));
return(0);
}
BX_INFO(("PE is %u", BX_CPU_THIS_PTR cr0.pe));
BX_INFO(("VM is %u", BX_CPU_THIS_PTR getB_VM ()));
BX_INFO(("CPL is %u, IOPL is %u", CPL, BX_CPU_THIS_PTR get_IOPL ()));
BX_INFO(("addr is %u, len = %u", addr, len));
BX_PANIC(("allow_io(): TR:io_base (%u) <= 103",io_base));
return(0);
}
if ( (Bit32s) (addr/8) >= (Bit32s) (BX_CPU_THIS_PTR tr.cache.u.tss386.limit_scaled - io_base)) {
BX_INFO(("allow_io(): IO addr %x (len %d) outside TSS IO permission map (base=%x, limit=%x) #GP(0)",
addr, len, io_base, BX_CPU_THIS_PTR tr.cache.u.tss386.limit_scaled));
return(0);
}
}
access_linear(BX_CPU_THIS_PTR tr.cache.u.tss386.base + io_base + addr/8,
2, 0, BX_READ, &permission16);
@ -181,7 +174,7 @@ BX_INFO(("len is %u", len));
if (permission16 & 0x01)
return(0);
permission16 >>= 1;
}
}
return(1);
}

View File

@ -105,37 +105,65 @@ void BX_CPU_C::INT_Ib(bxInstruction_c *i)
BX_CPU_THIS_PTR show_flag |= Flag_int;
#endif
Bit8u imm8 = i->Ib();
Bit8u vector = i->Ib();
if (v8086_mode() && (BX_CPU_THIS_PTR get_IOPL()<3))
exception(BX_GP_EXCEPTION, 0, 0);
if (v8086_mode())
{
if (BX_CPU_THIS_PTR cr4.get_VME())
{
Bit16u io_base;
access_linear(BX_CPU_THIS_PTR tr.cache.u.tss386.base + 102,
2, 0, BX_READ, &io_base);
Bit8u vme_redirection_bitmap;
access_linear(BX_CPU_THIS_PTR tr.cache.u.tss386.base + io_base - 32 + (vector >> 3),
1, 0, BX_READ, &vme_redirection_bitmap);
if (vme_redirection_bitmap & (1 << (vector & 7)))
{
// VME redirecion bit is set so the interrupt is not redirected
if (BX_CPU_THIS_PTR get_IOPL() < 3)
{
exception(BX_GP_EXCEPTION, 0, 0);
}
}
else {
// redirect interrupt through virtual-mode idt
v86_redirect_interrupt(vector);
return;
}
}
else // VME is off
{
if (BX_CPU_THIS_PTR get_IOPL() < 3)
{
exception(BX_GP_EXCEPTION, 0, 0);
}
}
}
#ifdef SHOW_EXIT_STATUS
if ( (imm8 == 0x21) && (AH == 0x4c) ) {
BX_INFO(("INT 21/4C called AL=0x%02x, BX=0x%04x", (unsigned) AL, (unsigned) BX));
if ( (vector == 0x21) && (AH == 0x4c) ) {
BX_INFO(("INT 21/4C called AL=0x%02x, BX=0x%04x", (unsigned) AL, (unsigned) BX));
}
#endif
interrupt(imm8, 1, 0, 0);
interrupt(vector, 1, 0, 0);
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_INT,
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
EIP);
}
void BX_CPU_C::INTO(bxInstruction_c *i)
{
#if BX_DEBUGGER
BX_CPU_THIS_PTR show_flag |= Flag_int;
#endif
/* ??? is this IOPL sensitive ? */
if (v8086_mode()) BX_PANIC(("soft_int: v8086 mode unsupported"));
if (get_OF()) {
interrupt(4, 1, 0, 0);
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_INT,
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
EIP);
}
}
}

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: vm8086.cc,v 1.16 2004-07-08 20:15:23 sshwarts Exp $
// $Id: vm8086.cc,v 1.17 2005-03-09 22:01:13 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -48,8 +48,7 @@
#if BX_CPU_LEVEL >= 3
void
BX_CPU_C::stack_return_to_v86(Bit32u new_eip, Bit32u raw_cs_selector,
void BX_CPU_C::stack_return_to_v86(Bit32u new_eip, Bit32u raw_cs_selector,
Bit32u flags32)
{
Bit32u temp_ESP, new_esp, esp_laddr;
@ -123,15 +122,14 @@ BX_CPU_C::stack_return_to_v86(Bit32u new_eip, Bit32u raw_cs_selector,
init_v8086_mode();
}
void
BX_CPU_C::stack_return_from_v86(bxInstruction_c *i)
void BX_CPU_C::stack_return_from_v86(bxInstruction_c *i)
{
if (BX_CPU_THIS_PTR get_IOPL() != 3) {
// trap to virtual 8086 monitor
BX_DEBUG(("IRET in vm86 with IOPL != 3"));
exception(BX_GP_EXCEPTION, 0, 0);
return;
}
}
if (i->os32L()) {
Bit32u eip, ecs_raw, eflags_tmp;
@ -169,9 +167,7 @@ BX_CPU_C::stack_return_from_v86(bxInstruction_c *i)
}
}
void
BX_CPU_C::init_v8086_mode(void)
void BX_CPU_C::init_v8086_mode(void)
{
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.valid = 1;
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.p = 1;
@ -276,33 +272,30 @@ BX_CPU_C::init_v8086_mode(void)
BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.rpl = 3;
}
void BX_CPU_C::v86_redirect_interrupt(Bit32u vector)
{
BX_PANIC(("Redirection of interrupts through virtual-mode idt still not implemented"));
}
#endif /* BX_CPU_LEVEL >= 3 */
#else // BX_SUPPORT_V8086_MODE
// non-support of v8086 mode
void
BX_CPU_C::stack_return_to_v86(Bit32u new_eip, Bit32u raw_cs_selector, Bit32u flags32)
void BX_CPU_C::stack_return_to_v86(Bit32u new_eip, Bit32u raw_cs_selector, Bit32u flags32)
{
BX_INFO(("stack_return_to_v86: VM bit set in EFLAGS stack image"));
v8086_message();
}
void
BX_CPU_C::stack_return_from_v86(void)
void BX_CPU_C::stack_return_from_v86(void)
{
BX_INFO(("stack_return_from_v86:"));
v8086_message();
}
void
BX_CPU_C::v8086_message(void)
void BX_CPU_C::v8086_message(void)
{
BX_INFO(("Program compiled with BX_SUPPORT_V8086_MODE = 0"));
BX_INFO(("You need to rerun the configure script and recompile"));