VME support - beta #1
This commit is contained in:
parent
e83c77db49
commit
670395f1be
@ -2,7 +2,7 @@ dnl // Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ(2.50)
|
||||
AC_INIT(bochs.h)
|
||||
AC_REVISION([[$Id: configure.in,v 1.298 2005-10-16 23:13:18 sshwarts Exp $]])
|
||||
AC_REVISION([[$Id: configure.in,v 1.299 2005-10-17 13:06:08 sshwarts Exp $]])
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
AC_CONFIG_HEADER(ltdlconf.h)
|
||||
|
||||
@ -1543,12 +1543,6 @@ AC_ARG_ENABLE(vme,
|
||||
AC_DEFINE(BX_SUPPORT_VME, 0)
|
||||
fi
|
||||
],
|
||||
[
|
||||
if test "$bx_cpu_level" -ge 5; then
|
||||
AC_MSG_RESULT(no)
|
||||
AC_DEFINE(BX_SUPPORT_VME, 0)
|
||||
fi
|
||||
]
|
||||
)
|
||||
|
||||
AC_MSG_CHECKING(for MMX support)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: cpu.h,v 1.245 2005-10-16 23:13:19 sshwarts Exp $
|
||||
// $Id: cpu.h,v 1.246 2005-10-17 13:06:08 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -398,13 +398,13 @@ BOCHSAPI extern BX_CPU_C *bx_cpu_array[BX_SMP_PROCESSORS];
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
/* 31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16
|
||||
* ==|==|=====|==|==|==|==|==|==|==|==|==|==|==|==
|
||||
* 0| 0| 0| 0| 0| 0| 0| 0| 0| 0|ID|VP|VF|AC|VM|RF
|
||||
/* 31|30|29|28| 27|26|25|24| 23|22|21|20| 19|18|17|16
|
||||
* ==|==|=====| ==|==|==|==| ==|==|==|==| ==|==|==|==
|
||||
* 0| 0| 0| 0| 0| 0| 0| 0| 0| 0|ID|VP| VF|AC|VM|RF
|
||||
*
|
||||
* 15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0
|
||||
* ==|==|=====|==|==|==|==|==|==|==|==|==|==|==|==
|
||||
* 0|NT| IOPL|OF|DF|IF|TF|SF|ZF| 0|AF| 0|PF| 1|CF
|
||||
* 15|14|13|12| 11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0
|
||||
* ==|==|=====| ==|==|==|==| ==|==|==|==| ==|==|==|==
|
||||
* 0|NT| IOPL| OF|DF|IF|TF| SF|ZF| 0|AF| 0|PF| 1|CF
|
||||
*/
|
||||
Bit32u val32; // Raw 32-bit value in x86 bit position. Used to store
|
||||
// some eflags which are not cached in separate fields.
|
||||
@ -512,6 +512,8 @@ typedef struct {
|
||||
#define EFlagsVIFMask EFlagsVFMask
|
||||
#define EFlagsVIPMask EFlagsVPMask
|
||||
|
||||
#define EFlagsValidMask 0x003f7fd5 // only supported bits for EFLAGS
|
||||
|
||||
} bx_flags_reg_t;
|
||||
|
||||
|
||||
@ -610,12 +612,14 @@ typedef struct {
|
||||
#define IMPLEMENT_CR4_ACCESSORS(name,bitnum) \
|
||||
BX_CPP_INLINE bx_bool get_##name () { \
|
||||
return 1 & (registerValue >> bitnum); \
|
||||
} \
|
||||
} \
|
||||
BX_CPP_INLINE void set_##name (Bit8u val) { \
|
||||
registerValue = (registerValue&~(1<<bitnum)) | (val ? (1<<bitnum) : 0); \
|
||||
}
|
||||
#if BX_SUPPORT_VME
|
||||
IMPLEMENT_CR4_ACCESSORS(VME, 0);
|
||||
IMPLEMENT_CR4_ACCESSORS(PVI, 1);
|
||||
#endif
|
||||
IMPLEMENT_CR4_ACCESSORS(TSD, 2);
|
||||
IMPLEMENT_CR4_ACCESSORS(DE, 3);
|
||||
IMPLEMENT_CR4_ACCESSORS(PSE, 4);
|
||||
@ -1196,8 +1200,8 @@ public: // for now...
|
||||
|
||||
bx_segment_reg_t save_cs;
|
||||
bx_segment_reg_t save_ss;
|
||||
Bit32u save_eip;
|
||||
Bit32u save_esp;
|
||||
bx_address save_eip;
|
||||
bx_address save_esp;
|
||||
// This help for OS/2
|
||||
bx_bool except_chk;
|
||||
Bit16u except_cs;
|
||||
@ -2799,9 +2803,9 @@ public: // for now...
|
||||
BX_SMF void long_iret(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
|
||||
#endif
|
||||
BX_SMF void validate_seg_regs(void);
|
||||
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 stack_return_to_v86(Bit32u new_eip, Bit32u raw_cs_selector, Bit32u flags32);
|
||||
BX_SMF void iret16_stack_return_from_v86(bxInstruction_c *);
|
||||
BX_SMF void iret32_stack_return_from_v86(bxInstruction_c *);
|
||||
#if BX_SUPPORT_VME
|
||||
BX_SMF void v86_redirect_interrupt(Bit32u vector);
|
||||
#endif
|
||||
@ -2815,8 +2819,6 @@ public: // for now...
|
||||
BX_SMF void get_RSP_from_TSS(unsigned pl, Bit64u *rsp);
|
||||
#endif
|
||||
BX_SMF void write_flags(Bit16u flags, bx_bool change_IOPL, bx_bool change_IF) BX_CPP_AttrRegparmN(3);
|
||||
BX_SMF void write_eflags(Bit32u eflags, bx_bool change_IOPL, bx_bool change_IF,
|
||||
bx_bool change_VM, bx_bool change_RF);
|
||||
BX_SMF void writeEFlags(Bit32u eflags, Bit32u changeMask) BX_CPP_AttrRegparmN(2); // Newer variant.
|
||||
#if BX_SUPPORT_FPU || BX_SUPPORT_SSE >= 1
|
||||
BX_SMF void write_eflags_fpu_compare(int float_relation);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: ctrl_xfer16.cc,v 1.30 2005-07-20 01:26:44 sshwarts Exp $
|
||||
// $Id: ctrl_xfer16.cc,v 1.31 2005-10-17 13:06:09 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -404,7 +404,7 @@ void BX_CPU_C::IRET16(bxInstruction_c *i)
|
||||
|
||||
if (v8086_mode()) {
|
||||
// IOPL check in stack_return_from_v86()
|
||||
stack_return_from_v86(i);
|
||||
iret16_stack_return_from_v86(i);
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: ctrl_xfer32.cc,v 1.43 2005-10-16 23:13:19 sshwarts Exp $
|
||||
// $Id: ctrl_xfer32.cc,v 1.44 2005-10-17 13:06:09 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -398,7 +398,7 @@ void BX_CPU_C::IRET32(bxInstruction_c *i)
|
||||
|
||||
if (v8086_mode()) {
|
||||
// IOPL check in stack_return_from_v86()
|
||||
stack_return_from_v86(i);
|
||||
iret32_stack_return_from_v86(i);
|
||||
goto done;
|
||||
}
|
||||
|
||||
@ -414,24 +414,21 @@ void BX_CPU_C::IRET32(bxInstruction_c *i)
|
||||
exception(BX_SS_EXCEPTION, 0, 0);
|
||||
}
|
||||
|
||||
access_linear(BX_CPU_THIS_PTR get_segment_base(BX_SEG_REG_SS) + ESP,
|
||||
4, CPL == 3, BX_READ, &eip);
|
||||
pop_32(&eip);
|
||||
|
||||
// still need to be validated !
|
||||
if (eip > 0xffff) {
|
||||
// CS.LIMIT in real mode is 0xffff
|
||||
if (eip > 0xffff) {
|
||||
BX_PANIC(("IRETD: instruction pointer not within code segment limits"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
|
||||
pop_32(&eip);
|
||||
pop_32(&ecs);
|
||||
pop_32(&eflags);
|
||||
ecs &= 0xffff;
|
||||
eflags = (eflags & 0x257fd5) | (read_eflags() & 0x1a0000);
|
||||
|
||||
|
||||
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], (Bit16u)ecs);
|
||||
EIP = eip;
|
||||
writeEFlags(eflags, 0xffffffff);
|
||||
writeEFlags(eflags, 0x00257fd5); // VIF, VIP, VM unchanged
|
||||
|
||||
done:
|
||||
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_IRET,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: exception.cc,v 1.64 2005-10-13 16:22:21 sshwarts Exp $
|
||||
// $Id: exception.cc,v 1.65 2005-10-17 13:06:09 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -783,10 +783,15 @@ void BX_CPU_C::interrupt(Bit8u vector, bx_bool is_INT, bx_bool is_error_code, Bi
|
||||
BX_CPU_THIS_PTR debug_trap = 0;
|
||||
BX_CPU_THIS_PTR inhibit_mask = 0;
|
||||
|
||||
BX_CPU_THIS_PTR save_cs = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS];
|
||||
BX_CPU_THIS_PTR save_ss = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS];
|
||||
BX_CPU_THIS_PTR save_cs = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS];
|
||||
BX_CPU_THIS_PTR save_ss = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS];
|
||||
#if BX_SUPPORT_X86_64
|
||||
BX_CPU_THIS_PTR save_eip = RIP;
|
||||
BX_CPU_THIS_PTR save_esp = RSP;
|
||||
#else
|
||||
BX_CPU_THIS_PTR save_eip = EIP;
|
||||
BX_CPU_THIS_PTR save_esp = ESP;
|
||||
#endif
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (BX_CPU_THIS_PTR msr.lma) {
|
||||
@ -832,10 +837,15 @@ void BX_CPU_C::exception(unsigned vector, Bit16u error_code, bx_bool is_INT)
|
||||
// if not initial error, restore previous register values from
|
||||
// previous attempt to handle exception
|
||||
if (BX_CPU_THIS_PTR errorno) {
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS] = BX_CPU_THIS_PTR save_cs;
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS] = BX_CPU_THIS_PTR save_ss;
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS] = BX_CPU_THIS_PTR save_cs;
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS] = BX_CPU_THIS_PTR save_ss;
|
||||
#if BX_SUPPORT_X86_64
|
||||
RIP = BX_CPU_THIS_PTR save_eip;
|
||||
RSP = BX_CPU_THIS_PTR save_esp;
|
||||
#else
|
||||
EIP = BX_CPU_THIS_PTR save_eip;
|
||||
ESP = BX_CPU_THIS_PTR save_esp;
|
||||
#endif
|
||||
}
|
||||
|
||||
BX_CPU_THIS_PTR errorno++;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: flag_ctrl.cc,v 1.23 2005-10-16 23:13:19 sshwarts Exp $
|
||||
// $Id: flag_ctrl.cc,v 1.24 2005-10-17 13:06:09 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2002 MandrakeSoft S.A.
|
||||
@ -114,7 +114,7 @@ void BX_CPU_C::STI(bxInstruction_c *i)
|
||||
if (BX_CPU_THIS_PTR cr4.get_PVI())
|
||||
{
|
||||
if (cpl == 3 && IOPL < 3) {
|
||||
if (! BX_CPU_THIS_PTR get_VIP ())
|
||||
if (! BX_CPU_THIS_PTR get_VIP())
|
||||
{
|
||||
BX_CPU_THIS_PTR assert_VIF();
|
||||
return;
|
||||
@ -168,14 +168,76 @@ void BX_CPU_C::CMC(bxInstruction_c *i)
|
||||
|
||||
void BX_CPU_C::PUSHF_Fw(bxInstruction_c *i)
|
||||
{
|
||||
Bit16u flags = read_flags();
|
||||
|
||||
if (v8086_mode()) {
|
||||
if ((BX_CPU_THIS_PTR get_IOPL () < 3) && (CR4_VME_ENABLED == 0)) {
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
return;
|
||||
}
|
||||
#if BX_SUPPORT_VME
|
||||
if (CR4_VME_ENABLED && BX_CPU_THIS_PTR get_IOPL() < 3) {
|
||||
flags |= EFlagsIOPLMask;
|
||||
if (BX_CPU_THIS_PTR get_VIF())
|
||||
flags |= EFlagsIFMask;
|
||||
else
|
||||
flags &= ~EFlagsIFMask;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
push_16(read_flags());
|
||||
push_16(flags);
|
||||
}
|
||||
|
||||
void BX_CPU_C::POPF_Fw(bxInstruction_c *i)
|
||||
{
|
||||
// Build a mask of the following bits:
|
||||
// x,NT,IOPL,OF,DF,IF,TF,SF,ZF,x,AF,x,PF,x,CF
|
||||
Bit32u changeMask = EFlagsOSZAPCMask | EFlagsTFMask | EFlagsDFMask;
|
||||
#if BX_CPU_LEVEL >= 3
|
||||
changeMask |= EFlagsNTMask; // NT could be modified
|
||||
#endif
|
||||
Bit16u flags16;
|
||||
|
||||
if (protected_mode()) {
|
||||
pop_16(&flags16);
|
||||
if (CPL==0)
|
||||
changeMask |= EFlagsIOPLMask;
|
||||
if (CPL <= BX_CPU_THIS_PTR get_IOPL())
|
||||
changeMask |= EFlagsIFMask;
|
||||
}
|
||||
else if (v8086_mode()) {
|
||||
if ((BX_CPU_THIS_PTR get_IOPL () < 3) && (CR4_VME_ENABLED == 0)) {
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
return;
|
||||
}
|
||||
pop_16(&flags16);
|
||||
#if BX_SUPPORT_VME
|
||||
if (CR4_VME_ENABLED && BX_CPU_THIS_PTR get_IOPL() < 3) {
|
||||
if (((flags16 & EFlagsIFMask) && BX_CPU_THIS_PTR get_VIP()) ||
|
||||
(flags16 & EFlagsTFMask))
|
||||
{
|
||||
BX_DEBUG(("POPFW: #GP(0) in VME mode"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
|
||||
// IF, IOPL unchanged, EFLAGS.VIF = TMP_FLAGS.IF
|
||||
changeMask |= EFlagsVIFMask;
|
||||
Bit32u flags32 = (Bit32u) flags16;
|
||||
if (BX_CPU_THIS_PTR get_IF()) flags32 |= EFlagsVIFMask;
|
||||
writeEFlags(flags32, changeMask);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
changeMask |= EFlagsIFMask;
|
||||
}
|
||||
else {
|
||||
pop_16(&flags16);
|
||||
// All non-reserved flags can be modified
|
||||
changeMask |= (EFlagsIOPLMask | EFlagsIFMask);
|
||||
}
|
||||
|
||||
writeEFlags((Bit32u) flags16, changeMask);
|
||||
}
|
||||
|
||||
#if BX_CPU_LEVEL >= 3
|
||||
@ -191,58 +253,10 @@ void BX_CPU_C::PUSHF_Fd(bxInstruction_c *i)
|
||||
push_32(read_eflags() & 0x00fcffff);
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
void BX_CPU_C::PUSHF_Fq(bxInstruction_c *i)
|
||||
{
|
||||
// VM & RF flags cleared in image stored on the stack
|
||||
push_64(read_eflags() & 0x00fcffff);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // BX_CPU_LEVEL >= 3
|
||||
|
||||
void BX_CPU_C::POPF_Fw(bxInstruction_c *i)
|
||||
{
|
||||
// Build a mask of the following bits:
|
||||
// x,NT,IOPL,OF,DF,IF,TF,SF,ZF,x,AF,x,PF,x,CF
|
||||
Bit32u changeMask = EFlagsOSZAPCMask | EFlagsTFMask | EFlagsDFMask;
|
||||
0x0dd5;
|
||||
#if BX_CPU_LEVEL >= 3
|
||||
changeMask |= EFlagsNTMask; // NT could be modified
|
||||
#endif
|
||||
Bit16u flags16;
|
||||
|
||||
if (protected_mode()) {
|
||||
pop_16(&flags16);
|
||||
if (CPL==0)
|
||||
changeMask |= EFlagsIOPLMask;
|
||||
if (CPL <= BX_CPU_THIS_PTR get_IOPL())
|
||||
changeMask |= EFlagsIFMask;
|
||||
}
|
||||
else if (v8086_mode()) {
|
||||
if (BX_CPU_THIS_PTR get_IOPL() < 3) {
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
return;
|
||||
}
|
||||
pop_16(&flags16);
|
||||
// All non-reserved flags except IOPL can be modified
|
||||
changeMask |= EFlagsIFMask;
|
||||
}
|
||||
else {
|
||||
pop_16(&flags16);
|
||||
// All non-reserved flags can be modified
|
||||
changeMask |= (EFlagsIOPLMask | EFlagsIFMask);
|
||||
}
|
||||
|
||||
writeEFlags((Bit32u) flags16, changeMask);
|
||||
}
|
||||
|
||||
#if BX_CPU_LEVEL >= 3
|
||||
|
||||
void BX_CPU_C::POPF_Fd(bxInstruction_c *i)
|
||||
{
|
||||
// Build a mask of the following bits:
|
||||
// ID,VP,VF,AC,VM,RF,x,NT,IOPL,OF,DF,IF,TF,SF,ZF,x,AF,x,PF,x,CF
|
||||
// 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 | EFlagsNTMask | EFlagsRFMask;
|
||||
#if BX_CPU_LEVEL >= 4
|
||||
@ -266,7 +280,7 @@ void BX_CPU_C::POPF_Fd(bxInstruction_c *i)
|
||||
return;
|
||||
}
|
||||
pop_32(&flags32);
|
||||
// v8086-mode: VM,IOPL,VIP,VIF are unaffected
|
||||
// v8086-mode: VM, IOPL, VIP, VIF are unaffected
|
||||
changeMask |= EFlagsIFMask;
|
||||
}
|
||||
else { // Real-mode
|
||||
@ -279,21 +293,25 @@ void BX_CPU_C::POPF_Fd(bxInstruction_c *i)
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
void BX_CPU_C::PUSHF_Fq(bxInstruction_c *i)
|
||||
{
|
||||
// VM & RF flags cleared in image stored on the stack
|
||||
push_64(read_eflags() & 0x00fcffff);
|
||||
}
|
||||
|
||||
void BX_CPU_C::POPF_Fq(bxInstruction_c *i)
|
||||
{
|
||||
// Build a mask of the following bits:
|
||||
// ID,VP,VF,AC,VM,RF,x,NT,IOPL,OF,DF,IF,TF,SF,ZF,x,AF,x,PF,x,CF
|
||||
Bit32u changeMask = EFlagsOSZAPCMask | EFlagsTFMask |
|
||||
EFlagsDFMask | EFlagsNTMask | EFlagsRFMask;
|
||||
#if BX_CPU_LEVEL >= 4
|
||||
changeMask |= (EFlagsIDMask | EFlagsACMask); // ID/AC
|
||||
#endif
|
||||
// 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
|
||||
| EFlagsNTMask | EFlagsRFMask | EFlagsACMask
|
||||
| EFlagsIDMask;
|
||||
Bit64u flags64;
|
||||
|
||||
BX_ASSERT (protected_mode());
|
||||
|
||||
pop_64(&flags64);
|
||||
Bit32u flags32 = flags64 & 0xffffffff;
|
||||
Bit32u flags32 = (Bit32u) flags64;
|
||||
if (CPL==0)
|
||||
changeMask |= EFlagsIOPLMask;
|
||||
if (CPL <= BX_CPU_THIS_PTR get_IOPL())
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: flag_ctrl_pro.cc,v 1.20 2005-10-16 23:13:19 sshwarts Exp $
|
||||
// $Id: flag_ctrl_pro.cc,v 1.21 2005-10-17 13:06:09 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -88,31 +88,6 @@ BX_CPU_C::write_flags(Bit16u flags, bx_bool change_IOPL, bx_bool change_IF)
|
||||
writeEFlags(Bit32u(flags), changeMask);
|
||||
}
|
||||
|
||||
|
||||
#if BX_CPU_LEVEL >= 3
|
||||
void BX_CPU_C::write_eflags(Bit32u eflags_raw, bx_bool change_IOPL,
|
||||
bx_bool change_IF, bx_bool change_VM, bx_bool change_RF)
|
||||
{
|
||||
// Build a mask of the following bits:
|
||||
// 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 | EFlagsNTMask;
|
||||
#if BX_CPU_LEVEL >= 4
|
||||
changeMask |= (EFlagsIDMask | EFlagsACMask); // ID/AC
|
||||
#endif
|
||||
if (change_IOPL)
|
||||
changeMask |= EFlagsIOPLMask;
|
||||
if (change_IF)
|
||||
changeMask |= EFlagsIFMask;
|
||||
if (change_VM)
|
||||
changeMask |= EFlagsVMMask;
|
||||
if (change_RF)
|
||||
changeMask |= EFlagsRFMask;
|
||||
|
||||
writeEFlags(eflags_raw, changeMask);
|
||||
}
|
||||
#endif /* BX_CPU_LEVEL >= 3 */
|
||||
|
||||
// Cause arithmetic flags to be in known state and cached in val32.
|
||||
Bit32u BX_CPU_C::force_flags(void)
|
||||
{
|
||||
|
@ -1,5 +1,5 @@
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// $Id: iret.cc,v 1.8 2005-10-16 23:13:19 sshwarts Exp $
|
||||
// $Id: iret.cc,v 1.9 2005-10-17 13:06:09 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -215,8 +215,21 @@ BX_CPU_C::iret_protected(bxInstruction_c *i)
|
||||
/* load CS-cache with new code segment descriptor */
|
||||
branch_far32(&cs_selector, &cs_descriptor, new_eip, cs_selector.rpl);
|
||||
|
||||
/* load EFLAGS with 3rd doubleword from stack */
|
||||
write_eflags(new_eflags, CPL==0, CPL<=BX_CPU_THIS_PTR get_IOPL (), 0, 1);
|
||||
// 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 | EFlagsNTMask | EFlagsRFMask;
|
||||
#if BX_CPU_LEVEL >= 4
|
||||
changeMask |= (EFlagsIDMask | EFlagsACMask); // ID/AC
|
||||
#endif
|
||||
if (CPL <= BX_CPU_THIS_PTR get_IOPL())
|
||||
changeMask |= EFlagsIFMask;
|
||||
if (CPL == 0)
|
||||
changeMask |= EFlagsVIPMask | EFlagsVIFMask | EFlagsIOPLMask;
|
||||
|
||||
// IF only changed if (CPL <= EFLAGS.IOPL)
|
||||
// VIF, VIP, IOPL only changed if CPL == 0
|
||||
// VM unaffected
|
||||
writeEFlags(new_eflags, changeMask);
|
||||
}
|
||||
else {
|
||||
/* load CS-cache with new code segment descriptor */
|
||||
@ -326,13 +339,24 @@ BX_CPU_C::iret_protected(bxInstruction_c *i)
|
||||
/* set CPL to the RPL of the return CS selector */
|
||||
branch_far32(&cs_selector, &cs_descriptor, new_eip, cs_selector.rpl);
|
||||
|
||||
/* load flags from stack */
|
||||
// perhaps I should always write_eflags(), thus zeroing
|
||||
// out the upper 16bits of eflags for CS.D_B==0 ???
|
||||
// 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 | EFlagsNTMask | EFlagsRFMask;
|
||||
#if BX_CPU_LEVEL >= 4
|
||||
changeMask |= (EFlagsIDMask | EFlagsACMask); // ID/AC
|
||||
#endif
|
||||
if (prev_cpl <= BX_CPU_THIS_PTR get_IOPL())
|
||||
changeMask |= EFlagsIFMask;
|
||||
if (prev_cpl == 0)
|
||||
changeMask |= EFlagsVIPMask | EFlagsVIFMask | EFlagsIOPLMask;
|
||||
|
||||
if (cs_descriptor.u.segment.d_b)
|
||||
write_eflags(new_eflags, prev_cpl==0, prev_cpl<=BX_CPU_THIS_PTR get_IOPL(), 0, 1);
|
||||
else
|
||||
write_flags((Bit16u) new_eflags, prev_cpl==0, prev_cpl<=BX_CPU_THIS_PTR get_IOPL());
|
||||
changeMask &= 0xffff;
|
||||
|
||||
// IF only changed if (prev_CPL <= EFLAGS.IOPL)
|
||||
// VIF, VIP, IOPL only changed if prev_CPL == 0
|
||||
// VM unaffected
|
||||
writeEFlags(new_eflags, changeMask);
|
||||
|
||||
// load SS:eSP from stack
|
||||
// load the SS-cache with SS descriptor
|
||||
@ -473,8 +497,18 @@ BX_CPU_C::long_iret(bxInstruction_c *i)
|
||||
/* load CS-cache with new code segment descriptor */
|
||||
branch_far32(&cs_selector, &cs_descriptor, new_rip, CPL);
|
||||
|
||||
/* load EFLAGS with 3rd doubleword from stack */
|
||||
write_eflags(new_eflags, CPL==0, CPL<=BX_CPU_THIS_PTR get_IOPL(), 0, 1);
|
||||
// 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 |
|
||||
EFlagsNTMask | EFlagsRFMask | EFlagsIDMask | EFlagsACMask;
|
||||
if (CPL <= BX_CPU_THIS_PTR get_IOPL())
|
||||
changeMask |= EFlagsIFMask;
|
||||
if (CPL == 0)
|
||||
changeMask |= EFlagsVIPMask | EFlagsVIFMask | EFlagsIOPLMask;
|
||||
|
||||
// IF only changed if (CPL <= EFLAGS.IOPL)
|
||||
// VIF, VIP, IOPL only changed if CPL == 0
|
||||
// VM unaffected
|
||||
writeEFlags(new_eflags, changeMask);
|
||||
|
||||
/* we are NOT in 64-bit mode */
|
||||
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
|
||||
@ -570,13 +604,21 @@ BX_CPU_C::long_iret(bxInstruction_c *i)
|
||||
/* set CPL to the RPL of the return CS selector */
|
||||
branch_far64(&cs_selector, &cs_descriptor, new_rip, cs_selector.rpl);
|
||||
|
||||
/* load flags from stack */
|
||||
// perhaps I should always write_eflags(), thus zeroing
|
||||
// out the upper 16bits of eflags for CS.D_B==0 ???
|
||||
// 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 |
|
||||
EFlagsNTMask | EFlagsRFMask | EFlagsIDMask | EFlagsACMask;
|
||||
if (prev_cpl <= BX_CPU_THIS_PTR get_IOPL())
|
||||
changeMask |= EFlagsIFMask;
|
||||
if (prev_cpl == 0)
|
||||
changeMask |= EFlagsVIPMask | EFlagsVIFMask | EFlagsIOPLMask;
|
||||
|
||||
if (cs_descriptor.u.segment.d_b)
|
||||
write_eflags(new_eflags, prev_cpl==0, prev_cpl<=BX_CPU_THIS_PTR get_IOPL(), 0, 1);
|
||||
else
|
||||
write_flags((Bit16u) new_eflags, prev_cpl==0, prev_cpl<=BX_CPU_THIS_PTR get_IOPL());
|
||||
changeMask &= 0xffff;
|
||||
|
||||
// IF only changed if (prev_CPL <= EFLAGS.IOPL)
|
||||
// VIF, VIP, IOPL only changed if prev_CPL == 0
|
||||
// VM unaffected
|
||||
writeEFlags(new_eflags, changeMask);
|
||||
|
||||
if ( (raw_ss_selector & 0xfffc) != 0 ) {
|
||||
// load SS:RSP from stack
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: proc_ctrl.cc,v 1.118 2005-10-16 23:13:19 sshwarts Exp $
|
||||
// $Id: proc_ctrl.cc,v 1.119 2005-10-17 13:06:09 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -2012,7 +2012,7 @@ SYSCALL_LEGACY_MODE:
|
||||
Bit32u dword1, dword2;
|
||||
|
||||
if (!BX_CPU_THIS_PTR msr.sce) {
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
exception(BX_UD_EXCEPTION, 0, 0);
|
||||
}
|
||||
|
||||
invalidate_prefetch_q();
|
||||
@ -2020,10 +2020,7 @@ SYSCALL_LEGACY_MODE:
|
||||
if (BX_CPU_THIS_PTR msr.lma)
|
||||
{
|
||||
RCX = RIP;
|
||||
#ifdef __GNUC__
|
||||
#warning - PRT: SYSCALL -- do we reset RF/VM before saving to R11?
|
||||
#endif
|
||||
R11 = read_eflags();
|
||||
R11 = read_eflags() & ~(EFlagsRFMask);
|
||||
|
||||
if (BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64) {
|
||||
temp_RIP = MSR_LSTAR;
|
||||
@ -2042,8 +2039,8 @@ SYSCALL_LEGACY_MODE:
|
||||
parse_descriptor(dword1, dword2, &ss_descriptor);
|
||||
load_ss(&ss_selector, &ss_descriptor, 0);
|
||||
|
||||
write_eflags(read_eflags() & (~MSR_FMASK),1,1,1,0);
|
||||
BX_CPU_THIS_PTR clear_RF ();
|
||||
writeEFlags(read_eflags() & (~MSR_FMASK), EFlagsValidMask);
|
||||
BX_CPU_THIS_PTR clear_RF();
|
||||
RIP = temp_RIP;
|
||||
}
|
||||
else {
|
||||
@ -2132,7 +2129,7 @@ SYSRET_NON_64BIT_MODE:
|
||||
Bit32u dword1, dword2;
|
||||
|
||||
if (!BX_CPU_THIS_PTR msr.sce) {
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
exception(BX_UD_EXCEPTION, 0, 0);
|
||||
}
|
||||
|
||||
if(real_mode() || CPL != 0) {
|
||||
@ -2168,7 +2165,7 @@ SYSRET_NON_64BIT_MODE:
|
||||
load_ss(&ss_selector, &ss_descriptor, 0);
|
||||
|
||||
// SS base, limit, attributes unchanged.
|
||||
write_eflags(R11,1,1,1,1);
|
||||
writeEFlags(R11, EFlagsValidMask);
|
||||
|
||||
RIP = temp_RIP;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: stack_pro.cc,v 1.25 2005-08-28 17:37:37 sshwarts Exp $
|
||||
// $Id: stack_pro.cc,v 1.26 2005-10-17 13:06:09 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -55,7 +55,7 @@ BX_CPU_C::push_16(Bit16u value16)
|
||||
}
|
||||
}
|
||||
|
||||
/* push 32 bit operand size */
|
||||
/* push 32 bit operand */
|
||||
void BX_CPU_C::push_32(Bit32u value32)
|
||||
{
|
||||
/* must use StackAddrSize, and either RSP, ESP or SP accordingly */
|
||||
@ -80,6 +80,7 @@ void BX_CPU_C::push_32(Bit32u value32)
|
||||
}
|
||||
}
|
||||
|
||||
/* push 64 bit operand */
|
||||
void BX_CPU_C::push_64(Bit64u value64)
|
||||
{
|
||||
/* must use StackAddrSize, and either RSP, ESP or SP accordingly */
|
||||
@ -104,6 +105,7 @@ void BX_CPU_C::push_64(Bit64u value64)
|
||||
}
|
||||
}
|
||||
|
||||
/* pop 16 bit operand from the stack */
|
||||
void BX_CPU_C::pop_16(Bit16u *value16_ptr)
|
||||
{
|
||||
bx_address temp_RSP;
|
||||
@ -120,7 +122,6 @@ void BX_CPU_C::pop_16(Bit16u *value16_ptr)
|
||||
#endif
|
||||
temp_RSP = SP;
|
||||
|
||||
/* access within limits */
|
||||
read_virtual_word(BX_SEG_REG_SS, temp_RSP, value16_ptr);
|
||||
|
||||
#if BX_CPU_LEVEL >= 3
|
||||
@ -136,6 +137,7 @@ void BX_CPU_C::pop_16(Bit16u *value16_ptr)
|
||||
SP += 2;
|
||||
}
|
||||
|
||||
/* pop 32 bit operand from the stack */
|
||||
void BX_CPU_C::pop_32(Bit32u *value32_ptr)
|
||||
{
|
||||
bx_address temp_RSP;
|
||||
@ -152,7 +154,6 @@ void BX_CPU_C::pop_32(Bit32u *value32_ptr)
|
||||
#endif
|
||||
temp_RSP = SP;
|
||||
|
||||
/* access within limits */
|
||||
read_virtual_dword(BX_SEG_REG_SS, temp_RSP, value32_ptr);
|
||||
|
||||
#if BX_CPU_LEVEL >= 3
|
||||
@ -168,6 +169,7 @@ void BX_CPU_C::pop_32(Bit32u *value32_ptr)
|
||||
SP += 4;
|
||||
}
|
||||
|
||||
/* pop 64 bit operand from the stack */
|
||||
void BX_CPU_C::pop_64(Bit64u *value64_ptr)
|
||||
{
|
||||
bx_address temp_RSP;
|
||||
@ -184,7 +186,6 @@ void BX_CPU_C::pop_64(Bit64u *value64_ptr)
|
||||
#endif
|
||||
temp_RSP = SP;
|
||||
|
||||
/* access within limits */
|
||||
read_virtual_qword(BX_SEG_REG_SS, temp_RSP, value64_ptr);
|
||||
|
||||
#if BX_CPU_LEVEL >= 3
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: tasking.cc,v 1.25 2005-09-03 11:39:26 sshwarts Exp $
|
||||
// $Id: tasking.cc,v 1.26 2005-10-17 13:06:09 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -460,7 +460,7 @@ void BX_CPU_C::task_switch(bx_selector_t *tss_selector,
|
||||
}
|
||||
|
||||
BX_CPU_THIS_PTR prev_eip = EIP = newEIP;
|
||||
write_eflags(newEFLAGS, 1,1,1,1);
|
||||
writeEFlags(newEFLAGS, EFlagsValidMask);
|
||||
EAX = newEAX;
|
||||
ECX = newECX;
|
||||
EDX = newEDX;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: vm8086.cc,v 1.21 2005-10-16 23:13:19 sshwarts Exp $
|
||||
// $Id: vm8086.cc,v 1.22 2005-10-17 13:06:09 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -30,6 +30,12 @@
|
||||
#include "bochs.h"
|
||||
#define LOG_THIS BX_CPU_THIS_PTR
|
||||
|
||||
#if BX_SUPPORT_X86_64==0
|
||||
// Make life easier for merging 64&32-bit code.
|
||||
#define RIP EIP
|
||||
#define RSP ESP
|
||||
#endif
|
||||
|
||||
|
||||
// Notes:
|
||||
//
|
||||
@ -55,9 +61,8 @@ void BX_CPU_C::stack_return_to_v86(Bit32u new_eip, Bit32u raw_cs_selector,
|
||||
Bit16u raw_es_selector, raw_ds_selector, raw_fs_selector,
|
||||
raw_gs_selector, raw_ss_selector;
|
||||
|
||||
|
||||
// Must be 32bit effective opsize, VM is in upper 16bits of eFLAGS
|
||||
// CPL = 0 to get here
|
||||
// Must be 32bit effective opsize, VM is set in upper 16bits of eFLAGS
|
||||
// and CPL = 0 to get here
|
||||
|
||||
// ----------------
|
||||
// | | OLD GS | eSP+32
|
||||
@ -82,8 +87,7 @@ void BX_CPU_C::stack_return_to_v86(Bit32u new_eip, Bit32u raw_cs_selector,
|
||||
exception(BX_SS_EXCEPTION, 0, 0);
|
||||
}
|
||||
|
||||
esp_laddr = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base +
|
||||
temp_ESP;
|
||||
esp_laddr = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP;
|
||||
|
||||
// load SS:ESP from stack
|
||||
access_linear(esp_laddr + 12, 4, 0, BX_READ, &new_esp);
|
||||
@ -95,8 +99,7 @@ void BX_CPU_C::stack_return_to_v86(Bit32u new_eip, Bit32u raw_cs_selector,
|
||||
access_linear(esp_laddr + 28, 2, 0, BX_READ, &raw_fs_selector);
|
||||
access_linear(esp_laddr + 32, 2, 0, BX_READ, &raw_gs_selector);
|
||||
|
||||
write_eflags(flags32, /*change IOPL*/ 1, /*change IF*/ 1,
|
||||
/*change VM*/ 1, /*change RF*/ 1);
|
||||
writeEFlags(flags32, EFlagsValidMask);
|
||||
|
||||
// load CS:IP from stack; already read and passed as args
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value = raw_cs_selector;
|
||||
@ -107,16 +110,61 @@ void BX_CPU_C::stack_return_to_v86(Bit32u new_eip, Bit32u raw_cs_selector,
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value = raw_fs_selector;
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value = raw_gs_selector;
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value = raw_ss_selector;
|
||||
#if BX_SUPPORT_X86_64
|
||||
RSP = new_esp;
|
||||
#else
|
||||
ESP = new_esp; // Full 32bits are loaded.
|
||||
#endif
|
||||
RSP = new_esp; // full 32 bit are loaded
|
||||
|
||||
init_v8086_mode();
|
||||
}
|
||||
|
||||
void BX_CPU_C::stack_return_from_v86(bxInstruction_c *i)
|
||||
void BX_CPU_C::iret16_stack_return_from_v86(bxInstruction_c *i)
|
||||
{
|
||||
if ((BX_CPU_THIS_PTR get_IOPL() < 3) && (CR4_VME_ENABLED == 0)) {
|
||||
// trap to virtual 8086 monitor
|
||||
BX_DEBUG(("IRET in vm86 with IOPL != 3, VME = 0"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
|
||||
Bit16u ip, cs_raw, flags16;
|
||||
|
||||
if( !can_pop(6) )
|
||||
{
|
||||
exception(BX_SS_EXCEPTION, 0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
pop_16(&ip);
|
||||
pop_16(&cs_raw);
|
||||
pop_16(&flags16);
|
||||
|
||||
#if BX_SUPPORT_VME
|
||||
if (CR4_VME_ENABLED && BX_CPU_THIS_PTR get_IOPL() < 3)
|
||||
{
|
||||
if (((flags16 & EFlagsIFMask) && BX_CPU_THIS_PTR get_VIP()) ||
|
||||
(flags16 & EFlagsTFMask))
|
||||
{
|
||||
BX_DEBUG(("iret16_stack_return_from_v86: #GP(0) in VME mode"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
|
||||
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
|
||||
RIP = (Bit32u) ip;
|
||||
|
||||
// IF, IOPL unchanged, EFLAGS.VIF = TMP_FLAGS.IF
|
||||
Bit32u changeMask = EFlagsOSZAPCMask | EFlagsTFMask |
|
||||
EFlagsDFMask | EFlagsNTMask | EFlagsVIFMask;
|
||||
Bit32u flags32 = (Bit32u) flags16;
|
||||
if (BX_CPU_THIS_PTR get_IF()) flags32 |= EFlagsVIFMask;
|
||||
writeEFlags(flags32, changeMask);
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
|
||||
RIP = (Bit32u) ip;
|
||||
write_flags(flags16, /*IOPL*/ 0, /*IF*/ 1);
|
||||
}
|
||||
|
||||
void BX_CPU_C::iret32_stack_return_from_v86(bxInstruction_c *i)
|
||||
{
|
||||
if (BX_CPU_THIS_PTR get_IOPL() < 3) {
|
||||
// trap to virtual 8086 monitor
|
||||
@ -124,42 +172,68 @@ void BX_CPU_C::stack_return_from_v86(bxInstruction_c *i)
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
|
||||
if (i->os32L()) {
|
||||
Bit32u eip, cs_raw, eflags_tmp;
|
||||
Bit32u eip, cs_raw, flags32;
|
||||
// Build a mask of the following bits:
|
||||
// ID,VIP,VIF,AC,VM,RF,x,NT,IOPL,OF,DF,IF,TF,SF,ZF,x,AF,x,PF,x,CF
|
||||
Bit32u change_mask = EFlagsOSZAPCMask | EFlagsTFMask | EFlagsIFMask
|
||||
| EFlagsDFMask | EFlagsNTMask | EFlagsRFMask;
|
||||
|
||||
if( !can_pop(12) )
|
||||
{
|
||||
exception(BX_SS_EXCEPTION, 0, 0);
|
||||
return;
|
||||
}
|
||||
#if BX_CPU_LEVEL >= 4
|
||||
change_mask |= (EFlagsIDMask | EFlagsACMask); // ID/AC
|
||||
#endif
|
||||
|
||||
if( !can_pop(12) )
|
||||
{
|
||||
exception(BX_SS_EXCEPTION, 0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
pop_32(&eip);
|
||||
pop_32(&cs_raw);
|
||||
pop_32(&eflags_tmp);
|
||||
pop_32(&eip);
|
||||
pop_32(&cs_raw);
|
||||
pop_32(&flags32);
|
||||
|
||||
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], (Bit16u) cs_raw);
|
||||
EIP = eip;
|
||||
write_eflags(eflags_tmp, /*IOPL*/ 0, /*IF*/ 1, /*VM*/ 0, /*RF*/ 1);
|
||||
}
|
||||
else {
|
||||
Bit16u ip, cs_raw, flags;
|
||||
|
||||
if( !can_pop(6) )
|
||||
{
|
||||
exception(BX_SS_EXCEPTION, 0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
pop_16(&ip);
|
||||
pop_16(&cs_raw);
|
||||
pop_16(&flags);
|
||||
|
||||
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
|
||||
EIP = (Bit32u) ip;
|
||||
write_flags(flags, /*IOPL*/ 0, /*IF*/ 1);
|
||||
}
|
||||
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], (Bit16u) cs_raw);
|
||||
RIP = eip;
|
||||
// VIF, VIP, VM, IOPL unchanged
|
||||
writeEFlags(flags32, change_mask);
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_VME
|
||||
void BX_CPU_C::v86_redirect_interrupt(Bit32u vector)
|
||||
{
|
||||
Bit16u temp_IP, temp_CS, temp_flags = read_flags();
|
||||
|
||||
access_linear(vector*4, 2, 0, BX_READ, &temp_IP);
|
||||
access_linear(vector*4 + 2, 2, 0, BX_READ, &temp_CS);
|
||||
|
||||
if (BX_CPU_THIS_PTR get_IOPL() < 3) {
|
||||
temp_flags |= EFlagsIOPLMask;
|
||||
if (BX_CPU_THIS_PTR get_VIF())
|
||||
temp_flags |= EFlagsIFMask;
|
||||
else
|
||||
temp_flags &= ~EFlagsIFMask;
|
||||
}
|
||||
|
||||
Bit16u old_IP = IP;
|
||||
Bit16u old_CS = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value;
|
||||
|
||||
push_16(temp_flags);
|
||||
// push return address onto new stack
|
||||
push_16(old_CS);
|
||||
push_16(old_IP);
|
||||
|
||||
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], (Bit16u) temp_CS);
|
||||
RIP = temp_IP;
|
||||
|
||||
BX_CPU_THIS_PTR clear_TF ();
|
||||
BX_CPU_THIS_PTR clear_RF ();
|
||||
if (BX_CPU_THIS_PTR get_IOPL() == 3)
|
||||
BX_CPU_THIS_PTR clear_IF ();
|
||||
else
|
||||
BX_CPU_THIS_PTR clear_VIF();
|
||||
}
|
||||
#endif
|
||||
|
||||
void BX_CPU_C::init_v8086_mode(void)
|
||||
{
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.valid = 1;
|
||||
@ -265,13 +339,6 @@ void BX_CPU_C::init_v8086_mode(void)
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.rpl = 3;
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_VME
|
||||
void BX_CPU_C::v86_redirect_interrupt(Bit32u vector)
|
||||
{
|
||||
BX_PANIC(("Redirection of interrupts through virtual-mode idt still not implemented"));
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* BX_CPU_LEVEL >= 3 */
|
||||
|
||||
#else // BX_SUPPORT_V8086_MODE
|
||||
|
Loading…
Reference in New Issue
Block a user